def test_recompute_inputs_even_if_mtime_doesnt_change(self): cr = compile_rule.find_compile_rule('genfiles/a.ii') self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h', 'a1'], cr.input_files('genfiles/a.ii')) # modify includes/a.h without modifying its mtime mtime = os.path.getmtime(self._abspath('a.h')) self._write_to('a.h', '#include "includes/d.h" // change the include') os.utime(self._abspath('a.h'), (mtime, mtime)) filemod_db.clear_mtime_cache() self.assertEqual(['a.c', 'a.h', 'includes/d.h', 'a1'], cr.input_files('genfiles/a.ii'))
def test_computed_inputs_from_file(self): self._write_to('a1', 'a1,a2,genfiles/fnumber') cr = compile_rule.find_compile_rule('genfiles/computed_inputs/content') self.assertEqual(['a1', 'a2', 'genfiles/fnumber'], cr.input_files('genfiles/computed_inputs/content')) self._write_to('a1', 'b1,genfiles/fletter') filemod_db.clear_mtime_cache() with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual( ['b1', 'genfiles/fletter'], cr.input_files('genfiles/computed_inputs/content'))
def test_trigger_changes(self): cr = compile_rule.find_compile_rule('genfiles/computed_inputs/static') with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/static')) # a1 is one of the trigger files for this rule. self._write_to('a1', '') filemod_db.clear_mtime_cache() with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/static'))
def test_generated_trigger_files(self): # To avoid having build() calls in # computed_inputs, it assumes that all the # trigger files are built as part of a build call. We're # interested in inspecting the results of the input_files() # call here, so we need to make sure all the trigger files are # already built kake.make.build('genfiles/yelling.genii') cr = compile_rule.find_compile_rule('genfiles/yelling.genii') self.assertEqual([ 'genfiles/godzilla.c', 'genfiles/vuvuzela.c', 'genfiles/yelling.c' ], cr.input_files('genfiles/yelling.genii'))
def test_var_with_underscore(self): # Testing {var_with_underscore} compile_rule.register_compile( 'VAR WITH UNDERSCORE', 'genfiles/us/{var_with_underscore}.js', ['{var_with_underscore}2'], self.rev_compile) cr = compile_rule.find_compile_rule( 'genfiles/us/foo.js') self.assertNotEqual(None, cr) self.assertEqual({'{var_with_underscore}': 'foo'}, cr.var_values('genfiles/us/foo.js'))
def test_find_compile_rule_prefers_more_directory_parts(self): # Something that uses two vs three directory parts compile_rule.register_compile( 'TWO DIRS', 'genfiles/{{path}}_copy_2', ['{{path}}2'], self.copy_compile) compile_rule.register_compile( 'THREE DIRS', 'genfiles/subdir/{{path}}_copy_2', ['genfiles/subdir/{{path}}2'], self.rev_compile) cr = compile_rule.find_compile_rule( 'genfiles/make_a_copy_2') self.assertEqual('genfiles/{{path}}_copy_2', cr.output_pattern) cr = compile_rule.find_compile_rule( 'genfiles/whatever/make_a_copy_2') self.assertEqual('genfiles/{{path}}_copy_2', cr.output_pattern) cr = compile_rule.find_compile_rule( 'genfiles/subdir/make_a_copy_2') self.assertEqual('genfiles/subdir/{{path}}_copy_2', cr.output_pattern)
def test_current_inputs(self): cr = compile_rule.find_compile_rule('genfiles/computed_inputs/curr') self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/curr')) self.assertEqual( ['a1', 'a2'], cr.input_trigger_files('genfiles/computed_inputs/curr')) self._write_to('a1', '') filemod_db.clear_mtime_cache() with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/curr'))
def test_include_cache(self): cr = compile_rule.find_compile_rule('genfiles/a.ii') self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h', 'a1'], cr.input_files('genfiles/a.ii')) self._write_to('includes/b.h', '#include "d.h" /* new include */ \n') filemod_db.clear_mtime_cache() with mock.patch('kake.log.v3') as logger: actual = cr.input_files('genfiles/a.ii') self.assertEqual([ mock.call('extracting includes from %s', 'includes/b.h'), mock.call('extracting includes from %s', 'includes/d.h') ], logger.call_args_list) self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/d.h', 'a1'], actual)
def test_force(self): cr = compile_rule.find_compile_rule('genfiles/computed_inputs/static') with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/static')) # num_calls still be 1 this time because we are forcing it with self.assertCalled(cr.input_patterns.input_patterns, 0): self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/static')) # num_calls still be 1 this time because we are forcing it with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/static', force=True))
def test_generated_trigger_files_immediate(self): # To avoid having build() calls in computed_inputs, it assumes that all # the trigger files are built as part of a build call. We're interested # in inspecting the results of the input_files() call here, so we need # to make sure all the trigger files are already built build._immediate_build(['genfiles/yelling.genii'], context={}, caller=None, already_built=set(), timing_map={}, force=True) cr = compile_rule.find_compile_rule('genfiles/yelling.genii') self.assertEqual([ 'genfiles/yelling.c', 'genfiles/vuvuzela.c', 'genfiles/godzilla.c' ], cr.input_files('genfiles/yelling.genii'))
def _build_many(self, *outfile_names): build_many_args = [] compile_instance = None for outfile_name in outfile_names: cr = compile_rule.find_compile_rule(outfile_name) if compile_instance is None: compile_instance = cr.compile_instance else: # All of the outfiles must share the same compile instance self.assertEqual(compile_instance.__class__, cr.compile_instance.__class__) var_values = cr.var_values(outfile_name) input_filenames = cr.input_files(outfile_name, var_values) build_many_args.append((outfile_name, input_filenames, [outfile_name], var_values)) compile_instance.build_many(build_many_args)
def test_version_change_forces_full_rebuild(self): cr = compile_rule.find_compile_rule('genfiles/a.ii') self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h', 'a1'], cr.input_files('genfiles/a.ii')) with mock.patch.object(self.includer, 'version', lambda: 2): with mock.patch('kake.log.v3') as logger: actual = cr.input_files('genfiles/a.ii') self.assertEqual([ mock.call('extracting includes from %s', 'a.c'), mock.call('extracting includes from %s', 'a.h'), mock.call('extracting includes from %s', 'includes/b.h'), mock.call('extracting includes from %s', 'includes/c.h') ], logger.call_args_list) self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h', 'a1'], actual)
def test_trigger_depends_on_output(self): cr = compile_rule.find_compile_rule('genfiles/computed_inputs/b2') with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a2'], cr.input_files('genfiles/computed_inputs/b2')) self._write_to('b2', '') filemod_db.clear_mtime_cache() with self.assertCalled(cr.input_patterns.input_patterns, 1): self.assertEqual(['a2'], cr.input_files('genfiles/computed_inputs/b2')) # But if we touch b1, it doesn't cause a new call self._write_to('b1', '') filemod_db.clear_mtime_cache() with self.assertCalled(cr.input_patterns.input_patterns, 0): self.assertEqual(['a2'], cr.input_files('genfiles/computed_inputs/b2'))
def test_recompute_inputs_when_var_changes(self): cr = compile_rule.find_compile_rule('genfiles/a.varii') with self.assertCalled(cr.input_patterns.resolve_includee_path, 5): self.assertEqual( ['magic.c', 'a.h', 'includes/b.h', 'includes/c.h'], list(cr.input_trigger_files('genfiles/a.varii'))) with self.assertCalled(cr.input_patterns.resolve_includee_path, 1): self.assertEqual(['magic.c', 'includes/d.h'], list(cr.input_trigger_files('genfiles/d.varii'))) # Both sets of contexts should be in the include cache now with self.assertCalled(cr.input_patterns.resolve_includee_path, 0): self.assertEqual( ['magic.c', 'a.h', 'includes/b.h', 'includes/c.h'], list(cr.input_trigger_files('genfiles/a.varii'))) with self.assertCalled(cr.input_patterns.resolve_includee_path, 0): self.assertEqual(['magic.c', 'includes/d.h'], list(cr.input_trigger_files('genfiles/d.varii')))
def test_recompute_inputs_when_a_bad_include_is_fixed(self): # Have a.c have a bad include. self._write_to( 'a.c', '#include <stdio.h>\n' '#include "includes/non_existent_file.h"\n' 'int main() { return 0; }\n') cr = compile_rule.find_compile_rule('genfiles/a.ii') with self.assertRaises(IOError): # 'file not found' cr.input_files('genfiles/a.ii') # Now fix up a.c. self._write_to( 'a.c', '#include <stdio.h>\n' '#include "a.h"\n' 'int main() { return 0; }\n') filemod_db.clear_mtime_cache() # We should be able to calculate the new trigger files, even # though the last, failed request cached a non-existent file. self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h'], list(cr.input_trigger_files('genfiles/a.ii')))
def test_var_values(self): cr = compile_rule.find_compile_rule('genfiles/i_number_1') self.assertEqual({'{number}': '1'}, cr.var_values('genfiles/i_number_1')) cr = compile_rule.find_compile_rule('genfiles/i_number_2') self.assertEqual({'{number}': '2'}, cr.var_values('genfiles/i_number_2')) cr = compile_rule.find_compile_rule('genfiles/i_number_3') self.assertEqual({}, cr.var_values('genfiles/i_number_3')) cr = compile_rule.find_compile_rule('genfiles/both_a_1') self.assertEqual({ '{number}': '1', '{letter}': 'a' }, cr.var_values('genfiles/both_a_1')) cr = compile_rule.find_compile_rule('genfiles/path/subpath/foo.js') self.assertEqual({'{{path}}': 'subpath/foo'}, cr.var_values('genfiles/path/subpath/foo.js')) cr = compile_rule.find_compile_rule('genfiles/dir/bar.js') self.assertEqual({'{path}': 'bar'}, cr.var_values('genfiles/dir/bar.js'))
def test_regexp_has_two_groups(self): cr = compile_rule.find_compile_rule('genfiles/a.fullii') self.assertEqual( ['a.c', 'a.h', 'stdio.h', 'includes/b.h', 'includes/c.h'], list(cr.input_trigger_files('genfiles/a.fullii')))
def _build(self, outfile_name): cr = compile_rule.find_compile_rule(outfile_name) var_values = cr.var_values(outfile_name) # the {var}'s. input_filenames = cr.input_files(outfile_name, var_values) cr.compile_instance.build(outfile_name, input_filenames, [outfile_name], var_values)
def test_find_compile_rule(self): cr = compile_rule.find_compile_rule( 'genfiles/i_letter_a') self.assertEqual('genfiles/i_letter_{letter}', cr.output_pattern) cr = compile_rule.find_compile_rule('genfiles/fmost') self.assertEqual('genfiles/fmost', cr.output_pattern)
def test_duplicated_includes(self): cr = compile_rule.find_compile_rule('genfiles/double_include.ii') self.assertEqual( ['a.h', 'double_include.c', 'includes/b.h', 'includes/c.h', 'a1'], cr.input_files('genfiles/double_include.ii'))
def test_current_inputs(self): cr = compile_rule.find_compile_rule('genfiles/computed_inputs/curr') # Should be empty because CURRENT_INPUTS is empty. self.assertEqual( [], cr.input_trigger_files('genfiles/computed_inputs/curr'))
def test_computes_inputs(self): cr = compile_rule.find_compile_rule('genfiles/computed_inputs/static') self.assertEqual(['a1', 'a2'], cr.input_files('genfiles/computed_inputs/static'))
def test_other_inputs_not_in_triggers(self): cr = compile_rule.find_compile_rule('genfiles/a.ii') self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h', 'a1'], cr.input_files('genfiles/a.ii')) self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h'], list(cr.input_trigger_files('genfiles/a.ii')))
def test_does_not_normalize(self): cr = compile_rule.find_compile_rule( 'genfiles/computed_inputs/unnormalized') self.assertEqual( ['genfiles/../a1', 'genfiles/../a2'], cr.input_files('genfiles/computed_inputs/unnormalized'))
def test_maybe_symlink_to(self): cr = compile_rule.find_compile_rule('genfiles/both_a_1') self.assertEqual('a1', cr.maybe_symlink_to('genfiles/both_a_1')) cr = compile_rule.find_compile_rule('genfiles/i_number_2') self.assertEqual(None, cr.maybe_symlink_to('genfiles/i_number_2'))
def test_simple(self): cr = compile_rule.find_compile_rule('genfiles/a.ii') self.assertEqual(['a.c', 'a.h', 'includes/b.h', 'includes/c.h', 'a1'], cr.input_files('genfiles/a.ii'))