def test_writes(self): self.assertEqual( action_tracer.finalize_filesystem_accesses( [ action_tracer.Write("wb.txt"), action_tracer.Write("wa.txt"), ]), action_tracer.FSAccessSet(writes={"wa.txt", "wb.txt"}))
def test_forbidden_writes(self): # make sure multiple violations accumulate bad_writes = [ action_tracer.Write("unwriteable.txt"), action_tracer.Write("you-shall-not-pass.txt"), ] self.assertEqual( action_tracer.check_access_permissions(bad_writes), bad_writes, )
def test_reads_writes_no_deletes(self): self.assertEqual( action_tracer.finalize_filesystem_accesses([ action_tracer.Read("r2.txt"), action_tracer.Write("wb.txt"), action_tracer.Write("wa.txt"), action_tracer.Read("r1.txt"), ]), action_tracer.FSAccessSet(reads={"r1.txt", "r2.txt"}, writes={"wa.txt", "wb.txt"}))
def test_sequence(self): self.assertEqual( list( action_tracer.parse_fsatrace_output([ "m|dest.txt|source.txt", "r|input.txt", "w|output.log", ])), [ action_tracer.Delete("source.txt"), action_tracer.Write("dest.txt"), action_tracer.Read("input.txt"), action_tracer.Write("output.log"), ], )
def test_read_after_write(self): self.assertEqual( action_tracer.finalize_filesystem_accesses( [ action_tracer.Write("temp.txt"), action_tracer.Read("temp.txt"), ]), action_tracer.FSAccessSet(reads=set(), writes={"temp.txt"}))
def test_fresh_output_with_used_input(self): def fake_getctime(path: str): if path.startswith("read"): return 100 if path.startswith("write"): return 200 return 0 used_input = "read.me" written_output = "write.me" with mock.patch.object(os.path, 'exists', return_value=True) as mock_exists: with mock.patch.object(os.path, 'getctime', wraps=fake_getctime) as mock_ctime: output_diagnostics = action_tracer.diagnose_stale_outputs( accesses=[ action_tracer.Read(used_input), action_tracer.Write(written_output), ], access_constraints=action_tracer.AccessConstraints( allowed_reads={used_input}, required_writes={written_output}), ) # There are no untouched outputs, so getctime is never called. mock_exists.assert_not_called() mock_ctime.assert_not_called() self.assertEqual( output_diagnostics, action_tracer.StalenessDiagnostics( required_writes={written_output}, # newest_input is not evaluated stale_outputs=set(), ), )
def test_ignored_prefix_no_match(self): prefixes = {"/tmp", "/no/look/here"} self.assertTrue( action_tracer.Read("book").should_check(ignored_prefixes=prefixes)) self.assertTrue( action_tracer.Write("out/log").should_check( ignored_prefixes=prefixes))
def test_ok_write(self): self.assertEqual( action_tracer.check_access_permissions( [action_tracer.Write("writeable.txt")], allowed_writes={"writeable.txt"}), [], )
def test_write_after_delete(self): self.assertEqual( action_tracer.finalize_filesystem_accesses( [ action_tracer.Delete("temp.txt"), action_tracer.Write("temp.txt"), ]), action_tracer.FSAccessSet(writes={"temp.txt"}))
def test_no_ignored_suffix(self): ignore_conditions = action_tracer.MatchConditions(suffixes={}) self.assertTrue( action_tracer.Read("book").should_check( ignore_conditions=ignore_conditions)) self.assertTrue( action_tracer.Write("output/log").should_check( ignore_conditions=ignore_conditions))
def test_ignored_prefix_matches(self): ignore_conditions = action_tracer.MatchConditions(prefixes={"/tmp"}) self.assertFalse( action_tracer.Read("/tmp/book").should_check( ignore_conditions=ignore_conditions)) self.assertFalse( action_tracer.Write("/tmp/log").should_check( ignore_conditions=ignore_conditions))
def test_no_required_prefix(self): ignore_conditions = action_tracer.MatchConditions() self.assertTrue( action_tracer.Read("book").should_check( ignore_conditions=ignore_conditions, required_path_prefix="")) self.assertTrue( action_tracer.Write("block").should_check( ignore_conditions=ignore_conditions, required_path_prefix=""))
def test_required_prefix_matches(self): prefix = "/home/project" self.assertTrue( action_tracer.Read("/home/project/book").should_check( required_path_prefix=prefix)) self.assertTrue( action_tracer.Write("/home/project/out/block").should_check( required_path_prefix=prefix))
def test_ignored_path_components_matches(self): components = {"__auto__", ".generated"} self.assertFalse( action_tracer.Read("library/__auto__/book").should_check( ignored_path_parts=components)) self.assertFalse( action_tracer.Write(".generated/out/log").should_check( ignored_path_parts=components))
def test_fulfilled_write(self): self.assertEqual( action_tracer.check_missing_writes( [action_tracer.Write("compiled.o")], {"compiled.o"}, ), set(), )
def test_ignored_suffix_no_match(self): suffixes = {".ii", ".S"} # e.g. from compiler --save-temps self.assertTrue( action_tracer.Read("book.txt").should_check( ignored_suffixes=suffixes)) self.assertTrue( action_tracer.Write("out/process.log").should_check( ignored_suffixes=suffixes))
def test_ignored_prefix_matches(self): prefixes = {"/tmp"} self.assertFalse( action_tracer.Read("/tmp/book").should_check( ignored_prefixes=prefixes)) self.assertFalse( action_tracer.Write("/tmp/log").should_check( ignored_prefixes=prefixes))
def test_ignored_suffix_matches(self): suffixes = {".ii"} # e.g. from compiler --save-temps self.assertFalse( action_tracer.Read("book.ii").should_check( ignored_suffixes=suffixes)) self.assertFalse( action_tracer.Write("tmp/log.ii").should_check( ignored_suffixes=suffixes))
def test_required_prefix_no_match(self): prefix = "/home/project" self.assertFalse( action_tracer.Read("book").should_check( required_path_prefix=prefix)) self.assertFalse( action_tracer.Write("output/log").should_check( required_path_prefix=prefix))
def test_excess_write(self): self.assertEqual( action_tracer.check_missing_writes( [action_tracer.Write("side-effect.txt")], {}, ), {}, )
def test_ignored_path_components_no_match(self): components = {"__auto__", ".generated"} self.assertTrue( action_tracer.Read("book").should_check( ignored_path_parts=components)) self.assertTrue( action_tracer.Write("out/log").should_check( ignored_path_parts=components))
def test_ignored_path_components_no_match(self): ignore_conditions = action_tracer.MatchConditions( components={"__auto__", ".generated"}) self.assertTrue( action_tracer.Read("book").should_check( ignore_conditions=ignore_conditions)) self.assertTrue( action_tracer.Write("out/log").should_check( ignore_conditions=ignore_conditions))
def test_ignored_prefix_no_match(self): ignore_conditions = action_tracer.MatchConditions( prefixes={"/tmp", "/no/look/here"}) self.assertTrue( action_tracer.Read("book").should_check( ignore_conditions=ignore_conditions)) self.assertTrue( action_tracer.Write("out/log").should_check( ignore_conditions=ignore_conditions))
def test_ignored_suffix_matches(self): # e.g. from compiler --save-temps ignore_conditions = action_tracer.MatchConditions(suffixes={".ii"}) self.assertFalse( action_tracer.Read("book.ii").should_check( ignore_conditions=ignore_conditions)) self.assertFalse( action_tracer.Write("tmp/log.ii").should_check( ignore_conditions=ignore_conditions))
def test_move(self): self.assertEqual( list(action_tracer.parse_fsatrace_output(["m|dest.txt|source.txt" ])), [ action_tracer.Delete("source.txt"), action_tracer.Write("dest.txt"), ], )
def test_deleted_then_written(self): self.assertEqual( action_tracer.check_missing_writes( [ action_tracer.Delete("compiled.o"), action_tracer.Write("compiled.o"), ], {"compiled.o"}, ), set(), )
def test_required_prefix_no_match(self): ignore_conditions = action_tracer.MatchConditions() prefix = "/home/project" self.assertFalse( action_tracer.Read("book").should_check( ignore_conditions=ignore_conditions, required_path_prefix=prefix)) self.assertFalse( action_tracer.Write("output/log").should_check( ignore_conditions=ignore_conditions, required_path_prefix=prefix))
def test_missing_and_fulfilled_write(self): self.assertEqual( action_tracer.check_missing_writes( [action_tracer.Write("compiled.o")], { "write-me.out", "compiled.o", }, ), {"write-me.out"}, )
def test_required_prefix_matches(self): ignore_conditions = action_tracer.MatchConditions() prefix = "/home/project" self.assertTrue( action_tracer.Read("/home/project/book").should_check( ignore_conditions=ignore_conditions, required_path_prefix=prefix)) self.assertTrue( action_tracer.Write("/home/project/out/block").should_check( ignore_conditions=ignore_conditions, required_path_prefix=prefix))
def test_touch(self): self.assertEqual( list(action_tracer.parse_fsatrace_output(["t|file.stamp"])), [action_tracer.Write("file.stamp")], )