Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: QubesOS/qubes-core-qrexec
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 820b3833688a443097b3212d499e42329a821fcb
Choose a base ref
..
head repository: QubesOS/qubes-core-qrexec
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 966e3836db6aa0c55cfc76f728e64a8b249fe05f
Choose a head ref
Showing with 62 additions and 4 deletions.
  1. +13 −1 qrexec/policy/utils.py
  2. +49 −3 qrexec/tests/policy_cache.py
14 changes: 13 additions & 1 deletion qrexec/policy/utils.py
Original file line number Diff line number Diff line change
@@ -50,7 +50,13 @@ def initialize_watcher(self):
self.watch_manager = pyinotify.WatchManager()

# pylint: disable=no-member
mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY
mask = (
pyinotify.IN_CREATE |
pyinotify.IN_DELETE |
pyinotify.IN_MODIFY |
pyinotify.IN_MOVED_FROM |
pyinotify.IN_MOVED_TO
)

loop = asyncio.get_event_loop()

@@ -105,3 +111,9 @@ def process_IN_DELETE(self, _):

def process_IN_MODIFY(self, _):
self.cache.outdated = True

def process_IN_MOVED_TO(self, _):
self.cache.outdated = True

def process_IN_MOVED_FROM(self, _):
self.cache.outdated = True
52 changes: 49 additions & 3 deletions qrexec/tests/policy_cache.py
Original file line number Diff line number Diff line change
@@ -108,17 +108,63 @@ async def test_13_no_change(self, tmp_paths, mock_parser):

assert not cache.outdated

@pytest.mark.asyncio
async def test_14_policy_move(self, tmp_path, mock_parser):
policy_path = tmp_path / "policy"
policy_path.mkdir()
cache = utils.PolicyCache([policy_path])
cache.initialize_watcher()

mock_parser.assert_called_once_with(policy_path=[policy_path])

assert not cache.outdated

file = tmp_path / "test"
file.write_text("test")

await asyncio.sleep(1)

assert not cache.outdated

# move in
file_moved = file.rename(policy_path / "test")

await asyncio.sleep(1)

assert cache.outdated

cache.get_policy()

assert not cache.outdated

# now move out
file_moved.rename(file)

await asyncio.sleep(1)

assert cache.outdated

cache.get_policy()

call = unittest.mock.call(policy_path=[policy_path])
assert mock_parser.mock_calls == [call, call, call]

@pytest.mark.asyncio
async def test_20_policy_updates(self, tmp_paths, mock_parser):
cache = utils.PolicyCache(tmp_paths)
cache.initialize_watcher()
count = 0
call = unittest.mock.call(policy_path=tmp_paths)

for i in tmp_paths:
call = unittest.mock.call(policy_path=tmp_paths)

count += 2
assert mock_parser.mock_calls == [call] * (count - 1)
cache = utils.PolicyCache(tmp_paths)
cache.initialize_watcher()

assert mock_parser.mock_calls == [call] * (count - 1)
l = len(mock_parser.mock_calls)
assert mock_parser.mock_calls == [call] * l

assert not cache.outdated

@@ -131,4 +177,4 @@ async def test_20_policy_updates(self, tmp_paths, mock_parser):

cache.get_policy()

assert mock_parser.mock_calls == [call] * count
assert mock_parser.mock_calls == [call] * (count + 1)