Home | History | Annotate | Download | only in tests
      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