| Index: tools/mb/mb_unittest.py
|
| diff --git a/tools/mb/mb_unittest.py b/tools/mb/mb_unittest.py
|
| old mode 100644
|
| new mode 100755
|
| index 6723950b96ef8d2bd1e0b1f2c5da6ccbbdc0c8a4..64f53123612505b423f3c6b24a5c958595094897
|
| --- a/tools/mb/mb_unittest.py
|
| +++ b/tools/mb/mb_unittest.py
|
| @@ -1,3 +1,4 @@
|
| +#!/usr/bin/python
|
| # Copyright 2015 The Chromium Authors. All rights reserved.
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
| @@ -5,6 +6,8 @@
|
| """Tests for mb.py."""
|
|
|
| import json
|
| +import StringIO
|
| +import os
|
| import sys
|
| import unittest
|
|
|
| @@ -12,16 +15,30 @@ import mb
|
|
|
|
|
| class FakeMBW(mb.MetaBuildWrapper):
|
| - def __init__(self):
|
| + def __init__(self, win32=False):
|
| super(FakeMBW, self).__init__()
|
| +
|
| + # Override vars for test portability.
|
| + if win32:
|
| + self.chromium_src_dir = 'c:\\fake_src'
|
| + self.default_config = 'c:\\fake_src\\tools\\mb\\mb_config.pyl'
|
| + self.platform = 'win32'
|
| + self.executable = 'c:\\python\\python.exe'
|
| + self.sep = '\\'
|
| + else:
|
| + self.chromium_src_dir = '/fake_src'
|
| + self.default_config = '/fake_src/tools/mb/mb_config.pyl'
|
| + self.executable = '/usr/bin/python'
|
| + self.platform = 'linux2'
|
| + self.sep = '/'
|
| +
|
| self.files = {}
|
| self.calls = []
|
| self.cmds = []
|
| + self.cross_compile = None
|
| self.out = ''
|
| self.err = ''
|
| - self.platform = 'linux2'
|
| - self.chromium_src_dir = '/fake_src'
|
| - self.default_config = '/fake_src/tools/mb/mb_config.pyl'
|
| + self.rmdirs = []
|
|
|
| def ExpandUser(self, path):
|
| return '$HOME/%s' % path
|
| @@ -30,15 +47,20 @@ class FakeMBW(mb.MetaBuildWrapper):
|
| return self.files.get(path) is not None
|
|
|
| def MaybeMakeDirectory(self, path):
|
| - pass
|
| + self.files[path] = True
|
| +
|
| + def PathJoin(self, *comps):
|
| + return self.sep.join(comps)
|
|
|
| def ReadFile(self, path):
|
| return self.files[path]
|
|
|
| - def WriteFile(self, path, contents):
|
| + def WriteFile(self, path, contents, force_verbose=False):
|
| self.files[path] = contents
|
|
|
| - def Call(self, cmd):
|
| + def Call(self, cmd, env=None):
|
| + if env:
|
| + self.cross_compile = env.get('GYP_CROSSCOMPILE')
|
| self.calls.append(cmd)
|
| if self.cmds:
|
| return self.cmds.pop(0)
|
| @@ -59,6 +81,12 @@ class FakeMBW(mb.MetaBuildWrapper):
|
| def RemoveFile(self, path):
|
| del self.files[path]
|
|
|
| + def RemoveDirectory(self, path):
|
| + self.rmdirs.append(path)
|
| + files_to_delete = [f for f in self.files if f.startswith(path)]
|
| + for f in files_to_delete:
|
| + self.files[f] = None
|
| +
|
|
|
| class FakeFile(object):
|
| def __init__(self, files):
|
| @@ -73,32 +101,28 @@ class FakeFile(object):
|
| self.files[self.name] = self.buf
|
|
|
|
|
| -class IntegrationTest(unittest.TestCase):
|
| - def test_validate(self):
|
| - # Note that this validates that the actual mb_config.pyl is valid.
|
| - ret = mb.main(['validate', '--quiet'])
|
| - self.assertEqual(ret, 0)
|
| -
|
| -
|
| TEST_CONFIG = """\
|
| {
|
| 'common_dev_configs': ['gn_debug'],
|
| 'configs': {
|
| 'gyp_rel_bot': ['gyp', 'rel', 'goma'],
|
| - 'gn_debug': ['gn', 'debug'],
|
| + 'gn_debug': ['gn', 'debug', 'goma'],
|
| + 'gyp_debug': ['gyp', 'debug'],
|
| 'gn_rel_bot': ['gn', 'rel', 'goma'],
|
| - 'private': ['gyp', 'fake_feature1'],
|
| + 'private': ['gyp', 'rel', 'fake_feature1'],
|
| 'unsupported': ['gn', 'fake_feature2'],
|
| },
|
| 'masters': {
|
| 'fake_master': {
|
| 'fake_builder': 'gyp_rel_bot',
|
| 'fake_gn_builder': 'gn_rel_bot',
|
| + 'fake_gyp_builder': 'gyp_debug',
|
| },
|
| },
|
| 'mixins': {
|
| 'fake_feature1': {
|
| 'gn_args': 'enable_doom_melon=true',
|
| + 'gyp_crosscompile': True,
|
| 'gyp_defines': 'doom_melon=1',
|
| },
|
| 'fake_feature2': {
|
| @@ -109,11 +133,10 @@ TEST_CONFIG = """\
|
| 'gn': {'type': 'gn'},
|
| 'goma': {
|
| 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"',
|
| - 'gyp_defines': 'goma=1 gomadir="$(goma_dir)"',
|
| + 'gyp_defines': 'goma=1 gomadir=$(goma_dir)',
|
| },
|
| 'rel': {
|
| 'gn_args': 'is_debug=false',
|
| - 'gyp_config': 'Release',
|
| },
|
| 'debug': {
|
| 'gn_args': 'is_debug=true',
|
| @@ -126,8 +149,8 @@ TEST_CONFIG = """\
|
|
|
|
|
| class UnitTest(unittest.TestCase):
|
| - def fake_mbw(self, files=None):
|
| - mbw = FakeMBW()
|
| + def fake_mbw(self, files=None, win32=False):
|
| + mbw = FakeMBW(win32=win32)
|
| mbw.files.setdefault(mbw.default_config, TEST_CONFIG)
|
| if files:
|
| for path, contents in files.items():
|
| @@ -147,6 +170,37 @@ class UnitTest(unittest.TestCase):
|
| self.assertEqual(mbw.err, err)
|
| return mbw
|
|
|
| + def test_clobber(self):
|
| + files = {
|
| + '/fake_src/out/Debug': None,
|
| + '/fake_src/out/Debug/mb_type': None,
|
| + }
|
| + mbw = self.fake_mbw(files)
|
| +
|
| + # The first time we run this, the build dir doesn't exist, so no clobber.
|
| + self.check(['gen', '-c', 'gn_debug', '//out/Debug'], mbw=mbw, ret=0)
|
| + self.assertEqual(mbw.rmdirs, [])
|
| + self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn')
|
| +
|
| + # The second time we run this, the build dir exists and matches, so no
|
| + # clobber.
|
| + self.check(['gen', '-c', 'gn_debug', '//out/Debug'], mbw=mbw, ret=0)
|
| + self.assertEqual(mbw.rmdirs, [])
|
| + self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn')
|
| +
|
| + # Now we switch build types; this should result in a clobber.
|
| + self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0)
|
| + self.assertEqual(mbw.rmdirs, ['/fake_src/out/Debug'])
|
| + self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp')
|
| +
|
| + # Now we delete mb_type; this checks the case where the build dir
|
| + # exists but wasn't populated by mb; this should also result in a clobber.
|
| + del mbw.files['/fake_src/out/Debug/mb_type']
|
| + self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0)
|
| + self.assertEqual(mbw.rmdirs,
|
| + ['/fake_src/out/Debug', '/fake_src/out/Debug'])
|
| + self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp')
|
| +
|
| def test_gn_analyze(self):
|
| files = {'/tmp/in.json': """{\
|
| "files": ["foo/foo_unittest.cc"],
|
| @@ -154,7 +208,7 @@ class UnitTest(unittest.TestCase):
|
| }"""}
|
|
|
| mbw = self.fake_mbw(files)
|
| - mbw.Call = lambda cmd: (0, 'out/Default/foo_unittests\n', '')
|
| + mbw.Call = lambda cmd, env=None: (0, 'out/Default/foo_unittests\n', '')
|
|
|
| self.check(['analyze', '-c', 'gn_debug', '//out/Default',
|
| '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0)
|
| @@ -171,7 +225,7 @@ class UnitTest(unittest.TestCase):
|
| "targets": ["all", "bar_unittests"]
|
| }"""}
|
| mbw = self.fake_mbw(files)
|
| - mbw.Call = lambda cmd: (0, 'out/Default/foo_unittests\n', '')
|
| + mbw.Call = lambda cmd, env=None: (0, 'out/Default/foo_unittests\n', '')
|
| self.check(['analyze', '-c', 'gn_debug', '//out/Default',
|
| '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0)
|
| out = json.loads(mbw.files['/tmp/out.json'])
|
| @@ -201,19 +255,34 @@ class UnitTest(unittest.TestCase):
|
| })
|
|
|
| def test_gn_gen(self):
|
| - self.check(['gen', '-c', 'gn_debug', '//out/Default'], ret=0)
|
| - self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0)
|
| + self.check(['gen', '-c', 'gn_debug', '//out/Default', '-g', '/goma'],
|
| + ret=0,
|
| + out=('/fake_src/buildtools/linux64/gn gen //out/Default '
|
| + '\'--args=is_debug=true use_goma=true goma_dir="/goma"\' '
|
| + '--check\n'))
|
| +
|
| + mbw = self.fake_mbw(win32=True)
|
| + self.check(['gen', '-c', 'gn_debug', '-g', 'c:\\goma', '//out/Debug'],
|
| + mbw=mbw, ret=0,
|
| + out=('c:\\fake_src\\buildtools\\win\\gn gen //out/Debug '
|
| + '"--args=is_debug=true use_goma=true goma_dir=\\"'
|
| + 'c:\\goma\\"" --check\n'))
|
| +
|
|
|
| def test_gn_gen_fails(self):
|
| mbw = self.fake_mbw()
|
| - mbw.Call = lambda cmd: (1, '', '')
|
| + mbw.Call = lambda cmd, env=None: (1, '', '')
|
| self.check(['gen', '-c', 'gn_debug', '//out/Default'], mbw=mbw, ret=1)
|
|
|
| def test_gn_gen_swarming(self):
|
| files = {
|
| '/tmp/swarming_targets': 'base_unittests\n',
|
| - '/fake_src/testing/buildbot/ninja_to_gn.pyl': (
|
| - "{'base_unittests': '//base:base_unittests'}\n"
|
| + '/fake_src/testing/buildbot/gn_isolate_map.pyl': (
|
| + "{'base_unittests': {"
|
| + " 'label': '//base:base_unittests',"
|
| + " 'type': 'raw',"
|
| + " 'args': [],"
|
| + "}}\n"
|
| ),
|
| '/fake_src/out/Default/base_unittests.runtime_deps': (
|
| "base_unittests\n"
|
| @@ -234,32 +303,53 @@ class UnitTest(unittest.TestCase):
|
|
|
| def test_gn_lookup_goma_dir_expansion(self):
|
| self.check(['lookup', '-c', 'gn_rel_bot', '-g', '/foo'], ret=0,
|
| - out=("/fake_src/buildtools/linux64/gn gen '<path>' "
|
| + out=("/fake_src/buildtools/linux64/gn gen _path_ "
|
| "'--args=is_debug=false use_goma=true "
|
| "goma_dir=\"/foo\"'\n" ))
|
|
|
| def test_gyp_analyze(self):
|
| - self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release',
|
| - '/tmp/in.json', '/tmp/out.json'],
|
| - ret=0)
|
| + mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release',
|
| + '/tmp/in.json', '/tmp/out.json'],
|
| + ret=0)
|
| + self.assertIn('analyzer', mbw.calls[0])
|
| +
|
| + def test_gyp_crosscompile(self):
|
| + mbw = self.fake_mbw()
|
| + self.check(['gen', '-c', 'private', '//out/Release'], mbw=mbw)
|
| + self.assertTrue(mbw.cross_compile)
|
|
|
| def test_gyp_gen(self):
|
| - self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0)
|
| + self.check(['gen', '-c', 'gyp_rel_bot', '-g', '/goma', '//out/Release'],
|
| + ret=0,
|
| + out=("GYP_DEFINES='goma=1 gomadir=/goma'\n"
|
| + "python build/gyp_chromium -G output_dir=out\n"))
|
| +
|
| + mbw = self.fake_mbw(win32=True)
|
| + self.check(['gen', '-c', 'gyp_rel_bot', '-g', 'c:\\goma', '//out/Release'],
|
| + mbw=mbw, ret=0,
|
| + out=("set GYP_DEFINES=goma=1 gomadir='c:\\goma'\n"
|
| + "python build\\gyp_chromium -G output_dir=out\n"))
|
|
|
| def test_gyp_gen_fails(self):
|
| mbw = self.fake_mbw()
|
| - mbw.Call = lambda cmd: (1, '', '')
|
| + mbw.Call = lambda cmd, env=None: (1, '', '')
|
| self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], mbw=mbw, ret=1)
|
|
|
| def test_gyp_lookup_goma_dir_expansion(self):
|
| self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0,
|
| - out=("python build/gyp_chromium -G 'output_dir=<path>' "
|
| - "-G config=Release -D goma=1 -D gomadir=/foo\n"))
|
| + out=("GYP_DEFINES='goma=1 gomadir=/foo'\n"
|
| + "python build/gyp_chromium -G output_dir=_path_\n"))
|
|
|
| def test_help(self):
|
| - self.assertRaises(SystemExit, self.check, ['-h'])
|
| - self.assertRaises(SystemExit, self.check, ['help'])
|
| - self.assertRaises(SystemExit, self.check, ['help', 'gen'])
|
| + orig_stdout = sys.stdout
|
| + try:
|
| + sys.stdout = StringIO.StringIO()
|
| + self.assertRaises(SystemExit, self.check, ['-h'])
|
| + self.assertRaises(SystemExit, self.check, ['help'])
|
| + self.assertRaises(SystemExit, self.check, ['help', 'gen'])
|
| + finally:
|
| + sys.stdout = orig_stdout
|
| +
|
|
|
| def test_validate(self):
|
| self.check(['validate'], ret=0)
|
|
|