Skip to content

Commit e5224aa

Browse files
committed
[GR-22987] Add utility to compare unittest results.
PullRequest: graalpython/973
2 parents 5c994b6 + 3463454 commit e5224aa

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
import sys
41+
import csv
42+
import argparse
43+
44+
def read_file(filename):
45+
with open(filename) as csvfile:
46+
return {x["unittest"]:x for x in csv.DictReader(csvfile) if x["unittest"] != "TOTAL"}
47+
48+
# ----------------------------------------------------------------------------------------------------------------------
49+
#
50+
# main tool
51+
#
52+
# ----------------------------------------------------------------------------------------------------------------------
53+
def main(prog, args):
54+
parser = argparse.ArgumentParser(prog=prog,
55+
description="Compare the result of two runs of the standard python unittests based on their csv reports.")
56+
parser.add_argument("-v", "--verbose", help="Verbose output.", action="store_true")
57+
parser.add_argument("csvfile1", help="first input csv file")
58+
parser.add_argument("csvfile2", help="first input csv file")
59+
60+
global flags
61+
flags = parser.parse_args(args=args)
62+
print("comparing {} and {}".format(flags.csvfile1, flags.csvfile2))
63+
64+
raw1 = read_file(flags.csvfile1)
65+
raw2 = read_file(flags.csvfile2)
66+
print("number of entries: {} / {}".format(len(raw1.keys()), len(raw2.keys())))
67+
68+
result = []
69+
missing_tests = []
70+
new_tests = []
71+
for name, data in raw1.items():
72+
other_data = raw2.get(name)
73+
if other_data:
74+
result.append({'name':name, 'old_passing':int(data['num_passes']), 'new_passing':int(other_data['num_passes'])})
75+
else:
76+
missing_tests.append(name)
77+
78+
for name in raw2.keys():
79+
if not raw1.get(name):
80+
new_tests.append(name)
81+
82+
def custom(a):
83+
return (a['new_passing'] - a['old_passing']) * 1000000 + a['old_passing']
84+
85+
result = sorted(result, key=custom)
86+
87+
RED = u"\u001b[31m"
88+
GREEN = u"\u001b[32m"
89+
RESET = u"\u001b[0m"
90+
91+
for entry in result:
92+
delta = entry['new_passing'] - entry['old_passing']
93+
if delta != 0:
94+
print("%s%30s: %d (from %d to %d passing tests)" % (GREEN if delta > 0 else RED, entry['name'], delta, entry['old_passing'], entry['new_passing']))
95+
print(RESET)
96+
97+
if __name__ == "__main__":
98+
main(sys.argv[0], sys.argv[1:])

mx.graalpython/mx_graalpython.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ def python3_unittests(args):
219219
mx.run([sys.executable, "graalpython/com.oracle.graal.python.test/src/python_unittests.py", "-v"] + args)
220220

221221

222+
def compare_unittests(args):
223+
"""compare the output of two runs of the cPython stdlib unittests"""
224+
mx.run([sys.executable, "graalpython/com.oracle.graal.python.test/src/compare_unittests.py", "-v"] + args)
225+
226+
222227
def retag_unittests(args):
223228
"""run the cPython stdlib unittests"""
224229
parser = ArgumentParser('mx python-retag-unittests')
@@ -1722,6 +1727,7 @@ def checkout_find_version_for_graalvm(args):
17221727
'python-svm': [python_svm, ''],
17231728
'python-gvm': [python_gvm, ''],
17241729
'python-unittests': [python3_unittests, ''],
1730+
'python-compare-unittests': [compare_unittests, ''],
17251731
'python-retag-unittests': [retag_unittests, ''],
17261732
'python-update-unittest-tags': [update_unittest_tags, ''],
17271733
'python-import-for-graal': [checkout_find_version_for_graalvm, ''],

0 commit comments

Comments
 (0)