OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 status_clean; | 5 library status_clean; |
6 | 6 |
7 import "dart:async"; | 7 import "dart:async"; |
8 import "dart:convert" show JSON, UTF8; | 8 import "dart:convert" show JSON, UTF8; |
9 import "dart:io"; | 9 import "dart:io"; |
10 import "testing/dart/multitest.dart"; | 10 import "testing/dart/multitest.dart"; |
11 import "testing/dart/status_file_parser.dart"; | 11 import "testing/dart/status_file_parser.dart"; |
12 import "testing/dart/test_suite.dart" | 12 import "testing/dart/test_suite.dart" |
13 show multiHtmlTestGroupRegExp, multiTestRegExp, multiHtmlTestRegExp, | 13 show |
14 TestUtils; | 14 multiHtmlTestGroupRegExp, |
| 15 multiTestRegExp, |
| 16 multiHtmlTestRegExp, |
| 17 TestUtils; |
15 import "testing/dart/utils.dart" show Path; | 18 import "testing/dart/utils.dart" show Path; |
16 | 19 |
17 // [STATUS_TUPLES] is a list of (suite-name, directory, status-file)-tuples. | 20 // [STATUS_TUPLES] is a list of (suite-name, directory, status-file)-tuples. |
18 final STATUS_TUPLES = [ | 21 final STATUS_TUPLES = [ |
19 ["corelib", "tests/corelib", "tests/corelib/corelib.status"], | 22 ["corelib", "tests/corelib", "tests/corelib/corelib.status"], |
20 ["html", "tests/html", "tests/html/html.status"], | 23 ["html", "tests/html", "tests/html/html.status"], |
21 ["isolate", "tests/isolate", "tests/isolate/isolate.status"], | 24 ["isolate", "tests/isolate", "tests/isolate/isolate.status"], |
22 ["language", "tests/language", "tests/language/language.status"], | 25 ["language", "tests/language", "tests/language/language.status"], |
23 ["language", "tests/language", "tests/language/language_analyzer2.status"], | 26 ["language", "tests/language", "tests/language/language_analyzer2.status"], |
24 ["language","tests/language", "tests/language/language_analyzer.status"], | 27 ["language", "tests/language", "tests/language/language_analyzer.status"], |
25 ["language","tests/language", "tests/language/language_dart2js.status"], | 28 ["language", "tests/language", "tests/language/language_dart2js.status"], |
26 ["lib", "tests/lib", "tests/lib/lib.status"], | 29 ["lib", "tests/lib", "tests/lib/lib.status"], |
27 ["standalone", "tests/standalone", "tests/standalone/standalone.status"], | 30 ["standalone", "tests/standalone", "tests/standalone/standalone.status"], |
28 ["pkg", "pkg", "pkg/pkg.status"], | 31 ["pkg", "pkg", "pkg/pkg.status"], |
29 ["pkgbuild", ".", "pkg/pkgbuild.status"], | 32 ["pkgbuild", ".", "pkg/pkgbuild.status"], |
30 ["utils", "tests/utils", "tests/utils/utils.status"], | 33 ["utils", "tests/utils", "tests/utils/utils.status"], |
31 ["samples", "samples", "samples/samples.status"], | 34 ["samples", "samples", "samples/samples.status"], |
32 ["analyze_library", "sdk", "tests/lib/analyzer/analyze_library.status"], | 35 ["analyze_library", "sdk", "tests/lib/analyzer/analyze_library.status"], |
33 ["dart2js_extra", "tests/compiler/dart2js_extra", | 36 [ |
34 "tests/compiler/dart2js_extra/dart2js_extra.status"], | 37 "dart2js_extra", |
35 ["dart2js_native", "tests/compiler/dart2js_native", | 38 "tests/compiler/dart2js_extra", |
36 "tests/compiler/dart2js_native/dart2js_native.status"], | 39 "tests/compiler/dart2js_extra/dart2js_extra.status" |
37 ["dart2js", "tests/compiler/dart2js", | 40 ], |
38 "tests/compiler/dart2js/dart2js.status"], | 41 [ |
39 ["benchmark_smoke", "tests/benchmark_smoke", | 42 "dart2js_native", |
40 "tests/benchmark_smoke/benchmark_smoke.status"], | 43 "tests/compiler/dart2js_native", |
41 ["co19", "tests/co19/src", "tests/co19/co19-analyzer2.status"], | 44 "tests/compiler/dart2js_native/dart2js_native.status" |
42 ["co19", "tests/co19/src", "tests/co19/co19-analyzer.status"], | 45 ], |
43 ["co19", "tests/co19/src", "tests/co19/co19-dart2js.status"], | 46 [ |
44 ["co19", "tests/co19/src", "tests/co19/co19-co19.status"], | 47 "dart2js", |
45 ["co19", "tests/co19/src", "tests/co19/co19-dartium.status"], | 48 "tests/compiler/dart2js", |
46 ["co19", "tests/co19/src", "tests/co19/co19-runtime.status"], | 49 "tests/compiler/dart2js/dart2js.status" |
| 50 ], |
| 51 [ |
| 52 "benchmark_smoke", |
| 53 "tests/benchmark_smoke", |
| 54 "tests/benchmark_smoke/benchmark_smoke.status" |
| 55 ], |
| 56 ["co19", "tests/co19/src", "tests/co19/co19-analyzer2.status"], |
| 57 ["co19", "tests/co19/src", "tests/co19/co19-analyzer.status"], |
| 58 ["co19", "tests/co19/src", "tests/co19/co19-dart2js.status"], |
| 59 ["co19", "tests/co19/src", "tests/co19/co19-co19.status"], |
| 60 ["co19", "tests/co19/src", "tests/co19/co19-dartium.status"], |
| 61 ["co19", "tests/co19/src", "tests/co19/co19-runtime.status"], |
47 ]; | 62 ]; |
48 | 63 |
49 void main(List<String> args) { | 64 void main(List<String> args) { |
50 TestUtils.setDartDirUri(Platform.script.resolve('..')); | 65 TestUtils.setDartDirUri(Platform.script.resolve('..')); |
51 usage() { | 66 usage() { |
52 print("Usage: ${Platform.executable} <deflake|remove-nonexistent-tests>"); | 67 print("Usage: ${Platform.executable} <deflake|remove-nonexistent-tests>"); |
53 exit(1); | 68 exit(1); |
54 } | 69 } |
55 | 70 |
56 if (args.length == 0) usage(); | 71 if (args.length == 0) usage(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 Future run(String suiteName, String directory, String filePath) { | 115 Future run(String suiteName, String directory, String filePath) { |
101 return _readSections(filePath).then((List<Section> sections) { | 116 return _readSections(filePath).then((List<Section> sections) { |
102 Set<int> invalidLines = _analyzeStatusFile(directory, filePath, sections); | 117 Set<int> invalidLines = _analyzeStatusFile(directory, filePath, sections); |
103 if (invalidLines.length > 0) { | 118 if (invalidLines.length > 0) { |
104 return _writeFixedStatusFile(filePath, invalidLines); | 119 return _writeFixedStatusFile(filePath, invalidLines); |
105 } | 120 } |
106 return new Future.value(); | 121 return new Future.value(); |
107 }); | 122 }); |
108 } | 123 } |
109 | 124 |
110 bool _testExists(String filePath, | 125 bool _testExists(String filePath, List<String> testFiles, String directory, |
111 List<String> testFiles, | 126 TestRule rule) { |
112 String directory, | |
113 TestRule rule) { | |
114 // TODO: Unify this regular expression matching with status_file_parser.dart | 127 // TODO: Unify this regular expression matching with status_file_parser.dart |
115 List<RegExp> getRuleRegex(String name) { | 128 List<RegExp> getRuleRegex(String name) { |
116 return name.split("/") | 129 return name |
| 130 .split("/") |
117 .map((name) => new RegExp(name.replaceAll('*', '.*'))) | 131 .map((name) => new RegExp(name.replaceAll('*', '.*'))) |
118 .toList(); | 132 .toList(); |
119 } | 133 } |
| 134 |
120 bool matchRegexp(List<RegExp> patterns, String str) { | 135 bool matchRegexp(List<RegExp> patterns, String str) { |
121 var parts = str.split("/"); | 136 var parts = str.split("/"); |
122 if (patterns.length > parts.length) { | 137 if (patterns.length > parts.length) { |
123 return false; | 138 return false; |
124 } | 139 } |
125 // NOTE: patterns.length <= parts.length | 140 // NOTE: patterns.length <= parts.length |
126 for (var i = 0; i < patterns.length; i++) { | 141 for (var i = 0; i < patterns.length; i++) { |
127 if (!patterns[i].hasMatch(parts[i])) { | 142 if (!patterns[i].hasMatch(parts[i])) { |
128 return false; | 143 return false; |
129 } | 144 } |
130 } | 145 } |
131 return true; | 146 return true; |
132 } | 147 } |
133 | 148 |
134 var rulePattern = getRuleRegex(rule.name); | 149 var rulePattern = getRuleRegex(rule.name); |
135 return testFiles.any((String file) { | 150 return testFiles.any((String file) { |
136 // TODO: Use test_suite.dart's [buildTestCaseDisplayName] instead. | 151 // TODO: Use test_suite.dart's [buildTestCaseDisplayName] instead. |
137 var filePath = new Path(file).relativeTo(new Path(directory)); | 152 var filePath = new Path(file).relativeTo(new Path(directory)); |
138 String baseTestName = _concat("${filePath.directoryPath}", | 153 String baseTestName = _concat( |
139 "${filePath.filenameWithoutExtension}"); | 154 "${filePath.directoryPath}", "${filePath.filenameWithoutExtension}"); |
140 | 155 |
141 List<String> testNames = []; | 156 List<String> testNames = []; |
142 for (var name in multiTestDetector.getMultitestNames(file)) { | 157 for (var name in multiTestDetector.getMultitestNames(file)) { |
143 testNames.add(_concat(baseTestName, name)); | 158 testNames.add(_concat(baseTestName, name)); |
144 } | 159 } |
145 | 160 |
146 // If it is not a multitest the testname is [baseTestName] | 161 // If it is not a multitest the testname is [baseTestName] |
147 if (testNames.isEmpty) { | 162 if (testNames.isEmpty) { |
148 testNames.add(baseTestName); | 163 testNames.add(baseTestName); |
149 } | 164 } |
150 | 165 |
151 return testNames.any( | 166 return testNames |
152 (String testName) => matchRegexp(rulePattern, testName)); | 167 .any((String testName) => matchRegexp(rulePattern, testName)); |
153 }); | 168 }); |
154 } | 169 } |
155 | 170 |
156 Set<int> _analyzeStatusFile(String directory, | 171 Set<int> _analyzeStatusFile( |
157 String filePath, | 172 String directory, String filePath, List<Section> sections) { |
158 List<Section> sections) { | |
159 var invalidLines = new Set<int>(); | 173 var invalidLines = new Set<int>(); |
160 var dartFiles = testFileLister.listTestFiles(directory); | 174 var dartFiles = testFileLister.listTestFiles(directory); |
161 for (var section in sections) { | 175 for (var section in sections) { |
162 for (var rule in section.testRules) { | 176 for (var rule in section.testRules) { |
163 if (!_testExists(filePath, dartFiles, directory, rule)) { | 177 if (!_testExists(filePath, dartFiles, directory, rule)) { |
164 print("Invalid rule: ${rule.name} in file " | 178 print("Invalid rule: ${rule.name} in file " |
165 "$filePath:${rule.lineNumber}"); | 179 "$filePath:${rule.lineNumber}"); |
166 invalidLines.add(rule.lineNumber); | 180 invalidLines.add(rule.lineNumber); |
167 } | 181 } |
168 } | 182 } |
169 } | 183 } |
170 return invalidLines; | 184 return invalidLines; |
171 } | 185 } |
172 | 186 |
173 _writeFixedStatusFile(String statusFilePath, Set<int> invalidLines) { | 187 _writeFixedStatusFile(String statusFilePath, Set<int> invalidLines) { |
174 var lines = new File(statusFilePath).readAsLinesSync(); | 188 var lines = new File(statusFilePath).readAsLinesSync(); |
175 var outputLines = <String>[]; | 189 var outputLines = <String>[]; |
176 for (int i = 0; i < lines.length; i++) { | 190 for (int i = 0; i < lines.length; i++) { |
177 // The status file parser numbers lines starting with 1, not 0. | 191 // The status file parser numbers lines starting with 1, not 0. |
178 if (!invalidLines.contains(i + 1)) { | 192 if (!invalidLines.contains(i + 1)) { |
179 outputLines.add(lines[i]); | 193 outputLines.add(lines[i]); |
180 } | 194 } |
181 } | 195 } |
182 var outputFile = new File("$statusFilePath.fixed"); | 196 var outputFile = new File("$statusFilePath.fixed"); |
183 outputFile.writeAsStringSync(outputLines.join("\n")); | 197 outputFile.writeAsStringSync(outputLines.join("\n")); |
184 } | 198 } |
185 | 199 |
186 String _concat(String base, String part) { | 200 String _concat(String base, String part) { |
187 if (base == "") return part; | 201 if (base == "") return part; |
188 if (part == "") return base; | 202 if (part == "") return base; |
189 return "$base/$part"; | 203 return "$base/$part"; |
190 } | 204 } |
191 } | 205 } |
192 | 206 |
193 class StatusFileDeflaker extends StatusFileProcessor { | 207 class StatusFileDeflaker extends StatusFileProcessor { |
194 TestOutcomeFetcher _testOutcomeFetcher = new TestOutcomeFetcher(); | 208 TestOutcomeFetcher _testOutcomeFetcher = new TestOutcomeFetcher(); |
195 | 209 |
196 Future run(String suiteName, String directory, String filePath) { | 210 Future run(String suiteName, String directory, String filePath) { |
197 return _readSections(filePath).then((List<Section> sections) { | 211 return _readSections(filePath).then((List<Section> sections) { |
198 return _generatedDeflakedLines(suiteName, sections) | 212 return _generatedDeflakedLines(suiteName, sections) |
199 .then((Map<int, String> fixedLines) { | 213 .then((Map<int, String> fixedLines) { |
200 if (fixedLines.length > 0) { | 214 if (fixedLines.length > 0) { |
201 return _writeFixedStatusFile(filePath, fixedLines); | 215 return _writeFixedStatusFile(filePath, fixedLines); |
202 } | 216 } |
203 }); | 217 }); |
204 }); | 218 }); |
205 } | 219 } |
206 | 220 |
207 Future _generatedDeflakedLines(String suiteName, | 221 Future _generatedDeflakedLines(String suiteName, List<Section> sections) { |
208 List<Section> sections) { | |
209 var fixedLines = new Map<int, String>(); | 222 var fixedLines = new Map<int, String>(); |
210 return Future.forEach(sections, (Section section) { | 223 return Future.forEach(sections, (Section section) { |
211 return Future.forEach(section.testRules, (rule) { | 224 return Future.forEach(section.testRules, (rule) { |
212 return _maybeFixStatusfileLine(suiteName, section, rule, fixedLines); | 225 return _maybeFixStatusfileLine(suiteName, section, rule, fixedLines); |
213 }); | 226 }); |
214 }).then((_) => fixedLines); | 227 }).then((_) => fixedLines); |
215 } | 228 } |
216 | 229 |
217 Future _maybeFixStatusfileLine(String suiteName, | 230 Future _maybeFixStatusfileLine(String suiteName, Section section, |
218 Section section, | 231 TestRule rule, Map<int, String> fixedLines) { |
219 TestRule rule, | |
220 Map<int, String> fixedLines) { | |
221 print("Processing ${section.statusFile.location}: ${rule.lineNumber}"); | 232 print("Processing ${section.statusFile.location}: ${rule.lineNumber}"); |
222 // None of our status file lines have expressions, so we pass {} here. | 233 // None of our status file lines have expressions, so we pass {} here. |
223 var notedOutcomes = rule.expression | 234 var notedOutcomes = rule.expression |
224 .evaluate({}) | 235 .evaluate({}) |
225 .map((name) => Expectation.byName(name)) | 236 .map((name) => Expectation.byName(name)) |
226 .where((Expectation expectation) => !expectation.isMetaExpectation) | 237 .where((Expectation expectation) => !expectation.isMetaExpectation) |
227 .toSet(); | 238 .toSet(); |
228 | 239 |
229 if (notedOutcomes.isEmpty) return new Future.value(); | 240 if (notedOutcomes.isEmpty) return new Future.value(); |
230 | 241 |
231 // TODO: [rule.name] is actually a pattern not just a testname. We should | 242 // TODO: [rule.name] is actually a pattern not just a testname. We should |
232 // find all possible testnames this rule matches against and unify the | 243 // find all possible testnames this rule matches against and unify the |
233 // outcomes of these tests. | 244 // outcomes of these tests. |
234 return _testOutcomeFetcher.outcomesOf(suiteName, section, rule.name) | 245 return _testOutcomeFetcher |
235 .then((Set<Expectation> actualOutcomes) { | 246 .outcomesOf(suiteName, section, rule.name) |
236 | 247 .then((Set<Expectation> actualOutcomes) { |
237 var outcomesThatNeverHappened = new Set<Expectation>(); | 248 var outcomesThatNeverHappened = new Set<Expectation>(); |
238 for (Expectation notedOutcome in notedOutcomes) { | 249 for (Expectation notedOutcome in notedOutcomes) { |
239 bool found = false; | 250 bool found = false; |
240 for (Expectation actualOutcome in actualOutcomes) { | 251 for (Expectation actualOutcome in actualOutcomes) { |
241 if (actualOutcome.canBeOutcomeOf(notedOutcome)) { | 252 if (actualOutcome.canBeOutcomeOf(notedOutcome)) { |
242 found = true; | 253 found = true; |
243 break; | 254 break; |
244 } | 255 } |
245 } | 256 } |
246 if (!found) { | 257 if (!found) { |
247 outcomesThatNeverHappened.add(notedOutcome); | 258 outcomesThatNeverHappened.add(notedOutcome); |
248 } | 259 } |
249 } | 260 } |
250 | 261 |
251 if (outcomesThatNeverHappened.length > 0 && actualOutcomes.length > 0) { | 262 if (outcomesThatNeverHappened.length > 0 && actualOutcomes.length > 0) { |
252 // Print the change to stdout. | 263 // Print the change to stdout. |
253 print("${rule.name} " | 264 print("${rule.name} " |
254 "(${section.statusFile.location}:${rule.lineNumber}):"); | 265 "(${section.statusFile.location}:${rule.lineNumber}):"); |
255 print(" Actual outcomes: ${actualOutcomes.toList()}"); | 266 print(" Actual outcomes: ${actualOutcomes.toList()}"); |
256 print(" Outcomes in status file: ${notedOutcomes.toList()}"); | 267 print(" Outcomes in status file: ${notedOutcomes.toList()}"); |
257 print(" Outcomes in status file that never happened : " | 268 print(" Outcomes in status file that never happened : " |
258 "${outcomesThatNeverHappened.toList()}\n"); | 269 "${outcomesThatNeverHappened.toList()}\n"); |
259 | 270 |
260 // Build the fixed status file line. | 271 // Build the fixed status file line. |
261 fixedLines[rule.lineNumber] = | 272 fixedLines[rule.lineNumber] = |
262 '${rule.name}: ${actualOutcomes.join(', ')} ' | 273 '${rule.name}: ${actualOutcomes.join(', ')} ' |
263 '# before: ${notedOutcomes.join(', ')} / ' | 274 '# before: ${notedOutcomes.join(', ')} / ' |
264 'never happened: ${outcomesThatNeverHappened.join(', ')}'; | 275 'never happened: ${outcomesThatNeverHappened.join(', ')}'; |
265 } | 276 } |
266 }); | 277 }); |
267 } | 278 } |
268 | 279 |
269 _writeFixedStatusFile(String filePath, Map<int, String> fixedLines) { | 280 _writeFixedStatusFile(String filePath, Map<int, String> fixedLines) { |
270 var lines = new File(filePath).readAsLinesSync(); | 281 var lines = new File(filePath).readAsLinesSync(); |
271 var outputLines = <String>[]; | 282 var outputLines = <String>[]; |
272 for (int i = 0; i < lines.length; i++) { | 283 for (int i = 0; i < lines.length; i++) { |
273 if (fixedLines.containsKey(i + 1)) { | 284 if (fixedLines.containsKey(i + 1)) { |
274 outputLines.add(fixedLines[i + 1]); | 285 outputLines.add(fixedLines[i + 1]); |
275 } else { | 286 } else { |
276 outputLines.add(lines[i]); | 287 outputLines.add(lines[i]); |
277 } | 288 } |
278 } | 289 } |
279 var output = outputLines.join("\n"); | 290 var output = outputLines.join("\n"); |
280 var outputFile = new File("$filePath.deflaked"); | 291 var outputFile = new File("$filePath.deflaked"); |
281 outputFile.writeAsStringSync(output); | 292 outputFile.writeAsStringSync(output); |
282 } | 293 } |
283 } | 294 } |
284 | 295 |
285 class MultiTestDetector { | 296 class MultiTestDetector { |
286 final multiTestsCache = new Map<String,List<String>>(); | 297 final multiTestsCache = new Map<String, List<String>>(); |
287 final multiHtmlTestsCache = new Map<String,List<String>>(); | 298 final multiHtmlTestsCache = new Map<String, List<String>>(); |
288 | |
289 | 299 |
290 List<String> getMultitestNames(String file) { | 300 List<String> getMultitestNames(String file) { |
291 List<String> names = []; | 301 List<String> names = []; |
292 names.addAll(getStandardMultitestNames(file)); | 302 names.addAll(getStandardMultitestNames(file)); |
293 names.addAll(getHtmlMultitestNames(file)); | 303 names.addAll(getHtmlMultitestNames(file)); |
294 return names; | 304 return names; |
295 } | 305 } |
296 | 306 |
297 List<String> getStandardMultitestNames(String file) { | 307 List<String> getStandardMultitestNames(String file) { |
298 return multiTestsCache.putIfAbsent(file, () { | 308 return multiTestsCache.putIfAbsent(file, () { |
(...skipping 11 matching lines...) Expand all Loading... |
310 }); | 320 }); |
311 } | 321 } |
312 | 322 |
313 List<String> getHtmlMultitestNames(String file) { | 323 List<String> getHtmlMultitestNames(String file) { |
314 return multiHtmlTestsCache.putIfAbsent(file, () { | 324 return multiHtmlTestsCache.putIfAbsent(file, () { |
315 try { | 325 try { |
316 List<String> subtestNames = []; | 326 List<String> subtestNames = []; |
317 var content = new File(file).readAsStringSync(); | 327 var content = new File(file).readAsStringSync(); |
318 | 328 |
319 if (multiHtmlTestRegExp.hasMatch(content)) { | 329 if (multiHtmlTestRegExp.hasMatch(content)) { |
320 var matchesIter = multiHtmlTestGroupRegExp.allMatches(content).iterato
r; | 330 var matchesIter = |
321 while(matchesIter.moveNext()) { | 331 multiHtmlTestGroupRegExp.allMatches(content).iterator; |
| 332 while (matchesIter.moveNext()) { |
322 String fullMatch = matchesIter.current.group(0); | 333 String fullMatch = matchesIter.current.group(0); |
323 subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1)); | 334 subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1)); |
324 } | 335 } |
325 } | 336 } |
326 return subtestNames; | 337 return subtestNames; |
327 } catch (error) { | 338 } catch (error) { |
328 print("WARNING: Couldn't determine multitests in file ${file}: $error"); | 339 print("WARNING: Couldn't determine multitests in file ${file}: $error"); |
329 } | 340 } |
330 return []; | 341 return []; |
331 }); | 342 }); |
332 } | 343 } |
333 } | 344 } |
334 | 345 |
335 class TestFileLister { | 346 class TestFileLister { |
336 final Map<String, List<String>> _filesCache = {}; | 347 final Map<String, List<String>> _filesCache = {}; |
337 | 348 |
338 List<String> listTestFiles(String directory) { | 349 List<String> listTestFiles(String directory) { |
339 return _filesCache.putIfAbsent(directory, () { | 350 return _filesCache.putIfAbsent(directory, () { |
340 var dir = new Directory(directory); | 351 var dir = new Directory(directory); |
341 // Cannot test for _test.dart because co19 tests don't have that ending. | 352 // Cannot test for _test.dart because co19 tests don't have that ending. |
342 var dartFiles = dir.listSync(recursive: true) | 353 var dartFiles = dir |
| 354 .listSync(recursive: true) |
343 .where((fe) => fe is File) | 355 .where((fe) => fe is File) |
344 .where((file) => file.path.endsWith(".dart") || | 356 .where((file) => |
345 file.path.endsWith("_test.html")) | 357 file.path.endsWith(".dart") || file.path.endsWith("_test.html")) |
346 .map((file) => file.path) | 358 .map((file) => file.path) |
347 .toList(); | 359 .toList(); |
348 return dartFiles; | 360 return dartFiles; |
349 }); | 361 }); |
350 } | 362 } |
351 } | 363 } |
352 | 364 |
353 | |
354 /* | 365 /* |
355 * [TestOutcomeFetcher] will fetch test results from a server using a REST-like | 366 * [TestOutcomeFetcher] will fetch test results from a server using a REST-like |
356 * interface. | 367 * interface. |
357 */ | 368 */ |
358 class TestOutcomeFetcher { | 369 class TestOutcomeFetcher { |
359 static String SERVER = '108.170.219.8'; | 370 static String SERVER = '108.170.219.8'; |
360 static int PORT = 4540; | 371 static int PORT = 4540; |
361 | 372 |
362 HttpClient _client = new HttpClient(); | 373 HttpClient _client = new HttpClient(); |
363 | 374 |
364 Future<Set<Expectation>> outcomesOf( | 375 Future<Set<Expectation>> outcomesOf( |
365 String suiteName, Section section, String testName) { | 376 String suiteName, Section section, String testName) { |
366 var pathComponents = ['json', 'test-outcomes', 'outcomes', | 377 var pathComponents = [ |
367 Uri.encodeComponent("$suiteName/$testName")]; | 378 'json', |
| 379 'test-outcomes', |
| 380 'outcomes', |
| 381 Uri.encodeComponent("$suiteName/$testName") |
| 382 ]; |
368 var path = pathComponents.join('/') + '/'; | 383 var path = pathComponents.join('/') + '/'; |
369 var url = new Uri(scheme: 'http', host: SERVER, port: PORT, path: path); | 384 var url = new Uri(scheme: 'http', host: SERVER, port: PORT, path: path); |
370 | 385 |
371 return _client.getUrl(url) | 386 return _client |
372 .then((HttpClientRequest request) => request.close()) | 387 .getUrl(url) |
373 .then((HttpClientResponse response) { | 388 .then((HttpClientRequest request) => request.close()) |
374 return response.transform(UTF8.decoder).transform(JSON.decoder).first | 389 .then((HttpClientResponse response) { |
375 .then((List testResults) { | 390 return response |
376 var setOfActualOutcomes = new Set<Expectation>(); | 391 .transform(UTF8.decoder) |
| 392 .transform(JSON.decoder) |
| 393 .first |
| 394 .then((List testResults) { |
| 395 var setOfActualOutcomes = new Set<Expectation>(); |
377 | 396 |
378 try { | 397 try { |
379 for (var result in testResults) { | 398 for (var result in testResults) { |
380 var config = result['configuration']; | 399 var config = result['configuration']; |
381 var testResult = result['test_result']; | 400 var testResult = result['test_result']; |
382 var outcome = testResult['outcome']; | 401 var outcome = testResult['outcome']; |
383 | 402 |
384 // These variables are derived variables and will be set in | 403 // These variables are derived variables and will be set in |
385 // tools/testing/dart/test_options.dart. | 404 // tools/testing/dart/test_options.dart. |
386 // [Mostly due to the fact that we don't have an unary ! | 405 // [Mostly due to the fact that we don't have an unary ! |
387 // operator in status file expressions.] | 406 // operator in status file expressions.] |
388 config['unchecked'] = !config['checked']; | 407 config['unchecked'] = !config['checked']; |
389 config['unminified'] = !config['minified']; | 408 config['unminified'] = !config['minified']; |
390 config['nocsp'] = !config['csp']; | 409 config['nocsp'] = !config['csp']; |
391 config['browser'] = | 410 config['browser'] = TestUtils.isBrowserRuntime(config['runtime']); |
392 TestUtils.isBrowserRuntime(config['runtime']); | 411 config['analyzer'] = |
393 config['analyzer'] = | 412 TestUtils.isCommandLineAnalyzer(config['compiler']); |
394 TestUtils.isCommandLineAnalyzer(config['compiler']); | 413 config['jscl'] = |
395 config['jscl'] = | 414 TestUtils.isJsCommandLineRuntime(config['runtime']); |
396 TestUtils.isJsCommandLineRuntime(config['runtime']); | |
397 | 415 |
398 if (section.condition == null || | 416 if (section.condition == null || |
399 section.condition.evaluate(config)) { | 417 section.condition.evaluate(config)) { |
400 setOfActualOutcomes.add(Expectation.byName(outcome)); | 418 setOfActualOutcomes.add(Expectation.byName(outcome)); |
401 } | 419 } |
402 } | 420 } |
403 return setOfActualOutcomes; | 421 return setOfActualOutcomes; |
404 } catch (error) { | 422 } catch (error) { |
405 print("Warning: Error occured while processing testoutcomes" | 423 print("Warning: Error occured while processing testoutcomes" |
406 ": $error"); | 424 ": $error"); |
407 return []; | 425 return []; |
408 } | 426 } |
409 }).catchError((error) { | 427 }).catchError((error) { |
410 print("Warning: Error occured while fetching testoutcomes: $error"
); | 428 print("Warning: Error occured while fetching testoutcomes: $error"); |
411 return []; | 429 return []; |
412 }); | 430 }); |
413 }); | 431 }); |
414 } | 432 } |
415 } | 433 } |
OLD | NEW |