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 | |
53 class TestLLCOptions(unittest.TestCase): | |
54 | |
55 def setUp(self): | |
56 driver_test_utils.ApplyTestEnvOverrides(env) | |
57 self.tempfiles = [] | |
58 | |
59 def getTemp(self, **kwargs): | |
60 # Set delete=False, so that we can close the files and | |
61 # re-open them. Windows sometimes does not allow you to | |
62 # re-open an already opened temp file. | |
63 t = tempfile.NamedTemporaryFile(delete=False, **kwargs) | |
64 self.tempfiles.append(t) | |
65 return t | |
66 | |
67 def tearDown(self): | |
68 for t in self.tempfiles: | |
69 if not t.closed: | |
70 t.close() | |
71 os.remove(t.name) | |
72 # Wipe other temp files that are normally wiped by DriverExit. | |
73 # We don't want anything to exit, so we do not call DriverExit manually. | |
74 driver_log.TempFiles.wipe() | |
75 | |
76 def getFakePexe(self): | |
77 # Even --dry-run requires a file to exist, so make a fake pexe. | |
78 # It even cares that the file is "bitcode" =( | |
79 with self.getTemp(suffix='.ll') as t: | |
80 with self.getTemp(suffix='.pexe') as p: | |
81 t.write(''' | |
82 define i32 @main() { | |
83 ret i32 0 | |
84 } | |
85 ''') | |
86 t.close() | |
87 p.close() | |
88 driver_tools.RunDriver('as', [t.name, '-o', p.name]) | |
89 return p | |
90 | |
91 | |
92 def dryRunTranslateWithFlags(self, pexe, arch, | |
Derek Schuff
2013/03/06 21:10:12
make it more clear that this function runs a trans
jvoung (off chromium)
2013/03/06 21:26:58
Done. I think...
| |
93 flags, expected_flags): | |
94 temp_output = self.getTemp() | |
95 temp_output.close() | |
96 # Major hack to capture the output. | |
97 # RunDriver() prints a bunch of things to stdout, which we need to capture. | |
98 # Another major hack is to prevent DriverExit() from aborting the test.' | |
99 # The test will surely DriverLog.Fatal() because dry-run currently | |
100 # does not handle anything that involves invoking a subprocess and | |
101 # grepping the stdout/stderr since it never actually invokes | |
102 # the subprocess. Unfortunately, pnacl-translate does grep the output of | |
103 # the sandboxed LLC run, so we can only go that far with --dry-run. | |
104 (fake_out, fake_err, backup_stdout, backup_stderr) = MakeFakeStdStream() | |
105 backup_exit = sys.exit | |
106 sys.exit = FakeExit | |
107 try: | |
108 with self.assertRaises(DriverExitException): | |
109 driver_tools.RunDriver('translate', | |
110 ['--pnacl-driver-verbose', | |
111 '--dry-run', | |
112 '-arch', | |
113 arch, | |
114 pexe.name, | |
115 '-o', temp_output.name] + flags) | |
116 finally: | |
117 out = sys.stdout.getvalue() # release output | |
118 err = sys.stderr.getvalue() # release output | |
119 RestoreStdStream(fake_out, fake_err, | |
120 backup_stdout, backup_stderr) | |
121 sys.exit = backup_exit | |
122 for f in expected_flags: | |
123 self.assertTrue(re.search(f, err), | |
124 msg='Searching for regex %s in %s' % (f, err)) | |
125 return | |
126 | |
127 #### Individual tests. | |
128 | |
129 def test_no_overrides(self): | |
130 if driver_test_utils.CanRunHost(): | |
131 pexe = self.getFakePexe() | |
132 # Test that certain defaults are set, when no flags are given. | |
133 self.dryRunTranslateWithFlags( | |
134 pexe, | |
135 'arm', | |
136 [], | |
137 ['-mtriple=arm.*', '-mcpu=cortex.*']) | |
138 # Test that the default StreamInit is used, when no flags are given. | |
139 self.dryRunTranslateWithFlags( | |
140 pexe, | |
141 'arm', | |
142 ['--pnacl-sb'], | |
143 ['StreamInit h']) | |
144 | |
145 def test_overrideO0(self): | |
146 if driver_test_utils.CanRunHost(): | |
147 pexe = self.getFakePexe() | |
148 # Test that you get O0 when you ask for O0. | |
149 # You also get no frame pointer elimination. | |
150 self.dryRunTranslateWithFlags( | |
151 pexe, | |
152 'arm', | |
153 ['-O0'], | |
154 ['-O0 ', '-disable-fp-elim ']) | |
155 self.dryRunTranslateWithFlags( | |
156 pexe, | |
157 'arm', | |
158 ['-O0', '--pnacl-sb'], | |
159 ['StreamInitWithOverrides.*-O0.*-disable-fp-elim.*-mcpu=.*']) | |
160 | |
161 def test_overrideTranslateFast(self): | |
162 if driver_test_utils.CanRunHost(): | |
163 pexe = self.getFakePexe() | |
164 # Test that you get O0 when you ask for -translate-fast. | |
165 # In this case... you don't get no frame pointer elimination. | |
166 self.dryRunTranslateWithFlags( | |
167 pexe, | |
168 'arm', | |
169 ['-translate-fast'], | |
170 ['-O0']) | |
171 self.dryRunTranslateWithFlags( | |
172 pexe, | |
173 'arm', | |
174 ['-translate-fast', '--pnacl-sb'], | |
175 ['StreamInitWithOverrides.*-O0.*-mcpu=.*']) | |
176 | |
177 def test_overrideTLSUseCall(self): | |
178 if driver_test_utils.CanRunHost(): | |
179 pexe = self.getFakePexe() | |
180 # Test that you -mtls-use-call, etc. when you ask for it. | |
181 self.dryRunTranslateWithFlags( | |
182 pexe, | |
183 'arm', | |
184 ['-mtls-use-call', '-fdata-sections', '-ffunction-sections'], | |
185 ['-mtls-use-call', '-fdata-sections', '-ffunction-sections']) | |
186 self.dryRunTranslateWithFlags( | |
187 pexe, | |
188 'arm', | |
189 ['-mtls-use-call', '-fdata-sections', '-ffunction-sections', | |
190 '--pnacl-sb'], | |
191 ['StreamInitWithOverrides.*-mtls-use-call' + | |
192 '.*-fdata-sections.*-ffunction-sections']) | |
193 | |
194 def test_overrideMCPU(self): | |
195 if driver_test_utils.CanRunHost(): | |
196 pexe = self.getFakePexe() | |
197 # Test that you get the -mcpu that you ask for. | |
198 self.dryRunTranslateWithFlags( | |
199 pexe, | |
200 'arm', | |
201 ['-mcpu=cortex-a15'], | |
202 ['-mcpu=cortex-a15']) | |
203 self.dryRunTranslateWithFlags( | |
204 pexe, | |
205 'arm', | |
206 ['-mcpu=cortex-a15', '--pnacl-sb'], | |
207 ['StreamInitWithOverrides.*-mcpu=cortex-a15']) | |
208 | |
209 def test_overrideMAttr(self): | |
210 if driver_test_utils.CanRunHost(): | |
211 pexe = self.getFakePexe() | |
212 # Test that you get the -mattr=.* that you ask for. | |
213 self.dryRunTranslateWithFlags( | |
214 pexe, | |
215 'x86-64', | |
216 ['-mattr=+avx2,+sse4'], | |
217 ['-mtriple=x86_64.*', '-mattr=\+avx2,\+sse4']) | |
218 self.dryRunTranslateWithFlags( | |
219 pexe, | |
220 'x86-64', | |
221 ['-mattr=+avx2,+sse4', '--pnacl-sb'], | |
222 ['StreamInitWithOverrides.*mattr=\+avx2,\+sse4.*-mcpu=core']) | |
223 | |
224 | |
225 if __name__ == '__main__': | |
226 unittest.main() | |
OLD | NEW |