diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c610c6a76..4f96578e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,10 +38,18 @@ jobs: run: | python -m pip install --upgrade pip pip install tox + - name: Setup SocketCAN + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + sudo apt-get -y install linux-modules-extra-$(uname -r) + sudo ./test/open_vcan.sh - name: Test with pytest via tox run: | tox -e gh - + env: + # SocketCAN tests currently fail with PyPy because it does not support raw CAN sockets + # See: https://foss.heptapod.net/pypy/pypy/-/issues/3809 + TEST_SOCKETCAN: "${{ matrix.os == 'ubuntu-latest' && ! startsWith(matrix.python-version, 'pypy' ) }}" - name: Coveralls Parallel uses: coverallsapp/github-action@master with: diff --git a/test/test_cyclic_socketcan.py b/test/test_cyclic_socketcan.py index ca1db6bfc..30c86d6a5 100644 --- a/test/test_cyclic_socketcan.py +++ b/test/test_cyclic_socketcan.py @@ -256,14 +256,8 @@ def test_start_already_started_task(self): task_a = self._send_bus.send_periodic(messages_a, self.PERIOD) time.sleep(0.1) - # Try to start it again, task_id is not incremented in this case - with self.assertRaises(can.CanOperationError) as ctx: - task_a.start() - self.assertEqual( - "A periodic task for task ID 1 is already in progress by the SocketCAN Linux layer", - str(ctx.exception), - ) - + # Task restarting is permitted as of #1440 + task_a.start() task_a.stop() def test_create_same_id(self): diff --git a/test/test_socketcan.py b/test/test_socketcan.py index 1c38e1583..324890dad 100644 --- a/test/test_socketcan.py +++ b/test/test_socketcan.py @@ -6,8 +6,17 @@ import ctypes import struct import unittest +import warnings from unittest.mock import patch +import can +from can.interfaces.socketcan.constants import ( + CAN_BCM_TX_DELETE, + CAN_BCM_TX_SETUP, + SETTIMER, + STARTTIMER, + TX_COUNTEVT, +) from can.interfaces.socketcan.socketcan import ( bcm_header_factory, build_bcm_header, @@ -16,13 +25,7 @@ build_bcm_update_header, BcmMsgHead, ) -from can.interfaces.socketcan.constants import ( - CAN_BCM_TX_DELETE, - CAN_BCM_TX_SETUP, - SETTIMER, - STARTTIMER, - TX_COUNTEVT, -) +from .config import IS_LINUX, IS_PYPY class SocketCANTest(unittest.TestCase): @@ -353,6 +356,24 @@ def test_build_bcm_update_header(self): self.assertEqual(can_id, result.can_id) self.assertEqual(1, result.nframes) + @unittest.skipUnless(IS_LINUX and IS_PYPY, "Only test when run on Linux with PyPy") + def test_pypy_socketcan_support(self): + """Wait for PyPy raw CAN socket support + + This test shall document raw CAN socket support under PyPy. Once this test fails, it is likely that PyPy + either implemented raw CAN socket support or at least changed the error that is thrown. + https://foss.heptapod.net/pypy/pypy/-/issues/3809 + https://github.com/hardbyte/python-can/issues/1479 + """ + try: + can.Bus(interface="socketcan", channel="vcan0", bitrate=500000) + except OSError as e: + if "unknown address family" not in str(e): + warnings.warn( + "Please check if PyPy has implemented raw CAN socket support! " + "See: https://foss.heptapod.net/pypy/pypy/-/issues/3809" + ) + if __name__ == "__main__": unittest.main() diff --git a/tox.ini b/tox.ini index 0dbd6423e..96cc82425 100644 --- a/tox.ini +++ b/tox.ini @@ -26,6 +26,7 @@ passenv = GITHUB_* COVERALLS_* PY_COLORS + TEST_SOCKETCAN [testenv:travis] passenv =