Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library browser; | 4 library browser; |
| 5 | 5 |
| 6 import "dart:async"; | 6 import "dart:async"; |
| 7 import "dart:core"; | 7 import "dart:core"; |
| 8 import "dart:io"; | 8 import "dart:io"; |
| 9 | 9 |
| 10 import 'android.dart'; | 10 import 'android.dart'; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 return browserTerminationFuture; | 119 return browserTerminationFuture; |
| 120 } | 120 } |
| 121 | 121 |
| 122 /** | 122 /** |
| 123 * Start the browser using the supplied argument. | 123 * Start the browser using the supplied argument. |
| 124 * This sets up the error handling and usage logging. | 124 * This sets up the error handling and usage logging. |
| 125 */ | 125 */ |
| 126 Future<bool> startBrowser(String command, List<String> arguments) { | 126 Future<bool> startBrowser(String command, List<String> arguments) { |
| 127 return Process.start(command, arguments).then((startedProcess) { | 127 return Process.start(command, arguments).then((startedProcess) { |
| 128 process = startedProcess; | 128 process = startedProcess; |
| 129 Completer stdoutDone = new Completer(); | |
| 130 Completer stderrDone = new Completer(); | |
| 131 | |
| 129 process.stdout.transform(new StringDecoder()).listen((data) { | 132 process.stdout.transform(new StringDecoder()).listen((data) { |
| 130 _addStdout(data); | 133 _addStdout(data); |
| 131 }, onError: (error) { | 134 }, onError: (error) { |
| 132 // This should _never_ happen, but we really want this in the log | 135 // This should _never_ happen, but we really want this in the log |
| 133 // if it actually does due to dart:io or vm bug. | 136 // if it actually does due to dart:io or vm bug. |
| 134 _logEvent("An error occured in the process stdout handling: $error"); | 137 _logEvent("An error occured in the process stdout handling: $error"); |
| 138 }, onDone: () { | |
| 139 stdoutDone.complete(true); | |
| 135 }); | 140 }); |
| 136 | 141 |
| 137 process.stderr.transform(new StringDecoder()).listen((data) { | 142 process.stderr.transform(new StringDecoder()).listen((data) { |
| 138 _addStderr(data); | 143 _addStderr(data); |
| 139 }, onError: (error) { | 144 }, onError: (error) { |
| 140 // This should _never_ happen, but we really want this in the log | 145 // This should _never_ happen, but we really want this in the log |
| 141 // if it actually does due to dart:io or vm bug. | 146 // if it actually does due to dart:io or vm bug. |
| 142 _logEvent("An error occured in the process stderr handling: $error"); | 147 _logEvent("An error occured in the process stderr handling: $error"); |
| 148 }, onDone: () { | |
| 149 stderrDone.complete(true); | |
| 143 }); | 150 }); |
| 144 | 151 |
| 145 process.exitCode.then((exitCode) { | 152 process.exitCode.then((exitCode) { |
| 146 _logEvent("Browser closed with exitcode $exitCode"); | 153 _logEvent("Browser closed with exitcode $exitCode"); |
| 147 if (_processClosed != null) _processClosed(); | 154 Future.wait([stdoutDone.future, stderrDone.future]).then((_) { |
| 148 if (_cleanup != null) _cleanup(); | 155 if (_processClosed != null) _processClosed(); |
| 149 if (onClose != null) onClose(exitCode); | 156 if (_cleanup != null) _cleanup(); |
| 157 if (onClose != null) onClose(exitCode); | |
| 158 }); | |
| 150 }); | 159 }); |
| 151 return true; | 160 return true; |
| 152 }).catchError((error) { | 161 }).catchError((error) { |
| 153 _logEvent("Running $command $arguments failed with $error"); | 162 _logEvent("Running $command $arguments failed with $error"); |
| 154 return false; | 163 return false; |
| 155 }); | 164 }); |
| 156 } | 165 } |
| 157 | 166 |
| 158 /** | 167 /** |
| 159 * Get any stdout that the browser wrote during execution. | 168 * Get any stdout that the browser wrote during execution. |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 462 * The interface is rather simple. After starting the runner tests | 471 * The interface is rather simple. After starting the runner tests |
| 463 * are simply added to the queue and a the supplied callbacks are called | 472 * are simply added to the queue and a the supplied callbacks are called |
| 464 * whenever a test completes. | 473 * whenever a test completes. |
| 465 */ | 474 */ |
| 466 class BrowserTestRunner { | 475 class BrowserTestRunner { |
| 467 String local_ip; | 476 String local_ip; |
| 468 String browserName; | 477 String browserName; |
| 469 int maxNumBrowsers; | 478 int maxNumBrowsers; |
| 470 // Used to send back logs from the browser (start, stop etc) | 479 // Used to send back logs from the browser (start, stop etc) |
| 471 Function logger; | 480 Function logger; |
| 481 int browserIdCount = 0; | |
| 472 | 482 |
| 473 bool underTermination = false; | 483 bool underTermination = false; |
| 474 | 484 |
| 475 List<BrowserTest> testQueue = new List<BrowserTest>(); | 485 List<BrowserTest> testQueue = new List<BrowserTest>(); |
| 476 Map<String, BrowserTestingStatus> browserStatus = | 486 Map<String, BrowserTestingStatus> browserStatus = |
| 477 new Map<String, BrowserTestingStatus>(); | 487 new Map<String, BrowserTestingStatus>(); |
| 478 | 488 |
| 479 var adbDeviceMapping = new Map<String, AdbDevice>(); | 489 var adbDeviceMapping = new Map<String, AdbDevice>(); |
| 480 // This cache is used to guarantee that we never see double reporting. | 490 // This cache is used to guarantee that we never see double reporting. |
| 481 // If we do we need to provide developers with this information. | 491 // If we do we need to provide developers with this information. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 browser.id = id; | 543 browser.id = id; |
| 534 } | 544 } |
| 535 browsersCompleter.complete(browsers); | 545 browsersCompleter.complete(browsers); |
| 536 } else { | 546 } else { |
| 537 throw new StateError("No android devices found."); | 547 throw new StateError("No android devices found."); |
| 538 } | 548 } |
| 539 }); | 549 }); |
| 540 } else { | 550 } else { |
| 541 var browsers = []; | 551 var browsers = []; |
| 542 for (int i = 0; i < maxNumBrowsers; i++) { | 552 for (int i = 0; i < maxNumBrowsers; i++) { |
| 543 var id = "BROWSER$i"; | 553 var id = "BROWSER$browserIdCount"; |
| 554 browserIdCount++; | |
| 544 var browser = getInstance(); | 555 var browser = getInstance(); |
| 545 browsers.add(browser); | 556 browsers.add(browser); |
| 546 // We store this in case we need to kill the browser. | 557 // We store this in case we need to kill the browser. |
| 547 browser.id = id; | 558 browser.id = id; |
| 548 } | 559 } |
| 549 browsersCompleter.complete(browsers); | 560 browsersCompleter.complete(browsers); |
| 550 } | 561 } |
| 551 return browsersCompleter.future; | 562 return browsersCompleter.future; |
| 552 } | 563 } |
| 553 | 564 |
| 554 var timedOut = []; | 565 var timedOut = []; |
| 555 | 566 |
| 556 void handleResults(String browserId, String output, int testId) { | 567 void handleResults(String browserId, String output, int testId) { |
| 557 var status = browserStatus[browserId]; | 568 var status = browserStatus[browserId]; |
| 569 DebugLogger.info("Handling result for browser ${browserId}"); | |
| 558 if (testCache.containsKey(testId)) { | 570 if (testCache.containsKey(testId)) { |
| 559 doubleReportingTests.add(testId); | 571 doubleReportingTests.add(testId); |
| 560 return; | 572 return; |
| 561 } | 573 } |
| 562 | 574 |
| 563 if (status.timeout) { | 575 if (status.timeout) { |
| 564 // We don't do anything, this browser is currently being killed and | 576 // We don't do anything, this browser is currently being killed and |
| 565 // replaced. | 577 // replaced. |
| 566 } else if (status.currentTest != null) { | 578 } else if (status.currentTest != null) { |
| 567 status.currentTest.timeoutTimer.cancel(); | 579 status.currentTest.timeoutTimer.cancel(); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 583 print(output); | 595 print(output); |
| 584 terminate().then((_) { | 596 terminate().then((_) { |
| 585 exit(1); | 597 exit(1); |
| 586 }); | 598 }); |
| 587 } | 599 } |
| 588 } | 600 } |
| 589 | 601 |
| 590 void handleTimeout(BrowserTestingStatus status) { | 602 void handleTimeout(BrowserTestingStatus status) { |
| 591 // We simply kill the browser and starts up a new one! | 603 // We simply kill the browser and starts up a new one! |
| 592 // We could be smarter here, but it does not seems like it is worth it. | 604 // We could be smarter here, but it does not seems like it is worth it. |
| 605 DebugLogger.info("Handling timeout for browser ${status.browser.id}"); | |
| 593 status.timeout = true; | 606 status.timeout = true; |
| 594 timedOut.add(status.currentTest.url); | 607 timedOut.add(status.currentTest.url); |
| 595 var id = status.browser.id; | 608 var id = status.browser.id; |
| 596 status.browser.close().then((closed) { | 609 status.browser.close().then((closed) { |
| 597 if (!closed) { | 610 if (!closed) { |
| 598 // Very bad, we could not kill the browser. | 611 // Very bad, we could not kill the browser. |
| 599 print("could not kill browser $id"); | 612 print("could not kill browser $id"); |
| 600 return; | 613 return; |
| 601 } | 614 } |
| 602 // We don't want to start a new browser if we are terminating. | 615 // We don't want to start a new browser if we are terminating. |
| 603 if (underTermination) return; | 616 if (underTermination) return; |
| 604 | |
| 605 var browser; | 617 var browser; |
| 618 var new_id = id; | |
| 606 if (browserName == 'chromeOnAndroid') { | 619 if (browserName == 'chromeOnAndroid') { |
| 607 browser = new AndroidChrome(adbDeviceMapping[id]); | 620 browser = new AndroidChrome(adbDeviceMapping[id]); |
| 608 } else { | 621 } else { |
| 622 browserStatus.remove(id); | |
| 609 browser = getInstance(); | 623 browser = getInstance(); |
| 624 new_id = "BROWSER$browserIdCount"; | |
| 625 browserIdCount++; | |
| 626 browser.id = new_id; | |
|
kustermann
2013/06/12 12:52:09
Please move this 2 lines down after the else branc
ricow1
2013/06/12 12:54:30
Done.
| |
| 627 browserStatus[browser.id] = new BrowserTestingStatus(browser); | |
| 610 } | 628 } |
| 611 browser.start(testingServer.getDriverUrl(id)).then((success) { | 629 browser.start(testingServer.getDriverUrl(new_id)).then((success) { |
| 612 // We may have started terminating in the mean time. | 630 // We may have started terminating in the mean time. |
| 613 if (underTermination) { | 631 if (underTermination) { |
| 614 browser.close().then((success) { | 632 browser.close().then((success) { |
| 615 // We should never hit this, print it out. | 633 // We should never hit this, print it out. |
| 616 if (!success) { | 634 if (!success) { |
| 617 print("Could not kill browser ($id) started due to timeout"); | 635 print("Could not kill browser ($id) started due to timeout"); |
| 618 } | 636 } |
| 619 }); | 637 }); |
| 620 return; | 638 return; |
| 621 } | 639 } |
| 622 if (success) { | 640 if (success) { |
| 623 browser.id = id; | 641 browserStatus[browser.id] = new BrowserTestingStatus(browser); |
| 624 status.browser = browser; | |
| 625 status.timeout = false; | |
| 626 } else { | 642 } else { |
| 627 // TODO(ricow): Handle this better. | 643 // TODO(ricow): Handle this better. |
| 628 print("This is bad, should never happen, could not start browser"); | 644 print("This is bad, should never happen, could not start browser"); |
| 629 exit(1); | 645 exit(1); |
| 630 } | 646 } |
| 631 }); | 647 }); |
| 632 }); | 648 }); |
| 633 | 649 |
| 634 status.currentTest.doneCallback("TIMEOUT"); | 650 status.currentTest.doneCallback("TIMEOUT"); |
| 635 status.currentTest = null; | 651 status.currentTest = null; |
| 636 } | 652 } |
| 637 | 653 |
| 638 BrowserTest getNextTest(String browserId) { | 654 BrowserTest getNextTest(String browserId) { |
| 639 if (testQueue.isEmpty) return null; | 655 if (testQueue.isEmpty) return null; |
| 640 var status = browserStatus[browserId]; | 656 var status = browserStatus[browserId]; |
| 641 if (status == null) return null; | 657 if (status == null) return null; |
| 658 DebugLogger.info("Handling getNext for browser ${browserId}" | |
| 659 " timeout status: ${status.timeout}"); | |
| 660 | |
| 642 // We are currently terminating this browser, don't start a new test. | 661 // We are currently terminating this browser, don't start a new test. |
| 643 if (status.timeout) return null; | 662 if (status.timeout) return null; |
| 644 BrowserTest test = testQueue.removeLast(); | 663 BrowserTest test = testQueue.removeLast(); |
| 645 if (status.currentTest == null) { | 664 if (status.currentTest == null) { |
| 646 status.currentTest = test; | 665 status.currentTest = test; |
| 647 } else { | 666 } else { |
| 648 // TODO(ricow): Handle this better. | 667 // TODO(ricow): Handle this better. |
| 649 print("This is bad, should never happen, getNextTest all full"); | 668 print("This is bad, should never happen, getNextTest all full"); |
| 669 print("This happened for browser $browserId"); | |
| 650 print("Old test was: ${status.currentTest.url}"); | 670 print("Old test was: ${status.currentTest.url}"); |
| 651 print("Timed out tests:"); | 671 print("Timed out tests:"); |
| 652 for (var v in timedOut) { | 672 for (var v in timedOut) { |
| 653 print(" $v"); | 673 print(" $v"); |
| 654 } | 674 } |
| 655 exit(1); | 675 exit(1); |
| 656 } | 676 } |
| 657 Timer timer = new Timer(new Duration(seconds: test.timeout), | 677 Timer timer = new Timer(new Duration(seconds: test.timeout), |
| 658 () { handleTimeout(status); }); | 678 () { handleTimeout(status); }); |
| 659 status.currentTest.timeoutTimer = timer; | 679 status.currentTest.timeoutTimer = timer; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 913 </head> | 933 </head> |
| 914 <body onload="startTesting()"> | 934 <body onload="startTesting()"> |
| 915 Dart test driver, number of tests: <div id="number"></div> | 935 Dart test driver, number of tests: <div id="number"></div> |
| 916 <iframe id="embedded_iframe"></iframe> | 936 <iframe id="embedded_iframe"></iframe> |
| 917 </body> | 937 </body> |
| 918 </html> | 938 </html> |
| 919 """; | 939 """; |
| 920 return driverContent; | 940 return driverContent; |
| 921 } | 941 } |
| 922 } | 942 } |
| OLD | NEW |