Chromium Code Reviews| 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 |