blob: bbf99d8c63fcb8e08a0602158be6393d1d865824 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import com.android.cts.TestDevice.DeviceParameterCollector;
/**
* Store the information of a test plan.
*/
public class TestSessionLog extends XMLResourceHandler {
private static final String EXPR_TEST_FAILED = ".+\\((\\S+):(\\d+)\\)";
private static Pattern mTestFailedPattern = Pattern.compile(EXPR_TEST_FAILED);
private static final String ATTRIBUTE_NAME = "name";
private static final String ATTRIBUTE_RESULT = "result";
private static final String ATTRIBUTE_VERSION = "version";
private static final String ATTRIBUTE_DIGEST = "digest";
private static final String ATTRIBUTE_KNOWN_FAILURE = "KnownFailure";
public static final int CTS_RESULT_CODE_INIT = -1;
public static final int CTS_RESULT_CODE_NOT_EXECUTED = 0;
public static final int CTS_RESULT_CODE_PASS = 1;
public static final int CTS_RESULT_CODE_FAIL = 2;
public static final int CTS_RESULT_CODE_ERROR = 3;
public static final int CTS_RESULT_CODE_TIMEOUT = 4;
public static final int CTS_RESULT_CODE_FIRST = CTS_RESULT_CODE_INIT;
public static final int CTS_RESULT_CODE_LAST = CTS_RESULT_CODE_TIMEOUT;
class TestResult {
public static final String CTS_RESULT_STR_ERROR = "error";
public static final String CTS_RESULT_STR_TIMEOUT = "timeout";
public static final String CTS_RESULT_STR_NOT_EXECUTED = "notExecuted";
public static final String CTS_RESULT_STR_FAIL = "fail";
public static final String CTS_RESULT_STR_PASS = "pass";
}
private static final String CTS_RESULT_FILE_NAME = "testResult.xml";
private static HashMap<Integer, String> sCodeToResultMap;
static {
sCodeToResultMap = new HashMap<Integer, String>();
sCodeToResultMap.put(TestSessionLog.CTS_RESULT_CODE_NOT_EXECUTED,
TestResult.CTS_RESULT_STR_NOT_EXECUTED);
sCodeToResultMap.put(TestSessionLog.CTS_RESULT_CODE_PASS,
TestResult.CTS_RESULT_STR_PASS);
sCodeToResultMap.put(TestSessionLog.CTS_RESULT_CODE_FAIL,
TestResult.CTS_RESULT_STR_FAIL);
sCodeToResultMap.put(TestSessionLog.CTS_RESULT_CODE_ERROR,
TestResult.CTS_RESULT_STR_ERROR);
sCodeToResultMap.put(TestSessionLog.CTS_RESULT_CODE_TIMEOUT,
TestResult.CTS_RESULT_STR_TIMEOUT);
}
// define the possible format of the result file format
public static final int CTS_RESULT_FORMAT_INVALID = 100;
public static final int CTS_RESULT_FORMAT_XML = 101;
static final String ATTRIBUTE_STARTTIME = "starttime";
static final String ATTRIBUTE_ENDTIME = "endtime";
static final String ATTRIBUTE_TESTPLAN = "testPlan";
static final String ATTRIBUTE_RESOLUTION = "resolution";
static final String ATTRIBUTE_SUBSCRIBER_ID = "subscriberId";
static final String ATTRIBUTE_DEVICE_ID = "deviceID";
static final String ATTRIBUTE_BUILD_ID = "buildID";
static final String ATTRIBUTE_BUILD_VERSION = "buildVersion";
static final String ATTRIBUTE_ANDROID_PLATFORM_VERSION = "androidPlatformVersion";
static final String ATTRIBUTE_LOCALES = "locales";
static final String ATTRIBUTE_XDPI = "Xdpi";
static final String ATTRIBUTE_YDPI = "Ydpi";
static final String ATTRIBUTE_TOUCH = "touch";
static final String ATTRIBUTE_NAVIGATION = "navigation";
static final String ATTRIBUTE_KEYPAD = "keypad";
static final String ATTRIBUTE_NETWORK = "network";
static final String ATTRIBUTE_IMEI = "imei";
static final String ATTRIBUTE_IMSI = "imsi";
static final String ATTRIBUTE_BUILD_NAME = "buildName";
static final String ATTRIBUTE_PASS = "pass";
static final String ATTRIBUTE_FAILED = "failed";
static final String ATTRIBUTE_TIMEOUT = "timeout";
static final String ATTRIBUTE_NOT_EXECUTED = "notExecuted";
static final String TAG_DEVICEINFO = "DeviceInfo";
static final String TAG_SUMMARY = "Summary";
static final String TAG_SCREEN = "Screen";
static final String TAG_BUILD_INFO = "BuildInfo";
static final String TAG_PHONE_SUB_INFO = "PhoneSubInfo";
static final String TAG_TESTPACKAGE = "TestPackage";
static final String TAG_TESTSUITE = "TestSuite";
static final String TAG_TESTCASE = "TestCase";
static final String TAG_FAILED_SCENE = "FailedScene";
static final String TAG_STACK_TRACE = "StackTrace";
static final String TAG_FAILED_MESSAGE = "message";
private Collection<TestPackage> mTestPackages;
private Date mSessionStartTime;
private Date mSessionEndTime;
private String mResultPath;
private int mResultFormat;
private String mTestPlanName;
private ArrayList<DeviceParameterCollector> mDeviceParameterBase;
public TestSessionLog(final Collection<TestPackage> packages, final String testPlanName) {
mTestPackages = packages;
mResultFormat = CTS_RESULT_FORMAT_XML;
mDeviceParameterBase = new ArrayList<TestDevice.DeviceParameterCollector>();
mTestPlanName = testPlanName;
mSessionStartTime = new Date();
mSessionEndTime = new Date();
}
/**
* Get the test plan name.
*
* @return The test plan name.
*/
public String getTestPlanName() {
return mTestPlanName;
}
/**
* Get all result of this session.
*
* @return All the tests with a result code of this session.
*/
public Collection<Test> getAllResults() {
if (mTestPackages == null || mTestPackages.size() == 0) {
return null;
}
ArrayList<Test> results = new ArrayList<Test>();
for (TestPackage p : mTestPackages) {
results.addAll(p.getTests());
}
return results;
}
/**
* Get test list according to the result type code.
*
* @param resCode The result code.
* @return The list of {@link Test}.
*/
public Collection<Test> getTestList(int resCode) {
if (resCode < CTS_RESULT_CODE_FIRST || resCode > CTS_RESULT_CODE_LAST) {
return null;
}
ArrayList<Test> results = new ArrayList<Test>();
for (Test res : getAllResults()) {
if (resCode == res.getResultCode()) {
results.add(res);
}
}
return results;
}
/**
* Get TestSession start time
*
* @return The start time.
*/
public Date getStartTime() {
return mSessionStartTime;
}
/**
* Get TestSession end time
*
* @return The end time.
*/
public Date getEndTime() {
return mSessionEndTime;
}
/**
* Get test packages.
*
* @return The test packages.
*/
public Collection<TestPackage> getTestPackages() {
return mTestPackages;
}
/**
* Get the result path.
*
* @return The result path.
*/
public String getResultPath() {
return mResultPath;
}
/**
* set TestSession start time
*
* @param time The start time.
*/
public void setStartTime(final long time) {
mSessionStartTime.setTime(time);
String startTimeStr = HostUtils.getFormattedTimeString(time, "_", ".", ".");
mResultPath = HostConfig.getInstance().getResultRepository().getRoot()
+ File.separator + startTimeStr + "_" + CTS_RESULT_FILE_NAME;
}
/**
* set TestSession end time
*
* @param time The end time.
*/
public void setEndTime(final long time) {
mSessionEndTime.setTime(time);
}
/**
* Dump result to file.
*/
public void dumpToFile() {
switch (mResultFormat) {
case CTS_RESULT_FORMAT_XML:
try {
writeToFile(new File(mResultPath), createResultDoc());
} catch (Exception e) {
Log.e("Got exception when trying to write to result file", e);
}
break;
default:
Log.e("Unrecognized result format" + mResultFormat, null);
break;
}
}
/**
* Create result Doc in XML format.
*
* @return Result document.
*/
protected Document createResultDoc() {
try {
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
ProcessingInstruction pr = doc.createProcessingInstruction(
"xml-stylesheet", "type=\"text/xsl\" href=\"cts_result.xsl\"");
doc.appendChild(pr);
Node root = doc.createElement("TestResult");
doc.appendChild(root);
setAttribute(doc, root, ATTRIBUTE_VERSION, "1.0");
setAttribute(doc, root, ATTRIBUTE_STARTTIME, mSessionStartTime.toString());
setAttribute(doc, root, ATTRIBUTE_ENDTIME, mSessionEndTime.toString());
setAttribute(doc, root, ATTRIBUTE_TESTPLAN, mTestPlanName);
// set device information
for (int i = 0; i < mDeviceParameterBase.size(); i ++) {
DeviceParameterCollector bldInfo = mDeviceParameterBase.get(i);
// set device setting
Node deviceSettingNode = doc.createElement(TAG_DEVICEINFO);
Node screenNode = doc.createElement(TAG_SCREEN);
setAttribute(doc, screenNode, ATTRIBUTE_RESOLUTION, bldInfo.getScreenResolution());
deviceSettingNode.appendChild(screenNode);
Node simCardNode = doc.createElement(TAG_PHONE_SUB_INFO);
setAttribute(doc, simCardNode, ATTRIBUTE_SUBSCRIBER_ID, bldInfo.getPhoneNumber());
deviceSettingNode.appendChild(simCardNode);
root.appendChild(deviceSettingNode);
Node devInfoNode = doc.createElement(TAG_BUILD_INFO);
setAttribute(doc, devInfoNode, ATTRIBUTE_DEVICE_ID, bldInfo.getSerialNumber());
setAttribute(doc, devInfoNode, ATTRIBUTE_BUILD_ID, bldInfo.getBuildId());
setAttribute(doc, devInfoNode, ATTRIBUTE_BUILD_NAME, bldInfo.getProductName());
setAttribute(doc, devInfoNode, ATTRIBUTE_BUILD_VERSION,
bldInfo.getBuildVersion());
setAttribute(doc, devInfoNode, ATTRIBUTE_ANDROID_PLATFORM_VERSION,
bldInfo.getAndroidPlatformVersion());
setAttribute(doc, devInfoNode, ATTRIBUTE_LOCALES, bldInfo.getLocales());
setAttribute(doc, devInfoNode, ATTRIBUTE_XDPI, bldInfo.getXdpi());
setAttribute(doc, devInfoNode, ATTRIBUTE_YDPI, bldInfo.getYdpi());
setAttribute(doc, devInfoNode, ATTRIBUTE_TOUCH, bldInfo.getTouchInfo());
setAttribute(doc, devInfoNode, ATTRIBUTE_NAVIGATION, bldInfo.getNavigation());
setAttribute(doc, devInfoNode, ATTRIBUTE_KEYPAD, bldInfo.getKeypad());
setAttribute(doc, devInfoNode, ATTRIBUTE_NETWORK, bldInfo.getNetwork());
setAttribute(doc, devInfoNode, ATTRIBUTE_IMEI, bldInfo.getIMEI());
setAttribute(doc, devInfoNode, ATTRIBUTE_IMSI, bldInfo.getIMSI());
setAttribute(doc, devInfoNode,
DeviceParameterCollector.BUILD_FINGERPRINT, bldInfo.getBuildFingerPrint());
setAttribute(doc, devInfoNode,
DeviceParameterCollector.BUILD_TYPE, bldInfo.getBuildType());
setAttribute(doc, devInfoNode,
DeviceParameterCollector.BUILD_MODEL, bldInfo.getBuildModel());
setAttribute(doc, devInfoNode,
DeviceParameterCollector.BUILD_BRAND, bldInfo.getBuildBrand());
setAttribute(doc, devInfoNode,
DeviceParameterCollector.BUILD_BOARD, bldInfo.getBuildBoard());
setAttribute(doc, devInfoNode,
DeviceParameterCollector.BUILD_DEVICE, bldInfo.getBuildDevice());
deviceSettingNode.appendChild(devInfoNode);
}
int passNum = getTestList(CTS_RESULT_CODE_PASS).size();
int failNum = getTestList(CTS_RESULT_CODE_FAIL).size();
int notExecutedNum = getTestList(CTS_RESULT_CODE_NOT_EXECUTED).size();
int timeOutNum = getTestList(CTS_RESULT_CODE_TIMEOUT).size();
Node summaryNode = doc.createElement(TAG_SUMMARY);
root.appendChild(summaryNode);
setAttribute(doc, summaryNode, ATTRIBUTE_PASS, passNum);
setAttribute(doc, summaryNode, ATTRIBUTE_FAILED, failNum);
setAttribute(doc, summaryNode, ATTRIBUTE_NOT_EXECUTED, notExecutedNum);
setAttribute(doc, summaryNode, ATTRIBUTE_TIMEOUT, timeOutNum);
for (TestPackage testPackage : mTestPackages) {
Node testPackageNode = doc.createElement(TAG_TESTPACKAGE);
setAttribute(doc, testPackageNode, ATTRIBUTE_NAME, testPackage.getAppPackageName());
setAttribute(doc, testPackageNode, ATTRIBUTE_DIGEST,
testPackage.getMessageDigest());
if (testPackage instanceof SignatureCheckPackage) {
setAttribute(doc, testPackageNode,
TestSessionBuilder.ATTRIBUTE_SIGNATURE_CHECK, "true");
}
for (TestSuite testSuite : testPackage.getTestSuites()) {
outputTestSuite(doc, testPackage, testPackageNode, testSuite);
}
root.appendChild(testPackageNode);
}
return doc;
} catch (Exception e) {
Log.e("create result doc failed", e);
}
return null;
}
/**
* Output TestSuite and result to XML DOM Document.
*
* @param doc The document.
* @param parentNode The parent node.
* @param testSuite The test suite.
*/
private void outputTestSuite(final Document doc,
final TestPackage testPackage, final Node parentNode,
TestSuite testSuite) {
Collection<TestSuite> subSuites = testSuite.getSubSuites();
Collection<TestCase> testCases = testSuite.getTestCases();
Node testSuiteNode = doc.createElement(TAG_TESTSUITE);
setAttribute(doc, testSuiteNode, ATTRIBUTE_NAME, testSuite.getName());
for (TestCase testCase : testCases) {
Node testCaseNode = doc.createElement(TAG_TESTCASE);
testSuiteNode.appendChild(testCaseNode);
setAttribute(doc, testCaseNode, ATTRIBUTE_NAME, testCase.getName());
setAttribute(doc, testCaseNode, TestSessionBuilder.ATTRIBUTE_PRIORITY,
testCase.getPriority());
Collection<Test> tests = testCase.getTests();
for (Test test : tests) {
Node testNode = doc.createElement(TestSessionBuilder.TAG_TEST);
testCaseNode.appendChild(testNode);
if (test.isKnownFailure()) {
setAttribute(doc, testNode, ATTRIBUTE_KNOWN_FAILURE, test.getKnownFailure());
}
setAttribute(doc, testNode, ATTRIBUTE_NAME, test.getName());
setAttribute(doc, testNode, ATTRIBUTE_RESULT, test.getResultStr());
setAttribute(doc, testNode, ATTRIBUTE_STARTTIME,
new Date(test.getStartTime()).toString());
setAttribute(doc, testNode, ATTRIBUTE_ENDTIME,
new Date(test.getEndTime()).toString());
String failedMessage = test.getFailedMessage();
if (failedMessage != null) {
Node failedMessageNode = doc.createElement(TAG_FAILED_SCENE);
testNode.appendChild(failedMessageNode);
setAttribute(doc, failedMessageNode,TAG_FAILED_MESSAGE, failedMessage);
String stackTrace = test.getStackTrace();
if (stackTrace != null) {
Node stackTraceNode = doc.createElement(TAG_STACK_TRACE);
failedMessageNode.appendChild(stackTraceNode);
Node stackTraceTextNode = doc.createTextNode(stackTrace);
stackTraceNode.appendChild(stackTraceTextNode);
}
}
}
}
for (TestSuite subSuite : subSuites) {
outputTestSuite(doc, testPackage, testSuiteNode, subSuite);
parentNode.appendChild(testSuiteNode);
}
parentNode.appendChild(testSuiteNode);
}
/**
* Fetch failed file name and line number
*
* @param failedResult failed message
* @return failed file name and line number
*/
public final static String[] getFailedLineNumber(final String failedResult) {
Matcher m = mTestFailedPattern.matcher(failedResult);
if (m.matches()) {
return new String[]{m.group(1), m.group(2)};
}
return null;
}
/**
* set the device information of a specific device
*
* @param dInfo The device information.
*/
public void setDeviceInfo(final TestDevice.DeviceParameterCollector dInfo) {
mDeviceParameterBase.add(dInfo);
}
/**
* Get the test result as string. Just translate result code to readable string.
* @param resultCode The result code.
* @return The readable result string.
*/
public static String getResultString(final int resultCode) {
return sCodeToResultMap.get(resultCode);
}
}