Skip to content

Commit 91437ba

Browse files
committed
test: fix flaky test_fs_event
1 parent 3060ceb commit 91437ba

File tree

1 file changed

+63
-80
lines changed

1 file changed

+63
-80
lines changed

tests/test_fs_event.py

Lines changed: 63 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,83 @@
11
import asyncio
2+
import contextlib
23
import os.path
34
import tempfile
45

56
from uvloop import _testbase as tb
67
from uvloop.loop import FileSystemEvent
78

89

9-
class Test_UV_FS_EVENT_CHANGE(tb.UVTestCase):
10-
async def _file_writer(self):
11-
f = await self.q.get()
12-
while True:
13-
f.write('hello uvloop\n')
14-
f.flush()
15-
x = await self.q.get()
16-
if x is None:
17-
return
18-
19-
def fs_event_setup(self):
20-
self.change_event_count = 0
21-
self.fname = ''
22-
self.q = asyncio.Queue()
23-
24-
def event_cb(self, ev_fname: bytes, evt: FileSystemEvent):
25-
_d, fn = os.path.split(self.fname)
26-
self.assertEqual(ev_fname, fn)
27-
self.assertEqual(evt, FileSystemEvent.CHANGE)
28-
self.change_event_count += 1
29-
if self.change_event_count < 4:
30-
self.q.put_nowait(0)
31-
else:
32-
self.q.put_nowait(None)
10+
class Test_UV_FS_Event(tb.UVTestCase):
11+
def setUp(self):
12+
super().setUp()
13+
self.exit_stack = contextlib.ExitStack()
14+
self.tmp_dir = self.exit_stack.enter_context(tempfile.TemporaryDirectory())
15+
16+
def tearDown(self):
17+
self.exit_stack.close()
18+
super().tearDown()
3319

3420
def test_fs_event_change(self):
35-
self.fs_event_setup()
36-
37-
async def run(write_task):
38-
self.q.put_nowait(tf)
39-
try:
40-
await asyncio.wait_for(write_task, 4)
41-
except asyncio.TimeoutError:
42-
write_task.cancel()
43-
44-
with tempfile.NamedTemporaryFile('wt') as tf:
45-
self.fname = tf.name.encode()
46-
h = self.loop._monitor_fs(tf.name, self.event_cb)
21+
change_event_count = 0
22+
filename = "fs_event_change.txt"
23+
path = os.path.join(self.tmp_dir, filename)
24+
q = asyncio.Queue()
25+
26+
with open(path, 'wt') as f:
27+
async def file_writer():
28+
while True:
29+
f.write('hello uvloop\n')
30+
f.flush()
31+
x = await q.get()
32+
if x is None:
33+
return
34+
35+
def event_cb(ev_fname: bytes, evt: FileSystemEvent):
36+
nonlocal change_event_count
37+
self.assertEqual(ev_fname, filename.encode())
38+
self.assertEqual(evt, FileSystemEvent.CHANGE)
39+
change_event_count += 1
40+
if change_event_count < 4:
41+
q.put_nowait(0)
42+
else:
43+
q.put_nowait(None)
44+
45+
h = self.loop._monitor_fs(path, event_cb)
46+
self.loop.run_until_complete(asyncio.sleep(0.1)) # let monitor start
4747
self.assertFalse(h.cancelled())
4848

49-
self.loop.run_until_complete(run(
50-
self.loop.create_task(self._file_writer())))
49+
self.loop.run_until_complete(asyncio.wait_for(file_writer(), 4))
5150
h.cancel()
5251
self.assertTrue(h.cancelled())
5352

54-
self.assertEqual(self.change_event_count, 4)
55-
56-
57-
class Test_UV_FS_EVENT_RENAME(tb.UVTestCase):
58-
async def _file_renamer(self):
59-
await self.q.get()
60-
os.rename(os.path.join(self.dname, self.changed_name),
61-
os.path.join(self.dname, self.changed_name + "-new"))
62-
await self.q.get()
63-
64-
def fs_event_setup(self):
65-
self.dname = ''
66-
self.changed_name = "hello_fs_event.txt"
67-
self.changed_set = {self.changed_name, self.changed_name + '-new'}
68-
self.q = asyncio.Queue()
69-
70-
def event_cb(self, ev_fname: bytes, evt: FileSystemEvent):
71-
ev_fname = ev_fname.decode()
72-
self.assertEqual(evt, FileSystemEvent.RENAME)
73-
self.changed_set.remove(ev_fname)
74-
if len(self.changed_set) == 0:
75-
self.q.put_nowait(None)
53+
self.assertEqual(change_event_count, 4)
7654

7755
def test_fs_event_rename(self):
78-
self.fs_event_setup()
79-
80-
async def run(write_task):
81-
self.q.put_nowait(0)
82-
try:
83-
await asyncio.wait_for(write_task, 4)
84-
except asyncio.TimeoutError:
85-
write_task.cancel()
86-
87-
with tempfile.TemporaryDirectory() as td_name:
88-
self.dname = td_name
89-
f = open(os.path.join(td_name, self.changed_name), 'wt')
56+
orig_name = "hello_fs_event.txt"
57+
new_name = "hello_fs_event_rename.txt"
58+
changed_set = {orig_name, new_name}
59+
event = asyncio.Event()
60+
61+
async def file_renamer():
62+
os.rename(os.path.join(self.tmp_dir, orig_name),
63+
os.path.join(self.tmp_dir, new_name))
64+
await event.wait()
65+
66+
def event_cb(ev_fname: bytes, evt: FileSystemEvent):
67+
ev_fname = ev_fname.decode()
68+
self.assertEqual(evt, FileSystemEvent.RENAME)
69+
changed_set.discard(ev_fname)
70+
if len(changed_set) == 0:
71+
event.set()
72+
73+
with open(os.path.join(self.tmp_dir, orig_name), 'wt') as f:
9074
f.write('hello!')
91-
f.close()
92-
h = self.loop._monitor_fs(td_name, self.event_cb)
93-
self.assertFalse(h.cancelled())
75+
h = self.loop._monitor_fs(self.tmp_dir, event_cb)
76+
self.loop.run_until_complete(asyncio.sleep(0.5)) # let monitor start
77+
self.assertFalse(h.cancelled())
9478

95-
self.loop.run_until_complete(run(
96-
self.loop.create_task(self._file_renamer())))
97-
h.cancel()
98-
self.assertTrue(h.cancelled())
79+
self.loop.run_until_complete(asyncio.wait_for(file_renamer(), 4))
80+
h.cancel()
81+
self.assertTrue(h.cancelled())
9982

100-
self.assertEqual(len(self.changed_set), 0)
83+
self.assertEqual(len(changed_set), 0)

0 commit comments

Comments
 (0)