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 #library("test_suite"); | 5 #library("test_suite"); |
| 6 | 6 |
| 7 //#source("libraries.dart"); | |
|
Mads Ager (google)
2011/12/09 09:21:12
?
| |
| 8 | |
| 7 #import("status_file_parser.dart"); | 9 #import("status_file_parser.dart"); |
| 8 #import("test_runner.dart"); | 10 #import("test_runner.dart"); |
| 9 #import("multitest.dart"); | 11 #import("multitest.dart"); |
| 10 | 12 |
| 13 #source("browser_test.dart"); | |
| 11 | 14 |
| 12 interface TestSuite { | 15 interface TestSuite { |
| 13 void forEachTest(Function onTest, [Function onDone]); | 16 void forEachTest(Function onTest, [Function onDone]); |
| 14 } | 17 } |
| 15 | 18 |
| 16 | 19 |
| 17 class CCTestListerIsolate extends Isolate { | 20 class CCTestListerIsolate extends Isolate { |
| 18 CCTestListerIsolate() : super.heavy(); | 21 CCTestListerIsolate() : super.heavy(); |
| 19 | 22 |
| 20 void main() { | 23 void main() { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 String suiteName; | 131 String suiteName; |
| 129 String directoryPath; | 132 String directoryPath; |
| 130 List<String> statusFilePaths; | 133 List<String> statusFilePaths; |
| 131 Function doTest; | 134 Function doTest; |
| 132 Function doDone; | 135 Function doDone; |
| 133 int activeTestGenerators = 0; | 136 int activeTestGenerators = 0; |
| 134 bool listingDone = false; | 137 bool listingDone = false; |
| 135 TestExpectations testExpectations; | 138 TestExpectations testExpectations; |
| 136 | 139 |
| 137 StandardTestSuite(Map this.configuration, | 140 StandardTestSuite(Map this.configuration, |
| 138 String this.suiteName, | 141 String this.suiteName, |
|
Mads Ager (google)
2011/12/09 09:21:12
Indentation
| |
| 139 String this.directoryPath, | 142 String this.directoryPath, |
| 140 List<String> this.statusFilePaths); | 143 List<String> this.statusFilePaths); |
| 141 | 144 |
| 142 void isTestFile(String filename) => filename.endsWith("Test.dart"); | 145 void isTestFile(String filename) => filename.endsWith("Test.dart"); |
| 143 | 146 |
| 144 void listRecursively() => false; | 147 void listRecursively() => false; |
| 145 | 148 |
| 146 void complexStatusMatching() => false; | 149 void complexStatusMatching() => false; |
| 147 | 150 |
| 148 String shellPath() => TestUtils.dartShellFileName(configuration); | 151 String shellPath() => TestUtils.dartShellFileName(configuration); |
| 149 | 152 |
| 150 List<String> additionalOptions() => []; | 153 List<String> additionalOptions() => []; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 args, | 225 args, |
| 223 configuration, | 226 configuration, |
| 224 completeHandler, | 227 completeHandler, |
| 225 expectations, | 228 expectations, |
| 226 isNegative)); | 229 isNegative)); |
| 227 } | 230 } |
| 228 }; | 231 }; |
| 229 } | 232 } |
| 230 | 233 |
| 231 void processFile(String filename) { | 234 void processFile(String filename) { |
| 235 if (configuration['component'] == 'dartium') { | |
|
Mads Ager (google)
2011/12/09 09:21:12
Everything up to and including the parsing of opti
Bill Hesse
2011/12/09 12:33:29
Split is done at the directory lister.
These initi
| |
| 236 processDartiumFile(filename); | |
| 237 return; | |
| 238 } | |
| 232 if (!isTestFile(filename)) return; | 239 if (!isTestFile(filename)) return; |
| 233 | 240 |
| 234 // Only run the tests that match the pattern. | 241 // Only run the tests that match the pattern. |
| 235 RegExp pattern = configuration['selectors'][suiteName]; | 242 RegExp pattern = configuration['selectors'][suiteName]; |
| 236 if (!pattern.hasMatch(filename)) return; | 243 if (!pattern.hasMatch(filename)) return; |
| 237 | 244 |
| 238 var optionsFromFile = optionsFromFile(filename); | 245 var optionsFromFile = optionsFromFile(filename); |
| 239 Function createTestCase = | 246 Function createTestCase = |
| 240 makeTestCaseCreator(optionsFromFile, configuration); | 247 makeTestCaseCreator(optionsFromFile, configuration); |
| 241 | 248 |
| 242 if (optionsFromFile['isMultitest']) { | 249 if (optionsFromFile['isMultitest']) { |
| 243 bool supportsFatalTypeErrors = (configuration['component'] == 'dartc'); | 250 bool supportsFatalTypeErrors = (configuration['component'] == 'dartc'); |
| 244 testGeneratorStarted(); | 251 testGeneratorStarted(); |
| 245 DoMultitest(filename, | 252 DoMultitest(filename, |
| 246 TestUtils.buildDir(configuration), | 253 TestUtils.buildDir(configuration), |
| 247 directoryPath, | 254 directoryPath, |
| 248 supportsFatalTypeErrors, | 255 supportsFatalTypeErrors, |
| 249 createTestCase, | 256 createTestCase, |
| 250 testGeneratorDone); | 257 testGeneratorDone); |
| 251 } else { | 258 } else { |
| 252 createTestCase(filename, optionsFromFile['isNegative']); | 259 createTestCase(filename, optionsFromFile['isNegative']); |
| 253 } | 260 } |
| 254 } | 261 } |
| 255 | 262 |
| 263 void processDartiumFile(String filename) { | |
| 264 if (!isTestFile(filename)) return; | |
| 265 | |
| 266 // Only run the tests that match the pattern. | |
| 267 RegExp pattern = configuration['selectors'][suiteName]; | |
| 268 if (!pattern.hasMatch(filename)) return; | |
| 269 | |
| 270 var optionsFromFile = optionsFromFile(filename); | |
| 271 if (optionsFromFile['isMultitest']) return; | |
| 272 | |
| 273 String pathSeparator = new Platform().pathSeparator(); | |
|
Mads Ager (google)
2011/12/09 09:21:12
This block of stuff looks familiar. That looks lik
Bill Hesse
2011/12/09 12:33:29
Moved to final class member.
On 2011/12/09 09:21:
| |
| 274 String testName; | |
| 275 int start = filename.lastIndexOf('src' + pathSeparator); | |
| 276 if (start != -1) { | |
| 277 testName = filename.substring(start + 4, filename.length - 5); | |
| 278 } else { | |
| 279 // This case is hit by the dartc client compilation | |
| 280 // tests. These tests are pretty broken compared to the | |
| 281 // rest. They use the .dart suffix in the status files. They | |
| 282 // find tests in weird ways (testing that they contain "#"). | |
| 283 // They need to be redone. | |
| 284 start = filename.indexOf(directoryPath); | |
| 285 testName = filename.substring(start + directoryPath.length + 1, | |
| 286 filename.length); | |
| 287 } | |
| 288 Set<String> expectations = testExpectations.expectations(testName); | |
| 289 if (expectations.contains(SKIP)) return; | |
| 290 | |
| 291 | |
|
Mads Ager (google)
2011/12/09 09:21:12
Remove extra blank line.
| |
| 292 var timeout = configuration['timeout']; | |
| 293 bool isWebTest = optionsFromFile['containsDomImport']; | |
| 294 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition']; | |
| 295 if (!isLibraryDefinition && optionsFromFile['containsSourceOrImport']) { | |
| 296 print('Warning for $filename: Browser tests require #library ' + | |
| 297 'in any file that uses #import or #source'); | |
| 298 } | |
| 299 | |
| 300 Directory tempDir = new Directory((isWebTest ? 'client/' : '') + | |
| 301 TestUtils.buildDir(configuration) + | |
| 302 'tmp'); | |
| 303 // TODO(whesse): Create directory in the client case, if it doesn't exist. | |
| 304 tempDir.createTempSync(); | |
| 305 | |
| 306 String dartTestFilename = new File(filename).fullPathSync(); | |
| 307 String dartWrapperFilename = '${tempDir.path}/test.dart'; | |
| 308 if (!isWebTest) { | |
| 309 // test.dart will import the dart test directly, if it is a library, | |
| 310 // or indirectly through test_as_library.dart, if it is not. | |
| 311 String dartLibraryFilename; | |
| 312 if (isLibraryDefinition) { | |
| 313 dartLibraryFilename = dartTestFilename; | |
| 314 } else { | |
| 315 dartLibraryFilename = 'test_as_library.dart'; | |
| 316 File dartLibrary = new File('${tempDir.path}/$dartLibraryFilename'); | |
| 317 dartLibrary.openSync(writable: true); | |
| 318 dartLibrary.writeStringSync(WrapDartTestInLibrary(dartTestFilename)); | |
| 319 dartLibrary.closeSync(); | |
| 320 } | |
| 321 | |
| 322 File dartWrapper = new File(dartWrapperFilename); | |
| 323 dartWrapper.openSync(writable: true); | |
| 324 dartWrapper.writeStringSync(dartTestWrapper(dartLibraryFilename)); | |
| 325 dartWrapper.closeSync(); | |
| 326 } | |
| 327 | |
| 328 // Create the HTML file for the test. | |
| 329 File htmlTest = new File('${tempDir.path}/${getHtmlName(filename)}'); | |
| 330 htmlTest.openSync(writable: true); | |
| 331 htmlTest.writeStringSync(GetHtmlContents( | |
| 332 filename, | |
| 333 'client/testing/unittest/test_controller.js', | |
| 334 scriptType, | |
| 335 dartWrapperFilename)); | |
| 336 htmlTest.closeSync(); | |
| 337 | |
| 338 var drtFlags = ['-no-timeout']; | |
| 339 var dartFlags = ['--enable_asserts', '--enable_type_checks']; | |
| 340 if (optionsFromFile['dartOptions'] != null) { | |
| 341 dartFlags.addAll(optionsFromFile['dartOptions']); | |
| 342 } | |
| 343 drtFlags.add('--dart-flags=${Strings.join(dartFlags, " ")}'); | |
| 344 var args = drtFlags; | |
| 345 args.add(htmlTest.fullPathSync()); | |
| 346 | |
| 347 // Create CompilingTestCase and queue it. | |
| 348 var testCase = new CompilingTestCase( | |
| 349 testName, | |
| 350 '/bin/cp', | |
| 351 ['/tmp/dogfile', '/tmp/cowfile'], | |
| 352 dumpRenderTreePath, | |
| 353 args, | |
| 354 configuration, | |
| 355 completeHandler, | |
| 356 expectations, optionsFromFile['isNegative']); | |
| 357 doTest(testCase); | |
| 358 } | |
| 359 | |
| 360 static String dartTestWrapper(String library) { | |
| 361 return DartTestWrapper('', '', 'dart:dom', | |
| 362 '../../../tests/isolate/src/TestFramework.dart', | |
| 363 library); | |
| 364 } | |
| 365 | |
| 366 static String get scriptType() => 'application/dart'; | |
| 367 | |
| 368 static String getHtmlName(String filename) { | |
| 369 // TODO(whesse): Implement: | |
| 370 // os.path.relpath(self.test, self.root_path).replace(os.sep, '_') + | |
| 371 // 'dartium.html' | |
| 372 return filename.replaceAll('/', '_') + 'dartium.html'; | |
|
Mads Ager (google)
2011/12/09 09:21:12
path separator instead of '/'
Bill Hesse
2011/12/09 12:33:29
Done.
| |
| 373 } | |
| 374 | |
| 375 static String get dumpRenderTreePath() => 'client/tests/drt/DumpRenderTree'; | |
| 376 | |
| 256 void testGeneratorStarted() { | 377 void testGeneratorStarted() { |
| 257 ++activeTestGenerators; | 378 ++activeTestGenerators; |
| 258 } | 379 } |
| 259 | 380 |
| 260 void testGeneratorDone() { | 381 void testGeneratorDone() { |
| 261 --activeTestGenerators; | 382 --activeTestGenerators; |
| 262 if (activeTestGenerators == 0 && listingDone) { | 383 if (activeTestGenerators == 0 && listingDone) { |
| 263 doDone(); | 384 doDone(); |
| 264 } | 385 } |
| 265 } | 386 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 | 433 |
| 313 return result; | 434 return result; |
| 314 } | 435 } |
| 315 | 436 |
| 316 Map optionsFromFile(String filename) { | 437 Map optionsFromFile(String filename) { |
| 317 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)"); | 438 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)"); |
| 318 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)"); | 439 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)"); |
| 319 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)"); | 440 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)"); |
| 320 RegExp leadingHashRegExp = const RegExp(@"^#", multiLine: true); | 441 RegExp leadingHashRegExp = const RegExp(@"^#", multiLine: true); |
| 321 RegExp isolateStubsRegExp = const RegExp(@"// IsolateStubs=(.*)"); | 442 RegExp isolateStubsRegExp = const RegExp(@"// IsolateStubs=(.*)"); |
| 322 | 443 RegExp domImportRegExp = |
| 444 const RegExp(@"^#import.*(dart:(dom|html)|html\.dart).*\)", | |
| 445 multiLine: true); | |
| 446 RegExp libraryDefinitionRegExp = | |
| 447 const RegExp(@"^#library\(", multiLine: true); | |
| 448 RegExp sourceOrImportRegExp = | |
| 449 const RegExp(@"^#(source|import)\(", multiLine: true); | |
| 450 | |
| 323 // Read the entire file into a byte buffer and transform it to a | 451 // Read the entire file into a byte buffer and transform it to a |
| 324 // String. This will treat the file as ascii but the only parts | 452 // String. This will treat the file as ascii but the only parts |
| 325 // we are interested in will be ascii in any case. | 453 // we are interested in will be ascii in any case. |
| 326 File file = new File(filename); | 454 File file = new File(filename); |
| 327 file.openSync(); | 455 file.openSync(); |
| 328 List chars = new List(file.lengthSync()); | 456 List chars = new List(file.lengthSync()); |
| 329 var offset = 0; | 457 var offset = 0; |
| 330 while (offset != chars.length) { | 458 while (offset != chars.length) { |
| 331 offset += file.readListSync(chars, offset, chars.length - offset); | 459 offset += file.readListSync(chars, offset, chars.length - offset); |
| 332 } | 460 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 359 isNegative = true; | 487 isNegative = true; |
| 360 } else if (contents.contains("@dynamic-type-error") && | 488 } else if (contents.contains("@dynamic-type-error") && |
| 361 configuration['checked']) { | 489 configuration['checked']) { |
| 362 isNegative = true; | 490 isNegative = true; |
| 363 } | 491 } |
| 364 | 492 |
| 365 bool isMultitest = multiTestRegExp.hasMatch(contents); | 493 bool isMultitest = multiTestRegExp.hasMatch(contents); |
| 366 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); | 494 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); |
| 367 Match isolateMatch = isolateStubsRegExp.firstMatch(contents); | 495 Match isolateMatch = isolateStubsRegExp.firstMatch(contents); |
| 368 String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; | 496 String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; |
| 497 bool containsDomImport = domImportRegExp.hasMatch(contents); | |
| 498 bool isLibraryDefinition = libraryDefinitionRegExp.hasMatch(contents); | |
| 499 bool containsSourceOrImport = sourceOrImportRegExp.hasMatch(contents); | |
| 500 | |
| 369 | 501 |
| 370 return { "vmOptions": result, | 502 return { "vmOptions": result, |
| 371 "dartOptions": dartOptions, | 503 "dartOptions": dartOptions, |
| 372 "isNegative": isNegative, | 504 "isNegative": isNegative, |
| 373 "isMultitest": isMultitest, | 505 "isMultitest": isMultitest, |
| 374 "containsLeadingHash" : containsLeadingHash, | 506 "containsLeadingHash" : containsLeadingHash, |
| 375 "isolateStubs" : isolateStubs }; | 507 "isolateStubs" : isolateStubs, |
| 508 "containsDomImport": containsDomImport, | |
| 509 "isLibraryDefinition": isLibraryDefinition, | |
| 510 "containsSourceOrImport": containsSourceOrImport }; | |
| 376 } | 511 } |
| 377 } | 512 } |
| 378 | 513 |
| 379 | 514 |
| 380 class DartcCompilationTestSuite extends StandardTestSuite { | 515 class DartcCompilationTestSuite extends StandardTestSuite { |
| 381 List<String> _testDirs; | 516 List<String> _testDirs; |
| 382 int activityCount = 0; | 517 int activityCount = 0; |
| 383 | 518 |
| 384 DartcCompilationTestSuite(Map configuration, | 519 DartcCompilationTestSuite(Map configuration, |
| 385 String suiteName, | 520 String suiteName, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 } | 594 } |
| 460 | 595 |
| 461 static String dartcCompilationShellPath(Map configuration) { | 596 static String dartcCompilationShellPath(Map configuration) { |
| 462 var name = buildDir(configuration) + 'compiler/bin/dartc'; | 597 var name = buildDir(configuration) + 'compiler/bin/dartc'; |
| 463 if (!(new File(name)).existsSync()) { | 598 if (!(new File(name)).existsSync()) { |
| 464 throw "Executable '$name' does not exist"; | 599 throw "Executable '$name' does not exist"; |
| 465 } | 600 } |
| 466 return name; | 601 return name; |
| 467 } | 602 } |
| 468 | 603 |
| 604 static String dumpRenderTreeFileName(Map configuration) { | |
| 605 String name = 'client/tests/drt'; | |
| 606 if (new Platform().operatingSystem() == 'macos') { | |
| 607 name += '.app/Contents/MacOS/DumpRenderTree'; | |
| 608 } | |
| 609 return name; | |
| 610 } | |
| 611 | |
| 469 static String buildDir(Map configuration) { | 612 static String buildDir(Map configuration) { |
| 470 var buildDir = ''; | 613 var buildDir = ''; |
| 471 var system = configuration['system']; | 614 var system = configuration['system']; |
| 472 if (system == 'linux') { | 615 if (system == 'linux') { |
| 473 buildDir = 'out/'; | 616 buildDir = 'out/'; |
| 474 } else if (system == 'macos') { | 617 } else if (system == 'macos') { |
| 475 buildDir = 'xcodebuild/'; | 618 buildDir = 'xcodebuild/'; |
| 476 } | 619 } |
| 477 buildDir += (configuration['mode'] == 'debug') ? 'Debug_' : 'Release_'; | 620 buildDir += (configuration['mode'] == 'debug') ? 'Debug_' : 'Release_'; |
| 478 buildDir += configuration['arch'] + '/'; | 621 buildDir += configuration['arch'] + '/'; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 * $noCrash tests are expected to be flaky but not crash | 685 * $noCrash tests are expected to be flaky but not crash |
| 543 * $pass tests are expected to pass | 686 * $pass tests are expected to pass |
| 544 * $failOk tests are expected to fail that we won't fix | 687 * $failOk tests are expected to fail that we won't fix |
| 545 * $fail tests are expected to fail that we should fix | 688 * $fail tests are expected to fail that we should fix |
| 546 * $crash tests are expected to crash that we should fix | 689 * $crash tests are expected to crash that we should fix |
| 547 * $timeout tests are allowed to timeout\ | 690 * $timeout tests are allowed to timeout\ |
| 548 """; | 691 """; |
| 549 print(report); | 692 print(report); |
| 550 } | 693 } |
| 551 } | 694 } |
| OLD | NEW |