Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 # for details. All rights reserved. Use of this source code is governed by a | 2 # for details. All rights reserved. Use of this source code is governed by a |
| 3 # BSD-style license that can be found in the LICENSE file. | 3 # BSD-style license that can be found in the LICENSE file. |
| 4 # | 4 # |
| 5 | 5 |
| 6 """Runs a Dart unit test in different configurations. | |
| 7 | |
| 8 Currently supported architectures include dartium, chromium, ia32, x64, | |
| 9 arm, simarm, and dartc. | |
| 10 | |
| 11 Example: | |
| 12 run.py --arch=dartium --mode=release --test=Test.dart | |
| 13 | |
| 14 """ | |
| 15 | |
| 16 import os | 6 import os |
| 17 import platform | 7 import platform |
| 18 import re | 8 import re |
| 19 import shutil | 9 import shutil |
| 20 import subprocess | 10 import subprocess |
| 21 import sys | 11 import sys |
| 22 import tempfile | 12 import tempfile |
| 23 | 13 |
| 24 import utils | 14 import utils |
| 25 | 15 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 def IsLibraryDefinition(test, source): | 126 def IsLibraryDefinition(test, source): |
| 137 """Returns True if the source has a #library statement.""" | 127 """Returns True if the source has a #library statement.""" |
| 138 if LIBRARY_DEFINITION_PATTERN.search(source): | 128 if LIBRARY_DEFINITION_PATTERN.search(source): |
| 139 return True | 129 return True |
| 140 if SOURCE_OR_IMPORT_PATTERN.search(source): | 130 if SOURCE_OR_IMPORT_PATTERN.search(source): |
| 141 print ('WARNING for %s: Browser tests need a #library ' | 131 print ('WARNING for %s: Browser tests need a #library ' |
| 142 'for a file that #import or #source' % test) | 132 'for a file that #import or #source' % test) |
| 143 return False | 133 return False |
| 144 | 134 |
| 145 | 135 |
| 146 class Architecture(object): | 136 class Architecture(object): |
|
Siggi Cherem (dart-lang)
2011/10/31 17:18:48
(probably for a follow up cl) Architecture --> Tes
ngeoffray
2011/11/01 08:30:50
Yes, naming them Architecture is really confusing
| |
| 147 """Definitions for different ways to test based on the --arch flag.""" | 137 """Definitions for different ways to test based on the FOOBAR flag.""" |
| 148 | 138 |
| 149 def __init__(self, root_path, arch, mode, test): | 139 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 150 self.root_path = root_path | 140 self.root_path = root_path |
| 151 self.arch = arch | 141 self.arch = arch |
| 152 self.mode = mode | 142 self.mode = mode |
| 143 self.FOOBAR = FOOBAR | |
| 153 self.test = test | 144 self.test = test |
| 154 self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch) | 145 self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch) |
| 155 source = file(test).read() | 146 source = file(test).read() |
| 156 self.vm_options = [] | 147 self.vm_options = [] |
| 157 self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN, | 148 self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN, |
| 158 source, | 149 source, |
| 159 root_path) | 150 root_path) |
| 160 self.is_web_test = _IsWebTest(source) | 151 self.is_web_test = _IsWebTest(source) |
| 161 self.temp_dir = None | 152 self.temp_dir = None |
| 162 | 153 |
| 163 def HasFatalTypeErrors(self): | 154 def HasFatalTypeErrors(self): |
| 164 """Returns True if this type of arch supports --fatal-type-errors.""" | 155 """Returns True if this type of FOOBAR supports --fatal-type-errors.""" |
| 165 return False | 156 return False |
| 166 | 157 |
| 167 def GetTestFrameworkPath(self): | 158 def GetTestFrameworkPath(self): |
| 168 """Path to dart source (TestFramework.dart) for testing framework.""" | 159 """Path to dart source (TestFramework.dart) for testing framework.""" |
| 169 return os.path.join(self.root_path, 'tests', 'isolate', 'src', | 160 return os.path.join(self.root_path, 'tests', 'isolate', 'src', |
| 170 'TestFramework.dart') | 161 'TestFramework.dart') |
| 171 | 162 |
| 172 | 163 |
| 173 class BrowserArchitecture(Architecture): | 164 class BrowserArchitecture(Architecture): |
| 174 """Architecture that runs compiled dart->JS through a browser.""" | 165 """Architecture that runs compiled dart->JS through a browser.""" |
| 175 | 166 |
| 176 def __init__(self, root_path, arch, mode, test): | 167 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 177 super(BrowserArchitecture, self).__init__(root_path, arch, mode, test) | 168 super(BrowserArchitecture, self).__init__(root_path, arch, mode, FOOBAR, |
| 169 test) | |
| 178 self.temp_dir = tempfile.mkdtemp() | 170 self.temp_dir = tempfile.mkdtemp() |
| 179 if not self.is_web_test: self.GenerateWebTestScript() | 171 if not self.is_web_test: self.GenerateWebTestScript() |
| 180 | 172 |
| 181 def GetTestScriptFile(self): | 173 def GetTestScriptFile(self): |
| 182 """Returns the name of the .dart file to compile.""" | 174 """Returns the name of the .dart file to compile.""" |
| 183 if self.is_web_test: return os.path.abspath(self.test) | 175 if self.is_web_test: return os.path.abspath(self.test) |
| 184 return os.path.join(self.temp_dir, 'test.dart') | 176 return os.path.join(self.temp_dir, 'test.dart') |
| 185 | 177 |
| 186 def GetHtmlContents(self): | 178 def GetHtmlContents(self): |
| 187 """Fills in the HTML_CONTENTS template with info for this architecture.""" | 179 """Fills in the HTML_CONTENTS template with info for this architecture.""" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 212 os.makedirs(html_path) | 204 os.makedirs(html_path) |
| 213 return html_path | 205 return html_path |
| 214 | 206 |
| 215 return self.temp_dir | 207 return self.temp_dir |
| 216 | 208 |
| 217 def GetTestContents(self, library_file): | 209 def GetTestContents(self, library_file): |
| 218 """Pastes a preamble on the front of the .dart file before testing.""" | 210 """Pastes a preamble on the front of the .dart file before testing.""" |
| 219 unittest_path = os.path.join(self.root_path, 'client', 'testing', | 211 unittest_path = os.path.join(self.root_path, 'client', 'testing', |
| 220 'unittest', 'unittest.dart') | 212 'unittest', 'unittest.dart') |
| 221 | 213 |
| 222 if self.arch == 'chromium': | 214 if self.FOOBAR == 'chromium': |
| 223 dom_path = os.path.join(self.root_path, 'client', 'testing', | 215 dom_path = os.path.join(self.root_path, 'client', 'testing', |
| 224 'unittest', 'dom_for_unittest.dart') | 216 'unittest', 'dom_for_unittest.dart') |
| 225 else: | 217 else: |
| 226 dom_path = os.path.join('dart:dom') | 218 dom_path = os.path.join('dart:dom') |
| 227 | 219 |
| 228 test_framework_path = self.GetTestFrameworkPath() | 220 test_framework_path = self.GetTestFrameworkPath() |
| 229 test_path = os.path.abspath(self.test) | 221 test_path = os.path.abspath(self.test) |
| 230 | 222 |
| 231 inputs = { | 223 inputs = { |
| 232 'unittest': unittest_path, | 224 'unittest': unittest_path, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 def Cleanup(self): | 309 def Cleanup(self): |
| 318 """Removes temporary files created for the test.""" | 310 """Removes temporary files created for the test.""" |
| 319 if self.temp_dir: | 311 if self.temp_dir: |
| 320 shutil.rmtree(self.temp_dir) | 312 shutil.rmtree(self.temp_dir) |
| 321 self.temp_dir = None | 313 self.temp_dir = None |
| 322 | 314 |
| 323 | 315 |
| 324 class ChromiumArchitecture(BrowserArchitecture): | 316 class ChromiumArchitecture(BrowserArchitecture): |
| 325 """Architecture that runs compiled dart->JS through a chromium DRT.""" | 317 """Architecture that runs compiled dart->JS through a chromium DRT.""" |
| 326 | 318 |
| 327 def __init__(self, root_path, arch, mode, test): | 319 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 328 super(ChromiumArchitecture, self).__init__(root_path, arch, mode, test) | 320 super(ChromiumArchitecture, self).__init__(root_path, arch, mode, FOOBAR, te st) |
| 329 | 321 |
| 330 def GetScriptType(self): | 322 def GetScriptType(self): |
| 331 return 'text/javascript' | 323 return 'text/javascript' |
| 332 | 324 |
| 333 def GetScriptPath(self): | 325 def GetScriptPath(self): |
| 334 """Returns the name of the output .js file to create.""" | 326 """Returns the name of the output .js file to create.""" |
| 335 path = self.GetTestScriptFile() | 327 path = self.GetTestScriptFile() |
| 336 return os.path.abspath(os.path.join(self.temp_dir, | 328 return os.path.abspath(os.path.join(self.temp_dir, |
| 337 os.path.basename(path) + '.js')) | 329 os.path.basename(path) + '.js')) |
| 338 | 330 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 361 cmd.append(self.GetTestScriptFile()) | 353 cmd.append(self.GetTestScriptFile()) |
| 362 return cmd | 354 return cmd |
| 363 | 355 |
| 364 def Compile(self): | 356 def Compile(self): |
| 365 return ExecuteCommand(self.GetCompileCommand()) | 357 return ExecuteCommand(self.GetCompileCommand()) |
| 366 | 358 |
| 367 | 359 |
| 368 class DartiumArchitecture(BrowserArchitecture): | 360 class DartiumArchitecture(BrowserArchitecture): |
| 369 """Architecture that runs dart in an VM embedded in DumpRenderTree.""" | 361 """Architecture that runs dart in an VM embedded in DumpRenderTree.""" |
| 370 | 362 |
| 371 def __init__(self, root_path, arch, mode, test): | 363 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 372 super(DartiumArchitecture, self).__init__(root_path, arch, mode, test) | 364 super(DartiumArchitecture, self).__init__(root_path, arch, mode, FOOBAR, tes t) |
| 373 | 365 |
| 374 def GetScriptType(self): | 366 def GetScriptType(self): |
| 375 return 'application/dart' | 367 return 'application/dart' |
| 376 | 368 |
| 377 def GetScriptPath(self): | 369 def GetScriptPath(self): |
| 378 return 'file:///' + self.GetTestScriptFile() | 370 return 'file:///' + self.GetTestScriptFile() |
| 379 | 371 |
| 380 def GetHtmlName(self): | 372 def GetHtmlName(self): |
| 381 path = os.path.relpath(self.test, self.root_path).replace(os.sep, '_') | 373 path = os.path.relpath(self.test, self.root_path).replace(os.sep, '_') |
| 382 return path + '.dartium.html' | 374 return path + '.dartium.html' |
| 383 | 375 |
| 384 def GetCompileCommand(self, fatal_static_type_errors=False): | 376 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 385 fatal_static_type_errors = fatal_static_type_errors # shutup lint! | 377 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 386 return None | 378 return None |
| 387 | 379 |
| 388 def Compile(self): | 380 def Compile(self): |
| 389 return 0 | 381 return 0 |
| 390 | 382 |
| 391 | 383 |
| 392 class StandaloneArchitecture(Architecture): | 384 class StandaloneArchitecture(Architecture): |
| 393 """Base class for architectures that run tests without a browser.""" | 385 """Base class for architectures that run tests without a browser.""" |
| 394 | 386 |
| 395 def __init__(self, root_path, arch, mode, test): | 387 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 396 super(StandaloneArchitecture, self).__init__(root_path, arch, mode, test) | 388 super(StandaloneArchitecture, self).__init__(root_path, arch, mode, FOOBAR, |
| 389 test) | |
| 397 | 390 |
| 398 def GetCompileCommand(self, fatal_static_type_errors=False): | 391 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 399 fatal_static_type_errors = fatal_static_type_errors # shutup lint! | 392 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 400 return None | 393 return None |
| 401 | 394 |
| 402 def GetRunCommand(self, fatal_static_type_errors=False): | 395 def GetRunCommand(self, fatal_static_type_errors=False): |
| 403 """Returns a command line to execute for the test.""" | 396 """Returns a command line to execute for the test.""" |
| 404 dart = self.GetExecutable() | 397 dart = self.GetExecutable() |
| 405 test_name = os.path.basename(self.test) | 398 test_name = os.path.basename(self.test) |
| 406 test_path = os.path.abspath(self.test) | 399 test_path = os.path.abspath(self.test) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 430 | 423 |
| 431 def Cleanup(self): | 424 def Cleanup(self): |
| 432 return | 425 return |
| 433 | 426 |
| 434 | 427 |
| 435 # Long term, we should do the running machinery that is currently in | 428 # Long term, we should do the running machinery that is currently in |
| 436 # DartRunner.java | 429 # DartRunner.java |
| 437 class DartcArchitecture(StandaloneArchitecture): | 430 class DartcArchitecture(StandaloneArchitecture): |
| 438 """Runs the Dart ->JS compiler then runs the result in a standalone JS VM.""" | 431 """Runs the Dart ->JS compiler then runs the result in a standalone JS VM.""" |
| 439 | 432 |
| 440 def __init__(self, root_path, arch, mode, test): | 433 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 441 super(DartcArchitecture, self).__init__(root_path, arch, mode, test) | 434 super(DartcArchitecture, self).__init__(root_path, arch, mode, FOOBAR, test) |
| 442 | 435 |
| 443 def GetExecutable(self): | 436 def GetExecutable(self): |
| 444 """Returns the name of the executable to run the test.""" | 437 """Returns the name of the executable to run the test.""" |
| 445 return os.path.abspath(os.path.join(self.build_root, | 438 return os.path.abspath(os.path.join(self.build_root, |
| 446 'compiler', | 439 'compiler', |
| 447 'bin', | 440 'bin', |
| 448 'dartc_test')) | 441 'dartc_test')) |
| 449 | 442 |
| 450 def GetFatalTypeErrorsFlags(self): | 443 def GetFatalTypeErrorsFlags(self): |
| 451 return ['--fatal-type-errors'] | 444 return ['--fatal-type-errors'] |
| 452 | 445 |
| 453 def HasFatalTypeErrors(self): | 446 def HasFatalTypeErrors(self): |
| 454 return True | 447 return True |
| 455 | 448 |
| 456 def GetRunCommand(self, fatal_static_type_errors=False): | 449 def GetRunCommand(self, fatal_static_type_errors=False): |
| 457 """Returns a command line to execute for the test.""" | 450 """Returns a command line to execute for the test.""" |
| 458 cmd = super(DartcArchitecture, self).GetRunCommand( | 451 cmd = super(DartcArchitecture, self).GetRunCommand( |
| 459 fatal_static_type_errors) | 452 fatal_static_type_errors) |
| 460 return cmd | 453 return cmd |
| 461 | 454 |
| 462 | 455 |
| 463 class RuntimeArchitecture(StandaloneArchitecture): | 456 class RuntimeArchitecture(StandaloneArchitecture): |
| 464 """Executes tests on the standalone VM (runtime).""" | 457 """Executes tests on the standalone VM (runtime).""" |
| 465 | 458 |
| 466 def __init__(self, root_path, arch, mode, test): | 459 def __init__(self, root_path, arch, mode, FOOBAR, test): |
| 467 super(RuntimeArchitecture, self).__init__(root_path, arch, mode, test) | 460 super(RuntimeArchitecture, self).__init__(root_path, arch, mode, FOOBAR, |
| 461 test) | |
| 468 | 462 |
| 469 def GetExecutable(self): | 463 def GetExecutable(self): |
| 470 """Returns the name of the executable to run the test.""" | 464 """Returns the name of the executable to run the test.""" |
| 471 return os.path.abspath(os.path.join(self.build_root, 'dart_bin')) | 465 return os.path.abspath(os.path.join(self.build_root, 'dart_bin')) |
| 472 | 466 |
| 473 | 467 |
| 474 def ExecutePipedCommand(cmd, verbose): | 468 def ExecutePipedCommand(cmd, verbose): |
| 475 """Execute a command in a subprocess.""" | 469 """Execute a command in a subprocess.""" |
| 476 if verbose: | 470 if verbose: |
| 477 print 'Executing: ' + ' '.join(cmd) | 471 print 'Executing: ' + ' '.join(cmd) |
| 478 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 472 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 479 (output, err) = pipe.communicate() | 473 (output, err) = pipe.communicate() |
| 480 if pipe.returncode != 0 and verbose: | 474 if pipe.returncode != 0 and verbose: |
| 481 print 'Execution failed: ' + output + '\n' + err | 475 print 'Execution failed: ' + output + '\n' + err |
| 482 print output | 476 print output |
| 483 print err | 477 print err |
| 484 return pipe.returncode, output, err | 478 return pipe.returncode, output, err |
| 485 | 479 |
| 486 | 480 |
| 487 def ExecuteCommand(cmd, verbose=False): | 481 def ExecuteCommand(cmd, verbose=False): |
| 488 """Execute a command in a subprocess.""" | 482 """Execute a command in a subprocess.""" |
| 489 if verbose: print 'Executing: ' + ' '.join(cmd) | 483 if verbose: print 'Executing: ' + ' '.join(cmd) |
| 490 return subprocess.call(cmd) | 484 return subprocess.call(cmd) |
| 491 | 485 |
| 492 | 486 |
| 493 def GetArchitecture(arch, mode, test): | 487 def GetArchitecture(arch, mode, FOOBAR, test): |
| 494 root_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..')) | 488 root_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..')) |
| 495 if arch == 'chromium': | 489 if FOOBAR == 'chromium': |
| 496 return ChromiumArchitecture(root_path, arch, mode, test) | 490 return ChromiumArchitecture(root_path, arch, mode, FOOBAR, test) |
| 497 | 491 |
| 498 elif arch == 'dartium': | 492 elif FOOBAR == 'dartium': |
| 499 return DartiumArchitecture(root_path, arch, mode, test) | 493 return DartiumArchitecture(root_path, arch, mode, FOOBAR, test) |
| 500 | 494 |
| 501 elif arch in ['ia32', 'x64', 'simarm', 'arm']: | 495 elif FOOBAR == 'vm': |
| 502 return RuntimeArchitecture(root_path, arch, mode, test) | 496 return RuntimeArchitecture(root_path, arch, mode, FOOBAR, test) |
| 503 | 497 |
| 504 elif arch == 'dartc': | 498 elif FOOBAR == 'dartc': |
| 505 return DartcArchitecture(root_path, arch, mode, test) | 499 return DartcArchitecture(root_path, arch, mode, FOOBAR, test) |
| OLD | NEW |