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 #import("status_file_parser.dart"); | 7 #import("status_file_parser.dart"); |
| 8 #import("test_runner.dart"); | 8 #import("test_runner.dart"); |
| 9 #import("multitest.dart"); | 9 #import("multitest.dart"); |
| 10 | 10 |
| 11 #source("browser_test.dart"); | |
| 11 | 12 |
| 12 interface TestSuite { | 13 interface TestSuite { |
| 13 void forEachTest(Function onTest, [Function onDone]); | 14 void forEachTest(Function onTest, [Function onDone]); |
| 14 } | 15 } |
| 15 | 16 |
| 16 | 17 |
| 17 class CCTestListerIsolate extends Isolate { | 18 class CCTestListerIsolate extends Isolate { |
| 18 CCTestListerIsolate() : super.heavy(); | 19 CCTestListerIsolate() : super.heavy(); |
| 19 | 20 |
| 20 void main() { | 21 void main() { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 class StandardTestSuite implements TestSuite { | 127 class StandardTestSuite implements TestSuite { |
| 127 Map configuration; | 128 Map configuration; |
| 128 String suiteName; | 129 String suiteName; |
| 129 String directoryPath; | 130 String directoryPath; |
| 130 List<String> statusFilePaths; | 131 List<String> statusFilePaths; |
| 131 Function doTest; | 132 Function doTest; |
| 132 Function doDone; | 133 Function doDone; |
| 133 int activeTestGenerators = 0; | 134 int activeTestGenerators = 0; |
| 134 bool listingDone = false; | 135 bool listingDone = false; |
| 135 TestExpectations testExpectations; | 136 TestExpectations testExpectations; |
| 137 final String pathSeparator; | |
| 136 | 138 |
| 137 StandardTestSuite(Map this.configuration, | 139 StandardTestSuite(Map this.configuration, |
| 138 String this.suiteName, | 140 String this.suiteName, |
| 139 String this.directoryPath, | 141 String this.directoryPath, |
| 140 List<String> this.statusFilePaths); | 142 List<String> this.statusFilePaths) |
| 143 : pathSeparator = new Platform().pathSeparator(); | |
| 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 13 matching lines...) Expand all Loading... | |
| 164 | 167 |
| 165 processDirectory(); | 168 processDirectory(); |
| 166 } | 169 } |
| 167 | 170 |
| 168 void processDirectory() { | 171 void processDirectory() { |
| 169 directoryPath = getDirname(directoryPath); | 172 directoryPath = getDirname(directoryPath); |
| 170 Directory dir = new Directory(directoryPath); | 173 Directory dir = new Directory(directoryPath); |
| 171 dir.errorHandler = (s) { | 174 dir.errorHandler = (s) { |
| 172 throw s; | 175 throw s; |
| 173 }; | 176 }; |
| 174 dir.fileHandler = processFile; | 177 if (configuration['component'] == 'dartium') { |
| 178 dir.fileHandler = processDartiumFile; | |
| 179 } else { | |
| 180 dir.fileHandler = processFile; | |
| 181 } | |
| 175 dir.doneHandler = directoryListingDone; | 182 dir.doneHandler = directoryListingDone; |
| 176 dir.list(recursive: listRecursively()); | 183 dir.list(recursive: listRecursively()); |
| 177 } | 184 } |
| 178 | 185 |
| 179 Function makeTestCaseCreator(Map optionsFromFile, Map configuration) { | 186 Function makeTestCaseCreator(Map optionsFromFile, Map configuration) { |
| 180 return (String filename, | 187 return (String filename, |
| 181 bool isNegative, | 188 bool isNegative, |
| 182 [bool isNegativeIfChecked = false, | 189 [bool isNegativeIfChecked = false, |
| 183 bool enableFatalTypeErrors = false]) { | 190 bool enableFatalTypeErrors = false]) { |
| 184 // Look up expectations in status files using a modified file path. | 191 // Look up expectations in status files using a modified file path. |
| 185 String pathSeparator = new Platform().pathSeparator(); | |
| 186 String testName; | 192 String testName; |
| 187 int start = filename.lastIndexOf('src' + pathSeparator); | 193 int start = filename.lastIndexOf('src' + pathSeparator); |
| 188 if (start != -1) { | 194 if (start != -1) { |
| 189 testName = filename.substring(start + 4, filename.length - 5); | 195 testName = filename.substring(start + 4, filename.length - 5); |
| 190 } else if (optionsFromFile['isMultitest']) { | 196 } else if (optionsFromFile['isMultitest']) { |
| 191 start = filename.lastIndexOf(pathSeparator); | 197 start = filename.lastIndexOf(pathSeparator); |
| 192 int middle = filename.lastIndexOf('_'); | 198 int middle = filename.lastIndexOf('_'); |
| 193 testName = filename.substring(start + 1, middle) + pathSeparator + | 199 testName = filename.substring(start + 1, middle) + pathSeparator + |
| 194 filename.substring(middle + 1, filename.length - 5); | 200 filename.substring(middle + 1, filename.length - 5); |
| 195 } else { | 201 } else { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 TestUtils.buildDir(configuration), | 252 TestUtils.buildDir(configuration), |
| 247 directoryPath, | 253 directoryPath, |
| 248 supportsFatalTypeErrors, | 254 supportsFatalTypeErrors, |
| 249 createTestCase, | 255 createTestCase, |
| 250 testGeneratorDone); | 256 testGeneratorDone); |
| 251 } else { | 257 } else { |
| 252 createTestCase(filename, optionsFromFile['isNegative']); | 258 createTestCase(filename, optionsFromFile['isNegative']); |
| 253 } | 259 } |
| 254 } | 260 } |
| 255 | 261 |
| 262 void processDartiumFile(String filename) { | |
| 263 if (!isTestFile(filename)) return; | |
| 264 | |
| 265 // Only run the tests that match the pattern. | |
|
Mads Ager (google)
2011/12/09 13:19:37
I still think these line should be extracted into
| |
| 266 RegExp pattern = configuration['selectors'][suiteName]; | |
| 267 if (!pattern.hasMatch(filename)) return; | |
| 268 | |
| 269 var optionsFromFile = optionsFromFile(filename); | |
| 270 if (optionsFromFile['isMultitest']) return; | |
| 271 | |
| 272 String testName; | |
| 273 int start = filename.lastIndexOf('src' + pathSeparator); | |
| 274 if (start != -1) { | |
| 275 testName = filename.substring(start + 4, filename.length - 5); | |
| 276 } else { | |
| 277 // This case is hit by the dartc client compilation | |
| 278 // tests. These tests are pretty broken compared to the | |
| 279 // rest. They use the .dart suffix in the status files. They | |
| 280 // find tests in weird ways (testing that they contain "#"). | |
| 281 // They need to be redone. | |
| 282 start = filename.indexOf(directoryPath); | |
| 283 testName = filename.substring(start + directoryPath.length + 1, | |
| 284 filename.length); | |
| 285 } | |
| 286 Set<String> expectations = testExpectations.expectations(testName); | |
| 287 if (expectations.contains(SKIP)) return; | |
| 288 | |
| 289 var timeout = configuration['timeout']; | |
| 290 bool isWebTest = optionsFromFile['containsDomImport']; | |
| 291 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition']; | |
| 292 if (!isLibraryDefinition && optionsFromFile['containsSourceOrImport']) { | |
| 293 print('Warning for $filename: Browser tests require #library ' + | |
| 294 'in any file that uses #import or #source'); | |
| 295 } | |
| 296 | |
| 297 Directory tempDir = new Directory((isWebTest ? 'client/' : '') + | |
| 298 TestUtils.buildDir(configuration) + | |
| 299 'tmp'); | |
| 300 // TODO(whesse): Create directory in the client case, if it doesn't exist. | |
|
Mads Ager (google)
2011/12/09 13:19:37
I'm not sure I understand this TODO. If client doe
| |
| 301 tempDir.createTempSync(); | |
| 302 | |
| 303 String dartTestFilename = new File(filename).fullPathSync(); | |
| 304 String dartWrapperFilename = '${tempDir.path}/test.dart'; | |
| 305 if (!isWebTest) { | |
| 306 // test.dart will import the dart test directly, if it is a library, | |
| 307 // or indirectly through test_as_library.dart, if it is not. | |
| 308 String dartLibraryFilename; | |
| 309 if (isLibraryDefinition) { | |
| 310 dartLibraryFilename = dartTestFilename; | |
| 311 } else { | |
| 312 dartLibraryFilename = 'test_as_library.dart'; | |
| 313 File file = new File('${tempDir.path}/$dartLibraryFilename'); | |
| 314 RandomAccessFile dartLibrary = file.openSync(writable: true); | |
| 315 dartLibrary.writeStringSync(WrapDartTestInLibrary(dartTestFilename)); | |
| 316 dartLibrary.closeSync(); | |
| 317 } | |
| 318 | |
| 319 File file = new File(dartWrapperFilename); | |
| 320 RandomAccessFile dartWrapper = file.openSync(writable: true); | |
| 321 dartWrapper.writeStringSync(dartTestWrapper(dartLibraryFilename)); | |
| 322 dartWrapper.closeSync(); | |
| 323 } | |
| 324 | |
| 325 // Create the HTML file for the test. | |
| 326 File htmlTestBase = new File('${tempDir.path}/${getHtmlName(filename)}'); | |
| 327 RandomAccessFile htmlTest = htmlTestBase.openSync(writable: true); | |
| 328 htmlTest.writeStringSync(GetHtmlContents( | |
| 329 filename, | |
| 330 'client/testing/unittest/test_controller.js', | |
| 331 scriptType, | |
| 332 dartWrapperFilename)); | |
| 333 htmlTest.closeSync(); | |
| 334 | |
| 335 for (var vmOptions in optionsFromFile["vmOptions"]) { | |
| 336 var drtFlags = ['-no-timeout']; | |
| 337 var dartFlags = ['--enable_asserts', '--enable_type_checks']; | |
| 338 dartFlags.addAll(vmOptions); | |
| 339 drtFlags.add('--dart-flags=${Strings.join(dartFlags, " ")}'); | |
| 340 var args = drtFlags; | |
| 341 args.add(htmlTestBase.fullPathSync()); | |
| 342 | |
| 343 // Create BrowserTestCase and queue it. | |
| 344 var testCase = new BrowserTestCase( | |
| 345 testName, | |
| 346 '/bin/echo', | |
| 347 ['No compilation step for component dartium.'], | |
| 348 dumpRenderTreeFilename, | |
| 349 args, | |
| 350 configuration, | |
| 351 completeHandler, | |
| 352 expectations, optionsFromFile['isNegative']); | |
| 353 doTest(testCase); | |
| 354 } | |
| 355 } | |
| 356 | |
| 357 static String dartTestWrapper(String library) { | |
| 358 return DartTestWrapper('', '', 'dart:dom', | |
| 359 '../../../tests/isolate/src/TestFramework.dart', | |
| 360 library); | |
| 361 } | |
| 362 | |
| 363 static String get scriptType() => 'application/dart'; | |
| 364 | |
| 365 String getHtmlName(String filename) { | |
| 366 return filename.replaceAll(pathSeparator, '_') + 'dartium.html'; | |
| 367 } | |
| 368 | |
| 369 static String get dumpRenderTreeFilename() { | |
| 370 if (new Platform().operatingSystem() == 'macos') { | |
| 371 return 'client/tests/drt/.app/Contents/MacOS/DumpRenderTree'; | |
| 372 } | |
| 373 return 'client/tests/drt/DumpRenderTree'; | |
| 374 } | |
| 375 | |
| 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 RandomAccessFile file = (new File(filename)).openSync(); | 454 RandomAccessFile file = new File(filename).openSync(); |
| 327 List chars = new List(file.lengthSync()); | 455 List chars = new List(file.lengthSync()); |
| 328 var offset = 0; | 456 var offset = 0; |
| 329 while (offset != chars.length) { | 457 while (offset != chars.length) { |
| 330 offset += file.readListSync(chars, offset, chars.length - offset); | 458 offset += file.readListSync(chars, offset, chars.length - offset); |
| 331 } | 459 } |
| 332 file.closeSync(); | 460 file.closeSync(); |
| 333 String contents = new String.fromCharCodes(chars); | 461 String contents = new String.fromCharCodes(chars); |
| 334 chars = null; | 462 chars = null; |
| 335 | 463 |
| 336 // Find the options in the file. | 464 // Find the options in the file. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 358 isNegative = true; | 486 isNegative = true; |
| 359 } else if (contents.contains("@dynamic-type-error") && | 487 } else if (contents.contains("@dynamic-type-error") && |
| 360 configuration['checked']) { | 488 configuration['checked']) { |
| 361 isNegative = true; | 489 isNegative = true; |
| 362 } | 490 } |
| 363 | 491 |
| 364 bool isMultitest = multiTestRegExp.hasMatch(contents); | 492 bool isMultitest = multiTestRegExp.hasMatch(contents); |
| 365 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); | 493 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); |
| 366 Match isolateMatch = isolateStubsRegExp.firstMatch(contents); | 494 Match isolateMatch = isolateStubsRegExp.firstMatch(contents); |
| 367 String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; | 495 String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; |
| 496 bool containsDomImport = domImportRegExp.hasMatch(contents); | |
| 497 bool isLibraryDefinition = libraryDefinitionRegExp.hasMatch(contents); | |
| 498 bool containsSourceOrImport = sourceOrImportRegExp.hasMatch(contents); | |
| 499 | |
| 368 | 500 |
| 369 return { "vmOptions": result, | 501 return { "vmOptions": result, |
| 370 "dartOptions": dartOptions, | 502 "dartOptions": dartOptions, |
| 371 "isNegative": isNegative, | 503 "isNegative": isNegative, |
| 372 "isMultitest": isMultitest, | 504 "isMultitest": isMultitest, |
| 373 "containsLeadingHash" : containsLeadingHash, | 505 "containsLeadingHash" : containsLeadingHash, |
| 374 "isolateStubs" : isolateStubs }; | 506 "isolateStubs" : isolateStubs, |
| 507 "containsDomImport": containsDomImport, | |
| 508 "isLibraryDefinition": isLibraryDefinition, | |
| 509 "containsSourceOrImport": containsSourceOrImport }; | |
| 375 } | 510 } |
| 376 } | 511 } |
| 377 | 512 |
| 378 | 513 |
| 379 class DartcCompilationTestSuite extends StandardTestSuite { | 514 class DartcCompilationTestSuite extends StandardTestSuite { |
| 380 List<String> _testDirs; | 515 List<String> _testDirs; |
| 381 int activityCount = 0; | 516 int activityCount = 0; |
| 382 | 517 |
| 383 DartcCompilationTestSuite(Map configuration, | 518 DartcCompilationTestSuite(Map configuration, |
| 384 String suiteName, | 519 String suiteName, |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 * $noCrash tests are expected to be flaky but not crash | 676 * $noCrash tests are expected to be flaky but not crash |
| 542 * $pass tests are expected to pass | 677 * $pass tests are expected to pass |
| 543 * $failOk tests are expected to fail that we won't fix | 678 * $failOk tests are expected to fail that we won't fix |
| 544 * $fail tests are expected to fail that we should fix | 679 * $fail tests are expected to fail that we should fix |
| 545 * $crash tests are expected to crash that we should fix | 680 * $crash tests are expected to crash that we should fix |
| 546 * $timeout tests are allowed to timeout\ | 681 * $timeout tests are allowed to timeout\ |
| 547 """; | 682 """; |
| 548 print(report); | 683 print(report); |
| 549 } | 684 } |
| 550 } | 685 } |
| OLD | NEW |