Commit 78a3eb8e authored by Julien Muchembled's avatar Julien Muchembled Committed by Klaus Wölfel

testnode: more code clean up

parent 841301f7
import unittest import unittest
from unittest import TestCase from unittest import TestCase
from erp5.util.testnode.testnode import TestNode from erp5.util.testnode.testnode import TestNode, test_type_registry
from erp5.util.testnode.NodeTestSuite import SlapOSInstance from erp5.util.testnode.NodeTestSuite import SlapOSInstance, NodeTestSuite
from erp5.util.testnode.ProcessManager import ProcessManager, SubprocessError from erp5.util.testnode.ProcessManager import ProcessManager, SubprocessError
from erp5.util.testnode.Updater import Updater from erp5.util.testnode.Updater import Updater
from erp5.util.testnode.SlapOSMasterCommunicator import SlapOSMasterCommunicator from erp5.util.testnode.SlapOSMasterCommunicator import SlapOSMasterCommunicator
from erp5.util.testnode.SlapOSControler import SlapOSControler from erp5.util.testnode.SlapOSControler import SlapOSControler
from erp5.util.testnode.UnitTestRunner import UnitTestRunner
from erp5.util.testnode.ScalabilityTestRunner import ScalabilityTestRunner
from erp5.util.testnode.SlapOSControler import createFolder from erp5.util.testnode.SlapOSControler import createFolder
from erp5.util.taskdistribution import TaskDistributor from erp5.util.taskdistribution import TaskDistributor
...@@ -55,14 +53,6 @@ class ERP5TestNode(TestCase): ...@@ -55,14 +53,6 @@ class ERP5TestNode(TestCase):
print "TESTNODE LOG : %r, %r" % (arg, kw) print "TESTNODE LOG : %r, %r" % (arg, kw)
self.log = log self.log = log
def returnGoodClassRunner(self, test_type):
if test_type == 'UnitTest':
return UnitTestRunner
elif test_type == 'ScalabilityTest':
return ScalabilityTestRunner
else:
raise NotImplementedError
def tearDown(self): def tearDown(self):
shutil.rmtree(self._temp_dir, True) shutil.rmtree(self._temp_dir, True)
...@@ -126,7 +116,7 @@ class ERP5TestNode(TestCase): ...@@ -126,7 +116,7 @@ class ERP5TestNode(TestCase):
""" """
Update from zero/Regenerate the testsuite Update from zero/Regenerate the testsuite
""" """
node_test_suite.edit(working_directory=self.working_directory, node_test_suite.edit(
**self.getTestSuiteData(add_third_repository=add_third_repository, **self.getTestSuiteData(add_third_repository=add_third_repository,
add_broken_repository=add_broken_repository)[0]) add_broken_repository=add_broken_repository)[0])
...@@ -187,8 +177,9 @@ class ERP5TestNode(TestCase): ...@@ -187,8 +177,9 @@ class ERP5TestNode(TestCase):
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
self.assertEquals(0, node_test_suite.retry_software_count) self.assertEquals(0, node_test_suite.retry_software_count)
node_test_suite.retry_software_count = 2 node_test_suite.retry_software_count = 2
self.assertIs(node_test_suite, test_node.getNodeTestSuite('foo'))
self.assertEquals(2, node_test_suite.retry_software_count) self.assertEquals(2, node_test_suite.retry_software_count)
node_test_suite = test_node.delNodeTestSuite('foo') del test_node.node_test_suite_dict['foo']
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
self.assertEquals(0, node_test_suite.retry_software_count) self.assertEquals(0, node_test_suite.retry_software_count)
...@@ -198,7 +189,6 @@ class ERP5TestNode(TestCase): ...@@ -198,7 +189,6 @@ class ERP5TestNode(TestCase):
""" """
test_node = self.getTestNode() test_node = self.getTestNode()
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
node_test_suite.edit(working_directory=self.working_directory)
self.assertEquals("%s/foo" % self.working_directory, self.assertEquals("%s/foo" % self.working_directory,
node_test_suite.working_directory) node_test_suite.working_directory)
self.assertEquals("%s/foo/test_suite" % self.working_directory, self.assertEquals("%s/foo/test_suite" % self.working_directory,
...@@ -462,83 +452,56 @@ develop = false ...@@ -462,83 +452,56 @@ develop = false
test_node = self.getTestNode() test_node = self.getTestNode()
test_suite_data = self.getTestSuiteData(add_third_repository=True) test_suite_data = self.getTestSuiteData(add_third_repository=True)
self.assertEquals([], os.listdir(self.working_directory)) self.assertEquals([], os.listdir(self.working_directory))
test_node.checkOldTestSuite(test_suite_data) test_node.purgeOldTestSuite(test_suite_data)
self.assertEquals([], os.listdir(self.working_directory)) self.assertEquals([], os.listdir(self.working_directory))
os.mkdir(os.path.join(self.working_directory, 'foo')) os.mkdir(os.path.join(self.working_directory, 'foo'))
self.assertEquals(['foo'], os.listdir(self.working_directory)) self.assertEquals(['foo'], os.listdir(self.working_directory))
test_node.checkOldTestSuite(test_suite_data) test_node.purgeOldTestSuite(test_suite_data)
self.assertEquals(['foo'], os.listdir(self.working_directory)) self.assertEquals(['foo'], os.listdir(self.working_directory))
os.mkdir(os.path.join(self.working_directory, 'bar')) os.mkdir(os.path.join(self.working_directory, 'bar'))
self.assertEquals(set(['bar','foo']), self.assertEquals(set(['bar','foo']),
set(os.listdir(self.working_directory))) set(os.listdir(self.working_directory)))
test_node.checkOldTestSuite(test_suite_data) test_node.purgeOldTestSuite(test_suite_data)
self.assertEquals(['foo'], os.listdir(self.working_directory)) self.assertEquals(['foo'], os.listdir(self.working_directory))
def test_08_getSupportedParamaterSet(self):
original_spawn = ProcessManager.spawn
try:
def get_help(self, *args, **kw):
return {'stdout': """My Program
--foo foo
--bar bar"""}
ProcessManager.spawn = get_help
process_manager = ProcessManager(log=None)
parameter_list = ['--foo', '--baz']
expected_suported_parameter_set = set(['--foo'])
supported_parameter_set = process_manager.getSupportedParameterSet(
"dummy_program_path", parameter_list)
self.assertEquals(expected_suported_parameter_set, supported_parameter_set)
finally:
ProcessManager.spawn = original_spawn
def test_09_runTestSuite(self, my_test_type='UnitTest'): def test_09_runTestSuite(self, my_test_type='UnitTest'):
""" """
Check parameters passed to runTestSuite Check parameters passed to runTestSuite
Also make sure that --firefox_bin and --xvfb_bin are passed when needed Also make sure that optional parameters are passed when needed
""" """
original_getSupportedParameter = ProcessManager.getSupportedParameterSet call_parameter_list = []
original_spawn = ProcessManager.spawn parser = argparse.ArgumentParser()
try: parser.add_argument('--foo', type=int)
# Create a file parser.add_argument('--hello_world', help='Hello world!')
def _createPath(path_to_create, end_path): def spawn(*args, **kw):
os.makedirs(path_to_create) if args[1] == '--help':
return os.close(os.open(os.path.join(path_to_create, return {'stdout': parser.format_help()}
end_path),os.O_CREAT)) call_parameter_list.append(args)
def get_parameters(self, *args, **kw): test_node = self.getTestNode()
call_parameter_list.append({'args': [x for x in args], 'kw':kw}) test_node.process_manager.spawn = spawn
runner = test_type_registry[my_test_type](test_node)
# Create and initialise/regenerate a nodetestsuite
node_test_suite = test_node.getNodeTestSuite('foo')
self.updateNodeTestSuiteData(node_test_suite)
node_test_suite.revision_list = ('dummy', (0, '')),
def patch_getSupportedParameterSet(self, run_test_suite_path, parameter_list,): path = runner.getInstanceRoot(node_test_suite) + '/a/bin/runTestSuite'
if '--firefox_bin' and '--xvfb_bin' in parameter_list: os.makedirs(os.path.dirname(path))
return set(['--firefox_bin','--xvfb_bin']) os.close(os.open(path, os.O_CREAT))
else:
return []
test_node = self.getTestNode() expected_parameter_list = [path,
RunnerClass = self.returnGoodClassRunner(my_test_type) '--master_url', 'http://foo.bar',
runner = RunnerClass(test_node) '--revision', 'dummy=0-',
slapos_controler = runner._getSlapOSControler(self.working_directory) '--test_suite', 'Foo',
# Create and initialise/regenerate a nodetestsuite '--test_suite_title', 'Foo-Test',
node_test_suite = test_node.getNodeTestSuite('foo') ]
self.updateNodeTestSuiteData(node_test_suite) def checkRunTestSuiteParameters():
node_test_suite.revision = 'dummy' runner.runTestSuite(node_test_suite, "http://foo.bar")
# Path to the dummy runable self.assertEqual(list(call_parameter_list.pop()), expected_parameter_list)
run_test_suite_path = _createPath( self.assertFalse(call_parameter_list)
os.path.join(slapos_controler.instance_root,'a/bin'),'runTestSuite')
def checkRunTestSuiteParameters(additional_parameter_list=None): checkRunTestSuiteParameters()
ProcessManager.getSupportedParameterSet = patch_getSupportedParameterSet
ProcessManager.spawn = get_parameters
RunnerClass = self.returnGoodClassRunner(my_test_type)
runner = RunnerClass(test_node)
runner.runTestSuite(node_test_suite,"http://foo.bar")
expected_parameter_list = ['%s/a/bin/runTestSuite'
%(slapos_controler.instance_root), '--test_suite', 'Foo', '--revision',
'dummy', '--test_suite_title', 'Foo-Test', '--node_quantity', 3, '--master_url',
'http://foo.bar']
if additional_parameter_list:
expected_parameter_list.extend(additional_parameter_list)
self.assertEqual(call_parameter_list[0]['args'], expected_parameter_list)
def part(path): # in "bar" SR def part(path): # in "bar" SR
path = test_node.config['slapos_directory'] \ path = test_node.config['slapos_directory'] \
...@@ -556,13 +519,29 @@ develop = false ...@@ -556,13 +519,29 @@ develop = false
expected_parameter_list += option expected_parameter_list += option
checkRunTestSuiteParameters() checkRunTestSuiteParameters()
def test_08_getSupportedParamaterSet(self):
original_spawn = ProcessManager.spawn
try:
def get_help(self, *args, **kw):
return {'stdout': """My Program
--foo foo
--bar bar"""}
ProcessManager.spawn = get_help
process_manager = ProcessManager(log=None)
parameter_list = ['--foo', '--baz']
expected_suported_parameter_set = set(['--foo'])
supported_parameter_set = process_manager.getSupportedParameterSet(
"dummy_program_path", parameter_list)
self.assertEquals(expected_suported_parameter_set, supported_parameter_set)
finally:
ProcessManager.spawn = original_spawn
def test_10_prepareSlapOS(self, my_test_type='UnitTest'): def test_10_prepareSlapOS(self, my_test_type='UnitTest'):
test_node = self.getTestNode() test_node = self.getTestNode()
test_node_slapos = SlapOSInstance() test_node_slapos = SlapOSInstance(self.slapos_directory)
RunnerClass = self.returnGoodClassRunner(my_test_type) runner = test_type_registry[my_test_type](test_node)
runner = RunnerClass(test_node)
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
node_test_suite.edit(working_directory=self.working_directory)
status_dict = {"status_code" : 0} status_dict = {"status_code" : 0}
global call_list global call_list
call_list = [] call_list = []
...@@ -676,7 +655,7 @@ develop = false ...@@ -676,7 +655,7 @@ develop = false
original_sleep = time.sleep original_sleep = time.sleep
time.sleep = doNothing time.sleep = doNothing
self.generateTestRepositoryList() self.generateTestRepositoryList()
RunnerClass = self.returnGoodClassRunner(my_test_type) RunnerClass = test_type_registry[my_test_type]
# Patch # Patch
if my_test_type == "ScalabilityTest": if my_test_type == "ScalabilityTest":
original_getSlaposAccountKey = TaskDistributor.getSlaposAccountKey original_getSlaposAccountKey = TaskDistributor.getSlaposAccountKey
...@@ -758,7 +737,6 @@ develop = false ...@@ -758,7 +737,6 @@ develop = false
def test_14_createFolder(self): def test_14_createFolder(self):
test_node = self.getTestNode() test_node = self.getTestNode()
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
node_test_suite.edit(working_directory=self.working_directory)
folder = node_test_suite.test_suite_directory folder = node_test_suite.test_suite_directory
self.assertEquals(False, os.path.exists(folder)) self.assertEquals(False, os.path.exists(folder))
createFolder(folder) createFolder(folder)
...@@ -834,7 +812,7 @@ develop = false ...@@ -834,7 +812,7 @@ develop = false
self.assertEquals(1, len([x for x in suite_log.readlines() \ self.assertEquals(1, len([x for x in suite_log.readlines() \
if x.find("Activated logfile")>=0])) if x.find("Activated logfile")>=0]))
RunnerClass = self.returnGoodClassRunner(my_test_type) RunnerClass = test_type_registry[my_test_type]
original_sleep = time.sleep original_sleep = time.sleep
time.sleep = doNothing time.sleep = doNothing
self.generateTestRepositoryList() self.generateTestRepositoryList()
...@@ -954,8 +932,7 @@ develop = false ...@@ -954,8 +932,7 @@ develop = false
SlapOSControler.initializeSlapOSControler SlapOSControler.initializeSlapOSControler
initial_runSoftwareRelease = SlapOSControler.runSoftwareRelease initial_runSoftwareRelease = SlapOSControler.runSoftwareRelease
test_node = self.getTestNode() test_node = self.getTestNode()
RunnerClass = self.returnGoodClassRunner(my_test_type) runner = test_type_registry[my_test_type](test_node)
runner = RunnerClass(test_node)
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
init_call_kw_list = [] init_call_kw_list = []
def initializeSlapOSControler(self, **kw): def initializeSlapOSControler(self, **kw):
...@@ -1061,7 +1038,7 @@ develop = false ...@@ -1061,7 +1038,7 @@ develop = false
os.makedirs(test_result_path_root) os.makedirs(test_result_path_root)
self.generateTestRepositoryList() self.generateTestRepositoryList()
# Select the good runner to modify # Select the good runner to modify
RunnerClass = self.returnGoodClassRunner('ScalabilityTest') RunnerClass = test_type_registry['ScalabilityTest']
# Patch methods # Patch methods
original_sleep = time.sleep original_sleep = time.sleep
original_getSlaposAccountKey = TaskDistributor.getSlaposAccountKey original_getSlaposAccountKey = TaskDistributor.getSlaposAccountKey
......
...@@ -37,38 +37,28 @@ class SlapOSInstance(object): ...@@ -37,38 +37,28 @@ class SlapOSInstance(object):
Base of an software instance, Base of an software instance,
store variables used during software installation store variables used during software installation
""" """
def __init__(self): def __init__(self, working_directory):
self.retry_software_count = 0 self.retry_software_count = 0
self.retry = False self.retry = False
self.working_directory = working_directory
def edit(self, **kw):
self.__dict__.update(**kw)
self._checkData()
def _checkData(self):
pass
class NodeTestSuite(SlapOSInstance): class NodeTestSuite(SlapOSInstance):
""" """
""" """
def __init__(self, reference): def __init__(self, reference, working_directory):
super(NodeTestSuite, self).__init__() d = os.path.join(working_directory, reference)
super(NodeTestSuite, self).__init__(d)
self.reference = reference self.reference = reference
self.cluster_configuration = {} self.cluster_configuration = {}
self.test_suite_directory = os.path.join(d, 'test_suite')
self.custom_profile_path = os.path.join(d, 'software.cfg')
createFolder(d)
def _checkData(self): def edit(self, **kw):
if getattr(self, "working_directory", None) is not None: self.__dict__.update(**kw)
if not(self.working_directory.endswith(os.path.sep + self.reference)): for vcs_repository in kw.get('vcs_repository_list', ()):
self.working_directory = os.path.join(self.working_directory,
self.reference)
createFolder(self.working_directory)
self.test_suite_directory = os.path.join(
self.working_directory, "test_suite")
self.custom_profile_path = os.path.join(self.working_directory,
'software.cfg')
if getattr(self, "vcs_repository_list", None) is not None:
for vcs_repository in self.vcs_repository_list:
buildout_section_id = vcs_repository.get('buildout_section_id') buildout_section_id = vcs_repository.get('buildout_section_id')
repository_id = buildout_section_id or \ repository_id = buildout_section_id or \
vcs_repository.get('url').split('/')[-1].split('.')[0] vcs_repository.get('url').split('/')[-1].split('.')[0]
......
...@@ -99,12 +99,6 @@ class SlapOSControler(object): ...@@ -99,12 +99,6 @@ class SlapOSControler(object):
else: else:
raise ValueError("Configuration file not found.") raise ValueError("Configuration file not found.")
def getInstanceRequestedState(self, reference):
try:
return self.instance_config[reference]['requested_state']
except Exception:
raise ValueError("Instance '%s' not exist" %self.instance_config[reference])
def request(self, reference, software_url, software_type=None, def request(self, reference, software_url, software_type=None,
software_configuration=None, computer_guid=None, state='started'): software_configuration=None, computer_guid=None, state='started'):
""" """
...@@ -219,7 +213,7 @@ class SlapOSControler(object): ...@@ -219,7 +213,7 @@ class SlapOSControler(object):
self.software_path_list = software_path_list self.software_path_list = software_path_list
self.log('SlapOSControler, initialize, reset_software: %r', reset_software) self.log('SlapOSControler, initialize, reset_software: %r', reset_software)
config = self.config config = self.config
slapos_config_dict = self.config.copy() slapos_config_dict = config.copy()
slapos_config_dict.update(software_root=self.software_root, slapos_config_dict.update(software_root=self.software_root,
instance_root=self.instance_root, instance_root=self.instance_root,
proxy_database=self.proxy_database) proxy_database=self.proxy_database)
......
...@@ -102,7 +102,7 @@ class UnitTestRunner(object): ...@@ -102,7 +102,7 @@ class UnitTestRunner(object):
# report-url, report-project and suite-url are required to seleniumrunner # report-url, report-project and suite-url are required to seleniumrunner
# instance. This is a hack which must be removed. # instance. This is a hack which must be removed.
config = self.testnode.config config = self.testnode.config
return self._prepareSlapOS(config['slapos_directory'], return self._prepareSlapOS(test_node_slapos.working_directory,
test_node_slapos, self.testnode.log, create_partition=0, test_node_slapos, self.testnode.log, create_partition=0,
software_path_list=config.get("software_list"), software_path_list=config.get("software_list"),
cluster_configuration={ cluster_configuration={
...@@ -120,16 +120,18 @@ class UnitTestRunner(object): ...@@ -120,16 +120,18 @@ class UnitTestRunner(object):
software_path_list=[node_test_suite.custom_profile_path], software_path_list=[node_test_suite.custom_profile_path],
cluster_configuration={'_': json.dumps(node_test_suite.cluster_configuration)}) cluster_configuration={'_': json.dumps(node_test_suite.cluster_configuration)})
def getInstanceRoot(self, node_test_suite):
return self._getSlapOSControler(
node_test_suite.working_directory).instance_root
def runTestSuite(self, node_test_suite, portal_url, log=None): def runTestSuite(self, node_test_suite, portal_url, log=None):
config = self.testnode.config config = self.testnode.config
parameter_list = [] run_test_suite_path_list = glob.glob(
slapos_controler = self._getSlapOSControler(self.testnode.working_directory) self.getInstanceRoot(node_test_suite) + "/*/bin/runTestSuite")
run_test_suite_path_list = sorted(glob.glob("%s/*/bin/runTestSuite" % \ try:
slapos_controler.instance_root)) run_test_suite_path = min(run_test_suite_path_list)
if not len(run_test_suite_path_list): except ValueError:
raise ValueError('No runTestSuite provided in installed partitions.') raise ValueError('No runTestSuite provided in installed partitions.')
run_test_suite_path = run_test_suite_path_list[0]
run_test_suite_revision = node_test_suite.revision
# Deal with Shebang size limitation # Deal with Shebang size limitation
invocation_list = dealShebang(run_test_suite_path) invocation_list = dealShebang(run_test_suite_path)
invocation_list += (run_test_suite_path, invocation_list += (run_test_suite_path,
...@@ -172,4 +174,4 @@ class UnitTestRunner(object): ...@@ -172,4 +174,4 @@ class UnitTestRunner(object):
Used by the method testnode.constructProfile() to know Used by the method testnode.constructProfile() to know
if the software.cfg have to use relative path or not. if the software.cfg have to use relative path or not.
""" """
return False return False
\ No newline at end of file
...@@ -29,14 +29,8 @@ import argparse ...@@ -29,14 +29,8 @@ import argparse
import logging import logging
import logging.handlers import logging.handlers
import os import os
import pkg_resources
from testnode import TestNode from .testnode import TestNode
CONFIG = {
'computer_id': 'COMPUTER',
'partition_reference': 'test0',
}
def main(*args): def main(*args):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
...@@ -54,6 +48,10 @@ def main(*args): ...@@ -54,6 +48,10 @@ def main(*args):
logging.basicConfig(level=logging.INFO, logging.basicConfig(level=logging.INFO,
format=logger_format) format=logger_format)
logger = logging.getLogger('erp5testnode') logger = logging.getLogger('erp5testnode')
CONFIG = {
'logger': logger.info,
'partition_reference': 'test0',
}
if parsed_argument.console or parsed_argument.logfile: if parsed_argument.console or parsed_argument.logfile:
if parsed_argument.console: if parsed_argument.console:
logger.addHandler(logging.StreamHandler()) logger.addHandler(logging.StreamHandler())
...@@ -64,11 +62,10 @@ def main(*args): ...@@ -64,11 +62,10 @@ def main(*args):
maxBytes=20000000, backupCount=4) maxBytes=20000000, backupCount=4)
file_handler.setFormatter(formatter) file_handler.setFormatter(formatter)
logger.addHandler(file_handler) logger.addHandler(file_handler)
logger.info('Activated logfile %r output' % parsed_argument.logfile) logger.info('Activated logfile %r output', parsed_argument.logfile)
CONFIG['log_file'] = parsed_argument.logfile CONFIG['log_file'] = parsed_argument.logfile
else: else:
logger.addHandler(logging.NullHandler()) logger.addHandler(logging.NullHandler())
CONFIG['logger'] = logger.info
config = ConfigParser.SafeConfigParser() config = ConfigParser.SafeConfigParser()
# do not change case of option keys # do not change case of option keys
config.optionxform = str config.optionxform = str
......
...@@ -53,6 +53,11 @@ class DummyLogger(object): ...@@ -53,6 +53,11 @@ class DummyLogger(object):
'critical', 'fatal'): 'critical', 'fatal'):
setattr(self, name, func) setattr(self, name, func)
test_type_registry = {
'UnitTest': UnitTestRunner,
'ScalabilityTest': ScalabilityTestRunner,
}
class TestNode(object): class TestNode(object):
def __init__(self, log, config, max_log_time=MAX_LOG_TIME, def __init__(self, log, config, max_log_time=MAX_LOG_TIME,
...@@ -68,36 +73,29 @@ class TestNode(object): ...@@ -68,36 +73,29 @@ class TestNode(object):
self.max_temp_time = max_temp_time self.max_temp_time = max_temp_time
self.url_access = "https://[0::0]:0123" # Ipv6 + port of the node self.url_access = "https://[0::0]:0123" # Ipv6 + port of the node
def purgeOldTestSuite(self, test_suite_data):
def checkOldTestSuite(self,test_suite_data): reference_set = set(os.listdir(self.working_directory))
installed_reference_set = set(os.listdir(self.working_directory)) reference_set.difference_update(x['test_suite_reference']
wished_reference_set = set([x['test_suite_reference'] for x in test_suite_data]) for x in test_suite_data)
to_remove_reference_set = installed_reference_set.difference( for reference in reference_set:
wished_reference_set) fpath = os.path.join(self.working_directory, reference)
for y in to_remove_reference_set: self.node_test_suite_dict.pop(reference, None)
fpath = os.path.join(self.working_directory,y) self.log("testnode.purgeOldTestSuite, DELETING : %r", fpath)
self.delNodeTestSuite(y)
self.log("testnode.checkOldTestSuite, DELETING : %r", fpath)
if os.path.isdir(fpath): if os.path.isdir(fpath):
shutil.rmtree(fpath) shutil.rmtree(fpath)
else: else:
os.remove(fpath) os.remove(fpath)
def getNodeTestSuite(self, reference): def getNodeTestSuite(self, reference):
node_test_suite = self.node_test_suite_dict.get(reference) try:
if node_test_suite is None: node_test_suite = self.node_test_suite_dict[reference]
node_test_suite = NodeTestSuite(reference) except KeyError:
self.node_test_suite_dict[reference] = node_test_suite node_test_suite = self.node_test_suite_dict[reference] = \
NodeTestSuite(reference, self.working_directory)
node_test_suite.edit( config = self.config
log=self.log, node_test_suite.edit(log_directory=config['log_directory'])
config=self.config,
process_manager=self.process_manager)
return node_test_suite return node_test_suite
def delNodeTestSuite(self, reference):
self.node_test_suite_dict.pop(reference, None)
def constructProfile(self, node_test_suite, test_type, use_relative_path=False): def constructProfile(self, node_test_suite, test_type, use_relative_path=False):
assert len(node_test_suite.vcs_repository_list), "we must have at least one repository" assert len(node_test_suite.vcs_repository_list), "we must have at least one repository"
software_config_path = None software_config_path = None
...@@ -128,6 +126,10 @@ class TestNode(object): ...@@ -128,6 +126,10 @@ class TestNode(object):
node_test_suite.reference) node_test_suite.reference)
repository_path = os.path.relpath(repository_path, from_path) repository_path = os.path.relpath(repository_path, from_path)
# XXX: Like in run(), code depending on specific test type must be
# moved to the test type classes. In particular, the use of a
# replacement pattern ('<obfuscated_url>') is ugly: buildout
# has cleaner ways to do that.
if test_type=="ScalabilityTest": if test_type=="ScalabilityTest":
# updater = Updater(repository_path, git_binary=self.config['git_binary'], # updater = Updater(repository_path, git_binary=self.config['git_binary'],
# branch = vcs_repository.get('branch','master'), log=self.log, process_manager=self.process_manager) # branch = vcs_repository.get('branch','master'), log=self.log, process_manager=self.process_manager)
...@@ -165,7 +167,6 @@ develop = false ...@@ -165,7 +167,6 @@ develop = false
f.write("[buildout]\nextends = %s\n%s" % ( f.write("[buildout]\nextends = %s\n%s" % (
software_config_path, software_config_path,
''.join(profile_content_list))) ''.join(profile_content_list)))
sys.path.append(repository_path)
def getAndUpdateFullRevisionList(self, node_test_suite): def getAndUpdateFullRevisionList(self, node_test_suite):
full_revision_list = [] full_revision_list = []
...@@ -201,12 +202,9 @@ develop = false ...@@ -201,12 +202,9 @@ develop = false
test_result.reportStatus('LOG url', "%s/%s" % (self.config.get('httpd_url'), test_result.reportStatus('LOG url', "%s/%s" % (self.config.get('httpd_url'),
folder_id), '') folder_id), '')
self.log("going to switch to log %r", suite_log_path) self.log("going to switch to log %r", suite_log_path)
self.process_manager.log = self.log = self.getSuiteLog() self.process_manager.log = self.log = self.suite_log
return suite_log_path return suite_log_path
def getSuiteLog(self):
return self.suite_log
def _initializeSuiteLog(self, suite_log_path): def _initializeSuiteLog(self, suite_log_path):
# remove previous handlers # remove previous handlers
logger = logging.getLogger('testsuite') logger = logging.getLogger('testsuite')
...@@ -287,8 +285,8 @@ develop = false ...@@ -287,8 +285,8 @@ develop = false
def run(self): def run(self):
log = self.log log = self.log
config = self.config config = self.config
test_node_slapos = SlapOSInstance() portal_url = config['test_suite_master_url']
test_node_slapos.edit(working_directory=config['slapos_directory']) test_node_slapos = SlapOSInstance(config['slapos_directory'])
try: try:
while True: while True:
test_result = None test_result = None
...@@ -297,12 +295,12 @@ develop = false ...@@ -297,12 +295,12 @@ develop = false
self.log = self.process_manager.log = self.testnode_log self.log = self.process_manager.log = self.testnode_log
self.cleanUp() self.cleanUp()
begin = time.time() begin = time.time()
portal_url = config['test_suite_master_url'] taskdistributor = taskdistribution.TaskDistributor(
self.taskdistribution = taskdistribution.TaskDistributor( portal_url, logger=DummyLogger(log))
portal_url, self.test_suite_portal = taskdistributor # XXX ScalabilityTest
logger=DummyLogger(log)) node_configuration = taskdistributor.subscribeNode(
node_configuration = self.taskdistribution.subscribeNode(node_title=config['test_node_title'], node_title=config['test_node_title'],
computer_guid=config['computer_id']) computer_guid=config['computer_id'])
if type(node_configuration) is str: if type(node_configuration) is str:
# Backward compatiblity # Backward compatiblity
node_configuration = json.loads(node_configuration) node_configuration = json.loads(node_configuration)
...@@ -313,9 +311,9 @@ develop = false ...@@ -313,9 +311,9 @@ develop = false
log('Received and using process timeout from master: %i', log('Received and using process timeout from master: %i',
process_timeout) process_timeout)
self.process_manager.max_timeout = process_timeout self.process_manager.max_timeout = process_timeout
test_suite_data = self.taskdistribution.startTestSuite( test_suite_data = taskdistributor.startTestSuite(
node_title=config['test_node_title'], node_title=config['test_node_title'],
computer_guid=config['computer_id']) computer_guid=config['computer_id'])
if type(test_suite_data) is str: if type(test_suite_data) is str:
# Backward compatiblity # Backward compatiblity
test_suite_data = json.loads(test_suite_data) test_suite_data = json.loads(test_suite_data)
...@@ -323,40 +321,27 @@ develop = false ...@@ -323,40 +321,27 @@ develop = false
log("Got following test suite data from master : %r", log("Got following test suite data from master : %r",
test_suite_data) test_suite_data)
try: try:
my_test_type = self.taskdistribution.getTestType() my_test_type = taskdistributor.getTestType()
except Exception: except Exception:
log("testnode, error during requesting getTestType() method" log("testnode, error during requesting getTestType() method"
" from the distributor.") " from the distributor.")
raise raise
# Select runner according to the test type # Select runner according to the test type
if my_test_type == 'UnitTest': try:
runner = UnitTestRunner(self) runner_class = test_type_registry[my_test_type]
elif my_test_type == 'ScalabilityTest': except KeyError:
runner = ScalabilityTestRunner(self)
else:
log("testnode, Runner type %s not implemented.", my_test_type) log("testnode, Runner type %s not implemented.", my_test_type)
raise NotImplementedError raise NotImplementedError
log("Type of current test is %s" % (my_test_type,)) runner = runner_class(self)
log("Type of current test is %s", my_test_type)
# master testnode gets test_suites, slaves get nothing # master testnode gets test_suites, slaves get nothing
runner.prepareSlapOSForTestNode(test_node_slapos) runner.prepareSlapOSForTestNode(test_node_slapos)
# Clean-up test suites # Clean-up test suites
self.checkOldTestSuite(test_suite_data) self.purgeOldTestSuite(test_suite_data)
for test_suite in test_suite_data: for test_suite in test_suite_data:
node_test_suite = self.getNodeTestSuite( node_test_suite = self.getNodeTestSuite(
test_suite["test_suite_reference"]) test_suite.pop("test_suite_reference"))
node_test_suite.edit(
working_directory=config['working_directory'],
log_directory=config['log_directory'])
node_test_suite.edit(**test_suite) node_test_suite.edit(**test_suite)
if my_test_type == 'UnitTest':
runner = UnitTestRunner(node_test_suite)
elif my_test_type == 'ScalabilityTest':
runner = ScalabilityTestRunner(self)
else:
log("testnode, Runner type %s not implemented.", my_test_type)
raise NotImplementedError
# XXX: temporary hack to prevent empty test_suite # XXX: temporary hack to prevent empty test_suite
if not hasattr(node_test_suite, 'test_suite'): if not hasattr(node_test_suite, 'test_suite'):
...@@ -366,11 +351,7 @@ develop = false ...@@ -366,11 +351,7 @@ develop = false
revision_list = self.getAndUpdateFullRevisionList(node_test_suite) revision_list = self.getAndUpdateFullRevisionList(node_test_suite)
if revision_list is None: if revision_list is None:
continue continue
# Write our own software.cfg to use the local repository test_result = taskdistributor.createTestResult(
self.constructProfile(node_test_suite, my_test_type,
runner.getRelativePathUsage())
# Make sure we have local repository
test_result = self.taskdistribution.createTestResult(
node_test_suite.revision, [], node_test_suite.revision, [],
config['test_node_title'], False, config['test_node_title'], False,
node_test_suite.test_suite_title, node_test_suite.test_suite_title,
...@@ -382,17 +363,23 @@ develop = false ...@@ -382,17 +363,23 @@ develop = false
node_test_suite.edit(test_result=test_result) node_test_suite.edit(test_result=test_result)
# get cluster configuration for this test suite, this is needed to # get cluster configuration for this test suite, this is needed to
# know slapos parameters to user for creating instances # know slapos parameters to user for creating instances
log("Getting configuration from test suite %s", node_test_suite.test_suite_title) log("Getting configuration from test suite %s",
generated_config = self.taskdistribution.generateConfiguration(node_test_suite.test_suite_title) node_test_suite.test_suite_title)
generated_config = taskdistributor.generateConfiguration(
node_test_suite.test_suite_title)
json_data = json.loads(generated_config) json_data = json.loads(generated_config)
cluster_configuration = deunicodeData(json_data['configuration_list'][0]) cluster_configuration = deunicodeData(json_data['configuration_list'][0])
node_test_suite.edit(cluster_configuration=cluster_configuration) node_test_suite.edit(cluster_configuration=cluster_configuration)
# Now prepare the installation of SlapOS and create instance # Now prepare the installation of SlapOS and create instance
self.constructProfile(node_test_suite, my_test_type,
runner.getRelativePathUsage())
status_dict = runner.prepareSlapOSForTestSuite(node_test_suite) status_dict = runner.prepareSlapOSForTestSuite(node_test_suite)
# Give some time so computer partitions may start # Give some time so computer partitions may start
# as partitions can be of any kind we have and likely will never have # as partitions can be of any kind we have and likely will never have
# a reliable way to check if they are up or not ... # a reliable way to check if they are up or not ...
time.sleep(20) time.sleep(20)
# XXX: Do not switch according to the test type. IOW, the
# following code must be moved to the test type class.
if my_test_type == 'UnitTest': if my_test_type == 'UnitTest':
runner.runTestSuite(node_test_suite, portal_url) runner.runTestSuite(node_test_suite, portal_url)
elif my_test_type == 'ScalabilityTest': elif my_test_type == 'ScalabilityTest':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment