def test__get_status__sleeping(mocker):
    """
    Test "_get_status" method must return main check status (sleeping case).
    """

    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    result = checker._get_status(
        data={
            "/dev/sda": {
                "template": "ok",
                "priority": 4,
                "data": {
                    "device": "/dev/sda",
                    "temperature": 27,
                    "scale": "C",
                    "warning": 40,
                    "critical": 65,
                },
            },
            "/dev/sdb": {
                "template": "sleeping",
                "priority": 5,
                "data": {
                    "device": "/dev/sdb",
                    "temperature": "SLP",
                    "scale": "C",
                    "warning": 40,
                    "critical": 65,
                },
            },
        })

    assert result == "ok"  # nosec: B101
def test_check__unknown_device__performance_data(mocker):
    """
    Test "check" method must return Nagios and human readable HDD's statuses
    with performance data (unknown device case).
    """

    expected = "UNKNOWN: device /dev/sdb temperature info not found in server response or can't be recognized by hddtemp, device /dev/sda is functional and stable 27C | /dev/sdb=None; /dev/sda=27\n"  # noqa: E501
    mocker.patch(
        "sys.argv",
        [
            "check_hddtemp.py",
            "-s",
            "127.0.0.1",
            "-p",
            "7634",
            "-P",
            "-d",
            "/dev/sda, /dev/sdb",
        ],
    )
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C|",
    )
    checker = CheckHDDTemp()
    result, code = checker.check()

    assert result == expected  # nosec: B101
    assert code == 3  # nosec: B101
def test__get_output__performance_data(mocker):
    """
    Test "_get_output" method must return human readable HDD's statuses
    with performance data.
    """

    expected = "OK: device /dev/sda is functional and stable 27C | /dev/sda=27\n"
    data = {
        "/dev/sda": {
            "template": "ok",
            "priority": 4,
            "data": {
                "device": "/dev/sda",
                "temperature": 27,
                "scale": "C",
                "warning": 40,
                "critical": 65,
            },
        },
    }
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634", "-P"])
    checker = CheckHDDTemp()
    status = checker._get_status(data=data)
    result = checker._get_output(data=data, status=status)

    assert result == expected  # nosec: B101
def test__check_data__unknown_device_temperature(mocker):
    """
    Test "_check_data" method must return devices states info
    (unknown device temperature case).
    """

    expected = {
        "/dev/sda": {
            "template": "unknown",
            "priority": 3,
            "data": {
                "device": "/dev/sda",
                "temperature": "UNK",
                "scale": "*",
                "warning": 40,
                "critical": 65,
            },
        },
    }
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    result = checker._check_data(data={
        "/dev/sda": {
            "model": "HARD DRIVE",
            "temperature": "UNK",
            "scale": "*"
        }
    })

    assert result == expected  # nosec: B101
def test__get_code(mocker):
    """
    Test "_get_code" method must return plugin exit code.
    """

    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    result = checker._get_code(status="ok")

    assert result == 0  # nosec: B101
def test__get_code__unknown_device_temperature(mocker):
    """
    Test "_get_code" method must return plugin exit code
    (unknown device temperature case).
    """

    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    result = checker._get_code(status="unknown")

    assert result == 3  # nosec: B101
def test__parse_data__parsing_error(mocker):
    """
    Test "_parse_data" method must exit with parsing error.
    """

    out = StringIO()
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()

    with pytest.raises(SystemExit):
        with contextlib2.redirect_stdout(out):
            checker._parse_data(data="|/dev/sda|HARD DRIVE|C|")  # noqa: E501

    assert "ERROR: Server response for device" in out.getvalue().strip(
    )  # nosec: B101
def test__parse_data__too_short_error(mocker):
    """
    Test "_parse_data" method must exit with too short response error.
    """

    out = StringIO()
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()

    with pytest.raises(SystemExit):
        with contextlib2.redirect_stdout(out):
            checker._parse_data(data="")

    assert "ERROR: Server response too short" in out.getvalue().strip(
    )  # nosec: B101
