Skip to content

host.service('test').is_running is throwing _Unexpected exit code 4_ exception on Ubuntu 24 #775

@pfuntner

Description

@pfuntner

systemctl is-active FOOBAR (where FOOBAR is a non-existent service) is behaving differently on Ubuntu 24. It has exit code 4 rather than exit code 3 on releases such as Ubuntu 20 and Ubuntu 22.

$ python3 -m pip list | grep -P pytest\|testinfra
pytest           8.3.3
pytest-testinfra 10.1.1
testinfra        6.0.0
$ cat ~/tmp/test_service.py
def test_service1(host):
  print(f'\ntest_service1: {host.service("test").is_running}')

def test_service2(host):
  running = host.run_expect([0, 1, 3, 4, 8], 'systemctl is-active test').rc == 0
  print(f'\ntest_service2: {running}')
$ pytest -s --connection ssh --hosts gcp-ubuntu2404 ~/tmp/test_service.py
/home/jpfuntne/third-party/pytest/lib/python3.11/site-packages/_testinfra_renamed.py:5: DeprecationWarning: testinfra package has been renamed to pytest-testinfra. Please `pip install pytest-testinfra` and `pip uninstall testinfra` and update your package requirements to avoid this message
  warnings.warn((
==================================================================================== test session starts =====================================================================================
platform linux -- Python 3.11.0rc1, pytest-8.3.3, pluggy-1.5.0
rootdir: /home/jpfuntne
plugins: testinfra-10.1.1, testinfra-6.0.0
collected 2 items

../tmp/test_service.py F
test_service2: False
.

========================================================================================== FAILURES ==========================================================================================
____________________________________________________________________________ test_service1[ssh://gcp-ubuntu2404] _____________________________________________________________________________

host = <testinfra.host.Host ssh://gcp-ubuntu2404>

    def test_service1(host):
>     print(f'\ntest_service1: {host.service("test").is_running}')

../tmp/test_service.py:2:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pytest/lib/python3.11/site-packages/testinfra/modules/service.py:184: in is_running
    out = self.run_expect([0, 1, 3], "systemctl is-active %s", self.name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'testinfra.modules.base.SystemdService'>, args = ([0, 1, 3], 'systemctl is-active %s', 'test'), kwargs = {}

    @classmethod
    def run_expect(cls, *args, **kwargs):
>       return cls._host.run_expect(*args, **kwargs)
E       AssertionError: Unexpected exit code 4 for CommandResult(backend=<testinfra.backend.ssh.SshBackend object at 0x7f63929a79d0>, exit_status=4, command=b'systemctl is-active test', _stdout=b'inactive\n', _stderr=b'')
E       assert 4 in [0, 1, 3]
E        +  where 4 = CommandResult(backend=<testinfra.backend.ssh.SshBackend object at 0x7f63929a79d0>, exit_status=4, command=b'systemctl is-active test', _stdout=b'inactive\n', _stderr=b'').rc

pytest/lib/python3.11/site-packages/testinfra/modules/base.py:44: AssertionError
================================================================================== short test summary info ===================================================================================
FAILED ../tmp/test_service.py::test_service1[ssh://gcp-ubuntu2404] - AssertionError: Unexpected exit code 4 for CommandResult(backend=<testinfra.backend.ssh.SshBackend object at 0x7f63929a79d0>, exit_status=4, command=b'systemctl is-active test', _stdout...
================================================================================ 1 failed, 1 passed in 2.21s =================================================================================
$

test_service2() is similar to SysvService.is_running() but accepts an exit status of 4 as well.

Here's an example of the same script working as expected on Ubuntu 22:

$ pytest -s --connection ssh --hosts gcp-ubuntu2204 ~/tmp/test_service.py
/home/jpfuntne/third-party/pytest/lib/python3.11/site-packages/_testinfra_renamed.py:5: DeprecationWarning: testinfra package has been renamed to pytest-testinfra. Please `pip install pytest-testinfra` and `pip uninstall testinfra` and update your package requirements to avoid this message
  warnings.warn((
==================================================================================== test session starts =====================================================================================
platform linux -- Python 3.11.0rc1, pytest-8.3.3, pluggy-1.5.0
rootdir: /home/jpfuntne
plugins: testinfra-10.1.1, testinfra-6.0.0
collected 2 items

../tmp/test_service.py
test_service1: False
.
test_service2: False
.

===================================================================================== 2 passed in 2.36s ======================================================================================
$

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions