From bc66b5758d238794a29ff08073305689635a8eec Mon Sep 17 00:00:00 2001 From: Simon Tegelid Date: Fri, 17 Dec 2021 12:40:49 +0100 Subject: [PATCH 01/27] Add preserve timestamps to virtual Add an option to virtual interfaces to preserve message timestamps on transmissions. This is useful in test setups fed by log files. --- can/interfaces/virtual.py | 4 +++- doc/interfaces/virtual.rst | 29 +++++++++++++++++++++++- test/test_interface_virtual.py | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 test/test_interface_virtual.py diff --git a/can/interfaces/virtual.py b/can/interfaces/virtual.py index a903435ac..ffd5b0241 100644 --- a/can/interfaces/virtual.py +++ b/can/interfaces/virtual.py @@ -59,6 +59,7 @@ def __init__( channel: Any = None, receive_own_messages: bool = False, rx_queue_size: int = 0, + preserve_timestamps: bool = False, **kwargs: Any, ) -> None: super().__init__( @@ -69,6 +70,7 @@ def __init__( self.channel_id = channel self.channel_info = f"Virtual bus channel {self.channel_id}" self.receive_own_messages = receive_own_messages + self.preserve_timestamps = preserve_timestamps self._open = True with channels_lock: @@ -103,7 +105,7 @@ def _recv_internal( def send(self, msg: Message, timeout: Optional[float] = None) -> None: self._check_if_open() - timestamp = time.time() + timestamp = msg.timestamp if self.preserve_timestamps else time.time() # Add message to all listening on this channel all_sent = True for bus_queue in self.channel: diff --git a/doc/interfaces/virtual.rst b/doc/interfaces/virtual.rst index b3fa7b38e..9258c9bbd 100644 --- a/doc/interfaces/virtual.rst +++ b/doc/interfaces/virtual.rst @@ -85,7 +85,7 @@ Example ------- .. code-block:: python - + import can bus1 = can.interface.Bus('test', bustype='virtual') @@ -100,6 +100,33 @@ Example assert msg1.data == msg2.data assert msg1.timestamp != msg2.timestamp +.. code-block:: python + + import can + + bus1 = can.interface.Bus('test', bustype='virtual', preserve_timestamps=True) + bus2 = can.interface.Bus('test', bustype='virtual') + + msg1 = can.Message(timestamp=1639740470.051948, arbitration_id=0xabcde, data=[1,2,3]) + + # Messages sent on bus1 will have their timestamps preserved when received + # on bus2 + bus1.send(msg1) + msg2 = bus2.recv() + + assert msg1.arbitration_id == msg2.arbitration_id + assert msg1.data == msg2.data + assert msg1.timestamp == msg2.timestamp + + # Messages sent on bus2 will not have their timestamps preserved when + # received on bus1 + bus2.send(msg1) + msg3 = bus1.recv() + + assert msg1.arbitration_id == msg3.arbitration_id + assert msg1.data == msg3.data + assert msg1.timestamp != msg3.timestamp + Bus Class Documentation ----------------------- diff --git a/test/test_interface_virtual.py b/test/test_interface_virtual.py new file mode 100644 index 000000000..009722779 --- /dev/null +++ b/test/test_interface_virtual.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" +This module tests :meth:`can.interface.virtual`. +""" + +import unittest + +from can import Bus, Message + +EXAMPLE_MSG1 = Message(timestamp=1639739471.5565314, arbitration_id=0x481, data=b"\x01") + + +class TestMessageFiltering(unittest.TestCase): + def setUp(self): + self.node1 = Bus("test", bustype="virtual", preserve_timestamps=True) + self.node2 = Bus("test", bustype="virtual") + + def tearDown(self): + self.node1.shutdown() + self.node2.shutdown() + + def test_sendmsg(self): + self.node2.send(EXAMPLE_MSG1) + r = self.node1.recv(0.1) + assert r.timestamp != EXAMPLE_MSG1.timestamp + assert r.arbitration_id == EXAMPLE_MSG1.arbitration_id + assert r.data == EXAMPLE_MSG1.data + + def test_sendmsg_preserve_timestamp(self): + self.node1.send(EXAMPLE_MSG1) + r = self.node2.recv(0.1) + assert r.timestamp == EXAMPLE_MSG1.timestamp + assert r.arbitration_id == EXAMPLE_MSG1.arbitration_id + assert r.data == EXAMPLE_MSG1.data + + +if __name__ == "__main__": + unittest.main() From 0362acbcae9dcdcb97474cc97788fd1983184b84 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 19:05:51 +0100 Subject: [PATCH 02/27] Add test case for player.py --- test/test_player.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100755 test/test_player.py diff --git a/test/test_player.py b/test/test_player.py new file mode 100755 index 000000000..62fdd0271 --- /dev/null +++ b/test/test_player.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +""" +This module tests the functions inside of player.py +""" + +import unittest +from unittest import mock +from unittest.mock import Mock +import os +import sys +import can +import can.player + +from .config import * + + +class TestPlayerScriptModule(unittest.TestCase): + def setUp(self) -> None: + # Patch VirtualBus object + patcher_virtual_bus = mock.patch("can.interfaces.virtual.VirtualBus", spec=True) + self.MockVirtualBus = patcher_virtual_bus.start() + self.addCleanup(patcher_virtual_bus.stop) + self.mock_virtual_bus = self.MockVirtualBus.return_value + self.mock_virtual_bus.shutdown = Mock() + + self.baseargs = [sys.argv[0], "-i", "virtual"] + self.logfile = os.path.join(os.path.dirname(__file__), "data", "test_CanMessage.asc") + + def assertSuccessfullCleanup(self): + self.MockVirtualBus.assert_called_once() + + def test_play_virtual(self): + sys.argv = self.baseargs + [self.logfile] + can.player.main() + self.assertSuccessfullCleanup() + + +if __name__ == "__main__": + unittest.main() From ee069470224686764445cf8e8cd8e62a960a375e Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 18:06:52 +0000 Subject: [PATCH 03/27] Format code with black --- test/test_player.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test_player.py b/test/test_player.py index 62fdd0271..1af48e429 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -26,7 +26,9 @@ def setUp(self) -> None: self.mock_virtual_bus.shutdown = Mock() self.baseargs = [sys.argv[0], "-i", "virtual"] - self.logfile = os.path.join(os.path.dirname(__file__), "data", "test_CanMessage.asc") + self.logfile = os.path.join( + os.path.dirname(__file__), "data", "test_CanMessage.asc" + ) def assertSuccessfullCleanup(self): self.MockVirtualBus.assert_called_once() From 5c72735a0d42fd10a159fec1f3cc1fb3a25da283 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 19:29:39 +0100 Subject: [PATCH 04/27] Add mock for sleep function to fasten up testing --- test/test_player.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_player.py b/test/test_player.py index 1af48e429..70a507ebe 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -25,6 +25,11 @@ def setUp(self) -> None: self.mock_virtual_bus = self.MockVirtualBus.return_value self.mock_virtual_bus.shutdown = Mock() + # Patch time sleep object + patcher_sleep = mock.patch("can.io.player.sleep", spec=True) + self.MockSleep = patcher_sleep.start() + self.addCleanup(patcher_sleep.stop) + self.baseargs = [sys.argv[0], "-i", "virtual"] self.logfile = os.path.join( os.path.dirname(__file__), "data", "test_CanMessage.asc" From fec26fbdd6bf8008ea67ac12029ed6ec64b558ae Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 19:30:33 +0100 Subject: [PATCH 05/27] Add test for verbose mode --- test/test_player.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_player.py b/test/test_player.py index 70a507ebe..aeb63764b 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -43,6 +43,11 @@ def test_play_virtual(self): can.player.main() self.assertSuccessfullCleanup() + def test_play_virtual_verbose(self): + sys.argv = self.baseargs + ["-v", self.logfile] + can.player.main() + self.assertSuccessfullCleanup() + if __name__ == "__main__": unittest.main() From fefdd53972a5cbf2697b99df7211522b1b51e6ae Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 19:42:18 +0100 Subject: [PATCH 06/27] Add call count assert --- test/test_player.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_player.py b/test/test_player.py index aeb63764b..8fa1e45ef 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -41,11 +41,13 @@ def assertSuccessfullCleanup(self): def test_play_virtual(self): sys.argv = self.baseargs + [self.logfile] can.player.main() + self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() def test_play_virtual_verbose(self): sys.argv = self.baseargs + ["-v", self.logfile] can.player.main() + self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() From 0907785c9025e49bcff09f77a2c7e9ba70475309 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 19:42:42 +0100 Subject: [PATCH 07/27] Add test for Keyboard interrupt during execution --- test/test_player.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test_player.py b/test/test_player.py index 8fa1e45ef..12a20ccd8 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -50,6 +50,14 @@ def test_play_virtual_verbose(self): self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() + def test_play_virtual_exit(self): + self.MockSleep.side_effect = KeyboardInterrupt + + sys.argv = self.baseargs + [self.logfile] + can.player.main() + self.assertEqual(self.MockSleep.call_count, 1) + self.assertSuccessfullCleanup() + if __name__ == "__main__": unittest.main() From 4721134c40fbd33465f923ee2beae37b79ee3a34 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Mon, 20 Dec 2021 19:53:43 +0100 Subject: [PATCH 08/27] Add todos --- test/test_player.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test_player.py b/test/test_player.py index 12a20ccd8..625c2842e 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -41,12 +41,15 @@ def assertSuccessfullCleanup(self): def test_play_virtual(self): sys.argv = self.baseargs + [self.logfile] can.player.main() + # TODO: add test two messages sent self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() def test_play_virtual_verbose(self): sys.argv = self.baseargs + ["-v", self.logfile] can.player.main() + # TODO: add test two messages sent + # TODO: add test message was printed self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() @@ -55,9 +58,15 @@ def test_play_virtual_exit(self): sys.argv = self.baseargs + [self.logfile] can.player.main() + # TODO: add test one message sent self.assertEqual(self.MockSleep.call_count, 1) self.assertSuccessfullCleanup() + def test_play_error_frame(self): + # TODO: implement + sys.argv = self.baseargs + ["--error-frames", self.logfile] + can.player.main() + if __name__ == "__main__": unittest.main() From 1d11a04d3fbb4eb9529d5180ac6fe28a6cc6931c Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sun, 26 Dec 2021 14:28:24 +0100 Subject: [PATCH 09/27] Implement check for successfull cleanup and send message call count --- test/test_player.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index 625c2842e..eb8697a36 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -23,7 +23,7 @@ def setUp(self) -> None: self.MockVirtualBus = patcher_virtual_bus.start() self.addCleanup(patcher_virtual_bus.stop) self.mock_virtual_bus = self.MockVirtualBus.return_value - self.mock_virtual_bus.shutdown = Mock() + self.mock_virtual_bus.__enter__ = Mock(return_value=self.mock_virtual_bus) # Patch time sleep object patcher_sleep = mock.patch("can.io.player.sleep", spec=True) @@ -37,11 +37,12 @@ def setUp(self) -> None: def assertSuccessfullCleanup(self): self.MockVirtualBus.assert_called_once() + self.mock_virtual_bus.__exit__.assert_called_once() def test_play_virtual(self): sys.argv = self.baseargs + [self.logfile] can.player.main() - # TODO: add test two messages sent + self.assertEqual(self.mock_virtual_bus.send.call_count, 2) self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() From bae496efa8f5de98f8d4c1f991a87636515791c0 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sun, 26 Dec 2021 14:31:37 +0100 Subject: [PATCH 10/27] Add assumptions for test cases --- test/test_player.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index eb8697a36..214f017c9 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -49,18 +49,18 @@ def test_play_virtual(self): def test_play_virtual_verbose(self): sys.argv = self.baseargs + ["-v", self.logfile] can.player.main() - # TODO: add test two messages sent # TODO: add test message was printed + self.assertEqual(self.mock_virtual_bus.send.call_count, 2) self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() def test_play_virtual_exit(self): - self.MockSleep.side_effect = KeyboardInterrupt + self.MockSleep.side_effect = [None, KeyboardInterrupt] sys.argv = self.baseargs + [self.logfile] can.player.main() - # TODO: add test one message sent - self.assertEqual(self.MockSleep.call_count, 1) + self.assertEqual(self.mock_virtual_bus.send.call_count, 1) + self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() def test_play_error_frame(self): From c41845fb96c6611b99364c3480ed991bbe3889b8 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sun, 26 Dec 2021 14:42:28 +0100 Subject: [PATCH 11/27] Add check for output on screen --- test/test_player.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index 214f017c9..65fa5b6b9 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -10,6 +10,7 @@ from unittest.mock import Mock import os import sys +import io import can import can.player @@ -48,8 +49,10 @@ def test_play_virtual(self): def test_play_virtual_verbose(self): sys.argv = self.baseargs + ["-v", self.logfile] - can.player.main() - # TODO: add test message was printed + with unittest.mock.patch('sys.stdout', new_callable=io.StringIO) as mock_stdout: + can.player.main() + self.assertIn('09 08 07 06 05 04 03 02', mock_stdout.getvalue()) + self.assertIn('05 0c 00 00 00 00 00 00', mock_stdout.getvalue()) self.assertEqual(self.mock_virtual_bus.send.call_count, 2) self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() From f6816b90f7f493e49bec7a97fea7a8c503e6308c Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sun, 26 Dec 2021 14:56:10 +0100 Subject: [PATCH 12/27] Implement test for replay with error frames --- test/data/logfile_errorframes.asc | 21 +++++++++++++++++++++ test/test_player.py | 19 +++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/data/logfile_errorframes.asc diff --git a/test/data/logfile_errorframes.asc b/test/data/logfile_errorframes.asc new file mode 100644 index 000000000..bcb5584a7 --- /dev/null +++ b/test/data/logfile_errorframes.asc @@ -0,0 +1,21 @@ +date Sam Sep 30 15:06:13.191 2017 +base hex timestamps absolute +internal events logged +// version 9.0.0 +Begin Triggerblock Sam Sep 30 15:06:13.191 2017 + 0.000000 Start of measurement + 0.015991 CAN 1 Status:chip status error passive - TxErr: 132 RxErr: 0 + 0.015991 CAN 2 Status:chip status error active + 2.501000 1 ErrorFrame + 2.501010 1 ErrorFrame ECC: 10100010 + 2.501020 2 ErrorFrame Flags = 0xe CodeExt = 0x20a2 Code = 0x82 ID = 0 DLC = 0 Position = 5 Length = 11300 + 2.520002 3 200 Tx r Length = 1704000 BitCount = 145 ID = 88888888x + 2.584921 4 300 Tx r 8 Length = 1704000 BitCount = 145 ID = 88888888x + 3.098426 1 18EBFF00x Rx d 8 01 A0 0F A6 60 3B D1 40 Length = 273910 BitCount = 141 ID = 418119424x + 3.197693 1 18EBFF00x Rx d 8 03 E1 00 4B FF FF 3C 0F Length = 283910 BitCount = 146 ID = 418119424x + 17.876976 1 6F8 Rx d 8 FF 00 0C FE 00 00 00 00 Length = 239910 BitCount = 124 ID = 1784 + 20.105214 2 18EBFF00x Rx d 8 01 A0 0F A6 60 3B D1 40 Length = 273925 BitCount = 141 ID = 418119424x + 20.155119 2 18EBFF00x Rx d 8 02 1F DE 80 25 DF C0 2B Length = 272152 BitCount = 140 ID = 418119424x + 20.204671 2 18EBFF00x Rx d 8 03 E1 00 4B FF FF 3C 0F Length = 283910 BitCount = 146 ID = 418119424x + 20.248887 2 18EBFF00x Rx d 8 04 00 4B FF FF FF FF FF Length = 283925 BitCount = 146 ID = 418119424x +End TriggerBlock diff --git a/test/test_player.py b/test/test_player.py index 65fa5b6b9..ab275b81a 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -66,10 +66,25 @@ def test_play_virtual_exit(self): self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() + def test_play_skip_error_frame(self): + logfile = os.path.join( + os.path.dirname(__file__), "data", "logfile_errorframes.asc" + ) + sys.argv = self.baseargs + ["-v", logfile] + can.player.main() + self.assertEqual(self.mock_virtual_bus.send.call_count, 9) + self.assertEqual(self.MockSleep.call_count, 12) + self.assertSuccessfullCleanup() + def test_play_error_frame(self): - # TODO: implement - sys.argv = self.baseargs + ["--error-frames", self.logfile] + logfile = os.path.join( + os.path.dirname(__file__), "data", "logfile_errorframes.asc" + ) + sys.argv = self.baseargs + ["-v", "--error-frames", logfile] can.player.main() + self.assertEqual(self.mock_virtual_bus.send.call_count, 12) + self.assertEqual(self.MockSleep.call_count, 12) + self.assertSuccessfullCleanup() if __name__ == "__main__": From dcbb9631a742a8951ca19f3f8083300217abfae9 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sun, 26 Dec 2021 13:57:12 +0000 Subject: [PATCH 13/27] Format code with black --- test/test_player.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index ab275b81a..c1048aae6 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -49,10 +49,10 @@ def test_play_virtual(self): def test_play_virtual_verbose(self): sys.argv = self.baseargs + ["-v", self.logfile] - with unittest.mock.patch('sys.stdout', new_callable=io.StringIO) as mock_stdout: + with unittest.mock.patch("sys.stdout", new_callable=io.StringIO) as mock_stdout: can.player.main() - self.assertIn('09 08 07 06 05 04 03 02', mock_stdout.getvalue()) - self.assertIn('05 0c 00 00 00 00 00 00', mock_stdout.getvalue()) + self.assertIn("09 08 07 06 05 04 03 02", mock_stdout.getvalue()) + self.assertIn("05 0c 00 00 00 00 00 00", mock_stdout.getvalue()) self.assertEqual(self.mock_virtual_bus.send.call_count, 2) self.assertEqual(self.MockSleep.call_count, 2) self.assertSuccessfullCleanup() From 7da73032752a9aee22ac1e1d2717ae4fd78171df Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Tue, 11 Jan 2022 20:27:34 +0100 Subject: [PATCH 14/27] Remove useless import Co-authored-by: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> --- test/test_player.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_player.py b/test/test_player.py index c1048aae6..ca590a898 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -14,7 +14,6 @@ import can import can.player -from .config import * class TestPlayerScriptModule(unittest.TestCase): From 2cb76b51f8178d5c5b35d3a0a41e4651e35ef493 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Tue, 11 Jan 2022 19:28:31 +0000 Subject: [PATCH 15/27] Format code with black --- test/test_player.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_player.py b/test/test_player.py index ca590a898..a3b88d65a 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -15,7 +15,6 @@ import can.player - class TestPlayerScriptModule(unittest.TestCase): def setUp(self) -> None: # Patch VirtualBus object From 5c6480bd03c3e0daf6891bd06baf8ca642ea304c Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Tue, 11 Jan 2022 20:31:59 +0100 Subject: [PATCH 16/27] Correct spell error --- test/test_player.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index a3b88d65a..d510a3d00 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -34,7 +34,7 @@ def setUp(self) -> None: os.path.dirname(__file__), "data", "test_CanMessage.asc" ) - def assertSuccessfullCleanup(self): + def assertSuccessfulCleanup(self): self.MockVirtualBus.assert_called_once() self.mock_virtual_bus.__exit__.assert_called_once() @@ -43,7 +43,7 @@ def test_play_virtual(self): can.player.main() self.assertEqual(self.mock_virtual_bus.send.call_count, 2) self.assertEqual(self.MockSleep.call_count, 2) - self.assertSuccessfullCleanup() + self.assertSuccessfulCleanup() def test_play_virtual_verbose(self): sys.argv = self.baseargs + ["-v", self.logfile] @@ -53,7 +53,7 @@ def test_play_virtual_verbose(self): self.assertIn("05 0c 00 00 00 00 00 00", mock_stdout.getvalue()) self.assertEqual(self.mock_virtual_bus.send.call_count, 2) self.assertEqual(self.MockSleep.call_count, 2) - self.assertSuccessfullCleanup() + self.assertSuccessfulCleanup() def test_play_virtual_exit(self): self.MockSleep.side_effect = [None, KeyboardInterrupt] @@ -62,7 +62,7 @@ def test_play_virtual_exit(self): can.player.main() self.assertEqual(self.mock_virtual_bus.send.call_count, 1) self.assertEqual(self.MockSleep.call_count, 2) - self.assertSuccessfullCleanup() + self.assertSuccessfulCleanup() def test_play_skip_error_frame(self): logfile = os.path.join( @@ -72,7 +72,7 @@ def test_play_skip_error_frame(self): can.player.main() self.assertEqual(self.mock_virtual_bus.send.call_count, 9) self.assertEqual(self.MockSleep.call_count, 12) - self.assertSuccessfullCleanup() + self.assertSuccessfulCleanup() def test_play_error_frame(self): logfile = os.path.join( @@ -82,7 +82,7 @@ def test_play_error_frame(self): can.player.main() self.assertEqual(self.mock_virtual_bus.send.call_count, 12) self.assertEqual(self.MockSleep.call_count, 12) - self.assertSuccessfullCleanup() + self.assertSuccessfulCleanup() if __name__ == "__main__": From 6f94d6b2791bda91bb80a332bd59c66dc11617ad Mon Sep 17 00:00:00 2001 From: Felix Divo <4403130+felixdivo@users.noreply.github.com> Date: Sat, 15 Jan 2022 11:43:15 +0100 Subject: [PATCH 17/27] Update workflow versions, platforms, library and tool versions and README to Python 3.7 --- .github/workflows/build.yml | 16 ++++++---------- .github/workflows/format-code.yml | 2 +- README.rst | 4 ++-- requirements-lint.txt | 6 +++--- setup.py | 5 ++--- tox.ini | 6 +++--- 6 files changed, 17 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb4c9a03b..95b295f90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,16 +13,12 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] experimental: [false] - python-version: ["3.6", "3.7", "3.8", "3.9", "pypy-3.7"] + python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7", "pypy-3.8"] include: - # Skipping Py 3.10 on Windows until windows-curses has a cp310 wheel, - # see https://github.com/zephyrproject-rtos/windows-curses/issues/26 + # Only test on a single configuration while there are just pre-releases - os: ubuntu-latest - experimental: false - python-version: "3.10" - - os: macos-latest - experimental: false - python-version: "3.10" + experimental: true + python-version: "3.11.0-alpha.3" fail-fast: false steps: - uses: actions/checkout@v2 @@ -38,7 +34,7 @@ jobs: run: | tox -e gh - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v2 with: fail_ci_if_error: true @@ -46,7 +42,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Python 3.10 + - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.10" diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml index 81e8fdf03..c3356e211 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: 3.10 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/README.rst b/README.rst index ac5537f7e..ebfa8431f 100644 --- a/README.rst +++ b/README.rst @@ -51,7 +51,7 @@ Python developers; providing common abstractions to different hardware devices, and a suite of utilities for sending and receiving messages on a can bus. -The library currently supports Python 3.6+ as well as PyPy 3 and runs +The library currently supports Python 3.7+ as well as PyPy 3 and runs on Mac, Linux and Windows. ============================== =========== @@ -59,7 +59,7 @@ Library Version Python ------------------------------ ----------- 2.x 2.6+, 3.4+ 3.x 2.7+, 3.5+ - 4.x *(currently on develop)* 3.6+ + 4.x *(currently on develop)* 3.7+ ============================== =========== diff --git a/requirements-lint.txt b/requirements-lint.txt index 9aefb7415..55d985d54 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -1,4 +1,4 @@ -pylint==2.11.1 -black==21.10b0 -mypy==0.910 +pylint==2.12.2 +black==21.12b0 +mypy==0.931 mypy-extensions==0.4.3 diff --git a/setup.py b/setup.py index 31318ac06..af47ecd4f 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,6 @@ classifiers=[ # a list of all available ones: https://pypi.org/classifiers/ "Programming Language :: Python", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", @@ -73,7 +72,7 @@ version=version, packages=find_packages(exclude=["test*", "doc", "scripts", "examples"]), scripts=list(filter(isfile, (join("scripts/", f) for f in listdir("scripts/")))), - author="Python CAN contributors", + author="python-can contributors", license="LGPL v3", package_data={ "": ["README.rst", "CONTRIBUTORS.txt", "LICENSE.txt", "CHANGELOG.txt"], @@ -82,7 +81,7 @@ }, # Installation # see https://www.python.org/dev/peps/pep-0345/#version-specifiers - python_requires=">=3.6", + python_requires=">=3.7", install_requires=[ "setuptools", "wrapt~=1.10", diff --git a/tox.ini b/tox.ini index 9964fb1e6..6b407dfeb 100644 --- a/tox.ini +++ b/tox.ini @@ -3,11 +3,11 @@ [testenv] deps = pytest==6.2.*,>=6.2.5 - pytest-timeout==2.0.1 + pytest-timeout==2.0.2 pytest-cov==3.0.0 - coverage==6.0.2 + coverage==6.2 codecov==2.1.12 - hypothesis~=6.24.0 + hypothesis~=6.35.0 pyserial~=3.5 parameterized~=0.8 From dd25e4b6feb7300028af4c5ce89a7646f85e684a Mon Sep 17 00:00:00 2001 From: Felix Divo <4403130+felixdivo@users.noreply.github.com> Date: Sat, 15 Jan 2022 11:52:40 +0100 Subject: [PATCH 18/27] Fix code formatting job --- .github/workflows/format-code.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml index c3356e211..b86789662 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.10 + python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip @@ -22,10 +22,7 @@ jobs: run: | black --verbose . - name: Commit Formated Code - uses: EndBug/add-and-commit@v5 - env: - # This is necessary in order to push a commit to the repo - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: EndBug/add-and-commit@v7 with: message: "Format code with black" # Ref https://git-scm.com/docs/git-add#_examples From 46ad7d46b92b3f1192c1511e67e3739becadf99f Mon Sep 17 00:00:00 2001 From: Felix Divo <4403130+felixdivo@users.noreply.github.com> Date: Sat, 15 Jan 2022 12:00:27 +0100 Subject: [PATCH 19/27] Disable Python 3.11 pre-releases --- .github/workflows/build.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 95b295f90..be222751c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,11 +14,12 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] experimental: [false] python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7", "pypy-3.8"] - include: + # Do not test on Python 3.11 pre-releases since wrapt causes problems: https://github.com/GrahamDumpleton/wrapt/issues/196 + # include: # Only test on a single configuration while there are just pre-releases - - os: ubuntu-latest - experimental: true - python-version: "3.11.0-alpha.3" + # - os: ubuntu-latest + # experimental: true + # python-version: "3.11.0-alpha.3" fail-fast: false steps: - uses: actions/checkout@v2 From 8641f5e02ec084b6754e38a7674aa72808a8de5c Mon Sep 17 00:00:00 2001 From: Felix Divo <4403130+felixdivo@users.noreply.github.com> Date: Sat, 15 Jan 2022 12:01:07 +0100 Subject: [PATCH 20/27] Test that the auto-formatting tool can still commit --- can/ctypesutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/can/ctypesutil.py b/can/ctypesutil.py index 7c1e1f573..ab4cb11b5 100644 --- a/can/ctypesutil.py +++ b/can/ctypesutil.py @@ -14,7 +14,7 @@ try: - _LibBase = ctypes.WinDLL # type: ignore + _LibBase = ctypes.WinDLL # type: ignore _FUNCTION_TYPE = ctypes.WINFUNCTYPE # type: ignore except AttributeError: _LibBase = ctypes.CDLL From 0acabbff21248b5c76039f026d31053711918147 Mon Sep 17 00:00:00 2001 From: felixdivo Date: Sat, 15 Jan 2022 11:01:42 +0000 Subject: [PATCH 21/27] Format code with black --- can/ctypesutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/can/ctypesutil.py b/can/ctypesutil.py index ab4cb11b5..7c1e1f573 100644 --- a/can/ctypesutil.py +++ b/can/ctypesutil.py @@ -14,7 +14,7 @@ try: - _LibBase = ctypes.WinDLL # type: ignore + _LibBase = ctypes.WinDLL # type: ignore _FUNCTION_TYPE = ctypes.WINFUNCTYPE # type: ignore except AttributeError: _LibBase = ctypes.CDLL From 954bb0295a845573d56a198c4b6c0d2d0fb8fdb7 Mon Sep 17 00:00:00 2001 From: Felix Divo <4403130+felixdivo@users.noreply.github.com> Date: Sat, 15 Jan 2022 21:37:48 +0100 Subject: [PATCH 22/27] Update README.rst This way, the information is not given twice and we actually mention **C**Python. --- README.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.rst b/README.rst index ac5537f7e..2d7f615e7 100644 --- a/README.rst +++ b/README.rst @@ -51,8 +51,7 @@ Python developers; providing common abstractions to different hardware devices, and a suite of utilities for sending and receiving messages on a can bus. -The library currently supports Python 3.6+ as well as PyPy 3 and runs -on Mac, Linux and Windows. +The library currently supports CPython as well as PyPy and runs on Mac, Linux and Windows. ============================== =========== Library Version Python From 1dd4581dc36352ffa374caccdcdd068dde03af29 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sat, 15 Jan 2022 21:57:18 +0100 Subject: [PATCH 23/27] Implement test of function calls --- test/test_player.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/test_player.py b/test/test_player.py index d510a3d00..c73623c05 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -41,8 +41,29 @@ def assertSuccessfulCleanup(self): def test_play_virtual(self): sys.argv = self.baseargs + [self.logfile] can.player.main() - self.assertEqual(self.mock_virtual_bus.send.call_count, 2) + msg1 = can.Message( + timestamp=2.501, + arbitration_id=0xC8, + is_extended_id=False, + is_fd=False, + is_rx=False, + channel=1, + dlc=8, + data=[0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2], + ) + msg2 = can.Message( + timestamp=17.876708, + arbitration_id=0x6F9, + is_extended_id=False, + is_fd=False, + is_rx=True, + channel=0, + dlc=8, + data=[0x5, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], + ) self.assertEqual(self.MockSleep.call_count, 2) + self.assertTrue(msg1.equals(self.mock_virtual_bus.send.mock_calls[0].args[0])) + self.assertTrue(msg2.equals(self.mock_virtual_bus.send.mock_calls[1].args[0])) self.assertSuccessfulCleanup() def test_play_virtual_verbose(self): From 3382d5310db30359c387889ca2f76b8c71b031e2 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sat, 15 Jan 2022 22:45:00 +0100 Subject: [PATCH 24/27] Limit test for correct calls to python versions >= 3.8 --- test/test_player.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index c73623c05..a4f9ed4ad 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -62,8 +62,10 @@ def test_play_virtual(self): data=[0x5, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], ) self.assertEqual(self.MockSleep.call_count, 2) - self.assertTrue(msg1.equals(self.mock_virtual_bus.send.mock_calls[0].args[0])) - self.assertTrue(msg2.equals(self.mock_virtual_bus.send.mock_calls[1].args[0])) + if sys.version_info.major > 3 or sys.version_info.minor >= 8: + # The args argument was introduced with python 3.8 + self.assertTrue(msg1.equals(self.mock_virtual_bus.send.mock_calls[0].args[0])) + self.assertTrue(msg2.equals(self.mock_virtual_bus.send.mock_calls[1].args[0])) self.assertSuccessfulCleanup() def test_play_virtual_verbose(self): From 67e409805e306fef778442d8c5d65d4c185324ee Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sat, 15 Jan 2022 21:45:54 +0000 Subject: [PATCH 25/27] Format code with black --- test/test_player.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index a4f9ed4ad..c58ff936e 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -64,8 +64,12 @@ def test_play_virtual(self): self.assertEqual(self.MockSleep.call_count, 2) if sys.version_info.major > 3 or sys.version_info.minor >= 8: # The args argument was introduced with python 3.8 - self.assertTrue(msg1.equals(self.mock_virtual_bus.send.mock_calls[0].args[0])) - self.assertTrue(msg2.equals(self.mock_virtual_bus.send.mock_calls[1].args[0])) + self.assertTrue( + msg1.equals(self.mock_virtual_bus.send.mock_calls[0].args[0]) + ) + self.assertTrue( + msg2.equals(self.mock_virtual_bus.send.mock_calls[1].args[0]) + ) self.assertSuccessfulCleanup() def test_play_virtual_verbose(self): From a5f0ef80d604643a21f6c4880564143adfcbf9fb Mon Sep 17 00:00:00 2001 From: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> Date: Sun, 16 Jan 2022 00:01:07 +0100 Subject: [PATCH 26/27] simplify version check --- test/test_player.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_player.py b/test/test_player.py index c58ff936e..efb446e9e 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -62,7 +62,7 @@ def test_play_virtual(self): data=[0x5, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], ) self.assertEqual(self.MockSleep.call_count, 2) - if sys.version_info.major > 3 or sys.version_info.minor >= 8: + if sys.version_info >= (3, 8): # The args argument was introduced with python 3.8 self.assertTrue( msg1.equals(self.mock_virtual_bus.send.mock_calls[0].args[0]) From 7a20405c5be293e7c293862fd096f126a4d20b89 Mon Sep 17 00:00:00 2001 From: Peter Kessen Date: Sun, 16 Jan 2022 11:33:19 +0100 Subject: [PATCH 27/27] Change shebang and remove coding Co-authored-by: Felix Divo <4403130+felixdivo@users.noreply.github.com> --- test/test_player.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_player.py b/test/test_player.py index efb446e9e..2f3307420 100755 --- a/test/test_player.py +++ b/test/test_player.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python3 -# coding: utf-8 +#!/usr/bin/env python """ This module tests the functions inside of player.py