def test__get_data__network_error(mocker):
    """
    Test "_get_data" method must exit with network error.
    """

    out = StringIO()
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    mocker.patch("telnetlib.Telnet.read_all", side_effect=socket.error)
    mocker.patch("telnetlib.Telnet.read_all", side_effect=EOFError)
    checker = CheckHDDTemp()

    with pytest.raises(SystemExit):
        with contextlib2.redirect_stdout(out):
            checker._get_data()

    assert (  # nosec: B101
        "ERROR: Server communication problem" in out.getvalue().strip())
def test_check(mocker):
    """
    Test "check" method must return Nagios and human readable HDD's statuses.
    """

    expected = "OK: device /dev/sda is functional and stable 27C\n"
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C|",
    )
    checker = CheckHDDTemp()
    result, code = checker.check()

    assert result == expected  # nosec: B101
    assert code == 0  # nosec: B101
def test__get_data(mocker):
    """
    Test "_get_data" method must return data from server.
    """

    expected = "|/dev/sda|HARD DRIVE|27|C|"
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C|",
    )

    checker = CheckHDDTemp()
    result = checker._get_data()

    assert result == expected  # nosec: B101
def test__get_options(mocker):
    """
    Test "_get_options" method must return argparse namespace.
    """

    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()

    assert isinstance(checker.options, Namespace)  # nosec: B101
def test_check__unknown_device_temperature(mocker):
    """
    Test "_get_output" method must return Nagios and human readable HDD's statuses
    (unknown device temperature case).
    """

    expected = "UNKNOWN: device /dev/sdb temperature info not found in server response or can't be recognized by hddtemp, device /dev/sda is functional and stable 27C\n"  # noqa: E501
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C||/dev/sdb|HARD DRIVE|UNK|*|",
    )
    result, code = checker.check()

    assert result == expected  # nosec: B101
    assert code == 3  # nosec: B101
def test_check__warning__performance_data(mocker):
    """
    Test "check" method must return Nagios and human readable HDD's statuses
    with performance data (warning case).
    """

    expected = "WARNING: device /dev/sdb temperature 42C exceeds warning temperature threshold 40C, device /dev/sda is functional and stable 27C | /dev/sdb=42; /dev/sda=27\n"  # noqa: E501
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634", "-P"])
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C||/dev/sdb|HARD DRIVE|42|C|",
    )
    checker = CheckHDDTemp()
    result, code = checker.check()

    assert result == expected  # nosec: B101
    assert code == 1  # nosec: B101
def test_check__sleeping__performance_data(mocker):
    """
    Test "check" method must return Nagios and human readable HDD's statuses
    with performance data (sleeping case).
    """

    expected = "OK: device /dev/sda is functional and stable 27C, device /dev/sdb is sleeping | /dev/sda=27; /dev/sdb=SLP\n"  # noqa: E501
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634", "-P"])
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C||/dev/sdb|HARD DRIVE|SLP|*|",
    )
    checker = CheckHDDTemp()
    result, code = checker.check()

    assert result == expected  # nosec: B101
    assert code == 0  # nosec: B101
def test__parse_data(mocker):
    """
    Test "_parse_data" method must return structured data.
    """

    expected = {
        "/dev/sda": {
            "model": "HARD DRIVE",
            "temperature": "27",
            "scale": "C"
        },
    }
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    result = checker._parse_data(
        data="|/dev/sda|HARD DRIVE|27|C|")  # noqa: E501

    assert result == expected  # nosec: B101
def test_check__critical(mocker):
    """
    Test "_get_output" method must return Nagios and human readable HDD's statuses
    (critical case).
    """

    expected = "CRITICAL: device /dev/sdb temperature 69C exceeds critical temperature threshold 65C, device /dev/sda is functional and stable 27C\n"  # noqa: E501
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    mocker.patch("telnetlib.Telnet.open")
    mocker.patch(
        "telnetlib.Telnet.read_all",
        lambda data: b"|/dev/sda|HARD DRIVE|27|C||/dev/sdb|HARD DRIVE|69|C|",
    )
    checker = CheckHDDTemp()

    result, code = checker.check()

    assert result == expected  # nosec: B101
    assert code == 2  # nosec: B101
