| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Tests for mb.py.""" | 6 """Tests for mb.py.""" |
| 7 | 7 |
| 8 import json | 8 import json |
| 9 import StringIO | 9 import StringIO |
| 10 import sys | 10 import sys |
| 11 import unittest | 11 import unittest |
| 12 | 12 |
| 13 import mb | 13 import mb |
| 14 | 14 |
| 15 | 15 |
| 16 class FakeMBW(mb.MetaBuildWrapper): | 16 class FakeMBW(mb.MetaBuildWrapper): |
| 17 def __init__(self): | 17 def __init__(self): |
| 18 super(FakeMBW, self).__init__() | 18 super(FakeMBW, self).__init__() |
| 19 self.files = {} | 19 self.files = {} |
| 20 self.calls = [] | 20 self.calls = [] |
| 21 self.cmds = [] | 21 self.cmds = [] |
| 22 self.cross_compile = None |
| 22 self.out = '' | 23 self.out = '' |
| 23 self.err = '' | 24 self.err = '' |
| 24 self.platform = 'linux2' | 25 self.platform = 'linux2' |
| 25 self.chromium_src_dir = '/fake_src' | 26 self.chromium_src_dir = '/fake_src' |
| 26 self.default_config = '/fake_src/tools/mb/mb_config.pyl' | 27 self.default_config = '/fake_src/tools/mb/mb_config.pyl' |
| 27 | 28 |
| 28 def ExpandUser(self, path): | 29 def ExpandUser(self, path): |
| 29 return '$HOME/%s' % path | 30 return '$HOME/%s' % path |
| 30 | 31 |
| 31 def Exists(self, path): | 32 def Exists(self, path): |
| 32 return self.files.get(path) is not None | 33 return self.files.get(path) is not None |
| 33 | 34 |
| 34 def MaybeMakeDirectory(self, path): | 35 def MaybeMakeDirectory(self, path): |
| 35 pass | 36 pass |
| 36 | 37 |
| 37 def ReadFile(self, path): | 38 def ReadFile(self, path): |
| 38 return self.files[path] | 39 return self.files[path] |
| 39 | 40 |
| 40 def WriteFile(self, path, contents): | 41 def WriteFile(self, path, contents): |
| 41 self.files[path] = contents | 42 self.files[path] = contents |
| 42 | 43 |
| 43 def Call(self, cmd): | 44 def Call(self, cmd, env=None): |
| 45 if env: |
| 46 self.cross_compile = env.get('GYP_CROSSCOMPILE') |
| 44 self.calls.append(cmd) | 47 self.calls.append(cmd) |
| 45 if self.cmds: | 48 if self.cmds: |
| 46 return self.cmds.pop(0) | 49 return self.cmds.pop(0) |
| 47 return 0, '', '' | 50 return 0, '', '' |
| 48 | 51 |
| 49 def Print(self, *args, **kwargs): | 52 def Print(self, *args, **kwargs): |
| 50 sep = kwargs.get('sep', ' ') | 53 sep = kwargs.get('sep', ' ') |
| 51 end = kwargs.get('end', '\n') | 54 end = kwargs.get('end', '\n') |
| 52 f = kwargs.get('file', sys.stdout) | 55 f = kwargs.get('file', sys.stdout) |
| 53 if f == sys.stderr: | 56 if f == sys.stderr: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 75 self.files[self.name] = self.buf | 78 self.files[self.name] = self.buf |
| 76 | 79 |
| 77 | 80 |
| 78 TEST_CONFIG = """\ | 81 TEST_CONFIG = """\ |
| 79 { | 82 { |
| 80 'common_dev_configs': ['gn_debug'], | 83 'common_dev_configs': ['gn_debug'], |
| 81 'configs': { | 84 'configs': { |
| 82 'gyp_rel_bot': ['gyp', 'rel', 'goma'], | 85 'gyp_rel_bot': ['gyp', 'rel', 'goma'], |
| 83 'gn_debug': ['gn', 'debug'], | 86 'gn_debug': ['gn', 'debug'], |
| 84 'gn_rel_bot': ['gn', 'rel', 'goma'], | 87 'gn_rel_bot': ['gn', 'rel', 'goma'], |
| 85 'private': ['gyp', 'fake_feature1'], | 88 'private': ['gyp', 'rel', 'fake_feature1'], |
| 86 'unsupported': ['gn', 'fake_feature2'], | 89 'unsupported': ['gn', 'fake_feature2'], |
| 87 }, | 90 }, |
| 88 'masters': { | 91 'masters': { |
| 89 'fake_master': { | 92 'fake_master': { |
| 90 'fake_builder': 'gyp_rel_bot', | 93 'fake_builder': 'gyp_rel_bot', |
| 91 'fake_gn_builder': 'gn_rel_bot', | 94 'fake_gn_builder': 'gn_rel_bot', |
| 92 }, | 95 }, |
| 93 }, | 96 }, |
| 94 'mixins': { | 97 'mixins': { |
| 95 'fake_feature1': { | 98 'fake_feature1': { |
| 96 'gn_args': 'enable_doom_melon=true', | 99 'gn_args': 'enable_doom_melon=true', |
| 100 'gyp_crosscompile': True, |
| 97 'gyp_defines': 'doom_melon=1', | 101 'gyp_defines': 'doom_melon=1', |
| 98 }, | 102 }, |
| 99 'fake_feature2': { | 103 'fake_feature2': { |
| 100 'gn_args': 'enable_doom_melon=false', | 104 'gn_args': 'enable_doom_melon=false', |
| 101 'gyp_defaults': 'doom_melon=0', | 105 'gyp_defaults': 'doom_melon=0', |
| 102 }, | 106 }, |
| 103 'gyp': {'type': 'gyp'}, | 107 'gyp': {'type': 'gyp'}, |
| 104 'gn': {'type': 'gn'}, | 108 'gn': {'type': 'gn'}, |
| 105 'goma': { | 109 'goma': { |
| 106 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"', | 110 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"', |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 self.assertEqual(mbw.err, err) | 146 self.assertEqual(mbw.err, err) |
| 143 return mbw | 147 return mbw |
| 144 | 148 |
| 145 def test_gn_analyze(self): | 149 def test_gn_analyze(self): |
| 146 files = {'/tmp/in.json': """{\ | 150 files = {'/tmp/in.json': """{\ |
| 147 "files": ["foo/foo_unittest.cc"], | 151 "files": ["foo/foo_unittest.cc"], |
| 148 "targets": ["foo_unittests", "bar_unittests"] | 152 "targets": ["foo_unittests", "bar_unittests"] |
| 149 }"""} | 153 }"""} |
| 150 | 154 |
| 151 mbw = self.fake_mbw(files) | 155 mbw = self.fake_mbw(files) |
| 152 mbw.Call = lambda cmd: (0, 'out/Default/foo_unittests\n', '') | 156 mbw.Call = lambda cmd, env=None: (0, 'out/Default/foo_unittests\n', '') |
| 153 | 157 |
| 154 self.check(['analyze', '-c', 'gn_debug', '//out/Default', | 158 self.check(['analyze', '-c', 'gn_debug', '//out/Default', |
| 155 '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0) | 159 '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0) |
| 156 out = json.loads(mbw.files['/tmp/out.json']) | 160 out = json.loads(mbw.files['/tmp/out.json']) |
| 157 self.assertEqual(out, { | 161 self.assertEqual(out, { |
| 158 'status': 'Found dependency', | 162 'status': 'Found dependency', |
| 159 'targets': ['foo_unittests'], | 163 'targets': ['foo_unittests'], |
| 160 'build_targets': ['foo_unittests'] | 164 'build_targets': ['foo_unittests'] |
| 161 }) | 165 }) |
| 162 | 166 |
| 163 def test_gn_analyze_all(self): | 167 def test_gn_analyze_all(self): |
| 164 files = {'/tmp/in.json': """{\ | 168 files = {'/tmp/in.json': """{\ |
| 165 "files": ["foo/foo_unittest.cc"], | 169 "files": ["foo/foo_unittest.cc"], |
| 166 "targets": ["all", "bar_unittests"] | 170 "targets": ["all", "bar_unittests"] |
| 167 }"""} | 171 }"""} |
| 168 mbw = self.fake_mbw(files) | 172 mbw = self.fake_mbw(files) |
| 169 mbw.Call = lambda cmd: (0, 'out/Default/foo_unittests\n', '') | 173 mbw.Call = lambda cmd, env=None: (0, 'out/Default/foo_unittests\n', '') |
| 170 self.check(['analyze', '-c', 'gn_debug', '//out/Default', | 174 self.check(['analyze', '-c', 'gn_debug', '//out/Default', |
| 171 '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0) | 175 '/tmp/in.json', '/tmp/out.json'], mbw=mbw, ret=0) |
| 172 out = json.loads(mbw.files['/tmp/out.json']) | 176 out = json.loads(mbw.files['/tmp/out.json']) |
| 173 self.assertEqual(out, { | 177 self.assertEqual(out, { |
| 174 'status': 'Found dependency (all)', | 178 'status': 'Found dependency (all)', |
| 175 }) | 179 }) |
| 176 | 180 |
| 177 def test_gn_analyze_missing_file(self): | 181 def test_gn_analyze_missing_file(self): |
| 178 files = {'/tmp/in.json': """{\ | 182 files = {'/tmp/in.json': """{\ |
| 179 "files": ["foo/foo_unittest.cc"], | 183 "files": ["foo/foo_unittest.cc"], |
| (...skipping 14 matching lines...) Expand all Loading... |
| 194 'targets': [], | 198 'targets': [], |
| 195 'status': 'No dependency', | 199 'status': 'No dependency', |
| 196 }) | 200 }) |
| 197 | 201 |
| 198 def test_gn_gen(self): | 202 def test_gn_gen(self): |
| 199 self.check(['gen', '-c', 'gn_debug', '//out/Default'], ret=0) | 203 self.check(['gen', '-c', 'gn_debug', '//out/Default'], ret=0) |
| 200 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0) | 204 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0) |
| 201 | 205 |
| 202 def test_gn_gen_fails(self): | 206 def test_gn_gen_fails(self): |
| 203 mbw = self.fake_mbw() | 207 mbw = self.fake_mbw() |
| 204 mbw.Call = lambda cmd: (1, '', '') | 208 mbw.Call = lambda cmd, env=None: (1, '', '') |
| 205 self.check(['gen', '-c', 'gn_debug', '//out/Default'], mbw=mbw, ret=1) | 209 self.check(['gen', '-c', 'gn_debug', '//out/Default'], mbw=mbw, ret=1) |
| 206 | 210 |
| 207 def test_gn_gen_swarming(self): | 211 def test_gn_gen_swarming(self): |
| 208 files = { | 212 files = { |
| 209 '/tmp/swarming_targets': 'base_unittests\n', | 213 '/tmp/swarming_targets': 'base_unittests\n', |
| 210 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( | 214 '/fake_src/testing/buildbot/gn_isolate_map.pyl': ( |
| 211 "{'base_unittests': {" | 215 "{'base_unittests': {" |
| 212 " 'label': '//base:base_unittests'," | 216 " 'label': '//base:base_unittests'," |
| 213 " 'type': 'raw'," | 217 " 'type': 'raw'," |
| 214 " 'args': []," | 218 " 'args': []," |
| (...skipping 21 matching lines...) Expand all Loading... |
| 236 out=("/fake_src/buildtools/linux64/gn gen '<path>' " | 240 out=("/fake_src/buildtools/linux64/gn gen '<path>' " |
| 237 "'--args=is_debug=false use_goma=true " | 241 "'--args=is_debug=false use_goma=true " |
| 238 "goma_dir=\"/foo\"'\n" )) | 242 "goma_dir=\"/foo\"'\n" )) |
| 239 | 243 |
| 240 def test_gyp_analyze(self): | 244 def test_gyp_analyze(self): |
| 241 mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release', | 245 mbw = self.check(['analyze', '-c', 'gyp_rel_bot', '//out/Release', |
| 242 '/tmp/in.json', '/tmp/out.json'], | 246 '/tmp/in.json', '/tmp/out.json'], |
| 243 ret=0) | 247 ret=0) |
| 244 self.assertIn('analyzer', mbw.calls[0]) | 248 self.assertIn('analyzer', mbw.calls[0]) |
| 245 | 249 |
| 250 def test_gyp_crosscompile(self): |
| 251 mbw = self.fake_mbw() |
| 252 self.check(['gen', '-c', 'private', '//out/Release'], mbw=mbw) |
| 253 self.assertTrue(mbw.cross_compile) |
| 254 |
| 246 def test_gyp_gen(self): | 255 def test_gyp_gen(self): |
| 247 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0) | 256 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], ret=0) |
| 248 | 257 |
| 249 def test_gyp_gen_fails(self): | 258 def test_gyp_gen_fails(self): |
| 250 mbw = self.fake_mbw() | 259 mbw = self.fake_mbw() |
| 251 mbw.Call = lambda cmd: (1, '', '') | 260 mbw.Call = lambda cmd, env=None: (1, '', '') |
| 252 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], mbw=mbw, ret=1) | 261 self.check(['gen', '-c', 'gyp_rel_bot', '//out/Release'], mbw=mbw, ret=1) |
| 253 | 262 |
| 254 def test_gyp_lookup_goma_dir_expansion(self): | 263 def test_gyp_lookup_goma_dir_expansion(self): |
| 255 self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0, | 264 self.check(['lookup', '-c', 'gyp_rel_bot', '-g', '/foo'], ret=0, |
| 256 out=("python build/gyp_chromium -G 'output_dir=<path>' " | 265 out=("python build/gyp_chromium -G 'output_dir=<path>' " |
| 257 "-G config=Release -D goma=1 -D gomadir=/foo\n")) | 266 "-G config=Release -D goma=1 -D gomadir=/foo\n")) |
| 258 | 267 |
| 259 def test_help(self): | 268 def test_help(self): |
| 260 orig_stdout = sys.stdout | 269 orig_stdout = sys.stdout |
| 261 try: | 270 try: |
| 262 sys.stdout = StringIO.StringIO() | 271 sys.stdout = StringIO.StringIO() |
| 263 self.assertRaises(SystemExit, self.check, ['-h']) | 272 self.assertRaises(SystemExit, self.check, ['-h']) |
| 264 self.assertRaises(SystemExit, self.check, ['help']) | 273 self.assertRaises(SystemExit, self.check, ['help']) |
| 265 self.assertRaises(SystemExit, self.check, ['help', 'gen']) | 274 self.assertRaises(SystemExit, self.check, ['help', 'gen']) |
| 266 finally: | 275 finally: |
| 267 sys.stdout = orig_stdout | 276 sys.stdout = orig_stdout |
| 268 | 277 |
| 269 | 278 |
| 270 def test_validate(self): | 279 def test_validate(self): |
| 271 self.check(['validate'], ret=0) | 280 self.check(['validate'], ret=0) |
| 272 | 281 |
| 273 | 282 |
| 274 if __name__ == '__main__': | 283 if __name__ == '__main__': |
| 275 unittest.main() | 284 unittest.main() |
| OLD | NEW |