blob: cba78f86587a3d0630563fedb04238262c3e6692 [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',
460 '--target-devices-file', '${SWARMING_BOT_FILE}',
461 '-v',
462 ])
463
464 def test_gn_gen_non_parallel_console_test_launcher(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': 'non_parallel_console_test_launcher',"
471 "}}\n"
472 ),
473 '/fake_src/out/Default/base_unittests.runtime_deps': (
474 "base_unittests\n"
475 ),
476 }
477 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default',
478 '--swarming-targets-file', '/tmp/swarming_targets',
479 '--isolate-map-file',
480 '/fake_src/testing/buildbot/gn_isolate_map.pyl'],
481 files=test_files, ret=0)
482
483 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate']
484 isolate_file_contents = ast.literal_eval(isolate_file)
485 files = isolate_file_contents['variables']['files']
486 command = isolate_file_contents['variables']['command']
487
488 self.assertEqual(files, [
489 '../../testing/test_env.py',
490 'base_unittests',
491 ])
492 self.assertEqual(command, [
493 '../../testing/test_env.py',
494 './base_unittests',
495 '--',
496 '--asan=0',
497 '--msan=0',
498 '--tsan=0',
499 ])
500
501 def test_gn_isolate_windowed_test_launcher_linux(self):
502 test_files = {
503 '/tmp/swarming_targets': 'base_unittests\n',
504 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
505 "{'base_unittests': {"
506 " 'label': '//base:base_unittests',"
507 " 'type': 'windowed_test_launcher',"
508 "}}\n"
509 ),
510 '/fake_src/out/Default/base_unittests.runtime_deps': (
511 "base_unittests\n"
512 "some_resource_file\n"
513 ),
514 }
515 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default',
516 '--swarming-targets-file', '/tmp/swarming_targets',
517 '--isolate-map-file',
518 '/fake_src/testing/buildbot/gn_isolate_map.pyl'],
519 files=test_files, ret=0)
520
521 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate']
522 isolate_file_contents = ast.literal_eval(isolate_file)
523 files = isolate_file_contents['variables']['files']
524 command = isolate_file_contents['variables']['command']
525
526 self.assertEqual(files, [
527 '../../testing/test_env.py',
528 '../../testing/xvfb.py',
529 '../../third_party/gtest-parallel/gtest-parallel',
530 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py',
531 'base_unittests',
532 'some_resource_file',
533 'xdisplaycheck',
534 ])
535 self.assertEqual(command, [
536 '../../testing/xvfb.py',
537 '.',
538 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py',
539 './base_unittests',
540 '--',
541 '--asan=0',
542 '--msan=0',
543 '--tsan=0',
544 ])
545
546 def test_gn_gen_windowed_test_launcher_win(self):
547 files = {
548 '/tmp/swarming_targets': 'unittests\n',
549 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
550 "{'unittests': {"
551 " 'label': '//somewhere:unittests',"
552 " 'type': 'windowed_test_launcher',"
553 "}}\n"
554 ),
555 r'c:\fake_src\out\Default\unittests.exe.runtime_deps': (
556 "unittests.exe\n"
557 "some_dependency\n"
558 ),
559 }
560 mbw = self.fake_mbw(files=files, win32=True)
561 self.check(['gen',
562 '-c', 'gn_debug_goma',
563 '--swarming-targets-file', '/tmp/swarming_targets',
564 '--isolate-map-file',
565 '/fake_src/testing/buildbot/gn_isolate_map.pyl',
566 '//out/Default'], mbw=mbw, ret=0)
567
568 isolate_file = mbw.files['c:\\fake_src\\out\\Default\\unittests.isolate']
569 isolate_file_contents = ast.literal_eval(isolate_file)
570 files = isolate_file_contents['variables']['files']
571 command = isolate_file_contents['variables']['command']
572
573 self.assertEqual(files, [
574 '../../testing/test_env.py',
575 '../../third_party/gtest-parallel/gtest-parallel',
576 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py',
577 'some_dependency',
578 'unittests.exe',
579 ])
580 self.assertEqual(command, [
581 '../../testing/test_env.py',
582 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py',
583 r'.\unittests.exe',
584 '--',
585 '--asan=0',
586 '--msan=0',
587 '--tsan=0',
588 ])
589
590 def test_gn_gen_console_test_launcher(self):
591 test_files = {
592 '/tmp/swarming_targets': 'base_unittests\n',
593 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
594 "{'base_unittests': {"
595 " 'label': '//base:base_unittests',"
596 " 'type': 'console_test_launcher',"
597 "}}\n"
598 ),
599 '/fake_src/out/Default/base_unittests.runtime_deps': (
600 "base_unittests\n"
601 ),
602 }
603 mbw = self.check(['gen', '-c', 'gn_debug_goma', '//out/Default',
604 '--swarming-targets-file', '/tmp/swarming_targets',
605 '--isolate-map-file',
606 '/fake_src/testing/buildbot/gn_isolate_map.pyl'],
607 files=test_files, ret=0)
608
609 isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate']
610 isolate_file_contents = ast.literal_eval(isolate_file)
611 files = isolate_file_contents['variables']['files']
612 command = isolate_file_contents['variables']['command']
613
614 self.assertEqual(files, [
615 '../../testing/test_env.py',
616 '../../third_party/gtest-parallel/gtest-parallel',
617 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py',
618 'base_unittests',
619 ])
620 self.assertEqual(command, [
621 '../../testing/test_env.py',
622 '../../third_party/gtest-parallel/gtest-parallel-wrapper.py',
623 './base_unittests',
624 '--',
625 '--asan=0',
626 '--msan=0',
627 '--tsan=0',
628 ])
629
630 def test_gn_isolate_console_test_launcher_memcheck(self):
631 test_files = {
632 '/tmp/swarming_targets': 'base_unittests\n',
633 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
634 "{'base_unittests': {"
635 " 'label': '//base:base_unittests',"
636 " 'type': 'console_test_launcher',"
637 "}}\n"
638 ),
639 '/fake_src/out/Release/base_unittests.runtime_deps': (
640 "base_unittests\n"
641 "lots_of_memcheck_dependencies\n"
642 "../../tools/valgrind-webrtc/webrtc_tests.sh\n"
643 ),
644 }
645 mbw = self.check(['gen', '-c', 'gn_memcheck_bot', '//out/Release',
646 '--swarming-targets-file', '/tmp/swarming_targets',
647 '--isolate-map-file',
648 '/fake_src/testing/buildbot/gn_isolate_map.pyl'],
649 files=test_files, ret=0)
650
651 isolate_file = mbw.files['/fake_src/out/Release/base_unittests.isolate']
652 isolate_file_contents = ast.literal_eval(isolate_file)
653 files = isolate_file_contents['variables']['files']
654 command = isolate_file_contents['variables']['command']
655
656 self.assertEqual(files, [
657 '../../testing/test_env.py',
658 '../../tools/valgrind-webrtc/webrtc_tests.sh',
659 'base_unittests',
660 'lots_of_memcheck_dependencies',
661 ])
662 self.assertEqual(command, [
663 '../../testing/test_env.py',
664 'bash',
665 '../../tools/valgrind-webrtc/webrtc_tests.sh',
666 '--tool',
667 'memcheck',
668 '--target',
669 'Release',
670 '--build-dir',
671 '..',
672 '--test',
673 './base_unittests',
674 '--',
675 '--asan=0',
676 '--msan=0',
677 '--tsan=0',
678 ])
kjellandera013a022016-11-14 05:54:22 -0800679
680 def test_gn_isolate(self):
681 files = {
682 '/fake_src/out/Default/toolchain.ninja': "",
683 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
684 "{'base_unittests': {"
685 " 'label': '//base:base_unittests',"
ehmaldonadob2fcf6d2016-11-15 12:20:30 -0800686 " 'type': 'non_parallel_console_test_launcher',"
kjellandera013a022016-11-14 05:54:22 -0800687 "}}\n"
688 ),
689 '/fake_src/out/Default/base_unittests.runtime_deps': (
690 "base_unittests\n"
691 ),
692 }
693 self.check(['isolate', '-c', 'gn_debug_goma', '//out/Default',
694 'base_unittests'], files=files, ret=0)
695
696 # test running isolate on an existing build_dir
697 files['/fake_src/out/Default/args.gn'] = 'is_debug = True\n'
698 self.check(['isolate', '//out/Default', 'base_unittests'],
699 files=files, ret=0)
kjellandera013a022016-11-14 05:54:22 -0800700 files['/fake_src/out/Default/mb_type'] = 'gn\n'
701 self.check(['isolate', '//out/Default', 'base_unittests'],
702 files=files, ret=0)
703
704 def test_gn_run(self):
705 files = {
706 '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
707 "{'base_unittests': {"
708 " 'label': '//base:base_unittests',"
ehmaldonadob2fcf6d2016-11-15 12:20:30 -0800709 " 'type': 'windowed_test_launcher',"
kjellandera013a022016-11-14 05:54:22 -0800710 "}}\n"
711 ),
712 '/fake_src/out/Default/base_unittests.runtime_deps': (
713 "base_unittests\n"
714 ),
715 }
716 self.check(['run', '-c', 'gn_debug_goma', '//out/Default',
717 'base_unittests'], files=files, ret=0)
718
719 def test_gn_lookup(self):
720 self.check(['lookup', '-c', 'gn_debug_goma'], ret=0)
721
722 def test_gn_lookup_goma_dir_expansion(self):
723 self.check(['lookup', '-c', 'gn_rel_bot', '-g', '/foo'], ret=0,
724 out=('\n'
725 'Writing """\\\n'
726 'goma_dir = "/foo"\n'
727 'is_debug = false\n'
728 'use_goma = true\n'
729 '""" to _path_/args.gn.\n\n'
730 '/fake_src/buildtools/linux64/gn gen _path_\n'))
731
732 def test_gyp_analyze(self):
733 mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release',
734 '/tmp/in.json', '/tmp/out.json'], ret=0)
735 self.assertIn('analyzer', mbw.calls[0])
736
737 def test_gyp_crosscompile(self):
738 mbw = self.fake_mbw()
739 self.check(['gen', '-c', 'gyp_crosscompile', '//out/Release'],
740 mbw=mbw, ret=0)
741 self.assertTrue(mbw.cross_compile)
742
743 def test_gyp_gen(self):
744 self.check(['gen', '-c', 'gyp_rel_bot', '-g', '/goma', '//out/Release'],
745 ret=0,
746 out=("GYP_DEFINES='goma=1 gomadir=/goma'\n"
747 "python build/gyp_chromium -G output_dir=out\n"))
748
749 mbw = self.fake_mbw(win32=True)
750 self.check(['gen', '-c', 'gyp_rel_bot', '-g', 'c:\\goma', '//out/Release'],
751 mbw=mbw, ret=0,
752 out=("set GYP_DEFINES=goma=1 gomadir='c:\\goma'\n"
753 "python build\\gyp_chromium -G output_dir=out\n"))
754
755 def test_gyp_gen_fails(self):
756 mbw = self.fake_mbw()
757 mbw.Call = lambda cmd, env=None, buffer_output=True: (1, '', '')
758 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], mbw=mbw, ret=1)
759
760 def test_gyp_lookup_goma_dir_expansion(self):
761 self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0,
762 out=("GYP_DEFINES='goma=1 gomadir=/foo'\n"
763 "python build/gyp_chromium -G output_dir=_path_\n"))
764
765 def test_help(self):
766 orig_stdout = sys.stdout
767 try:
768 sys.stdout = StringIO.StringIO()
769 self.assertRaises(SystemExit, self.check, ['-h'])
770 self.assertRaises(SystemExit, self.check, ['help'])
771 self.assertRaises(SystemExit, self.check, ['help', 'gen'])
772 finally:
773 sys.stdout = orig_stdout
774
775 def test_multiple_phases(self):
776 # Check that not passing a --phase to a multi-phase builder fails.
777 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase'],
778 ret=1)
779 self.assertIn('Must specify a build --phase', mbw.out)
780
781 # Check that passing a --phase to a single-phase builder fails.
782 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_gn_builder',
783 '--phase', 'phase_1'], ret=1)
784 self.assertIn('Must not specify a build --phase', mbw.out)
785
786 # Check that passing a wrong phase key to a multi-phase builder fails.
787 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase',
788 '--phase', 'wrong_phase'], ret=1)
789 self.assertIn('Phase wrong_phase doesn\'t exist', mbw.out)
790
791 # Check that passing a correct phase key to a multi-phase builder passes.
792 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase',
793 '--phase', 'phase_1'], ret=0)
794 self.assertIn('phase = 1', mbw.out)
795
796 mbw = self.check(['lookup', '-m', 'fake_master', '-b', 'fake_multi_phase',
797 '--phase', 'phase_2'], ret=0)
798 self.assertIn('phase = 2', mbw.out)
799
800 def test_validate(self):
801 mbw = self.fake_mbw()
802 self.check(['validate'], mbw=mbw, ret=0)
803
804 def test_bad_validate(self):
805 mbw = self.fake_mbw()
806 mbw.files[mbw.default_config] = TEST_BAD_CONFIG
807 self.check(['validate'], mbw=mbw, ret=1)
808
809 def test_gyp_env_hacks(self):
810 mbw = self.fake_mbw()
811 mbw.files[mbw.default_config] = GYP_HACKS_CONFIG
812 self.check(['lookup', '-c', 'fake_config'], mbw=mbw,
813 ret=0,
814 out=("GYP_DEFINES='foo=bar baz=1'\n"
815 "GYP_LINK_CONCURRENCY=1\n"
816 "LLVM_FORCE_HEAD_REVISION=1\n"
817 "python build/gyp_chromium -G output_dir=_path_\n"))
818
819
820if __name__ == '__main__':
821 unittest.main()
822
823 def test_validate(self):
824 mbw = self.fake_mbw()
825 self.check(['validate'], mbw=mbw, ret=0)
826
827 def test_bad_validate(self):
828 mbw = self.fake_mbw()
829 mbw.files[mbw.default_config] = TEST_BAD_CONFIG
830 self.check(['validate'], mbw=mbw, ret=1)
831
832 def test_gyp_env_hacks(self):
833 mbw = self.fake_mbw()
834 mbw.files[mbw.default_config] = GYP_HACKS_CONFIG
835 self.check(['lookup', '-c', 'fake_config'], mbw=mbw,
836 ret=0,
837 out=("GYP_DEFINES='foo=bar baz=1'\n"
838 "GYP_LINK_CONCURRENCY=1\n"
839 "LLVM_FORCE_HEAD_REVISION=1\n"
840 "python build/gyp_chromium -G output_dir=_path_\n"))
841
842
843if __name__ == '__main__':
844 unittest.main()