def test__get_output__sleeping(mocker):
    """
    Test "_get_output" method must return human readable HDD's statuses
    (sleeping case).
    """

    expected = "OK: device /dev/sda is functional and stable 27C, device /dev/sdb is sleeping\n"  # noqa: E501
    data = {
        "/dev/sda": {
            "template": "ok",
            "priority": 4,
            "data": {
                "device": "/dev/sda",
                "temperature": 27,
                "scale": "C",
                "warning": 40,
                "critical": 65,
            },
        },
        "/dev/sdb": {
            "template": "sleeping",
            "priority": 5,
            "data": {
                "device": "/dev/sdb",
                "temperature": "SLP",
                "scale": "C",
                "warning": 40,
                "critical": 65,
            },
        },
    }
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    status = checker._get_status(data=data)
    result = checker._get_output(data=data, status=status)

    assert result == expected  # nosec: B101
def test__get_output__unknown_device_temperature(mocker):
    """
    Test "_get_output" method must return human readable HDD's statuses
    (unknown device temperature case).
    """

    expected = "UNKNOWN: device /dev/sdb temperature info not found in server response or can't be recognized by hddtemp, device /dev/sda is functional and stable 27C\n"  # noqa: E501
    data = {
        "/dev/sda": {
            "template": "ok",
            "priority": 4,
            "data": {
                "device": "/dev/sda",
                "temperature": 27,
                "scale": "C",
                "warning": 40,
                "critical": 65,
            },
        },
        "/dev/sdb": {
            "template": "unknown",
            "priority": 3,
            "data": {
                "device": "/dev/sdb",
                "temperature": "UNK",
                "scale": "*",
                "warning": 40,
                "critical": 65,
            },
        },
    }
    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    status = checker._get_status(data=data)
    result = checker._get_output(data=data, status=status)

    assert result == expected  # nosec: B101
def test__get_options__missing_server_option(mocker):
    """
    Test "_get_options" method must exit with server option missing error.
    """

    out = StringIO()
    mocker.patch("sys.argv", ["check_hddtemp.py"])

    with pytest.raises(SystemExit):
        with contextlib2.redirect_stderr(out):
            CheckHDDTemp()

    assert (  # nosec: B101
        "Required server address option missing" in out.getvalue().strip())
def test__get_status__unknown_device_temperature(mocker):
    """
    Test "_get_status" method must return main check result
    (unknown device temperature case).
    """

    mocker.patch("sys.argv",
                 ["check_hddtemp.py", "-s", "127.0.0.1", "-p", "7634"])
    checker = CheckHDDTemp()
    result = checker._get_status(
        data={
            "/dev/sda": {
                "template": "ok",
                "priority": 4,
                "data": {
                    "device": "/dev/sda",
                    "temperature": 27,
                    "scale": "C",
                    "warning": 40,
                    "critical": 65,
                },
            },
            "/dev/sdb": {
                "template": "unknown",
                "priority": 3,
                "data": {
                    "device": "/dev/sdb",
                    "temperature": "UNK",
                    "scale": "*",
                    "warning": 40,
                    "critical": 65,
                },
            },
        })

    assert result == "unknown"  # nosec: B101
def test__get_options__warning_gte_critical(mocker):
    """
    Test "_get_options" method must exit with warning option
    greater or equal than critical error.
    """

    out = StringIO()
    mocker.patch(
        "sys.argv",
        ["check_hddtemp.py", "-s"
         "127.0.0.1", "-w", "65", "-c", "40"])

    with pytest.raises(SystemExit):
        with contextlib2.redirect_stderr(out):
            CheckHDDTemp()

    assert (  # nosec: B101
        "Warning temperature option value must be less than critical option value"
        in out.getvalue().strip())