A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:a7a43371b306 1 # -----------------------------------------------------------------------
ram54288 0:a7a43371b306 2 # Copyright (c) 2016 ARM Limited. All rights reserved.
ram54288 0:a7a43371b306 3 # SPDX-License-Identifier: Apache-2.0
ram54288 0:a7a43371b306 4 # Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:a7a43371b306 5 # not use this file except in compliance with the License.
ram54288 0:a7a43371b306 6 # You may obtain a copy of the License at
ram54288 0:a7a43371b306 7 #
ram54288 0:a7a43371b306 8 # http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:a7a43371b306 9 #
ram54288 0:a7a43371b306 10 # Unless required by applicable law or agreed to in writing, software
ram54288 0:a7a43371b306 11 # distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:a7a43371b306 12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:a7a43371b306 13 # See the License for the specific language governing permissions and
ram54288 0:a7a43371b306 14 # limitations under the License.
ram54288 0:a7a43371b306 15 # -----------------------------------------------------------------------
ram54288 0:a7a43371b306 16
ram54288 0:a7a43371b306 17 import re
ram54288 0:a7a43371b306 18 import sys
ram54288 0:a7a43371b306 19 from tabulate import tabulate
ram54288 0:a7a43371b306 20
ram54288 0:a7a43371b306 21 def extract_tags(logLines):
ram54288 0:a7a43371b306 22
ram54288 0:a7a43371b306 23 # These are the Unity tag names we are going to look for.
ram54288 0:a7a43371b306 24 tagNames = [
ram54288 0:a7a43371b306 25 "UnityTest",
ram54288 0:a7a43371b306 26 "UnityIgnoredTest",
ram54288 0:a7a43371b306 27 "UnityResult",
ram54288 0:a7a43371b306 28 ]
ram54288 0:a7a43371b306 29
ram54288 0:a7a43371b306 30 # All tags will end up here.
ram54288 0:a7a43371b306 31 tags = []
ram54288 0:a7a43371b306 32
ram54288 0:a7a43371b306 33 for tagName in tagNames:
ram54288 0:a7a43371b306 34
ram54288 0:a7a43371b306 35 # Fetch start and end locations for the start and end markers.
ram54288 0:a7a43371b306 36
ram54288 0:a7a43371b306 37 startMatches = re.finditer(re.escape("<***" + tagName + "***>"), logLines)
ram54288 0:a7a43371b306 38 endMatches = re.finditer(re.escape("</***" + tagName + "***>"), logLines)
ram54288 0:a7a43371b306 39
ram54288 0:a7a43371b306 40 startOffsets = [match.end() for match in startMatches]
ram54288 0:a7a43371b306 41 endOffsets = [match.start() - 1 for match in endMatches]
ram54288 0:a7a43371b306 42
ram54288 0:a7a43371b306 43 # If the amount of start and end markers isn't identical, this is an error.
ram54288 0:a7a43371b306 44 if len(startOffsets) != len(endOffsets):
ram54288 0:a7a43371b306 45 raise Exception("For tag '" + tagName + "', start and end tags do not match!")
ram54288 0:a7a43371b306 46
ram54288 0:a7a43371b306 47 # Append all found tags to the tags list.
ram54288 0:a7a43371b306 48 for tagOffsets in zip(startOffsets, endOffsets):
ram54288 0:a7a43371b306 49 tagContent = logLines[tagOffsets[0]: tagOffsets[1] + 1]
ram54288 0:a7a43371b306 50 tags.append((tagOffsets[0], tagName, tagContent))
ram54288 0:a7a43371b306 51
ram54288 0:a7a43371b306 52 # Sort the tags list by the offset.
ram54288 0:a7a43371b306 53 tags.sort(key=lambda tag_: tag_[0])
ram54288 0:a7a43371b306 54
ram54288 0:a7a43371b306 55 # Throw away the offset (once sorted, it is no longer needed).
ram54288 0:a7a43371b306 56 tags = [tag[1:] for tag in tags]
ram54288 0:a7a43371b306 57
ram54288 0:a7a43371b306 58 # At this point we are left with list of tags, each one a pair, consisting of
ram54288 0:a7a43371b306 59 # (group name, test name, status).
ram54288 0:a7a43371b306 60 return tags
ram54288 0:a7a43371b306 61
ram54288 0:a7a43371b306 62 def get_test_group_and_name(printableName):
ram54288 0:a7a43371b306 63 match = re.match(r"TEST\((.*), (.*)\)", printableName)
ram54288 0:a7a43371b306 64 if match is not None:
ram54288 0:a7a43371b306 65 return match.group(1), match.group(2)
ram54288 0:a7a43371b306 66 else:
ram54288 0:a7a43371b306 67 raise Exception("Erorr parsing test group and name")
ram54288 0:a7a43371b306 68
ram54288 0:a7a43371b306 69 def get_ignored_test_group_and_name(printableName):
ram54288 0:a7a43371b306 70 match = re.match(r"IGNORE_TEST\((.*), (.*)\)", printableName)
ram54288 0:a7a43371b306 71 if match is not None:
ram54288 0:a7a43371b306 72 return match.group(1), match.group(2)
ram54288 0:a7a43371b306 73 else:
ram54288 0:a7a43371b306 74 raise Exception("Erorr parsing test group and name")
ram54288 0:a7a43371b306 75
ram54288 0:a7a43371b306 76 def collect_tests(tags):
ram54288 0:a7a43371b306 77
ram54288 0:a7a43371b306 78 tests = []
ram54288 0:a7a43371b306 79
ram54288 0:a7a43371b306 80 # Build the list of tests, with status for each.
ram54288 0:a7a43371b306 81 curTest = ""
ram54288 0:a7a43371b306 82 resultHandled = False
ram54288 0:a7a43371b306 83 for tag in tags:
ram54288 0:a7a43371b306 84
ram54288 0:a7a43371b306 85 tagName = tag[0]
ram54288 0:a7a43371b306 86 tagValue = tag[1]
ram54288 0:a7a43371b306 87
ram54288 0:a7a43371b306 88 if tagName == "UnityTest":
ram54288 0:a7a43371b306 89 curTest = get_test_group_and_name(tagValue)
ram54288 0:a7a43371b306 90 resultHandled = False
ram54288 0:a7a43371b306 91 elif tagName == "UnityResult":
ram54288 0:a7a43371b306 92 if not resultHandled:
ram54288 0:a7a43371b306 93 tests.append((curTest, tagValue))
ram54288 0:a7a43371b306 94 resultHandled = True
ram54288 0:a7a43371b306 95 elif tagName == "UnityIgnoredTest":
ram54288 0:a7a43371b306 96 curTest = get_ignored_test_group_and_name(tagValue)
ram54288 0:a7a43371b306 97 tests.append((curTest, "IGNORE"))
ram54288 0:a7a43371b306 98 else:
ram54288 0:a7a43371b306 99 raise Exception("Unknown tag '" + tagName + "' encountered")
ram54288 0:a7a43371b306 100
ram54288 0:a7a43371b306 101 return tests
ram54288 0:a7a43371b306 102
ram54288 0:a7a43371b306 103 def generate_junit_xml_output(packageName, tests, xmlOutFile):
ram54288 0:a7a43371b306 104
ram54288 0:a7a43371b306 105 testsCount = len(tests)
ram54288 0:a7a43371b306 106
ram54288 0:a7a43371b306 107 with open(xmlOutFile, "wt") as f:
ram54288 0:a7a43371b306 108 print >> f, '<testsuite tests="' + str(testsCount) + '">'
ram54288 0:a7a43371b306 109 for test in tests:
ram54288 0:a7a43371b306 110 print >> f, ' <testcase classname="' + packageName + "." + test[0][0] + '" name="' + test[0][1] + '">'
ram54288 0:a7a43371b306 111 if test[1] == "FAIL":
ram54288 0:a7a43371b306 112 print >> f, ' <failure/>'
ram54288 0:a7a43371b306 113 if test[1] == "IGNORE":
ram54288 0:a7a43371b306 114 print >> f, ' <skipped/>'
ram54288 0:a7a43371b306 115 print >> f, ' </testcase>'
ram54288 0:a7a43371b306 116 print >> f, '</testsuite>'
ram54288 0:a7a43371b306 117
ram54288 0:a7a43371b306 118 def generate_text_output(packageName, tests, textOutFile):
ram54288 0:a7a43371b306 119
ram54288 0:a7a43371b306 120 testsCount = len(tests)
ram54288 0:a7a43371b306 121
ram54288 0:a7a43371b306 122 failingTests = 0
ram54288 0:a7a43371b306 123 passedTests = 0
ram54288 0:a7a43371b306 124 ignoredTests = 0
ram54288 0:a7a43371b306 125
ram54288 0:a7a43371b306 126 testsTable = []
ram54288 0:a7a43371b306 127 for test in tests:
ram54288 0:a7a43371b306 128 if test[1] == "FAIL":
ram54288 0:a7a43371b306 129 failingTests += 1
ram54288 0:a7a43371b306 130 if test[1] == "PASS":
ram54288 0:a7a43371b306 131 passedTests += 1
ram54288 0:a7a43371b306 132 if test[1] == "IGNORE":
ram54288 0:a7a43371b306 133 ignoredTests += 1
ram54288 0:a7a43371b306 134
ram54288 0:a7a43371b306 135 testsTable.append([test[0][0], test[0][1], test[1]])
ram54288 0:a7a43371b306 136
ram54288 0:a7a43371b306 137 resultsTableHeader = ["TOTAL", "PASS", "FAIL", "IGNORE"]
ram54288 0:a7a43371b306 138 resultsTable = [[str(testsCount), str(passedTests), str(failingTests), str(ignoredTests)]]
ram54288 0:a7a43371b306 139
ram54288 0:a7a43371b306 140 with open(textOutFile, "wt") as f:
ram54288 0:a7a43371b306 141
ram54288 0:a7a43371b306 142 print >> f, "==== " + packageName + " ===="
ram54288 0:a7a43371b306 143 print >> f, tabulate(testsTable)
ram54288 0:a7a43371b306 144 print >> f, tabulate(resultsTable, headers=resultsTableHeader)
ram54288 0:a7a43371b306 145
ram54288 0:a7a43371b306 146 if testsCount == 0 or failingTests > 0:
ram54288 0:a7a43371b306 147 finalStatus = "FAIL"
ram54288 0:a7a43371b306 148 else:
ram54288 0:a7a43371b306 149 finalStatus = "PASS"
ram54288 0:a7a43371b306 150 print >> f
ram54288 0:a7a43371b306 151 print >> f, "Final status: " + finalStatus + "."
ram54288 0:a7a43371b306 152
ram54288 0:a7a43371b306 153 def unity_to_junit(packageName, inputFile, xmlOutFile, textOutFile):
ram54288 0:a7a43371b306 154
ram54288 0:a7a43371b306 155 with open(inputFile, "rt") as f:
ram54288 0:a7a43371b306 156 logLines = f.read()
ram54288 0:a7a43371b306 157
ram54288 0:a7a43371b306 158 tags = extract_tags(logLines)
ram54288 0:a7a43371b306 159 tests = collect_tests(tags)
ram54288 0:a7a43371b306 160
ram54288 0:a7a43371b306 161 generate_junit_xml_output(packageName, tests, xmlOutFile)
ram54288 0:a7a43371b306 162 generate_text_output(packageName, tests, textOutFile)
ram54288 0:a7a43371b306 163
ram54288 0:a7a43371b306 164
ram54288 0:a7a43371b306 165 if __name__ == "__main__":
ram54288 0:a7a43371b306 166
ram54288 0:a7a43371b306 167 if len(sys.argv) != 5:
ram54288 0:a7a43371b306 168 print "Usage: <package-name> <input-file> <xml-out-file> <text-out-file>"
ram54288 0:a7a43371b306 169 sys.exit(1)
ram54288 0:a7a43371b306 170
ram54288 0:a7a43371b306 171 unity_to_junit(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
ram54288 0:a7a43371b306 172