Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: tools/testing/dart/browser_controller.dart

Issue 218683009: test.dart: Add timeout for browsers that are started but do not fetch tests. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix long lines Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/testing/dart/android.dart ('k') | tools/testing/dart/scrub_status_file.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:convert" show LineSplitter, UTF8; 7 import "dart:convert" show LineSplitter, UTF8;
8 import "dart:core"; 8 import "dart:core";
9 import "dart:io"; 9 import "dart:io";
10 10
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 624
625 625
626 class Firefox extends Browser { 626 class Firefox extends Browser {
627 static const String enablePopUp = 627 static const String enablePopUp =
628 'user_pref("dom.disable_open_during_load", false);'; 628 'user_pref("dom.disable_open_during_load", false);';
629 static const String disableDefaultCheck = 629 static const String disableDefaultCheck =
630 'user_pref("browser.shell.checkDefaultBrowser", false);'; 630 'user_pref("browser.shell.checkDefaultBrowser", false);';
631 static const String disableScriptTimeLimit = 631 static const String disableScriptTimeLimit =
632 'user_pref("dom.max_script_run_time", 0);'; 632 'user_pref("dom.max_script_run_time", 0);';
633 633
634 Future _createPreferenceFile(var path) { 634 void _createPreferenceFile(var path) {
635 var file = new File("${path.toString()}/user.js"); 635 var file = new File("${path.toString()}/user.js");
636 var randomFile = file.openSync(mode: FileMode.WRITE); 636 var randomFile = file.openSync(mode: FileMode.WRITE);
637 randomFile.writeStringSync(enablePopUp); 637 randomFile.writeStringSync(enablePopUp);
638 randomFile.writeStringSync(disableDefaultCheck); 638 randomFile.writeStringSync(disableDefaultCheck);
639 randomFile.writeStringSync(disableScriptTimeLimit); 639 randomFile.writeStringSync(disableScriptTimeLimit);
640 randomFile.close(); 640 randomFile.close();
641 } 641 }
642 642
643 Future<bool> start(String url) { 643 Future<bool> start(String url) {
644 _logEvent("Starting firefox browser on: $url"); 644 _logEvent("Starting firefox browser on: $url");
(...skipping 30 matching lines...) Expand all
675 */ 675 */
676 class BrowserTestingStatus { 676 class BrowserTestingStatus {
677 Browser browser; 677 Browser browser;
678 BrowserTest currentTest; 678 BrowserTest currentTest;
679 679
680 // This is currently not used for anything except for error reporting. 680 // This is currently not used for anything except for error reporting.
681 // Given the usefulness of this in debugging issues this should not be 681 // Given the usefulness of this in debugging issues this should not be
682 // removed even when we have really stable system. 682 // removed even when we have really stable system.
683 BrowserTest lastTest; 683 BrowserTest lastTest;
684 bool timeout = false; 684 bool timeout = false;
685 BrowserTestingStatus(Browser this.browser); 685 Timer getNextTestTimeout;
686
687 BrowserTestingStatus(Browser this.browser,
688 BrowserTestRunner runner,
689 {BrowserTest last: null}) {
690 lastTest = last;
691 getNextTestTimeout = new Timer(BrowserTestRunner.BROWSER_GET_TEST_TIMEOUT,
692 runner.getTimeoutBeforeGetNextTestHandler(this));
693 }
kustermann 2014/04/01 20:59:49 I don't like this, it makes circular dependencies
Bill Hesse 2014/04/02 17:01:45 Done.
686 } 694 }
687 695
688 696
689 /** 697 /**
690 * Describes a single test to be run int the browser. 698 * Describes a single test to be run int the browser.
691 */ 699 */
692 class BrowserTest { 700 class BrowserTest {
693 // TODO(ricow): Add timeout callback instead of the string passing hack. 701 // TODO(ricow): Add timeout callback instead of the string passing hack.
694 Function doneCallback; 702 Function doneCallback;
695 String url; 703 String url;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 final bool checkedMode; // needed for dartium 748 final bool checkedMode; // needed for dartium
741 749
742 String localIp; 750 String localIp;
743 String browserName; 751 String browserName;
744 int maxNumBrowsers; 752 int maxNumBrowsers;
745 // Used to send back logs from the browser (start, stop etc) 753 // Used to send back logs from the browser (start, stop etc)
746 Function logger; 754 Function logger;
747 int browserIdCount = 0; 755 int browserIdCount = 0;
748 756
749 bool underTermination = false; 757 bool underTermination = false;
758 int numBrowserGetTestTimeouts = 0;
759 static const int MAX_BROWSER_GET_TEST_TIMEOUTS = 10;
760 static const Duration BROWSER_GET_TEST_TIMEOUT = const Duration(seconds: 60);
kustermann 2014/04/01 20:59:49 Move the static variables to the top, before the i
761
750 762
751 List<BrowserTest> testQueue = new List<BrowserTest>(); 763 List<BrowserTest> testQueue = new List<BrowserTest>();
752 Map<String, BrowserTestingStatus> browserStatus = 764 Map<String, BrowserTestingStatus> browserStatus =
753 new Map<String, BrowserTestingStatus>(); 765 new Map<String, BrowserTestingStatus>();
754 766
755 var adbDeviceMapping = new Map<String, AdbDevice>(); 767 var adbDeviceMapping = new Map<String, AdbDevice>();
756 // This cache is used to guarantee that we never see double reporting. 768 // This cache is used to guarantee that we never see double reporting.
757 // If we do we need to provide developers with this information. 769 // If we do we need to provide developers with this information.
758 // We don't add urls to the cache until we have run it. 770 // We don't add urls to the cache until we have run it.
759 Map<int, String> testCache = new Map<int, String>(); 771 Map<int, String> testCache = new Map<int, String>();
(...skipping 26 matching lines...) Expand all
786 testingServer.testDoneCallBack = handleResults; 798 testingServer.testDoneCallBack = handleResults;
787 testingServer.testStatusUpdateCallBack = handleStatusUpdate; 799 testingServer.testStatusUpdateCallBack = handleStatusUpdate;
788 testingServer.testStartedCallBack = handleStarted; 800 testingServer.testStartedCallBack = handleStarted;
789 testingServer.nextTestCallBack = getNextTest; 801 testingServer.nextTestCallBack = getNextTest;
790 return getBrowsers().then((browsers) { 802 return getBrowsers().then((browsers) {
791 var futures = []; 803 var futures = [];
792 for (var browser in browsers) { 804 for (var browser in browsers) {
793 var url = testingServer.getDriverUrl(browser.id); 805 var url = testingServer.getDriverUrl(browser.id);
794 var future = browser.start(url).then((success) { 806 var future = browser.start(url).then((success) {
795 if (success) { 807 if (success) {
796 browserStatus[browser.id] = new BrowserTestingStatus(browser); 808 browserStatus[browser.id] =
809 new BrowserTestingStatus(browser, this);
797 } 810 }
798 return success; 811 return success;
799 }); 812 });
800 futures.add(future); 813 futures.add(future);
801 } 814 }
802 return Future.wait(futures).then((values) { 815 return Future.wait(futures).then((values) {
803 return !values.contains(false); 816 return !values.contains(false);
804 }); 817 });
805 }); 818 });
806 }); 819 });
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 882
870 if (status.currentTest.id != testId) { 883 if (status.currentTest.id != testId) {
871 print("Expected test id ${status.currentTest.id} for" 884 print("Expected test id ${status.currentTest.id} for"
872 "${status.currentTest.url}"); 885 "${status.currentTest.url}");
873 print("Got test id ${testId}"); 886 print("Got test id ${testId}");
874 print("Last test id was ${status.lastTest.id} for " 887 print("Last test id was ${status.lastTest.id} for "
875 "${status.currentTest.url}"); 888 "${status.currentTest.url}");
876 throw("This should never happen, wrong test id"); 889 throw("This should never happen, wrong test id");
877 } 890 }
878 testCache[testId] = status.currentTest.url; 891 testCache[testId] = status.currentTest.url;
879 Stopwatch watch = new Stopwatch()..start();
880 892
881 // Report that the test is finished now 893 // Report that the test is finished now
882 var browserTestOutput = new BrowserTestOutput( 894 var browserTestOutput = new BrowserTestOutput(
883 status.currentTest.delayUntilTestStarted, 895 status.currentTest.delayUntilTestStarted,
884 status.currentTest.stopwatch.elapsed, 896 status.currentTest.stopwatch.elapsed,
885 output, 897 output,
886 status.browser.testBrowserOutput); 898 status.browser.testBrowserOutput);
887 status.currentTest.doneCallback(browserTestOutput); 899 status.currentTest.doneCallback(browserTestOutput);
888 900
889 watch.stop(); 901 browserStatus[browserId] =
890 status.lastTest = status.currentTest; 902 new BrowserTestingStatus(status.browser,
891 status.currentTest = null; 903 this,
904 last: status.currentTest);
kustermann 2014/04/01 20:59:49 The intent (I think) was to have *one* BrowserTest
Bill Hesse 2014/04/02 17:01:45 Done. But I think it was better this way. This o
kustermann 2014/04/03 12:18:56 I'm not saying that you can't have methods on the
892 } else { 905 } else {
893 print("\nThis is bad, should never happen, handleResult no test"); 906 print("\nThis is bad, should never happen, handleResult no test");
894 print("URL: ${status.lastTest.url}"); 907 print("URL: ${status.lastTest.url}");
895 print(output); 908 print(output);
896 terminate().then((_) { 909 terminate().then((_) {
897 exit(1); 910 exit(1);
898 }); 911 });
899 } 912 }
900 } 913 }
901 914
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 status.currentTest.delayUntilTestStarted, 957 status.currentTest.delayUntilTestStarted,
945 status.currentTest.stopwatch.elapsed, 958 status.currentTest.stopwatch.elapsed,
946 lastKnownMessage, 959 lastKnownMessage,
947 status.browser.testBrowserOutput, 960 status.browser.testBrowserOutput,
948 didTimeout: true); 961 didTimeout: true);
949 status.currentTest.doneCallback(browserTestOutput); 962 status.currentTest.doneCallback(browserTestOutput);
950 status.currentTest = null; 963 status.currentTest = null;
951 964
952 // We don't want to start a new browser if we are terminating. 965 // We don't want to start a new browser if we are terminating.
953 if (underTermination) return; 966 if (underTermination) return;
954 var browser; 967 restartBrowser(id);
955 var new_id = id;
956 if (browserName == 'chromeOnAndroid') {
957 browser = new AndroidChrome(adbDeviceMapping[id]);
958 } else if (browserName == 'ContentShellOnAndroid') {
959 browser = new AndroidBrowser(adbDeviceMapping[id],
960 contentShellOnAndroidConfig,
961 checkedMode);
962 } else if (browserName == 'DartiumOnAndroid') {
963 browser = new AndroidBrowser(adbDeviceMapping[id],
964 dartiumOnAndroidConfig,
965 checkedMode);
966 } else {
967 browserStatus.remove(id);
968 browser = getInstance();
969 new_id = "BROWSER$browserIdCount";
970 browserIdCount++;
971 browserStatus[new_id] = new BrowserTestingStatus(browser);
972 }
973 browser.id = new_id;
974 browser.start(testingServer.getDriverUrl(new_id)).then((success) {
975 // We may have started terminating in the mean time.
976 if (underTermination) {
977 browser.close().then((success) {
978 // We should never hit this, print it out.
979 if (!success) {
980 print("Could not kill browser ($id) started due to timeout");
981 }
982 });
983 return;
984 }
985 if (success) {
986 browserStatus[browser.id] = new BrowserTestingStatus(browser);
987 } else {
988 // TODO(ricow): Handle this better.
989 print("This is bad, should never happen, could not start browser");
990 exit(1);
991 }
992 });
993 }); 968 });
994 } 969 }
995 970
971 void restartBrowser(String id) {
972 var browser;
973 var new_id = id;
974 if (browserName == 'chromeOnAndroid') {
975 browser = new AndroidChrome(adbDeviceMapping[id]);
976 } else if (browserName == 'ContentShellOnAndroid') {
977 browser = new AndroidBrowser(adbDeviceMapping[id],
978 contentShellOnAndroidConfig,
979 checkedMode);
980 } else if (browserName == 'DartiumOnAndroid') {
981 browser = new AndroidBrowser(adbDeviceMapping[id],
982 dartiumOnAndroidConfig,
983 checkedMode);
984 } else {
985 browserStatus.remove(id);
986 browser = getInstance();
987 new_id = "BROWSER$browserIdCount";
988 browserIdCount++;
989 // browserStatus[new_id] = new BrowserTestingStatus(browser);
kustermann 2014/04/01 20:59:49 Commented code.
Bill Hesse 2014/04/02 17:01:45 moved outside if statement.
990 }
991 browser.id = new_id;
992 browser.start(testingServer.getDriverUrl(new_id)).then((success) {
993 // We may have started terminating in the mean time.
994 if (underTermination) {
995 browser.close().then((success) {
996 // We should never hit this, print it out.
997 if (!success) {
998 print("Could not kill browser ($id) started due to timeout");
999 }
1000 });
1001 return;
1002 }
1003 if (success) {
1004 browserStatus[browser.id] = new BrowserTestingStatus(browser, this);
kustermann 2014/04/01 20:59:49 You need to set this before starting the browser,
Bill Hesse 2014/04/02 17:01:45 Yes. This means that the cases that didn't set it
1005 } else {
1006 // TODO(ricow): Handle this better.
1007 print("This is bad, should never happen, could not start browser");
1008 exit(1);
1009 }
1010 });
1011 }
1012
1013 Function getTimeoutBeforeGetNextTestHandler(BrowserTestingStatus status) {
1014 return () {
1015 DebugLogger.warning(
1016 "Browser timed out before getting next test. Restarting");
1017 numBrowserGetTestTimeouts++;
1018 if (numBrowserGetTestTimeouts >= MAX_BROWSER_GET_TEST_TIMEOUTS) {
1019 DebugLogger.error(
1020 "Too many browser timeouts before getting next test. Terminating");
1021 terminate().then((_) {
1022 exit(1);
1023 });
1024 }
1025 status.browser.close().then((_) {
1026 restartBrowser(status.browser.id);
1027 });
kustermann 2014/04/01 20:59:49 The terminate() above includes the browse.close()
Bill Hesse 2014/04/02 17:01:45 Placed fall-through code in an else { }.
1028 };
1029 }
1030
996 BrowserTest getNextTest(String browserId) { 1031 BrowserTest getNextTest(String browserId) {
997 if (testQueue.isEmpty) return null;
998 var status = browserStatus[browserId]; 1032 var status = browserStatus[browserId];
999 if (status == null) return null; 1033 if (status == null) return null;
1000 1034
1035 status.getNextTestTimeout.cancel();
kustermann 2014/04/01 20:59:49 Since we cannot reuse the timer, we might as well
Bill Hesse 2014/04/02 17:01:45 Done.
1036 if (testQueue.isEmpty) return null;
1037
1001 // We are currently terminating this browser, don't start a new test. 1038 // We are currently terminating this browser, don't start a new test.
1002 if (status.timeout) return null; 1039 if (status.timeout) return null;
1003 1040
1004 BrowserTest test = testQueue.removeLast(); 1041 BrowserTest test = testQueue.removeLast();
1005 if (status.currentTest == null) { 1042 if (status.currentTest == null) {
1006 status.currentTest = test; 1043 status.currentTest = test;
1007 status.currentTest.lastKnownMessage = ''; 1044 status.currentTest.lastKnownMessage = '';
1008 } else { 1045 } else {
1009 // TODO(ricow): Handle this better. 1046 // TODO(ricow): Handle this better.
1010 print("This is bad, should never happen, getNextTest all full"); 1047 print("This is bad, should never happen, getNextTest all full");
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 DebugLogger.warning(""); 1092 DebugLogger.warning("");
1056 } 1093 }
1057 } 1094 }
1058 1095
1059 Future<bool> terminate() { 1096 Future<bool> terminate() {
1060 var futures = []; 1097 var futures = [];
1061 underTermination = true; 1098 underTermination = true;
1062 testingServer.underTermination = true; 1099 testingServer.underTermination = true;
1063 for (BrowserTestingStatus status in browserStatus.values) { 1100 for (BrowserTestingStatus status in browserStatus.values) {
1064 futures.add(status.browser.close()); 1101 futures.add(status.browser.close());
1102 if (status.getNextTestTimeout != null) {
1103 status.getNextTestTimeout.cancel();
kustermann 2014/04/01 20:59:49 See above.
Bill Hesse 2014/04/02 17:01:45 Done.
1104 }
1065 } 1105 }
1066 return Future.wait(futures).then((values) { 1106 return Future.wait(futures).then((values) {
1067 testingServer.httpServer.close(); 1107 testingServer.httpServer.close();
1068 testingServer.errorReportingServer.close(); 1108 testingServer.errorReportingServer.close();
1069 printDoubleReportingTests(); 1109 printDoubleReportingTests();
1070 return !values.contains(false); 1110 return !values.contains(false);
1071 }); 1111 });
1072 } 1112 }
1073 1113
1074 Browser getInstance() { 1114 Browser getInstance() {
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 Dart test driver, number of tests: <div id="number"></div><br> 1493 Dart test driver, number of tests: <div id="number"></div><br>
1454 Currently executing: <div id="currently_executing"></div><br> 1494 Currently executing: <div id="currently_executing"></div><br>
1455 Unhandled error: <div id="unhandled_error"></div> 1495 Unhandled error: <div id="unhandled_error"></div>
1456 <iframe id="embedded_iframe"></iframe> 1496 <iframe id="embedded_iframe"></iframe>
1457 </body> 1497 </body>
1458 </html> 1498 </html>
1459 """; 1499 """;
1460 return driverContent; 1500 return driverContent;
1461 } 1501 }
1462 } 1502 }
OLDNEW
« no previous file with comments | « tools/testing/dart/android.dart ('k') | tools/testing/dart/scrub_status_file.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698