blob: 73096cb04e0e8d673e38c71f8535299560254039 [file] [log] [blame]
/*
* Copyright (C) 2019 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.compatibility.common.util;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.Serializable;
import java.util.Objects;
import java.util.Set;
/**
* Utility class to add test case result history to the report. This class records per-case history
* for CTS Verifier. If this field is used for large test suites like CTS, it may cause performance
* issues in APFE. Thus please do not use this class in other test suites.
*/
public class TestResultHistory implements Serializable {
private static final long serialVersionUID = 10L;
private static final String ENCODING = "UTF-8";
private static final String TYPE = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
// XML constants
private static final String SUB_TEST_ATTR = "subtest";
private static final String RUN_HISTORY_TAG = "RunHistory";
private static final String RUN_TAG = "Run";
private static final String START_TIME_ATTR = "start";
private static final String END_TIME_ATTR = "end";
private static final String IS_AUTOMATED_ATTR = "isAutomated";
private final String mTestName;
private final Set<ExecutionRecord> mExecutionRecords;
/**
* Constructor of test result history.
*
* @param testName a string of test name.
* @param executionRecords a Set of ExecutionRecords.
*/
public TestResultHistory(String testName, Set<ExecutionRecord> executionRecords) {
this.mTestName = testName;
this.mExecutionRecords = executionRecords;
}
/** Get test name */
public String getTestName() {
return mTestName;
}
/** Get a set of ExecutionRecords. */
public Set<ExecutionRecord> getExecutionRecords() {
return mExecutionRecords;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TestResultHistory that = (TestResultHistory) o;
return Objects.equals(mTestName, that.mTestName)
&& Objects.equals(mExecutionRecords, that.mExecutionRecords);
}
/** {@inheritDoc} */
@Override
public int hashCode() {
return Objects.hash(mTestName, mExecutionRecords);
}
/**
* Serializes a given {@link TestResultHistory} to XML.
*
* @param serializer given serializer.
* @param resultHistory test result history with test name and execution record.
* @param testName top-level test name.
* @throws IOException
*/
public static void serialize(
XmlSerializer serializer, TestResultHistory resultHistory, String testName)
throws IOException {
if (resultHistory == null) {
throw new IllegalArgumentException("Test result history was null");
}
serializer.startTag(null, RUN_HISTORY_TAG);
// Only show sub-test names in test attribute in run history node.
String name = getSubTestName(testName, resultHistory.getTestName());
if (!name.isEmpty() && !name.equalsIgnoreCase(testName)) {
serializer.attribute(null, SUB_TEST_ATTR, name);
}
for (ExecutionRecord execRecord : resultHistory.getExecutionRecords()) {
serializer.startTag(null, RUN_TAG);
serializer.attribute(null, START_TIME_ATTR, String.valueOf(execRecord.getStartTime()));
serializer.attribute(null, END_TIME_ATTR, String.valueOf(execRecord.getEndTime()));
serializer.attribute(
null, IS_AUTOMATED_ATTR, String.valueOf(execRecord.getIsAutomated()));
serializer.endTag(null, RUN_TAG);
}
serializer.endTag(null, RUN_HISTORY_TAG);
}
/**
* Get subtest name by replacing top-level test name.
*
* @param testName top-level test name.
* @param fullTestName test name with the combination of top-level and subtest name.
* @return subtest name without top-level test name
*/
protected static String getSubTestName(String testName, String fullTestName) {
// Handle test name with brackets, like [folded] as the suffix for foldable test plan.
testName = testName.replace("[", "\\[").replace("]", "\\]");
String subTestName = fullTestName.replaceFirst(testName + ":", "");
return subTestName;
}
/** Execution Record about start time, end time and isAutomated */
public static class ExecutionRecord implements Serializable {
private static final long serialVersionUID = 0L;
// Start time of test case.
private final long startTime;
// End time of test case.
private final long endTime;
// Whether test case was executed through automation.
private final boolean isAutomated;
public ExecutionRecord(long startTime, long endTime, boolean isAutomated) {
this.startTime = startTime;
this.endTime = endTime;
this.isAutomated = isAutomated;
}
public long getStartTime() {
return startTime;
}
public long getEndTime() {
return endTime;
}
public boolean getIsAutomated() {
return isAutomated;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ExecutionRecord that = (ExecutionRecord) o;
return startTime == that.startTime
&& endTime == that.endTime
&& isAutomated == that.isAutomated;
}
@Override
public int hashCode() {
return Objects.hash(startTime, endTime, isAutomated);
}
}
}