| /* |
| * Copyright (C) 2011 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.tradefed.result; |
| |
| import com.android.tradefed.result.TestResult; |
| import com.android.tradefed.result.TestResult.TestStatus; |
| |
| import org.kxml2.io.KXmlSerializer; |
| |
| import java.io.IOException; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| |
| /** |
| * Data structure that represents a "TestCase" XML element and its children. |
| */ |
| class TestCase { |
| |
| private final String mName; |
| |
| Map<String, TestResult> mChildTestMap = new LinkedHashMap<String, TestResult>(); |
| |
| /** |
| * Create a {@link TestCase} |
| * @param testCaseName |
| */ |
| public TestCase(String testCaseName) { |
| mName = testCaseName; |
| } |
| |
| /** |
| * Inserts given test result |
| * |
| * @param testName |
| * @param testResult |
| */ |
| public void insertTest(String testName, TestResult testResult) { |
| mChildTestMap.put(testName, testResult); |
| } |
| |
| /** |
| * Serialize this object and all its contents to XML. |
| * |
| * @param serializer |
| * @throws IOException |
| */ |
| public void serialize(KXmlSerializer serializer) throws IOException { |
| serializer.startTag(CtsXmlResultReporter.ns, "TestCase"); |
| serializer.attribute(CtsXmlResultReporter.ns, "name", mName); |
| // unused |
| serializer.attribute(CtsXmlResultReporter.ns, "priority", ""); |
| for (Map.Entry<String, TestResult> resultEntry: mChildTestMap.entrySet()) { |
| serializeTestResult(serializer, resultEntry.getKey(), resultEntry.getValue()); |
| } |
| serializer.endTag(CtsXmlResultReporter.ns, "TestCase"); |
| } |
| |
| private void serializeTestResult(KXmlSerializer serializer, String name, TestResult result) |
| throws IOException { |
| serializer.startTag(CtsXmlResultReporter.ns, "Test"); |
| serializer.attribute(CtsXmlResultReporter.ns, "name", name); |
| serializer.attribute(CtsXmlResultReporter.ns, "result", convertStatus(result.getStatus())); |
| serializer.attribute(CtsXmlResultReporter.ns, "starttime", TimeUtil.getTimestamp( |
| result.getStartTime())); |
| serializer.attribute(CtsXmlResultReporter.ns, "endtime", TimeUtil.getTimestamp( |
| result.getEndTime())); |
| serializer.attribute(CtsXmlResultReporter.ns, "result", convertStatus(result.getStatus())); |
| |
| if (result.getStackTrace() != null) { |
| String sanitizedStack = sanitizeStackTrace(result.getStackTrace()); |
| serializer.startTag(CtsXmlResultReporter.ns, "FailedScene"); |
| serializer.attribute(CtsXmlResultReporter.ns, "message", |
| getFailureMessageFromStackTrace(sanitizedStack)); |
| serializer.text(sanitizedStack); |
| serializer.endTag(CtsXmlResultReporter.ns, "FailedScene"); |
| } |
| |
| serializer.endTag(CtsXmlResultReporter.ns, "Test"); |
| |
| } |
| |
| /** |
| * Convert a {@link TestStatus} to the result text to output in XML |
| * |
| * @param status the {@link TestStatus} |
| * @return |
| */ |
| private String convertStatus(TestStatus status) { |
| switch (status) { |
| case ERROR: |
| return "fail"; |
| case FAILURE: |
| return "fail"; |
| case PASSED: |
| return "pass"; |
| // TODO add notExecuted |
| } |
| return "fail"; |
| } |
| |
| /** |
| * Strip out any invalid XML characters that might cause the report to be unviewable. |
| * http://www.w3.org/TR/REC-xml/#dt-character |
| */ |
| private static String sanitizeStackTrace(String trace) { |
| if (trace != null) { |
| return trace.replaceAll("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD]", ""); |
| } else { |
| return null; |
| } |
| } |
| |
| private static String getFailureMessageFromStackTrace(String stack) { |
| // This is probably too simplistic to work in all cases, but for now, just return first |
| // line of stack as failure message |
| int firstNewLine = stack.indexOf('\n'); |
| if (firstNewLine != -1) { |
| return stack.substring(0, firstNewLine); |
| } |
| return stack; |
| } |
| } |