blob: e3433420c8e919b1df8bf1cd0b0ed3b2cca6d49f [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import unittest
from unittest import mock
import action_tracer
class CheckAccessLineTests(unittest.TestCase):
def test_allowed_read(self):
self.assertEqual(
action_tracer.check_access_line(
"r", "foo.txt", allowed_reads={"foo.txt"}, allowed_writes={}),
[])
def test_forbiddden_read(self):
self.assertEqual(
action_tracer.check_access_line(
"r", "bar.txt", allowed_reads={}, allowed_writes={}),
[("read", "bar.txt")])
def test_allowed_write(self):
self.assertEqual(
action_tracer.check_access_line(
"w", "foo.txt", allowed_reads={}, allowed_writes={"foo.txt"}),
[])
def test_forbiddden_write(self):
self.assertEqual(
action_tracer.check_access_line(
"w", "baz.txt", allowed_reads={}, allowed_writes={}),
[("write", "baz.txt")])
def test_allowed_touch(self):
self.assertEqual(
action_tracer.check_access_line(
"t", "foo.txt", allowed_reads={}, allowed_writes={"foo.txt"}),
[])
def test_forbiddden_touch(self):
self.assertEqual(
action_tracer.check_access_line(
"t", "baz.txt", allowed_reads={}, allowed_writes={}),
[("write", "baz.txt")])
def test_allowed_delete(self):
self.assertEqual(
action_tracer.check_access_line(
"d", "foo.txt", allowed_reads={}, allowed_writes={"foo.txt"}),
[])
def test_forbiddden_delete(self):
self.assertEqual(
action_tracer.check_access_line(
"d", "baz.txt", allowed_reads={}, allowed_writes={}),
[("write", "baz.txt")])
def test_allowed_move(self):
self.assertEqual(
action_tracer.check_access_line(
"m",
"dest|source",
allowed_reads={},
allowed_writes={"source", "dest"}), [])
def test_forbidden_move_from_source(self):
self.assertEqual(
action_tracer.check_access_line(
"m", "dest|source", allowed_reads={}, allowed_writes={"dest"}),
[("write", "source")])
def test_forbidden_move_to_dest(self):
self.assertEqual(
action_tracer.check_access_line(
"m", "dest|source", allowed_reads={},
allowed_writes={"source"}), [("write", "dest")])
def test_forbidden_move_source_and_dest(self):
self.assertEqual(
action_tracer.check_access_line(
"m", "dest|source", allowed_reads={}, allowed_writes={}),
[("write", "dest"), ("write", "source")])
# No required prefix, no ignore affixes, no allowed accesses.
_default_checker = action_tracer.AccessTraceChecker(
required_path_prefix="",
ignored_prefixes={},
ignored_suffixes={},
allowed_reads={},
allowed_writes={})
class AccessTraceCheckerTests(unittest.TestCase):
def test_no_accesses(self):
self.assertEqual(
_default_checker.check_accesses([]),
[],
)
def test_ignore_invalid_trace_line(self):
self.assertEqual(
_default_checker.check_accesses(["invalid-trace-desc"]),
[],
)
def test_ok_read(self):
checker = action_tracer.AccessTraceChecker(
allowed_reads={"readable.txt"})
self.assertEqual(
checker.check_accesses(["r|readable.txt"]),
[],
)
def test_forbidden_read(self):
self.assertEqual(
_default_checker.check_accesses(["r|unreadable.txt"]),
[("read", "unreadable.txt")],
)
def test_ignore_read_outside_of_prefix(self):
checker = action_tracer.AccessTraceChecker(
required_path_prefix="/home/project")
self.assertEqual(
checker.check_accesses(["r|/elsewhere/file.txt"]),
[],
)
def test_ok_read_inside_of_prefix(self):
checker = action_tracer.AccessTraceChecker(
required_path_prefix="/home/project",
allowed_reads={"/home/project/file.txt"})
self.assertEqual(
checker.check_accesses(["r|/home/project/file.txt"]),
[],
)
def test_ok_write(self):
checker = action_tracer.AccessTraceChecker(
allowed_writes={"writeable.txt"})
self.assertEqual(
checker.check_accesses(["w|writeable.txt"]),
[],
)
def test_forbidden_writes(self):
# make sure multiple violations accumulate
self.assertEqual(
_default_checker.check_accesses(
[
"w|unwriteable.txt",
"w|you-shall-not-pass.txt",
]),
[
("write", "unwriteable.txt"),
("write", "you-shall-not-pass.txt"),
],
)
def test_ignore_write_outside_of_prefix(self):
checker = action_tracer.AccessTraceChecker(
required_path_prefix="/home/project")
self.assertEqual(
checker.check_accesses(["w|/elsewhere/file.txt"]),
[],
)
def test_ok_write_inside_of_prefix(self):
checker = action_tracer.AccessTraceChecker(
required_path_prefix="/home/project",
allowed_writes={"/home/project/file.out"})
self.assertEqual(
checker.check_accesses(["w|/home/project/file.out"]),
[],
)
def test_ignore_write_prefix(self):
# Make sure this fails without an ignored_prefix.
self.assertEqual(
_default_checker.check_accesses(
["w|/tmp/intermediate_calculation.txt"]),
[("write", "/tmp/intermediate_calculation.txt")],
)
# Make sure this passes with an ignored_prefix.
checker = action_tracer.AccessTraceChecker(ignored_prefixes={"/tmp/"})
self.assertEqual(
checker.check_accesses(["w|/tmp/intermediate_calculation.txt"]),
[],
)
def test_ignore_write_suffix(self):
# Make sure this fails without an ignored_prefix.
self.assertEqual(
_default_checker.check_accesses(
["w|/home/project/out/preprocessed.ii"]),
[("write", "/home/project/out/preprocessed.ii")],
)
# Make sure this passes with an ignored_prefix.
checker = action_tracer.AccessTraceChecker(
# e.g. from compiling with --save-temps
ignored_suffixes={".ii"})
self.assertEqual(
checker.check_accesses(["w|/home/project/out/preprocessed.ii"]),
[],
)
def test_ignore_write_infix(self):
# Make sure this fails without ignored_path_parts.
self.assertEqual(
_default_checker.check_accesses(
["w|/home/project/out/__tmp__/preprocessed.ii"]),
[("write", "/home/project/out/__tmp__/preprocessed.ii")],
)
# Make sure this passes with ignored_path_parts.
checker = action_tracer.AccessTraceChecker(
# e.g. from compiling with --save-temps
ignored_path_parts={"__tmp__"})
self.assertEqual(
checker.check_accesses(
["w|/home/project/out/__tmp__/preprocessed.ii"]),
[],
)
if __name__ == '__main__':
unittest.main()