OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 # Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | |
3 # | |
4 # Use of this source code is governed by a BSD-style license | |
5 # that can be found in the LICENSE file in the root of the source | |
6 # tree. An additional intellectual property rights grant can be found | |
7 # in the file PATENTS. All contributing project authors may | |
8 # be found in the AUTHORS file in the root of the source tree. | |
9 | |
10 """Tests for mb.py.""" | |
11 | |
12 import ast | |
13 import json | |
14 import StringIO | |
15 import os | |
16 import sys | |
17 import unittest | |
18 | |
19 import mb | |
20 | |
21 | |
22 class FakeMBW(mb.MetaBuildWrapper): | |
23 def __init__(self, win32=False): | |
24 super(FakeMBW, self).__init__() | |
25 | |
26 # Override vars for test portability. | |
27 if win32: | |
28 self.chromium_src_dir = 'c:\\fake_src' | |
29 self.default_config = 'c:\\fake_src\\tools\\mb\\mb_config.pyl' | |
30 self.default_isolate_map = ('c:\\fake_src\\testing\\buildbot\\' | |
31 'gn_isolate_map.pyl') | |
32 self.platform = 'win32' | |
33 self.executable = 'c:\\python\\python.exe' | |
34 self.sep = '\\' | |
35 else: | |
36 self.chromium_src_dir = '/fake_src' | |
37 self.default_config = '/fake_src/tools/mb/mb_config.pyl' | |
38 self.default_isolate_map = '/fake_src/testing/buildbot/gn_isolate_map.pyl' | |
39 self.executable = '/usr/bin/python' | |
40 self.platform = 'linux2' | |
41 self.sep = '/' | |
42 | |
43 self.files = {} | |
44 self.calls = [] | |
45 self.cmds = [] | |
46 self.cross_compile = None | |
47 self.out = '' | |
48 self.err = '' | |
49 self.rmdirs = [] | |
50 | |
51 def ExpandUser(self, path): | |
52 return '$HOME/%s' % path | |
53 | |
54 def Exists(self, path): | |
55 return self.files.get(path) is not None | |
56 | |
57 def MaybeMakeDirectory(self, path): | |
58 self.files[path] = True | |
59 | |
60 def PathJoin(self, *comps): | |
61 return self.sep.join(comps) | |
62 | |
63 def ReadFile(self, path): | |
64 return self.files[path] | |
65 | |
66 def WriteFile(self, path, contents, force_verbose=False): | |
67 if self.args.dryrun or self.args.verbose or force_verbose: | |
68 self.Print('\nWriting """\\\n%s""" to %s.\n' % (contents, path)) | |
69 self.files[path] = contents | |
70 | |
71 def Call(self, cmd, env=None, buffer_output=True): | |
72 if env: | |
73 self.cross_compile = env.get('GYP_CROSSCOMPILE') | |
74 self.calls.append(cmd) | |
75 if self.cmds: | |
76 return self.cmds.pop(0) | |
77 return 0, '', '' | |
78 | |
79 def Print(self, *args, **kwargs): | |
80 sep = kwargs.get('sep', ' ') | |
81 end = kwargs.get('end', '\n') | |
82 f = kwargs.get('file', sys.stdout) | |
83 if f == sys.stderr: | |
84 self.err += sep.join(args) + end | |
85 else: | |
86 self.out += sep.join(args) + end | |
87 | |
88 def TempFile(self, mode='w'): | |
89 return FakeFile(self.files) | |
90 | |
91 def RemoveFile(self, path): | |
92 del self.files[path] | |
93 | |
94 def RemoveDirectory(self, path): | |
95 self.rmdirs.append(path) | |
96 files_to_delete = [f for f in self.files if f.startswith(path)] | |
97 for f in files_to_delete: | |
98 self.files[f] = None | |
99 | |
100 | |
101 class FakeFile(object): | |
102 def __init__(self, files): | |
103 self.name = '/tmp/file' | |
104 self.buf = '' | |
105 self.files = files | |
106 | |
107 def write(self, contents): | |
108 self.buf += contents | |
109 | |
110 def close(self): | |
111 self.files[self.name] = self.buf | |
112 | |
113 | |
114 TEST_CONFIG = """\ | |
115 { | |
116 'masters': { | |
117 'chromium': {}, | |
118 'fake_master': { | |
119 'fake_builder': 'gyp_rel_bot', | |
120 'fake_gn_builder': 'gn_rel_bot', | |
121 'fake_gyp_crosscompile_builder': 'gyp_crosscompile', | |
122 'fake_gn_debug_builder': 'gn_debug_goma', | |
123 'fake_gyp_builder': 'gyp_debug', | |
124 'fake_gn_args_bot': '//build/args/bots/fake_master/fake_gn_args_bot.gn', | |
125 'fake_memcheck_bot': 'gn_memcheck_bot', | |
126 'fake_multi_phase': { 'phase_1': 'gn_phase_1', 'phase_2': 'gn_phase_2'}, | |
127 'fake_android_bot': 'gn_android_bot', | |
128 }, | |
129 }, | |
130 'configs': { | |
131 'gyp_rel_bot': ['gyp', 'rel', 'goma'], | |
132 'gn_debug_goma': ['gn', 'debug', 'goma'], | |
133 'gyp_debug': ['gyp', 'debug', 'fake_feature1'], | |
134 'gn_rel_bot': ['gn', 'rel', 'goma'], | |
135 'gyp_crosscompile': ['gyp', 'crosscompile'], | |
136 'gn_phase_1': ['gn', 'phase_1'], | |
137 'gn_phase_2': ['gn', 'phase_2'], | |
138 'gn_memcheck_bot': ['gn', 'memcheck'], | |
139 'gn_android_bot': ['gn', 'android'], | |
140 }, | |
141 'mixins': { | |
142 'crosscompile': { | |
143 'gyp_crosscompile': True, | |
144 }, | |
145 'fake_feature1': { | |
146 'gn_args': 'enable_doom_melon=true', | |
147 'gyp_defines': 'doom_melon=1', | |
148 }, | |
149 'gyp': {'type': 'gyp'}, | |
150 'gn': {'type': 'gn'}, | |
151 'goma': { | |
152 'gn_args': 'use_goma=true', | |
153 'gyp_defines': 'goma=1', | |
154 }, | |
155 'phase_1': { | |
156 'gn_args': 'phase=1', | |
157 'gyp_args': 'phase=1', | |
158 }, | |
159 'phase_2': { | |
160 'gn_args': 'phase=2', | |
161 'gyp_args': 'phase=2', | |
162 }, | |
163 'rel': { | |
164 'gn_args': 'is_debug=false', | |
165 }, | |
166 'debug': { | |
167 'gn_args': 'is_debug=true', | |
168 }, | |
169 'memcheck': { | |
170 'gn_args': 'rtc_use_memcheck=true', | |
171 }, | |
172 'android': { | |
173 'gn_args': 'target_os="android"', | |
174 } | |
175 }, | |
176 } | |
177 """ | |
178 | |
179 | |
180 TEST_BAD_CONFIG = """\ | |
181 { | |
182 'configs': { | |
183 'gn_rel_bot_1': ['gn', 'rel', 'chrome_with_codecs'], | |
184 'gn_rel_bot_2': ['gn', 'rel', 'bad_nested_config'], | |
185 }, | |
186 'masters': { | |
187 'chromium': { | |
188 'a': 'gn_rel_bot_1', | |
189 'b': 'gn_rel_bot_2', | |
190 }, | |
191 }, | |
192 'mixins': { | |
193 'gn': {'type': 'gn'}, | |
194 'chrome_with_codecs': { | |
195 'gn_args': 'proprietary_codecs=true', | |
196 }, | |
197 'bad_nested_config': { | |
198 'mixins': ['chrome_with_codecs'], | |
199 }, | |
200 'rel': { | |
201 'gn_args': 'is_debug=false', | |
202 }, | |
203 }, | |
204 } | |
205 """ | |
206 | |
207 | |
208 GYP_HACKS_CONFIG = """\ | |
209 { | |
210 'masters': { | |
211 'chromium': {}, | |
212 'fake_master': { | |
213 'fake_builder': 'fake_config', | |
214 }, | |
215 }, | |
216 'configs': { | |
217 'fake_config': ['fake_mixin'], | |
218 }, | |
219 'mixins': { | |
220 'fake_mixin': { | |
221 'type': 'gyp', | |
222 'gn_args': '', | |
223 'gyp_defines': | |
224 ('foo=bar llvm_force_head_revision=1 ' | |
225 'gyp_link_concurrency=1 baz=1'), | |
226 }, | |
227 }, | |
228 } | |
229 """ | |
230 | |
231 | |
232 class UnitTest(unittest.TestCase): | |
233 def fake_mbw(self, files=None, win32=False): | |
234 mbw = FakeMBW(win32=win32) | |
235 mbw.files.setdefault(mbw.default_config, TEST_CONFIG) | |
236 mbw.files.setdefault( | |
237 mbw.ToAbsPath('//testing/buildbot/gn_isolate_map.pyl'), | |
238 '''{ | |
239 "foo_unittests": { | |
240 "label": "//foo:foo_unittests", | |
241 "type": "console_test_launcher", | |
242 "args": [], | |
243 }, | |
244 }''') | |
245 mbw.files.setdefault( | |
246 mbw.ToAbsPath('//build/args/bots/fake_master/fake_gn_args_bot.gn'), | |
247 'is_debug = false\n') | |
248 if files: | |
249 for path, contents in files.items(): | |
250 mbw.files[path] = contents | |
251 return mbw | |
252 | |
253 def check(self, args, mbw=None, files=None, out=None, err=None, ret=None): | |
254 if not mbw: | |
255 mbw = self.fake_mbw(files) | |
256 | |
257 actual_ret = mbw.Main(args) | |
258 | |
259 self.assertEqual(actual_ret, ret) | |
260 if out is not None: | |
261 self.assertEqual(mbw.out, out) | |
262 if err is not None: | |
263 self.assertEqual(mbw.err, err) | |
264 return mbw | |
265 | |
266 def test_clobber(self): | |
267 files = { | |
268 '/fake_src/out/Debug': None, | |
269 '/fake_src/out/Debug/mb_type': None, | |
270 } | |
271 mbw = self.fake_mbw(files) | |
272 | |
273 # The first time we run this, the build dir doesn't exist, so no clobber. | |
274 self.check(['gen', '-c', 'gn_debug_goma', '//out/Debug'], mbw=mbw, ret=0) | |
275 self.assertEqual(mbw.rmdirs, []) | |
276 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn') | |
277 | |
278 # The second time we run this, the build dir exists and matches, so no | |
279 # clobber. | |
280 self.check(['gen', '-c', 'gn_debug_goma', '//out/Debug'], mbw=mbw, ret=0) | |
281 self.assertEqual(mbw.rmdirs, []) | |
282 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn') | |
283 | |
284 # Now we switch build types; this should result in a clobber. | |
285 self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0) | |
286 self.assertEqual(mbw.rmdirs, ['/fake_src/out/Debug']) | |
287 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp') | |
288 | |
289 # Now we delete mb_type; this checks the case where the build dir | |
290 # exists but wasn't populated by mb; this should also result in a clobber. | |
291 del mbw.files['/fake_src/out/Debug/mb_type'] | |
292 self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0) | |
293 self.assertEqual(mbw.rmdirs, | |
294 ['/fake_src/out/Debug', '/fake_src/out/Debug']) | |
295 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp') | |
296 | |
297 def test_gn_analyze(self): | |
298 files = {'/tmp/in.json': '''{\ | |
299 "files": ["foo/foo_unittest.cc"], | |
300 "test_targets": ["foo_unittests"], | |
301 "additional_compile_targets": ["all"] | |
302 }''', | |
303 '/tmp/out.json.gn': '''{\ | |
304 "status": "Found dependency", | |
305 "compile_targets": ["//foo:foo_unittests"], | |
306 "test_targets": ["//foo:foo_unittests"] | |
307 }'''} | |
308 | |
309 mbw = self.fake_mbw(files) | |
310 mbw.Call = lambda cmd, env=None, buffer_output=True: (0, '', '') | |
311 | |
312 self.check(['analyze', '-c', 'gn_debug_goma', '//out/Default', | |
313 '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0) | |
314 out = json.loads(mbw.files['/tmp/out.json']) | |
315 self.assertEqual(out, { | |
316 'status': 'Found dependency', | |
317 'compile_targets': ['foo:foo_unittests'], | |
318 'test_targets': ['foo_unittests'] | |
319 }) | |
320 | |
321 def test_gn_gen(self): | |
322 mbw = self.fake_mbw() | |
323 self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', '-g', '/goma'], | |
324 mbw=mbw, ret=0) | |
325 self.assertMultiLineEqual(mbw.files['/fake_src/out/Default/args.gn'], | |
326 ('goma_dir = "/goma"\n' | |
327 'is_debug = true\n' | |
328 'use_goma = true\n')) | |
329 | |
330 # Make sure we log both what is written to args.gn and the command line. | |
331 self.assertIn('Writing """', mbw.out) | |
332 self.assertIn('/fake_src/buildtools/linux64/gn gen //out/Default --check', | |
333 mbw.out) | |
334 | |
335 mbw = self.fake_mbw(win32=True) | |
336 self.check(['gen', '-c', 'gn_debug_goma', '-g', 'c:\\goma', '//out/Debug'], | |
337 mbw=mbw, ret=0) | |
338 self.assertMultiLineEqual(mbw.files['c:\\fake_src\\out\\Debug\\args.gn'], | |
339 ('goma_dir = "c:\\\\goma"\n' | |
340 'is_debug = true\n' | |
341 'use_goma = true\n')) | |
342 self.assertIn('c:\\fake_src\\buildtools\\win\\gn.exe gen //out/Debug ' | |
343 '--check\n', mbw.out) | |
344 | |
345 mbw = self.fake_mbw() | |
346 self.check(['gen', '-m', 'fake_master', '-b', 'fake_gn_args_bot', | |
347 '//out/Debug'], | |
348 mbw=mbw, ret=0) | |
349 self.assertEqual( | |
350 mbw.files['/fake_src/out/Debug/args.gn'], | |
351 'import("//build/args/bots/fake_master/fake_gn_args_bot.gn")\n') | |
352 | |
353 | |
354 def test_gn_gen_fails(self): | |
355 mbw = self.fake_mbw() | |
356 mbw.Call = lambda cmd, env=None, buffer_output=True: (1, '', '') | |
357 self.check(['gen', '-c', 'gn_debug_goma', '//out/Default'], mbw=mbw, ret=1) | |
358 | |
359 def test_gn_gen_swarming(self): | |
360 files = { | |
361 '/tmp/swarming_targets': 'cc_perftests\n', | |
362 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
363 "{'cc_perftests': {" | |
364 " 'label': '//cc:cc_perftests'," | |
365 " 'type': 'console_test_launcher'," | |
366 "}}\n" | |
367 ), | |
368 'c:\\fake_src\out\Default\cc_perftests.exe.runtime_deps': ( | |
369 "cc_perftests\n" | |
370 ), | |
371 } | |
372 mbw = self.fake_mbw(files=files, win32=True) | |
373 self.check(['gen', | |
374 '-c', 'gn_debug_goma', | |
375 '--swarming-targets-file', '/tmp/swarming_targets', | |
376 '--isolate-map-file', | |
377 '/fake_src/testing/buildbot/gn_isolate_map.pyl', | |
378 '//out/Default'], mbw=mbw, ret=0) | |
379 self.assertIn('c:\\fake_src\\out\\Default\\cc_perftests.isolate', | |
380 mbw.files) | |
381 self.assertIn('c:\\fake_src\\out\\Default\\cc_perftests.isolated.gen.json', | |
382 mbw.files) | |
383 | |
384 def test_gn_gen_swarming_android(self): | |
385 test_files = { | |
386 '/tmp/swarming_targets': 'base_unittests\n', | |
387 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
388 "{'base_unittests': {" | |
389 " 'label': '//base:base_unittests'," | |
390 " 'type': 'additional_compile_target'," | |
391 "}}\n" | |
392 ), | |
393 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
394 "base_unittests\n" | |
395 ), | |
396 } | |
397 mbw = self.check(['gen', '-c', 'gn_android_bot', '//out/Default', | |
398 '--swarming-targets-file', '/tmp/swarming_targets', | |
399 '--isolate-map-file', | |
400 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
401 files=test_files, ret=0) | |
402 | |
403 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
404 isolate_file_contents = ast.literal_eval(isolate_file) | |
405 files = isolate_file_contents['variables']['files'] | |
406 command = isolate_file_contents['variables']['command'] | |
407 | |
408 self.assertEqual(files, ['base_unittests']) | |
409 self.assertEqual(command, [ | |
410 './../../build/android/test_wrapper/logdog_wrapper.py', | |
411 '--logdog-bin-cmd', './../../bin/logdog_butler', | |
412 '--project', 'chromium', | |
413 '--service-account-json', | |
414 '/creds/service_accounts/service-account-luci-logdog-publisher.json', | |
415 '--prefix', 'android/swarming/logcats/${SWARMING_TASK_ID}', | |
416 '--source', '${ISOLATED_OUTDIR}/logcats', | |
417 '--name', 'unified_logcats', | |
418 'bin/run_base_unittests', | |
419 '--logcat-output-file', '${ISOLATED_OUTDIR}/logcats', | |
420 '--target-devices-file', '${SWARMING_BOT_FILE}', | |
421 '-v', | |
422 ]) | |
423 | |
424 def test_gn_gen_swarming_android_junit_test(self): | |
425 test_files = { | |
426 '/tmp/swarming_targets': 'base_unittests\n', | |
427 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
428 "{'base_unittests': {" | |
429 " 'label': '//base:base_unittests'," | |
430 " 'type': 'junit_test'," | |
431 "}}\n" | |
432 ), | |
433 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
434 "base_unittests\n" | |
435 ), | |
436 } | |
437 mbw = self.check(['gen', '-c', 'gn_android_bot', '//out/Default', | |
438 '--swarming-targets-file', '/tmp/swarming_targets', | |
439 '--isolate-map-file', | |
440 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
441 files=test_files, ret=0) | |
442 | |
443 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
444 isolate_file_contents = ast.literal_eval(isolate_file) | |
445 files = isolate_file_contents['variables']['files'] | |
446 command = isolate_file_contents['variables']['command'] | |
447 | |
448 self.assertEqual(files, ['base_unittests']) | |
449 self.assertEqual(command, [ | |
450 './../../build/android/test_wrapper/logdog_wrapper.py', | |
451 '--logdog-bin-cmd', './../../bin/logdog_butler', | |
452 '--project', 'chromium', | |
453 '--service-account-json', | |
454 '/creds/service_accounts/service-account-luci-logdog-publisher.json', | |
455 '--prefix', 'android/swarming/logcats/${SWARMING_TASK_ID}', | |
456 '--source', '${ISOLATED_OUTDIR}/logcats', | |
457 '--name', 'unified_logcats', | |
458 'bin/run_base_unittests', | |
459 '--logcat-output-file', '${ISOLATED_OUTDIR}/logcats', | |
460 '-v', | |
461 ]) | |
462 | |
463 def test_gn_gen_non_parallel_console_test_launcher(self): | |
464 test_files = { | |
465 '/tmp/swarming_targets': 'base_unittests\n', | |
466 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
467 "{'base_unittests': {" | |
468 " 'label': '//base:base_unittests'," | |
469 " 'type': 'non_parallel_console_test_launcher'," | |
470 "}}\n" | |
471 ), | |
472 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
473 "base_unittests\n" | |
474 ), | |
475 } | |
476 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', | |
477 '--swarming-targets-file', '/tmp/swarming_targets', | |
478 '--isolate-map-file', | |
479 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
480 files=test_files, ret=0) | |
481 | |
482 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
483 isolate_file_contents = ast.literal_eval(isolate_file) | |
484 files = isolate_file_contents['variables']['files'] | |
485 command = isolate_file_contents['variables']['command'] | |
486 | |
487 self.assertEqual(files, [ | |
488 '../../testing/test_env.py', | |
489 'base_unittests', | |
490 ]) | |
491 self.assertEqual(command, [ | |
492 '../../testing/test_env.py', | |
493 './base_unittests', | |
494 '--', | |
495 '--asan=0', | |
496 '--msan=0', | |
497 '--tsan=0', | |
498 ]) | |
499 | |
500 def test_gn_isolate_windowed_test_launcher_linux(self): | |
501 test_files = { | |
502 '/tmp/swarming_targets': 'base_unittests\n', | |
503 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
504 "{'base_unittests': {" | |
505 " 'label': '//base:base_unittests'," | |
506 " 'type': 'windowed_test_launcher'," | |
507 "}}\n" | |
508 ), | |
509 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
510 "base_unittests\n" | |
511 "some_resource_file\n" | |
512 ), | |
513 } | |
514 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', | |
515 '--swarming-targets-file', '/tmp/swarming_targets', | |
516 '--isolate-map-file', | |
517 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
518 files=test_files, ret=0) | |
519 | |
520 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
521 isolate_file_contents = ast.literal_eval(isolate_file) | |
522 files = isolate_file_contents['variables']['files'] | |
523 command = isolate_file_contents['variables']['command'] | |
524 | |
525 self.assertEqual(files, [ | |
526 '../../testing/test_env.py', | |
527 '../../testing/xvfb.py', | |
528 '../../third_party/gtest-parallel/gtest-parallel', | |
529 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py', | |
530 'base_unittests', | |
531 'some_resource_file', | |
532 ]) | |
533 self.assertEqual(command, [ | |
534 '../../testing/xvfb.py', | |
535 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py', | |
536 './base_unittests', | |
537 '--', | |
538 '--asan=0', | |
539 '--msan=0', | |
540 '--tsan=0', | |
541 ]) | |
542 | |
543 def test_gn_gen_windowed_test_launcher_win(self): | |
544 files = { | |
545 '/tmp/swarming_targets': 'unittests\n', | |
546 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
547 "{'unittests': {" | |
548 " 'label': '//somewhere:unittests'," | |
549 " 'type': 'windowed_test_launcher'," | |
550 "}}\n" | |
551 ), | |
552 r'c:\fake_src\out\Default\unittests.exe.runtime_deps': ( | |
553 "unittests.exe\n" | |
554 "some_dependency\n" | |
555 ), | |
556 } | |
557 mbw = self.fake_mbw(files=files, win32=True) | |
558 self.check(['gen', | |
559 '-c', 'gn_debug_goma', | |
560 '--swarming-targets-file', '/tmp/swarming_targets', | |
561 '--isolate-map-file', | |
562 '/fake_src/testing/buildbot/gn_isolate_map.pyl', | |
563 '//out/Default'], mbw=mbw, ret=0) | |
564 | |
565 isolate_file = mbw.files['c:\\fake_src\\out\\Default\\unittests.isolate'] | |
566 isolate_file_contents = ast.literal_eval(isolate_file) | |
567 files = isolate_file_contents['variables']['files'] | |
568 command = isolate_file_contents['variables']['command'] | |
569 | |
570 self.assertEqual(files, [ | |
571 '../../testing/test_env.py', | |
572 '../../third_party/gtest-parallel/gtest-parallel', | |
573 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py', | |
574 'some_dependency', | |
575 'unittests.exe', | |
576 ]) | |
577 self.assertEqual(command, [ | |
578 '../../testing/test_env.py', | |
579 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py', | |
580 r'.\unittests.exe', | |
581 '--', | |
582 '--asan=0', | |
583 '--msan=0', | |
584 '--tsan=0', | |
585 ]) | |
586 | |
587 def test_gn_gen_console_test_launcher(self): | |
588 test_files = { | |
589 '/tmp/swarming_targets': 'base_unittests\n', | |
590 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
591 "{'base_unittests': {" | |
592 " 'label': '//base:base_unittests'," | |
593 " 'type': 'console_test_launcher'," | |
594 "}}\n" | |
595 ), | |
596 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
597 "base_unittests\n" | |
598 ), | |
599 } | |
600 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', | |
601 '--swarming-targets-file', '/tmp/swarming_targets', | |
602 '--isolate-map-file', | |
603 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
604 files=test_files, ret=0) | |
605 | |
606 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
607 isolate_file_contents = ast.literal_eval(isolate_file) | |
608 files = isolate_file_contents['variables']['files'] | |
609 command = isolate_file_contents['variables']['command'] | |
610 | |
611 self.assertEqual(files, [ | |
612 '../../testing/test_env.py', | |
613 '../../third_party/gtest-parallel/gtest-parallel', | |
614 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py', | |
615 'base_unittests', | |
616 ]) | |
617 self.assertEqual(command, [ | |
618 '../../testing/test_env.py', | |
619 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py', | |
620 './base_unittests', | |
621 '--', | |
622 '--asan=0', | |
623 '--msan=0', | |
624 '--tsan=0', | |
625 ]) | |
626 | |
627 def test_gn_isolate_console_test_launcher_memcheck(self): | |
628 test_files = { | |
629 '/tmp/swarming_targets': 'base_unittests\n', | |
630 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
631 "{'base_unittests': {" | |
632 " 'label': '//base:base_unittests'," | |
633 " 'type': 'console_test_launcher'," | |
634 "}}\n" | |
635 ), | |
636 '/fake_src/out/Release/base_unittests.runtime_deps': ( | |
637 "base_unittests\n" | |
638 "lots_of_memcheck_dependencies\n" | |
639 "../../tools/valgrind-webrtc/webrtc_tests.sh\n" | |
640 ), | |
641 } | |
642 mbw = self.check(['gen', '-c', 'gn_memcheck_bot', '//out/Release', | |
643 '--swarming-targets-file', '/tmp/swarming_targets', | |
644 '--isolate-map-file', | |
645 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
646 files=test_files, ret=0) | |
647 | |
648 isolate_file = mbw.files['/fake_src/out/Release/base_unittests.isolate'] | |
649 isolate_file_contents = ast.literal_eval(isolate_file) | |
650 files = isolate_file_contents['variables']['files'] | |
651 command = isolate_file_contents['variables']['command'] | |
652 | |
653 self.assertEqual(files, [ | |
654 '../../testing/test_env.py', | |
655 '../../tools/valgrind-webrtc/webrtc_tests.sh', | |
656 'base_unittests', | |
657 'lots_of_memcheck_dependencies', | |
658 ]) | |
659 self.assertEqual(command, [ | |
660 '../../testing/test_env.py', | |
661 'bash', | |
662 '../../tools/valgrind-webrtc/webrtc_tests.sh', | |
663 '--tool', | |
664 'memcheck', | |
665 '--target', | |
666 'Release', | |
667 '--build-dir', | |
668 '..', | |
669 '--test', | |
670 './base_unittests', | |
671 '--', | |
672 '--asan=0', | |
673 '--msan=0', | |
674 '--tsan=0', | |
675 ]) | |
676 | |
677 def test_gn_isolate(self): | |
678 files = { | |
679 '/fake_src/out/Default/toolchain.ninja': "", | |
680 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
681 "{'base_unittests': {" | |
682 " 'label': '//base:base_unittests'," | |
683 " 'type': 'non_parallel_console_test_launcher'," | |
684 "}}\n" | |
685 ), | |
686 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
687 "base_unittests\n" | |
688 ), | |
689 } | |
690 self.check(['isolate', '-c', 'gn_debug_goma', '//out/Default', | |
691 'base_unittests'], files=files, ret=0) | |
692 | |
693 # test running isolate on an existing build_dir | |
694 files['/fake_src/out/Default/args.gn'] = 'is_debug = True\n' | |
695 self.check(['isolate', '//out/Default', 'base_unittests'], | |
696 files=files, ret=0) | |
697 files['/fake_src/out/Default/mb_type'] = 'gn\n' | |
698 self.check(['isolate', '//out/Default', 'base_unittests'], | |
699 files=files, ret=0) | |
700 | |
701 def test_gn_run(self): | |
702 files = { | |
703 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
704 "{'base_unittests': {" | |
705 " 'label': '//base:base_unittests'," | |
706 " 'type': 'windowed_test_launcher'," | |
707 "}}\n" | |
708 ), | |
709 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
710 "base_unittests\n" | |
711 ), | |
712 } | |
713 self.check(['run', '-c', 'gn_debug_goma', '//out/Default', | |
714 'base_unittests'], files=files, ret=0) | |
715 | |
716 def test_gn_lookup(self): | |
717 self.check(['lookup', '-c', 'gn_debug_goma'], ret=0) | |
718 | |
719 def test_gn_lookup_goma_dir_expansion(self): | |
720 self.check(['lookup', '-c', 'gn_rel_bot', '-g', '/foo'], ret=0, | |
721 out=('\n' | |
722 'Writing """\\\n' | |
723 'goma_dir = "/foo"\n' | |
724 'is_debug = false\n' | |
725 'use_goma = true\n' | |
726 '""" to _path_/args.gn.\n\n' | |
727 '/fake_src/buildtools/linux64/gn gen _path_\n')) | |
728 | |
729 def test_gyp_analyze(self): | |
730 mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release', | |
731 '/tmp/in.json', '/tmp/out.json'], ret=0) | |
732 self.assertIn('analyzer', mbw.calls[0]) | |
733 | |
734 def test_gyp_crosscompile(self): | |
735 mbw = self.fake_mbw() | |
736 self.check(['gen', '-c', 'gyp_crosscompile', '//out/Release'], | |
737 mbw=mbw, ret=0) | |
738 self.assertTrue(mbw.cross_compile) | |
739 | |
740 def test_gyp_gen(self): | |
741 self.check(['gen', '-c', 'gyp_rel_bot', '-g', '/goma', '//out/Release'], | |
742 ret=0, | |
743 out=("GYP_DEFINES='goma=1 gomadir=/goma'\n" | |
744 "python build/gyp_chromium -G output_dir=out\n")) | |
745 | |
746 mbw = self.fake_mbw(win32=True) | |
747 self.check(['gen', '-c', 'gyp_rel_bot', '-g', 'c:\\goma', '//out/Release'], | |
748 mbw=mbw, ret=0, | |
749 out=("set GYP_DEFINES=goma=1 gomadir='c:\\goma'\n" | |
750 "python build\\gyp_chromium -G output_dir=out\n")) | |
751 | |
752 def test_gyp_gen_fails(self): | |
753 mbw = self.fake_mbw() | |
754 mbw.Call = lambda cmd, env=None, buffer_output=True: (1, '', '') | |
755 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], mbw=mbw, ret=1) | |
756 | |
757 def test_gyp_lookup_goma_dir_expansion(self): | |
758 self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0, | |
759 out=("GYP_DEFINES='goma=1 gomadir=/foo'\n" | |
760 "python build/gyp_chromium -G output_dir=_path_\n")) | |
761 | |
762 def test_help(self): | |
763 orig_stdout = sys.stdout | |
764 try: | |
765 sys.stdout = StringIO.StringIO() | |
766 self.assertRaises(SystemExit, self.check, ['-h']) | |
767 self.assertRaises(SystemExit, self.check, ['help']) | |
768 self.assertRaises(SystemExit, self.check, ['help', 'gen']) | |
769 finally: | |
770 sys.stdout = orig_stdout | |
771 | |
772 def test_multiple_phases(self): | |
773 # Check that not passing a --phase to a multi-phase builder fails. | |
774 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase'], | |
775 ret=1) | |
776 self.assertIn('Must specify a build --phase', mbw.out) | |
777 | |
778 # Check that passing a --phase to a single-phase builder fails. | |
779 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_gn_builder', | |
780 '--phase', 'phase_1'], ret=1) | |
781 self.assertIn('Must not specify a build --phase', mbw.out) | |
782 | |
783 # Check that passing a wrong phase key to a multi-phase builder fails. | |
784 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase', | |
785 '--phase', 'wrong_phase'], ret=1) | |
786 self.assertIn('Phase wrong_phase doesn\'t exist', mbw.out) | |
787 | |
788 # Check that passing a correct phase key to a multi-phase builder passes. | |
789 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase', | |
790 '--phase', 'phase_1'], ret=0) | |
791 self.assertIn('phase = 1', mbw.out) | |
792 | |
793 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase', | |
794 '--phase', 'phase_2'], ret=0) | |
795 self.assertIn('phase = 2', mbw.out) | |
796 | |
797 def test_validate(self): | |
798 mbw = self.fake_mbw() | |
799 self.check(['validate'], mbw=mbw, ret=0) | |
800 | |
801 def test_bad_validate(self): | |
802 mbw = self.fake_mbw() | |
803 mbw.files[mbw.default_config] = TEST_BAD_CONFIG | |
804 self.check(['validate'], mbw=mbw, ret=1) | |
805 | |
806 def test_gyp_env_hacks(self): | |
807 mbw = self.fake_mbw() | |
808 mbw.files[mbw.default_config] = GYP_HACKS_CONFIG | |
809 self.check(['lookup', '-c', 'fake_config'], mbw=mbw, | |
810 ret=0, | |
811 out=("GYP_DEFINES='foo=bar baz=1'\n" | |
812 "GYP_LINK_CONCURRENCY=1\n" | |
813 "LLVM_FORCE_HEAD_REVISION=1\n" | |
814 "python build/gyp_chromium -G output_dir=_path_\n")) | |
815 | |
816 | |
817 if __name__ == '__main__': | |
818 unittest.main() | |
819 | |
820 def test_validate(self): | |
821 mbw = self.fake_mbw() | |
822 self.check(['validate'], mbw=mbw, ret=0) | |
823 | |
824 def test_bad_validate(self): | |
825 mbw = self.fake_mbw() | |
826 mbw.files[mbw.default_config] = TEST_BAD_CONFIG | |
827 self.check(['validate'], mbw=mbw, ret=1) | |
828 | |
829 def test_gyp_env_hacks(self): | |
830 mbw = self.fake_mbw() | |
831 mbw.files[mbw.default_config] = GYP_HACKS_CONFIG | |
832 self.check(['lookup', '-c', 'fake_config'], mbw=mbw, | |
833 ret=0, | |
834 out=("GYP_DEFINES='foo=bar baz=1'\n" | |
835 "GYP_LINK_CONCURRENCY=1\n" | |
836 "LLVM_FORCE_HEAD_REVISION=1\n" | |
837 "python build/gyp_chromium -G output_dir=_path_\n")) | |
838 | |
839 | |
840 if __name__ == '__main__': | |
841 unittest.main() | |
OLD | NEW |