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