blob: 3348b731019c5ddb684a3181ddb92758153f5b4c [file] [log] [blame]
kjellandera013a022016-11-14 05:54:22 -08001#!/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
ehmaldonadoed8c8ed2016-11-23 12:58:35 -080012import ast
kjellandera013a022016-11-14 05:54:22 -080013import json
14import StringIO
15import os
16import sys
17import unittest
18
19import mb
20
21
22class 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
101class 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
114TEST_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',
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800125 'fake_memcheck_bot': 'gn_memcheck_bot',
kjellandera013a022016-11-14 05:54:22 -0800126 'fake_multi_phase': { 'phase_1': 'gn_phase_1', 'phase_2': 'gn_phase_2'},
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800127 'fake_android_bot': 'gn_android_bot',
kjellandera013a022016-11-14 05:54:22 -0800128 },
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'],
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800138 'gn_memcheck_bot': ['gn', 'memcheck'],
139 'gn_android_bot': ['gn', 'android'],
kjellandera013a022016-11-14 05:54:22 -0800140 },
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 },
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800169 'memcheck': {
170 'gn_args': 'rtc_use_memcheck=true',
171 },
172 'android': {
173 'gn_args': 'target_os="android"',
174 }
kjellandera013a022016-11-14 05:54:22 -0800175 },
176}
177"""
178
179
180TEST_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
208GYP_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
232class 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 = {
kjellandera013a022016-11-14 05:54:22 -0800361 '/tmp/swarming_targets': 'cc_perftests\n',
362 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
363 "{'cc_perftests': {"
364 " 'label': '//cc:cc_perftests',"
ehmaldonadob2fcf6d2016-11-15 12:20:30 -0800365 " 'type': 'console_test_launcher',"
kjellandera013a022016-11-14 05:54:22 -0800366 "}}\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
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800384 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',
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800460 '-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',
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800532 ])
533 self.assertEqual(command, [
534 '../../testing/xvfb.py',
ehmaldonadoed8c8ed2016-11-23 12:58:35 -0800535 '../../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 ])
kjellandera013a022016-11-14 05:54:22 -0800676
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',"
ehmaldonadob2fcf6d2016-11-15 12:20:30 -0800683 " 'type': 'non_parallel_console_test_launcher',"
kjellandera013a022016-11-14 05:54:22 -0800684 "}}\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)
kjellandera013a022016-11-14 05:54:22 -0800697 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',"
ehmaldonadob2fcf6d2016-11-15 12:20:30 -0800706 " 'type': 'windowed_test_launcher',"
kjellandera013a022016-11-14 05:54:22 -0800707 "}}\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
817if __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
840if __name__ == '__main__':
841 unittest.main()