Home | History | Annotate | Download | only in result
      1 /*
      2  * Copyright (C) 2011 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.ddmlib.testrunner.TestIdentifier;
     19 import com.android.tradefed.result.TestResult;
     20 
     21 import org.kxml2.io.KXmlSerializer;
     22 import org.xmlpull.v1.XmlPullParser;
     23 import org.xmlpull.v1.XmlPullParserException;
     24 
     25 import java.io.IOException;
     26 import java.util.Collection;
     27 import java.util.Deque;
     28 import java.util.LinkedHashMap;
     29 import java.util.List;
     30 import java.util.Map;
     31 
     32 /**
     33  * Data structure that represents a "TestSuite" XML element and its children.
     34  */
     35 class TestSuite extends AbstractXmlPullParser {
     36 
     37     static final String TAG = "TestSuite";
     38 
     39     private String mName;
     40 
     41     // use linked hash map for predictable iteration order
     42     Map<String, TestSuite> mChildSuiteMap = new LinkedHashMap<String, TestSuite>();
     43     Map<String, TestCase> mChildTestCaseMap = new LinkedHashMap<String, TestCase>();
     44 
     45     /**
     46      * @param testSuite
     47      */
     48     public TestSuite(String suiteName) {
     49         mName = suiteName;
     50     }
     51 
     52     public TestSuite() {
     53     }
     54 
     55     /**
     56      * @return the name of this suite
     57      */
     58     public String getName() {
     59         return mName;
     60     }
     61 
     62     /**
     63      * Set the name of this suite
     64      */
     65     public void setName(String name) {
     66         mName = name;
     67     }
     68 
     69     /**
     70      * Insert the given test result into this suite.
     71      *
     72      * @param suiteNames list of remaining suite names for this test
     73      * @param testClassName the test class name
     74      * @param testName the test method name
     75      * @param testResult the {@link TestResult}
     76      */
     77     public Test findTest(List<String> suiteNames, String testClassName, String testName,
     78             boolean insertIfMissing) {
     79         if (suiteNames.size() <= 0) {
     80             // no more package segments
     81             TestCase testCase = getTestCase(testClassName);
     82             return testCase.findTest(testName, insertIfMissing);
     83         } else {
     84             String rootName = suiteNames.remove(0);
     85             TestSuite suite = getTestSuite(rootName);
     86             return suite.findTest(suiteNames, testClassName, testName, insertIfMissing);
     87         }
     88     }
     89 
     90     /**
     91      * Gets all the child {@link TestSuite}s
     92      */
     93     public Collection<TestSuite> getTestSuites() {
     94         return mChildSuiteMap.values();
     95     }
     96 
     97     /**
     98      * Gets all the child {@link TestCase}s
     99      */
    100     public Collection<TestCase> getTestCases() {
    101         return mChildTestCaseMap.values();
    102     }
    103 
    104     /**
    105      * Get the child {@link TestSuite} with given name, creating if necessary.
    106      *
    107      * @param suiteName
    108      * @return the {@link TestSuite}
    109      */
    110     private TestSuite getTestSuite(String suiteName) {
    111         TestSuite testSuite = mChildSuiteMap.get(suiteName);
    112         if (testSuite == null) {
    113             testSuite = new TestSuite(suiteName);
    114             mChildSuiteMap.put(suiteName, testSuite);
    115         }
    116         return testSuite;
    117     }
    118 
    119     /**
    120      * Get the child {@link TestCase} with given name, creating if necessary.
    121      * @param testCaseName
    122      * @return
    123      */
    124     private TestCase getTestCase(String testCaseName) {
    125         TestCase testCase = mChildTestCaseMap.get(testCaseName);
    126         if (testCase == null) {
    127             testCase = new TestCase(testCaseName);
    128             mChildTestCaseMap.put(testCaseName, testCase);
    129         }
    130         return testCase;
    131     }
    132 
    133     /**
    134      * Serialize this object and all its contents to XML.
    135      *
    136      * @param serializer
    137      * @throws IOException
    138      */
    139     public void serialize(KXmlSerializer serializer) throws IOException {
    140         if (mName != null) {
    141             serializer.startTag(CtsXmlResultReporter.ns, TAG);
    142             serializer.attribute(CtsXmlResultReporter.ns, "name", mName);
    143         }
    144         for (TestSuite childSuite : mChildSuiteMap.values()) {
    145             childSuite.serialize(serializer);
    146         }
    147         for (TestCase childCase : mChildTestCaseMap.values()) {
    148             childCase.serialize(serializer);
    149         }
    150         if (mName != null) {
    151             serializer.endTag(CtsXmlResultReporter.ns, TAG);
    152         }
    153     }
    154 
    155     /**
    156      * Populates this class with suite result data parsed from XML.
    157      *
    158      * @param parser the {@link XmlPullParser}. Expected to be pointing at start
    159      *            of a TestSuite tag
    160      */
    161     @Override
    162     void parse(XmlPullParser parser) throws XmlPullParserException, IOException {
    163         if (!parser.getName().equals(TAG)) {
    164             throw new XmlPullParserException(String.format(
    165                     "invalid XML: Expected %s tag but received %s", TAG, parser.getName()));
    166         }
    167         setName(getAttribute(parser, "name"));
    168         int eventType = parser.next();
    169         while (eventType != XmlPullParser.END_DOCUMENT) {
    170             if (eventType == XmlPullParser.START_TAG && parser.getName().equals(TestSuite.TAG)) {
    171                 TestSuite suite = new TestSuite();
    172                 suite.parse(parser);
    173                 insertSuite(suite);
    174             } else if (eventType == XmlPullParser.START_TAG && parser.getName().equals(
    175                     TestCase.TAG)) {
    176                 TestCase testCase = new TestCase();
    177                 testCase.parse(parser);
    178                 insertTestCase(testCase);
    179             } else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(TAG)) {
    180                 return;
    181             }
    182             eventType = parser.next();
    183         }
    184     }
    185 
    186     /**
    187      * Adds a child {@link TestCase}.
    188      */
    189     public void insertTestCase(TestCase testCase) {
    190         mChildTestCaseMap.put(testCase.getName(), testCase);
    191     }
    192 
    193     /**
    194      * Adds a child {@link TestSuite}.
    195      */
    196     public void insertSuite(TestSuite suite) {
    197         mChildSuiteMap.put(suite.getName(), suite);
    198     }
    199 
    200 
    201     /**
    202      * Adds tests contained in this result that have the given <var>resultFilter</var>
    203      *
    204      * @param tests the {@link Collection} of {@link TestIdentifier}s to add to
    205      * @param parentSuiteNames a {@link Deque} of parent suite names. Used to construct the full
    206      * class name of the test
    207      * @param resultFilter the {@link CtsTestStatus} to filter by
    208      */
    209     void addTestsWithStatus(Collection<TestIdentifier> tests, Deque<String> parentSuiteNames,
    210             CtsTestStatus resultFilter) {
    211         if (getName() != null) {
    212             parentSuiteNames.addLast(getName());
    213         }
    214         for (TestSuite suite : mChildSuiteMap.values()) {
    215             suite.addTestsWithStatus(tests, parentSuiteNames, resultFilter);
    216         }
    217         for (TestCase testCase : mChildTestCaseMap.values()) {
    218             testCase.addTestsWithStatus(tests, parentSuiteNames, resultFilter);
    219         }
    220         if (getName() != null) {
    221             parentSuiteNames.removeLast();
    222         }
    223     }
    224 
    225     /**
    226      * Count the number of tests in this {@link TestSuite} with given status.
    227      *
    228      * @param status
    229      * @return the test count
    230      */
    231     public int countTests(CtsTestStatus status) {
    232         int total = 0;
    233         for (TestSuite suite : mChildSuiteMap.values()) {
    234             total += suite.countTests(status);
    235         }
    236         for (TestCase testCase : mChildTestCaseMap.values()) {
    237             total += testCase.countTests(status);
    238         }
    239         return total;
    240     }
    241 }
    242