diff options
Diffstat (limited to 'dovetail/testcase.py')
-rw-r--r-- | dovetail/testcase.py | 231 |
1 files changed, 135 insertions, 96 deletions
diff --git a/dovetail/testcase.py b/dovetail/testcase.py index c9aef0e7..b07a878b 100644 --- a/dovetail/testcase.py +++ b/dovetail/testcase.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -# grakiss.wanglei@huawei.com +# Copyright (c) 2018 grakiss.wanglei@huawei.com and others. +# # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at @@ -12,10 +13,11 @@ import os import yaml from dovetail import constants -from parser import Parser -from test_runner import TestRunnerFactory -from utils.dovetail_config import DovetailConfig as dt_cfg -import utils.dovetail_logger as dt_logger +from dovetail.parser import Parser +from dovetail.test_runner import TestRunnerFactory +from dovetail.utils.dovetail_config import DovetailConfig as dt_cfg +import dovetail.utils.dovetail_logger as dt_logger +import dovetail.utils.dovetail_utils as dt_utils class Testcase(object): @@ -23,11 +25,13 @@ class Testcase(object): logger = None def __init__(self, testcase_yaml): - self.testcase = testcase_yaml.values()[0] + self.testcase = list(testcase_yaml.values())[0] self.testcase['passed'] = 'FAIL' self.cmds = [] self.sub_testcase_status = {} self.update_validate_testcase(self.validate_testcase()) + self.is_mandatory = False + self.results = None @classmethod def create_log(cls): @@ -38,7 +42,6 @@ class Testcase(object): cmd_lines = Parser.parse_cmd(cmd, self) if not cmd_lines: return False - # self.logger.debug('cmd_lines:%s', cmd_lines) self.cmds.append(cmd_lines) self.logger.debug('cmds: {}'.format(self.cmds)) return True @@ -69,31 +72,27 @@ class Testcase(object): return self.testcase['objective'] def sub_testcase(self): - try: - return self.testcase['report']['sub_testcase_list'] - except KeyError: - return [] + return dt_utils.get_value_from_dict('report.sub_testcase_list', + self.testcase) def sub_testcase_passed(self, name, passed=None): if passed is not None: - self.logger.debug( - 'sub_testcase_passed: {} {}'.format(name, passed)) self.sub_testcase_status[name] = passed return self.sub_testcase_status[name] def validate_type(self): return self.testcase['validate']['type'] + def vnf_type(self): + return self.testcase['vnf_type'] + def validate_testcase(self): return self.testcase['validate']['testcase'] - def exceed_max_retry_times(self): - # logger.debug('retry times:%d' % self.testcase['retry']) - return self._exceed_max_retry_times(self.validate_testcase()) + def portal_key_file(self): + return self.testcase['report']['portal_key_file'] def increase_retry(self): - # self.testcase['retry'] = self.testcase['retry'] + 1 - # return self.testcase['retry'] return self._increase_retry(self.validate_testcase()) def passed(self, passed=None): @@ -101,8 +100,11 @@ class Testcase(object): self.testcase['passed'] = passed return self.testcase['passed'] - def script_result_acquired(self, acquired=None): - return self._result_acquired(self.validate_testcase(), acquired) + def set_results(self, results): + self.results = results + + def get_results(self): + return self.results def pre_condition(self): try: @@ -138,27 +140,24 @@ class Testcase(object): return post_condition def mk_src_file(self): - testcase_src_file = self.pre_copy_path('src_file') - try: - file_path = os.path.join(dt_cfg.dovetail_config['result_dir'], - testcase_src_file) - with open(file_path, 'w+') as src_file: - if self.sub_testcase() is not None: + test_list = os.path.join(dt_cfg.dovetail_config['result_dir'], + 'tempest_custom.txt') + if self.sub_testcase() is not None: + try: + with open(test_list, 'w+') as src_file: for sub_test in self.sub_testcase(): - self.logger.debug( - 'Save test cases {}'.format(sub_test)) src_file.write(sub_test + '\n') - self.logger.debug('Save test cases to {}'.format(file_path)) - return file_path - except Exception: - self.logger.exception('Failed to save: {}'.format(file_path)) - return None + self.logger.debug('Save test cases to {}'.format(test_list)) + return test_list + except Exception: + self.logger.exception('Failed to save: {}'.format(test_list)) + return None def run(self): runner = TestRunnerFactory.create(self) try: runner.run() - runner.save_logs() + runner.archive_logs() except AttributeError as e: self.logger.exception( 'Test case: {} Exception: {}'.format(self.name, e)) @@ -169,18 +168,6 @@ class Testcase(object): # testcase in dovetail testcase_list = {} - @classmethod - def prepared(cls, prepared=None): - if prepared is not None: - cls.validate_testcase_list['prepared'] = prepared - return cls.validate_testcase_list['prepared'] - - @classmethod - def cleaned(cls, cleaned=None): - if cleaned is not None: - cls.validate_testcase_list['cleaned'] = cleaned - return cls.validate_testcase_list['cleaned'] - @staticmethod def pre_condition_cls(validate_type): try: @@ -195,46 +182,31 @@ class Testcase(object): except KeyError: return None - @classmethod - def update_validate_testcase(cls, testcase_name): - if testcase_name not in cls.validate_testcase_list: - cls.validate_testcase_list[testcase_name] = \ - {'retry': 0, 'acquired': False} - cls.validate_testcase_list['prepared'] = False - cls.validate_testcase_list['cleaned'] = False - - @classmethod - def _exceed_max_retry_times(cls, validate_testcase): - retry = cls.validate_testcase_list[validate_testcase]['retry'] - return retry > 1 + def update_validate_testcase(self, testcase_name): + if testcase_name not in self.validate_testcase_list: + self.validate_testcase_list[testcase_name] = {'retry': 0} - @classmethod def _increase_retry(cls, validate_testcase): cls.validate_testcase_list[validate_testcase]['retry'] += 1 return cls.validate_testcase_list[validate_testcase]['retry'] @classmethod - def _result_acquired(cls, testcase, acquired=None): - if acquired is not None: - cls.validate_testcase_list[testcase]['acquired'] = \ - acquired - return cls.validate_testcase_list[testcase]['acquired'] - - @classmethod def load(cls): abs_testcase_path = constants.TESTCASE_PATH - for root, dirs, files in os.walk(abs_testcase_path): + for root, _, files in os.walk(abs_testcase_path): for testcase_file in files: with open(os.path.join(root, testcase_file)) as f: testcase_yaml = yaml.safe_load(f) - case_type = testcase_yaml.values()[0]['validate']['type'] + case_type = \ + list(testcase_yaml.values())[0]['validate']['type'] testcase = TestcaseFactory.create(case_type, testcase_yaml) if testcase is not None: - cls.testcase_list[next(testcase_yaml.iterkeys())] = \ + cls.testcase_list[next(iter(testcase_yaml.keys()))] = \ testcase else: cls.logger.error('Failed to create test case: {}' .format(testcase_file)) + return cls.testcase_list @classmethod def get(cls, testcase_name): @@ -242,8 +214,8 @@ class Testcase(object): return cls.testcase_list[testcase_name] return None - @classmethod - def check_testarea(cls, testarea): + @staticmethod + def check_testarea(testarea): area_no_duplicate = [] area_full = ['full'] @@ -251,32 +223,60 @@ class Testcase(object): if not testarea: return True, area_full - mandatory_list = dt_cfg.dovetail_config['mandatory'] - optional_list = dt_cfg.dovetail_config['optional'] for area in testarea: - if area not in dt_cfg.dovetail_config['testarea_supported']: - return False, None if area == 'full': return True, area_full - if area == 'mandatory': - for mandatory_area in mandatory_list: - area_no_duplicate.append(mandatory_area) - continue - if area == 'optional': - for optional_area in optional_list: - area_no_duplicate.append(optional_area) - continue area_no_duplicate.append(area) area_no_duplicate = list(set(area_no_duplicate)) return True, area_no_duplicate + @staticmethod + def check_testcase_area(testcase, testarea): + if not testcase: + return False + if testarea == 'full' or testarea in testcase: + return True + else: + return False + @classmethod - def get_testcase_list(cls, testsuite, testarea): + def get_testcases_for_testsuite(cls, testsuite, testarea): testcase_list = [] - for value in testsuite['testcases_list']: + selected_tests = [] + testcases = dt_utils.get_value_from_dict('testcases_list', testsuite) + mandatory = dt_utils.get_value_from_dict('mandatory', testcases) + optional = dt_utils.get_value_from_dict('optional', testcases) + if not testcases: + return testcase_list + if dt_cfg.dovetail_config['mandatory']: + if not mandatory: + cls.logger.error("There is no mandatory test case in " + "test suite {}".format(testsuite['name'])) + else: + selected_tests += mandatory + if dt_cfg.dovetail_config['optional']: + if not optional: + cls.logger.error("There is no optional test case in " + "test suite {}".format(testsuite['name'])) + else: + selected_tests += optional + if (not dt_cfg.dovetail_config['mandatory'] + and not dt_cfg.dovetail_config['optional']): + if mandatory: + selected_tests += mandatory + if optional: + selected_tests += optional + + if not selected_tests: + return None + for value in selected_tests: for area in testarea: - if value is not None and (area == 'full' or area in value): + if cls.check_testcase_area(value, area): testcase_list.append(value) + if mandatory and value in mandatory: + Testcase.testcase_list[value].is_mandatory = True + else: + Testcase.testcase_list[value].is_mandatory = False break return testcase_list @@ -289,6 +289,33 @@ class FunctestTestcase(Testcase): super(FunctestTestcase, self).__init__(testcase_yaml) self.type = 'functest' + def prepare_cmd(self, test_type): + if not super(FunctestTestcase, self).prepare_cmd(test_type): + return False + + # if API validation is disabled, append a command for applying a + # patch inside the functest container + if dt_cfg.dovetail_config['no_api_validation']: + patch_cmd = os.path.join( + dt_cfg.dovetail_config['functest']['patches_dir'], + 'functest', + 'disable-api-validation', + 'apply.sh') + self.cmds = [patch_cmd] + self.cmds + self.logger.debug('Updated list of commands for test run with ' + 'disabled API response validation: {}' + .format(self.cmds)) + return True + + +class FunctestK8sTestcase(Testcase): + + validate_testcase_list = {} + + def __init__(self, testcase_yaml): + super(FunctestK8sTestcase, self).__init__(testcase_yaml) + self.type = 'functest-k8s' + class YardstickTestcase(Testcase): @@ -306,14 +333,6 @@ class BottlenecksTestcase(Testcase): 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): @@ -325,12 +344,33 @@ class ShellTestcase(Testcase): self.type = 'shell' +class OnapVtpTestcase(Testcase): + + validate_testcase_list = {} + + def __init__(self, testcase_yaml): + super(OnapVtpTestcase, self).__init__(testcase_yaml) + self.type = 'onap-vtp' + + +class OnapVvpTestcase(Testcase): + + validate_testcase_list = {} + + def __init__(self, testcase_yaml): + super(OnapVvpTestcase, self).__init__(testcase_yaml) + self.type = 'onap-vvp' + + class TestcaseFactory(object): TESTCASE_TYPE_MAP = { 'functest': FunctestTestcase, 'yardstick': YardstickTestcase, 'bottlenecks': BottlenecksTestcase, 'shell': ShellTestcase, + 'functest-k8s': FunctestK8sTestcase, + 'onap-vtp': OnapVtpTestcase, + 'onap-vvp': OnapVvpTestcase } @classmethod @@ -368,8 +408,7 @@ class Testsuite(object): with open(os.path.join(root, testsuite_yaml)) as f: testsuite_yaml = yaml.safe_load(f) cls.testsuite_list.update(testsuite_yaml) - - # cls.logger.debug(cls.testsuite_list) + return cls.testsuite_list @classmethod def get(cls, testsuite_name): |