-
Notifications
You must be signed in to change notification settings - Fork 7
/
sanity.py
148 lines (110 loc) · 4 KB
/
sanity.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import os, json, re
import common
RESULTS_DIR = None
def project_dir(project):
return os.path.join(RESULTS_DIR, 'dljc-out', project['name'])
def error(project, check, message):
err = {'check': check, 'error': message}
print('ERROR: [{proj}] - {check} - {msg}'.format(
proj=project['name'],
check=check,
msg=message))
return [err]
def check_daikon(project):
# If dyntrace is enabled for this project
if "dyntrace" in project['exclude']:
return []
# And there are some generated tests,
# there should be invariants.gz in each test-classes folder
# that corresponds to a test-src folder
errors = []
src_dirs = test_src_dirs(project)
p_dir = project_dir(project)
for d in src_dirs:
m = re.match(r'test-src(\d+)', d)
dirnum = m.group(1)
inv_file = os.path.join(p_dir, 'test-classes{}'.format(dirnum), 'invariants.gz')
if not os.path.exists(inv_file):
errors.extend(error(project, 'daikon',
'No invariants found for generated tests #{}.'.format(dirnum)))
return errors
def test_src_dirs(project):
return [entry for entry in os.listdir(project_dir(project))
if 'test-src' in entry]
def check_randoop_log(project):
randoop_log = os.path.join(project_dir(project), 'randoop.log')
errors = []
lineno = 1
with open(randoop_log) as f:
for line in f.readlines():
if "Randoop failed." in line:
errors.extend(error(project, 'randoop', 'Randoop failed. See randoop.log:{}'.format(lineno)))
lineno += 1
return errors
def check_randoop(project):
# If dyntrace is enabled for this project
if "dyntrace" in project['exclude']:
return []
# There should be some generated tests
# and no "randoop failed" in the randoop log
errors = []
errors.extend(check_randoop_log(project))
if not test_src_dirs(project):
errors.extend(error(project, 'randoop', 'No tests generated.'))
return errors
def check_checker(project):
# There should be an "Inference succeeded" in the checker framework log
infer_log = os.path.join(project_dir(project), 'infer.log')
successes = 0
errors = []
with open(infer_log) as f:
lines = f.readlines()
for line in lines:
if "Inference succeeded" in line:
successes += 1
if "Inference failed" in line:
errors.extend(error(project, 'checker', 'Inference failed.'))
if successes == 0:
errors.extend(error(project, 'checker', 'No successful inferences.'))
return errors
def check_jars(project):
# If there were jar instructions, there should be some generated jars
if 'jar' not in project:
return []
jars_dir = os.path.join(RESULTS_DIR, 'jars', project['name'])
jars = [f for f in os.listdir(jars_dir) if '.jar' in f]
if not jars:
return error(project, 'jars', 'Project has jar commmand, but no jars were built.')
return []
def check_compiled(project):
# There should be some DLJC results
javac_json = os.path.join(project_dir(project), 'javac.json')
with open(javac_json, 'r') as f:
javac_results = json.load(f)
if not javac_results:
return error(project, 'compiled', 'No javac commands detected.')
java_files = []
for command in javac_results:
java_files.extend(command['java_files'])
if not java_files:
return error(project, 'compiled', 'No java files compiled.')
return []
# TODO - replace with annotation
ALL_CHECKS = [check_compiled, check_jars, check_checker, check_randoop, check_daikon]
def check_project(project):
errors = []
for check in ALL_CHECKS:
# TODO - catch exceptions generated when checking
errors.extend(check(project))
return errors
def check_run(project_list, results_dir):
global RESULTS_DIR
RESULTS_DIR = results_dir
errors = {}
for project_name in project_list:
project_info = common.project_info(project_name)
errors[project_name] = {'project': project_info}
errors[project_name]['errors'] = check_project(project_info)
with open(os.path.join(results_dir, 'sanity.json'), 'w') as f:
json.dump(errors, f)
return errors