| 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 |