OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 import glob | |
7 import optparse | |
8 import subprocess | |
9 import sys | |
10 | |
11 import test_format | |
12 | |
13 | |
14 FIELDS_TO_IGNORE = set(['rdfa_output', 'validators_disagree']) | |
15 | |
16 | |
17 def AssertEquals(actual, expected): | |
18 if actual != expected: | |
19 raise AssertionError('\nEXPECTED:\n"""\n%s"""\n\nACTUAL:\n"""\n%s"""' | |
20 % (expected, actual)) | |
21 | |
22 | |
23 def GetX8632Combinations(): | |
24 for detailed in (True, False): | |
25 for test_stats in (True, False): | |
26 for test_cpuid_all in (True, False): | |
27 ext = 'nval' | |
28 options = [] | |
29 if detailed: | |
30 ext += 'd' | |
31 options.append('--detailed') | |
32 else: | |
33 options.append('--detailed=false') | |
34 if test_stats: | |
35 ext += 's' | |
36 options.append('--stats') | |
37 if test_cpuid_all: | |
38 options.append('--cpuid-all') | |
39 else: | |
40 ext += '0' | |
41 options.append('--cpuid-none') | |
42 yield ext, options | |
43 | |
44 | |
45 def GetX8664Combinations(): | |
46 for test_readwrite in (True, False): | |
47 for detailed in (True, False): | |
48 for test_cpuid_all in (True, False): | |
49 for test_annotate in (True, False): | |
50 for validator_decoder in (True, False): | |
51 options = [] | |
52 # TODO(shcherbina): Remove support for testing validation | |
53 # without sandboxing memory reads. | |
54 if test_readwrite: | |
55 ext = 'rval' | |
56 options.append('--readwrite_sfi') | |
57 else: | |
58 ext = 'val' | |
59 options.append('--write_sfi') | |
60 if detailed: | |
61 ext += 'd' | |
62 options.append('--detailed') | |
63 else: | |
64 options.append('--detailed=false') | |
65 if test_cpuid_all: | |
66 options.append('--cpuid-all') | |
67 else: | |
68 ext += '0' | |
69 options.append('--cpuid-none') | |
70 if test_annotate: | |
71 ext += 'a' | |
72 options.append('--annotate') | |
73 else: | |
74 options.append('--annotate=false') | |
75 if validator_decoder: | |
76 ext = "vd-" + ext | |
77 options.append('--validator_decoder') | |
78 yield ext, options | |
79 | |
80 | |
81 def Test(options, items_list): | |
82 info = dict(items_list) | |
83 handled_fields = set(['hex']) | |
84 | |
85 def RunCommandOnHex(field, command): | |
86 handled_fields.add(field) | |
87 if field in info: | |
88 proc = subprocess.Popen(command, | |
89 stdin=subprocess.PIPE, | |
90 stdout=subprocess.PIPE) | |
91 # r'\\' is used as line continuation marker by | |
92 # run_rdfa_validator_tests.py. Old validator does not care about line | |
93 # partitioning, so we just remove the marker. | |
94 stdout, stderr = proc.communicate(info['hex'].replace(r'\\', '')) | |
95 assert proc.wait() == 0, (command, stdout, stderr) | |
96 # Remove the carriage return characters that we get on Windows. | |
97 stdout = stdout.replace('\r', '') | |
98 print ' Checking %r field...' % field | |
99 if options.update: | |
100 if stdout != info[field]: | |
101 print ' Updating %r field...' % field | |
102 info[field] = stdout | |
103 else: | |
104 AssertEquals(stdout, info[field]) | |
105 | |
106 ncdis = [options.ncdis, '--hex_text=-'] | |
107 RunCommandOnHex('dis', ncdis + ['--full_decoder']) | |
108 RunCommandOnHex('vdis', ncdis + ['--validator_decoder']) | |
109 | |
110 ncval = [options.ncval, '--hex_text=-', '--max_errors=-1'] | |
111 if options.bits == 32: | |
112 for ext, ncval_options in GetX8632Combinations(): | |
113 RunCommandOnHex(ext, ncval + ncval_options) | |
114 elif options.bits == 64: | |
115 for ext, ncval_options in GetX8664Combinations(): | |
116 RunCommandOnHex(ext, ncval + ncval_options) | |
117 | |
118 RunCommandOnHex('sval', ncval + ['--stubout']) | |
119 else: | |
120 raise AssertionError('Unknown architecture: %r' % options.bits) | |
121 | |
122 unhandled = set(info.keys()) - set(handled_fields) - FIELDS_TO_IGNORE | |
123 if unhandled: | |
124 raise AssertionError('Unhandled fields: %r' % sorted(unhandled)) | |
125 | |
126 # Update field values, but preserve their order. | |
127 items_list = [(field, info[field]) for field, _ in items_list] | |
128 | |
129 return items_list | |
130 | |
131 | |
132 def main(args): | |
133 parser = optparse.OptionParser() | |
134 parser.add_option('--ncval', default='ncval', | |
135 help='Path to the ncval validator executable') | |
136 parser.add_option('--ncdis', default='ncdis', | |
137 help='Path to the ncdis disassembler executable') | |
138 parser.add_option('--bits', | |
139 type=int, | |
140 help='The subarchitecture to run tests against: 32 or 64') | |
141 parser.add_option('--update', | |
142 default=False, | |
143 action='store_true', | |
144 help='Regenerate golden fields instead of testing') | |
145 options, args = parser.parse_args(args) | |
146 if options.bits not in [32, 64]: | |
147 parser.error('specify --bits 32 or --bits 64') | |
148 if len(args) == 0: | |
149 parser.error('No test files specified') | |
150 processed = 0 | |
151 for glob_expr in args: | |
152 test_files = sorted(glob.glob(glob_expr)) | |
153 if len(test_files) == 0: | |
154 raise AssertionError( | |
155 '%r matched no files, which was probably not intended' % glob_expr) | |
156 for test_file in test_files: | |
157 print 'Testing %s...' % test_file | |
158 tests = test_format.LoadTestFile(test_file) | |
159 tests = [Test(options, test) for test in tests] | |
160 if options.update: | |
161 test_format.SaveTestFile(tests, test_file) | |
162 processed += 1 | |
163 print '%s test files were processed.' % processed | |
164 | |
165 | |
166 if __name__ == '__main__': | |
167 main(sys.argv[1:]) | |
OLD | NEW |