1#!/usr/bin/env python
2#
3# Copyright (C) 2012 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the 'License');
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an 'AS IS' BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17import os
18import sys
19from xml.dom import Node
20from xml.dom import minidom
21
22def getChildrenWithTag(parent, tagName):
23    children = []
24    for child in  parent.childNodes:
25        if (child.nodeType == Node.ELEMENT_NODE) and (child.tagName == tagName):
26            #print "parent " + parent.getAttribute("name") + " " + tagName +\
27            #    " " + child.getAttribute("name")
28            children.append(child)
29    return children
30
31def parseSuite(suite, parentName):
32    if parentName != "":
33        parentName += '.'
34    failedCases = []
35    childSuites = getChildrenWithTag(suite, "TestSuite")
36    for child in childSuites:
37        for failure in parseSuite(child, parentName + child.getAttribute("name")):
38            failedCases.append(failure)
39    childTestCases = getChildrenWithTag(suite, "TestCase")
40    for child in childTestCases:
41        className = parentName + child.getAttribute("name")
42        for test in getChildrenWithTag(child, "Test"):
43            if test.getAttribute("result") != "pass":
44                failureName = className + "#" + test.getAttribute("name")
45                failedCases.append(failureName)
46    #if len(failedCases) > 0:
47    #    print failedCases
48    return failedCases
49
50def getFailedCases(resultXml):
51    failedCases = []
52    doc = minidom.parse(resultXml)
53    testResult = doc.getElementsByTagName("TestResult")[0]
54    packages = getChildrenWithTag(testResult, "TestPackage")
55    for package in packages:
56        casesFromChild = parseSuite(package, "")
57        for case in casesFromChild:
58            if case not in failedCases:
59                failedCases.append(case)
60
61    return failedCases
62
63def main(argv):
64    if len(argv) < 3:
65        print "rerun.py cts_path result_xml [-s serial]"
66        print " cts_path should end with android-cts"
67        sys.exit(1)
68    ctsPath = os.path.abspath(argv[1])
69    resultXml = os.path.abspath(argv[2])
70    deviceSerial = ""
71    if len(argv) > 3:
72        if argv[3] == "-s":
73            deviceSerial = argv[4]
74
75    failedCases = getFailedCases(resultXml)
76    print "Re-run follwong cases:"
77    for failure in failedCases:
78        print " " + failure
79    for failure in failedCases:
80        [className, methodName] = failure.split('#')
81        command = ctsPath + "/tools/cts-tradefed run singleCommand cts"
82        if deviceSerial != "":
83            command += " --serial " + deviceSerial
84        command += " --class " + className + " --method " + methodName
85        print command
86        os.system(command)
87
88if __name__ == '__main__':
89    main(sys.argv)
90