1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.cts.tradefed.result; 17 18 import com.android.compatibility.common.util.AbiUtils; 19 import com.android.cts.tradefed.build.CtsBuildProvider; 20 import com.android.tradefed.log.LogUtil.CLog; 21 22 import org.kxml2.io.KXmlSerializer; 23 import org.xmlpull.v1.XmlPullParser; 24 import org.xmlpull.v1.XmlPullParserException; 25 26 import java.io.IOException; 27 import java.net.InetAddress; 28 import java.net.UnknownHostException; 29 import java.util.ArrayList; 30 import java.util.Collection; 31 import java.util.Collections; 32 import java.util.Comparator; 33 import java.util.LinkedHashMap; 34 import java.util.List; 35 import java.util.Map; 36 37 /** 38 * Data structure for the detailed CTS test results. 39 * <p/> 40 * Can deserialize results for test packages from XML 41 */ 42 class TestResults extends AbstractXmlPullParser { 43 44 private static final String ns = CtsXmlResultReporter.ns; 45 46 // XML constants 47 static final String SUMMARY_TAG = "Summary"; 48 static final String PASS_ATTR = "pass"; 49 static final String TIMEOUT_ATTR = "timeout"; 50 static final String NOT_EXECUTED_ATTR = "notExecuted"; 51 static final String FAILED_ATTR = "failed"; 52 53 private Map<String, TestPackageResult> mPackageResults = 54 new LinkedHashMap<String, TestPackageResult>(); 55 private DeviceInfoResult mDeviceInfo = new DeviceInfoResult(); 56 57 /** 58 * {@inheritDoc} 59 */ 60 @Override parse(XmlPullParser parser)61 void parse(XmlPullParser parser) throws XmlPullParserException, IOException { 62 int eventType = parser.getEventType(); 63 while (eventType != XmlPullParser.END_DOCUMENT) { 64 if (eventType == XmlPullParser.START_TAG && parser.getName().equals( 65 DeviceInfoResult.TAG)) { 66 mDeviceInfo.parse(parser); 67 } 68 if (eventType == XmlPullParser.START_TAG && parser.getName().equals( 69 TestPackageResult.TAG)) { 70 TestPackageResult pkg = new TestPackageResult(); 71 pkg.parse(parser); 72 if (pkg.getId() != null) { 73 mPackageResults.put(pkg.getId(), pkg); 74 } else { 75 CLog.w("Found package with no id"); 76 } 77 } 78 eventType = parser.next(); 79 } 80 } 81 82 /** 83 * @return the list of {@link TestPackageResult}. 84 */ getPackages()85 public Collection<TestPackageResult> getPackages() { 86 return mPackageResults.values(); 87 } 88 89 /** 90 * Count the number of tests with given status 91 * @param status 92 */ countTests(CtsTestStatus status)93 public int countTests(CtsTestStatus status) { 94 int total = 0; 95 for (TestPackageResult result : mPackageResults.values()) { 96 total += result.countTests(status); 97 } 98 return total; 99 } 100 101 /** 102 * Serialize the test results to XML. 103 * 104 * @param serializer 105 * @throws IOException 106 */ serialize(KXmlSerializer serializer, String buildId)107 public void serialize(KXmlSerializer serializer, String buildId) throws IOException { 108 mDeviceInfo.serialize(serializer); 109 serializeHostInfo(serializer, buildId); 110 serializeTestSummary(serializer); 111 // sort before serializing 112 List<TestPackageResult> pkgs = new ArrayList<TestPackageResult>(mPackageResults.values()); 113 Collections.sort(pkgs, new PkgComparator()); 114 for (TestPackageResult r : pkgs) { 115 r.serialize(serializer); 116 } 117 } 118 119 /** 120 * Output the host info XML. 121 * 122 * @param serializer 123 */ serializeHostInfo(KXmlSerializer serializer, String buildId)124 private void serializeHostInfo(KXmlSerializer serializer, String buildId) throws IOException { 125 serializer.startTag(ns, "HostInfo"); 126 127 String hostName = ""; 128 try { 129 hostName = InetAddress.getLocalHost().getHostName(); 130 } catch (UnknownHostException ignored) {} 131 serializer.attribute(ns, "name", hostName); 132 133 serializer.startTag(ns, "Os"); 134 serializer.attribute(ns, "name", System.getProperty("os.name")); 135 serializer.attribute(ns, "version", System.getProperty("os.version")); 136 serializer.attribute(ns, "arch", System.getProperty("os.arch")); 137 serializer.endTag(ns, "Os"); 138 139 serializer.startTag(ns, "Java"); 140 serializer.attribute(ns, "name", System.getProperty("java.vendor")); 141 serializer.attribute(ns, "version", System.getProperty("java.version")); 142 serializer.endTag(ns, "Java"); 143 144 serializer.startTag(ns, "Cts"); 145 serializer.attribute(ns, "version", CtsBuildProvider.CTS_BUILD_VERSION); 146 serializer.attribute(ns, "build", buildId); 147 // TODO: consider outputting other tradefed options here 148 serializer.startTag(ns, "IntValue"); 149 serializer.attribute(ns, "name", "testStatusTimeoutMs"); 150 // TODO: create a constant variable for testStatusTimeoutMs value. Currently it cannot be 151 // changed 152 serializer.attribute(ns, "value", "600000"); 153 serializer.endTag(ns, "IntValue"); 154 serializer.endTag(ns, "Cts"); 155 156 serializer.endTag(ns, "HostInfo"); 157 } 158 159 /** 160 * Output the test summary XML containing summary totals for all tests. 161 * 162 * @param serializer 163 * @throws IOException 164 */ serializeTestSummary(KXmlSerializer serializer)165 private void serializeTestSummary(KXmlSerializer serializer) throws IOException { 166 serializer.startTag(ns, SUMMARY_TAG); 167 serializer.attribute(ns, FAILED_ATTR, Integer.toString(countTests(CtsTestStatus.FAIL))); 168 serializer.attribute(ns, NOT_EXECUTED_ATTR, 169 Integer.toString(countTests(CtsTestStatus.NOT_EXECUTED))); 170 // ignore timeouts - these are reported as errors 171 serializer.attribute(ns, TIMEOUT_ATTR, "0"); 172 serializer.attribute(ns, PASS_ATTR, Integer.toString(countTests(CtsTestStatus.PASS))); 173 serializer.endTag(ns, SUMMARY_TAG); 174 } 175 176 private static class PkgComparator implements Comparator<TestPackageResult> { 177 178 @Override compare(TestPackageResult lhs, TestPackageResult rhs)179 public int compare(TestPackageResult lhs, TestPackageResult rhs) { 180 return lhs.getId().compareTo(rhs.getId()); 181 } 182 } 183 184 /** 185 * Return existing package with given id. If not found, create a new one. 186 * @param id 187 * @return 188 */ getOrCreatePackage(String id)189 public TestPackageResult getOrCreatePackage(String id) { 190 TestPackageResult pkgResult = mPackageResults.get(id); 191 if (pkgResult == null) { 192 pkgResult = new TestPackageResult(); 193 String[] abiAndName = AbiUtils.parseId(id); 194 pkgResult.setAbi(abiAndName[0]); 195 pkgResult.setAppPackageName(abiAndName[1]); 196 mPackageResults.put(id, pkgResult); 197 } 198 return pkgResult; 199 } 200 201 /** 202 * Populate the results with collected device info metrics. 203 * @param runMetrics 204 */ populateDeviceInfoMetrics(Map<String, String> runMetrics)205 public void populateDeviceInfoMetrics(Map<String, String> runMetrics) { 206 mDeviceInfo.populateMetrics(runMetrics); 207 } 208 } 209