import subprocess import unittest.mock import pytest from mnpw import nagios OUTPUT_1 = """DISK OK - free space: / 3326 MB (56%);""" OUTPUT_2 = ( """ DISK OK - free space: / 3326 MB (56%); | /=2643MB;5948;5958;0;5968""" ) OUTPUT_3 = """\ DISK OK - free space: / 3326 MB (56%); | /=2643MB;5948;5958;0;5968 / 15272 MB (77%); /boot 68 MB (69%); /home 69357 MB (27%); /var/log 819 MB (84%); | /boot=68MB;88;93;0;98 /home=69357MB;253404;253409;0;253414 /var/log=818MB;970;975;0;980 """ # Lifted from the Alignak project: # https://github.com/Alignak-monitoring/alignak/blob/fcc3d6499478ce67f4b91c694111f45cc8282535/tests/test_perfdata_parsing.py PERF_DATA = [ """ramused=90%;85;95;;""", """ramused=1009MB;;;0;1982 """, """memused=1550MB;2973;3964;0;5810""", """swapused=540MB;;;; """, """memused=90%""", """'Physical Memory Used'=12085620736Bytes; """, """Physical Memory Utilisation'=94%;80;90;""", """'C: used'=13.06452GB;22.28832;25.2601;0;29.71777 """, """'C: used %'=44%;75;85;0;100""", """time_offset-192.168.0.1=-7.22636468709e-05s;1;2;0;;""", """àéèï-192.168.0.1=-7.22636468709e-05s;1;2;0;;""", """Kernel=0;0;;0;2 Microcode=U;0;;0;1 Services=0;;0;0 Containers=0;;0;0 Sessions=0;0;;0""", # noqa: E501 ] @pytest.mark.parametrize( "command,args,exit_code", [ ("/bin/sh", ["-c", "exit 0"], nagios.NagiosCode.OK), ("/bin/sh", ["-c", "exit 1"], nagios.NagiosCode.WARNING), ("/bin/sh", ["-c", "exit 2"], nagios.NagiosCode.CRITICAL), ("/bin/sh", ["-c", "exit 3"], nagios.NagiosCode.UNKNOWN), ], ) def test_check_exec(command, args, exit_code): """Test the execution of checks.""" check = nagios.Check(command, args) check.run() assert check.ExitCode == exit_code def test_check_command_not_found(): """Test check with a nonexistent command.""" check = nagios.Check("/abcdef", []) with pytest.raises(RuntimeError): check.run() def test_check_timeout(): """Test check with a timed out command.""" check = nagios.Check("sleep", ["20"]) with pytest.raises(RuntimeError): check.run(timeout=3) def _mock_run(*args, **kwargs): """Mock subprocess' run.""" return unittest.mock.patch.object( nagios.subprocess, "run", *args, **kwargs, ) @pytest.mark.parametrize( "exception", [ FileNotFoundError, subprocess.TimeoutExpired(cmd="true", timeout=nagios.DEFAULT_TIMEOUT), ], ) def test_check_exceptions(exception): """Test handling of subprocess' run exceptions. See https://docs.python.org/3/library/subprocess.html?highlight=popen#subprocess.SubprocessError """ check = nagios.Check("true") with _mock_run(side_effect=exception), pytest.raises(RuntimeError): check.run() @pytest.mark.parametrize("output", [OUTPUT_1, OUTPUT_2, OUTPUT_3]) def test_output_parsing(output): """Test parsing of plugin output.""" check = nagios.Check("true") proc = subprocess.CompletedProcess( [ "true", ], 0, output, "", ) with _mock_run(return_value=proc): check.run() assert isinstance(check.Output, str) assert len(check.Output.splitlines()) == 1 @pytest.mark.parametrize("line", PERF_DATA) def test_data_perf(line): """Test parsing of perfdata.""" pd = nagios.parse_perf_data(line) assert isinstance(pd.name, str) assert len(pd.name) > 0 assert isinstance(pd.value, float) assert isinstance(pd.unit, (str, type(None))) assert isinstance(pd.warning, (float, type(None))) assert isinstance(pd.critical, (float, type(None))) assert isinstance(pd.min, (float, type(None))) assert isinstance(pd.max, (float, type(None)))