| OLD | NEW |
| 1 #!/usr/bin/env python | |
| 2 # | |
| 3 # 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 |
| 4 # 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 |
| 5 # BSD-style license that can be found in the LICENSE file. | 3 # BSD-style license that can be found in the LICENSE file. |
| 6 # | 4 # |
| 7 | 5 |
| 8 """ | 6 """Runs a Dart unit test in different configurations. |
| 9 Runs a Dart unit test in different configurations: dartium, chromium, ia32, x64, | |
| 10 arm, simarm, and dartc. Example: | |
| 11 | 7 |
| 12 run.py --arch=dartium --mode=release --test=Test.dart | 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 |
| 13 """ | 14 """ |
| 14 | 15 |
| 15 import os | 16 import os |
| 16 from os.path import join, abspath, dirname, basename, relpath | |
| 17 import platform | 17 import platform |
| 18 import re | 18 import re |
| 19 import shutil | 19 import shutil |
| 20 import subprocess | 20 import subprocess |
| 21 import sys | 21 import sys |
| 22 import tempfile | 22 import tempfile |
| 23 |
| 23 import utils | 24 import utils |
| 24 | 25 |
| 25 OS_GUESS = utils.GuessOS() | 26 OS_GUESS = utils.GuessOS() |
| 26 | 27 |
| 27 HTML_CONTENTS = ''' | 28 HTML_CONTENTS = """ |
| 28 <html> | 29 <html> |
| 29 <head> | 30 <head> |
| 30 <title> Test %(title)s </title> | 31 <title> Test %(title)s </title> |
| 31 <style> | 32 <style> |
| 32 .unittest-table { font-family:monospace; border:1px; } | 33 .unittest-table { font-family:monospace; border:1px; } |
| 33 .unittest-pass { background: #6b3;} | 34 .unittest-pass { background: #6b3;} |
| 34 .unittest-fail { background: #d55;} | 35 .unittest-fail { background: #d55;} |
| 35 .unittest-error { background: #a11;} | 36 .unittest-error { background: #a11;} |
| 36 </style> | 37 </style> |
| 37 </head> | 38 </head> |
| 38 <body> | 39 <body> |
| 39 <h1> Running %(title)s </h1> | 40 <h1> Running %(title)s </h1> |
| 40 <script type="text/javascript" src="%(controller_script)s"></script> | 41 <script type="text/javascript" src="%(controller_script)s"></script> |
| 41 <script type="%(script_type)s" src="%(source_script)s"></script> | 42 <script type="%(script_type)s" src="%(source_script)s"></script> |
| 42 <script type="text/javascript"> | 43 <script type="text/javascript"> |
| 43 // If 'startedDartTest' is not set, that means that the test did not have | 44 // If 'startedDartTest' is not set, that means that the test did not have |
| 44 // a chance to load. This will happen when a load error occurs in the VM. | 45 // a chance to load. This will happen when a load error occurs in the VM. |
| 45 // Give the machine time to start up. | 46 // Give the machine time to start up. |
| 46 setTimeout(function() { | 47 setTimeout(function() { |
| 47 if (window.layoutTestController | 48 if (window.layoutTestController |
| 48 && !window.layoutTestController.startedDartTest) { | 49 && !window.layoutTestController.startedDartTest) { |
| 49 window.layoutTestController.notifyDone(); | 50 window.layoutTestController.notifyDone(); |
| 50 } | 51 } |
| 51 }, 3000); | 52 }, 3000); |
| 52 </script> | 53 </script> |
| 53 </body> | 54 </body> |
| 54 </html> | 55 </html> |
| 55 ''' | 56 """ |
| 56 | 57 |
| 57 DART_TEST_AS_LIBRARY = ''' | 58 DART_TEST_AS_LIBRARY = """ |
| 58 #library('test'); | 59 #library('test'); |
| 59 #source('%(test)s'); | 60 #source('%(test)s'); |
| 60 ''' | 61 """ |
| 61 | 62 |
| 62 DART_CONTENTS = ''' | 63 DART_CONTENTS = """ |
| 63 #library('test'); | 64 #library('test'); |
| 64 | 65 |
| 65 #import('%(dom_library)s'); | 66 #import('%(dom_library)s'); |
| 66 #import('%(test_framework)s'); | 67 #import('%(test_framework)s'); |
| 67 | 68 |
| 68 #import('%(library)s', prefix: "Test"); | 69 #import('%(library)s', prefix: "Test"); |
| 69 | 70 |
| 70 pass() { | 71 pass() { |
| 71 document.body.innerHTML = 'PASS'; | 72 document.body.innerHTML = 'PASS'; |
| 72 window.postMessage('unittest-suite-done', '*'); | 73 window.postMessage('unittest-suite-done', '*'); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 94 } | 95 } |
| 95 }; | 96 }; |
| 96 try { | 97 try { |
| 97 Test.main(); | 98 Test.main(); |
| 98 if (!needsToWait) pass(); | 99 if (!needsToWait) pass(); |
| 99 mainIsFinished = true; | 100 mainIsFinished = true; |
| 100 } catch(var e, var trace) { | 101 } catch(var e, var trace) { |
| 101 fail(e, trace); | 102 fail(e, trace); |
| 102 } | 103 } |
| 103 } | 104 } |
| 104 ''' | 105 """ |
| 105 | 106 |
| 106 | 107 |
| 107 # Patterns for matching test options in .dart files. | 108 # Patterns for matching test options in .dart files. |
| 108 VM_OPTIONS_PATTERN = re.compile(r"// VMOptions=(.*)") | 109 VM_OPTIONS_PATTERN = re.compile(r'// VMOptions=(.*)') |
| 109 DART_OPTIONS_PATTERN = re.compile(r"// DartOptions=(.*)") | 110 DART_OPTIONS_PATTERN = re.compile(r'// DartOptions=(.*)') |
| 110 | 111 |
| 111 # Pattern for checking if the test is a web test. | 112 # Pattern for checking if the test is a web test. |
| 112 DOM_IMPORT_PATTERN = re.compile(r"^#import.*(dart:dom|html.dart)'\);", | 113 DOM_IMPORT_PATTERN = re.compile(r'#import.*(dart:dom|html.dart).*\);', |
| 113 re.MULTILINE) | 114 re.MULTILINE) |
| 114 | 115 |
| 115 # Pattern for matching the output of a browser test. | 116 # Pattern for matching the output of a browser test. |
| 116 BROWSER_OUTPUT_PASS_PATTERN = re.compile(r"^Content-Type: text/plain\nPASS$", | 117 BROWSER_OUTPUT_PASS_PATTERN = re.compile(r'^Content-Type: text/plain\nPASS$', |
| 117 re.MULTILINE) | 118 re.MULTILINE) |
| 118 | 119 |
| 119 # Pattern for checking if the test is a library in itself. | 120 # Pattern for checking if the test is a library in itself. |
| 120 LIBRARY_DEFINITION_PATTERN = re.compile(r"^#library\(.*\);", | 121 LIBRARY_DEFINITION_PATTERN = re.compile(r'^#library\(.*\);', |
| 121 re.MULTILINE) | 122 re.MULTILINE) |
| 122 SOURCE_OR_IMPORT_PATTERN = re.compile(r"^#(source|import)\(.*\);", | 123 SOURCE_OR_IMPORT_PATTERN = re.compile(r'^#(source|import)\(.*\);', |
| 123 re.MULTILINE) | 124 re.MULTILINE) |
| 124 | 125 |
| 125 | 126 |
| 126 class Error(Exception): | 127 class Error(Exception): |
| 128 """Base class for exceptions in this module.""" |
| 127 pass | 129 pass |
| 128 | 130 |
| 129 | 131 |
| 130 def IsWebTest(test, source): | 132 def _IsWebTest(source): |
| 133 """Returns True if the source includes a dart dom library #import.""" |
| 131 return DOM_IMPORT_PATTERN.search(source) | 134 return DOM_IMPORT_PATTERN.search(source) |
| 132 | 135 |
| 136 |
| 133 def IsLibraryDefinition(test, source): | 137 def IsLibraryDefinition(test, source): |
| 134 if LIBRARY_DEFINITION_PATTERN.search(source): return True | 138 """Returns True if the source has a #library statement.""" |
| 139 if LIBRARY_DEFINITION_PATTERN.search(source): |
| 140 return True |
| 135 if SOURCE_OR_IMPORT_PATTERN.search(source): | 141 if SOURCE_OR_IMPORT_PATTERN.search(source): |
| 136 print ("WARNING for %s: Browser tests need a #library " | 142 print ('WARNING for %s: Browser tests need a #library ' |
| 137 "for a file that #import or #source" % test) | 143 'for a file that #import or #source' % test) |
| 138 return False | 144 return False |
| 139 | 145 |
| 140 | 146 |
| 141 class Architecture(object): | 147 class Architecture(object): |
| 148 """Definitions for different ways to test based on the --arch flag.""" |
| 149 |
| 142 def __init__(self, root_path, arch, mode, test): | 150 def __init__(self, root_path, arch, mode, test): |
| 143 self.root_path = root_path; | 151 self.root_path = root_path |
| 144 self.arch = arch; | 152 self.arch = arch |
| 145 self.mode = mode; | 153 self.mode = mode |
| 146 self.test = test; | 154 self.test = test |
| 147 self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch) | 155 self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch) |
| 148 source = file(test).read() | 156 source = file(test).read() |
| 149 self.vm_options = utils.ParseTestOptions(VM_OPTIONS_PATTERN, | 157 self.vm_options = utils.ParseTestOptions(VM_OPTIONS_PATTERN, |
| 150 source, | 158 source, |
| 151 root_path) | 159 root_path) |
| 152 if not self.vm_options: self.vm_options = [] | 160 if not self.vm_options: self.vm_options = [] |
| 153 | 161 |
| 154 self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN, | 162 self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN, |
| 155 source, | 163 source, |
| 156 root_path) | 164 root_path) |
| 157 self.is_web_test = IsWebTest(test, source) | 165 self.is_web_test = _IsWebTest(source) |
| 158 self.temp_dir = None | 166 self.temp_dir = None |
| 159 | 167 |
| 160 def HasFatalTypeErrors(self): | 168 def HasFatalTypeErrors(self): |
| 169 """Returns True if this type of arch supports --fatal-type-errors.""" |
| 161 return False | 170 return False |
| 162 | 171 |
| 163 def GetTestFrameworkPath(self): | 172 def GetTestFrameworkPath(self): |
| 164 return join(self.root_path, 'tests', 'isolate', 'src', | 173 """Path to dart source (TestFramework.dart) for testing framework.""" |
| 165 'TestFramework.dart') | 174 return os.path.join(self.root_path, 'tests', 'isolate', 'src', |
| 175 'TestFramework.dart') |
| 176 |
| 166 | 177 |
| 167 class BrowserArchitecture(Architecture): | 178 class BrowserArchitecture(Architecture): |
| 179 """Architecture that runs compiled dart->JS through a browser.""" |
| 180 |
| 168 def __init__(self, root_path, arch, mode, test): | 181 def __init__(self, root_path, arch, mode, test): |
| 169 super(BrowserArchitecture, self).__init__(root_path, arch, mode, test) | 182 super(BrowserArchitecture, self).__init__(root_path, arch, mode, test) |
| 170 self.temp_dir = tempfile.mkdtemp(); | 183 self.temp_dir = tempfile.mkdtemp() |
| 171 if not self.is_web_test: self.GenerateWebTestScript() | 184 if not self.is_web_test: self.GenerateWebTestScript() |
| 172 | 185 |
| 173 def GetTestScriptFile(self): | 186 def GetTestScriptFile(self): |
| 174 """Returns the name of the .dart file to compile.""" | 187 """Returns the name of the .dart file to compile.""" |
| 175 if self.is_web_test: return abspath(self.test) | 188 if self.is_web_test: return os.path.abspath(self.test) |
| 176 return join(self.temp_dir, 'test.dart') | 189 return os.path.join(self.temp_dir, 'test.dart') |
| 177 | 190 |
| 178 def GetHtmlContents(self): | 191 def GetHtmlContents(self): |
| 192 """Fills in the HTML_CONTENTS template with info for this architecture.""" |
| 179 script_type = self.GetScriptType() | 193 script_type = self.GetScriptType() |
| 180 | 194 controller_path = os.path.join(self.root_path, 'client', 'testing', |
| 181 controller_path = join(self.root_path, | 195 'unittest', 'test_controller.js') |
| 182 'client', 'testing', 'unittest', 'test_controller.js') | 196 return HTML_CONTENTS % { |
| 183 | 197 'title': self.test, |
| 184 return HTML_CONTENTS % { 'title' : self.test, | 198 'controller_script': controller_path, |
| 185 'controller_script': controller_path, | 199 'script_type': script_type, |
| 186 'script_type' : script_type, | 200 'source_script': self.GetScriptPath() |
| 187 'source_script' : self.GetScriptPath() } | 201 } |
| 188 | 202 |
| 189 def GetHtmlPath(self): | 203 def GetHtmlPath(self): |
| 190 # Resources for web tests are relative to the 'html' file. We | 204 """Creates a path for the generated .html file. |
| 191 # output the 'html' file in the 'out' directory instead of the temporary | 205 |
| 192 # directory because we can easily go the the resources in 'client' through | 206 Resources for web tests are relative to the 'html' file. We |
| 193 # 'out'. | 207 output the 'html' file in the 'out' directory instead of the temporary |
| 208 directory because we can easily go the the resources in 'client' through |
| 209 'out'. |
| 210 |
| 211 Returns: |
| 212 Created path for the generated .html file. |
| 213 """ |
| 194 if self.is_web_test: | 214 if self.is_web_test: |
| 195 html_path = join(self.root_path, 'client', self.build_root) | 215 html_path = os.path.join(self.root_path, 'client', self.build_root) |
| 196 if not os.path.exists(html_path): os.makedirs(html_path) | 216 if not os.path.exists(html_path): |
| 217 os.makedirs(html_path) |
| 197 return html_path | 218 return html_path |
| 198 | 219 |
| 199 return self.temp_dir | 220 return self.temp_dir |
| 200 | 221 |
| 201 def GetTestContents(self, library_file): | 222 def GetTestContents(self, library_file): |
| 202 unittest_path = join(self.root_path, | 223 """Pastes a preamble on the front of the .dart file before testing.""" |
| 203 'client', 'testing', 'unittest', 'unittest.dart') | 224 unittest_path = os.path.join(self.root_path, 'client', 'testing', |
| 225 'unittest', 'unittest.dart') |
| 226 |
| 204 if self.arch == 'chromium': | 227 if self.arch == 'chromium': |
| 205 dom_path = join(self.root_path, | 228 dom_path = os.path.join(self.root_path, 'client', 'testing', |
| 206 'client', 'testing', 'unittest', 'dom_for_unittest.dart') | 229 'unittest', 'dom_for_unittest.dart') |
| 207 else: | 230 else: |
| 208 dom_path = join('dart:dom') | 231 dom_path = os.path.join('dart:dom') |
| 209 | 232 |
| 210 test_framework_path = self.GetTestFrameworkPath() | 233 test_framework_path = self.GetTestFrameworkPath() |
| 211 test_name = basename(self.test) | 234 test_path = os.path.abspath(self.test) |
| 212 test_path = abspath(self.test) | |
| 213 | 235 |
| 214 inputs = { 'unittest': unittest_path, | 236 inputs = { |
| 215 'test': test_path, | 237 'unittest': unittest_path, |
| 216 'dom_library': dom_path, | 238 'test': test_path, |
| 217 'test_framework': test_framework_path, | 239 'dom_library': dom_path, |
| 218 'library': library_file } | 240 'test_framework': test_framework_path, |
| 241 'library': library_file |
| 242 } |
| 219 return DART_CONTENTS % inputs | 243 return DART_CONTENTS % inputs |
| 220 | 244 |
| 221 def GenerateWebTestScript(self): | 245 def GenerateWebTestScript(self): |
| 246 """Creates a .dart file to run in the test.""" |
| 222 if IsLibraryDefinition(self.test, file(self.test).read()): | 247 if IsLibraryDefinition(self.test, file(self.test).read()): |
| 223 library_file = abspath(self.test) | 248 library_file = os.path.abspath(self.test) |
| 224 else: | 249 else: |
| 225 library_file = 'test_as_library.dart' | 250 library_file = 'test_as_library.dart' |
| 226 test_as_library = DART_TEST_AS_LIBRARY % { 'test': abspath(self.test) } | 251 test_as_library = DART_TEST_AS_LIBRARY % { |
| 227 test_as_library_file = join(self.temp_dir, library_file) | 252 'test': os.path.abspath(self.test) |
| 253 } |
| 254 test_as_library_file = os.path.join(self.temp_dir, library_file) |
| 228 f = open(test_as_library_file, 'w') | 255 f = open(test_as_library_file, 'w') |
| 229 f.write(test_as_library) | 256 f.write(test_as_library) |
| 230 f.close() | 257 f.close() |
| 231 | 258 |
| 232 app_output_file = self.GetTestScriptFile() | 259 app_output_file = self.GetTestScriptFile() |
| 233 f = open(app_output_file, 'w') | 260 f = open(app_output_file, 'w') |
| 234 f.write(self.GetTestContents(library_file)) | 261 f.write(self.GetTestContents(library_file)) |
| 235 f.close() | 262 f.close() |
| 236 | 263 |
| 237 def GetRunCommand(self, fatal_static_type_errors = False): | 264 def GetRunCommand(self, fatal_static_type_errors=False): |
| 265 """Returns a command line to execute for the test.""" |
| 266 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 238 # For some reason, DRT needs to be called via an absolute path | 267 # For some reason, DRT needs to be called via an absolute path |
| 239 drt_location = join(self.root_path, | 268 drt_location = os.path.join(self.root_path, 'client', 'tests', 'drt', |
| 240 'client', 'tests', 'drt', 'DumpRenderTree') | 269 'DumpRenderTree') |
| 241 | 270 |
| 242 # On Mac DumpRenderTree is a .app folder | 271 # On Mac DumpRenderTree is a .app folder |
| 243 if platform.system() == 'Darwin': | 272 if platform.system() == 'Darwin': |
| 244 drt_location += '.app/Contents/MacOS/DumpRenderTree' | 273 drt_location += '.app/Contents/MacOS/DumpRenderTree' |
| 245 | 274 |
| 246 drt_flags = [ '--no-timeout' ] | 275 drt_flags = ['--no-timeout'] |
| 247 dart_flags = '--dart-flags=--enable_asserts --enable_type_checks ' | 276 dart_flags = '--dart-flags=--enable_asserts --enable_type_checks ' |
| 248 dart_flags += ' '.join(self.vm_options) | 277 dart_flags += ' '.join(self.vm_options) |
| 249 | 278 |
| 250 if self.arch == 'chromium' and self.mode == 'release': | 279 if self.arch == 'chromium' and self.mode == 'release': |
| 251 dart_flags += ' --optimize ' | 280 dart_flags += ' --optimize ' |
| 252 drt_flags.append(dart_flags) | 281 drt_flags.append(dart_flags) |
| 253 | 282 |
| 254 html_output_file = join(self.GetHtmlPath(), self.GetHtmlName()) | 283 html_output_file = os.path.join(self.GetHtmlPath(), self.GetHtmlName()) |
| 255 f = open(html_output_file, 'w') | 284 f = open(html_output_file, 'w') |
| 256 f.write(self.GetHtmlContents()) | 285 f.write(self.GetHtmlContents()) |
| 257 f.close() | 286 f.close() |
| 258 | 287 |
| 259 drt_flags.append(html_output_file) | 288 drt_flags.append(html_output_file) |
| 260 | 289 |
| 261 return [drt_location] + drt_flags | 290 return [drt_location] + drt_flags |
| 262 | 291 |
| 263 def HasFailed(self, output): | 292 def HasFailed(self, output): |
| 293 """Return True if the 'PASS' result string isn't in the output.""" |
| 264 return not BROWSER_OUTPUT_PASS_PATTERN.search(output) | 294 return not BROWSER_OUTPUT_PASS_PATTERN.search(output) |
| 265 | 295 |
| 266 def RunTest(self, verbose): | 296 def RunTest(self, verbose): |
| 297 """Calls GetRunCommand() and executes the returned commandline. |
| 298 |
| 299 Args: |
| 300 verbose: if True, print additional diagnostics to stdout. |
| 301 |
| 302 Returns: |
| 303 Return code from executable. 0 == PASS, 253 = CRASH, anything |
| 304 else is treated as FAIL |
| 305 """ |
| 267 retcode = self.Compile() | 306 retcode = self.Compile() |
| 268 if retcode != 0: return 1 | 307 if retcode != 0: return 1 |
| 269 | 308 |
| 270 command = self.GetRunCommand() | 309 command = self.GetRunCommand() |
| 271 | 310 |
| 272 status, output, err = ExecutePipedCommand(command, verbose) | 311 unused_status, output, err = ExecutePipedCommand(command, verbose) |
| 273 if not self.HasFailed(output): | 312 if not self.HasFailed(output): |
| 274 self.Cleanup() | 313 self.Cleanup() |
| 275 return 0 | 314 return 0 |
| 276 | 315 |
| 277 # TODO(sigmund): print better error message, including how to run test | 316 # TODO(sigmund): print better error message, including how to run test |
| 278 # locally, and translate error traces using source map info. | 317 # locally, and translate error traces using source map info. |
| 279 print "(FAIL) test page:\033[31m " + command[2] + " \033[0m" | 318 print '(FAIL) test page:\033[31m %s \033[0m' % command[2] |
| 280 if verbose: | 319 if verbose: |
| 281 print 'Additional info: ' | 320 print 'Additional info: ' |
| 282 print output | 321 print output |
| 283 print err | 322 print err |
| 284 return 1 | 323 return 1 |
| 285 | 324 |
| 286 def Cleanup(self): | 325 def Cleanup(self): |
| 326 """Removes temporary files created for the test.""" |
| 287 if self.temp_dir: | 327 if self.temp_dir: |
| 288 shutil.rmtree(self.temp_dir) | 328 shutil.rmtree(self.temp_dir) |
| 289 self.temp_dir = None | 329 self.temp_dir = None |
| 290 | 330 |
| 291 | 331 |
| 292 class ChromiumArchitecture(BrowserArchitecture): | 332 class ChromiumArchitecture(BrowserArchitecture): |
| 333 """Architecture that runs compiled dart->JS through a chromium DRT.""" |
| 334 |
| 293 def __init__(self, root_path, arch, mode, test): | 335 def __init__(self, root_path, arch, mode, test): |
| 294 super(ChromiumArchitecture, self).__init__(root_path, arch, mode, test) | 336 super(ChromiumArchitecture, self).__init__(root_path, arch, mode, test) |
| 295 | 337 |
| 296 def GetScriptType(self): | 338 def GetScriptType(self): |
| 297 return 'text/javascript' | 339 return 'text/javascript' |
| 298 | 340 |
| 299 def GetScriptPath(self): | 341 def GetScriptPath(self): |
| 300 """ Returns the name of the output .js file to create """ | 342 """Returns the name of the output .js file to create.""" |
| 301 path = self.GetTestScriptFile() | 343 path = self.GetTestScriptFile() |
| 302 return abspath(os.path.join(self.temp_dir, | 344 return os.path.abspath(os.path.join(self.temp_dir, |
| 303 os.path.basename(path) + '.js')) | 345 os.path.basename(path) + '.js')) |
| 304 | |
| 305 | 346 |
| 306 def GetHtmlName(self): | 347 def GetHtmlName(self): |
| 307 return relpath(self.test, self.root_path).replace(os.sep, '_') + '.html' | 348 """Returns the name of the output .html file to create.""" |
| 349 relpath = os.path.relpath(self.test, self.root_path) |
| 350 return relpath.replace(os.sep, '_') + '.html' |
| 308 | 351 |
| 309 def GetCompileCommand(self, fatal_static_type_errors=False): | 352 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 310 """ Returns cmdline as an array to invoke the compiler on this test""" | 353 """Returns cmdline as an array to invoke the compiler on this test.""" |
| 354 |
| 311 # We need an absolute path because the compilation will run | 355 # We need an absolute path because the compilation will run |
| 312 # in a temporary directory. | 356 # in a temporary directory. |
| 313 | 357 build_root = utils.GetBuildRoot(OS_GUESS, self.mode, 'dartc') |
| 314 dartc = abspath(join(utils.GetBuildRoot(OS_GUESS, self.mode, 'dartc'), | 358 dartc = os.path.abspath(os.path.join(build_root, 'compiler', 'bin', |
| 315 'compiler', | 359 'dartc')) |
| 316 'bin', | |
| 317 'dartc')) | |
| 318 if utils.IsWindows(): dartc += '.exe' | 360 if utils.IsWindows(): dartc += '.exe' |
| 319 cmd = [dartc, '--work', self.temp_dir] | 361 cmd = [dartc, '--work', self.temp_dir] |
| 320 cmd += self.vm_options | 362 cmd += self.vm_options |
| 321 cmd += ['--out', self.GetScriptPath()] | 363 cmd += ['--out', self.GetScriptPath()] |
| 322 if fatal_static_type_errors: | 364 if fatal_static_type_errors: |
| 365 # TODO(zundel): update to --fatal_type_errors for both VM and Compiler |
| 323 cmd.append('-fatal-type-errors') | 366 cmd.append('-fatal-type-errors') |
| 324 cmd.append(self.GetTestScriptFile()) | 367 cmd.append(self.GetTestScriptFile()) |
| 325 return cmd | 368 return cmd |
| 326 | 369 |
| 327 def Compile(self): | 370 def Compile(self): |
| 328 return ExecuteCommand(self.GetCompileCommand()) | 371 return ExecuteCommand(self.GetCompileCommand()) |
| 329 | 372 |
| 330 | 373 |
| 331 class DartiumArchitecture(BrowserArchitecture): | 374 class DartiumArchitecture(BrowserArchitecture): |
| 375 """Architecture that runs dart in an VM embedded in DumpRenderTree.""" |
| 376 |
| 332 def __init__(self, root_path, arch, mode, test): | 377 def __init__(self, root_path, arch, mode, test): |
| 333 super(DartiumArchitecture, self).__init__(root_path, arch, mode, test) | 378 super(DartiumArchitecture, self).__init__(root_path, arch, mode, test) |
| 334 | 379 |
| 335 def GetScriptType(self): | 380 def GetScriptType(self): |
| 336 return 'application/dart' | 381 return 'application/dart' |
| 337 | 382 |
| 338 def GetScriptPath(self): | 383 def GetScriptPath(self): |
| 339 return 'file:///' + self.GetTestScriptFile() | 384 return 'file:///' + self.GetTestScriptFile() |
| 340 | 385 |
| 341 def GetHtmlName(self): | 386 def GetHtmlName(self): |
| 342 path = relpath(self.test, self.root_path).replace(os.sep, '_') | 387 path = os.path.relpath(self.test, self.root_path).replace(os.sep, '_') |
| 343 return path + '.dartium.html' | 388 return path + '.dartium.html' |
| 344 | 389 |
| 345 def GetCompileCommand(self, fatal_static_type_errors=False): | 390 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 391 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 346 return None | 392 return None |
| 347 | 393 |
| 348 def Compile(self): | 394 def Compile(self): |
| 349 return 0 | 395 return 0 |
| 350 | 396 |
| 351 | 397 |
| 352 class StandaloneArchitecture(Architecture): | 398 class StandaloneArchitecture(Architecture): |
| 399 """Base class for architectures that run tests without a browser.""" |
| 400 |
| 353 def __init__(self, root_path, arch, mode, test): | 401 def __init__(self, root_path, arch, mode, test): |
| 354 super(StandaloneArchitecture, self).__init__(root_path, arch, mode, test) | 402 super(StandaloneArchitecture, self).__init__(root_path, arch, mode, test) |
| 355 | 403 |
| 356 def GetCompileCommand(self, fatal_static_type_errors=False): | 404 def GetCompileCommand(self, fatal_static_type_errors=False): |
| 405 fatal_static_type_errors = fatal_static_type_errors # shutup lint! |
| 357 return None | 406 return None |
| 358 | 407 |
| 359 def GetRunCommand(self, fatal_static_type_errors=False): | 408 def GetRunCommand(self, fatal_static_type_errors=False): |
| 409 """Returns a command line to execute for the test.""" |
| 360 dart = self.GetExecutable() | 410 dart = self.GetExecutable() |
| 361 test_name = basename(self.test) | 411 test_name = os.path.basename(self.test) |
| 362 test_path = abspath(self.test) | 412 test_path = os.path.abspath(self.test) |
| 363 command = [dart] + self.vm_options | 413 command = [dart] + self.vm_options |
| 364 (classname, extension) = os.path.splitext(test_name) | 414 (classname, extension) = os.path.splitext(test_name) |
| 365 if self.dart_options: | 415 if self.dart_options: |
| 366 command += self.dart_options | 416 command += self.dart_options |
| 367 elif (extension == '.dart'): | 417 elif extension == '.dart': |
| 368 if fatal_static_type_errors: | 418 if fatal_static_type_errors: |
| 369 command += self.GetFatalTypeErrorsFlags() | 419 command += self.GetFatalTypeErrorsFlags() |
| 370 if '_' in classname: | 420 if '_' in classname: |
| 371 (classname, sep, tag) = classname.rpartition('_') | 421 (classname, unused_sep, unused_tag) = classname.rpartition('_') |
| 372 command += [test_path] | 422 command += [test_path] |
| 373 else: | 423 else: |
| 374 command += ['--', test_path] | 424 command += ['--', test_path] |
| 375 | 425 |
| 376 return command | 426 return command |
| 377 | 427 |
| 378 def GetFatalTypeErrorsFlags(self): | 428 def GetFatalTypeErrorsFlags(self): |
| 379 return [] | 429 return [] |
| 380 | 430 |
| 381 def RunTest(self, verbose): | 431 def RunTest(self, verbose): |
| 382 command = self.GetRunCommand() | 432 command = self.GetRunCommand() |
| 383 return ExecuteCommand(command, verbose) | 433 return ExecuteCommand(command, verbose) |
| 384 | 434 |
| 385 def Cleanup(self): | 435 def Cleanup(self): |
| 386 return | 436 return |
| 387 | 437 |
| 388 | 438 |
| 389 # Long term, we should do the running machinery that is currently in | 439 # Long term, we should do the running machinery that is currently in |
| 390 # DartRunner.java | 440 # DartRunner.java |
| 391 class DartcArchitecture(StandaloneArchitecture): | 441 class DartcArchitecture(StandaloneArchitecture): |
| 442 """Runs the Dart ->JS compiler then runs the result in a standalone JS VM.""" |
| 443 |
| 392 def __init__(self, root_path, arch, mode, test): | 444 def __init__(self, root_path, arch, mode, test): |
| 393 super(DartcArchitecture, self).__init__(root_path, arch, mode, test) | 445 super(DartcArchitecture, self).__init__(root_path, arch, mode, test) |
| 394 | 446 |
| 395 def GetExecutable(self): | 447 def GetExecutable(self): |
| 396 return abspath(join(self.build_root, 'compiler', 'bin', 'dartc_test')) | 448 """Returns the name of the executable to run the test.""" |
| 449 return os.path.abspath(os.path.join(self.build_root, |
| 450 'compiler', |
| 451 'bin', |
| 452 'dartc_test')) |
| 397 | 453 |
| 398 def GetFatalTypeErrorsFlags(self): | 454 def GetFatalTypeErrorsFlags(self): |
| 399 return ['--fatal-type-errors'] | 455 return ['--fatal-type-errors'] |
| 400 | 456 |
| 401 def HasFatalTypeErrors(self): | 457 def HasFatalTypeErrors(self): |
| 402 return True | 458 return True |
| 403 | 459 |
| 404 def GetRunCommand(self, fatal_static_type_errors=False): | 460 def GetRunCommand(self, fatal_static_type_errors=False): |
| 461 """Returns a command line to execute for the test.""" |
| 405 cmd = super(DartcArchitecture, self).GetRunCommand( | 462 cmd = super(DartcArchitecture, self).GetRunCommand( |
| 406 fatal_static_type_errors) | 463 fatal_static_type_errors) |
| 407 return cmd | 464 return cmd |
| 408 | 465 |
| 409 | 466 |
| 410 class RuntimeArchitecture(StandaloneArchitecture): | 467 class RuntimeArchitecture(StandaloneArchitecture): |
| 468 """Executes tests on the standalone VM (runtime).""" |
| 469 |
| 411 def __init__(self, root_path, arch, mode, test): | 470 def __init__(self, root_path, arch, mode, test): |
| 412 super(RuntimeArchitecture, self).__init__(root_path, arch, mode, test) | 471 super(RuntimeArchitecture, self).__init__(root_path, arch, mode, test) |
| 413 | 472 |
| 414 def GetExecutable(self): | 473 def GetExecutable(self): |
| 415 return abspath(join(self.build_root, 'dart_bin')) | 474 """Returns the name of the executable to run the test.""" |
| 475 return os.path.abspath(os.path.join(self.build_root, 'dart_bin')) |
| 416 | 476 |
| 417 | 477 |
| 418 def ExecutePipedCommand(cmd, verbose): | 478 def ExecutePipedCommand(cmd, verbose): |
| 419 """Execute a command in a subprocess. | 479 """Execute a command in a subprocess.""" |
| 420 """ | 480 if verbose: |
| 421 if verbose: print 'Executing: ' + ' '.join(cmd) | 481 print 'Executing: ' + ' '.join(cmd) |
| 422 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 482 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 423 (output, err) = pipe.communicate() | 483 (output, err) = pipe.communicate() |
| 424 if pipe.returncode != 0 and verbose: | 484 if pipe.returncode != 0 and verbose: |
| 425 print 'Execution failed: ' + output + '\n' + err | 485 print 'Execution failed: ' + output + '\n' + err |
| 426 print output | 486 print output |
| 427 print err | 487 print err |
| 428 return pipe.returncode, output, err | 488 return pipe.returncode, output, err |
| 429 | 489 |
| 430 | 490 |
| 431 def ExecuteCommand(cmd, verbose = False): | 491 def ExecuteCommand(cmd, verbose=False): |
| 432 """Execute a command in a subprocess. | 492 """Execute a command in a subprocess.""" |
| 433 """ | |
| 434 if verbose: print 'Executing: ' + ' '.join(cmd) | 493 if verbose: print 'Executing: ' + ' '.join(cmd) |
| 435 return subprocess.call(cmd) | 494 return subprocess.call(cmd) |
| 436 | 495 |
| 437 | 496 |
| 438 def GetArchitecture(arch, mode, test): | 497 def GetArchitecture(arch, mode, test): |
| 439 root_path = abspath(join(dirname(sys.argv[0]), '..')) | 498 root_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..')) |
| 440 if arch == 'chromium': | 499 if arch == 'chromium': |
| 441 return ChromiumArchitecture(root_path, arch, mode, test) | 500 return ChromiumArchitecture(root_path, arch, mode, test) |
| 442 | 501 |
| 443 elif arch == 'dartium': | 502 elif arch == 'dartium': |
| 444 return DartiumArchitecture(root_path, arch, mode, test) | 503 return DartiumArchitecture(root_path, arch, mode, test) |
| 445 | 504 |
| 446 elif arch in ['ia32', 'x64', 'simarm', 'arm']: | 505 elif arch in ['ia32', 'x64', 'simarm', 'arm']: |
| 447 return RuntimeArchitecture(root_path, arch, mode, test) | 506 return RuntimeArchitecture(root_path, arch, mode, test) |
| 448 | 507 |
| 449 elif arch == 'dartc': | 508 elif arch == 'dartc': |
| 450 return DartcArchitecture(root_path, arch, mode, test) | 509 return DartcArchitecture(root_path, arch, mode, test) |
| 451 | |
| OLD | NEW |