• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
TestSuite(String suiteName)48     public TestSuite(String suiteName) {
49         mName = suiteName;
50     }
51 
TestSuite()52     public TestSuite() {
53     }
54 
55     /**
56      * @return the name of this suite
57      */
getName()58     public String getName() {
59         return mName;
60     }
61 
62     /**
63      * Set the name of this suite
64      */
setName(String name)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      */
findTest(List<String> suiteNames, String testClassName, String testName, boolean insertIfMissing)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      */
getTestSuites()93     public Collection<TestSuite> getTestSuites() {
94         return mChildSuiteMap.values();
95     }
96 
97     /**
98      * Gets all the child {@link TestCase}s
99      */
getTestCases()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      */
getTestSuite(String suiteName)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      */
getTestCase(String testCaseName)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      */
serialize(KXmlSerializer serializer)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
parse(XmlPullParser parser)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      */
insertTestCase(TestCase testCase)189     public void insertTestCase(TestCase testCase) {
190         mChildTestCaseMap.put(testCase.getName(), testCase);
191     }
192 
193     /**
194      * Adds a child {@link TestSuite}.
195      */
insertSuite(TestSuite suite)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      */
addTestsWithStatus(Collection<TestIdentifier> tests, Deque<String> parentSuiteNames, CtsTestStatus resultFilter)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      */
countTests(CtsTestStatus status)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