413 lines
12 KiB
Python
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()
|
|
|
|
|