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

Side by Side Diff: utils/testrunner/standard_test_runner.dart

Issue 14247033: Updated testrunner: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | « utils/testrunner/run_pipeline.dart ('k') | utils/testrunner/testrunner.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // TODO(gram): dart2js is not handling 'part of' properly yet; when it does 5 part of test_controller;
6 // uncomment this.
7 //part of test_controller;
8 6
9 /** Path to DRT executable. */ 7 /** Path to DRT executable. */
10 String drt; 8 String drt;
11 9
12 /** Whether to include elapsed time. */ 10 /** Whether to include elapsed time. */
13 bool includeTime; 11 bool includeTime;
14 12
15 /** Whether to regenerate layout test files. */ 13 /** Whether to regenerate layout test files. */
16 bool regenerate; 14 bool regenerate;
17 15
(...skipping 15 matching lines...) Expand all
33 31
34 /** The print function to use. */ 32 /** The print function to use. */
35 Function tprint; 33 Function tprint;
36 34
37 /** A callback function to notify the caller we are done. */ 35 /** A callback function to notify the caller we are done. */
38 Function notifyDone; 36 Function notifyDone;
39 37
40 /** The action function to use. */ 38 /** The action function to use. */
41 Function action; 39 Function action;
42 40
41 /**
42 * A special marker string used to separate group names and
43 * identify non-debug output.
44 */
45 final marker = '###';
46
43 class Macros { 47 class Macros {
44 static const String testTime = '<TIME>'; 48 static const String testTime = '<TIME>';
45 static const String testfile = '<FILENAME>'; 49 static const String testfile = '<FILENAME>';
46 static const String testGroup = '<GROUPNAME>'; 50 static const String testGroup = '<GROUPNAME>';
47 static const String testDescription = '<TESTNAME>'; 51 static const String testDescription = '<TESTNAME>';
48 static const String testMessage = '<MESSAGE>'; 52 static const String testMessage = '<MESSAGE>';
49 static const String testStacktrace = '<STACK>'; 53 static const String testStacktrace = '<STACK>';
50 } 54 }
51 55
52 class TestRunnerConfiguration extends unittest.Configuration { 56 class TestRunnerConfiguration extends Configuration {
53 get name => 'Minimal test runner configuration'; 57 get name => 'Minimal test runner configuration';
54 get autoStart => false; 58 get autoStart => false;
55 59
60 void onInit() {}
61
56 String formatMessage(filename, groupname, 62 String formatMessage(filename, groupname,
57 [ testname = '', testTime = '', result = '', 63 [ testname = '', testTime = '', result = '',
58 message = '', stack = '' ]) { 64 message = '', stack = '' ]) {
59 var format = errorFormat; 65 var format = errorFormat;
60 if (result == 'pass') format = passFormat; 66 if (result == 'pass') format = passFormat;
61 else if (result == 'fail') format = failFormat; 67 else if (result == 'fail') format = failFormat;
62 return format. 68 return format.
63 replaceAll(Macros.testTime, testTime). 69 replaceAll(Macros.testTime, testTime).
64 replaceAll(Macros.testfile, filename). 70 replaceAll(Macros.testfile, filename).
65 replaceAll(Macros.testGroup, groupname). 71 replaceAll(Macros.testGroup, groupname).
66 replaceAll(Macros.testDescription, testname). 72 replaceAll(Macros.testDescription, testname).
67 replaceAll(Macros.testMessage, message). 73 replaceAll(Macros.testMessage, message).
68 replaceAll(Macros.testStacktrace, stack); 74 replaceAll(Macros.testStacktrace, stack);
69 } 75 }
70 76
71 String elapsed(unittest.TestCase t) { 77 String elapsed(TestCase t) {
72 if (includeTime) { 78 if (includeTime) {
73 double duration = t.runningTime.inMilliseconds.toDouble(); 79 double duration = t.runningTime.inMilliseconds.toDouble();
74 duration /= 1000; 80 duration /= 1000;
75 return '${duration.toStringAsFixed(3)}s '; 81 return '${duration.toStringAsFixed(3)}s ';
76 } else { 82 } else {
77 return ''; 83 return '';
78 } 84 }
79 } 85 }
80 86
81 void dumpTestResult(source, unittest.TestCase t) { 87 void dumpTestResult(source, TestCase t) {
82 var groupName = '', testName = ''; 88 var groupName = '', testName = '';
83 var idx = t.description.lastIndexOf('###'); 89 var idx = t.description.lastIndexOf(marker);
84 if (idx >= 0) { 90 if (idx >= 0) {
85 groupName = t.description.substring(0, idx).replaceAll('###', ' '); 91 groupName = t.description.substring(0, idx).replaceAll(marker, ' ');
86 testName = t.description.substring(idx+3); 92 testName = t.description.substring(idx+3);
87 } else { 93 } else {
88 testName = t.description; 94 testName = t.description;
89 } 95 }
90 var stack = (t.stackTrace == null) ? '' : '${t.stackTrace} '; 96 var stack = (t.stackTrace == null) ? '' : '${t.stackTrace} ';
91 var message = (t.message.length > 0) ? '${t.message} ' : ''; 97 var message = (t.message.length > 0) ? '${t.message} ' : '';
92 var duration = elapsed(t); 98 var duration = elapsed(t);
93 tprint(formatMessage(source, '$groupName ', '$testName ', 99 tprint(formatMessage(source, '$groupName ', '$testName ',
94 duration, t.result, message, stack)); 100 duration, t.result, message, stack));
95 } 101 }
96 102
97 void onTestResult(unittest.TestCase testCase) { 103 void onTestResult(TestCase testCase) {
98 if (immediate) { 104 if (immediate) {
99 dumpTestResult('$testfile ', testCase); 105 dumpTestResult('$testfile ', testCase);
100 } 106 }
101 } 107 }
102 108
103 void printSummary(int passed, int failed, int errors, 109 void printSummary(int passed, int failed, int errors,
104 [String uncaughtError = '']) { 110 [String uncaughtError = '']) {
105 tprint(''); 111 tprint('');
106 if (passed == 0 && failed == 0 && errors == 0) { 112 if (passed == 0 && failed == 0 && errors == 0) {
107 tprint('$testfile: No tests found.'); 113 tprint('$testfile: No tests found.');
108 } else if (failed == 0 && errors == 0 && uncaughtError == null) { 114 } else if (failed == 0 && errors == 0 && uncaughtError == null) {
109 tprint('$testfile: All $passed tests passed.'); 115 tprint('$testfile: All $passed tests passed.');
110 } else { 116 } else {
111 if (uncaughtError != null) { 117 if (uncaughtError != null) {
112 tprint('$testfile: Top-level uncaught error: $uncaughtError'); 118 tprint('$testfile: Top-level uncaught error: $uncaughtError');
113 } 119 }
114 tprint('$testfile: $passed PASSED, $failed FAILED, $errors ERRORS'); 120 tprint('$testfile: $passed PASSED, $failed FAILED, $errors ERRORS');
115 } 121 }
116 } 122 }
117 123
118 void onSummary(int passed, int failed, int errors, 124 void onSummary(int passed, int failed, int errors,
119 List<unittest.TestCase> results, String uncaughtError) { 125 List<TestCase> results, String uncaughtError) {
120 if (!immediate) { 126 if (!immediate) {
121 for (final testCase in results) { 127 for (final testCase in results) {
122 dumpTestResult('$testfile ', testCase); 128 dumpTestResult('$testfile ', testCase);
123 } 129 }
124 } 130 }
125 if (summarize) { 131 if (summarize) {
126 printSummary(passed, failed, errors, uncaughtError); 132 printSummary(passed, failed, errors, uncaughtError);
127 } 133 }
128 } 134 }
129 135
130 void onDone(bool success) { 136 void onDone(bool success) {
131 if (notifyDone != null) { 137 if (notifyDone != null) {
132 notifyDone(success ? 0 : -1); 138 notifyDone(success ? 0 : -1);
133 } 139 }
134 } 140 }
135 } 141 }
136 142
137 // Support for listing tests and groups. We use a minimal config.
138 class MinimalTestRunnerConfiguration extends unittest.Configuration {
139 get name => 'Minimal test runner configuration';
140 get autoStart => false;
141 }
142
143 String formatListMessage(filename, groupname, [ testname = '']) { 143 String formatListMessage(filename, groupname, [ testname = '']) {
144 return listFormat. 144 return listFormat.
145 replaceAll(Macros.testfile, filename). 145 replaceAll(Macros.testfile, filename).
146 replaceAll(Macros.testGroup, groupname). 146 replaceAll(Macros.testGroup, groupname).
147 replaceAll(Macros.testDescription, testname); 147 replaceAll(Macros.testDescription, testname);
148 } 148 }
149 149
150 listGroups() { 150 listGroups() {
151 List tests = unittest.testCases; 151 List tests = testCases;
152 Map groups = {}; 152 Map groups = {};
153 for (var t in tests) { 153 for (var t in tests) {
154 var groupName, testName = ''; 154 var groupName, testName = '';
155 var idx = t.description.lastIndexOf('###'); 155 var idx = t.description.lastIndexOf(marker);
156 if (idx >= 0) { 156 if (idx >= 0) {
157 groupName = t.description.substring(0, idx).replaceAll('###', ' '); 157 groupName = t.description.substring(0, idx).replaceAll(marker, ' ');
158 if (!groups.containsKey(groupName)) { 158 if (!groups.containsKey(groupName)) {
159 groups[groupName] = ''; 159 groups[groupName] = '';
160 } 160 }
161 } 161 }
162 } 162 }
163 for (var g in groups.keys) { 163 for (var g in groups.keys) {
164 var msg = formatListMessage('$testfile ', '$g '); 164 var msg = formatListMessage('$testfile ', '$g ');
165 print('###$msg'); 165 print('$marker$msg');
166 } 166 }
167 if (notifyDone != null) { 167 if (notifyDone != null) {
168 notifyDone(0); 168 notifyDone(0);
169 } 169 }
170 } 170 }
171 171
172 listTests() { 172 listTests() {
173 List tests = unittest.testCases; 173 List tests = testCases;
174 for (var t in tests) { 174 for (var t in tests) {
175 var groupName, testName = ''; 175 var groupName, testName = '';
176 var idx = t.description.lastIndexOf('###'); 176 var idx = t.description.lastIndexOf(marker);
177 if (idx >= 0) { 177 if (idx >= 0) {
178 groupName = t.description.substring(0, idx).replaceAll('###', ' '); 178 groupName = t.description.substring(0, idx).replaceAll(marker, ' ');
179 testName = t.description.substring(idx+3); 179 testName = t.description.substring(idx+3);
180 } else { 180 } else {
181 groupName = ''; 181 groupName = '';
182 testName = t.description; 182 testName = t.description;
183 } 183 }
184 var msg = formatListMessage('$testfile ', '$groupName ', '$testName '); 184 var msg = formatListMessage('$testfile ', '$groupName ', '$testName ');
185 print('###$msg'); 185 print('$marker$msg');
186 } 186 }
187 if (notifyDone != null) { 187 if (notifyDone != null) {
188 notifyDone(0); 188 notifyDone(0);
189 } 189 }
190 } 190 }
191 191
192 // Support for running in isolates. 192 // Support for running in isolates.
193 193
194 class TestRunnerChildConfiguration extends unittest.Configuration { 194 class TestRunnerChildConfiguration extends Configuration {
195 get name => 'Test runner child configuration'; 195 get name => 'Test runner child configuration';
196 get autoStart => false; 196 get autoStart => false;
197 197
198 void onSummary(int passed, int failed, int errors, 198 void onSummary(int passed, int failed, int errors,
199 List<unittest.TestCase> results, String uncaughtError) { 199 List<TestCase> results, String uncaughtError) {
200 unittest.TestCase test = results[0]; 200 TestCase test = results[0];
201 parentPort.send([test.result, test.runningTime.inMilliseconds, 201 parentPort.send([test.result, test.runningTime.inMilliseconds,
202 test.message, test.stackTrace]); 202 test.message, test.stackTrace]);
203 } 203 }
204 } 204 }
205 205
206 var parentPort; 206 var parentPort;
207 runChildTest() { 207 runChildTest() {
208 port.receive((testName, sendport) { 208 port.receive((testName, sendport) {
209 parentPort = sendport; 209 parentPort = sendport;
210 unittest.configure(new TestRunnerChildConfiguration()); 210 unittestConfiguration = new TestRunnerChildConfiguration();
211 unittest.groupSep = '###'; 211 groupSep = marker;
212 unittest.group('', test.main); 212 group('', test.main);
213 unittest.filterTests(testName); 213 filterTests(testName);
214 unittest.runTests(); 214 runTests();
215 }); 215 });
216 } 216 }
217 217
218 var testNum; 218 isolatedTestParentWrapper(testCase) => () {
219 var failed;
220 var errors;
221 var passed;
222
223 runParentTest() {
224 var tests = unittest.testCases;
225 tests[testNum].startTime = new DateTime.now();
226 SendPort childPort = spawnFunction(runChildTest); 219 SendPort childPort = spawnFunction(runChildTest);
227 childPort.call(tests[testNum].description).then((results) { 220 var f = childPort.call(testCase.description);
221 f.then((results) {
228 var result = results[0]; 222 var result = results[0];
229 var duration = new Duration(milliseconds: results[1]); 223 var duration = new Duration(milliseconds: results[1]);
230 var message = results[2]; 224 var message = results[2];
231 var stack = results[3]; 225 var stack = results[3];
232 if (result == 'pass') { 226 if (result == 'fail') {
233 tests[testNum].pass(); 227 testCase.fail(message, stack);
234 ++passed; 228 } else if (result == 'error') {
235 } else if (result == 'fail') { 229 testCase.error(message, stack);
236 tests[testNum].fail(message, stack);
237 ++failed;
238 } else {
239 tests[testNum].error(message, stack);
240 ++errors;
241 }
242 tests[testNum].runningTime = duration;
243 ++testNum;
244 if (testNum < tests.length) {
245 runParentTest();
246 } else {
247 unittest.config.onDone(passed, failed, errors,
248 unittest.testCases, null);
249 } 230 }
250 }); 231 });
251 } 232 return f;
233 };
252 234
253 runIsolateTests() { 235 runIsolateTests() {
254 testNum = 0; 236 // Replace each test with a wrapped version first.
255 passed = failed = errors = 0; 237 for (var i = 0; i < testCases.length; i++) {
256 runParentTest(); 238 testCases[i].testFunction = isolatedTestParentWrapper(testCases[i]);
239 }
240 runTests();
257 } 241 }
258 242
259 // Main 243 // Main
260 244
261 filterTest(t) { 245 filterTest(t) {
262 var name = t.description.replaceAll("###", " "); 246 var name = t.description.replaceAll(marker, " ");
263 if (includeFilters.length > 0) { 247 if (includeFilters.length > 0) {
264 for (var f in includeFilters) { 248 for (var f in includeFilters) {
265 if (name.indexOf(f) >= 0) return true; 249 if (name.indexOf(f) >= 0) return true;
266 } 250 }
267 return false; 251 return false;
268 } else if (excludeFilters.length > 0) { 252 } else if (excludeFilters.length > 0) {
269 for (var f in excludeFilters) { 253 for (var f in excludeFilters) {
270 if (name.indexOf(f) >= 0) return false; 254 if (name.indexOf(f) >= 0) return false;
271 } 255 }
272 return true; 256 return true;
273 } else { 257 } else {
274 return true; 258 return true;
275 } 259 }
276 } 260 }
277 261
278 process(testMain, action) { 262 process(testMain, action) {
279 unittest.groupSep = '###'; 263 groupSep = marker;
280 unittest.configure(new TestRunnerConfiguration()); 264 unittestConfiguration = new TestRunnerConfiguration();
281 unittest.group('', testMain); 265 group('', testMain);
282 // Do any user-specified test filtering. 266 // Do any user-specified test filtering.
283 unittest.filterTests(filterTest); 267 filterTests(filterTest);
284 action(); 268 action();
285 } 269 }
OLDNEW
« no previous file with comments | « utils/testrunner/run_pipeline.dart ('k') | utils/testrunner/testrunner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698