OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 // Create and return an options parser for the test runner. | |
6 ArgParser getOptionParser() { | |
7 var parser = new ArgParser(); | |
8 | |
9 parser.addOption('help', abbr: '?', | |
10 help: 'Show usage information.'); | |
11 | |
12 parser.addOption('runtime', abbr: 'r', defaultsTo: 'vm', | |
13 help: 'Where the tests should be run.', | |
14 allowed: ['vm', 'drt-dart', 'drt-js', 'd8'], | |
15 allowedHelp: { | |
16 'vm': 'Run Dart code natively on the standalone dart vm.', | |
17 'drt-dart': 'Run Dart code natively in the headless version of\n' | |
18 'Chrome, DumpRenderTree.', | |
19 'drt-js': 'Run Dart compiled to JavaScript in the headless version\n' | |
20 'of Chrome, DumpRenderTree.', | |
21 'd8': 'Run Dart compiled to JavaScript from the command line using v8.' | |
22 }); | |
23 | |
24 parser.addFlag('checked', defaultsTo: false, | |
25 help: 'Run tests in checked mode.'); | |
26 | |
27 parser.addOption('timeout', abbr: 't', | |
28 help: 'Timeout in seconds', defaultsTo: '60'); | |
29 | |
30 parser.addOption('tasks', abbr: 'j', | |
31 defaultsTo: Platform.numberOfProcessors.toString(), | |
32 help: 'The number of parallel tasks to run.'); | |
33 | |
34 parser.addOption('out', abbr: 'o', defaultsTo: 'stdout', | |
35 help: 'File to send test results. This should be a ' | |
36 'file name or one of stdout, stderr, or none.'); | |
37 | |
38 parser.addOption('list-format', | |
39 defaultsTo: '${Meta.testfile}${Meta.testGroup}${Meta.testDescription}', | |
40 help: 'Format for test list result output.'); | |
41 | |
42 parser.addOption('pass-format', | |
43 defaultsTo: 'PASS ${Meta.testTime}' | |
44 '${Meta.testfile}${Meta.testGroup}' | |
45 '${Meta.testDescription}${Meta.testMessage}', | |
46 help: 'Format for passing test result output.'); | |
47 | |
48 parser.addOption('fail-format', | |
49 defaultsTo: 'FAIL ${Meta.testTime}' | |
50 '${Meta.testfile}${Meta.testGroup}' | |
51 '${Meta.testDescription}${Meta.testMessage}', | |
52 help: 'Format for failed test result output.'); | |
53 | |
54 parser.addOption('error-format', | |
55 defaultsTo: 'ERROR ${Meta.testTime}' | |
56 '${Meta.testfile}${Meta.testGroup}' | |
57 '${Meta.testDescription}${Meta.testMessage}', | |
58 help: 'Format for tests with errors result output.'); | |
59 | |
60 parser.addFlag('summary', defaultsTo: false, | |
61 help: 'Print a summary of tests passed/failed for each test file.'); | |
62 | |
63 parser.addOption('log', abbr: 'l', defaultsTo: 'none', | |
64 help: 'File to send test log/print output to. This should be a ' | |
65 'file name or one of stdout, stderr, or none.'); | |
66 | |
67 // TODO(gram) - add loglevel once we have switched unittest to use the log | |
68 // library. | |
69 | |
70 parser.addFlag('list-files', defaultsTo: false, | |
71 help: 'List test files only, do not run them.'); | |
72 | |
73 parser.addFlag('list-tests', defaultsTo: false, | |
74 help: 'List tests only, do not run them.'); | |
75 | |
76 parser.addFlag('list-groups', defaultsTo: false, | |
77 help: 'List test groups only, do not run tests.'); | |
78 | |
79 parser.addFlag('keep-generated-tests', defaultsTo: false, | |
80 help: 'Keep the generated files in the temporary directory.'); | |
81 | |
82 parser.addFlag('list-options', defaultsTo: false, | |
83 help: 'Print non-default option settings, usable as a test.config.'); | |
84 | |
85 parser.addFlag('list-all-options', defaultsTo: false, | |
86 help: 'Print all option settings, usable as a test.config.'); | |
87 | |
88 parser.addFlag('time', | |
89 help: 'Print timing information after running tests', | |
90 defaultsTo: false); | |
91 | |
92 parser.addFlag('stop-on-failure', defaultsTo: false, | |
93 help: 'Stop execution upon first failure.'); | |
94 | |
95 parser.addFlag('isolate', defaultsTo: false, | |
96 help: 'Runs each test in a separate isolate.'); | |
97 | |
98 parser.addOption('configfile', help: 'Path to an argument file to load.'); | |
99 | |
100 // The defaults here should be the name of the executable, with | |
101 // the assumption that it is available on the PATH. | |
102 parser.addOption('dart2js', help: 'Path to dart2js executable.', | |
103 defaultsTo: 'dart2js'); | |
104 parser.addOption('dart', help: 'Path to dart executable.', | |
105 defaultsTo: 'dart'); | |
106 parser.addOption('drt', help: 'Path to DumpRenderTree executable.', | |
107 defaultsTo: 'drt'); | |
108 parser.addOption('d8', help: 'Path to d8 executable.', | |
109 defaultsTo: 'd8'); | |
110 | |
111 parser.addOption('tempdir', help: 'Directory to store temp files.', | |
112 defaultsTo: '${Platform.pathSeparator}tmp' | |
113 '${Platform.pathSeparator}testrunner'); | |
114 | |
115 parser.addOption('test-file-pat', | |
116 help: 'A regular expression that test file names must match ' | |
117 'to be considered', defaultsTo: '_test.dart\$'); | |
118 | |
119 parser.addOption('include', | |
120 help: 'Only run tests from the specified group(s).', | |
121 allowMultiple: true); | |
122 | |
123 parser.addOption('exclude', | |
124 help: 'Exclude tests from the specified group(s).', | |
125 allowMultiple: true); | |
126 | |
127 parser.addFlag('recurse', abbr: 'R', | |
128 help: 'Recurse through child directories looking for tests.', | |
129 defaultsTo: false); | |
130 | |
131 parser.addFlag('immediate', | |
132 help: 'Print test results immediately, instead of at the end of a test ' | |
133 'file. Note that in some async cases this may result in multiple ' | |
134 'messages for a single test.', | |
135 defaultsTo: false); | |
136 | |
137 parser.addOption('unittest', help: '#import path for unit test library.'); | |
138 | |
139 return parser; | |
140 } | |
141 | |
142 // Print a value option, quoting it if it has embedded spaces. | |
143 _printValueOption(String name, value, OutputStream stream) { | |
144 if (value.indexOf(' ') >= 0) { | |
145 stream.writeString("--$name='$value'\n"); | |
146 } else { | |
147 stream.writeString("--$name=$value\n"); | |
148 } | |
149 } | |
150 | |
151 // Print the current option values. | |
152 printOptions(ArgParser parser, ArgResults arguments, | |
153 bool includeDefaults, OutputStream stream) { | |
154 if (stream == null) return; | |
155 for (var name in arguments.options) { | |
156 if (!name.startsWith('list-')) { | |
157 var value = arguments[name]; | |
158 var defaultValue = parser.getDefault(name); | |
159 if (value is bool) { | |
160 if (includeDefaults || (value != defaultValue)) { | |
161 stream.writeString('--${value ? "" : "no-"}$name\n'); | |
162 } | |
163 } else if (value is List) { | |
164 if (value.length > 0) { | |
165 for (var v in value) { | |
166 _printValueOption(name, v, stream); | |
167 } | |
168 } | |
169 } else if (value != null && (includeDefaults || value != defaultValue)) { | |
170 _printValueOption(name, value, stream); | |
171 } | |
172 } | |
173 } | |
174 } | |
175 | |
176 // Get the test runner configuration. This loads options from multiple | |
177 // sources, in increasing order of priority: a test.config file in the | |
178 // current directory, a test config file specified with --configfile on | |
179 // the command line, and other arguments specified on the command line. | |
180 ArgResults loadConfiguration(optionsParser) { | |
181 var options = new List(); | |
182 // We first load options from a test.config file in the working directory. | |
183 options.addAll(getFileContents('test.config', false). | |
184 filter((e) => e.trim().length > 0 && e[0] != '#')); | |
185 // Next we look to see if the command line included a -testconfig argument, | |
186 // and if so, load options from that file too; where these are not | |
187 // multi-valued they will take precedence over the ones in test.config. | |
188 var commandLineArgs = new Options().arguments; | |
189 var cfgarg = '--configfile'; | |
190 for (var i = 0; i < commandLineArgs.length; i++) { | |
191 if (commandLineArgs[i].startsWith(cfgarg)) { | |
192 if (commandLineArgs[i] == cfgarg) { | |
193 if (i == commandLineArgs.length - 1) { | |
194 throw new Exception('Missing argument to $cfgarg'); | |
195 } | |
196 options.addAll(getFileContents(commandLineArgs[++i], true). | |
197 filter((e) => e.trim().length > 0 && e[0] != '#')); | |
198 } else if (commandLineArgs[i].startsWith('$cfgarg=')) { | |
199 options.addAll( | |
200 getFileContents(commandLineArgs[i].substring(cfgarg.length), true). | |
201 filter((e) => e.trim().length > 0 && e[0] != '#')); | |
202 } else { | |
203 throw new Exception('Missing argument to $cfgarg'); | |
204 } | |
205 } | |
206 } | |
207 // Finally, we add options from the command line. These have the highest | |
208 // precedence of all. | |
209 options.addAll(commandLineArgs); | |
210 // Now try parse the whole collection of options, and if this fails, | |
211 // issue a usage message. | |
212 try { | |
213 return optionsParser.parse(options); | |
Siggi Cherem (dart-lang)
2012/08/29 01:05:55
it might be worth converting the resulting ArgResu
gram
2012/08/29 20:12:26
Done.
| |
214 } catch (var e) { | |
215 print(e); | |
216 print('Usage: testrunner <options> [<directory or file> ...]'); | |
217 print(optionsParser.getUsage()); | |
218 return null; | |
219 } | |
220 } | |
221 | |
222 // Perform some sanity checking of the configuration. | |
223 bool sane(ArgResults config) { | |
224 if (config == null) { | |
225 return false; | |
226 } | |
227 if (config['runtime'] == null) { | |
228 print('Missing required option --runtime'); | |
229 return false; | |
230 } | |
231 if (config['unittest'] == null) { | |
232 print('Missing required option --unittest'); | |
233 return false; | |
234 } | |
235 if (config['include'].length > 0 && | |
236 config['exclude'].length > 0) { | |
237 print('--include and --exclude are mutually exclusive.'); | |
238 return false; | |
239 } | |
240 return true; | |
241 } | |
242 | |
243 | |
OLD | NEW |