| 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 """Returns True if the source has a #library statement.""" | 140 """Returns True if the source has a #library statement.""" |
| 151 if LIBRARY_DEFINITION_PATTERN.search(source): | 141 if LIBRARY_DEFINITION_PATTERN.search(source): |
| 152 return True | 142 return True |
| 153 if SOURCE_OR_IMPORT_PATTERN.search(source): | 143 if SOURCE_OR_IMPORT_PATTERN.search(source): |
| 154 print ('WARNING for %s: Browser tests need a #library ' | 144 print ('WARNING for %s: Browser tests need a #library ' |
| 155 'for a file that #import or #source' % test) | 145 'for a file that #import or #source' % test) |
| 156 return False | 146 return False |
| 157 | 147 |
| 158 | 148 |
| 159 class Architecture(object): | 149 class Architecture(object): |
| 160 """Definitions for different ways to test based on the --arch flag.""" | 150 """Definitions for different ways to test based on the component flag.""" |
| 161 | 151 |
| 162 def __init__(self, root_path, arch, mode, test): | 152 def __init__(self, root_path, arch, mode, component, test): |
| 163 self.root_path = root_path | 153 self.root_path = root_path |
| 164 self.arch = arch | 154 self.arch = arch |
| 165 self.mode = mode | 155 self.mode = mode |
| 156 self.component = component |
| 166 self.test = test | 157 self.test = test |
| 167 self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch) | 158 self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch) |
| 168 source = file(test).read() | 159 source = file(test).read() |
| 169 self.vm_options = [] | 160 self.vm_options = [] |
| 170 self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN, | 161 self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN, |
| 171 source, | 162 source, |
| 172 root_path) | 163 root_path) |
| 173 self.is_web_test = _IsWebTest(source) | 164 self.is_web_test = _IsWebTest(source) |
| 174 self.temp_dir = None | 165 self.temp_dir = None |
| 175 | 166 |
| 176 def HasFatalTypeErrors(self): | 167 def HasFatalTypeErrors(self): |
| 177 """Returns True if this type of arch supports --fatal-type-errors.""" | 168 """Returns True if this type of component supports --fatal-type-errors.""" |
| 178 return False | 169 return False |
| 179 | 170 |
| 180 def GetTestFrameworkPath(self): | 171 def GetTestFrameworkPath(self): |
| 181 """Path to dart source (TestFramework.dart) for testing framework.""" | 172 """Path to dart source (TestFramework.dart) for testing framework.""" |
| 182 return os.path.join(self.root_path, 'tests', 'isolate', 'src', | 173 return os.path.join(self.root_path, 'tests', 'isolate', 'src', |
| 183 'TestFramework.dart') | 174 'TestFramework.dart') |
| 184 | 175 |
| 185 | 176 |
| 186 class BrowserArchitecture(Architecture): | 177 class BrowserArchitecture(Architecture): |
| 187 """Architecture that runs compiled dart->JS through a browser.""" | 178 """Architecture that runs compiled dart->JS through a browser.""" |
| 188 | 179 |
| 189 def __init__(self, root_path, arch, mode, test): | 180 def __init__(self, root_path, arch, mode, component, test): |
| 190 super(BrowserArchitecture, self).__init__(root_path, arch, mode, test) | 181 super(BrowserArchitecture, self).__init__(root_path, arch, mode, component, |
| 182 test) |
| 191 self.temp_dir = tempfile.mkdtemp() | 183 self.temp_dir = tempfile.mkdtemp() |
| 192 if not self.is_web_test: self.GenerateWebTestScript() | 184 if not self.is_web_test: self.GenerateWebTestScript() |
| 193 | 185 |
| 194 def GetTestScriptFile(self): | 186 def GetTestScriptFile(self): |
| 195 """Returns the name of the .dart file to compile.""" | 187 """Returns the name of the .dart file to compile.""" |
| 196 if self.is_web_test: return os.path.abspath(self.test) | 188 if self.is_web_test: return os.path.abspath(self.test) |
| 197 return os.path.join(self.temp_dir, 'test.dart') | 189 return os.path.join(self.temp_dir, 'test.dart') |
| 198 | 190 |
| 199 def GetHtmlContents(self): | 191 def GetHtmlContents(self): |
| 200 """Fills in the HTML_CONTENTS template with info for this architecture.""" | 192 """Fills in the HTML_CONTENTS template with info for this architecture.""" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 225 os.makedirs(html_path) | 217 os.makedirs(html_path) |
| 226 return html_path | 218 return html_path |
| 227 | 219 |
| 228 return self.temp_dir | 220 return self.temp_dir |
| 229 | 221 |
| 230 def GetTestContents(self, library_file): | 222 def GetTestContents(self, library_file): |
| 231 """Pastes a preamble on the front of the .dart file before testing.""" | 223 """Pastes a preamble on the front of the .dart file before testing.""" |
| 232 unittest_path = os.path.join(self.root_path, 'client', 'testing', | 224 unittest_path = os.path.join(self.root_path, 'client', 'testing', |
| 233 'unittest', 'unittest.dart') | 225 'unittest', 'unittest.dart') |
| 234 | 226 |
| 235 if self.arch == 'chromium': | 227 if self.component == 'chromium': |
| 236 dom_path = os.path.join(self.root_path, 'client', 'testing', | 228 dom_path = os.path.join(self.root_path, 'client', 'testing', |
| 237 'unittest', 'dom_for_unittest.dart') | 229 'unittest', 'dom_for_unittest.dart') |
| 238 else: | 230 else: |
| 239 dom_path = os.path.join('dart:dom') | 231 dom_path = os.path.join('dart:dom') |
| 240 | 232 |
| 241 test_framework_path = self.GetTestFrameworkPath() | 233 test_framework_path = self.GetTestFrameworkPath() |
| 242 test_path = os.path.abspath(self.test) | 234 test_path = os.path.abspath(self.test) |
| 243 | 235 |
| 244 inputs = { | 236 inputs = { |
| 245 'unittest': unittest_path, | 237 'unittest': unittest_path, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 def Cleanup(self): | 322 def Cleanup(self): |
| 331 """Removes temporary files created for the test.""" | 323 """Removes temporary files created for the test.""" |
| 332 if self.temp_dir: | 324 if self.temp_dir: |
| 333 shutil.rmtree(self.temp_dir) | 325 shutil.rmtree(self.temp_dir) |
| 334 self.temp_dir = None | 326 self.temp_dir = None |
| 335 | 327 |
| 336 | 328 |
| 337 class ChromiumArchitecture(BrowserArchitecture): | 329 class ChromiumArchitecture(BrowserArchitecture): |
| 338 """Architecture that runs compiled dart->JS through a chromium DRT.""" | 330 """Architecture that runs compiled dart->JS through a chromium DRT.""" |
| 339 | 331 |
| 340 def __init__(self, root_path, arch, mode, test): | 332 def __init__(self, root_path, arch, mode, component, test): |
| 341 super(ChromiumArchitecture, self).__init__(root_path, arch, mode, test) | 333 super(ChromiumArchitecture, self).__init__(root_path, arch, mode, component,
test) |
| 342 | 334 |
| 343 def GetScriptType(self): | 335 def GetScriptType(self): |
| 344 return 'text/javascript' | 336 return 'text/javascript' |
| 345 | 337 |
| 346 def GetScriptPath(self): | 338 def GetScriptPath(self): |
| 347 """Returns the name of the output .js file to create.""" | 339 """Returns the name of the output .js file to create.""" |
| 348 path = self.GetTestScriptFile() | 340 path = self.GetTestScriptFile() |
| 349 return os.path.abspath(os.path.join(self.temp_dir, | 341 return os.path.abspath(os.path.join(self.temp_dir, |
| 350 os.path.basename(path) + '.js')) | 342 os.path.basename(path) + '.js')) |
| 351 | 343 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 374 cmd.append(self.GetTestScriptFile()) | 366 cmd.append(self.GetTestScriptFile()) |
| 375 return cmd | 367 return cmd |
| 376 | 368 |
| 377 def Compile(self): | 369 def Compile(self): |
| 378 return ExecuteCommand(self.GetCompileCommand()) | 370 return ExecuteCommand(self.GetCompileCommand()) |
| 379 | 371 |
| 380 | 372 |
| 381 class DartiumArchitecture(BrowserArchitecture): | 373 class DartiumArchitecture(BrowserArchitecture): |
| 382 """Architecture that runs dart in an VM embedded in DumpRenderTree.""" | 374 """Architecture that runs dart in an VM embedded in DumpRenderTree.""" |
| 383 | 375 |
| 384 def __init__(self, root_path, arch, mode, test): | 376 def __init__(self, root_path, arch, mode, component, test): |
| 385 super(DartiumArchitecture, self).__init__(root_path, arch, mode, test) | 377 super(DartiumArchitecture, self).__init__(root_path, arch, mode, component,
test) |
| 386 | 378 |
| 387 def GetScriptType(self): | 379 def GetScriptType(self): |
| 388 return 'application/dart' | 380 return 'application/dart' |
| 389 | 381 |
| 390 def GetScriptPath(self): | 382 def GetScriptPath(self): |
| 391 return 'file:///' + self.GetTestScriptFile() | 383 return 'file:///' + self.GetTestScriptFile() |
| 392 | 384 |
| 393 def GetHtmlName(self): | 385 def GetHtmlName(self): |
| 394 path = os.path.relpath(self.test, self.root_path).replace(os.sep, '_') | 386 path = os.path.relpath(self.test, self.root_path).replace(os.sep, '_') |
| 395 return path + '.dartium.html' | 387 return path + '.dartium.html' |
| 396 | 388 |
| 397 def GetCompileCommand(self, fatal_static_type_errors=False): | 389 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 398 fatal_static_type_errors = fatal_static_type_errors # shutup lint! | 390 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 399 return None | 391 return None |
| 400 | 392 |
| 401 def Compile(self): | 393 def Compile(self): |
| 402 return 0 | 394 return 0 |
| 403 | 395 |
| 404 | 396 |
| 405 class StandaloneArchitecture(Architecture): | 397 class StandaloneArchitecture(Architecture): |
| 406 """Base class for architectures that run tests without a browser.""" | 398 """Base class for architectures that run tests without a browser.""" |
| 407 | 399 |
| 408 def __init__(self, root_path, arch, mode, test): | 400 def __init__(self, root_path, arch, mode, component, test): |
| 409 super(StandaloneArchitecture, self).__init__(root_path, arch, mode, test) | 401 super(StandaloneArchitecture, self).__init__(root_path, arch, mode, componen
t, |
| 402 test) |
| 410 | 403 |
| 411 def GetCompileCommand(self, fatal_static_type_errors=False): | 404 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 412 fatal_static_type_errors = fatal_static_type_errors # shutup lint! | 405 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 413 return None | 406 return None |
| 414 | 407 |
| 415 def GetRunCommand(self, fatal_static_type_errors=False): | 408 def GetRunCommand(self, fatal_static_type_errors=False): |
| 416 """Returns a command line to execute for the test.""" | 409 """Returns a command line to execute for the test.""" |
| 417 dart = self.GetExecutable() | 410 dart = self.GetExecutable() |
| 418 test_name = os.path.basename(self.test) | 411 test_name = os.path.basename(self.test) |
| 419 test_path = os.path.abspath(self.test) | 412 test_path = os.path.abspath(self.test) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 443 | 436 |
| 444 def Cleanup(self): | 437 def Cleanup(self): |
| 445 return | 438 return |
| 446 | 439 |
| 447 | 440 |
| 448 # Long term, we should do the running machinery that is currently in | 441 # Long term, we should do the running machinery that is currently in |
| 449 # DartRunner.java | 442 # DartRunner.java |
| 450 class DartcArchitecture(StandaloneArchitecture): | 443 class DartcArchitecture(StandaloneArchitecture): |
| 451 """Runs the Dart ->JS compiler then runs the result in a standalone JS VM.""" | 444 """Runs the Dart ->JS compiler then runs the result in a standalone JS VM.""" |
| 452 | 445 |
| 453 def __init__(self, root_path, arch, mode, test): | 446 def __init__(self, root_path, arch, mode, component, test): |
| 454 super(DartcArchitecture, self).__init__(root_path, arch, mode, test) | 447 super(DartcArchitecture, self).__init__(root_path, arch, mode, component, te
st) |
| 455 | 448 |
| 456 def GetExecutable(self): | 449 def GetExecutable(self): |
| 457 """Returns the name of the executable to run the test.""" | 450 """Returns the name of the executable to run the test.""" |
| 458 return os.path.abspath(os.path.join(self.build_root, | 451 return os.path.abspath(os.path.join(self.build_root, |
| 459 'compiler', | 452 'compiler', |
| 460 'bin', | 453 'bin', |
| 461 'dartc_test')) | 454 'dartc_test')) |
| 462 | 455 |
| 463 def GetFatalTypeErrorsFlags(self): | 456 def GetFatalTypeErrorsFlags(self): |
| 464 return ['--fatal-type-errors'] | 457 return ['--fatal-type-errors'] |
| 465 | 458 |
| 466 def HasFatalTypeErrors(self): | 459 def HasFatalTypeErrors(self): |
| 467 return True | 460 return True |
| 468 | 461 |
| 469 def GetRunCommand(self, fatal_static_type_errors=False): | 462 def GetRunCommand(self, fatal_static_type_errors=False): |
| 470 """Returns a command line to execute for the test.""" | 463 """Returns a command line to execute for the test.""" |
| 471 cmd = super(DartcArchitecture, self).GetRunCommand( | 464 cmd = super(DartcArchitecture, self).GetRunCommand( |
| 472 fatal_static_type_errors) | 465 fatal_static_type_errors) |
| 473 return cmd | 466 return cmd |
| 474 | 467 |
| 475 | 468 |
| 476 class RuntimeArchitecture(StandaloneArchitecture): | 469 class RuntimeArchitecture(StandaloneArchitecture): |
| 477 """Executes tests on the standalone VM (runtime).""" | 470 """Executes tests on the standalone VM (runtime).""" |
| 478 | 471 |
| 479 def __init__(self, root_path, arch, mode, test): | 472 def __init__(self, root_path, arch, mode, component, test): |
| 480 super(RuntimeArchitecture, self).__init__(root_path, arch, mode, test) | 473 super(RuntimeArchitecture, self).__init__(root_path, arch, mode, component, |
| 474 test) |
| 481 | 475 |
| 482 def GetExecutable(self): | 476 def GetExecutable(self): |
| 483 """Returns the name of the executable to run the test.""" | 477 """Returns the name of the executable to run the test.""" |
| 484 return os.path.abspath(os.path.join(self.build_root, 'dart_bin')) | 478 return os.path.abspath(os.path.join(self.build_root, 'dart_bin')) |
| 485 | 479 |
| 486 | 480 |
| 487 def ExecutePipedCommand(cmd, verbose): | 481 def ExecutePipedCommand(cmd, verbose): |
| 488 """Execute a command in a subprocess.""" | 482 """Execute a command in a subprocess.""" |
| 489 if verbose: | 483 if verbose: |
| 490 print 'Executing: ' + ' '.join(cmd) | 484 print 'Executing: ' + ' '.join(cmd) |
| 491 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 485 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 492 (output, err) = pipe.communicate() | 486 (output, err) = pipe.communicate() |
| 493 if pipe.returncode != 0 and verbose: | 487 if pipe.returncode != 0 and verbose: |
| 494 print 'Execution failed: ' + output + '\n' + err | 488 print 'Execution failed: ' + output + '\n' + err |
| 495 print output | 489 print output |
| 496 print err | 490 print err |
| 497 return pipe.returncode, output, err | 491 return pipe.returncode, output, err |
| 498 | 492 |
| 499 | 493 |
| 500 def ExecuteCommand(cmd, verbose=False): | 494 def ExecuteCommand(cmd, verbose=False): |
| 501 """Execute a command in a subprocess.""" | 495 """Execute a command in a subprocess.""" |
| 502 if verbose: print 'Executing: ' + ' '.join(cmd) | 496 if verbose: print 'Executing: ' + ' '.join(cmd) |
| 503 return subprocess.call(cmd) | 497 return subprocess.call(cmd) |
| 504 | 498 |
| 505 | 499 |
| 506 def GetArchitecture(arch, mode, test): | 500 def GetArchitecture(arch, mode, component, test): |
| 507 root_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..')) | 501 root_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..')) |
| 508 if arch == 'chromium': | 502 if component == 'chromium': |
| 509 return ChromiumArchitecture(root_path, arch, mode, test) | 503 return ChromiumArchitecture(root_path, arch, mode, component, test) |
| 510 | 504 |
| 511 elif arch == 'dartium': | 505 elif component == 'dartium': |
| 512 return DartiumArchitecture(root_path, arch, mode, test) | 506 return DartiumArchitecture(root_path, arch, mode, component, test) |
| 513 | 507 |
| 514 elif arch in ['ia32', 'x64', 'simarm', 'arm']: | 508 elif component == 'vm': |
| 515 return RuntimeArchitecture(root_path, arch, mode, test) | 509 return RuntimeArchitecture(root_path, arch, mode, component, test) |
| 516 | 510 |
| 517 elif arch == 'dartc': | 511 elif component == 'dartc': |
| 518 return DartcArchitecture(root_path, arch, mode, test) | 512 return DartcArchitecture(root_path, arch, mode, component, test) |
| OLD | NEW |