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

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

Issue 2901923003: Replace the configuration map with a typed object. (Closed)
Patch Set: Revise. Created 3 years, 6 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
« no previous file with comments | « tools/testing/dart/compiler_configuration.dart ('k') | tools/testing/dart/drt_updater.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
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.
4
5 import 'dart:async';
6 import 'dart:convert';
7 import 'dart:io';
8
9 import 'compiler_configuration.dart';
10 import 'http_server.dart';
11 import 'path.dart';
12 import 'runtime_configuration.dart';
13 import 'test_suite.dart';
14
15 /// All of the contextual information to determine how a test suite should be
16 /// run.
17 ///
18 /// Includes the compiler used to compile the code, the runtime the result is
19 /// executed on, etc.
20 class Configuration {
21 Configuration(
22 {this.architecture,
23 this.compiler,
24 this.mode,
25 this.progress,
26 this.runtime,
27 this.system,
28 this.selectors,
29 this.appendLogs,
30 this.batch,
31 this.batchDart2JS,
32 this.copyCoreDumps,
33 this.hotReload,
34 this.hotReloadRollback,
35 this.isChecked,
36 this.isStrong,
37 this.isHostChecked,
38 this.isCsp,
39 this.isMinified,
40 this.isVerbose,
41 this.listTests,
42 this.printTiming,
43 this.printReport,
44 this.reportInJson,
45 this.resetBrowser,
46 this.skipCompilation,
47 this.useBlobs,
48 this.useSdk,
49 this.useFastStartup,
50 this.useDart2JSWithKernel,
51 this.writeDebugLog,
52 this.writeTestOutcomeLog,
53 this.drtPath,
54 this.dartiumPath,
55 this.chromePath,
56 this.safariPath,
57 this.firefoxPath,
58 this.dartPath,
59 this.dartPrecompiledPath,
60 this.flutterPath,
61 this.recordingPath,
62 this.replayPath,
63 this.taskCount,
64 int timeout,
65 this.shardCount,
66 this.shard,
67 this.stepName,
68 this.testServerPort,
69 this.testServerCrossOriginPort,
70 this.testDriverErrorPort,
71 this.localIP,
72 this.dart2jsOptions,
73 this.vmOptions,
74 String packages,
75 this.packageRoot,
76 this.suiteDirectory,
77 this.builderTag,
78 this.reproducingArguments})
79 : _packages = packages,
80 _timeout = timeout;
81
82 final Architecture architecture;
83 final Compiler compiler;
84 final Mode mode;
85 final Progress progress;
86 final Runtime runtime;
87 final System system;
88
89 final Map<String, RegExp> selectors;
90
91 // Boolean flags.
92
93 final bool appendLogs;
94 final bool batch;
95 final bool batchDart2JS;
96 final bool copyCoreDumps;
97 final bool hotReload;
98 final bool hotReloadRollback;
99 final bool isChecked;
100 final bool isStrong;
101 final bool isHostChecked;
102 final bool isCsp;
103 final bool isMinified;
104 final bool isVerbose;
105 final bool listTests;
106 final bool printTiming;
107 final bool printReport;
108 final bool reportInJson;
109 final bool resetBrowser;
110 final bool skipCompilation;
111 final bool useBlobs;
112 final bool useSdk;
113 final bool useFastStartup;
114 final bool useDart2JSWithKernel;
115 final bool writeDebugLog;
116 final bool writeTestOutcomeLog;
117
118 // Various file paths.
119
120 final String drtPath;
121 final String dartiumPath;
122 final String chromePath;
123 final String safariPath;
124 final String firefoxPath;
125 final String dartPath;
126 final String dartPrecompiledPath;
127 final String flutterPath;
128 final String recordingPath;
129 final String replayPath;
130
131 final int taskCount;
132 final int shardCount;
133 final int shard;
134 final String stepName;
135
136 final int testServerPort;
137 final int testServerCrossOriginPort;
138 final int testDriverErrorPort;
139 final String localIP;
140
141 /// Extra dart2js options passed to the testing script.
142 final List<String> dart2jsOptions;
143
144 /// Extra VM options passed to the testing script.
145 final List<String> vmOptions;
146
147 String _packages;
148 String get packages {
149 // If the .packages file path wasn't given, find it.
150 if (packageRoot == null && _packages == null) {
151 _packages = TestUtils.dartDirUri.resolve('.packages').toFilePath();
152 }
153
154 return _packages;
155 }
156
157 final String packageRoot;
158 final String suiteDirectory;
159 final String builderTag;
160 final List<String> reproducingArguments;
161
162 TestingServers _servers;
163 TestingServers get servers {
164 if (_servers == null) {
165 throw new StateError("Servers have not been started yet.");
166 }
167 return _servers;
168 }
169
170 /// The base directory named for this configuration, like:
171 ///
172 /// none_vm_release_x64
173 String _configurationDirectory;
174 String get configurationDirectory {
175 // Lazy initialize and cache since it requires hitting the file system.
176 if (_configurationDirectory == null) {
177 _configurationDirectory = _calculateDirectory();
178 }
179
180 return _configurationDirectory;
181 }
182
183 /// The build directory path for this configuration, like:
184 ///
185 /// build/none_vm_release_x64
186 String get buildDirectory => system.outputDirectory + configurationDirectory;
187
188 int _timeout;
189 int get timeout {
190 if (_timeout == null) {
191 var isReload = hotReload || hotReloadRollback;
192
193 var compilerMulitiplier = compilerConfiguration.timeoutMultiplier;
194 var runtimeMultiplier = runtimeConfiguration.timeoutMultiplier(
195 mode: mode,
196 isChecked: isChecked,
197 isReload: isReload,
198 arch: architecture);
199
200 _timeout = 60 * compilerMulitiplier * runtimeMultiplier;
201 }
202
203 return _timeout;
204 }
205
206 List<String> get standardOptions {
207 if (compiler != Compiler.dart2js) {
208 return const ["--ignore-unrecognized-flags"];
209 }
210
211 var args = ['--generate-code-with-compile-time-errors', '--test-mode'];
212 if (isChecked) args.add('--enable-checked-mode');
213
214 if (!runtime.isBrowser) {
215 args.add("--allow-mock-compilation");
216 args.add("--categories=all");
217 }
218
219 if (isMinified) args.add("--minify");
220 if (isCsp) args.add("--csp");
221 if (useFastStartup) args.add("--fast-startup");
222 if (useDart2JSWithKernel) args.add("--use-kernel");
223 return args;
224 }
225
226 String _windowsSdkPath;
227 String get windowsSdkPath {
228 if (!Platform.isWindows) {
229 throw new StateError(
230 "Should not use windowsSdkPath when not running on Windows.");
231 }
232
233 if (_windowsSdkPath == null) {
234 // When running tests on Windows, use cdb from depot_tools to dump
235 // stack traces of tests timing out.
236 try {
237 var path = new Path("build/win_toolchain.json").toNativePath();
238 var text = new File(path).readAsStringSync();
239 _windowsSdkPath = JSON.decode(text)['win_sdk'] as String;
240 } on dynamic {
241 // Ignore errors here. If win_sdk is not found, stack trace dumping
242 // for timeouts won't work.
243 }
244 }
245
246 return _windowsSdkPath;
247 }
248
249 /// Gets the local file path to the browser executable for this configuration.
250 String get browserLocation {
251 // If the user has explicitly configured a browser path, use it.
252 String location;
253 switch (runtime) {
254 case Runtime.chrome:
255 location = chromePath;
256 break;
257 case Runtime.dartium:
258 location = dartiumPath;
259 break;
260 case Runtime.drt:
261 location = drtPath;
262 break;
263 case Runtime.firefox:
264 location = firefoxPath;
265 break;
266 case Runtime.flutter:
267 location = flutterPath;
268 break;
269 case Runtime.safari:
270 location = safariPath;
271 break;
272 }
273
274 if (location != null) return location;
275
276 const locations = const {
277 Runtime.firefox: const {
278 System.windows: 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
279 System.linux: 'firefox',
280 System.macos: '/Applications/Firefox.app/Contents/MacOS/firefox'
281 },
282 Runtime.chrome: const {
283 System.windows:
284 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
285 System.macos:
286 '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
287 System.linux: 'google-chrome'
288 },
289 Runtime.dartium: const {
290 System.windows: 'client\\tests\\dartium\\chrome.exe',
291 System.macos:
292 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
293 System.linux: 'client/tests/dartium/chrome'
294 },
295 Runtime.safari: const {
296 System.macos: '/Applications/Safari.app/Contents/MacOS/Safari'
297 },
298 Runtime.safariMobileSim: const {
299 System.macos: '/Applications/Xcode.app/Contents/Developer/Platforms/'
300 'iPhoneSimulator.platform/Developer/Applications/'
301 'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
302 },
303 Runtime.ie9: const {
304 System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
305 },
306 Runtime.ie10: const {
307 System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
308 },
309 Runtime.ie11: const {
310 System.windows: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
311 }
312 };
313
314 location = locations[runtime][System.find(Platform.operatingSystem)];
315
316 if (location == null) {
317 throw "${runtime.name} is not supported on ${Platform.operatingSystem}";
318 }
319
320 return location;
321 }
322
323 RuntimeConfiguration _runtimeConfiguration;
324 RuntimeConfiguration get runtimeConfiguration =>
325 _runtimeConfiguration ??= new RuntimeConfiguration(this);
326
327 CompilerConfiguration _compilerConfiguration;
328 CompilerConfiguration get compilerConfiguration =>
329 _compilerConfiguration ??= new CompilerConfiguration(this);
330
331 /// Determines if this configuration has a compatible compiler and runtime
332 /// and other valid fields.
333 ///
334 /// Prints a warning if the configuration isn't valid. Returns whether or not
335 /// it is.
336 bool validate() {
337 var isValid = true;
338 var validRuntimes = compiler.supportedRuntimes;
339
340 if (!validRuntimes.contains(runtime)) {
341 print("Warning: combination of compiler '${compiler.name}' and "
342 "runtime '${runtime.name}' is invalid. Skipping this combination.");
343 isValid = false;
344 }
345
346 if (runtime.isIE && Platform.operatingSystem != 'windows') {
347 print("Warning: cannot run Internet Explorer on non-Windows operating"
348 " system.");
349 isValid = false;
350 }
351
352 if (shard < 1 || shard > shardCount) {
353 print("Error: shard index is $shard out of $shardCount shards");
354 isValid = false;
355 }
356
357 if (runtime == Runtime.flutter && flutterPath == null) {
358 print("-rflutter requires the flutter engine executable to "
359 "be specified using --flutter");
360 isValid = false;
361 }
362
363 if (runtime == Runtime.flutter && architecture != Architecture.x64) {
364 isValid = false;
365 print("-rflutter is applicable only for --arch=x64");
366 }
367
368 return isValid;
369 }
370
371 /// Starts global HTTP servers that serve the entire dart repo.
372 ///
373 /// The HTTP server is available on `window.location.port`, and a second
374 /// server for cross-domain tests can be found by calling
375 /// `getCrossOriginPortNumber()`.
376 Future startServers() {
377 _servers = new TestingServers(
378 buildDirectory, isCsp, runtime, null, packageRoot, packages);
379 var future = servers.startServers(localIP,
380 port: testServerPort, crossOriginPort: testServerCrossOriginPort);
381
382 if (isVerbose) {
383 future = future.then((_) {
384 print('Started HttpServers: ${servers.httpServerCommandLine()}');
385 });
386 }
387
388 return future;
389 }
390
391 void stopServers() {
392 if (_servers != null) _servers.stopServers();
393 }
394
395 /// Returns the correct configuration directory (the last component of the
396 /// output directory path) for regular dart checkouts.
397 ///
398 /// Dartium checkouts use the `--build-directory` option to pass in the
399 /// correct build directory explicitly. We allow our code to have been cross
400 /// compiled, i.e., that there is an X in front of the arch. We don't allow
401 /// both a cross compiled and a normal version to be present (except if you
402 /// specifically pass in the build_directory).
403 String _calculateDirectory() {
404 // Capitalize the mode name.
405 var modeName =
406 mode.name.substring(0, 1).toUpperCase() + mode.name.substring(1);
407
408 var os = '';
409 if (system == System.android) os = "Android";
410
411 var arch = architecture.name.toUpperCase();
412 var normal = '$modeName$os$arch';
413 var cross = '$modeName${os}X$arch';
414 var outDir = system.outputDirectory;
415 var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
416 var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
417
418 if (normalDir.existsSync() && crossDir.existsSync()) {
419 throw "You can't have both $normalDir and $crossDir. We don't know which"
420 " binary to use.";
421 }
422
423 if (crossDir.existsSync()) return cross;
424
425 return normal;
426 }
427 }
428
429 class Architecture {
430 static const ia32 = const Architecture._('ia32');
431 static const x64 = const Architecture._('x64');
432 static const arm = const Architecture._('arm');
433 static const armv6 = const Architecture._('armv6');
434 static const armv5te = const Architecture._('armv5te');
435 static const arm64 = const Architecture._('arm64');
436 static const simarm = const Architecture._('simarm');
437 static const simarmv6 = const Architecture._('simarmv6');
438 static const simarmv5te = const Architecture._('simarmv5te');
439 static const simarm64 = const Architecture._('simarm64');
440 static const mips = const Architecture._('mips');
441 static const simmips = const Architecture._('simmips');
442 static const simdbc = const Architecture._('simdbc');
443 static const simdbc64 = const Architecture._('simdbc64');
444
445 static final List<String> names = _all.keys.toList();
446
447 static final _all = new Map<String, Architecture>.fromIterable([
448 ia32,
449 x64,
450 arm,
451 armv6,
452 armv5te,
453 arm64,
454 simarm,
455 simarmv6,
456 simarmv5te,
457 simarm64,
458 mips,
459 simmips,
460 simdbc,
461 simdbc64
462 ], key: (Architecture architecture) => architecture.name);
463
464 static Architecture find(String name) {
465 var architecture = _all[name];
466 if (architecture != null) return architecture;
467
468 throw new ArgumentError('Unknown architecture "$name".');
469 }
470
471 final String name;
472
473 const Architecture._(this.name);
474
475 String toString() => "Architecture($name)";
476 }
477
478 class Compiler {
479 static const none = const Compiler._('none');
480 static const precompiler = const Compiler._('precompiler');
481 static const dart2js = const Compiler._('dart2js');
482 static const dart2analyzer = const Compiler._('dart2analyzer');
483 static const appJit = const Compiler._('app_jit');
484 static const dartk = const Compiler._('dartk');
485 static const dartkp = const Compiler._('dartkp');
486
487 static final List<String> names = _all.keys.toList();
488
489 static final _all = new Map<String, Compiler>.fromIterable(
490 [none, precompiler, dart2js, dart2analyzer, appJit, dartk, dartkp],
491 key: (Compiler compiler) => compiler.name);
492
493 static Compiler find(String name) {
494 var compiler = _all[name];
495 if (compiler != null) return compiler;
496
497 throw new ArgumentError('Unknown compiler "$name".');
498 }
499
500 final String name;
501
502 const Compiler._(this.name);
503
504 /// Gets the runtimes this compiler can target.
505 List<Runtime> get supportedRuntimes {
506 switch (this) {
507 case Compiler.dart2js:
508 // Note: by adding 'none' as a configuration, if the user
509 // runs test.py -c dart2js -r drt,none the dart2js_none and
510 // dart2js_drt will be duplicating work. If later we don't need 'none'
511 // with dart2js, we should remove it from here.
512 return const [
513 Runtime.d8,
514 Runtime.jsshell,
515 Runtime.drt,
516 Runtime.none,
517 Runtime.dartium,
518 Runtime.firefox,
519 Runtime.chrome,
520 Runtime.safari,
521 Runtime.ie9,
522 Runtime.ie10,
523 Runtime.ie11,
524 Runtime.opera,
525 Runtime.chromeOnAndroid,
526 Runtime.safariMobileSim
527 ];
528
529 case Compiler.dart2analyzer:
530 return const [Runtime.none];
531 case Compiler.appJit:
532 case Compiler.dartk:
533 return const [Runtime.vm, Runtime.selfCheck, Runtime.none];
534 case Compiler.precompiler:
535 case Compiler.dartkp:
536 return const [Runtime.dartPrecompiled];
537 case Compiler.none:
538 return const [
539 Runtime.vm,
540 Runtime.flutter,
541 Runtime.drt,
542 Runtime.dartium,
543 Runtime.contentShellOnAndroid,
544 Runtime.dartiumOnAndroid
545 ];
546 }
547
548 throw "unreachable";
549 }
550
551 String toString() => "Compiler($name)";
552 }
553
554 class Mode {
555 static const debug = const Mode._('debug');
556 static const product = const Mode._('product');
557 static const release = const Mode._('release');
558
559 static final List<String> names = _all.keys.toList();
560
561 static final _all = new Map<String, Mode>.fromIterable(
562 [debug, product, release],
563 key: (Mode mode) => mode.name);
564
565 static Mode find(String name) {
566 var mode = _all[name];
567 if (mode != null) return mode;
568
569 throw new ArgumentError('Unknown mode "$name".');
570 }
571
572 final String name;
573
574 const Mode._(this.name);
575
576 bool get isDebug => this == debug;
577
578 String toString() => "Mode($name)";
579 }
580
581 class Progress {
582 static const compact = const Progress._('compact');
583 static const color = const Progress._('color');
584 static const line = const Progress._('line');
585 static const verbose = const Progress._('verbose');
586 static const silent = const Progress._('silent');
587 static const status = const Progress._('status');
588 static const buildbot = const Progress._('buildbot');
589 static const diff = const Progress._('diff');
590
591 static final List<String> names = _all.keys.toList();
592
593 static final _all = new Map<String, Progress>.fromIterable(
594 [compact, color, line, verbose, silent, status, buildbot, diff],
595 key: (Progress progress) => progress.name);
596
597 static Progress find(String name) {
598 var progress = _all[name];
599 if (progress != null) return progress;
600
601 throw new ArgumentError('Unknown progress type "$name".');
602 }
603
604 final String name;
605
606 const Progress._(this.name);
607
608 String toString() => "Progress($name)";
609 }
610
611 class Runtime {
612 static const vm = const Runtime._('vm');
613 static const flutter = const Runtime._('flutter');
614 static const dartPrecompiled = const Runtime._('dart_precompiled');
615 static const d8 = const Runtime._('d8');
616 static const jsshell = const Runtime._('jsshell');
617 static const drt = const Runtime._('drt');
618 static const dartium = const Runtime._('dartium');
619 static const firefox = const Runtime._('firefox');
620 static const chrome = const Runtime._('chrome');
621 static const safari = const Runtime._('safari');
622 static const ie9 = const Runtime._('ie9');
623 static const ie10 = const Runtime._('ie10');
624 static const ie11 = const Runtime._('ie11');
625 static const opera = const Runtime._('opera');
626 static const chromeOnAndroid = const Runtime._('chromeOnAndroid');
627 static const safariMobileSim = const Runtime._('safarimobilesim');
628 static const contentShellOnAndroid = const Runtime._('ContentShellOnAndroid');
629 static const dartiumOnAndroid = const Runtime._('DartiumOnAndroid');
630 static const selfCheck = const Runtime._('self_check');
631 static const none = const Runtime._('none');
632
633 static final List<String> names = _all.keys.toList()..add("ff");
634
635 static final _all = new Map<String, Runtime>.fromIterable([
636 vm,
637 flutter,
638 dartPrecompiled,
639 d8,
640 jsshell,
641 drt,
642 dartium,
643 firefox,
644 chrome,
645 safari,
646 ie9,
647 ie10,
648 ie11,
649 opera,
650 chromeOnAndroid,
651 safariMobileSim,
652 contentShellOnAndroid,
653 dartiumOnAndroid,
654 selfCheck,
655 none
656 ], key: (Runtime runtime) => runtime.name);
657
658 static Runtime find(String name) {
659 // Allow "ff" as a synonym for Firefox.
660 if (name == "ff") return firefox;
661
662 var runtime = _all[name];
663 if (runtime != null) return runtime;
664
665 throw new ArgumentError('Unknown runtime "$name".');
666 }
667
668 final String name;
669
670 const Runtime._(this.name);
671
672 bool get isBrowser => const [
673 drt,
674 dartium,
675 ie9,
676 ie10,
677 ie11,
678 safari,
679 opera,
680 chrome,
681 firefox,
682 chromeOnAndroid,
683 safariMobileSim,
684 contentShellOnAndroid,
685 dartiumOnAndroid,
686 ].contains(this);
687
688 bool get isIE => name.startsWith("ie");
689 bool get isSafari => name.startsWith("safari");
690
691 /// Whether this runtime is a command-line JavaScript environment.
692 bool get isJSCommandLine => const [d8, jsshell].contains(this);
693
694 /// If the runtime doesn't support `Window.open`, we use iframes instead.
695 bool get requiresIFrame => !const [ie11, ie10].contains(this);
696
697 String toString() => "Runtime($name)";
698 }
699
700 class System {
701 static const android = const System._('android');
702 static const fuchsia = const System._('fuchsia');
703 static const linux = const System._('linux');
704 static const macos = const System._('macos');
705 static const windows = const System._('windows');
706
707 static final List<String> names = _all.keys.toList();
708
709 static final _all = new Map<String, System>.fromIterable(
710 [android, fuchsia, linux, macos, windows],
711 key: (System system) => system.name);
712
713 static System find(String name) {
714 var system = _all[name];
715 if (system != null) return system;
716
717 throw new ArgumentError('Unknown operating system "$name".');
718 }
719
720 final String name;
721
722 const System._(this.name);
723
724 /// The root directory name for build outputs on this system.
725 String get outputDirectory {
726 switch (this) {
727 case android:
728 case fuchsia:
729 case linux:
730 case windows:
731 return 'out/';
732
733 case macos:
734 return 'xcodebuild/';
735 }
736
737 throw "unreachable";
738 }
739
740 String toString() => "System($name)";
741 }
OLDNEW
« no previous file with comments | « tools/testing/dart/compiler_configuration.dart ('k') | tools/testing/dart/drt_updater.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698