- dovetail.sdnvpn.tc002
- dovetail.sdnvpn.tc004
- dovetail.sdnvpn.tc008
+ # resiliency
+ - dovetail.resiliency.tc001
--- /dev/null
+---
+bottlenecks:
+ image_name: opnfv/bottlenecks
+ docker_tag: cvp.0.4.0
+ opts: '-id --privileged=true'
+ config:
+ dir: '/home/opnfv/userconfig'
+ pre_condition:
+ - 'echo test for precondition in bottlenecks'
+ cmds:
+ - '/home/opnfv/bottlenecks/run_tests.sh -c {{validate_testcase}}'
+ post_condition:
+ - 'echo test for postcondition in bottlenecks'
+ result:
+ dir: '/tmp'
+ file_path: 'bottlenecks.log'
+ openrc: '/tmp/admin_rc.sh'
+ extra_container:
+ - 'Bottlenecks-Yardstick'
+ - 'Bottlenecks-ELK'
- '-y'
path:
- 'yardstick/docker_tag'
- help: 'Overwrite tag for yardstick docker container (e.g. stable or latest)'
+ help: 'Overwrite tag for yardstick docker container (e.g. danube.3.1)'
func_tag:
flags:
- '--func_tag'
- '-f'
path:
- 'functest/docker_tag'
- help: 'Overwrite tag for functest docker container (e.g. stable or latest)'
+ help: 'Overwrite tag for functest docker container (e.g. cvp.0.2.0)'
+ bott_tag:
+ flags:
+ - '--bott_tag'
+ - '-b'
+ path:
+ - 'bottlenecks/docker_tag'
+ help: 'Overwrite tag for bottlenecks docker container (e.g. cvp.0.4.0)'
control:
testsuite:
flags:
- ipv6
- sdnvpn
- vping
+ - resiliency
functest_testsuite:
- refstack_defcore
include_config:
- functest_config.yml
- yardstick_config.yml
+ - bottlenecks_config.yml
test_project:
- 'yardstick'
- 'functest'
+ - 'bottlenecks'
validate_input:
valid_docker_tag:
- 'cvp.0.1.0'
- 'cvp.0.2.0'
- 'cvp.0.3.0'
+ - 'cvp.0.4.0'
class Container(object):
container_list = {}
- has_pull_latest_image = {'yardstick': False, 'functest': False}
+ has_pull_latest_image = {'yardstick': False, 'functest': False,
+ 'bottlenecks': False}
logger = None
key_vol = '-v %s:%s ' % (key_file, key_container_path)
return "%s %s %s" % (envs, log_vol, key_vol)
+ @classmethod
+ def set_bottlenecks_config(cls, testcase_name):
+ dovetail_config = dt_cfg.dovetail_config
+ yard_tag = dovetail_config['yardstick']['docker_tag']
+ docker_vol = '-v /var/run/docker.sock:/var/run/docker.sock'
+ env = ('-e Yardstick_TAG={} -e OUTPUT_FILE={}.out'
+ .format(yard_tag, testcase_name))
+ report = ""
+ if dovetail_config['report_dest'].startswith("http"):
+ report = ("-e BOTTLENECKS_DB_TARGET={}"
+ .format(dovetail_config['report_dest']))
+ return "{} {} {}".format(docker_vol, env, report)
+
@classmethod
def create(cls, type, testcase_name):
dovetail_config = dt_cfg.dovetail_config
config = cls.set_functest_config(testcase_name)
if type.lower() == "yardstick":
config = cls.set_yardstick_config()
+ if type.lower() == "bottlenecks":
+ config = cls.set_bottlenecks_config(testcase_name)
if not config:
return None
return image_id
@classmethod
- def clean(cls, container_id):
- cmd1 = 'sudo docker stop %s' % (container_id)
- dt_utils.exec_cmd(cmd1, cls.logger)
- cmd2 = 'sudo docker rm %s' % (container_id)
- dt_utils.exec_cmd(cmd2, cls.logger)
+ def check_container_exist(cls, container_name):
+ cmd = ('sudo docker ps -aq -f name={}'.format(container_name))
+ ret, msg = dt_utils.exec_cmd(cmd, cls.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']
+ for container in containers:
+ if cls.check_container_exist(container):
+ cmd = ('sudo docker rm -f {}'.format(container))
+ dt_utils.exec_cmd(cmd, cls.logger)
@classmethod
def exec_cmd(cls, container_id, sub_cmd, exit_on_error=False):
class Report(object):
- results = {'functest': {}, 'yardstick': {}, 'shell': {}}
+ results = {'functest': {}, 'yardstick': {}, 'bottlenecks': {}, 'shell': {}}
logger = None
return None
+class BottlenecksCrawler(object):
+
+ logger = None
+
+ def __init__(self):
+ self.type = 'bottlenecks'
+ self.logger.debug('Create crawler: {}'.format(self.type))
+
+ @classmethod
+ def create_log(cls):
+ cls.logger = \
+ dt_logger.Logger(__name__ + '.BottlenecksCrawler').getLogger()
+
+ def crawl(self, testcase=None):
+ report_dest = dt_cfg.dovetail_config['report_dest']
+ if report_dest.lower() == 'file':
+ return self.crawl_from_file(testcase)
+
+ if report_dest.lower().startswith('http'):
+ return self.crawl_from_url(testcase)
+
+ def crawl_from_file(self, testcase=None):
+ file_path = os.path.join(dt_cfg.dovetail_config['result_dir'],
+ testcase.name() + '.out')
+ if not os.path.exists(file_path):
+ self.logger.error('Result file not found: {}'.format(file_path))
+ return None
+ criteria = 'FAIL'
+ with open(file_path, 'r') as f:
+ for jsonfile in f:
+ data = json.loads(jsonfile)
+ try:
+ if 'PASS' == data["data_body"]["result"]:
+ criteria = 'PASS'
+ else:
+ criteria = 'FAIL'
+ break
+ except KeyError as e:
+ self.logger.exception('Pass flag not found {}'.format(e))
+ json_results = {'criteria': criteria}
+ self.logger.debug('Results: {}'.format(str(json_results)))
+ return json_results
+
+ def crawl_from_url(self, testcase=None):
+ return None
+
+
class ShellCrawler(object):
def __init__(self):
CRAWLER_MAP = {'functest': FunctestCrawler,
'yardstick': YardstickCrawler,
+ 'bottlenecks': BottlenecksCrawler,
'shell': ShellCrawler}
@classmethod
return
+class BottlenecksChecker(object):
+
+ logger = None
+
+ @classmethod
+ def create_log(cls):
+ cls.logger = \
+ dt_logger.Logger(__name__ + '.BottlenecksChecker').getLogger()
+
+ @staticmethod
+ def check(testcase, result):
+ if not result:
+ testcase.passed('FAIL')
+ else:
+ testcase.passed(result['criteria'])
+ return
+
+
class ShellChecker(object):
@staticmethod
CHECKER_MAP = {'functest': FunctestChecker,
'yardstick': YardstickChecker,
+ 'bottlenecks': BottlenecksChecker,
'shell': ShellChecker}
@classmethod
from testcase import Testcase
from testcase import Testsuite
from report import Report
-from report import FunctestCrawler, YardstickCrawler
-from report import FunctestChecker, YardstickChecker
+from report import FunctestCrawler, YardstickCrawler, BottlenecksCrawler
+from report import FunctestChecker, YardstickChecker, BottlenecksChecker
from utils.dovetail_config import DovetailConfig as dt_cfg
from test_runner import DockerRunner, ShellRunner
result_file = os.path.join(result_dir, testcase.name() + '.out')
elif validate_type.lower() == 'functest':
result_file = os.path.join(result_dir, functest_result)
+ elif validate_type.lower() == 'bottlenecks':
+ result_file = os.path.join(result_dir, testcase.name() + '.out')
else:
logger.error("Don't support {} now.".format(validate_type))
return
# for 'func_tag' and 'yard_tag' options
func_tag = input_dict['func_tag']
yard_tag = input_dict['yard_tag']
+ bott_tag = input_dict['bott_tag']
valid_tag = check_dict['valid_docker_tag']
if func_tag is not None and func_tag not in valid_tag:
logger.error("The input option 'func_tag' can't be {}, "
logger.error("The input option 'yard_tag' can't be {}, "
"valid values are {}.".format(yard_tag, valid_tag))
raise SystemExit(1)
+ if bott_tag is not None and bott_tag not in valid_tag:
+ logger.error("The input option 'bott_tag' can't be {}, "
+ "valid values are {}.".format(bott_tag, valid_tag))
+ raise SystemExit(1)
# for 'report' option
report = input_dict['report']
Report.create_log()
FunctestCrawler.create_log()
YardstickCrawler.create_log()
+ BottlenecksCrawler.create_log()
FunctestChecker.create_log()
YardstickChecker.create_log()
+ BottlenecksChecker.create_log()
Testcase.create_log()
Testsuite.create_log()
DockerRunner.create_log()
if(kwargs['report'].endswith('/')):
kwargs['report'] = kwargs['report'][0:kwargs['report'].rfind('/')]
dt_cfg.dovetail_config['report_dest'] = kwargs['report']
+ dt_cfg.update_cmds()
if kwargs['offline']:
dt_cfg.dovetail_config['offline'] = True
ret, msg = Container.exec_cmd(container_id, cmd)
self.testcase.cleaned(True)
- Container.clean(container_id)
+ Container.clean(container_id, self.type)
class FunctestRunner(DockerRunner):
super(YardstickRunner, self).__init__(testcase)
+class BottlenecksRunner(DockerRunner):
+
+ def __init__(self, testcase):
+ self.type = 'bottlenecks'
+ super(BottlenecksRunner, self).__init__(testcase)
+
+
class ShellRunner(object):
logger = None
TEST_RUNNER_MAP = {
"functest": FunctestRunner,
"yardstick": YardstickRunner,
+ "bottlenecks": BottlenecksRunner,
"shell": ShellRunner,
}
class YardstickTestcase(Testcase):
- validate_testcae_list = {}
+ validate_testcase_list = {}
def __init__(self, testcase_yaml):
super(YardstickTestcase, self).__init__(testcase_yaml)
self.type = 'yardstick'
+class BottlenecksTestcase(Testcase):
+
+ validate_testcase_list = {}
+
+ def __init__(self, testcase_yaml):
+ super(BottlenecksTestcase, self).__init__(testcase_yaml)
+ self.type = 'bottlenecks'
+ self._update_cmds()
+
+ def _update_cmds(self):
+ if dt_cfg.dovetail_config['report_dest'].startswith("http"):
+ try:
+ self.testcase['validate']['cmds'][0] += ' --report'
+ except KeyError:
+ return
+
+
class ShellTestcase(Testcase):
validate_testcase_list = {}
TESTCASE_TYPE_MAP = {
'functest': FunctestTestcase,
'yardstick': YardstickTestcase,
+ 'bottlenecks': BottlenecksTestcase,
'shell': ShellTestcase,
}
--- /dev/null
+---
+dovetail.resiliency.tc001:
+ name: dovetail.resiliency.tc001
+ objective: > # This test case verifies the ability of the SUT setting up VM pairs
+ # for different tenants and providing acceptable capacity after the amount of
+ # VM pairs reaches certain quantity.
+ validate:
+ type: bottlenecks
+ testcase: posca_factor_ping
+ report:
+ sub_testcase_list:
def update_non_envs(cls, path, value):
if value:
cls.set_leaf_dict(cls.dovetail_config, path, value)
+
+ @classmethod
+ def update_cmds(cls):
+ if cls.dovetail_config['report_dest'].startswith("http"):
+ cls.dovetail_config['bottlenecks']['cmds'][0] += ' --report'