Skip to content

Commit 3aa509d

Browse files
Tests: harden TestNetwork (#505)
- make tests deterministic - use cleanup hooks - check the periodicity of heartbeats, by number of triggers - roughly check the interval
1 parent 5207b32 commit 3aa509d

File tree

1 file changed

+41
-27
lines changed

1 file changed

+41
-27
lines changed

test/test_network.py

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import time
21
import unittest
2+
from threading import Event
33

44
import canopen
55
import can
@@ -10,7 +10,8 @@ class TestNetwork(unittest.TestCase):
1010

1111
def setUp(self):
1212
network = canopen.Network()
13-
network.add_node(2, SAMPLE_EDS)
13+
with self.assertLogs():
14+
network.add_node(2, SAMPLE_EDS)
1415
network.add_node(3, network[2].object_dictionary)
1516
self.network = network
1617

@@ -31,7 +32,10 @@ def test_notify(self):
3132

3233
def test_send(self):
3334
bus = can.interface.Bus(interface="virtual", channel=1)
35+
self.addCleanup(bus.shutdown)
36+
3437
self.network.connect(interface="virtual", channel=1)
38+
self.addCleanup(self.network.disconnect)
3539

3640
# Send standard ID
3741
self.network.send_message(0x123, [1, 2, 3, 4, 5, 6, 7, 8])
@@ -48,33 +52,43 @@ def test_send(self):
4852
self.assertEqual(msg.arbitration_id, 0x12345)
4953
self.assertTrue(msg.is_extended_id)
5054

51-
bus.shutdown()
52-
self.network.disconnect()
53-
54-
def test_send_perodic(self):
55-
bus = can.interface.Bus(interface="virtual", channel=1)
56-
self.network.connect(interface="virtual", channel=1)
57-
58-
task = self.network.send_periodic(0x123, [1, 2, 3], 0.01)
59-
time.sleep(0.1)
60-
# FIXME: This test is a little fragile, as the number of elements
61-
# depends on the timing of the machine.
62-
print(f"Queue size: {bus.queue.qsize()}")
63-
self.assertTrue(9 <= bus.queue.qsize() <= 13)
64-
msg = bus.recv(0)
65-
self.assertIsNotNone(msg)
66-
self.assertSequenceEqual(msg.data, [1, 2, 3])
67-
# Update data
68-
task.update([4, 5, 6])
69-
time.sleep(0.02)
70-
while msg is not None and msg.data == b'\x01\x02\x03':
71-
msg = bus.recv(0)
72-
self.assertIsNotNone(msg)
73-
self.assertSequenceEqual(msg.data, [4, 5, 6])
55+
def test_send_periodic(self):
56+
DATA1 = bytes([1, 2, 3])
57+
DATA2 = bytes([4, 5, 6])
58+
COB_ID = 0x123
59+
PERIOD = 0.1
60+
self.network.connect(
61+
interface="virtual",
62+
channel=1,
63+
receive_own_messages=True
64+
)
65+
self.addCleanup(self.network.disconnect)
66+
67+
acc = []
68+
event = Event()
69+
70+
def hook(_, data, ts):
71+
acc.append((data, ts))
72+
event.set()
73+
74+
self.network.subscribe(COB_ID, hook)
75+
self.addCleanup(self.network.unsubscribe, COB_ID)
76+
77+
task = self.network.send_periodic(COB_ID, DATA1, PERIOD)
78+
self.addCleanup(task.stop)
79+
80+
event.wait(PERIOD*2)
81+
82+
# Update task data.
83+
task.update(DATA2)
84+
event.clear()
85+
event.wait(PERIOD*2)
7486
task.stop()
7587

76-
bus.shutdown()
77-
self.network.disconnect()
88+
data = [v[0] for v in acc]
89+
self.assertEqual(data, [DATA1, DATA2])
90+
ts = [v[1] for v in acc]
91+
self.assertAlmostEqual(ts[1]-ts[0], PERIOD, places=1)
7892

7993

8094
class TestScanner(unittest.TestCase):

0 commit comments

Comments
 (0)