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 """Tests of the pnacl driver. | |
7 | |
8 This tests that pnacl-translate options pass through to LLC correctly, | |
9 and are overridden correctly. | |
10 """ | |
11 | |
12 from driver_env import env | |
13 import driver_log | |
14 import driver_test_utils | |
15 import driver_tools | |
16 | |
17 import cStringIO | |
18 import os | |
19 import re | |
20 import sys | |
21 import tempfile | |
22 import unittest | |
23 | |
24 class DriverExitException(Exception): | |
25 pass | |
26 | |
27 def FakeExit(i): | |
28 raise DriverExitException('Stubbed out DriverExit!') | |
29 | |
30 def MakeFakeStdStream(): | |
31 fake_out = cStringIO.StringIO() | |
32 fake_err = cStringIO.StringIO() | |
33 backup_stdout = sys.stdout | |
34 backup_stderr = sys.stderr | |
35 sys.stdout = fake_out | |
36 sys.stderr = fake_err | |
37 return (fake_out, fake_err, backup_stdout, backup_stderr) | |
38 | |
39 def RestoreStdStream(fake_out, fake_err, | |
40 backup_stdout, backup_stderr): | |
41 sys.stdout = backup_stdout | |
42 sys.stderr = backup_stderr | |
43 # For some reason, cStringIO.StringIO() returns the same object | |
44 # for fake_out, on each iteration. So, if we close() it we could | |
45 # end up getting a closed object and write to closed object | |
46 # in the next iteration. | |
47 fake_out.reset() | |
48 fake_out.truncate() | |
49 fake_err.reset() | |
50 fake_err.truncate() | |
51 | |
52 def GetPlatformToTest(): | |
53 for arg in sys.argv: | |
54 if arg.startswith('--platform='): | |
55 return arg.split('=')[1] | |
56 raise Exception('Unknown platform') | |
57 | |
58 class TestLLCOptions(unittest.TestCase): | |
59 | |
60 def setUp(self): | |
61 driver_test_utils.ApplyTestEnvOverrides(env) | |
62 self.platform = GetPlatformToTest() | |
63 self.tempfiles = [] | |
64 | |
65 def getTemp(self, **kwargs): | |
66 # Set delete=False, so that we can close the files and | |
67 # re-open them. Windows sometimes does not allow you to | |
68 # re-open an already opened temp file. | |
69 t = tempfile.NamedTemporaryFile(delete=False, **kwargs) | |
70 self.tempfiles.append(t) | |
71 return t | |
72 | |
73 def tearDown(self): | |
74 for t in self.tempfiles: | |
75 if not t.closed: | |
76 t.close() | |
77 os.remove(t.name) | |
78 # Wipe other temp files that are normally wiped by DriverExit. | |
79 # We don't want anything to exit, so we do not call DriverExit manually. | |
80 driver_log.TempFiles.wipe() | |
81 | |
82 def getFakePexe(self): | |
83 # Even --dry-run requires a file to exist, so make a fake pexe. | |
84 # It even cares that the file is really bitcode. | |
85 with self.getTemp(suffix='.ll') as t: | |
86 with self.getTemp(suffix='.pexe') as p: | |
87 t.write(''' | |
88 define i32 @main() { | |
89 ret i32 0 | |
90 } | |
91 ''') | |
92 t.close() | |
93 p.close() | |
94 driver_tools.RunDriver('as', [t.name, '-o', p.name]) | |
95 return p | |
96 | |
97 | |
98 def checkLLCTranslateFlags(self, pexe, arch, flags, | |
99 expected_flags): | |
100 ''' Given a |pexe| the |arch| for translation and additional pnacl-translate | |
101 |flags|, check that the commandline for LLC really contains the | |
102 |expected_flags|. This ensures that the pnacl-translate script | |
103 does not drop certain flags accidentally. ''' | |
104 temp_output = self.getTemp() | |
105 temp_output.close() | |
106 # Major hack to capture the output. | |
107 # RunDriver() prints a bunch of things to stdout, which we need to capture. | |
108 # Another major hack is to prevent DriverExit() from aborting the test.' | |
109 # The test will surely DriverLog.Fatal() because dry-run currently | |
110 # does not handle anything that involves invoking a subprocess and | |
111 # grepping the stdout/stderr since it never actually invokes | |
112 # the subprocess. Unfortunately, pnacl-translate does grep the output of | |
113 # the sandboxed LLC run, so we can only go that far with --dry-run. | |
114 (fake_out, fake_err, backup_stdout, backup_stderr) = MakeFakeStdStream() | |
115 backup_exit = sys.exit | |
116 sys.exit = FakeExit | |
117 try: | |
118 self.assertRaises(DriverExitException, | |
119 driver_tools.RunDriver, | |
120 'translate', | |
121 ['--pnacl-driver-verbose', | |
122 '--dry-run', | |
123 '-arch', arch, | |
124 pexe.name, | |
125 '-o', temp_output.name] + flags) | |
126 finally: | |
127 out = sys.stdout.getvalue() | |
128 err = sys.stderr.getvalue() | |
129 RestoreStdStream(fake_out, fake_err, | |
130 backup_stdout, backup_stderr) | |
131 sys.exit = backup_exit | |
132 for f in expected_flags: | |
133 self.assertTrue(re.search(f, err), | |
134 msg='Searching for regex %s in %s' % (f, err)) | |
135 return | |
136 | |
137 | |
138 #### Individual tests. | |
139 | |
140 def test_no_overrides(self): | |
141 if driver_test_utils.CanRunHost(): | |
142 pexe = self.getFakePexe() | |
143 if self.platform == 'arm': | |
144 expected_triple_cpu = ['-mtriple=arm.*', '-mcpu=.*'] | |
Derek Schuff
2013/03/12 17:13:09
this mcpu doesn't match what you had in patchset 6
jvoung (off chromium)
2013/03/12 18:02:02
Ah yes -- Done.
| |
145 elif self.platform == 'x86-32': | |
146 expected_triple_cpu = ['-mtriple=i686.*', '-mcpu=.*'] | |
147 elif self.platform == 'x86-64': | |
148 expected_triple_cpu = ['-mtriple=x86_64.*', '-mcpu=.*'] | |
149 else: | |
150 raise Exception('Unknown platform') | |
151 # Test that certain defaults are set, when no flags are given. | |
152 self.checkLLCTranslateFlags( | |
153 pexe, | |
154 self.platform, | |
155 [], | |
156 expected_triple_cpu) | |
157 # Test that the default StreamInit is used, when no flags are given. | |
158 self.checkLLCTranslateFlags( | |
159 pexe, | |
160 self.platform, | |
161 ['--pnacl-sb'], | |
162 ['StreamInit h']) | |
163 | |
164 def test_overrideO0(self): | |
165 if driver_test_utils.CanRunHost(): | |
166 pexe = self.getFakePexe() | |
167 # Test that you get O0 when you ask for O0. | |
168 # You also get no frame pointer elimination. | |
169 self.checkLLCTranslateFlags( | |
170 pexe, | |
171 self.platform, | |
172 ['-O0'], | |
173 ['-O0 ', '-disable-fp-elim ']) | |
174 self.checkLLCTranslateFlags( | |
175 pexe, | |
176 self.platform, | |
177 ['-O0', '--pnacl-sb'], | |
178 ['StreamInitWithOverrides.*-O0.*-disable-fp-elim.*-mcpu=.*']) | |
179 | |
180 def test_overrideTranslateFast(self): | |
181 if driver_test_utils.CanRunHost(): | |
182 pexe = self.getFakePexe() | |
183 # Test that you get O0 when you ask for -translate-fast. | |
184 # In this case... you don't get no frame pointer elimination. | |
185 self.checkLLCTranslateFlags( | |
186 pexe, | |
187 self.platform, | |
188 ['-translate-fast'], | |
189 ['-O0']) | |
190 self.checkLLCTranslateFlags( | |
191 pexe, | |
192 self.platform, | |
193 ['-translate-fast', '--pnacl-sb'], | |
194 ['StreamInitWithOverrides.*-O0.*-mcpu=.*']) | |
195 | |
196 def test_overrideTLSUseCall(self): | |
197 if driver_test_utils.CanRunHost(): | |
198 pexe = self.getFakePexe() | |
199 # Test that you -mtls-use-call, etc. when you ask for it. | |
200 self.checkLLCTranslateFlags( | |
201 pexe, | |
202 self.platform, | |
203 ['-mtls-use-call', '-fdata-sections', '-ffunction-sections'], | |
204 ['-mtls-use-call', '-fdata-sections', '-ffunction-sections']) | |
205 self.checkLLCTranslateFlags( | |
206 pexe, | |
207 self.platform, | |
208 ['-mtls-use-call', '-fdata-sections', '-ffunction-sections', | |
209 '--pnacl-sb'], | |
210 ['StreamInitWithOverrides.*-mtls-use-call' + | |
211 '.*-fdata-sections.*-ffunction-sections']) | |
212 | |
213 def test_overrideMCPU(self): | |
214 if driver_test_utils.CanRunHost(): | |
215 pexe = self.getFakePexe() | |
216 if self.platform == 'arm': | |
217 mcpu_pattern = '-mcpu=cortex-a15' | |
218 elif self.platform == 'x86-32': | |
219 mcpu_pattern = '-mcpu=atom' | |
220 elif self.platform == 'x86-64': | |
221 mcpu_pattern = '-mcpu=corei7' | |
222 else: | |
223 raise Exception('Unknown platform') | |
224 # Test that you get the -mcpu that you ask for. | |
225 self.checkLLCTranslateFlags( | |
226 pexe, | |
227 self.platform, | |
228 [mcpu_pattern], | |
229 [mcpu_pattern]) | |
230 self.checkLLCTranslateFlags( | |
231 pexe, | |
232 self.platform, | |
233 [mcpu_pattern, '--pnacl-sb'], | |
234 ['StreamInitWithOverrides.*' + mcpu_pattern]) | |
235 | |
236 def test_overrideMAttr(self): | |
237 if driver_test_utils.CanRunHost(): | |
238 pexe = self.getFakePexe() | |
239 if self.platform == 'arm': | |
240 mattr_flags, mattr_pat = '-mattr=+hwdiv', r'-mattr=\+hwdiv' | |
241 elif self.platform == 'x86-32' or self.platform == 'x86-64': | |
242 mattr_flags, mattr_pat = '-mattr=+avx2,+sse41', r'-mattr=\+avx2,\+sse41' | |
243 else: | |
244 raise Exception('Unknown platform') | |
245 # Test that you get the -mattr=.* that you ask for. | |
246 self.checkLLCTranslateFlags( | |
247 pexe, | |
248 self.platform, | |
249 [mattr_flags], | |
250 [mattr_pat]) | |
251 self.checkLLCTranslateFlags( | |
252 pexe, | |
253 self.platform, | |
254 [mattr_flags, '--pnacl-sb'], | |
255 ['StreamInitWithOverrides.*' + mattr_pat + '.*-mcpu=.*']) | |
256 | |
257 | |
258 if __name__ == '__main__': | |
259 unittest.main() | |
OLD | NEW |