forked from graalvm/mx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mx_sigtest.py
128 lines (119 loc) · 5.41 KB
/
mx_sigtest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python2.7
#
# ----------------------------------------------------------------------------------------------------
#
# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# ----------------------------------------------------------------------------------------------------
#
import mx
import os
from os.path import exists
from argparse import ArgumentParser
def _should_test_project(p):
if not p.isJavaProject():
return False
return len(mx.find_packages(p)) > 0
def sigtest(args, suite=None, projects=None):
parser = ArgumentParser(prog='mx sigtest')
parser.add_argument('--generate', action='store_true', help='Generates signature files for projects with API')
parser.add_argument('--check', action='store', help='Check <binary|all> against existing signature files', default='binary')
args = parser.parse_args(args)
if args.generate:
_sigtest_generate(args)
else:
if args.check:
_sigtest_check(args.check, args)
else:
parser.print_help()
def _sigtest_generate(args, suite=None, projects=None):
"""run sigtest generator for Java projects with API"""
sigtestlib = mx.library('SIGTEST').get_path(resolve=True)
nonTestProjects = [p for p in mx.projects() if _should_test_project(p)]
if not nonTestProjects:
return 0
javaCompliance = max([p.javaCompliance for p in nonTestProjects])
for p in nonTestProjects:
sigtestResults = p.dir + os.sep + 'snapshot.sigtest'
cmd = ['-cp', mx._cygpathU2W(sigtestlib), 'com.sun.tdk.signaturetest.Setup',
'-Static', '-FileName', sigtestResults,
'-ClassPath', mx.classpath(p) + os.pathsep + mx.get_jdk(javaCompliance).bootclasspath(),
]
for pkg in mx.find_packages(p):
cmd = cmd + ['-PackageWithoutSubpackages', pkg]
exitcode = mx.run_java(cmd, nonZeroIsFatal=False, jdk=mx.get_jdk(javaCompliance))
if exitcode != 95:
mx.abort('Exit code was ' + str(exitcode) + ' while generating ' + sigtestResults)
if not exists(sigtestResults):
mx.abort('Cannot generate ' + sigtestResults)
mx.log("Sigtest snapshot generated to " + sigtestResults)
return 0
def _sigtest_check(checktype, args, suite=None, projects=None):
"""run sigtest against Java projects with API"""
sigtestlib = mx.library('SIGTEST').get_path(resolve=True)
nonTestProjects = [p for p in mx.projects() if _should_test_project(p)]
if not nonTestProjects:
return 1
javaCompliance = max([p.javaCompliance for p in nonTestProjects])
class OutputCapture:
def __init__(self):
self.data = ""
def __call__(self, data):
self.data += data
failed = None
for p in nonTestProjects:
sigtestResults = p.dir + os.sep + 'snapshot.sigtest'
if not os.path.exists(sigtestResults):
continue
cmd = ['-cp', mx._cygpathU2W(sigtestlib), 'com.sun.tdk.signaturetest.SignatureTest',
'-Static', '-Mode', 'bin', '-FileName', sigtestResults,
'-ClassPath', mx.classpath(p) + os.pathsep + mx.get_jdk(javaCompliance).bootclasspath(),
]
if checktype != 'all':
cmd.append('-b')
for pkg in mx.find_packages(p):
cmd = cmd + ['-PackageWithoutSubpackages', pkg]
out = OutputCapture()
print 'Checking ' + checktype + ' signature changes against ' + sigtestResults
exitcode = mx.run_java(cmd, nonZeroIsFatal=False, jdk=mx.get_jdk(javaCompliance), out=out, err=out)
mx.ensure_dir_exists(p.get_output_root())
with open(p.get_output_root() + os.path.sep + 'sigtest-junit.xml', 'w') as f:
f.write('<?xml version="1.0" encoding="UTF-8" ?>\n')
f.write('<testsuite tests="1" name="' + p.name + '.sigtest.' + checktype + '">\n')
f.write('<testcase classname="' + p.name + '" name="sigtest.' + checktype + '">\n')
if exitcode != 95:
print out.data
failed = sigtestResults
f.write('<failure type="SignatureCheck"><![CDATA[\n')
f.write(out.data)
f.write(']]></failure>')
else:
f.write('<system-err><![CDATA[\n')
f.write(out.data)
f.write(']]></system-err>')
f.write('</testcase>\n')
f.write('</testsuite>\n')
if failed:
mx.abort('Signature error in ' + failed)
else:
print 'OK.'
return 0