2024-04-01 10:40:20 +02:00

413 lines
12 KiB
Python

from NSCP import Settings, Registry, Core, log, log_debug, log_error, status
import os
import inspect
test_manager = None
def install_testcases(tests, args = []):
test_manager = create_test_manager()
test_manager.add(tests)
test_manager.install()
def init_testcases(plugin_id, plugin_alias, script_alias, tests):
test_manager = create_test_manager(plugin_id, plugin_alias, script_alias)
test_manager.add(tests)
test_manager.init()
def shutdown_testcases():
if get_test_manager():
get_test_manager().shutdown()
destroy_test_manager()
def get_test_manager():
global test_manager
return test_manager
def destroy_test_manager():
global test_manager
if test_manager:
test_manager.destroy()
test_manager = None
def create_test_manager(plugin_id = 0, plugin_alias = '', script_alias = ''):
global test_manager
if not test_manager:
test_manager = TestManager(plugin_id, plugin_alias, script_alias)
reg = Registry.get(plugin_id)
reg.simple_cmdline('help', display_help)
reg.simple_cmdline('install_python_test', install_tests)
reg.simple_cmdline('run_python_test', run_tests)
reg.simple_function('py_unittest', run_tests, 'Run python unit test suite')
reg.simple_function('py_unittest_show_ok', set_show_ok, 'Set verbouse log')
reg.simple_function('py_unittest_add_case', add_case, 'Set which cases to run')
return test_manager
def add_test_suite(suites):
mgr = get_test_manager()
if isinstance(suites, (list)):
for s in suites:
mgr.add(s)
else:
mgr.add(suites)
def install_tests(arguments = []):
get_test_manager().install(arguments)
return (status.OK, 'installed?')
def run_tests(arguments = []):
result = get_test_manager().run(arguments)
return result.return_nagios(get_test_manager().show_all)
def set_show_ok(arguments = []):
get_test_manager().set_show_ok()
return (status.OK, 'Done')
def add_case(arguments = []):
get_test_manager().add_case(arguments)
return (status.OK, 'Done')
def display_help(arguments = []):
return (status.OK, 'TODO')
class Callable:
def __init__(self, anycallable):
self.__call__ = anycallable
class SingletonHelper:
klass = None
def __init__(self, klass):
self.klass = klass
def __call__(self, *args, **kw):
if not self.klass._instance:
self.klass._instance = self.klass()
return self.klass._instance
def setup_singleton(klass, src = None):
klass.getInstance = SingletonHelper(klass)
if not src:
cf = inspect.currentframe()
if cf:
bf = cf.f_back
if bf:
src = bf.f_code.co_filename
klass.__source__ = src
class BasicTest(object):
_instance = None
getInstance = None
__source__ = ''
def desc(self):
return 'TODO: Describe: %s'%self.title()
def title(self):
return self._instance.__class__.__name__
def setup(self, plugin_id, prefix):
None
def teardown(self):
None
def run_test(self):
result = TestResult('run_test')
result.add_message(False, 'TODO add implementation')
return result
def install(self, arguments):
conf = Settings.get()
conf.set_string('/modules', 'pytest', 'PythonScript')
fn = os.path.basename(self.__source__)
(sn, ext) = os.path.splitext(fn)
conf.register_key('/settings/pytest/scripts', sn, 'string', 'UNIT TEST SCRIPT: %s'%self.title(), 'A script for running unittests for: %s'%self.desc(), fn)
conf.set_string('/settings/pytest/scripts', sn, fn)
conf.save()
def uninstall(self):
None
def help(self):
None
def init(self, plugin_id):
None
def shutdown(self):
None
def require_boot(self):
return False
class TestResultEntry:
status = False
desc = 'Unassigned result'
error = None
def __init__(self, status, desc, error):
self.status = status
self.desc = desc
self.error = error
def log(self, show_all = False, prefix = '', indent = 0):
if self.status:
if show_all:
log('%s%s%s'%(prefix, ''.rjust(indent, ' '), self))
log_debug('%s%s%s'%(prefix, ''.rjust(indent, ' '), self))
else:
log_error('%s%s%s'%(prefix, ''.rjust(indent, ' '), self))
def is_ok(self):
return self.status
def count(self):
if self.status:
return (1, 1)
return (1, 0)
def contains(self, other):
if self == other:
return True
return False
def __str__(self):
if self.status:
return 'OK: %s'%self.desc
else:
return 'ERROR: %s (%s)'%(self.desc, self.error)
class TestResultCollection(TestResultEntry):
status = True
title = None
children = []
def __init__(self, title, list = None):
self.title = title
self.children = []
if list:
self.extend(list)
def log(self, show_all = False, prefix = '', indent = 0):
start = '%s%s'%(prefix, ''.rjust(indent, ' '))
if self.status:
if show_all:
log('%s%s'%(start, self))
log_debug('%s%s'%(start, self))
else:
log_error('%s%s'%(start, self))
for c in self.children:
c.log(show_all, prefix, indent+1)
def is_ok(self):
return self.status
def count(self):
total_count = 0
ok_count = 0
#if self.status:
# ok_count = 1
for c in self.children:
(total, ok) = c.count()
total_count = total_count + total
ok_count = ok_count + ok
return (total_count, ok_count)
def contains(self, other):
for c in self.children:
if c.contains(other):
return True
return False
def __str__(self):
if self.status:
return 'OK: %s'%self.title
else:
(total, ok) = self.count()
return 'ERROR: %s (%d/%d)'%(self.title, ok, total)
def extend(self, lst):
if isinstance(lst, list):
if self.status:
for c in lst:
if not c.is_ok():
self.status = False
for c in lst:
if c.contains(self):
log_error('Attempting to add a list with me in it')
return
self.children.extend(lst)
else:
self.append(lst)
def append(self, entry):
if not entry:
log_error('Attempting to add invalid entry (None)')
elif entry == self:
log_error('Attempting to add self to self')
else:
if self.status and not entry.is_ok():
self.status = False
self.children.append(entry)
class ArgumentParserError(Exception): pass
import argparse
class ThrowingArgumentParser(argparse.ArgumentParser):
def error(self, message):
raise ArgumentParserError(message)
class TestResult(TestResultCollection):
def __init__(self, title = 'DUMMY TITLE'):
TestResultCollection.__init__(self, title)
def add_message(self, status, message, error = None):
e = TestResultEntry(status, message, error)
e.log()
self.append(e)
def assert_equals(self, s1, s2, msg):
self.add_message(s1 == s2, msg, '"%s" != "%s"'%(s1, s2))
def assert_gt(self, v1, v2, msg):
self.add_message(v1 > v2, msg, '%d should be greater then %d'%(v1, v2))
def assert_lt(self, v1, v2, msg):
self.add_message(v1 < v2, msg, '%d should be less then %d'%(v1, v2))
def assert_contains(self, s1, s2, msg):
if s1 == s2:
self.add_message(s1 in s2 or s2 in s1, msg, '"%s" (contains) "%s"'%(s1, s2))
elif s1 == None or s2 == None:
self.add_message(False, msg, '"%s" (contains) "%s"'%(s1, s2))
else:
self.add_message(s1 in s2 or s2 in s1, msg, '"%s" (contains) "%s"'%(s1, s2))
def assert_not_contains(self, s1, s2, msg):
if s1 == s2:
self.add_message(False, msg, '"%s" (equals) "%s"'%(s1, s2))
elif s1 == None or s2 == None:
self.add_message(True, msg, '"%s" (is null?) "%s"'%(s1, s2))
else:
self.add_message(not (s1 in s2 or s2 in s1), msg, '"%s" (does not contains) "%s"'%(s1, s2))
def add_entry(self, e):
self.append(e)
def add(self, result):
self.extend(result)
def return_nagios(self, show_all = False):
(total, ok) = self.count()
self.log(show_all, ' | ')
if total == ok:
return (status.OK, "OK: %d test(s) successfull"%(total))
else:
return (status.CRITICAL, "ERROR: %d/%d test(s) failed"%(total-ok, total))
class TestManager:
suites = []
prefix = ''
plugin_id = None
plugin_alias = None
script_alias = None
show_all = False
cases = []
def __init__(self, plugin_id = 0, plugin_alias = '', script_alias = ''):
if script_alias:
self.prefix = '%s_'%script_alias
self.plugin_id = plugin_id
self.plugin_alias = plugin_alias
self.script_alias = script_alias
self.suites = []
self.show_all = False
self.cases = []
def set_show_ok(self):
self.show_all = True
def add_case(self, cases):
self.cases.extend(cases)
def add(self, suite):
if isinstance(suite, list):
for s in suite:
self.add(s)
else:
if not suite in self.suites:
self.suites.append(suite)
def run_suite(self, suite):
result = TestResult('Running suite: %s'%suite.title())
for c in list:
result.add(run_test(plugin_id, prefix, c))
return result
def run(self, arguments = []):
result = TestResult('Test result for %d suites'%len(self.suites))
for suite in self.suites:
instance = suite.getInstance()
instance.setup(self.plugin_id, self.prefix)
suite_result = TestResult('Running suite: %s'%instance.title())
if self.cases:
suite_result.append(instance.run_test(self.cases))
else:
suite_result.append(instance.run_test())
result.append(suite_result)
result.add_message(suite_result.is_ok(), 'Result from suite: %s'%instance.title())
instance.teardown()
return result
def init(self):
for suite in self.suites:
instance = suite.getInstance()
instance.init(self.plugin_id, self.prefix)
def destroy(self):
self.suites = []
self.prefix = ''
self.plugin_id = None
self.plugin_alias = None
self.script_alias = None
def install(self, arguments = []):
boot = False
for suite in self.suites:
instance = suite.getInstance()
instance.install(arguments)
if instance.require_boot():
boot = True
#core = Core.get()
#core.reload('service')
#(code, msg, perf) = core.simple_query('py_unittest', [])
log('-+---==(TEST INSTALLER)==---------------------------------------------------+-')
log(' | Setup nessecary configuration for running test |')
log(' | This includes: Loading the PythonScript module at startup |')
log(' | To use this please run nsclient++ in "test mode" like so: |')
if boot:
log(' | nscp client --boot --query py_unittest |')
else:
log(' | nscp client --query py_unittest |')
log('-+--------------------------------------------------------==(DAS ENDE!)==---+-')
def shutdown(self):
for suite in self.suites:
instance = suite.getInstance()
instance.uninstall()
for suite in self.suites:
instance = suite.getInstance()
instance.shutdown()