1 #!/usr/bin/python 2 3 # Copyright 2014 Google Inc. 4 # 5 # Use of this source code is governed by a BSD-style license that can be 6 # found in the LICENSE file. 7 8 """ 9 Test makefile_writer.py 10 """ 11 12 import argparse 13 import os 14 import shutil 15 import sys 16 import tempfile 17 import test_variables 18 import unittest 19 import utils 20 21 sys.path.append(test_variables.GYP_GEN_DIR) 22 23 import makefile_writer 24 import tool_makefile_writer 25 import vars_dict_lib 26 27 MAKEFILE_NAME = test_variables.ANDROID_MK 28 REBASELINE_MSG = ('If you\'ve modified makefile_writer.py, run ' 29 '"makefile_writer_tests.py --rebaseline" to rebaseline') 30 TOOL_DIR = 'tool' 31 32 def generate_dummy_vars_dict(name): 33 """Create a VarsDict and fill it with dummy entries. 34 35 Args: 36 name: string to be appended to each entry, if not None. 37 38 Returns: 39 A VarsDict with dummy entries. 40 """ 41 vars_dict = vars_dict_lib.VarsDict() 42 for key in vars_dict.keys(): 43 entry = key.lower() 44 if name: 45 entry += '_' + name 46 vars_dict[key].add(entry) 47 return vars_dict 48 49 def generate_write_local_vars_params(): 50 """Generator to compute params for write_local_vars tests. 51 52 Each iteration yields a new tuple: (filename, append, name), specific to a 53 way to call write_local_vars for the tests. 54 55 Yields: 56 filename: filename corresponding to the expectation file for this 57 combination of params to write_local_vars. 58 append: boolean to pass as append parameter to write_local_vars. 59 name: string to pass as name parameter to write_local_vars. 60 """ 61 for append in [ True, False ]: 62 for name in [ None, 'arm', 'foo' ]: 63 filename = 'write_local_vars' 64 if append: 65 filename += '_append' 66 else: 67 filename += '_no_append' 68 if name: 69 filename += '_' + name 70 else: 71 filename += '_no_name' 72 73 yield (filename, append, name) 74 75 def generate_dummy_vars_dict_data(name, condition): 76 """Create a dummy VarsDictData. 77 78 Create a dummy VarsDictData, using the name for both the contained 79 VarsDict and the VarsDictData 80 81 Args: 82 name: name used by both the returned VarsDictData and its contained 83 VarsDict. 84 condition: condition used by the returned VarsDictData. 85 86 Returns: 87 A VarsDictData with dummy values, using the passed in info. 88 """ 89 vars_dict = generate_dummy_vars_dict(name) 90 91 return makefile_writer.VarsDictData(vars_dict=vars_dict, name=name, 92 condition=condition) 93 94 95 def generate_dummy_makefile(target_dir): 96 """Create a dummy makefile to demonstrate how it works. 97 98 Use dummy values unrelated to any gyp files. Its output should remain the 99 same unless/until makefile_writer.write_android_mk changes. 100 101 Args: 102 target_dir: directory in which to write the resulting Android.mk 103 """ 104 common_vars_dict = generate_dummy_vars_dict(None) 105 106 deviation_params = [('foo', 'COND'), ('bar', None)] 107 deviations = [generate_dummy_vars_dict_data(name, condition) 108 for (name, condition) in deviation_params] 109 110 makefile_writer.write_android_mk(target_dir=target_dir, 111 common=common_vars_dict, 112 deviations_from_common=deviations) 113 114 def generate_dummy_static_deps_makefile(target_dir): 115 """Create a dummy makefile that prints out the static dependencies. 116 117 Use dummy values unrelated to any gyp files. Its output should remain the 118 same unless/until makefile_writer.write_static_deps_mk changes. 119 120 Args: 121 target_dir: directory in which to write the resulting file 122 """ 123 common_vars_dict = generate_dummy_vars_dict(None) 124 125 deviation_params = [('foo', 'COND'), ('bar', None)] 126 deviations = [generate_dummy_vars_dict_data(name, condition) 127 for (name, condition) in deviation_params] 128 129 makefile_writer.write_static_deps_mk(target_dir=target_dir, 130 common=common_vars_dict, 131 deviations_from_common=deviations) 132 133 def generate_dummy_tool_makefile(target_dir): 134 """Create a dummy makefile for a tool. 135 136 Args: 137 target_dir: directory in which to write the resulting Android.mk 138 """ 139 vars_dict = generate_dummy_vars_dict(None) 140 tool_makefile_writer.write_tool_android_mk(target_dir=target_dir, 141 var_dict=vars_dict) 142 143 144 class MakefileWriterTest(unittest.TestCase): 145 146 def test_write_group_empty(self): 147 f = tempfile.TemporaryFile() 148 assert f.tell() == 0 149 for empty in (None, []): 150 for truth in (True, False): 151 makefile_writer.write_group(f, 'name', empty, truth) 152 self.assertEqual(f.tell(), 0) 153 f.close() 154 155 def test_write_group(self): 156 animals = ('dog', 'cat', 'mouse', 'elephant') 157 fd, filename = tempfile.mkstemp() 158 with open(filename, 'w') as f: 159 makefile_writer.write_group(f, 'animals', animals, False) 160 os.close(fd) 161 # Now confirm that it matches expectations 162 utils.compare_to_expectation(filename, 'animals.txt', self.assertTrue) 163 164 with open(filename, 'w') as f: 165 makefile_writer.write_group(f, 'animals_append', animals, True) 166 # Now confirm that it matches expectations 167 utils.compare_to_expectation(filename, 'animals_append.txt', 168 self.assertTrue) 169 os.remove(filename) 170 171 def test_write_local_vars(self): 172 vars_dict = generate_dummy_vars_dict(None) 173 # Compare various ways of calling write_local_vars to expectations. 174 for (filename, append, name) in generate_write_local_vars_params(): 175 fd, outfile = tempfile.mkstemp() 176 with open(outfile, 'w') as f: 177 makefile_writer.write_local_vars(f, vars_dict, append, name) 178 os.close(fd) 179 180 # Compare to the expected file. 181 utils.compare_to_expectation(outfile, filename, self.assertTrue, 182 REBASELINE_MSG) 183 184 # KNOWN_TARGETS is always a key in the input VarsDict, but it should not 185 # be written to the resulting file. 186 # Note that this assumes none of our dummy entries is 'KNOWN_TARGETS'. 187 known_targets_name = 'KNOWN_TARGETS' 188 self.assertEqual(len(vars_dict[known_targets_name]), 1) 189 190 with open(outfile, 'r') as f: 191 self.assertNotIn(known_targets_name, f.read()) 192 os.remove(outfile) 193 194 def test_write_android_mk(self): 195 outdir = tempfile.mkdtemp() 196 generate_dummy_makefile(outdir) 197 198 utils.compare_to_expectation(os.path.join(outdir, MAKEFILE_NAME), 199 MAKEFILE_NAME, self.assertTrue, REBASELINE_MSG) 200 201 shutil.rmtree(outdir) 202 203 def test_include_static_deps_writer(self): 204 outdir = tempfile.mkdtemp() 205 generate_dummy_static_deps_makefile(outdir) 206 207 filename = test_variables.STATIC_DEPS_MK 208 utils.compare_to_expectation(os.path.join(outdir, filename), 209 filename, self.assertTrue, REBASELINE_MSG) 210 211 def test_tool_writer(self): 212 outdir = tempfile.mkdtemp() 213 tool_dir = os.path.join(outdir, TOOL_DIR) 214 os.mkdir(tool_dir) 215 generate_dummy_tool_makefile(tool_dir) 216 217 utils.compare_to_expectation(os.path.join(tool_dir, MAKEFILE_NAME), 218 os.path.join(TOOL_DIR, MAKEFILE_NAME), 219 self.assertTrue, REBASELINE_MSG) 220 221 def main(): 222 loader = unittest.TestLoader() 223 suite = loader.loadTestsFromTestCase(MakefileWriterTest) 224 results = unittest.TextTestRunner(verbosity=2).run(suite) 225 print repr(results) 226 if not results.wasSuccessful(): 227 raise Exception('failed one or more unittests') 228 229 230 def rebaseline(): 231 generate_dummy_makefile(utils.EXPECTATIONS_DIR) 232 233 vars_dict = generate_dummy_vars_dict(None) 234 for (filename, append, name) in generate_write_local_vars_params(): 235 with open(os.path.join(utils.EXPECTATIONS_DIR, filename), 'w') as f: 236 makefile_writer.write_local_vars(f, vars_dict, append, name) 237 238 generate_dummy_static_deps_makefile(utils.EXPECTATIONS_DIR) 239 generate_dummy_tool_makefile(os.path.join(utils.EXPECTATIONS_DIR, TOOL_DIR)) 240 241 242 if __name__ == '__main__': 243 parser = argparse.ArgumentParser() 244 parser.add_argument('-r', '--rebaseline', help='Rebaseline expectations.', 245 action='store_true') 246 args = parser.parse_args() 247 248 if args.rebaseline: 249 rebaseline() 250 else: 251 main() 252 253