def test_gen_and_regen(self): content = "foo" output = self.from_build_dir("out") manifest_path = self.create_simple_echo_manifest(content, output) self.assertFalse(os.path.exists(output)) ### 1st run. Generates the manifest self.take_fs_snapshot() samurai = self.samurai("-p", manifest_path, self.build_dir()) self.assertProcReturn(samurai, 0) self.pdbg("========= build.ninja") self.pdbg(read_file(self.build_ninja_file())) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED}, "ninja files not generated") ### 2nd run. Build outputs. ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertEqual(read_file(output), content+"\n") self.assertFSDiff({output:FSDiffOp.CREATED}, "output file not built") ### 3rd run: nothing to do ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "ninja modified something") ### 4th run: touched manifest trigger regeneration by ninja time.sleep(1) touch(manifest_path) self.assertFSDiff({manifest_path:FSDiffOp.UPDATED}, "samurai manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.pdbg("========= ninja output") self.pdbg(ninja.stdout) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED}, "ninja manifest not regenerated")
def test_build_cascade_targets(self): input1 = os.path.join(self.tmpdir, "f.in") output1 = self.from_build_dir("f.out1") output2 = self.from_build_dir("f.out2") fs = self.create_fs_tree({ "f.in": "line1\n", self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.test.fixture import Fixture Prefix = Fixture.Prefix() samurai_ctxt.add(Prefix(input={input1!r}, output={output1!r})) samurai_ctxt.add(Prefix(input={output1!r}, output={output2!r})) """.format(input1=input1, output1=output1, output2=output2)), }) ### 1st run. Generates the manifest self.take_fs_snapshot() samurai = self.samurai("-p", fs[self.MANIFEST_FILENAME], self.build_dir()) self.assertProcReturn(samurai, 0) self.pdbg("========= build.ninja") self.pdbg(read_file(self.build_ninja_file())) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED}, "ninja files not generated") ### 2nd run. Build outputs. ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({output1:FSDiffOp.CREATED, output2:FSDiffOp.CREATED}, "output files not built") self.assertEqual(read_file(output1), "prefix:line1\n") self.assertEqual(read_file(output2), "prefix:prefix:line1\n") ### 3rd run: nothing to do ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "ninja modified something") ### 4th run: touch input file triggers rebuild of two outputs. time.sleep(1) touch(input1) self.assertFSDiff({input1:FSDiffOp.UPDATED}, "input1 file not touched") ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({output1:FSDiffOp.UPDATED, output2:FSDiffOp.UPDATED}, "output files not re-built")
def test_relative_to_build_dir(self): self.dump(Fixture.Filter()( input=os.path.join(self.build_dir(), "file.in"), output=os.path.join(self.build_dir(), "file.out"))) build_content = read_file(self.dumper.build_pathname()) self.assertRegex( build_content, re.compile(r"^build file.out: r0 file.in | /path/to/filter$", re.MULTILINE))
def test_reload_after_regen(self): content1 = "foo1" output1 = self.from_build_dir("out1") manifest_path = self.create_simple_echo_manifest(content1, output1) ### 1st run. Generates the manifest self.take_fs_snapshot() samurai = self.samurai("-p", manifest_path, self.build_dir()) self.assertProcReturn(samurai, 0) self.pdbg("========= build.ninja") self.pdbg(read_file(self.build_ninja_file())) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED}, "ninja files not generated") ### 2nd run. Build outputs. ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({output1:FSDiffOp.CREATED}, "output1 file not built") self.assertEqual(read_file(output1), content1+"\n") ### 3rd run: nothing to do ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "ninja modified something") ### 4th run: add new target in manifest trigger regeneration by ninja ### and build the new target time.sleep(1) content2 = "foo2" output2 = self.from_build_dir("out2") with open(manifest_path, "a") as stream: stream.write( "samurai_ctxt.add(Echo(text={text!r}, output={output!r}))\n" .format(text=content2, output=output2)) self.assertFSDiff({manifest_path:FSDiffOp.UPDATED}, "samurai manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.pdbg("========= ninja output") self.pdbg(ninja.stdout) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED, output2:FSDiffOp.CREATED}, "ninja manifest not regenerated or " "new target not rebuilt") self.assertEqual(read_file(output2), content2+"\n")
def test_relative_to_top_build_dir(self): assert self.build_dir().startswith(self.tmpdir) self.dumper = NinjaDumper(self.build_dir(), top_build_dir=self.tmpdir) self.dump(Fixture.Filter()( input=os.path.join(self.build_dir(), "file.in"), output=os.path.join(self.build_dir(), "file.out"))) build_content = read_file(self.dumper.build_pathname()) self.assertRegex( build_content, re.compile(r"^build _build/file.out: r0 _build/file.in " "| /path/to/filter$", re.MULTILINE))
def test_interrupted_regen(self): content = "foo" output = self.from_build_dir("out") manifest_path = self.create_simple_echo_manifest(content, output) self.assertFalse(os.path.exists(output)) ### 1st: Generates the manifest. self.take_fs_snapshot() samurai = self.samurai("-p", manifest_path, self.build_dir()) self.assertProcReturn(samurai, 0) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED}, "ninja files not generated") self.assertFalse(os.path.exists(output)) ### 2nd: Generates the output. ninja = self.ninja("-C", self.build_dir()) self.assertEqual(read_file(output), content+"\n") self.assertFSDiff({output:FSDiffOp.CREATED}, "output file not built") ### 3nd: Ninja has nothing to do ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "nothing has changed") ### 4th: an error is introduced in the manifest, triggering the ### regeneration which fails. time.sleep(1) # ninja mtime use second precision errmsg = "on-purpose error from manifest" with open(manifest_path, "a") as stream: stream.write(textwrap.dedent(""" raise RuntimeError({errmsg!r}) """.format(errmsg=errmsg))) self.assertFSDiff({manifest_path:FSDiffOp.UPDATED}, "samurai manifest not modified") # exception will be not raised because samurai is triggered by ninja, # not by this process. self.ninja("-C", self.build_dir()) self.assertFSDiff({self.build_ninja_file()+".part":FSDiffOp.CREATED, self.decl_ninja_file()+".part":FSDiffOp.CREATED}, "ninja part files are generated") ### 5th: Fix the error by regenerating the original samurai's manifest. ### Ninja must regenerate its manifest successfully time.sleep(1) # ninja mtime use second precision manifest_path = self.create_simple_echo_manifest(content, output) self.assertFSDiff({manifest_path:FSDiffOp.UPDATED}, "samurai manifest not modified") self.ninja("-C", self.build_dir()) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED, self.build_ninja_file()+".part":FSDiffOp.DELETED, self.decl_ninja_file()+".part":FSDiffOp.DELETED}, "ninja files not regenerated") ### 6th: Ninja has nothing to do ninja = self.ninja("-C", self.build_dir()) self.assertFSDiff({}, "ninja modified something")
def test_basic(self): manifest = os.path.join(self.tmpdir, "sub", "manifest") mkdir_p(os.path.dirname(manifest)) write_file(manifest, "") build_dir = os.path.join(self.build_dir(), "sub") s = SubSamurai(manifest, build_dir) s.generate = MagicMock() self.dump(s) s.generate.assert_called_once_with() build_content = read_file(self.dumper.build_pathname()) self.assertRegex(build_content, re.compile(r"^# SubSamurai sub-project from", re.MULTILINE)) self.assertRegex(build_content, re.compile(r"^#.*'{manifest}'$" .format(manifest=manifest), re.MULTILINE)) self.assertRegex(build_content, re.compile(r"^subninja {build_dir}/build.ninja\n" .format(build_dir=build_dir), re.MULTILINE)) self.assertEqual(self.dumper.rule_count, 0) self.assertEqual(self.dumper.build_count, 0) self.assertEqual(self.dumper.subgenerator_count, 1)
def print_decl_ninja_file(self): """Useful for debugging.""" print(read_file(self.decl_ninja_file()))
def print_build_ninja_file(self): """Useful for debugging.""" print(read_file(self.build_ninja_file()))
def test_subgen(self): content1 = "foo1" sub_content1 = "sub foo1" output1 = self.from_build_dir("out1") sub_output1 = self.from_build_dir("sub", "out1") fs = self.create_fs_tree({ self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.subgenerator import SubSamurai from samurai.test.fixture import Fixture samurai_ctxt.add(SubSamurai("{manifest}", "{build_dir}/sub")) Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=content1, output=output1, manifest=os.path.join(self.tmpdir, "sub", self.MANIFEST_FILENAME), build_dir=self.build_dir())), "sub": { self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.test.fixture import Fixture Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=sub_content1, output=sub_output1)), }, }) sub_build_ninja_file = self.from_build_dir("sub", config.BUILD_FILENAME) sub_decl_ninja_file = self.from_build_dir("sub", config.DECL_FILENAME) self.pdbg("====== manifest") self.pdbg(read_file(fs[self.MANIFEST_FILENAME])) ### 1st run: generates both projects. self.pdbg("====== #1") self.take_fs_snapshot() samurai = self.samurai("-C", self.tmpdir, "-p", self.MANIFEST_FILENAME, self.BUILD_DIR) self.assertProcReturn(samurai, 0) self.pdbg("====== build.ninja") self.pdbg(read_file(self.build_ninja_file())) self.pdbg("====== sub/build.ninja") self.pdbg(read_file(sub_build_ninja_file)) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED, sub_build_ninja_file:FSDiffOp.CREATED, sub_decl_ninja_file:FSDiffOp.CREATED}, "all ninja files not generated") ### 2nd run: build outputs self.pdbg("====== #2") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({output1:FSDiffOp.CREATED, sub_output1:FSDiffOp.CREATED}, "output1 and sub_output1 not built") self.assertEqual(read_file(output1), content1+"\n") self.assertEqual(read_file(sub_output1), sub_content1+"\n") ### 3rd run: nothing to do self.pdbg("====== #3") ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "nothing has changed") ### 4th run: change sub output name self.pdbg("====== #4") sub_content2 = "sub foo2" sub_output2 = self.from_build_dir("sub", "out2") time.sleep(1) write_file(fs['sub'][self.MANIFEST_FILENAME], textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.test.fixture import Fixture Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=sub_content2, output=sub_output2))) self.assertFSDiff({fs['sub'][self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "sub samurai's manifest not updated") ### 5th run: rebuild outputs self.pdbg("====== #5") ninja = self.ninja("-C", self.build_dir()) self.pdbg("====== ninja output") self.pdbg(ninja.stdout) self.assertProcReturn(ninja, 0) self.assertFSDiff({sub_output1:FSDiffOp.DELETED, sub_output2:FSDiffOp.CREATED, sub_build_ninja_file:FSDiffOp.UPDATED, sub_decl_ninja_file:FSDiffOp.UPDATED}, "rebuild failed") ### 6th run: change both output file name self.pdbg("====== #6") content2 = "foo2" output2 = self.from_build_dir("out2") sub_content3 = "sub foo3" sub_output3 = self.from_build_dir("sub", "out3") time.sleep(1) write_file(fs[self.MANIFEST_FILENAME], textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.subgenerator import SubSamurai from samurai.test.fixture import Fixture samurai_ctxt.add(SubSamurai("{manifest}", "{build_dir}/sub")) Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=content2, output=output2, manifest=os.path.join(self.tmpdir, "sub", self.MANIFEST_FILENAME), build_dir=self.build_dir()))) write_file(fs['sub'][self.MANIFEST_FILENAME], textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.test.fixture import Fixture Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=sub_content3, output=sub_output3))) self.assertFSDiff({fs[self.MANIFEST_FILENAME]:FSDiffOp.UPDATED, fs['sub'][self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "both samurai's manifest not updated") ### 7th run: rebuild outputs self.pdbg("====== #7") ninja = self.ninja("-C", self.build_dir()) self.pdbg("====== ninja output") self.pdbg(ninja.stdout) self.assertProcReturn(ninja, 0) self.assertFSDiff({sub_output2:FSDiffOp.DELETED, sub_output3:FSDiffOp.CREATED, output1:FSDiffOp.DELETED, output2:FSDiffOp.CREATED, self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED, sub_build_ninja_file:FSDiffOp.UPDATED, sub_decl_ninja_file:FSDiffOp.UPDATED}, "rebuild failed")
def test_reload_after_regen(self): content1 = "foo1" sub_content1 = "sub foo1" output1 = self.from_build_dir("out1") sub_output1 = self.from_build_dir("sub", "out1") fs = self.create_fs_tree({ self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.subgenerator import SubSamurai from samurai.test.fixture import Fixture samurai_ctxt.add(SubSamurai("{manifest}", "{build_dir}/sub")) Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=content1, output=output1, manifest=os.path.join(self.tmpdir, "sub", self.MANIFEST_FILENAME), build_dir=self.build_dir())), "sub": { self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.test.fixture import Fixture Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=sub_content1, output=sub_output1)), }, }) sub_build_ninja_file = self.from_build_dir("sub", config.BUILD_FILENAME) sub_decl_ninja_file = self.from_build_dir("sub", config.DECL_FILENAME) self.pdbg("====== manifest") self.pdbg(read_file(fs[self.MANIFEST_FILENAME])) ### 1st run: generates and build both projects. self.pdbg("====== #1") self.take_fs_snapshot() samurai = self.samurai("-C", self.tmpdir, "-p", self.MANIFEST_FILENAME, self.BUILD_DIR) self.assertProcReturn(samurai, 0) self.pdbg("====== build.ninja") self.pdbg(read_file(self.build_ninja_file())) self.pdbg("====== sub/build.ninja") self.pdbg(read_file(sub_build_ninja_file)) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED, sub_build_ninja_file:FSDiffOp.CREATED, sub_decl_ninja_file:FSDiffOp.CREATED}, "all ninja files not generated") ### 2nd run: build outputs self.pdbg("====== #2") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({output1:FSDiffOp.CREATED, sub_output1:FSDiffOp.CREATED}, "output1 and sub_output1 not built") self.assertEqual(read_file(output1), content1+"\n") self.assertEqual(read_file(sub_output1), sub_content1+"\n") ### 3rd run: nothing to do self.pdbg("====== #3") ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "nothing has changed") ### 4th run: add new target in sub-manifest makes ninja regenerates ### only the sub-project and build the new target self.pdbg("====== #4") time.sleep(1) sub_content2 = "sub foo2" sub_output2 = self.from_build_dir("sub", "out2") with open(fs["sub"][self.MANIFEST_FILENAME], "a") as stream: stream.write( "samurai_ctxt.add(Echo(text={text!r}, output={output!r}))\n" .format(text=sub_content2, output=sub_output2)) self.assertFSDiff({fs["sub"][self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "samurai sub-manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({sub_build_ninja_file:FSDiffOp.UPDATED, sub_decl_ninja_file:FSDiffOp.UPDATED, sub_output2:FSDiffOp.CREATED}, "sub ninja files not re-generated or " "new target not built") self.assertEqual(read_file(sub_output2), sub_content2+"\n") ### 5th run: add new target in top manifest makes ninja regenerates ### only its top manifest but not the one of the sub-projects ### and build the new target. self.pdbg("====== #5") time.sleep(1) content2 = "foo2" output2 = self.from_build_dir("out2") with open(fs[self.MANIFEST_FILENAME], "a") as stream: stream.write( "samurai_ctxt.add(Echo(text={text!r}, output={output!r}))\n" .format(text=content2, output=output2)) self.assertFSDiff({fs[self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "samurai top manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED, output2:FSDiffOp.CREATED}, "ninja files not re-generated or " "new target not built") self.assertEqual(read_file(output2), content2+"\n") ### 6th run: touched both manifest makes ninja regenerates both self.pdbg("====== #6") time.sleep(1) content3 = "foo3" output3 = self.from_build_dir("out3") with open(fs[self.MANIFEST_FILENAME], "a") as stream: stream.write( "samurai_ctxt.add(Echo(text={text!r}, output={output!r}))\n" .format(text=content3, output=output3)) sub_content3 = "sub foo3" sub_output3 = self.from_build_dir("sub", "out3") with open(fs["sub"][self.MANIFEST_FILENAME], "a") as stream: stream.write( "samurai_ctxt.add(Echo(text={text!r}, output={output!r}))\n" .format(text=sub_content3, output=sub_output3)) self.assertFSDiff({fs[self.MANIFEST_FILENAME]:FSDiffOp.UPDATED, fs["sub"][self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "all samurai manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED, sub_build_ninja_file:FSDiffOp.UPDATED, sub_decl_ninja_file:FSDiffOp.UPDATED, output3:FSDiffOp.CREATED, sub_output3:FSDiffOp.CREATED}, "all ninja files not re-generated or " "new targets not built") self.assertEqual(read_file(output3), content3+"\n") self.assertEqual(read_file(sub_output3), sub_content3+"\n")
def test_gen_and_regen(self): content = "foo" sub_content = "sub foo" output = self.from_build_dir("out") sub_output = self.from_build_dir("sub", "out") fs = self.create_fs_tree({ self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.subgenerator import SubSamurai from samurai.test.fixture import Fixture samurai_ctxt.add(SubSamurai("{manifest}", "{build_dir}/sub")) Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=content, output=output, manifest=os.path.join(self.tmpdir, "sub", self.MANIFEST_FILENAME), build_dir=self.build_dir())), "sub": { self.MANIFEST_FILENAME: \ textwrap.dedent("""\ from samurai.sys import context as samurai_ctxt from samurai.test.fixture import Fixture Echo = Fixture.Echo() samurai_ctxt.add(Echo(text={text!r}, output={output!r})) """.format(text=sub_content, output=sub_output)), }, }) sub_build_ninja_file = self.from_build_dir("sub", config.BUILD_FILENAME) sub_decl_ninja_file = self.from_build_dir("sub", config.DECL_FILENAME) self.pdbg("====== manifest") self.pdbg(read_file(fs[self.MANIFEST_FILENAME])) ### 1st run: generates and build both projects. self.pdbg("====== #1") self.take_fs_snapshot() samurai = self.samurai("-C", self.tmpdir, "-p", self.MANIFEST_FILENAME, self.BUILD_DIR) self.assertProcReturn(samurai, 0) self.pdbg("====== build.ninja") self.pdbg(read_file(self.build_ninja_file())) self.pdbg("====== sub/build.ninja") self.pdbg(read_file(sub_build_ninja_file)) self.assertFSDiff({self.build_ninja_file():FSDiffOp.CREATED, self.decl_ninja_file():FSDiffOp.CREATED, sub_build_ninja_file:FSDiffOp.CREATED, sub_decl_ninja_file:FSDiffOp.CREATED}, "all ninja files not generated") ### 2nd run: build outputs self.pdbg("====== #2") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({output:FSDiffOp.CREATED, sub_output:FSDiffOp.CREATED}, "output files not built") self.assertEqual(read_file(output), content+"\n") self.assertEqual(read_file(sub_output), sub_content+"\n") ### 3rd run: nothing to do self.pdbg("====== #3") ninja = self.ninja("-C", self.build_dir()) self.assertEqual(ninja.returncode, 0) self.assertFSDiff({}, "nothing has changed") ### 4th run: touched sub-manifest makes ninja regenerates only the ### sub-project. self.pdbg("====== #4") time.sleep(1) touch(fs["sub"][self.MANIFEST_FILENAME]) self.assertFSDiff({fs["sub"][self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "sub samurai manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({sub_build_ninja_file:FSDiffOp.UPDATED, sub_decl_ninja_file:FSDiffOp.UPDATED}, "sub ninja files not re-generated") ### 5th run: touched manifest makes ninja regenerates only its ### manifest but not the one of the sub-projects. self.pdbg("====== #5") time.sleep(1) touch(fs[self.MANIFEST_FILENAME]) self.assertFSDiff({fs[self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "samurai manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED}, "ninja files not re-generated") ### 6th run: touched both manifest makes ninja regenerates both self.pdbg("====== #6") time.sleep(1) touch(fs[self.MANIFEST_FILENAME]) touch(fs["sub"][self.MANIFEST_FILENAME]) self.assertFSDiff({fs[self.MANIFEST_FILENAME]:FSDiffOp.UPDATED, fs["sub"][self.MANIFEST_FILENAME]:FSDiffOp.UPDATED}, "all samurai manifest not touched") ninja = self.ninja("-C", self.build_dir()) self.assertProcReturn(ninja, 0) self.assertFSDiff({self.build_ninja_file():FSDiffOp.UPDATED, self.decl_ninja_file():FSDiffOp.UPDATED, sub_build_ninja_file:FSDiffOp.UPDATED, sub_decl_ninja_file:FSDiffOp.UPDATED}, "all ninja files not re-generated")