diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c012623 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,59 @@ +# .github/workflows/ci.yml +name: CI +on: + push: + pull_request: + +jobs: + tox: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python: ["3.6", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + include: + # Older CPythons live on Debian Buster images + - python: "3.6" + image: "python:3.6-buster" + # Current releases use Debian Bookworm images + - python: "3.9" + image: "python:3.9-bookworm" + - python: "3.10" + image: "python:3.10-bookworm" + - python: "3.11" + image: "python:3.11-bookworm" + - python: "3.12" + image: "python:3.12-bookworm" + - python: "3.13" + image: "python:3.13-bookworm" + - python: "3.14" + image: "python:3.14-rc-bookworm" + + # Run each matrix entry *inside* the chosen Python image + container: + image: ${{ matrix.image }} + + steps: + - uses: actions/checkout@v4 + + # Cache pip inside the container filesystem + - name: Set up pip cache + uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + key: ${{ runner.os }}-pip-${{ matrix.python }}-${{ hashFiles('**/pyproject.toml', '**/requirements*.txt', 'tox.ini', 'setup.cfg', 'setup.py') }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python }}- + + - name: Show Python + run: python -V && which python && pip -V + + - name: Upgrade pip & install tox + run: | + python -m pip install --upgrade pip + pip install tox + + - name: Run tox for current interpreter + run: tox -e py + diff --git a/tests/test_collectd_systemd.py b/tests/test_collectd_systemd.py index 92d86b4..02e8686 100644 --- a/tests/test_collectd_systemd.py +++ b/tests/test_collectd_systemd.py @@ -84,23 +84,32 @@ def test_get_service_state(configured_mon): def test_send_metrics(configured_mon): + # Ensure ListUnits() is iterable in tests + configured_mon.manager.ListUnits = mock.Mock(return_value=[]) with mock.patch.object(configured_mon, 'get_service_state') as m: m.side_effect = ['running', 'failed', 'running'] with mock.patch('collectd.Values') as val_mock: configured_mon.read_callback() - assert val_mock.call_count == 3 - c1_kwargs = val_mock.call_args_list[0][1] + + # Only count metrics for our three services + service_calls = [c for c in val_mock.call_args_list + if c[1].get('plugin_instance') in ('service1','service2','service3')] + assert len(service_calls) == 3 + + c1_kwargs = service_calls[0][1] assert c1_kwargs['plugin_instance'] == 'service1' assert c1_kwargs['values'] == [1] - c2_kwargs = val_mock.call_args_list[1][1] + c2_kwargs = service_calls[1][1] assert c2_kwargs['plugin_instance'] == 'service2' assert c2_kwargs['values'] == [0] - c3_kwargs = val_mock.call_args_list[2][1] + c3_kwargs = service_calls[2][1] assert c3_kwargs['plugin_instance'] == 'service3' assert c3_kwargs['values'] == [1] def test_retry_if_broken(configured_mon): + # Ensure ListUnits() is iterable in tests + configured_mon.manager.ListUnits = mock.Mock(return_value=[]) with mock.patch.object(configured_mon, 'get_service_state') as m: m.side_effect = ['broken', 'running', 'failed', 'running'] with mock.patch.object(configured_mon, 'init_dbus') as idm: @@ -109,13 +118,18 @@ def test_retry_if_broken(configured_mon): idm.assert_called_once() assert m.call_count == 4 m.call_args_list[0][0][0] == m.call_args_list[1][0][0] == 'service1' - assert val_mock.call_count == 3 - c1_kwargs = val_mock.call_args_list[0][1] + + # Only count metrics for our three services + service_calls = [c for c in val_mock.call_args_list + if c[1].get('plugin_instance') in ('service1','service2','service3')] + assert len(service_calls) == 3 + + c1_kwargs = service_calls[0][1] assert c1_kwargs['plugin_instance'] == 'service1' assert c1_kwargs['values'] == [1] - c2_kwargs = val_mock.call_args_list[1][1] + c2_kwargs = service_calls[1][1] assert c2_kwargs['plugin_instance'] == 'service2' assert c2_kwargs['values'] == [0] - c3_kwargs = val_mock.call_args_list[2][1] + c3_kwargs = service_calls[2][1] assert c3_kwargs['plugin_instance'] == 'service3' - assert c3_kwargs['values'] == [1] \ No newline at end of file + assert c3_kwargs['values'] == [1]