summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dovetail/container.py181
-rw-r--r--dovetail/test_runner.py27
2 files changed, 98 insertions, 110 deletions
diff --git a/dovetail/container.py b/dovetail/container.py
index be92a67..580d6c3 100644
--- a/dovetail/container.py
+++ b/dovetail/container.py
@@ -18,12 +18,12 @@ from utils.dovetail_config import DovetailConfig as dt_cfg
class Container(object):
- container_list = {}
-
logger = None
- def __init__(self):
- pass
+ def __init__(self, testcase):
+ self.container_id = None
+ self.testcase = testcase
+ self.valid_type = self.testcase.validate_type()
def __str__(self):
pass
@@ -32,46 +32,39 @@ class Container(object):
def create_log(cls):
cls.logger = dt_logger.Logger(__name__ + '.Container').getLogger()
- @classmethod
- def get(cls, type):
- return cls.container_list[type]
-
- @classmethod
- def _get_config(cls, field, project_cfg, testcase_cfg):
+ def _get_config(self, field, project_cfg, testcase_cfg):
value = dt_utils.get_value_from_dict(field, testcase_cfg)
if not value:
value = dt_utils.get_value_from_dict(field, project_cfg)
if not value:
- cls.logger.error("Couldn't find key {}.".format(field))
+ self.logger.error("Couldn't find key {}.".format(field))
return None
return value
- @classmethod
- def get_docker_image(cls, testcase):
- project_cfg = dt_cfg.dovetail_config[testcase.validate_type()]
- testcase_cfg = testcase.testcase['validate']
+ def get_docker_image(self):
+ project_cfg = dt_cfg.dovetail_config[self.valid_type]
+ testcase_cfg = self.testcase.testcase['validate']
- name = cls._get_config('image_name', project_cfg, testcase_cfg)
- tag = cls._get_config('docker_tag', project_cfg, testcase_cfg)
+ name = self._get_config('image_name', project_cfg, testcase_cfg)
+ tag = self._get_config('docker_tag', project_cfg, testcase_cfg)
return "{}:{}".format(name, tag) if name and tag else None
# get the openrc_volume for creating the container
- @classmethod
- def openrc_volume(cls, type):
+ def openrc_volume(self):
dovetail_config = dt_cfg.dovetail_config
dovetail_config['openrc'] = os.path.join(dovetail_config['config_dir'],
dovetail_config['env_file'])
if os.path.isfile(dovetail_config['openrc']):
- openrc = ' -v %s:%s ' % (dovetail_config['openrc'],
- dovetail_config[type]['openrc'])
+ openrc = " -v {}:{} " \
+ .format(dovetail_config['openrc'],
+ dovetail_config[self.valid_type]['openrc'])
return openrc
else:
- cls.logger.error(
+ self.logger.error(
"File {} doesn't exist.".format(dovetail_config['openrc']))
return None
- @classmethod
- def set_vnftest_config(cls):
+ def set_vnftest_config(self):
dovetail_config = dt_cfg.dovetail_config
log_vol = '-v %s:%s ' % (dovetail_config['result_dir'],
@@ -81,19 +74,18 @@ class Container(object):
dovetail_config['pri_key'])
key_container_path = dovetail_config["vnftest"]['result']['key_path']
if not os.path.isfile(key_file):
- cls.logger.debug("Key file {} is not found".format(key_file))
+ self.logger.debug("Key file {} is not found".format(key_file))
key_vol = ''
else:
key_vol = '-v %s:%s ' % (key_file, key_container_path)
return "%s %s" % (log_vol, key_vol)
- @classmethod
- def create(cls, valid_type, testcase_name, docker_image):
+ def create(self, docker_image):
dovetail_config = dt_cfg.dovetail_config
- project_cfg = dovetail_config[valid_type]
+ project_cfg = dovetail_config[self.valid_type]
# credentials file openrc.sh is neccessary
- openrc = cls.openrc_volume(valid_type)
+ openrc = self.openrc_volume()
if not openrc:
return None
@@ -112,9 +104,9 @@ class Container(object):
else:
envs = envs + ' -e CI_DEBUG=false'
envs = envs + ' -e BUILD_TAG=%s-%s' % (dovetail_config['build_tag'],
- testcase_name)
+ self.testcase.name())
- hosts_config = dt_utils.get_hosts_info(cls.logger)
+ hosts_config = dt_utils.get_hosts_info(self.logger)
# This part will be totally removed after remove the 4 functions
# set_functest_config has been removed
@@ -122,8 +114,8 @@ class Container(object):
# set_bottlenecks_config has been removed
# set_vnftest_config
config = " "
- if valid_type.lower() == "vnftest":
- config = cls.set_vnftest_config()
+ if self.valid_type.lower() == "vnftest":
+ config = self.set_vnftest_config()
if not config:
return None
@@ -133,20 +125,20 @@ class Container(object):
project_cfg['config']['dir'])
cacert_volume = ""
- https_enabled = dt_utils.check_https_enabled(cls.logger)
+ https_enabled = dt_utils.check_https_enabled(self.logger)
cacert = os.getenv('OS_CACERT')
insecure = os.getenv('OS_INSECURE')
if cacert is not None:
- if dt_utils.check_cacert_file(cacert, cls.logger):
+ if dt_utils.check_cacert_file(cacert, self.logger):
cacert_volume = ' -v %s:%s ' % (cacert, cacert)
else:
return None
elif https_enabled:
if insecure and insecure.lower() == 'true':
- cls.logger.debug("Use the insecure mode...")
+ self.logger.debug("Use the insecure mode...")
else:
- cls.logger.error("https enabled, please set OS_CACERT or "
- "insecure mode...")
+ self.logger.error("https enabled, please set OS_CACERT or "
+ "insecure mode...")
return None
images_volume = ''
@@ -161,20 +153,18 @@ class Container(object):
'{hosts_config} {openrc} {cacert_volume} {config_volume} ' \
'{result_volume} {images_volume} {docker_image} /bin/bash' \
.format(**locals())
- ret, container_id = dt_utils.exec_cmd(cmd, cls.logger)
+ ret, container_id = dt_utils.exec_cmd(cmd, self.logger)
if ret != 0:
return None
- cls.container_list[valid_type] = container_id
-
- if valid_type.lower() == 'vnftest':
- cls.set_vnftest_conf_file(container_id)
+ if self.valid_type.lower() == 'vnftest':
+ self.set_vnftest_conf_file(container_id)
+ self.container_id = container_id
return container_id
- @classmethod
- def get_image_id(cls, image_name):
+ def get_image_id(self, image_name):
cmd = 'sudo docker images -q %s' % (image_name)
- ret, image_id = dt_utils.exec_cmd(cmd, cls.logger)
+ ret, image_id = dt_utils.exec_cmd(cmd, self.logger)
if ret == 0:
return image_id
else:
@@ -182,109 +172,104 @@ class Container(object):
# remove the image according to the image_id
# if there exists containers using this image, then skip
- @classmethod
- def remove_image(cls, image_id):
+ def remove_image(self, image_id):
cmd = "sudo docker ps -aq -f 'ancestor=%s'" % (image_id)
- ret, msg = dt_utils.exec_cmd(cmd, cls.logger)
+ ret, msg = dt_utils.exec_cmd(cmd, self.logger)
if msg and ret == 0:
- cls.logger.debug('Image {} has containers, skip.'.format(image_id))
+ self.logger.debug('Image {} has containers, skip.'
+ .format(image_id))
return True
cmd = 'sudo docker rmi %s' % (image_id)
- cls.logger.debug('Remove image {}.'.format(image_id))
- ret, msg = dt_utils.exec_cmd(cmd, cls.logger)
+ self.logger.debug('Remove image {}.'.format(image_id))
+ ret, msg = dt_utils.exec_cmd(cmd, self.logger)
if ret == 0:
- cls.logger.debug('Remove image {} successfully.'.format(image_id))
+ self.logger.debug('Remove image {} successfully.'.format(image_id))
return True
- cls.logger.error('Failed to remove image {}.'.format(image_id))
+ self.logger.error('Failed to remove image {}.'.format(image_id))
return False
- @classmethod
- def pull_image_only(cls, image_name):
+ def pull_image_only(self, image_name):
cmd = 'sudo docker pull %s' % (image_name)
- ret, msg = dt_utils.exec_cmd(cmd, cls.logger)
+ ret, msg = dt_utils.exec_cmd(cmd, self.logger)
if ret != 0:
- cls.logger.error(
+ self.logger.error(
'Failed to pull docker image {}!'.format(image_name))
return False
- cls.logger.debug('Success to pull docker image {}!'.format(image_name))
+ self.logger.debug('Success to pull docker image {}!'
+ .format(image_name))
return True
- @classmethod
- def pull_image(cls, docker_image):
+ def pull_image(self, docker_image):
if not docker_image:
return None
- old_image_id = cls.get_image_id(docker_image)
- if not cls.pull_image_only(docker_image):
+ old_image_id = self.get_image_id(docker_image)
+ if not self.pull_image_only(docker_image):
return None
- new_image_id = cls.get_image_id(docker_image)
+ new_image_id = self.get_image_id(docker_image)
if not new_image_id:
- cls.logger.error(
+ self.logger.error(
"Failed to get the id of image {}.".format(docker_image))
return None
if not old_image_id:
return docker_image
if new_image_id == old_image_id:
- cls.logger.debug('Image {} has no changes, no need to remove.'
- .format(docker_image))
+ self.logger.debug('Image {} has no changes, no need to remove.'
+ .format(docker_image))
else:
- cls.remove_image(old_image_id)
+ self.remove_image(old_image_id)
return docker_image
- @classmethod
- def check_container_exist(cls, container_name):
+ def check_container_exist(self, container_name):
cmd = ('sudo docker ps -aq -f name={}'.format(container_name))
- ret, msg = dt_utils.exec_cmd(cmd, cls.logger)
+ ret, msg = dt_utils.exec_cmd(cmd, self.logger)
if ret == 0 and msg:
return True
return False
- @classmethod
- def clean(cls, container_id, valid_type):
- cmd = ('sudo docker rm -f {}'.format(container_id))
- dt_utils.exec_cmd(cmd, cls.logger)
- if valid_type.lower() == 'bottlenecks':
- containers = dt_cfg.dovetail_config[valid_type]['extra_container']
+ def clean(self):
+ cmd = ('sudo docker rm -f {}'.format(self.container_id))
+ dt_utils.exec_cmd(cmd, self.logger)
+ if self.valid_type.lower() == 'bottlenecks':
+ containers = dt_utils.get_value_from_dict(
+ 'extra_container', dt_cfg.dovetail_config[self.valid_type])
for container in containers:
- if cls.check_container_exist(container):
+ if self.check_container_exist(container):
cmd = ('sudo docker rm -f {}'.format(container))
- dt_utils.exec_cmd(cmd, cls.logger)
+ dt_utils.exec_cmd(cmd, self.logger)
- @classmethod
- def exec_cmd(cls, container_id, sub_cmd, exit_on_error=False):
+ def exec_cmd(self, sub_cmd, exit_on_error=False):
if sub_cmd == "":
return (1, 'sub_cmd is empty')
- cmd = 'sudo docker exec %s /bin/bash -c "%s"' % (container_id, sub_cmd)
- return dt_utils.exec_cmd(cmd, cls.logger, exit_on_error)
+ cmd = 'sudo docker exec {} /bin/bash -c "{}"'.format(self.container_id,
+ sub_cmd)
+ return dt_utils.exec_cmd(cmd, self.logger, exit_on_error)
- @classmethod
- def copy_file(cls, container_id, src_path, dest_path,
- exit_on_error=False):
+ def copy_file(self, src_path, dest_path, exit_on_error=False):
if not src_path or not dest_path:
return (1, 'src_path or dest_path is empty')
cmd = 'cp %s %s' % (src_path, dest_path)
- return cls.exec_cmd(container_id, cmd, exit_on_error)
+ return self.exec_cmd(cmd, exit_on_error)
- @classmethod
- def docker_copy(cls, container_id, src_path, dest_path):
+ def docker_copy(self, src_path, dest_path):
if not src_path or not dest_path:
return (1, 'src_path or dest_path is empty')
- cmd = 'docker cp %s %s:%s' % (src_path, container_id, dest_path)
- return dt_utils.exec_cmd(cmd, cls.logger)
+ cmd = 'docker cp {} {}:{}'.format(src_path,
+ self.container_id,
+ dest_path)
+ return dt_utils.exec_cmd(cmd, self.logger)
- @classmethod
- def copy_files_in_container(cls, valid_type, container_id):
- project_config = dt_cfg.dovetail_config[valid_type]
+ def copy_files_in_container(self):
+ project_config = dt_cfg.dovetail_config[self.valid_type]
if 'copy_file_in_container' not in project_config.keys():
return
if not project_config['copy_file_in_container']:
return
for item in project_config['copy_file_in_container']:
- cls.copy_file(container_id, item['src_file'], item['dest_file'])
+ self.copy_file(item['src_file'], item['dest_file'])
- @classmethod
- def set_vnftest_conf_file(cls, container_id):
+ def set_vnftest_conf_file(self):
valid_type = 'vnftest'
for conf_file in dt_cfg.dovetail_config[valid_type]['vnftest_conf']:
src = conf_file['src_file']
dest = conf_file['dest_file']
- cls.docker_copy(container_id, src, dest)
+ self.docker_copy(src, dest)
diff --git a/dovetail/test_runner.py b/dovetail/test_runner.py
index 9b5114f..a2bc774 100644
--- a/dovetail/test_runner.py
+++ b/dovetail/test_runner.py
@@ -33,8 +33,11 @@ class DockerRunner(object):
def create_log(cls):
cls.logger = dt_logger.Logger(__name__ + '.DockerRunner').getLogger()
- def pre_copy(self, container_id=None, dest_path=None,
+ def pre_copy(self, container=None, dest_path=None,
src_file=None, exist_file=None):
+ if not container:
+ self.logger.error("Container instance is None.")
+ return None
if not dest_path:
self.logger.error("There has no dest_path in {} config file."
.format(self.testcase.name()))
@@ -47,24 +50,24 @@ class DockerRunner(object):
file_path = dt_cfg.dovetail_config[self.type]['config']['dir']
src_path = os.path.join(file_path, 'pre_config', exist_file)
- Container.copy_file(container_id, src_path, dest_path)
+ container.copy_file(src_path, dest_path)
return dest_path
def run(self):
- docker_image = Container.get_docker_image(self.testcase)
+ container = Container(self.testcase)
+ docker_image = container.get_docker_image()
if dt_cfg.dovetail_config['offline']:
- exist = Container.get_image_id(docker_image)
+ exist = container.get_image_id(docker_image)
if not exist:
self.logger.error("{} image doesn't exist, can't run offline."
.format(self.testcase.validate_type()))
return
else:
- if not Container.pull_image(docker_image):
+ if not container.pull_image(docker_image):
self.logger.error("Failed to pull the image.")
return
- container_id = Container.create(self.testcase.validate_type(),
- self.testcase.name(), docker_image)
+ container_id = container.create(docker_image)
if not container_id:
self.logger.error('Failed to create container.')
return
@@ -76,14 +79,14 @@ class DockerRunner(object):
exist_file_name = self.testcase.pre_copy_path("exist_src_file")
if src_file_name or exist_file_name:
- if not self.pre_copy(container_id, dest_path, src_file_name,
+ if not self.pre_copy(container, dest_path, src_file_name,
exist_file_name):
return
cmds = self.testcase.pre_condition()
if cmds:
for cmd in cmds:
- ret, msg = Container.exec_cmd(container_id, cmd)
+ ret, msg = container.exec_cmd(cmd)
if ret != 0:
self.logger.error("Failed to exec all pre_condition cmds.")
break
@@ -93,7 +96,7 @@ class DockerRunner(object):
'Failed to prepare test case: {}'.format(self.testcase.name()))
else:
for cmd in self.testcase.cmds:
- ret, msg = Container.exec_cmd(container_id, cmd)
+ ret, msg = container.exec_cmd(cmd)
if ret != 0:
self.logger.error('Failed to exec {}, ret: {}, msg: {}'
.format(cmd, ret, msg))
@@ -102,11 +105,11 @@ class DockerRunner(object):
cmds = self.testcase.post_condition()
if cmds:
for cmd in cmds:
- ret, msg = Container.exec_cmd(container_id, cmd)
+ ret, msg = container.exec_cmd(cmd)
self.testcase.cleaned(True)
if not dt_cfg.dovetail_config['noclean']:
- Container.clean(container_id, self.type)
+ container.clean()
def archive_logs(self):
result_path = os.path.join(os.environ["DOVETAIL_HOME"], 'results')