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.src_dir = 'c:\\fake_src' | |
29 self.default_config = 'c:\\fake_src\\tools-webrtc\\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.src_dir = '/fake_src' | |
37 self.default_config = '/fake_src/tools-webrtc/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 GYP_HACKS_CONFIG = """\ | |
180 { | |
181 'masters': { | |
182 'chromium': {}, | |
183 'fake_master': { | |
184 'fake_builder': 'fake_config', | |
185 }, | |
186 }, | |
187 'configs': { | |
188 'fake_config': ['fake_mixin'], | |
189 }, | |
190 'mixins': { | |
191 'fake_mixin': { | |
192 'type': 'gyp', | |
193 'gn_args': '', | |
194 'gyp_defines': | |
195 ('foo=bar llvm_force_head_revision=1 ' | |
196 'gyp_link_concurrency=1 baz=1'), | |
197 }, | |
198 }, | |
199 } | |
200 """ | |
201 | |
202 | |
203 class UnitTest(unittest.TestCase): | |
204 def fake_mbw(self, files=None, win32=False): | |
205 mbw = FakeMBW(win32=win32) | |
206 mbw.files.setdefault(mbw.default_config, TEST_CONFIG) | |
207 mbw.files.setdefault( | |
208 mbw.ToAbsPath('//testing/buildbot/gn_isolate_map.pyl'), | |
209 '''{ | |
210 "foo_unittests": { | |
211 "label": "//foo:foo_unittests", | |
212 "type": "console_test_launcher", | |
213 "args": [], | |
214 }, | |
215 }''') | |
216 mbw.files.setdefault( | |
217 mbw.ToAbsPath('//build/args/bots/fake_master/fake_gn_args_bot.gn'), | |
218 'is_debug = false\n') | |
219 if files: | |
220 for path, contents in files.items(): | |
221 mbw.files[path] = contents | |
222 return mbw | |
223 | |
224 def check(self, args, mbw=None, files=None, out=None, err=None, ret=None): | |
225 if not mbw: | |
226 mbw = self.fake_mbw(files) | |
227 | |
228 actual_ret = mbw.Main(args) | |
229 | |
230 self.assertEqual(actual_ret, ret) | |
231 if out is not None: | |
232 self.assertEqual(mbw.out, out) | |
233 if err is not None: | |
234 self.assertEqual(mbw.err, err) | |
235 return mbw | |
236 | |
237 def test_clobber(self): | |
238 files = { | |
239 '/fake_src/out/Debug': None, | |
240 '/fake_src/out/Debug/mb_type': None, | |
241 } | |
242 mbw = self.fake_mbw(files) | |
243 | |
244 # The first time we run this, the build dir doesn't exist, so no clobber. | |
245 self.check(['gen', '-c', 'gn_debug_goma', '//out/Debug'], mbw=mbw, ret=0) | |
246 self.assertEqual(mbw.rmdirs, []) | |
247 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn') | |
248 | |
249 # The second time we run this, the build dir exists and matches, so no | |
250 # clobber. | |
251 self.check(['gen', '-c', 'gn_debug_goma', '//out/Debug'], mbw=mbw, ret=0) | |
252 self.assertEqual(mbw.rmdirs, []) | |
253 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn') | |
254 | |
255 # Now we switch build types; this should result in a clobber. | |
256 self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0) | |
257 self.assertEqual(mbw.rmdirs, ['/fake_src/out/Debug']) | |
258 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp') | |
259 | |
260 # Now we delete mb_type; this checks the case where the build dir | |
261 # exists but wasn't populated by mb; this should also result in a clobber. | |
262 del mbw.files['/fake_src/out/Debug/mb_type'] | |
263 self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0) | |
264 self.assertEqual(mbw.rmdirs, | |
265 ['/fake_src/out/Debug', '/fake_src/out/Debug']) | |
266 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp') | |
267 | |
268 def test_gn_analyze(self): | |
269 files = {'/tmp/in.json': '''{\ | |
270 "files": ["foo/foo_unittest.cc"], | |
271 "test_targets": ["foo_unittests"], | |
272 "additional_compile_targets": ["all"] | |
273 }''', | |
274 '/tmp/out.json.gn': '''{\ | |
275 "status": "Found dependency", | |
276 "compile_targets": ["//foo:foo_unittests"], | |
277 "test_targets": ["//foo:foo_unittests"] | |
278 }'''} | |
279 | |
280 mbw = self.fake_mbw(files) | |
281 mbw.Call = lambda cmd, env=None, buffer_output=True: (0, '', '') | |
282 | |
283 self.check(['analyze', '-c', 'gn_debug_goma', '//out/Default', | |
284 '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0) | |
285 out = json.loads(mbw.files['/tmp/out.json']) | |
286 self.assertEqual(out, { | |
287 'status': 'Found dependency', | |
288 'compile_targets': ['foo:foo_unittests'], | |
289 'test_targets': ['foo_unittests'] | |
290 }) | |
291 | |
292 def test_gn_gen(self): | |
293 mbw = self.fake_mbw() | |
294 self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', '-g', '/goma'], | |
295 mbw=mbw, ret=0) | |
296 self.assertMultiLineEqual(mbw.files['/fake_src/out/Default/args.gn'], | |
297 ('goma_dir = "/goma"\n' | |
298 'is_debug = true\n' | |
299 'use_goma = true\n')) | |
300 | |
301 # Make sure we log both what is written to args.gn and the command line. | |
302 self.assertIn('Writing """', mbw.out) | |
303 self.assertIn('/fake_src/buildtools/linux64/gn gen //out/Default --check', | |
304 mbw.out) | |
305 | |
306 mbw = self.fake_mbw(win32=True) | |
307 self.check(['gen', '-c', 'gn_debug_goma', '-g', 'c:\\goma', '//out/Debug'], | |
308 mbw=mbw, ret=0) | |
309 self.assertMultiLineEqual(mbw.files['c:\\fake_src\\out\\Debug\\args.gn'], | |
310 ('goma_dir = "c:\\\\goma"\n' | |
311 'is_debug = true\n' | |
312 'use_goma = true\n')) | |
313 self.assertIn('c:\\fake_src\\buildtools\\win\\gn.exe gen //out/Debug ' | |
314 '--check\n', mbw.out) | |
315 | |
316 mbw = self.fake_mbw() | |
317 self.check(['gen', '-m', 'fake_master', '-b', 'fake_gn_args_bot', | |
318 '//out/Debug'], | |
319 mbw=mbw, ret=0) | |
320 self.assertEqual( | |
321 mbw.files['/fake_src/out/Debug/args.gn'], | |
322 'import("//build/args/bots/fake_master/fake_gn_args_bot.gn")\n') | |
323 | |
324 | |
325 def test_gn_gen_fails(self): | |
326 mbw = self.fake_mbw() | |
327 mbw.Call = lambda cmd, env=None, buffer_output=True: (1, '', '') | |
328 self.check(['gen', '-c', 'gn_debug_goma', '//out/Default'], mbw=mbw, ret=1) | |
329 | |
330 def test_gn_gen_swarming(self): | |
331 files = { | |
332 '/tmp/swarming_targets': 'cc_perftests\n', | |
333 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
334 "{'cc_perftests': {" | |
335 " 'label': '//cc:cc_perftests'," | |
336 " 'type': 'console_test_launcher'," | |
337 "}}\n" | |
338 ), | |
339 'c:\\fake_src\out\Default\cc_perftests.exe.runtime_deps': ( | |
340 "cc_perftests\n" | |
341 ), | |
342 } | |
343 mbw = self.fake_mbw(files=files, win32=True) | |
344 self.check(['gen', | |
345 '-c', 'gn_debug_goma', | |
346 '--swarming-targets-file', '/tmp/swarming_targets', | |
347 '--isolate-map-file', | |
348 '/fake_src/testing/buildbot/gn_isolate_map.pyl', | |
349 '//out/Default'], mbw=mbw, ret=0) | |
350 self.assertIn('c:\\fake_src\\out\\Default\\cc_perftests.isolate', | |
351 mbw.files) | |
352 self.assertIn('c:\\fake_src\\out\\Default\\cc_perftests.isolated.gen.json', | |
353 mbw.files) | |
354 | |
355 def test_gn_gen_swarming_android(self): | |
356 test_files = { | |
357 '/tmp/swarming_targets': 'base_unittests\n', | |
358 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
359 "{'base_unittests': {" | |
360 " 'label': '//base:base_unittests'," | |
361 " 'type': 'additional_compile_target'," | |
362 "}}\n" | |
363 ), | |
364 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
365 "base_unittests\n" | |
366 ), | |
367 } | |
368 mbw = self.check(['gen', '-c', 'gn_android_bot', '//out/Default', | |
369 '--swarming-targets-file', '/tmp/swarming_targets', | |
370 '--isolate-map-file', | |
371 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
372 files=test_files, ret=0) | |
373 | |
374 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
375 isolate_file_contents = ast.literal_eval(isolate_file) | |
376 files = isolate_file_contents['variables']['files'] | |
377 command = isolate_file_contents['variables']['command'] | |
378 | |
379 self.assertEqual(files, ['base_unittests']) | |
380 self.assertEqual(command, [ | |
381 '../../build/android/test_wrapper/logdog_wrapper.py', | |
382 '--target', 'base_unittests', | |
383 '--logdog-bin-cmd', '../../bin/logdog_butler', | |
384 '--target-devices-file', '${SWARMING_BOT_FILE}' | |
385 ]) | |
386 | |
387 def test_gn_gen_swarming_android_junit_test(self): | |
388 test_files = { | |
389 '/tmp/swarming_targets': 'base_unittests\n', | |
390 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
391 "{'base_unittests': {" | |
392 " 'label': '//base:base_unittests'," | |
393 " 'type': 'junit_test'," | |
394 "}}\n" | |
395 ), | |
396 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
397 "base_unittests\n" | |
398 ), | |
399 } | |
400 mbw = self.check(['gen', '-c', 'gn_android_bot', '//out/Default', | |
401 '--swarming-targets-file', '/tmp/swarming_targets', | |
402 '--isolate-map-file', | |
403 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
404 files=test_files, ret=0) | |
405 | |
406 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
407 isolate_file_contents = ast.literal_eval(isolate_file) | |
408 files = isolate_file_contents['variables']['files'] | |
409 command = isolate_file_contents['variables']['command'] | |
410 | |
411 self.assertEqual(files, ['base_unittests']) | |
412 self.assertEqual(command, [ | |
413 '../../build/android/test_wrapper/logdog_wrapper.py', | |
414 '--target', 'base_unittests', | |
415 '--logdog-bin-cmd', '../../bin/logdog_butler', | |
416 ]) | |
417 | |
418 def test_gn_gen_non_parallel_console_test_launcher(self): | |
419 test_files = { | |
420 '/tmp/swarming_targets': 'base_unittests\n', | |
421 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
422 "{'base_unittests': {" | |
423 " 'label': '//base:base_unittests'," | |
424 " 'type': 'non_parallel_console_test_launcher'," | |
425 "}}\n" | |
426 ), | |
427 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
428 "base_unittests\n" | |
429 ), | |
430 } | |
431 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', | |
432 '--swarming-targets-file', '/tmp/swarming_targets', | |
433 '--isolate-map-file', | |
434 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
435 files=test_files, ret=0) | |
436 | |
437 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
438 isolate_file_contents = ast.literal_eval(isolate_file) | |
439 files = isolate_file_contents['variables']['files'] | |
440 command = isolate_file_contents['variables']['command'] | |
441 | |
442 self.assertEqual(files, [ | |
443 '../../testing/test_env.py', | |
444 '../../third_party/gtest-parallel/gtest-parallel', | |
445 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
446 'base_unittests', | |
447 ]) | |
448 self.assertEqual(command, [ | |
449 '../../testing/test_env.py', | |
450 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
451 '--output_dir=${ISOLATED_OUTDIR}/test_logs', | |
452 '--gtest_color=no', | |
453 '--timeout=900', | |
454 '--retry_failed=3', | |
455 './base_unittests', | |
456 '--workers=1', | |
457 '--', | |
458 '--asan=0', | |
459 '--lsan=0', | |
460 '--msan=0', | |
461 '--tsan=0', | |
462 ]) | |
463 | |
464 def test_gn_isolate_windowed_test_launcher_linux(self): | |
465 test_files = { | |
466 '/tmp/swarming_targets': 'base_unittests\n', | |
467 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
468 "{'base_unittests': {" | |
469 " 'label': '//base:base_unittests'," | |
470 " 'type': 'windowed_test_launcher'," | |
471 "}}\n" | |
472 ), | |
473 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
474 "base_unittests\n" | |
475 "some_resource_file\n" | |
476 ), | |
477 } | |
478 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', | |
479 '--swarming-targets-file', '/tmp/swarming_targets', | |
480 '--isolate-map-file', | |
481 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
482 files=test_files, ret=0) | |
483 | |
484 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
485 isolate_file_contents = ast.literal_eval(isolate_file) | |
486 files = isolate_file_contents['variables']['files'] | |
487 command = isolate_file_contents['variables']['command'] | |
488 | |
489 self.assertEqual(files, [ | |
490 '../../testing/test_env.py', | |
491 '../../testing/xvfb.py', | |
492 '../../third_party/gtest-parallel/gtest-parallel', | |
493 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
494 'base_unittests', | |
495 'some_resource_file', | |
496 ]) | |
497 self.assertEqual(command, [ | |
498 '../../testing/xvfb.py', | |
499 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
500 '--output_dir=${ISOLATED_OUTDIR}/test_logs', | |
501 '--gtest_color=no', | |
502 '--timeout=900', | |
503 '--retry_failed=3', | |
504 './base_unittests', | |
505 '--', | |
506 '--asan=0', | |
507 '--lsan=0', | |
508 '--msan=0', | |
509 '--tsan=0', | |
510 ]) | |
511 | |
512 def test_gn_gen_windowed_test_launcher_win(self): | |
513 files = { | |
514 '/tmp/swarming_targets': 'unittests\n', | |
515 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
516 "{'unittests': {" | |
517 " 'label': '//somewhere:unittests'," | |
518 " 'type': 'windowed_test_launcher'," | |
519 "}}\n" | |
520 ), | |
521 r'c:\fake_src\out\Default\unittests.exe.runtime_deps': ( | |
522 "unittests.exe\n" | |
523 "some_dependency\n" | |
524 ), | |
525 } | |
526 mbw = self.fake_mbw(files=files, win32=True) | |
527 self.check(['gen', | |
528 '-c', 'gn_debug_goma', | |
529 '--swarming-targets-file', '/tmp/swarming_targets', | |
530 '--isolate-map-file', | |
531 '/fake_src/testing/buildbot/gn_isolate_map.pyl', | |
532 '//out/Default'], mbw=mbw, ret=0) | |
533 | |
534 isolate_file = mbw.files['c:\\fake_src\\out\\Default\\unittests.isolate'] | |
535 isolate_file_contents = ast.literal_eval(isolate_file) | |
536 files = isolate_file_contents['variables']['files'] | |
537 command = isolate_file_contents['variables']['command'] | |
538 | |
539 self.assertEqual(files, [ | |
540 '../../testing/test_env.py', | |
541 '../../third_party/gtest-parallel/gtest-parallel', | |
542 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
543 'some_dependency', | |
544 'unittests.exe', | |
545 ]) | |
546 self.assertEqual(command, [ | |
547 '../../testing/test_env.py', | |
548 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
549 '--output_dir=${ISOLATED_OUTDIR}\\test_logs', | |
550 '--gtest_color=no', | |
551 '--timeout=900', | |
552 '--retry_failed=3', | |
553 r'.\unittests.exe', | |
554 '--', | |
555 '--asan=0', | |
556 '--lsan=0', | |
557 '--msan=0', | |
558 '--tsan=0', | |
559 ]) | |
560 | |
561 def test_gn_gen_console_test_launcher(self): | |
562 test_files = { | |
563 '/tmp/swarming_targets': 'base_unittests\n', | |
564 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
565 "{'base_unittests': {" | |
566 " 'label': '//base:base_unittests'," | |
567 " 'type': 'console_test_launcher'," | |
568 "}}\n" | |
569 ), | |
570 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
571 "base_unittests\n" | |
572 ), | |
573 } | |
574 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default', | |
575 '--swarming-targets-file', '/tmp/swarming_targets', | |
576 '--isolate-map-file', | |
577 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
578 files=test_files, ret=0) | |
579 | |
580 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate'] | |
581 isolate_file_contents = ast.literal_eval(isolate_file) | |
582 files = isolate_file_contents['variables']['files'] | |
583 command = isolate_file_contents['variables']['command'] | |
584 | |
585 self.assertEqual(files, [ | |
586 '../../testing/test_env.py', | |
587 '../../third_party/gtest-parallel/gtest-parallel', | |
588 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
589 'base_unittests', | |
590 ]) | |
591 self.assertEqual(command, [ | |
592 '../../testing/test_env.py', | |
593 '../../tools-webrtc/gtest-parallel-wrapper.py', | |
594 '--output_dir=${ISOLATED_OUTDIR}/test_logs', | |
595 '--gtest_color=no', | |
596 '--timeout=900', | |
597 '--retry_failed=3', | |
598 './base_unittests', | |
599 '--', | |
600 '--asan=0', | |
601 '--lsan=0', | |
602 '--msan=0', | |
603 '--tsan=0', | |
604 ]) | |
605 | |
606 def test_gn_isolate_console_test_launcher_memcheck(self): | |
607 test_files = { | |
608 '/tmp/swarming_targets': 'base_unittests\n', | |
609 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
610 "{'base_unittests': {" | |
611 " 'label': '//base:base_unittests'," | |
612 " 'type': 'console_test_launcher'," | |
613 "}}\n" | |
614 ), | |
615 '/fake_src/out/Release/base_unittests.runtime_deps': ( | |
616 "base_unittests\n" | |
617 "lots_of_memcheck_dependencies\n" | |
618 "../../tools-webrtc/valgrind/webrtc_tests.sh\n" | |
619 ), | |
620 } | |
621 mbw = self.check(['gen', '-c', 'gn_memcheck_bot', '//out/Release', | |
622 '--swarming-targets-file', '/tmp/swarming_targets', | |
623 '--isolate-map-file', | |
624 '/fake_src/testing/buildbot/gn_isolate_map.pyl'], | |
625 files=test_files, ret=0) | |
626 | |
627 isolate_file = mbw.files['/fake_src/out/Release/base_unittests.isolate'] | |
628 isolate_file_contents = ast.literal_eval(isolate_file) | |
629 files = isolate_file_contents['variables']['files'] | |
630 command = isolate_file_contents['variables']['command'] | |
631 | |
632 self.assertEqual(files, [ | |
633 '../../testing/test_env.py', | |
634 '../../tools-webrtc/valgrind/webrtc_tests.sh', | |
635 'base_unittests', | |
636 'lots_of_memcheck_dependencies', | |
637 ]) | |
638 self.assertEqual(command, [ | |
639 '../../testing/test_env.py', | |
640 'bash', | |
641 '../../tools-webrtc/valgrind/webrtc_tests.sh', | |
642 '--tool', | |
643 'memcheck', | |
644 '--target', | |
645 'Release', | |
646 '--build-dir', | |
647 '..', | |
648 '--test', | |
649 './base_unittests', | |
650 '--', | |
651 '--asan=0', | |
652 '--lsan=0', | |
653 '--msan=0', | |
654 '--tsan=0', | |
655 ]) | |
656 | |
657 def test_gn_isolate(self): | |
658 files = { | |
659 '/fake_src/out/Default/toolchain.ninja': "", | |
660 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
661 "{'base_unittests': {" | |
662 " 'label': '//base:base_unittests'," | |
663 " 'type': 'non_parallel_console_test_launcher'," | |
664 "}}\n" | |
665 ), | |
666 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
667 "base_unittests\n" | |
668 ), | |
669 } | |
670 self.check(['isolate', '-c', 'gn_debug_goma', '//out/Default', | |
671 'base_unittests'], files=files, ret=0) | |
672 | |
673 # test running isolate on an existing build_dir | |
674 files['/fake_src/out/Default/args.gn'] = 'is_debug = True\n' | |
675 self.check(['isolate', '//out/Default', 'base_unittests'], | |
676 files=files, ret=0) | |
677 files['/fake_src/out/Default/mb_type'] = 'gn\n' | |
678 self.check(['isolate', '//out/Default', 'base_unittests'], | |
679 files=files, ret=0) | |
680 | |
681 def test_gn_run(self): | |
682 files = { | |
683 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | |
684 "{'base_unittests': {" | |
685 " 'label': '//base:base_unittests'," | |
686 " 'type': 'windowed_test_launcher'," | |
687 "}}\n" | |
688 ), | |
689 '/fake_src/out/Default/base_unittests.runtime_deps': ( | |
690 "base_unittests\n" | |
691 ), | |
692 } | |
693 self.check(['run', '-c', 'gn_debug_goma', '//out/Default', | |
694 'base_unittests'], files=files, ret=0) | |
695 | |
696 def test_gn_lookup(self): | |
697 self.check(['lookup', '-c', 'gn_debug_goma'], ret=0) | |
698 | |
699 def test_gn_lookup_goma_dir_expansion(self): | |
700 self.check(['lookup', '-c', 'gn_rel_bot', '-g', '/foo'], ret=0, | |
701 out=('\n' | |
702 'Writing """\\\n' | |
703 'goma_dir = "/foo"\n' | |
704 'is_debug = false\n' | |
705 'use_goma = true\n' | |
706 '""" to _path_/args.gn.\n\n' | |
707 '/fake_src/buildtools/linux64/gn gen _path_\n')) | |
708 | |
709 def test_gyp_analyze(self): | |
710 mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release', | |
711 '/tmp/in.json', '/tmp/out.json'], ret=0) | |
712 self.assertIn('analyzer', mbw.calls[0]) | |
713 | |
714 def test_gyp_crosscompile(self): | |
715 mbw = self.fake_mbw() | |
716 self.check(['gen', '-c', 'gyp_crosscompile', '//out/Release'], | |
717 mbw=mbw, ret=0) | |
718 self.assertTrue(mbw.cross_compile) | |
719 | |
720 def test_gyp_gen(self): | |
721 self.check(['gen', '-c', 'gyp_rel_bot', '-g', '/goma', '//out/Release'], | |
722 ret=0, | |
723 out=("GYP_DEFINES='goma=1 gomadir=/goma'\n" | |
724 "python build/gyp_chromium -G output_dir=out\n")) | |
725 | |
726 mbw = self.fake_mbw(win32=True) | |
727 self.check(['gen', '-c', 'gyp_rel_bot', '-g', 'c:\\goma', '//out/Release'], | |
728 mbw=mbw, ret=0, | |
729 out=("set GYP_DEFINES=goma=1 gomadir='c:\\goma'\n" | |
730 "python build\\gyp_chromium -G output_dir=out\n")) | |
731 | |
732 def test_gyp_gen_fails(self): | |
733 mbw = self.fake_mbw() | |
734 mbw.Call = lambda cmd, env=None, buffer_output=True: (1, '', '') | |
735 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], mbw=mbw, ret=1) | |
736 | |
737 def test_gyp_lookup_goma_dir_expansion(self): | |
738 self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0, | |
739 out=("GYP_DEFINES='goma=1 gomadir=/foo'\n" | |
740 "python build/gyp_chromium -G output_dir=_path_\n")) | |
741 | |
742 def test_help(self): | |
743 orig_stdout = sys.stdout | |
744 try: | |
745 sys.stdout = StringIO.StringIO() | |
746 self.assertRaises(SystemExit, self.check, ['-h']) | |
747 self.assertRaises(SystemExit, self.check, ['help']) | |
748 self.assertRaises(SystemExit, self.check, ['help', 'gen']) | |
749 finally: | |
750 sys.stdout = orig_stdout | |
751 | |
752 def test_multiple_phases(self): | |
753 # Check that not passing a --phase to a multi-phase builder fails. | |
754 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase'], | |
755 ret=1) | |
756 self.assertIn('Must specify a build --phase', mbw.out) | |
757 | |
758 # Check that passing a --phase to a single-phase builder fails. | |
759 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_gn_builder', | |
760 '--phase', 'phase_1'], ret=1) | |
761 self.assertIn('Must not specify a build --phase', mbw.out) | |
762 | |
763 # Check that passing a wrong phase key to a multi-phase builder fails. | |
764 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase', | |
765 '--phase', 'wrong_phase'], ret=1) | |
766 self.assertIn('Phase wrong_phase doesn\'t exist', mbw.out) | |
767 | |
768 # Check that passing a correct phase key to a multi-phase builder passes. | |
769 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase', | |
770 '--phase', 'phase_1'], ret=0) | |
771 self.assertIn('phase = 1', mbw.out) | |
772 | |
773 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase', | |
774 '--phase', 'phase_2'], ret=0) | |
775 self.assertIn('phase = 2', mbw.out) | |
776 | |
777 def test_validate(self): | |
778 mbw = self.fake_mbw() | |
779 self.check(['validate'], mbw=mbw, ret=0) | |
780 | |
781 def test_gyp_env_hacks(self): | |
782 mbw = self.fake_mbw() | |
783 mbw.files[mbw.default_config] = GYP_HACKS_CONFIG | |
784 self.check(['lookup', '-c', 'fake_config'], mbw=mbw, | |
785 ret=0, | |
786 out=("GYP_DEFINES='foo=bar baz=1'\n" | |
787 "GYP_LINK_CONCURRENCY=1\n" | |
788 "LLVM_FORCE_HEAD_REVISION=1\n" | |
789 "python build/gyp_chromium -G output_dir=_path_\n")) | |
790 | |
791 | |
792 if __name__ == '__main__': | |
793 unittest.main() | |
OLD | NEW |