Skip to content

Commit 91fbee7

Browse files
committed
Move integration tests to its own file
Since the integration tests in the `FileWatcher` tests are actually testing 3 different classes (and interacting with the OS), we move it to its own file, and we call it more generally. We also mark the tests with the pytest mark `integration` to make it more clear they are integration tests, and to enable an easy way to only run (exclude) integration tests. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 68eb200 commit 91fbee7

File tree

3 files changed

+84
-67
lines changed

3 files changed

+84
-67
lines changed

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ src_paths = ["src", "examples", "tests"]
7474
[tool.pytest.ini_options]
7575
asyncio_mode = "auto"
7676
required_plugins = ["pytest-asyncio", "pytest-mock"]
77+
markers = [
78+
"integration: integration tests (deselect with '-m \"not integration\"')",
79+
]
7780

7881
[[tool.mypy.overrides]]
7982
module = ["async_solipsism", "async_solipsism.*"]

tests/utils/test_file_watcher.py

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@
55

66
from __future__ import annotations
77

8-
import os
98
import pathlib
109
from collections.abc import AsyncGenerator, Iterator, Sequence
11-
from datetime import timedelta
1210
from typing import Any
1311
from unittest import mock
1412

1513
import pytest
1614
from watchfiles import Change
1715
from watchfiles.main import FileChange
1816

19-
from frequenz.channels.util import FileWatcher, Select, Timer
17+
from frequenz.channels.util import FileWatcher
2018

2119

2220
class _FakeAwatch:
@@ -72,67 +70,3 @@ async def test_file_watcher_receive_updates(
7270
for change in changes:
7371
recv_changes = await file_watcher.receive()
7472
assert recv_changes == pathlib.Path(change[1])
75-
76-
77-
async def test_file_watcher(tmp_path: pathlib.Path) -> None:
78-
"""Ensure file watcher is returning paths on file events.
79-
80-
Args:
81-
tmp_path (pathlib.Path): A tmp directory to run the file watcher on.
82-
Created by pytest.
83-
"""
84-
filename = tmp_path / "test-file"
85-
file_watcher = FileWatcher(paths=[str(tmp_path)])
86-
87-
number_of_writes = 0
88-
expected_number_of_writes = 3
89-
90-
select = Select(
91-
timer=Timer.timeout(timedelta(seconds=0.1)),
92-
file_watcher=file_watcher,
93-
)
94-
while await select.ready():
95-
if msg := select.timer:
96-
filename.write_text(f"{msg.inner}")
97-
elif msg := select.file_watcher:
98-
assert msg.inner == filename
99-
number_of_writes += 1
100-
# After receiving a write 3 times, unsubscribe from the writes channel
101-
if number_of_writes == expected_number_of_writes:
102-
break
103-
104-
assert number_of_writes == expected_number_of_writes
105-
106-
107-
async def test_file_watcher_change_types(tmp_path: pathlib.Path) -> None:
108-
"""Ensure file watcher is returning paths only on the DELETE change.
109-
110-
Args:
111-
tmp_path (pathlib.Path): A tmp directory to run the file watcher on.
112-
Created by pytest.
113-
"""
114-
filename = tmp_path / "test-file"
115-
file_watcher = FileWatcher(
116-
paths=[str(tmp_path)], event_types={FileWatcher.EventType.DELETE}
117-
)
118-
119-
select = Select(
120-
write_timer=Timer.timeout(timedelta(seconds=0.1)),
121-
deletion_timer=Timer.timeout(timedelta(seconds=0.25)),
122-
watcher=file_watcher,
123-
)
124-
number_of_deletes = 0
125-
number_of_write = 0
126-
while await select.ready():
127-
if msg := select.write_timer:
128-
filename.write_text(f"{msg.inner}")
129-
number_of_write += 1
130-
elif _ := select.deletion_timer:
131-
os.remove(filename)
132-
elif _ := select.watcher:
133-
number_of_deletes += 1
134-
break
135-
136-
assert number_of_deletes == 1
137-
# Can be more because the watcher could take some time to trigger
138-
assert number_of_write >= 2

tests/utils/test_integration.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# License: MIT
2+
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
3+
4+
"""Integration tests for the `util` module."""
5+
6+
from __future__ import annotations
7+
8+
import os
9+
import pathlib
10+
from datetime import timedelta
11+
12+
import pytest
13+
14+
from frequenz.channels.util import FileWatcher, Select, Timer
15+
16+
17+
@pytest.mark.integration
18+
async def test_file_watcher(tmp_path: pathlib.Path) -> None:
19+
"""Ensure file watcher is returning paths on file events.
20+
21+
Args:
22+
tmp_path (pathlib.Path): A tmp directory to run the file watcher on.
23+
Created by pytest.
24+
"""
25+
filename = tmp_path / "test-file"
26+
file_watcher = FileWatcher(paths=[str(tmp_path)])
27+
28+
number_of_writes = 0
29+
expected_number_of_writes = 3
30+
31+
select = Select(
32+
timer=Timer.timeout(timedelta(seconds=0.1)),
33+
file_watcher=file_watcher,
34+
)
35+
while await select.ready():
36+
if msg := select.timer:
37+
filename.write_text(f"{msg.inner}")
38+
elif msg := select.file_watcher:
39+
assert msg.inner == filename
40+
number_of_writes += 1
41+
# After receiving a write 3 times, unsubscribe from the writes channel
42+
if number_of_writes == expected_number_of_writes:
43+
break
44+
45+
assert number_of_writes == expected_number_of_writes
46+
47+
48+
@pytest.mark.integration
49+
async def test_file_watcher_change_types(tmp_path: pathlib.Path) -> None:
50+
"""Ensure file watcher is returning paths only on the DELETE change.
51+
52+
Args:
53+
tmp_path (pathlib.Path): A tmp directory to run the file watcher on.
54+
Created by pytest.
55+
"""
56+
filename = tmp_path / "test-file"
57+
file_watcher = FileWatcher(
58+
paths=[str(tmp_path)], event_types={FileWatcher.EventType.DELETE}
59+
)
60+
61+
select = Select(
62+
write_timer=Timer.timeout(timedelta(seconds=0.1)),
63+
deletion_timer=Timer.timeout(timedelta(seconds=0.25)),
64+
watcher=file_watcher,
65+
)
66+
number_of_deletes = 0
67+
number_of_write = 0
68+
while await select.ready():
69+
if msg := select.write_timer:
70+
filename.write_text(f"{msg.inner}")
71+
number_of_write += 1
72+
elif _ := select.deletion_timer:
73+
os.remove(filename)
74+
elif _ := select.watcher:
75+
number_of_deletes += 1
76+
break
77+
78+
assert number_of_deletes == 1
79+
# Can be more because the watcher could take some time to trigger
80+
assert number_of_write >= 2

0 commit comments

Comments
 (0)