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

Side by Side Diff: tools/testing/dart/lib/test_utils.dart

Issue 841193003: cleanup to tools/testing/dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: one last bit Created 5 years, 11 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/lib/test_progress.dart ('k') | tools/testing/dart/lib/utils.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 library test_utils;
2
3 import 'dart:async';
4 import 'dart:io';
5
6 import 'path.dart';
7
8 class TestUtils {
9 /**
10 * Any script using TestUtils must set dartDirUri to a file:// URI
11 * pointing to the root of the Dart checkout.
12 */
13 static setDartDirUri(uri) {
14 dartDirUri = uri;
15 dartDir = new Path(uri.toFilePath());
16 }
17 static Uri dartDirUri;
18 static Path dartDir;
19 static LastModifiedCache lastModifiedCache = new LastModifiedCache();
20 static ExistsCache existsCache = new ExistsCache();
21 static Path currentWorkingDirectory =
22 new Path(Directory.current.path);
23
24 /**
25 * Creates a directory using a [relativePath] to an existing
26 * [base] directory if that [relativePath] does not already exist.
27 */
28 static Directory mkdirRecursive(Path base, Path relativePath) {
29 if (relativePath.isAbsolute) {
30 base = new Path('/');
31 }
32 Directory dir = new Directory(base.toNativePath());
33 assert(dir.existsSync());
34 var segments = relativePath.segments();
35 for (String segment in segments) {
36 base = base.append(segment);
37 if (base.toString() == "/$segment" &&
38 segment.length == 2 &&
39 segment.endsWith(':')) {
40 // Skip the directory creation for a path like "/E:".
41 continue;
42 }
43 dir = new Directory(base.toNativePath());
44 if (!dir.existsSync()) {
45 dir.createSync();
46 }
47 assert(dir.existsSync());
48 }
49 return dir;
50 }
51
52 /**
53 * Copy a [source] file to a new place.
54 * Assumes that the directory for [dest] already exists.
55 */
56 static Future copyFile(Path source, Path dest) {
57 return new File(source.toNativePath()).openRead()
58 .pipe(new File(dest.toNativePath()).openWrite());
59 }
60
61 static Future copyDirectory(String source, String dest) {
62 source = new Path(source).toNativePath();
63 dest = new Path(dest).toNativePath();
64
65 var executable = 'cp';
66 var args = ['-Rp', source, dest];
67 if (Platform.operatingSystem == 'windows') {
68 executable = 'xcopy';
69 args = [source, dest, '/e', '/i'];
70 }
71 return Process.run(executable, args).then((ProcessResult result) {
72 if (result.exitCode != 0) {
73 throw new Exception("Failed to execute '$executable "
74 "${args.join(' ')}'.");
75 }
76 });
77 }
78
79 static Future deleteDirectory(String path) {
80 // We are seeing issues with long path names on windows when
81 // deleting them. Use the system tools to delete our long paths.
82 // See issue 16264.
83 if (Platform.operatingSystem == 'windows') {
84 var native_path = new Path(path).toNativePath();
85 // Running this in a shell sucks, but rmdir is not part of the standard
86 // path.
87 return Process.run('rmdir', ['/s', '/q', native_path], runInShell: true)
88 .then((ProcessResult result) {
89 if (result.exitCode != 0) {
90 throw new Exception('Can\'t delete path $native_path. '
91 'This path might be too long');
92 }
93 });
94 } else {
95 var dir = new Directory(path);
96 return dir.delete(recursive: true);
97 }
98 }
99
100 static Path debugLogfile() {
101 return new Path(".debug.log");
102 }
103
104 static String flakyFileName() {
105 // If a flaky test did fail, infos about it (i.e. test name, stdin, stdout)
106 // will be written to this file. This is useful for the debugging of
107 // flaky tests.
108 // When running on a built bot, the file can be made visible in the
109 // waterfall UI.
110 return ".flaky.log";
111 }
112
113 static String testOutcomeFileName() {
114 // If test.py was invoked with '--write-test-outcome-log it will write
115 // test outcomes to this file.
116 return ".test-outcome.log";
117 }
118
119 static void ensureExists(String filename, Map configuration) {
120 if (!configuration['list'] && !existsCache.doesFileExist(filename)) {
121 throw "'$filename' does not exist";
122 }
123 }
124
125 static Path absolutePath(Path path) {
126 if (!path.isAbsolute) {
127 return currentWorkingDirectory.join(path);
128 }
129 return path;
130 }
131
132 static String outputDir(Map configuration) {
133 var result = '';
134 var system = configuration['system'];
135 if (system == 'linux') {
136 result = 'out/';
137 } else if (system == 'macos') {
138 result = 'xcodebuild/';
139 } else if (system == 'windows') {
140 result = 'build/';
141 }
142 return result;
143 }
144
145 static List<String> standardOptions(Map configuration) {
146 List args = ["--ignore-unrecognized-flags"];
147 if (configuration["checked"]) {
148 args.add('--enable_asserts');
149 args.add("--enable_type_checks");
150 }
151 String compiler = configuration["compiler"];
152 if (compiler == "dart2js" || compiler == "dart2dart") {
153 args = [];
154 if (configuration["checked"]) {
155 args.add('--enable-checked-mode');
156 }
157 // args.add("--verbose");
158 if (!isBrowserRuntime(configuration['runtime'])) {
159 args.add("--allow-mock-compilation");
160 args.add("--categories=all");
161 }
162 }
163 if ((compiler == "dart2js" || compiler == "dart2dart") &&
164 configuration["minified"]) {
165 args.add("--minify");
166 }
167 if (compiler == "dartanalyzer" || compiler == "dart2analyzer") {
168 args.add("--show-package-warnings");
169 args.add("--enable-async");
170 }
171 return args;
172 }
173
174 static bool isBrowserRuntime(String runtime) {
175 const BROWSERS = const [
176 'drt',
177 'dartium',
178 'ie9',
179 'ie10',
180 'ie11',
181 'safari',
182 'opera',
183 'chrome',
184 'ff',
185 'chromeOnAndroid',
186 'safarimobilesim',
187 'ContentShellOnAndroid',
188 'DartiumOnAndroid'
189 ];
190 return BROWSERS.contains(runtime);
191 }
192
193 static bool isJsCommandLineRuntime(String runtime) =>
194 const ['d8', 'jsshell'].contains(runtime);
195
196 static bool isCommandLineAnalyzer(String compiler) =>
197 compiler == 'dartanalyzer' || compiler == 'dart2analyzer';
198
199 static String buildDir(Map configuration) {
200 // FIXME(kustermann,ricow): Our code assumes that the returned 'buildDir'
201 // is relative to the current working directory.
202 // Thus, if we pass in an absolute path (e.g. '--build-directory=/tmp/out')
203 // we get into trouble.
204 if (configuration['build_directory'] != '') {
205 return configuration['build_directory'];
206 }
207
208 return "${outputDir(configuration)}${configurationDir(configuration)}";
209 }
210
211 static getValidOutputDir(Map configuration, String mode, String arch) {
212 // We allow our code to have been cross compiled, i.e., that there
213 // is an X in front of the arch. We don't allow both a cross compiled
214 // and a normal version to be present (except if you specifically pass
215 // in the build_directory).
216 var normal = '$mode$arch';
217 var cross = '${mode}X$arch';
218 var outDir = outputDir(configuration);
219 var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
220 var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
221 if (normalDir.existsSync() && crossDir.existsSync()) {
222 throw "You can't have both $normalDir and $crossDir, we don't know which"
223 " binary to use";
224 }
225 if (crossDir.existsSync()) {
226 return cross;
227 }
228 return normal;
229 }
230
231 static String configurationDir(Map configuration) {
232 // For regular dart checkouts, the configDir by default is mode+arch.
233 // For Dartium, the configDir by default is mode (as defined by the Chrome
234 // build setup). We can detect this because in the dartium checkout, the
235 // "output" directory is a sibling of the dart directory instead of a child.
236 var mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
237 var arch = configuration['arch'].toUpperCase();
238 if (currentWorkingDirectory != dartDir) {
239 return getValidOutputDir(configuration, mode, arch);
240 } else {
241 return mode;
242 }
243 }
244
245 /**
246 * Returns the path to the dart binary checked into the repo, used for
247 * bootstrapping test.dart.
248 */
249 static Path get dartTestExecutable {
250 var path = '$dartDir/tools/testing/bin/'
251 '${Platform.operatingSystem}/dart';
252 if (Platform.operatingSystem == 'windows') {
253 path = '$path.exe';
254 }
255 return new Path(path);
256 }
257
258 /**
259 * Gets extra options under [key] passed to the testing script.
260 */
261 static List<String> getExtraOptions(Map configuration, String key) {
262 if (configuration[key] == null) return <String>[];
263 return configuration[key]
264 .split(" ")
265 .map((s) => s.trim())
266 .where((s) => s.isNotEmpty)
267 .toList();
268 }
269
270 /**
271 * Gets extra vm options passed to the testing script.
272 */
273 static List<String> getExtraVmOptions(Map configuration) =>
274 getExtraOptions(configuration, 'vm_options');
275
276 static String getShortName(String path) {
277 final PATH_REPLACEMENTS = const {
278 "pkg_polymer_e2e_test_bad_import_test": "polymer_bi",
279 "pkg_polymer_e2e_test_canonicalization_test": "polymer_c16n",
280 "pkg_polymer_e2e_test_experimental_boot_test": "polymer_boot",
281 "pkg_polymer_e2e_test_good_import_test": "polymer_gi",
282 "tests_co19_src_Language_12_Expressions_14_Function_Invocation_":
283 "co19_fn_invoke_",
284 "tests_co19_src_LayoutTests_fast_css_getComputedStyle_getComputedStyle-":
285 "co19_css_getComputedStyle_",
286 "tests_co19_src_LayoutTests_fast_dom_Document_CaretRangeFromPoint_"
287 "caretRangeFromPoint-": "co19_caretrangefrompoint_",
288 "tests_co19_src_LayoutTests_fast_dom_Document_CaretRangeFromPoint_"
289 "hittest-relative-to-viewport_": "co19_caretrange_hittest_",
290 "tests_co19_src_LayoutTests_fast_dom_HTMLLinkElement_link-onerror-"
291 "stylesheet-with-": "co19_dom_link-",
292 "tests_co19_src_LayoutTests_fast_dom_": "co19_dom",
293 "tests_co19_src_LayoutTests_fast_canvas_webgl": "co19_canvas_webgl",
294 "tests_co19_src_LibTest_core_AbstractClassInstantiationError_"
295 "AbstractClassInstantiationError_": "co19_abstract_class_",
296 "tests_co19_src_LibTest_core_IntegerDivisionByZeroException_"
297 "IntegerDivisionByZeroException_": "co19_division_by_zero",
298 "tests_co19_src_WebPlatformTest_html_dom_documents_dom-tree-accessors_":
299 "co19_dom_accessors_",
300 "tests_co19_src_WebPlatformTest_html_semantics_embedded-content_"
301 "media-elements_": "co19_media_elements",
302 "tests_co19_src_WebPlatformTest_html_semantics_": "co19_semantics_",
303
304 "tests_co19_src_WebPlatformTest_html-templates_additions-to-"
305 "the-steps-to-clone-a-node_": "co19_htmltemplates_clone_",
306 "tests_co19_src_WebPlatformTest_html-templates_definitions_"
307 "template-contents-owner": "co19_htmltemplates_contents",
308 "tests_co19_src_WebPlatformTest_html-templates_parsing-html-"
309 "templates_additions-to-": "co19_htmltemplates_add_",
310 "tests_co19_src_WebPlatformTest_html-templates_parsing-html-"
311 "templates_appending-to-a-template_": "co19_htmltemplates_append_",
312 "tests_co19_src_WebPlatformTest_html-templates_parsing-html-"
313 "templates_clearing-the-stack-back-to-a-given-context_":
314 "co19_htmltemplates_clearstack_",
315 "tests_co19_src_WebPlatformTest_html-templates_parsing-html-"
316 "templates_creating-an-element-for-the-token_":
317 "co19_htmltemplates_create_",
318 "tests_co19_src_WebPlatformTest_html-templates_template-element"
319 "_template-": "co19_htmltemplates_element-",
320 "tests_co19_src_WebPlatformTest_html-templates_": "co19_htmltemplate_",
321
322 "tests_co19_src_WebPlatformTest_shadow-dom_shadow-trees_":
323 "co19_shadow-trees_",
324 "tests_co19_src_WebPlatformTest_shadow-dom_elements-and-dom-objects_":
325 "co19_shadowdom_",
326 "tests_co19_src_WebPlatformTest_shadow-dom_html-elements-in-"
327 "shadow-trees_": "co19_shadow_html_",
328 "tests_co19_src_WebPlatformTest_html_webappapis_system-state-and-"
329 "capabilities_the-navigator-object": "co19_webappapis_navigator_",
330 "tests_co19_src_WebPlatformTest_DOMEvents_approved_": "co19_dom_approved_"
331 };
332
333 // Some tests are already in [build_dir]/generated_tests.
334 String GEN_TESTS = 'generated_tests/';
335 if (path.contains(GEN_TESTS)) {
336 int index = path.indexOf(GEN_TESTS) + GEN_TESTS.length;
337 path = 'multitest/${path.substring(index)}';
338 }
339 path = path.replaceAll('/', '_');
340 final int WINDOWS_SHORTEN_PATH_LIMIT = 58;
341 if (Platform.operatingSystem == 'windows' &&
342 path.length > WINDOWS_SHORTEN_PATH_LIMIT) {
343 for (var key in PATH_REPLACEMENTS.keys) {
344 if (path.startsWith(key)) {
345 path = path.replaceFirst(key, PATH_REPLACEMENTS[key]);
346 break;
347 }
348 }
349 }
350 return path;
351 }
352 }
353
354
355 class LastModifiedCache {
356 final Map<String, DateTime> _cache = <String, DateTime>{};
357
358 /**
359 * Returns the last modified date of the given [uri].
360 *
361 * The return value will be cached for future queries. If [uri] is a local
362 * file, it's last modified [Date] will be returned. If the file does not
363 * exist, null will be returned instead.
364 * In case [uri] is not a local file, this method will always return
365 * the current date.
366 */
367 DateTime getLastModified(Uri uri) {
368 if (uri.scheme == "file") {
369 if (_cache.containsKey(uri.path)) {
370 return _cache[uri.path];
371 }
372 var file = new File(new Path(uri.path).toNativePath());
373 _cache[uri.path] = file.existsSync() ? file.lastModifiedSync() : null;
374 return _cache[uri.path];
375 }
376 return new DateTime.now();
377 }
378 }
379
380
381 class ExistsCache {
382 final Map<String, bool> _cache = <String, bool>{};
383
384 /**
385 * Returns true if the file in [path] exists, false otherwise.
386 *
387 * The information will be cached.
388 */
389 bool doesFileExist(String path) {
390 if (!_cache.containsKey(path)) {
391 _cache[path] = new File(path).existsSync();
392 }
393 return _cache[path];
394 }
395 }
OLDNEW
« no previous file with comments | « tools/testing/dart/lib/test_progress.dart ('k') | tools/testing/dart/lib/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698