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.cross_compile = None |
23 self.out = '' | 23 self.out = '' |
24 self.err = '' | 24 self.err = '' |
25 self.platform = 'linux2' | 25 self.platform = 'linux2' |
26 self.chromium_src_dir = '/fake_src' | 26 self.chromium_src_dir = '/fake_src' |
27 self.default_config = '/fake_src/tools/mb/mb_config.pyl' | 27 self.default_config = '/fake_src/tools/mb/mb_config.pyl' |
| 28 self.rmdirs = [] |
28 | 29 |
29 def ExpandUser(self, path): | 30 def ExpandUser(self, path): |
30 return '$HOME/%s' % path | 31 return '$HOME/%s' % path |
31 | 32 |
32 def Exists(self, path): | 33 def Exists(self, path): |
33 return self.files.get(path) is not None | 34 return self.files.get(path) is not None |
34 | 35 |
35 def MaybeMakeDirectory(self, path): | 36 def MaybeMakeDirectory(self, path): |
36 pass | 37 self.files[path] = True |
37 | 38 |
38 def ReadFile(self, path): | 39 def ReadFile(self, path): |
39 return self.files[path] | 40 return self.files[path] |
40 | 41 |
41 def WriteFile(self, path, contents): | 42 def WriteFile(self, path, contents): |
42 self.files[path] = contents | 43 self.files[path] = contents |
43 | 44 |
44 def Call(self, cmd, env=None): | 45 def Call(self, cmd, env=None): |
45 if env: | 46 if env: |
46 self.cross_compile = env.get('GYP_CROSSCOMPILE') | 47 self.cross_compile = env.get('GYP_CROSSCOMPILE') |
(...skipping 10 matching lines...) Expand all Loading... |
57 self.err += sep.join(args) + end | 58 self.err += sep.join(args) + end |
58 else: | 59 else: |
59 self.out += sep.join(args) + end | 60 self.out += sep.join(args) + end |
60 | 61 |
61 def TempFile(self, mode='w'): | 62 def TempFile(self, mode='w'): |
62 return FakeFile(self.files) | 63 return FakeFile(self.files) |
63 | 64 |
64 def RemoveFile(self, path): | 65 def RemoveFile(self, path): |
65 del self.files[path] | 66 del self.files[path] |
66 | 67 |
| 68 def RemoveDirectory(self, path): |
| 69 self.rmdirs.append(path) |
| 70 files_to_delete = [f for f in self.files if f.startswith(path)] |
| 71 for f in files_to_delete: |
| 72 self.files[f] = None |
| 73 |
67 | 74 |
68 class FakeFile(object): | 75 class FakeFile(object): |
69 def __init__(self, files): | 76 def __init__(self, files): |
70 self.name = '/tmp/file' | 77 self.name = '/tmp/file' |
71 self.buf = '' | 78 self.buf = '' |
72 self.files = files | 79 self.files = files |
73 | 80 |
74 def write(self, contents): | 81 def write(self, contents): |
75 self.buf += contents | 82 self.buf += contents |
76 | 83 |
77 def close(self): | 84 def close(self): |
78 self.files[self.name] = self.buf | 85 self.files[self.name] = self.buf |
79 | 86 |
80 | 87 |
81 TEST_CONFIG = """\ | 88 TEST_CONFIG = """\ |
82 { | 89 { |
83 'common_dev_configs': ['gn_debug'], | 90 'common_dev_configs': ['gn_debug'], |
84 'configs': { | 91 'configs': { |
85 'gyp_rel_bot': ['gyp', 'rel', 'goma'], | 92 'gyp_rel_bot': ['gyp', 'rel', 'goma'], |
86 'gn_debug': ['gn', 'debug'], | 93 'gn_debug': ['gn', 'debug'], |
| 94 'gyp_debug': ['gyp', 'debug'], |
87 'gn_rel_bot': ['gn', 'rel', 'goma'], | 95 'gn_rel_bot': ['gn', 'rel', 'goma'], |
88 'private': ['gyp', 'rel', 'fake_feature1'], | 96 'private': ['gyp', 'rel', 'fake_feature1'], |
89 'unsupported': ['gn', 'fake_feature2'], | 97 'unsupported': ['gn', 'fake_feature2'], |
90 }, | 98 }, |
91 'masters': { | 99 'masters': { |
92 'fake_master': { | 100 'fake_master': { |
93 'fake_builder': 'gyp_rel_bot', | 101 'fake_builder': 'gyp_rel_bot', |
94 'fake_gn_builder': 'gn_rel_bot', | 102 'fake_gn_builder': 'gn_rel_bot', |
| 103 'fake_gyp_builder': 'gyp_debug', |
95 }, | 104 }, |
96 }, | 105 }, |
97 'mixins': { | 106 'mixins': { |
98 'fake_feature1': { | 107 'fake_feature1': { |
99 'gn_args': 'enable_doom_melon=true', | 108 'gn_args': 'enable_doom_melon=true', |
100 'gyp_crosscompile': True, | 109 'gyp_crosscompile': True, |
101 'gyp_defines': 'doom_melon=1', | 110 'gyp_defines': 'doom_melon=1', |
102 }, | 111 }, |
103 'fake_feature2': { | 112 'fake_feature2': { |
104 'gn_args': 'enable_doom_melon=false', | 113 'gn_args': 'enable_doom_melon=false', |
105 'gyp_defaults': 'doom_melon=0', | 114 'gyp_defaults': 'doom_melon=0', |
106 }, | 115 }, |
107 'gyp': {'type': 'gyp'}, | 116 'gyp': {'type': 'gyp'}, |
108 'gn': {'type': 'gn'}, | 117 'gn': {'type': 'gn'}, |
109 'goma': { | 118 'goma': { |
110 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"', | 119 'gn_args': 'use_goma=true goma_dir="$(goma_dir)"', |
111 'gyp_defines': 'goma=1 gomadir="$(goma_dir)"', | 120 'gyp_defines': 'goma=1 gomadir="$(goma_dir)"', |
112 }, | 121 }, |
113 'rel': { | 122 'rel': { |
114 'gn_args': 'is_debug=false', | 123 'gn_args': 'is_debug=false', |
115 'gyp_config': 'Release', | 124 'gyp_config': 'Release', |
116 }, | 125 }, |
117 'debug': { | 126 'debug': { |
118 'gn_args': 'is_debug=true', | 127 'gn_args': 'is_debug=true', |
| 128 'gyp_config': 'Debug', |
119 }, | 129 }, |
120 }, | 130 }, |
121 'private_configs': ['private'], | 131 'private_configs': ['private'], |
122 'unsupported_configs': ['unsupported'], | 132 'unsupported_configs': ['unsupported'], |
123 } | 133 } |
124 """ | 134 """ |
125 | 135 |
126 | 136 |
127 class UnitTest(unittest.TestCase): | 137 class UnitTest(unittest.TestCase): |
128 def fake_mbw(self, files=None): | 138 def fake_mbw(self, files=None): |
(...skipping 10 matching lines...) Expand all Loading... |
139 mbw.ParseArgs(args) | 149 mbw.ParseArgs(args) |
140 actual_ret = mbw.args.func() | 150 actual_ret = mbw.args.func() |
141 if ret is not None: | 151 if ret is not None: |
142 self.assertEqual(actual_ret, ret) | 152 self.assertEqual(actual_ret, ret) |
143 if out is not None: | 153 if out is not None: |
144 self.assertEqual(mbw.out, out) | 154 self.assertEqual(mbw.out, out) |
145 if err is not None: | 155 if err is not None: |
146 self.assertEqual(mbw.err, err) | 156 self.assertEqual(mbw.err, err) |
147 return mbw | 157 return mbw |
148 | 158 |
| 159 def test_clobber(self): |
| 160 files = { |
| 161 '/fake_src/out/Debug': None, |
| 162 '/fake_src/out/Debug/mb_type': None, |
| 163 } |
| 164 mbw = self.fake_mbw(files) |
| 165 |
| 166 # The first time we run this, the build dir doesn't exist, so no clobber. |
| 167 self.check(['gen', '-c', 'gn_debug', '//out/Debug'], mbw=mbw, ret=0) |
| 168 self.assertEqual(mbw.rmdirs, []) |
| 169 self.assertTrue(mbw.files['/fake_src/out/Debug/mb_type'], 'gn') |
| 170 |
| 171 # The second time we run this, the build dir exists and matches, so no |
| 172 # clobber. |
| 173 self.check(['gen', '-c', 'gn_debug', '//out/Debug'], mbw=mbw, ret=0) |
| 174 self.assertEqual(mbw.rmdirs, []) |
| 175 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gn') |
| 176 |
| 177 # Now we switch build types; this should result in a clobber. |
| 178 self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0) |
| 179 self.assertEqual(mbw.rmdirs, ['/fake_src/out/Debug']) |
| 180 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp') |
| 181 |
| 182 # Now we delete mb_type; this checks the case where the build dir |
| 183 # exists but wasn't populated by mb; this should also result in a clobber. |
| 184 del mbw.files['/fake_src/out/Debug/mb_type'] |
| 185 self.check(['gen', '-c', 'gyp_debug', '//out/Debug'], mbw=mbw, ret=0) |
| 186 self.assertEqual(mbw.rmdirs, |
| 187 ['/fake_src/out/Debug', '/fake_src/out/Debug']) |
| 188 self.assertEqual(mbw.files['/fake_src/out/Debug/mb_type'], 'gyp') |
| 189 |
149 def test_gn_analyze(self): | 190 def test_gn_analyze(self): |
150 files = {'/tmp/in.json': """{\ | 191 files = {'/tmp/in.json': """{\ |
151 "files": ["foo/foo_unittest.cc"], | 192 "files": ["foo/foo_unittest.cc"], |
152 "targets": ["foo_unittests", "bar_unittests"] | 193 "targets": ["foo_unittests", "bar_unittests"] |
153 }"""} | 194 }"""} |
154 | 195 |
155 mbw = self.fake_mbw(files) | 196 mbw = self.fake_mbw(files) |
156 mbw.Call = lambda cmd, env=None: (0, 'out/Default/foo_unittests\n', '') | 197 mbw.Call = lambda cmd, env=None: (0, 'out/Default/foo_unittests\n', '') |
157 | 198 |
158 self.check(['analyze', '-c', 'gn_debug', '//out/Default', | 199 self.check(['analyze', '-c', 'gn_debug', '//out/Default', |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 finally: | 316 finally: |
276 sys.stdout = orig_stdout | 317 sys.stdout = orig_stdout |
277 | 318 |
278 | 319 |
279 def test_validate(self): | 320 def test_validate(self): |
280 self.check(['validate'], ret=0) | 321 self.check(['validate'], ret=0) |
281 | 322 |
282 | 323 |
283 if __name__ == '__main__': | 324 if __name__ == '__main__': |
284 unittest.main() | 325 unittest.main() |
OLD | NEW |