|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
# SPDX-FileCopyrightText: 2022 LEdoian <checklib@pokemon.ledoian.cz>
|
|
|
|
# SPDX-License-Identifier: WTFPL
|
|
|
|
|
|
|
|
import unittest
|
|
|
|
from checklib import Result, Check
|
|
|
|
from contextlib import redirect_stdout
|
|
|
|
from textwrap import dedent
|
|
|
|
import io
|
|
|
|
import sys
|
|
|
|
|
|
|
|
def make_check(
|
|
|
|
result=Result.UNKNOWN,
|
|
|
|
short_message='Just a message',
|
|
|
|
long_message = None):
|
|
|
|
class Result(Check):
|
|
|
|
def check(self):
|
|
|
|
self.short_status = short_message
|
|
|
|
self.result=result
|
|
|
|
if long_message is not None:
|
|
|
|
self.long_status = long_message
|
|
|
|
return Result
|
|
|
|
|
|
|
|
class DefaultCheck(Check): pass
|
|
|
|
class ExceptionInInit(Check):
|
|
|
|
def __init__(self):
|
|
|
|
raise ValueError('whatever')
|
|
|
|
|
|
|
|
class ExceptionInCheck(Check):
|
|
|
|
def check(self):
|
|
|
|
raise ValueError('whatever')
|
|
|
|
|
|
|
|
class ExitInInit(Check):
|
|
|
|
def __init__(self):
|
|
|
|
sys.exit(42)
|
|
|
|
|
|
|
|
class ExitInCheck(Check):
|
|
|
|
def check(self):
|
|
|
|
sys.exit(42)
|
|
|
|
|
|
|
|
class T(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.passing_check = make_check(Result.OK)
|
|
|
|
self.warning_check = make_check(Result.WARNING)
|
|
|
|
self.critical_check = make_check(Result.CRITICAL)
|
|
|
|
self.unknown_check = make_check(Result.UNKNOWN)
|
|
|
|
self.check_without_status = make_check(Result.OK, short_message = None)
|
|
|
|
|
|
|
|
# Multiline status:
|
|
|
|
# Ref: IT Crowd :-)
|
|
|
|
self.short_message = 'Subject: Fire!'
|
|
|
|
self.long_message = dedent('''\
|
|
|
|
Dear Sir / Madam,
|
|
|
|
|
|
|
|
I am writing to inform
|
|
|
|
you of a fire, that has broken…
|
|
|
|
No, that\'s too formal.''')
|
|
|
|
self.multiline_check = make_check(Result.OK, self.short_message, self.long_message)
|
|
|
|
# Other checks are given as separate classes.
|
|
|
|
self.all_checks = [
|
|
|
|
self.unknown_check,
|
|
|
|
ExceptionInCheck,
|
|
|
|
ExceptionInInit,
|
|
|
|
ExitInCheck,
|
|
|
|
ExitInInit,
|
|
|
|
DefaultCheck,
|
|
|
|
self.check_without_status,
|
|
|
|
self.multiline_check,
|
|
|
|
self.passing_check,
|
|
|
|
self.warning_check,
|
|
|
|
self.critical_check,
|
|
|
|
]
|
|
|
|
|
|
|
|
def test_run_exits(self):
|
|
|
|
for check in self.all_checks:
|
|
|
|
with self.subTest(check=check):
|
|
|
|
with self.assertRaises(SystemExit):
|
|
|
|
check.run()
|
|
|
|
|
|
|
|
def test_correct_return_code(self):
|
|
|
|
expected_results = {
|
|
|
|
Result.UNKNOWN: [
|
|
|
|
self.unknown_check,
|
|
|
|
ExceptionInCheck,
|
|
|
|
ExceptionInInit,
|
|
|
|
ExitInCheck,
|
|
|
|
ExitInInit,
|
|
|
|
DefaultCheck,
|
|
|
|
self.check_without_status,
|
|
|
|
],
|
|
|
|
Result.OK: [
|
|
|
|
self.multiline_check,
|
|
|
|
self.passing_check,
|
|
|
|
],
|
|
|
|
Result.WARNING: [
|
|
|
|
self.warning_check,
|
|
|
|
],
|
|
|
|
Result.CRITICAL: [
|
|
|
|
self.critical_check,
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
for result, checks in expected_results.items():
|
|
|
|
for check in checks:
|
|
|
|
with self.subTest(check=check, expected_result=result):
|
|
|
|
try:
|
|
|
|
check.run()
|
|
|
|
except SystemExit as e:
|
|
|
|
self.assertEqual(e.code, result.value)
|
|
|
|
|
|
|
|
def test_something_output(self):
|
|
|
|
for check in self.all_checks:
|
|
|
|
with self.subTest(check=check):
|
|
|
|
with redirect_stdout(io.StringIO()) as output:
|
|
|
|
try:
|
|
|
|
check.run()
|
|
|
|
except SystemExit:
|
|
|
|
pass
|
|
|
|
output = output.getvalue()
|
|
|
|
assert len(output) > 0
|
|
|
|
assert '\n' in output
|
|
|
|
|
|
|
|
def test_correct_output(self):
|
|
|
|
"""
|
|
|
|
The multiline status must contain both messages verbatim.
|
|
|
|
"""
|
|
|
|
with redirect_stdout(io.StringIO()) as output:
|
|
|
|
try:
|
|
|
|
self.multiline_check.run()
|
|
|
|
except SystemExit:
|
|
|
|
pass
|
|
|
|
output = output.getvalue()
|
|
|
|
self.assertIn(self.short_message, output)
|
|
|
|
self.assertIn(self.long_message, output)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main(
|
|
|
|
buffer=True,
|
|
|
|
)
|