xref: /freebsd/contrib/ntp/sntp/unity/auto/parseOutput.rb (revision a466cc55373fc3cf86837f09da729535b57e69a1)
1*9034852cSGleb Smirnoff#============================================================
2*9034852cSGleb Smirnoff#  Author:   John Theofanopoulos
3*9034852cSGleb Smirnoff#  A simple parser.   Takes the output files generated during the build process and
4*9034852cSGleb Smirnoff# extracts information relating to the tests.
5*9034852cSGleb Smirnoff#
6*9034852cSGleb Smirnoff#  Notes:
7*9034852cSGleb Smirnoff#    To capture an output file under VS builds use the following:
8*9034852cSGleb Smirnoff#      devenv [build instructions]  > Output.txt & type Output.txt
9*9034852cSGleb Smirnoff#
10*9034852cSGleb Smirnoff#    To capture an output file under GCC/Linux builds use the following:
11*9034852cSGleb Smirnoff#      make | tee Output.txt
12*9034852cSGleb Smirnoff#
13*9034852cSGleb Smirnoff#    To use this parser use the following command
14*9034852cSGleb Smirnoff#    ruby parseOutput.rb [options] [file]
15*9034852cSGleb Smirnoff#        options:  -xml  : produce a JUnit compatible XML file
16*9034852cSGleb Smirnoff#        file      :  file to scan for results
17*9034852cSGleb Smirnoff#============================================================
18*9034852cSGleb Smirnoff
19*9034852cSGleb Smirnoff
20*9034852cSGleb Smirnoffclass ParseOutput
21*9034852cSGleb Smirnoff# The following flag is set to true when a test is found or false otherwise.
22*9034852cSGleb Smirnoff    @testFlag
23*9034852cSGleb Smirnoff    @xmlOut
24*9034852cSGleb Smirnoff    @arrayList
25*9034852cSGleb Smirnoff    @totalTests
26*9034852cSGleb Smirnoff    @classIndex
27*9034852cSGleb Smirnoff
28*9034852cSGleb Smirnoff#   Set the flag to indicate if there will be an XML output file or not
29*9034852cSGleb Smirnoff    def setXmlOutput()
30*9034852cSGleb Smirnoff        @xmlOut = true
31*9034852cSGleb Smirnoff    end
32*9034852cSGleb Smirnoff
33*9034852cSGleb Smirnoff#  if write our output to XML
34*9034852cSGleb Smirnoff    def writeXmlOuput()
35*9034852cSGleb Smirnoff            output = File.open("report.xml", "w")
36*9034852cSGleb Smirnoff            output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
37*9034852cSGleb Smirnoff            @arrayList.each do |item|
38*9034852cSGleb Smirnoff                output << item << "\n"
39*9034852cSGleb Smirnoff            end
40*9034852cSGleb Smirnoff            output << "</testsuite>\n"
41*9034852cSGleb Smirnoff    end
42*9034852cSGleb Smirnoff
43*9034852cSGleb Smirnoff#  This function will try and determine when the suite is changed.   This is
44*9034852cSGleb Smirnoff# is the name that gets added to the classname parameter.
45*9034852cSGleb Smirnoff    def  testSuiteVerify(testSuiteName)
46*9034852cSGleb Smirnoff        if @testFlag == false
47*9034852cSGleb Smirnoff            @testFlag = true;
48*9034852cSGleb Smirnoff            # Split the path name
49*9034852cSGleb Smirnoff            testName = testSuiteName.split("/")
50*9034852cSGleb Smirnoff            # Remove the extension
51*9034852cSGleb Smirnoff            baseName = testName[testName.size - 1].split(".")
52*9034852cSGleb Smirnoff            @testSuite = "test." + baseName[0]
53*9034852cSGleb Smirnoff            printf "New Test: %s\n", @testSuite
54*9034852cSGleb Smirnoff        end
55*9034852cSGleb Smirnoff    end
56*9034852cSGleb Smirnoff
57*9034852cSGleb Smirnoff
58*9034852cSGleb Smirnoff# Test was flagged as having passed so format the output
59*9034852cSGleb Smirnoff    def testPassed(array)
60*9034852cSGleb Smirnoff        lastItem = array.length - 1
61*9034852cSGleb Smirnoff        testName = array[lastItem - 1]
62*9034852cSGleb Smirnoff        testSuiteVerify(array[@className])
63*9034852cSGleb Smirnoff        printf "%-40s PASS\n", testName
64*9034852cSGleb Smirnoff        if @xmlOut == true
65*9034852cSGleb Smirnoff            @arrayList.push "     <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\"/>"
66*9034852cSGleb Smirnoff        end
67*9034852cSGleb Smirnoff    end
68*9034852cSGleb Smirnoff
69*9034852cSGleb Smirnoff# Test was flagged as being ingored so format the output
70*9034852cSGleb Smirnoff    def testIgnored(array)
71*9034852cSGleb Smirnoff        lastItem = array.length - 1
72*9034852cSGleb Smirnoff        testName = array[lastItem - 2]
73*9034852cSGleb Smirnoff        reason = array[lastItem].chomp
74*9034852cSGleb Smirnoff        testSuiteVerify(array[@className])
75*9034852cSGleb Smirnoff        printf "%-40s IGNORED\n", testName
76*9034852cSGleb Smirnoff        if @xmlOut == true
77*9034852cSGleb Smirnoff            @arrayList.push "     <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\">"
78*9034852cSGleb Smirnoff            @arrayList.push "            <skipped type=\"TEST IGNORED\"> " + reason + " </skipped>"
79*9034852cSGleb Smirnoff            @arrayList.push "     </testcase>"
80*9034852cSGleb Smirnoff        end
81*9034852cSGleb Smirnoff    end
82*9034852cSGleb Smirnoff
83*9034852cSGleb Smirnoff# Test was flagged as having failed  so format the line
84*9034852cSGleb Smirnoff    def testFailed(array)
85*9034852cSGleb Smirnoff        lastItem = array.length - 1
86*9034852cSGleb Smirnoff        testName = array[lastItem - 2]
87*9034852cSGleb Smirnoff        reason = array[lastItem].chomp + " at line: " + array[lastItem - 3]
88*9034852cSGleb Smirnoff        testSuiteVerify(array[@className])
89*9034852cSGleb Smirnoff        printf "%-40s FAILED\n", testName
90*9034852cSGleb Smirnoff        if @xmlOut == true
91*9034852cSGleb Smirnoff            @arrayList.push "     <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\">"
92*9034852cSGleb Smirnoff            @arrayList.push "            <failure type=\"ASSERT FAILED\"> " + reason + " </failure>"
93*9034852cSGleb Smirnoff            @arrayList.push "     </testcase>"
94*9034852cSGleb Smirnoff        end
95*9034852cSGleb Smirnoff    end
96*9034852cSGleb Smirnoff
97*9034852cSGleb Smirnoff
98*9034852cSGleb Smirnoff# Figure out what OS we are running on.   For now we are assuming if it's not Windows it must
99*9034852cSGleb Smirnoff# be Unix based.
100*9034852cSGleb Smirnoff    def detectOS()
101*9034852cSGleb Smirnoff        myOS = RUBY_PLATFORM.split("-")
102*9034852cSGleb Smirnoff        if myOS.size == 2
103*9034852cSGleb Smirnoff            if myOS[1] == "mingw32"
104*9034852cSGleb Smirnoff                @className = 1
105*9034852cSGleb Smirnoff            else
106*9034852cSGleb Smirnoff                @className = 0
107*9034852cSGleb Smirnoff            end
108*9034852cSGleb Smirnoff	else
109*9034852cSGleb Smirnoff                @className = 0
110*9034852cSGleb Smirnoff        end
111*9034852cSGleb Smirnoff
112*9034852cSGleb Smirnoff    end
113*9034852cSGleb Smirnoff
114*9034852cSGleb Smirnoff# Main function used to parse the file that was captured.
115*9034852cSGleb Smirnoff    def process(name)
116*9034852cSGleb Smirnoff        @testFlag = false
117*9034852cSGleb Smirnoff        @arrayList = Array.new
118*9034852cSGleb Smirnoff
119*9034852cSGleb Smirnoff        detectOS()
120*9034852cSGleb Smirnoff
121*9034852cSGleb Smirnoff        puts "Parsing file: " + name
122*9034852cSGleb Smirnoff
123*9034852cSGleb Smirnoff
124*9034852cSGleb Smirnoff        testPass = 0
125*9034852cSGleb Smirnoff        testFail = 0
126*9034852cSGleb Smirnoff        testIgnore = 0
127*9034852cSGleb Smirnoff        puts ""
128*9034852cSGleb Smirnoff        puts "=================== RESULTS ====================="
129*9034852cSGleb Smirnoff        puts ""
130*9034852cSGleb Smirnoff        File.open(name).each do |line|
131*9034852cSGleb Smirnoff        # Typical test lines look like this:
132*9034852cSGleb Smirnoff        # <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0
133*9034852cSGleb Smirnoff        # <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented
134*9034852cSGleb Smirnoff        # <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS
135*9034852cSGleb Smirnoff        #
136*9034852cSGleb Smirnoff        # where path is different on Unix vs Windows devices (Windows leads with a drive letter)
137*9034852cSGleb Smirnoff            lineArray = line.split(":")
138*9034852cSGleb Smirnoff            lineSize = lineArray.size
139*9034852cSGleb Smirnoff            # If we were able to split the line then we can look to see if any of our target words
140*9034852cSGleb Smirnoff            # were found.  Case is important.
141*9034852cSGleb Smirnoff            if lineSize >= 4
142*9034852cSGleb Smirnoff                # Determine if this test passed
143*9034852cSGleb Smirnoff                if  line.include? ":PASS"
144*9034852cSGleb Smirnoff                    testPassed(lineArray)
145*9034852cSGleb Smirnoff                    testPass += 1
146*9034852cSGleb Smirnoff                elsif line.include? ":FAIL:"
147*9034852cSGleb Smirnoff                    testFailed(lineArray)
148*9034852cSGleb Smirnoff                    testFail += 1
149*9034852cSGleb Smirnoff                elsif line.include? ":IGNORE:"
150*9034852cSGleb Smirnoff                    testIgnored(lineArray)
151*9034852cSGleb Smirnoff                    testIgnore += 1
152*9034852cSGleb Smirnoff                # If none of the keywords are found there are no more tests for this suite so clear
153*9034852cSGleb Smirnoff                # the test flag
154*9034852cSGleb Smirnoff                else
155*9034852cSGleb Smirnoff                    @testFlag = false
156*9034852cSGleb Smirnoff                end
157*9034852cSGleb Smirnoff            else
158*9034852cSGleb Smirnoff                @testFlag = false
159*9034852cSGleb Smirnoff                end
160*9034852cSGleb Smirnoff            end
161*9034852cSGleb Smirnoff        puts ""
162*9034852cSGleb Smirnoff        puts "=================== SUMMARY ====================="
163*9034852cSGleb Smirnoff        puts ""
164*9034852cSGleb Smirnoff        puts "Tests Passed  : " + testPass.to_s
165*9034852cSGleb Smirnoff        puts "Tests Failed  : " + testFail.to_s
166*9034852cSGleb Smirnoff        puts "Tests Ignored : " + testIgnore.to_s
167*9034852cSGleb Smirnoff        @totalTests = testPass + testFail + testIgnore
168*9034852cSGleb Smirnoff        if @xmlOut == true
169*9034852cSGleb Smirnoff            heading = "<testsuite tests=\"" +  @totalTests.to_s  + "\" failures=\"" + testFail.to_s + "\""  + " skips=\"" +  testIgnore.to_s + "\">"
170*9034852cSGleb Smirnoff            @arrayList.insert(0, heading)
171*9034852cSGleb Smirnoff            writeXmlOuput()
172*9034852cSGleb Smirnoff        end
173*9034852cSGleb Smirnoff
174*9034852cSGleb Smirnoff    #  return result
175*9034852cSGleb Smirnoff    end
176*9034852cSGleb Smirnoff
177*9034852cSGleb Smirnoff end
178*9034852cSGleb Smirnoff
179*9034852cSGleb Smirnoff# If the command line has no values in, used a default value of Output.txt
180*9034852cSGleb SmirnoffparseMyFile = ParseOutput.new
181*9034852cSGleb Smirnoff
182*9034852cSGleb Smirnoffif ARGV.size >= 1
183*9034852cSGleb Smirnoff    ARGV.each do |a|
184*9034852cSGleb Smirnoff        if a == "-xml"
185*9034852cSGleb Smirnoff            parseMyFile.setXmlOutput();
186*9034852cSGleb Smirnoff        else
187*9034852cSGleb Smirnoff            parseMyFile.process(a)
188*9034852cSGleb Smirnoff            break
189*9034852cSGleb Smirnoff        end
190*9034852cSGleb Smirnoff    end
191*9034852cSGleb Smirnoffend
192