Integrate k8s test casses 05/65105/10
authorxudan <xudan16@huawei.com>
Wed, 14 Nov 2018 09:42:11 +0000 (04:42 -0500)
committerxudan <xudan16@huawei.com>
Fri, 23 Nov 2018 08:59:56 +0000 (03:59 -0500)
In order to integrate k8s test cases, Dovetail framework should do some
refactor and make it more general for k8s test cases as well as ONAP ones.
Integrate 2 k8s test cases.

JIRA: DOVETAIL-748

Change-Id: Ibd87754ffb5fb29f6b4ce79232af860c2ed2da9c
Signed-off-by: xudan <xudan16@huawei.com>
20 files changed:
dovetail/container.py
dovetail/report.py
dovetail/run.py
dovetail/test_runner.py
dovetail/testcase.py
dovetail/tests/unit/test_container.py
dovetail/tests/unit/test_report.py
dovetail/tests/unit/test_run.py
dovetail/tests/unit/test_test_runner.py
dovetail/tests/unit/test_testcase.py
dovetail/tests/unit/utils/test_dovetail_utils.py
dovetail/utils/dovetail_utils.py
etc/compliance/proposed_tests.yml
etc/conf/bottlenecks_config.yml
etc/conf/dovetail_config.yml
etc/conf/functest-k8s_config.yml [new file with mode: 0644]
etc/conf/functest_config.yml
etc/conf/yardstick_config.yml
etc/testcase/functest.k8s.conformance.yml [new file with mode: 0644]
etc/testcase/functest.k8s.smoke.yml [new file with mode: 0644]

index b0940b4..ed006dc 100644 (file)
@@ -49,21 +49,6 @@ class Container(object):
         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
-    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 {}:{} " \
-                     .format(dovetail_config['openrc'],
-                             dovetail_config[self.valid_type]['openrc'])
-            return openrc
-        else:
-            self.logger.error(
-                "File {} doesn't exist.".format(dovetail_config['openrc']))
-            return None
-
     def set_vnftest_config(self):
         dovetail_config = dt_cfg.dovetail_config
 
@@ -84,27 +69,13 @@ class Container(object):
         dovetail_config = dt_cfg.dovetail_config
         project_cfg = dovetail_config[self.valid_type]
 
-        # credentials file openrc.sh is neccessary
-        openrc = self.openrc_volume()
-        if not openrc:
-            return None
-
         opts = dt_utils.get_value_from_dict('opts', project_cfg)
         envs = dt_utils.get_value_from_dict('envs', project_cfg)
-        volumes = dt_utils.get_value_from_dict('volumes', project_cfg)
+        volumes_list = dt_utils.get_value_from_dict('volumes', project_cfg)
         opts = ' ' if not opts else opts
         envs = ' ' if not envs else envs
-        volumes = ' ' if not volumes else ' '.join(volumes)
-
-        # CI_DEBUG is used for showing the debug logs of the upstream projects
-        # BUILD_TAG is the unique id for this test
-        DEBUG = os.getenv('DEBUG')
-        if DEBUG is not None and DEBUG.lower() == "true":
-            envs = envs + ' -e CI_DEBUG=true'
-        else:
-            envs = envs + ' -e CI_DEBUG=false'
-        envs = envs + ' -e BUILD_TAG=%s-%s' % (dovetail_config['build_tag'],
-                                               self.testcase.name())
+        volumes = ' '.join(volume for volume in volumes_list if volume) \
+            if volumes_list else ' '
 
         hosts_config = dt_utils.get_hosts_info(self.logger)
 
@@ -119,40 +90,8 @@ class Container(object):
         if not config:
             return None
 
-        # for refstack, support user self_defined configuration
-        config_volume = \
-            ' -v %s:%s ' % (os.getenv("DOVETAIL_HOME"),
-                            project_cfg['config']['dir'])
-
-        cacert_volume = ""
-        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, self.logger):
-                cacert_volume = ' -v %s:%s ' % (cacert, cacert)
-            else:
-                return None
-        elif https_enabled:
-            if insecure and insecure.lower() == 'true':
-                self.logger.debug("Use the insecure mode...")
-            else:
-                self.logger.error("https enabled, please set OS_CACERT or "
-                                  "insecure mode...")
-                return None
-
-        images_volume = ''
-        if project_cfg['config'].get('images', None):
-            images_volume = '-v {}:{}'.format(
-                dovetail_config['images_dir'],
-                project_cfg['config']['images'])
-
-        result_volume = ' -v %s:%s ' % (dovetail_config['result_dir'],
-                                        project_cfg['result']['dir'])
         cmd = 'sudo docker run {opts} {envs} {volumes} {config} ' \
-              '{hosts_config} {openrc} {cacert_volume} {config_volume} ' \
-              '{result_volume} {images_volume} {docker_image} /bin/bash' \
-              .format(**locals())
+              '{hosts_config} {docker_image} /bin/bash'.format(**locals())
         ret, container_id = dt_utils.exec_cmd(cmd, self.logger)
         if ret != 0:
             return None
index 5f925c2..26cd6c5 100644 (file)
@@ -28,7 +28,7 @@ from testcase import Testcase
 
 class Report(object):
 
-    results = {'functest': {}, 'yardstick': {},
+    results = {'functest': {}, 'yardstick': {}, 'functest-k8s': {},
                'bottlenecks': {}, 'shell': {}, 'vnftest': {}}
 
     logger = None
@@ -294,6 +294,20 @@ class FunctestCrawler(Crawler):
         return json_results
 
 
+class FunctestK8sCrawler(FunctestCrawler):
+
+    logger = None
+
+    def __init__(self):
+        self.type = 'functest-k8s'
+        self.logger.debug('Create crawler: {}'.format(self.type))
+
+    @classmethod
+    def create_log(cls):
+        cls.logger = \
+            dt_logger.Logger(__name__ + '.FunctestK8sCrawler').getLogger()
+
+
 class YardstickCrawler(Crawler):
 
     logger = None
@@ -430,7 +444,8 @@ class CrawlerFactory(object):
                    'yardstick': YardstickCrawler,
                    'bottlenecks': BottlenecksCrawler,
                    'vnftest': VnftestCrawler,
-                   'shell': ShellCrawler}
+                   'shell': ShellCrawler,
+                   'functest-k8s': FunctestK8sCrawler}
 
     @classmethod
     def create(cls, type):
@@ -510,6 +525,16 @@ class FunctestChecker(object):
         testcase.passed(testcase_passed)
 
 
+class FunctestK8sChecker(FunctestChecker):
+
+    logger = None
+
+    @classmethod
+    def create_log(cls):
+        cls.logger = \
+            dt_logger.Logger(__name__ + '.FunctestK8sChecker').getLogger()
+
+
 class YardstickChecker(object):
 
     logger = None
@@ -580,7 +605,8 @@ class CheckerFactory(object):
                    'yardstick': YardstickChecker,
                    'bottlenecks': BottlenecksChecker,
                    'shell': ShellChecker,
-                   'vnftest': VnftestChecker}
+                   'vnftest': VnftestChecker,
+                   'functest-k8s': FunctestK8sChecker}
 
     @classmethod
     def create(cls, type):
index 9b4dade..6d2bcf6 100755 (executable)
@@ -107,10 +107,12 @@ def create_logs():
     Parser.create_log()
     dt_report.Report.create_log()
     dt_report.FunctestCrawler.create_log()
+    dt_report.FunctestK8sCrawler.create_log()
     dt_report.YardstickCrawler.create_log()
     dt_report.VnftestCrawler.create_log()
     dt_report.BottlenecksCrawler.create_log()
     dt_report.FunctestChecker.create_log()
+    dt_report.FunctestK8sChecker.create_log()
     dt_report.YardstickChecker.create_log()
     dt_report.VnftestChecker.create_log()
     dt_report.BottlenecksChecker.create_log()
@@ -166,30 +168,12 @@ def copy_patch_files(logger):
     dt_utils.exec_cmd(cmd, logger, exit_on_error=False)
 
 
-# env_init can source some env variable used in dovetail, such as
-# when https+credential used, OS_CACERT
-def env_init(logger):
-    openrc = os.path.join(dt_cfg.dovetail_config['config_dir'],
-                          dt_cfg.dovetail_config['env_file'])
-    if not os.path.isfile(openrc):
-        logger.error('File {} does not exist.'.format(openrc))
-    dt_utils.source_env(openrc)
-
-
 def update_deploy_scenario(logger, **kwargs):
     if 'deploy_scenario' in kwargs and kwargs['deploy_scenario'] is not None:
         os.environ['DEPLOY_SCENARIO'] = kwargs['deploy_scenario']
         logger.info('DEPLOY_SCENARIO : %s', os.environ['DEPLOY_SCENARIO'])
 
 
-def check_hosts_file(logger):
-    hosts_file = os.path.join(dt_cfg.dovetail_config['config_dir'],
-                              'hosts.yaml')
-    if not os.path.isfile(hosts_file):
-        logger.warn('There is no hosts file {}, may be some issues with '
-                    'domain name resolution.'.format(hosts_file))
-
-
 def parse_cli(logger=None, **kwargs):
     configs = filter_config(kwargs, logger)
     if configs is not None:
@@ -267,13 +251,9 @@ def main(*args, **kwargs):
     logger.info('Build tag: {}'.format(dt_cfg.dovetail_config['build_tag']))
     parse_cli(logger, **kwargs)
     update_deploy_scenario(logger, **kwargs)
-    env_init(logger)
     copy_userconfig_files(logger)
     copy_patch_files(logger)
     dt_utils.check_docker_version(logger)
-    dt_utils.get_openstack_endpoint(logger)
-    check_hosts_file(logger)
-    dt_utils.get_hardware_info(logger)
 
     testcase_list = get_testcase_list(logger, **kwargs)
     if not testcase_list:
index 8932ad8..d77c3c6 100644 (file)
@@ -148,32 +148,37 @@ class DockerRunner(object):
         if 'DEPLOY_SCENARIO' in os.environ:
             config_item['deploy_scenario'] = os.environ['DEPLOY_SCENARIO']
         config_item['dovetail_home'] = os.getenv('DOVETAIL_HOME')
+        config_item['debug'] = os.getenv('DEBUG')
+        config_item['build_tag'] = dt_cfg.dovetail_config['build_tag']
+        config_item['cacert'] = os.getenv('OS_CACERT')
         return config_item
 
-    def _update_config(self, testcase):
+    def _update_config(self, testcase, update_pod=True):
         config_item = None
-        pod_file = os.path.join(dt_cfg.dovetail_config['config_dir'],
-                                dt_cfg.dovetail_config['pod_file'])
         config_file = os.path.join(constants.CONF_PATH, self.config_file_name)
-        pod_info = dt_utils.read_yaml_file(pod_file, self.logger)
         task_template = dt_utils.read_plain_file(config_file, self.logger)
         if not task_template:
             return None
-        if pod_info:
-            try:
-                process_info = pod_info['process_info']
-            except KeyError as e:
-                process_info = None
-        else:
-            process_info = None
-        if process_info:
-            for item in process_info:
+        if update_pod:
+            pod_file = os.path.join(dt_cfg.dovetail_config['config_dir'],
+                                    dt_cfg.dovetail_config['pod_file'])
+            pod_info = dt_utils.read_yaml_file(pod_file, self.logger)
+            if pod_info:
                 try:
-                    if item['testcase_name'] == testcase.name():
-                        config_item = self._add_testcase_info(testcase, item)
-                        break
+                    process_info = pod_info['process_info']
                 except KeyError as e:
-                    self.logger.error('Need key {} in {}'.format(e, item))
+                    process_info = None
+            else:
+                process_info = None
+            if process_info:
+                for item in process_info:
+                    try:
+                        if item['testcase_name'] == testcase.name():
+                            config_item = self._add_testcase_info(
+                                testcase, item)
+                        break
+                    except KeyError as e:
+                        self.logger.error('Need key {} in {}'.format(e, item))
         if not config_item:
             config_item = self._add_testcase_info(testcase)
         full_task = self._render(task_template, **config_item)
@@ -189,9 +194,23 @@ class FunctestRunner(DockerRunner):
     def __init__(self, testcase):
         self.type = 'functest'
         super(FunctestRunner, self).__init__(testcase)
+        endpoint_file = os.path.join(dt_cfg.dovetail_config['result_dir'],
+                                     'endpoint_info.json')
+        if not os.path.isfile(endpoint_file):
+            dt_utils.get_openstack_info(self.logger)
         self._update_config(testcase)
 
 
+class FunctestK8sRunner(DockerRunner):
+
+    config_file_name = 'functest-k8s_config.yml'
+
+    def __init__(self, testcase):
+        self.type = 'functest-k8s'
+        super(FunctestK8sRunner, self).__init__(testcase)
+        self._update_config(testcase, update_pod=False)
+
+
 class YardstickRunner(DockerRunner):
 
     config_file_name = 'yardstick_config.yml'
@@ -199,6 +218,10 @@ class YardstickRunner(DockerRunner):
     def __init__(self, testcase):
         self.type = 'yardstick'
         super(YardstickRunner, self).__init__(testcase)
+        endpoint_file = os.path.join(dt_cfg.dovetail_config['result_dir'],
+                                     'endpoint_info.json')
+        if not os.path.isfile(endpoint_file):
+            dt_utils.get_openstack_info(self.logger)
         self._update_config(testcase)
 
 
@@ -209,6 +232,10 @@ class BottlenecksRunner(DockerRunner):
     def __init__(self, testcase):
         self.type = 'bottlenecks'
         super(BottlenecksRunner, self).__init__(testcase)
+        endpoint_file = os.path.join(dt_cfg.dovetail_config['result_dir'],
+                                     'endpoint_info.json')
+        if not os.path.isfile(endpoint_file):
+            dt_utils.get_openstack_info(self.logger)
         self._update_config(testcase)
 
 
@@ -279,7 +306,8 @@ class TestRunnerFactory(object):
         "yardstick": YardstickRunner,
         "bottlenecks": BottlenecksRunner,
         "shell": ShellRunner,
-        "vnftest": VnftestRunner
+        "vnftest": VnftestRunner,
+        "functest-k8s": FunctestK8sRunner
     }
 
     @classmethod
index ada5df8..3be1cb0 100644 (file)
@@ -272,7 +272,7 @@ class Testcase(object):
             for area in testarea:
                 if cls.check_testcase_area(value, area):
                     testcase_list.append(value)
-                    if value in mandatory:
+                    if mandatory and value in mandatory:
                         Testcase.testcase_list[value].is_mandatory = True
                     else:
                         Testcase.testcase_list[value].is_mandatory = False
@@ -308,6 +308,15 @@ class FunctestTestcase(Testcase):
         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):
 
     validate_testcase_list = {}
@@ -350,7 +359,8 @@ class TestcaseFactory(object):
         'yardstick': YardstickTestcase,
         'bottlenecks': BottlenecksTestcase,
         'shell': ShellTestcase,
-        'vnftest': VnftestTestcase
+        'vnftest': VnftestTestcase,
+        'functest-k8s': FunctestK8sTestcase
     }
 
     @classmethod
index ec6871a..70e01d8 100644 (file)
@@ -395,49 +395,6 @@ class ContainerTesting(unittest.TestCase):
 
         self.assertEquals(self.logger, self.container.logger)
 
-    @patch('dovetail.container.dt_cfg')
-    @patch('dovetail.container.os.path')
-    def test_openrc_volume(self, mock_path, mock_config):
-        v_one = 'v_one'
-        v_two = 'v_two'
-        v_three = 'v_three'
-        v_four = 'v_four'
-        mock_path.join.return_value = '/'.join([v_one, v_two])
-        mock_path.isfile.return_value = True
-        mock_config.dovetail_config = {'config_dir': v_one,
-                                       'env_file': v_two,
-                                       'openrc': v_three,
-                                       'bottlenecks': {'openrc': v_four}}
-
-        expected = ' -v {}/{}:{} '.format(v_one, v_two, v_four)
-        result = self.container.openrc_volume()
-
-        mock_path.join.assert_called_once_with(v_one, v_two)
-        mock_path.isfile.assert_called_once_with('/'.join([v_one, v_two]))
-        self.assertEquals(expected, result)
-
-    @patch('dovetail.container.dt_cfg')
-    @patch('dovetail.container.os.path')
-    def test_openrc_volume_error(self, mock_path, mock_config):
-        v_one = 'v_one'
-        v_two = 'v_two'
-        v_three = 'v_three'
-        v_four = 'v_four'
-        mock_path.join.return_value = '/'.join([v_one, v_two])
-        mock_path.isfile.return_value = False
-        mock_config.dovetail_config = {'config_dir': v_one,
-                                       'env_file': v_two,
-                                       'openrc': v_three,
-                                       'bottlenecks': {'openrc': v_four}}
-
-        result = self.container.openrc_volume()
-
-        mock_path.join.assert_called_once_with(v_one, v_two)
-        mock_path.isfile.assert_called_once_with('/'.join([v_one, v_two]))
-        self.logger.error.assert_called_once_with(
-            "File {} doesn't exist.".format('/'.join([v_one, v_two])))
-        self.assertEquals(None, result)
-
     @patch('dovetail.container.dt_cfg')
     @patch('dovetail.container.os.path')
     def test_set_vnftest_config_no_file(self, mock_path, mock_config):
@@ -485,194 +442,99 @@ class ContainerTesting(unittest.TestCase):
         mock_path.isfile.assert_called_once_with('/'.join([v_two, v_three]))
         self.assertEquals(expected, result)
 
-    @patch('dovetail.container.dt_cfg')
-    @patch.object(Container, 'openrc_volume')
-    def test_create_no_openrc(self, mock_openrc, mock_config):
-        mock_openrc.return_value = None
-
-        result = self.container.create('docker_image')
-
-        mock_openrc.assert_called_once_with()
-        self.assertEquals(None, result)
-
     @patch('dovetail.container.dt_utils')
     @patch('dovetail.container.dt_cfg')
-    @patch('dovetail.container.os.getenv')
-    @patch.object(Container, 'openrc_volume')
-    def test_create(self, mock_openrc, mock_getenv, mock_config, mock_utils):
+    def test_create(self, mock_config, mock_utils):
         docker_image = 'docker_image'
         container_id = 'container_id'
-        mock_openrc.return_value = 'openrc'
         mock_utils.get_value_from_dict.side_effect = [
-            'opts', 'envs', ['volume_one']]
-        mock_getenv.side_effect = ['True', 'dovetail_home', 'cacert', 'True']
+            'opts', 'envs', ['volume_one', 'volume_two']]
         mock_utils.get_hosts_info.return_value = 'host_info'
-        mock_utils.check_cacert_file.return_value = True
         mock_utils.exec_cmd.return_value = (0, container_id)
-        v_one = 'v_one'
-        v_two = 'v_two'
-        v_three = 'v_three'
-        v_four = 'v_four'
-        v_five = 'v_five'
-        v_six = 'v_six'
-        project_config = {
-            'config': {'dir': v_one, 'images': v_two},
-            'result': {'dir': v_three}}
-        mock_config.dovetail_config = {
-            'bottlenecks': project_config,
-            'build_tag': v_four,
-            'images_dir': v_five,
-            'result_dir': v_six}
+        project_config = {}
+        mock_config.dovetail_config = {'bottlenecks': project_config}
 
         expected = container_id
         result = self.container.create(docker_image)
 
-        mock_openrc.assert_called_once_with()
         mock_utils.get_value_from_dict.assert_has_calls([
             call('opts', project_config),
             call('envs', project_config),
             call('volumes', project_config)])
-        mock_getenv.assert_has_calls([
-            call('DEBUG'),
-            call('DOVETAIL_HOME'),
-            call('OS_CACERT'),
-            call('OS_INSECURE')])
         mock_utils.get_hosts_info.assert_called_once_with(self.logger)
-        mock_utils.check_https_enabled.assert_called_once_with(self.logger)
-        mock_utils.check_cacert_file.assert_called_once_with('cacert',
-                                                             self.logger)
         mock_utils.exec_cmd.assert_called_once_with(
-            'sudo docker run opts envs -e CI_DEBUG=true '
-            '-e BUILD_TAG=v_four-name volume_one   host_info openrc  '
-            '-v cacert:cacert   -v dovetail_home:v_one   -v v_six:v_three  '
-            '-v v_five:v_two docker_image /bin/bash',
-            self.logger)
+            'sudo docker run opts envs volume_one volume_two   host_info '
+            'docker_image /bin/bash', self.logger)
         self.assertEquals(expected, result)
 
     @patch('dovetail.container.dt_utils')
     @patch('dovetail.container.dt_cfg')
     @patch('dovetail.container.os.getenv')
-    @patch.object(Container, 'openrc_volume')
-    def test_create_error(self, mock_openrc, mock_getenv, mock_config,
-                          mock_utils):
+    def test_create_error(self, mock_getenv, mock_config, mock_utils):
         docker_image = 'docker_image'
-        mock_openrc.return_value = 'openrc'
         mock_utils.get_value_from_dict.side_effect = [
             'opts', 'envs', ['volume_one']]
         mock_getenv.side_effect = ['True', 'dovetail_home', None, 'True']
         mock_utils.get_hosts_info.return_value = 'host_info'
         mock_utils.check_https_enabled.return_value = True
         mock_utils.exec_cmd.return_value = (1, 'error')
-        v_one = 'v_one'
-        v_two = 'v_two'
-        v_three = 'v_three'
-        v_four = 'v_four'
-        v_five = 'v_five'
-        v_six = 'v_six'
-        project_config = {
-            'config': {'dir': v_one, 'images': v_two},
-            'result': {'dir': v_three}}
-        mock_config.dovetail_config = {
-            'bottlenecks': project_config,
-            'build_tag': v_four,
-            'images_dir': v_five,
-            'result_dir': v_six}
-
+        project_config = {}
+        mock_config.dovetail_config = {'bottlenecks': project_config}
         result = self.container.create(docker_image)
 
-        mock_openrc.assert_called_once_with()
         mock_utils.get_value_from_dict.assert_has_calls([
             call('opts', project_config),
             call('envs', project_config),
             call('volumes', project_config)])
-        mock_getenv.assert_has_calls([
-            call('DEBUG'),
-            call('DOVETAIL_HOME'),
-            call('OS_CACERT'),
-            call('OS_INSECURE')])
         mock_utils.get_hosts_info.assert_called_once_with(self.logger)
-        mock_utils.check_https_enabled.assert_called_once_with(self.logger)
         mock_utils.exec_cmd.assert_called_once_with(
-            'sudo docker run opts envs -e CI_DEBUG=true '
-            '-e BUILD_TAG=v_four-name volume_one   host_info openrc   '
-            '-v dovetail_home:v_one   -v v_six:v_three  '
-            '-v v_five:v_two docker_image /bin/bash',
-            self.logger)
-        self.logger.debug.assert_called_once_with(
-            'Use the insecure mode...')
+            'sudo docker run opts envs volume_one   host_info '
+            'docker_image /bin/bash', self.logger)
         self.assertEquals(None, result)
 
     @patch('dovetail.container.dt_utils')
     @patch('dovetail.container.dt_cfg')
     @patch('dovetail.container.os.getenv')
-    @patch.object(Container, 'openrc_volume')
     @patch.object(Container, 'set_vnftest_config')
     @patch.object(Container, 'set_vnftest_conf_file')
     def test_create_vnftest(self, mock_setvnffile, mock_setvnfconf,
-                            mock_openrc, mock_getenv, mock_config, mock_utils):
+                            mock_getenv, mock_config, mock_utils):
         docker_image = 'docker_image'
         container_id = 'container_id'
-        mock_openrc.return_value = 'openrc'
         mock_utils.get_value_from_dict.side_effect = [
             'opts', 'envs', ['volume_one']]
         mock_getenv.side_effect = ['False', 'dovetail_home', 'cacert', 'True']
         mock_setvnfconf.return_value = 'vnftest_config'
         mock_utils.get_hosts_info.return_value = 'host_info'
-        mock_utils.check_cacert_file.return_value = True
         mock_utils.exec_cmd.return_value = (0, container_id)
-        v_one = 'v_one'
-        v_two = 'v_two'
-        v_three = 'v_three'
-        v_four = 'v_four'
-        v_five = 'v_five'
-        v_six = 'v_six'
-        project_config = {
-            'config': {'dir': v_one, 'images': v_two},
-            'result': {'dir': v_three}}
-        mock_config.dovetail_config = {
-            'vnftest': project_config,
-            'build_tag': v_four,
-            'images_dir': v_five,
-            'result_dir': v_six}
+        project_config = {}
+        mock_config.dovetail_config = {'vnftest': project_config}
 
         expected = container_id
         self.container.valid_type = 'vnftest'
         result = self.container.create(docker_image)
         self.container.valid_type = 'bottlenecks'
 
-        mock_openrc.assert_called_once_with()
         mock_utils.get_value_from_dict.assert_has_calls([
             call('opts', project_config),
             call('envs', project_config),
             call('volumes', project_config)])
-        mock_getenv.assert_has_calls([
-            call('DEBUG'),
-            call('DOVETAIL_HOME'),
-            call('OS_CACERT'),
-            call('OS_INSECURE')])
         mock_utils.get_hosts_info.assert_called_once_with(self.logger)
         mock_setvnfconf.assert_called_once_with()
         mock_setvnffile.assert_called_once_with(container_id)
-        mock_utils.check_https_enabled.assert_called_once_with(self.logger)
-        mock_utils.check_cacert_file.assert_called_once_with('cacert',
-                                                             self.logger)
         mock_utils.exec_cmd.assert_called_once_with(
-            'sudo docker run opts envs -e CI_DEBUG=false '
-            '-e BUILD_TAG=v_four-name volume_one vnftest_config host_info '
-            'openrc  -v cacert:cacert   -v dovetail_home:v_one   '
-            '-v v_six:v_three  -v v_five:v_two docker_image /bin/bash',
+            'sudo docker run opts envs volume_one vnftest_config host_info '
+            'docker_image /bin/bash',
             self.logger)
         self.assertEquals(expected, result)
 
     @patch('dovetail.container.dt_utils')
     @patch('dovetail.container.dt_cfg')
     @patch('dovetail.container.os.getenv')
-    @patch.object(Container, 'openrc_volume')
     @patch.object(Container, 'set_vnftest_config')
-    def test_create_vnftest_error(self, mock_setvnfconf, mock_openrc,
+    def test_create_vnftest_error(self, mock_setvnfconf,
                                   mock_getenv, mock_config, mock_utils):
         docker_image = 'docker_image'
-        mock_openrc.return_value = 'openrc'
         mock_utils.get_value_from_dict.side_effect = [
             'opts', 'envs', ['volume_one']]
         mock_getenv.return_value = 'True'
@@ -685,81 +547,10 @@ class ContainerTesting(unittest.TestCase):
         result = self.container.create(docker_image)
         self.container.valid_type = 'bottlenecks'
 
-        mock_openrc.assert_called_once_with()
         mock_utils.get_value_from_dict.assert_has_calls([
             call('opts', 'value'),
             call('envs', 'value'),
             call('volumes', 'value')])
-        mock_getenv.assert_called_once_with('DEBUG')
         mock_utils.get_hosts_info.assert_called_once_with(self.logger)
         mock_setvnfconf.assert_called_once_with()
         self.assertEquals(None, result)
-
-    @patch('dovetail.container.dt_utils')
-    @patch('dovetail.container.dt_cfg')
-    @patch('dovetail.container.os.getenv')
-    @patch.object(Container, 'openrc_volume')
-    def test_create_https_enabled_error(self, mock_openrc, mock_getenv,
-                                        mock_config, mock_utils):
-        mock_openrc.return_value = 'openrc'
-        mock_utils.get_value_from_dict.side_effect = [
-            'opts', 'envs', ['volume_one']]
-        mock_getenv.side_effect = ['True', 'dovetail_home', None, 'False']
-        mock_utils.get_hosts_info.return_value = 'host_info'
-        project_config = {'config': {'dir': 'v_one'}}
-        mock_config.dovetail_config = {
-            'bottlenecks': project_config,
-            'build_tag': 'v_two'}
-
-        result = self.container.create('docker_image')
-
-        mock_openrc.assert_called_once_with()
-        mock_utils.get_value_from_dict.assert_has_calls([
-            call('opts', project_config),
-            call('envs', project_config),
-            call('volumes', project_config)])
-        mock_getenv.assert_has_calls([
-            call('DEBUG'),
-            call('DOVETAIL_HOME'),
-            call('OS_CACERT'),
-            call('OS_INSECURE')])
-        mock_utils.get_hosts_info.assert_called_once_with(self.logger)
-        mock_utils.check_https_enabled.assert_called_once_with(self.logger)
-        self.logger.error.assert_called_once_with(
-            'https enabled, please set OS_CACERT or insecure mode...')
-        self.assertEquals(None, result)
-
-    @patch('dovetail.container.dt_utils')
-    @patch('dovetail.container.dt_cfg')
-    @patch('dovetail.container.os.getenv')
-    @patch.object(Container, 'openrc_volume')
-    def test_create_cacert_error(self, mock_openrc, mock_getenv, mock_config,
-                                 mock_utils):
-        mock_openrc.return_value = 'openrc'
-        mock_utils.get_value_from_dict.side_effect = [
-            'opts', 'envs', ['volume_one']]
-        mock_getenv.side_effect = ['True', 'dovetail_home', 'cacert', 'True']
-        mock_utils.get_hosts_info.return_value = 'host_info'
-        mock_utils.check_cacert_file.return_value = False
-        project_config = {'config': {'dir': 'v_one'}}
-        mock_config.dovetail_config = {
-            'bottlenecks': project_config,
-            'build_tag': 'v_two'}
-
-        result = self.container.create('docker_image')
-
-        mock_openrc.assert_called_once_with()
-        mock_utils.get_value_from_dict.assert_has_calls([
-            call('opts', project_config),
-            call('envs', project_config),
-            call('volumes', project_config)])
-        mock_getenv.assert_has_calls([
-            call('DEBUG'),
-            call('DOVETAIL_HOME'),
-            call('OS_CACERT'),
-            call('OS_INSECURE')])
-        mock_utils.get_hosts_info.assert_called_once_with(self.logger)
-        mock_utils.check_https_enabled.assert_called_once_with(self.logger)
-        mock_utils.check_cacert_file.assert_called_once_with('cacert',
-                                                             self.logger)
-        self.assertEquals(None, result)
index ad236e9..fa5a02e 100644 (file)
@@ -30,16 +30,18 @@ class ReportTesting(unittest.TestCase):
 
     def teardown_method(self, method):
         dt_report.FunctestCrawler.logger = None
+        dt_report.FunctestK8sCrawler.logger = None
         dt_report.YardstickCrawler.logger = None
         dt_report.BottlenecksCrawler.logger = None
         dt_report.VnftestCrawler.logger = None
         dt_report.FunctestChecker.logger = None
+        dt_report.FunctestK8sChecker.logger = None
         dt_report.YardstickChecker.logger = None
         dt_report.BottlenecksChecker.logger = None
         dt_report.VnftestChecker.logger = None
         dt_report.Report.logger = None
         dt_report.Report.results = {
-            'functest': {}, 'yardstick': {},
+            'functest': {}, 'yardstick': {}, 'functest-k8s': {},
             'bottlenecks': {}, 'shell': {}, 'vnftest': {}}
 
     def _produce_report_initial_text(self, report_data):
@@ -622,6 +624,36 @@ class ReportTesting(unittest.TestCase):
             "Result data don't have key 'case_name'.")
         self.assertEquals(None, result)
 
+    @patch('dovetail.report.dt_logger')
+    def test_functestk8s_crawler_create_log(self, mock_logger):
+        getlogger_obj = Mock()
+        logger_obj = Mock()
+        logger_obj.getLogger.return_value = getlogger_obj
+        mock_logger.Logger.return_value = logger_obj
+
+        dt_report.FunctestK8sCrawler.create_log()
+
+        self.assertEquals(getlogger_obj, dt_report.FunctestK8sCrawler.logger)
+
+    @patch('dovetail.report.FunctestK8sCrawler.crawl_from_file')
+    @patch('dovetail.report.dt_cfg')
+    @patch('dovetail.report.os.path')
+    def test_functestk8s_crawler_crawl_none(self, mock_path, mock_config,
+                                            mock_crawl):
+        logger_obj = Mock()
+        dt_report.FunctestK8sCrawler.logger = logger_obj
+        mock_crawl.return_value = None
+        testcase = 'testcase'
+        file_path = 'file_path'
+
+        crawler = dt_report.FunctestK8sCrawler()
+
+        result = crawler.crawl(testcase, file_path)
+
+        dt_report.FunctestK8sCrawler.crawl_from_file.assert_called_once_with(
+            'testcase', 'file_path')
+        self.assertEquals(None, result)
+
     @patch('dovetail.report.dt_logger')
     def test_yardstick_crawler_create_log(self, mock_logger):
         getlogger_obj = Mock()
@@ -1051,6 +1083,17 @@ class ReportTesting(unittest.TestCase):
             call('subt_d', 'FAIL')])
         testcase_obj.passed.assert_has_calls([call('PASS'), call('FAIL')])
 
+    @patch('dovetail.report.dt_logger')
+    def test_functestk8s_checker_create_log(self, mock_logger):
+        getlogger_obj = Mock()
+        logger_obj = Mock()
+        logger_obj.getLogger.return_value = getlogger_obj
+        mock_logger.Logger.return_value = logger_obj
+
+        dt_report.FunctestK8sChecker.create_log()
+
+        self.assertEquals(getlogger_obj, dt_report.FunctestK8sChecker.logger)
+
     @patch('dovetail.report.dt_logger')
     def test_yardstick_checker_create_log(self, mock_logger):
         getlogger_obj = Mock()
index 1e48fe6..c7fe4d6 100644 (file)
@@ -321,24 +321,6 @@ class RunTesting(unittest.TestCase):
         mock_utils.exec_cmd.assert_called_once_with(
             'sudo cp -a -r value/* value', logger, exit_on_error=False)
 
-    @patch('dovetail.run.dt_cfg')
-    @patch('dovetail.run.dt_utils')
-    @patch('dovetail.run.os')
-    def test_env_init(self, mock_os, mock_utils, mock_config):
-        mock_config.dovetail_config = {'config_dir': 'a', 'env_file': 'b'}
-        join_path = 'join_path'
-        mock_os.path.join.return_value = join_path
-        mock_os.path.isfile.return_value = False
-        logger = Mock()
-
-        dt_run.env_init(logger)
-
-        mock_os.path.join.assert_called_once_with('a', 'b')
-        mock_os.path.isfile.assert_called_once_with(join_path)
-        logger.error.assert_called_once_with(
-            "File {} does not exist.".format(join_path))
-        mock_utils.source_env.assert_called_once_with(join_path)
-
     @patch('dovetail.run.os')
     def test_update_deploy_scenario(self, mock_os):
         logger = Mock()
@@ -349,23 +331,6 @@ class RunTesting(unittest.TestCase):
         logger.info.assert_called_once_with('DEPLOY_SCENARIO : %s', 'a')
         self.assertEquals({'DEPLOY_SCENARIO': 'a'}, mock_os.environ)
 
-    @patch('dovetail.run.dt_cfg')
-    @patch('dovetail.run.os.path')
-    def test_check_hosts_file(self, mock_path, mock_config):
-        mock_config.dovetail_config = {'config_dir': 'value'}
-        hosts_file = 'h_file'
-        mock_path.join.return_value = hosts_file
-        mock_path.isfile.return_value = False
-        logger = Mock()
-
-        dt_run.check_hosts_file(logger)
-
-        mock_path.join.assert_called_once_with('value', 'hosts.yaml')
-        mock_path.isfile.assert_called_once_with(hosts_file)
-        logger.warn.assert_called_once_with(
-            'There is no hosts file {}, may be some issues with '
-            'domain name resolution.'.format(hosts_file))
-
     @patch('dovetail.run.dt_cfg')
     @patch.object(dt_run, 'filter_config')
     def test_cli_no_validation(self, mock_filter, mock_config):
@@ -517,17 +482,15 @@ class RunTesting(unittest.TestCase):
     @patch.object(dt_run, 'clean_results_dir')
     @patch.object(dt_run, 'parse_cli')
     @patch.object(dt_run, 'update_deploy_scenario')
-    @patch.object(dt_run, 'env_init')
     @patch.object(dt_run, 'copy_userconfig_files')
     @patch.object(dt_run, 'copy_patch_files')
-    @patch.object(dt_run, 'check_hosts_file')
     @patch.object(dt_run, 'get_testcase_list')
     @patch.object(dt_run, 'run_test')
     @patch.object(dt_run, 'create_logs')
-    def test_main(self, mock_create_logs, mock_run, mock_get_list, mock_check,
-                  mock_copy_patch, mock_copy_userconf, mock_env_init,
-                  mock_update, mock_parse, mock_clean, mock_get_result,
-                  mock_utils, mock_config, mock_logger, mock_uuid, mock_os):
+    def test_main(self, mock_create_logs, mock_run, mock_get_list,
+                  mock_copy_patch, mock_copy_userconf, mock_update, mock_parse,
+                  mock_clean, mock_get_result, mock_utils, mock_config,
+                  mock_logger, mock_uuid, mock_os):
         mock_config.dovetail_config = {}
         mock_os.environ = {}
         logger_obj = Mock()
@@ -566,13 +529,9 @@ class RunTesting(unittest.TestCase):
             call('Build tag: daily-master-42')])
         mock_parse.assert_called_once_with(logger_obj, **kwargs_dict)
         mock_update.assert_called_once_with(logger_obj, **kwargs_dict)
-        mock_env_init.assert_called_once_with(logger_obj)
         mock_copy_userconf.assert_called_once_with(logger_obj)
         mock_copy_patch.assert_called_once_with(logger_obj)
         mock_utils.check_docker_version.assert_called_once_with(logger_obj)
-        mock_utils.get_openstack_endpoint.assert_called_once_with(logger_obj)
-        mock_check.assert_called_once_with(logger_obj)
-        mock_utils.get_hardware_info.assert_called_once_with(logger_obj)
         mock_get_list.assert_called_once_with(logger_obj, **kwargs_dict)
         mock_run.assert_called_once_with(
             testcase_list, kwargs_dict['report'], logger_obj)
@@ -604,19 +563,16 @@ class RunTesting(unittest.TestCase):
     @patch('dovetail.run.dt_utils')
     @patch.object(dt_run, 'get_result_path')
     @patch.object(dt_run, 'clean_results_dir')
-    @patch.object(dt_run, 'parse_cli')
     @patch.object(dt_run, 'update_deploy_scenario')
-    @patch.object(dt_run, 'env_init')
     @patch.object(dt_run, 'copy_userconfig_files')
     @patch.object(dt_run, 'copy_patch_files')
-    @patch.object(dt_run, 'check_hosts_file')
     @patch.object(dt_run, 'get_testcase_list')
+    @patch.object(dt_run, 'parse_cli')
     @patch.object(dt_run, 'run_test')
     @patch.object(dt_run, 'create_logs')
-    def test_main_no_testcaselist(self, mock_create_logs, mock_run,
-                                  mock_get_list, mock_check, mock_copy_patch,
-                                  mock_copy_userconf, mock_env_init,
-                                  mock_update, mock_parse, mock_clean,
+    def test_main_no_testcaselist(self, mock_create_logs, mock_run, mock_parse,
+                                  mock_get_list, mock_copy_patch,
+                                  mock_copy_userconf, mock_update, mock_clean,
                                   mock_get_result, mock_utils, mock_config,
                                   mock_logger, mock_uuid, mock_os):
         mock_config.dovetail_config = {}
@@ -657,11 +613,7 @@ class RunTesting(unittest.TestCase):
             call('Build tag: daily-master-42')])
         mock_parse.assert_called_once_with(logger_obj, **kwargs_dict)
         mock_update.assert_called_once_with(logger_obj, **kwargs_dict)
-        mock_env_init.assert_called_once_with(logger_obj)
         mock_copy_userconf.assert_called_once_with(logger_obj)
         mock_copy_patch.assert_called_once_with(logger_obj)
         mock_utils.check_docker_version.assert_called_once_with(logger_obj)
-        mock_utils.get_openstack_endpoint.assert_called_once_with(logger_obj)
-        mock_check.assert_called_once_with(logger_obj)
-        mock_utils.get_hardware_info.assert_called_once_with(logger_obj)
         mock_get_list.assert_called_once_with(logger_obj, **kwargs_dict)
index f11bd92..08dbde6 100644 (file)
@@ -20,7 +20,8 @@ class TestRunnerTesting(unittest.TestCase):
 
     def setUp(self):
         self.patcher1 = patch.object(t_runner, 'dt_logger')
-        self.patcher2 = patch.object(t_runner.DockerRunner, '_update_config')
+        self.patcher2 = patch.object(t_runner.DockerRunner,
+                                     '_update_config')
 
         self.logger = self.patcher1.start().return_value
         self._update_config = self.patcher2.start().return_value
@@ -29,7 +30,7 @@ class TestRunnerTesting(unittest.TestCase):
         self.testcase_name = 'testcase_name'
         self.testcase_type = 'functest'
         self.testcase_dict = {}
-        self.testcase_valid = True
+        self.testcase_valid = 'validate_testcase'
 
         self.testcase.testcase = self.testcase_dict
         self.testcase.name.return_value = self.testcase_name
@@ -40,8 +41,11 @@ class TestRunnerTesting(unittest.TestCase):
         self.patcher1.stop()
         self.patcher2.stop()
 
-    def test_pre_copy_no_container(self):
+    @patch('dovetail.test_runner.dt_utils')
+    @patch('dovetail.test_runner.dt_cfg')
+    def test_pre_copy_no_container(self, mock_config, mock_utils):
         t_runner.FunctestRunner.create_log()
+        mock_config.dovetail_config = {'result_dir': 'result_dir'}
         docker_runner = t_runner.FunctestRunner(self.testcase)
 
         result = docker_runner.pre_copy(
@@ -52,8 +56,11 @@ class TestRunnerTesting(unittest.TestCase):
             'Container instance is None.')
         self.assertEquals(None, result)
 
-    def test_pre_copy_no_dest_path(self):
+    @patch('dovetail.test_runner.dt_utils')
+    @patch('dovetail.test_runner.dt_cfg')
+    def test_pre_copy_no_dest_path(self, mock_config, mock_utils):
         t_runner.FunctestRunner.create_log()
+        mock_config.dovetail_config = {'result_dir': 'result_dir'}
         docker_runner = t_runner.FunctestRunner(self.testcase)
 
         result = docker_runner.pre_copy(
@@ -93,14 +100,17 @@ class TestRunnerTesting(unittest.TestCase):
         container_obj.copy_file.assert_called_once_with('join', 'dest_path')
         self.assertEquals('dest_path', result)
 
+    @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.Container')
-    def test_run_offline_not_exist(self, mock_container, mock_config):
+    def test_run_offline_not_exist(self, mock_container, mock_config,
+                                   mock_utils):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.TestRunnerFactory.create(self.testcase)
         mock_config.dovetail_config = {
-            'offline': True
+            'offline': True, 'result_dir': 'result_dir'
         }
+        docker_runner = t_runner.TestRunnerFactory.create(self.testcase)
+
         container_obj = Mock()
         docker_img_obj = Mock()
         container_obj.get_docker_image.return_value = docker_img_obj
@@ -116,14 +126,17 @@ class TestRunnerTesting(unittest.TestCase):
             "{} image doesn't exist, can't run offline.".format(
                 self.testcase_type))
 
+    @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.Container')
-    def test_run__not_offline_no_pull(self, mock_container, mock_config):
+    def test_run__not_offline_no_pull(self, mock_container, mock_config,
+                                      mock_utils):
         t_runner.YardstickRunner.create_log()
-        docker_runner = t_runner.YardstickRunner(self.testcase)
         mock_config.dovetail_config = {
-            'offline': False
+            'offline': False, 'result_dir': 'result_dir'
         }
+        docker_runner = t_runner.YardstickRunner(self.testcase)
+
         container_obj = Mock()
         docker_img_obj = Mock()
         container_obj.get_docker_image.return_value = docker_img_obj
@@ -138,14 +151,17 @@ class TestRunnerTesting(unittest.TestCase):
         docker_runner.logger.error.assert_called_once_with(
             'Failed to pull the image.')
 
+    @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.Container')
-    def test_run__not_offline_no_create(self, mock_container, mock_config):
+    def test_run__not_offline_no_create(self, mock_container, mock_config,
+                                        mock_utils):
         t_runner.BottlenecksRunner.create_log()
-        docker_runner = t_runner.BottlenecksRunner(self.testcase)
         mock_config.dovetail_config = {
-            'offline': False
+            'offline': False, 'result_dir': 'result_dir'
         }
+        docker_runner = t_runner.BottlenecksRunner(self.testcase)
+
         container_obj = Mock()
         docker_img_obj = Mock()
         container_obj.get_docker_image.return_value = docker_img_obj
@@ -201,17 +217,20 @@ class TestRunnerTesting(unittest.TestCase):
         mock_precopy.assert_called_once_with(
             container_obj, dest_path, src_file_name, exist_file_name)
 
+    @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.Container')
     @patch.object(t_runner.DockerRunner, 'pre_copy')
     def test_run__not_offline_no_prepare(self, mock_precopy, mock_container,
-                                         mock_config):
+                                         mock_config, mock_utils):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.FunctestRunner(self.testcase)
         mock_config.dovetail_config = {
             'offline': False,
-            'noclean': False
+            'noclean': False,
+            'result_dir': 'result_dir'
         }
+        docker_runner = t_runner.FunctestRunner(self.testcase)
+
         container_obj = Mock()
         docker_img_obj = Mock()
         container_obj.get_docker_image.return_value = docker_img_obj
@@ -249,17 +268,19 @@ class TestRunnerTesting(unittest.TestCase):
                  .format(self.testcase_name))])
         container_obj.clean.assert_called_once_with()
 
+    @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.Container')
     @patch.object(t_runner.DockerRunner, 'pre_copy')
     def test_run__not_offline_prepare(self, mock_precopy, mock_container,
-                                      mock_config):
+                                      mock_config, mock_utils):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.FunctestRunner(self.testcase)
         mock_config.dovetail_config = {
             'offline': False,
-            'noclean': False
+            'noclean': False,
+            'result_dir': 'result_dir'
         }
+        docker_runner = t_runner.FunctestRunner(self.testcase)
         container_obj = Mock()
         docker_img_obj = Mock()
         container_obj.get_docker_image.return_value = docker_img_obj
@@ -298,33 +319,38 @@ class TestRunnerTesting(unittest.TestCase):
                  .format('cmd', 1, 'error'))])
         container_obj.clean.assert_called_once_with()
 
+    @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.os')
-    def test_archive_logs_no_files(self, mock_os, mock_utils):
+    def test_archive_logs_no_files(self, mock_os, mock_utils, mock_config):
         t_runner.FunctestRunner.create_log()
+        mock_config.dovetail_config = {'result_dir': 'result_dir'}
         docker_runner = t_runner.FunctestRunner(self.testcase)
         mock_os.environ = {'DOVETAIL_HOME': 'dovetail_home'}
         mock_utils.get_value_from_dict.return_value = []
 
         result = docker_runner.archive_logs()
 
-        mock_os.path.join.assert_called_once_with('dovetail_home', 'results')
+        mock_os.path.join.assert_has_calls([call('dovetail_home', 'results')])
         mock_utils.get_value_from_dict.assert_has_calls([
             call('report.source_archive_files', self.testcase_dict),
             call('report.dest_archive_files', self.testcase_dict)])
         self.assertEquals(True, result)
 
+    @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.os')
-    def test_archive_logs_difference_in_files(self, mock_os, mock_utils):
+    def test_archive_logs_difference_in_files(self, mock_os, mock_utils,
+                                              mock_config):
         t_runner.FunctestRunner.create_log()
+        mock_config.dovetail_config = {'result_dir': 'result_dir'}
         docker_runner = t_runner.FunctestRunner(self.testcase)
         mock_os.environ = {'DOVETAIL_HOME': 'dovetail_home'}
         mock_utils.get_value_from_dict.side_effect = [[], ['file']]
 
         result = docker_runner.archive_logs()
 
-        mock_os.path.join.assert_called_once_with('dovetail_home', 'results')
+        mock_os.path.join.assert_has_calls([call('dovetail_home', 'results')])
         mock_utils.get_value_from_dict.assert_has_calls([
             call('report.source_archive_files', self.testcase_dict),
             call('report.dest_archive_files', self.testcase_dict)])
@@ -334,10 +360,13 @@ class TestRunnerTesting(unittest.TestCase):
             .format(self.testcase_name))
         self.assertEquals(False, result)
 
+    @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.os')
-    def test_archive_logs_src_file_error(self, mock_os, mock_utils):
+    def test_archive_logs_src_file_error(self, mock_os, mock_utils,
+                                         mock_config):
         t_runner.FunctestRunner.create_log()
+        mock_config.dovetail_config = {'result_dir': 'result_dir'}
         docker_runner = t_runner.FunctestRunner(self.testcase)
         mock_os.environ = {'DOVETAIL_HOME': 'dovetail_home'}
         mock_utils.get_value_from_dict.side_effect = [['src_file'],
@@ -355,15 +384,18 @@ class TestRunnerTesting(unittest.TestCase):
         mock_utils.get_value_from_dict.assert_has_calls([
             call('report.source_archive_files', self.testcase_dict),
             call('report.dest_archive_files', self.testcase_dict)])
-        mock_os.path.isfile.assert_called_once_with('src_file_path')
+        mock_os.path.isfile.assert_has_calls([call('src_file_path')])
         docker_runner.logger.error.assert_called_once_with(
             "Can't find file {}.".format('src_file_path'))
         self.assertEquals(False, result)
 
+    @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.dt_utils')
     @patch('dovetail.test_runner.os')
-    def test_archive_logs_src_file_exists(self, mock_os, mock_utils):
+    def test_archive_logs_src_file_exists(self, mock_os, mock_utils,
+                                          mock_config):
         t_runner.FunctestRunner.create_log()
+        mock_config.dovetail_config = {'result_dir': 'result_dir'}
         docker_runner = t_runner.FunctestRunner(self.testcase)
         mock_os.environ = {'DOVETAIL_HOME': 'dovetail_home'}
         mock_utils.get_value_from_dict.side_effect = [['src_file'],
@@ -381,7 +413,7 @@ class TestRunnerTesting(unittest.TestCase):
         mock_utils.get_value_from_dict.assert_has_calls([
             call('report.source_archive_files', self.testcase_dict),
             call('report.dest_archive_files', self.testcase_dict)])
-        mock_os.path.isfile.assert_called_once_with('src_file_path')
+        mock_os.path.isfile.assert_has_calls([call('src_file_path')])
         mock_os.renames.assert_called_once_with(
             'src_file_path', 'dest_file_path')
         self.assertEquals(True, result)
@@ -399,20 +431,27 @@ class TestRunnerTesting(unittest.TestCase):
         template_obj.render.assert_called_with()
         self.assertEquals(render_obj, result)
 
+    @patch('dovetail.test_runner.dt_cfg')
     @patch('dovetail.test_runner.os')
-    def test_add_testcase_info(self, mock_os):
-        mock_os.getenv.side_effect = ['os_insecure', 'dovetail_home']
+    def test_add_testcase_info(self, mock_os, mock_config):
+        mock_os.getenv.side_effect = ['os_insecure', 'dovetail_home', 'debug',
+                                      'os_cacert']
         mock_os.environ = {'DEPLOY_SCENARIO': 'deploy_scenario'}
+        mock_config.dovetail_config = {'build_tag': 'build_tag'}
 
         expected = {
-            'os_insecure': 'os_insecure', 'dovetail_home': 'dovetail_home',
-            'testcase': 'testcase_name', 'validate_testcase': True,
-            'deploy_scenario': 'deploy_scenario'}
+            'validate_testcase': 'validate_testcase',
+            'testcase': 'testcase_name', 'os_insecure': 'os_insecure',
+            'deploy_scenario': 'deploy_scenario',
+            'dovetail_home': 'dovetail_home', 'debug': 'debug',
+            'build_tag': 'build_tag', 'cacert': 'os_cacert'}
         result = t_runner.FunctestRunner._add_testcase_info(self.testcase)
 
         self.testcase.validate_testcase.assert_called_once_with()
+        self.testcase.name.assert_called_once_with()
         mock_os.getenv.assert_has_calls([
-            call('OS_INSECURE'), call('DOVETAIL_HOME')])
+            call('OS_INSECURE'), call('DOVETAIL_HOME'), call('DEBUG'),
+            call('OS_CACERT')])
         self.assertEquals(expected, result)
 
     @patch('dovetail.test_runner.dt_utils')
@@ -422,10 +461,10 @@ class TestRunnerTesting(unittest.TestCase):
     def test_update_config_no_task_template(self, mock_const, mock_path,
                                             mock_config, mock_utils):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.FunctestRunner(self.testcase)
-        mock_path.join.side_effect = ['pod_file', 'config_file']
         mock_config.dovetail_config = {
-            'config_dir': 'one', 'pod_file': 'two'}
+            'config_dir': 'one', 'pod_file': 'two', 'result_dir': 'three'}
+        docker_runner = t_runner.FunctestRunner(self.testcase)
+        mock_path.join.side_effect = ['config_file', 'pod_file']
         mock_utils.read_yaml_file.return_value = 'pod_info'
         mock_utils.read_plain_file.return_value = None
         mock_const.CONF_PATH = 'conf_path'
@@ -435,10 +474,8 @@ class TestRunnerTesting(unittest.TestCase):
         self.patcher2.start()
 
         mock_path.join.assert_has_calls([
-            call('one', 'two'),
+            call('three', 'endpoint_info.json'),
             call('conf_path', docker_runner.config_file_name)])
-        mock_utils.read_yaml_file.assert_called_once_with(
-            'pod_file', docker_runner.logger)
         mock_utils.read_plain_file.assert_called_once_with(
             'config_file', docker_runner.logger)
         self.assertEquals(None, result)
@@ -454,10 +491,10 @@ class TestRunnerTesting(unittest.TestCase):
                                             mock_const, mock_path, mock_config,
                                             mock_utils, mock_load):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.FunctestRunner(self.testcase)
-        mock_path.join.side_effect = ['pod_file', 'config_file']
         mock_config.dovetail_config = {
-            'config_dir': 'one', 'pod_file': 'two'}
+            'config_dir': 'one', 'pod_file': 'two', 'result_dir': 'three'}
+        docker_runner = t_runner.FunctestRunner(self.testcase)
+        mock_path.join.side_effect = ['config_file', 'pod_file']
         mock_utils.read_yaml_file.return_value = {'key': 'value'}
         mock_utils.read_plain_file.return_value = True
         mock_const.CONF_PATH = 'conf_path'
@@ -470,15 +507,17 @@ class TestRunnerTesting(unittest.TestCase):
         self.patcher2.start()
 
         mock_path.join.assert_has_calls([
-            call('one', 'two'),
-            call('conf_path', docker_runner.config_file_name)])
+            call('three', 'endpoint_info.json'),
+            call('conf_path', docker_runner.config_file_name),
+            call('one', 'two')])
         mock_add_info.assert_called_once_with(self.testcase)
         mock_render.assert_called_once_with(True, config_item='item')
         mock_load.assert_called_once_with('full_task')
         self.assertEquals(
             {'config_dir': 'one',
              'pod_file': 'two',
-             'full_task_yaml': 'full_value'},
+             'full_task_yaml': 'full_value',
+             'result_dir': 'three'},
             result)
 
     @patch('dovetail.test_runner.yaml.safe_load')
@@ -492,10 +531,10 @@ class TestRunnerTesting(unittest.TestCase):
                                             mock_const, mock_path, mock_config,
                                             mock_utils, mock_load):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.FunctestRunner(self.testcase)
-        mock_path.join.side_effect = ['pod_file', 'config_file']
         mock_config.dovetail_config = {
-            'config_dir': 'one', 'pod_file': 'two'}
+            'config_dir': 'one', 'pod_file': 'two', 'result_dir': 'three'}
+        docker_runner = t_runner.FunctestRunner(self.testcase)
+        mock_path.join.side_effect = ['config_file', 'pod_file']
         mock_utils.read_yaml_file.return_value = False
         mock_utils.read_plain_file.return_value = True
         mock_const.CONF_PATH = 'conf_path'
@@ -508,15 +547,17 @@ class TestRunnerTesting(unittest.TestCase):
         self.patcher2.start()
 
         mock_path.join.assert_has_calls([
-            call('one', 'two'),
-            call('conf_path', docker_runner.config_file_name)])
+            call('three', 'endpoint_info.json'),
+            call('conf_path', docker_runner.config_file_name),
+            call('one', 'two')])
         mock_add_info.assert_called_once_with(self.testcase)
         mock_render.assert_called_once_with(True, config_item='item')
         mock_load.assert_called_once_with('full_task')
         self.assertEquals(
             {'config_dir': 'one',
              'pod_file': 'two',
-             'full_task_yaml': 'full_value'},
+             'full_task_yaml': 'full_value',
+             'result_dir': 'three'},
             result)
 
     @patch('dovetail.test_runner.yaml.safe_load')
@@ -530,10 +571,10 @@ class TestRunnerTesting(unittest.TestCase):
                                     mock_const, mock_path, mock_config,
                                     mock_utils, mock_load):
         t_runner.FunctestRunner.create_log()
-        docker_runner = t_runner.FunctestRunner(self.testcase)
-        mock_path.join.side_effect = ['pod_file', 'config_file']
         mock_config.dovetail_config = {
-            'config_dir': 'one', 'pod_file': 'two'}
+            'config_dir': 'one', 'pod_file': 'two', 'result_dir': 'three'}
+        docker_runner = t_runner.FunctestRunner(self.testcase)
+        mock_path.join.side_effect = ['config_file', 'pod_file']
         mock_utils.read_yaml_file.return_value = {
             'process_info': [
                 {'key': 'value'}, {'testcase_name': self.testcase_name}
@@ -549,8 +590,9 @@ class TestRunnerTesting(unittest.TestCase):
         self.patcher2.start()
 
         mock_path.join.assert_has_calls([
-            call('one', 'two'),
-            call('conf_path', docker_runner.config_file_name)])
+            call('three', 'endpoint_info.json'),
+            call('conf_path', docker_runner.config_file_name),
+            call('one', 'two')])
         mock_add_info.assert_called_once_with(
             self.testcase, {'testcase_name': self.testcase_name})
         docker_runner.logger.error.assert_called_once_with(
@@ -560,7 +602,8 @@ class TestRunnerTesting(unittest.TestCase):
         self.assertEquals(
             {'config_dir': 'one',
              'pod_file': 'two',
-             'full_task_yaml': 'full_value'},
+             'full_task_yaml': 'full_value',
+             'result_dir': 'three'},
             result)
 
     @patch('__builtin__.open')
@@ -650,3 +693,61 @@ class TestRunnerTesting(unittest.TestCase):
         result = docker_runner.create(self.testcase)
 
         self.assertEquals(None, result)
+
+    @patch('dovetail.test_runner.constants')
+    @patch('dovetail.test_runner.dt_utils')
+    @patch('dovetail.test_runner.os.path')
+    def test_k8s_update_config_no_task_template(self, mock_path, mock_utils,
+                                                mock_const):
+        t_runner.FunctestK8sRunner.create_log()
+        mock_utils.read_plain_file.return_value = None
+        mock_path.join.side_effect = ['config_file']
+        mock_const.CONF_PATH = 'conf_path'
+        docker_runner = t_runner.FunctestK8sRunner(self.testcase)
+
+        self.patcher2.stop()
+        result = docker_runner._update_config(self.testcase, update_pod=False)
+        self.patcher2.start()
+
+        mock_path.join.assert_has_calls([
+            call('conf_path', docker_runner.config_file_name)])
+        mock_utils.read_plain_file.assert_has_calls([
+            call('config_file', docker_runner.logger)])
+        self.assertEquals(None, result)
+
+    @patch('dovetail.test_runner.yaml.safe_load')
+    @patch('dovetail.test_runner.constants')
+    @patch('dovetail.test_runner.dt_utils')
+    @patch('dovetail.test_runner.os.path')
+    @patch('dovetail.test_runner.dt_cfg')
+    @patch.object(t_runner.DockerRunner, '_add_testcase_info')
+    @patch.object(t_runner.DockerRunner, '_render')
+    def test_k8s_update_config(self, mock_render, mock_add_info, mock_config,
+                               mock_path, mock_utils, mock_const, mock_load):
+        t_runner.FunctestK8sRunner.create_log()
+        mock_utils.read_plain_file.return_value = True
+        mock_path.join.side_effect = ['config_file', 'config_file']
+        mock_const.CONF_PATH = 'conf_path'
+        mock_add_info.return_value = {'config_item': 'item'}
+        mock_render.return_value = 'full_task'
+        mock_load.return_value = {'full_task_yaml': 'full_value'}
+        mock_config.dovetail_config = {
+            'config_dir': 'one', 'pod_file': 'two'}
+
+        docker_runner = t_runner.FunctestK8sRunner(self.testcase)
+        self.patcher2.stop()
+        result = docker_runner._update_config(self.testcase, update_pod=False)
+        self.patcher2.start()
+
+        mock_path.join.assert_has_calls([
+            call('conf_path', docker_runner.config_file_name)])
+        mock_utils.read_plain_file.assert_has_calls([
+            call('config_file', docker_runner.logger)])
+        mock_add_info.assert_has_calls([call(self.testcase)])
+        mock_render.assert_has_calls([call(True, config_item='item')])
+        mock_load.assert_has_calls([call('full_task')])
+        self.assertEquals(
+            {'config_dir': 'one',
+             'pod_file': 'two',
+             'full_task_yaml': 'full_value'},
+            result)
index 5dbb9cb..0d30320 100644 (file)
@@ -600,6 +600,11 @@ class TestcaseTesting(unittest.TestCase):
                           tcase.TestcaseFactory.create('unknown',
                                                        self.testcase_yaml))
 
+    def test_testfactory_k8s(self):
+        k8s_testcase = tcase.TestcaseFactory.create('functest-k8s',
+                                                    self.testcase_yaml)
+        self.assertEquals('functest-k8s', k8s_testcase.type)
+
     @patch('dovetail.testcase.dt_logger')
     def test_testsuite_create_log(self, mock_logger):
         getlogger_obj = Mock()
index 6027873..0f0e14f 100644 (file)
@@ -225,9 +225,10 @@ class DovetailUtilsTesting(unittest.TestCase):
         dovetail_utils.dt_cfg.dovetail_config = {'config_dir': file_path}
         mock_path.join.return_value = file_complete_name
         mock_path.isfile.return_value = False
+        logger = Mock()
 
         expected = ''
-        result = dovetail_utils.get_hosts_info(file_path)
+        result = dovetail_utils.get_hosts_info(logger)
 
         mock_path.join.assert_called_once_with(file_path, 'hosts.yaml')
         mock_path.isfile.assert_called_once_with(file_complete_name)
@@ -1316,3 +1317,41 @@ class DovetailUtilsTesting(unittest.TestCase):
         mock_getenv.assert_called_once_with('DEBUG')
         mock_bar.assert_called_once_with(1)
         mock_exit.assert_called_once_with(1)
+
+    @patch('os.path', autospec=True)
+    def test_get_openstack_info_no_openrc(self, mock_path):
+        logger = Mock()
+        config_dir = 'config_dir'
+        env_file = 'env_file'
+        dovetail_utils.dt_cfg.dovetail_config = {
+            'config_dir': config_dir, 'env_file': env_file}
+        mock_path.join.side_effect = ['openrc']
+        mock_path.isfile.return_value = False
+        dovetail_utils.get_openstack_info(logger)
+
+        mock_path.join.assert_called_once_with(config_dir, env_file)
+        mock_path.isfile.assert_called_once_with('openrc')
+        logger.error.assert_called_once_with('File openrc does not exist.')
+
+    @patch('dovetail.utils.dovetail_utils.source_env')
+    @patch('dovetail.utils.dovetail_utils.get_hosts_info')
+    @patch('dovetail.utils.dovetail_utils.get_openstack_endpoint')
+    @patch('dovetail.utils.dovetail_utils.get_hardware_info')
+    @patch('os.path', autospec=True)
+    def test_get_openstack_info(self, mock_path, mock_hardware, mock_endpoint,
+                                mock_host, mock_env):
+        logger = Mock()
+        config_dir = 'config_dir'
+        env_file = 'env_file'
+        dovetail_utils.dt_cfg.dovetail_config = {
+            'config_dir': config_dir, 'env_file': env_file}
+        mock_path.join.side_effect = ['openrc']
+        mock_path.isfile.return_value = True
+        dovetail_utils.get_openstack_info(logger)
+
+        mock_path.join.assert_called_once_with(config_dir, env_file)
+        mock_path.isfile.assert_called_once_with('openrc')
+        mock_env.assert_called_once()
+        mock_host.assert_called_once()
+        mock_endpoint.assert_called_once()
+        mock_hardware.assert_called_once()
index 50369e6..2e7b610 100644 (file)
@@ -43,7 +43,7 @@ def exec_log(verbose, logger, msg, level, flush=False):
 
 
 def exec_cmd(cmd, logger=None, exit_on_error=False, info=False,
-             exec_msg_on=True, err_msg="", verbose=True,
+             exec_msg_on=True, err_msg='', verbose=True,
              progress_bar=False):
     msg_err = ("The command '%s' failed." % cmd) if not err_msg else err_msg
     msg_exec = ("Executing command: '%s'" % cmd)
@@ -60,7 +60,7 @@ def exec_cmd(cmd, logger=None, exit_on_error=False, info=False,
     for line in iter(p.stdout.readline, b''):
         exec_log(verbose, logger, line.strip(), level, True)
         stdout += line
-        if progress_bar and (DEBUG is None or DEBUG.lower() != "true"):
+        if progress_bar and (DEBUG is None or DEBUG.lower() != 'true'):
             show_progress_bar(count)
             count += 1
     stdout = stdout.strip()
@@ -125,12 +125,12 @@ def source_env(env_file):
 
 
 def check_https_enabled(logger=None):
-    logger.debug("Checking if https enabled or not...")
+    logger.debug('Checking if https enabled or not...')
     os_auth_url = os.getenv('OS_AUTH_URL')
     if os_auth_url.startswith('https'):
-        logger.debug("https is enabled")
+        logger.debug('https is enabled')
         return True
-    logger.debug("https is not enabled")
+    logger.debug('https is not enabled')
     return False
 
 
@@ -140,10 +140,10 @@ def get_duration(start_date, stop_date, logger):
         datetime_start = datetime.strptime(start_date, fmt)
         datetime_stop = datetime.strptime(stop_date, fmt)
         delta = (datetime_stop - datetime_start).seconds
-        res = "%sm%ss" % (delta / 60, delta % 60)
+        res = '%sm%ss' % (delta / 60, delta % 60)
         return res
     except ValueError as e:
-        logger.exception("ValueError: {}".format(e))
+        logger.exception('ValueError: {}'.format(e))
         return None
 
 
@@ -162,12 +162,12 @@ def check_docker_version(logger=None):
     client_ret, client_ver = \
         exec_cmd("sudo docker version -f'{{.Client.Version}}'", logger=logger)
     if server_ret == 0:
-        logger.debug("docker server version: {}".format(server_ver))
+        logger.debug('docker server version: {}'.format(server_ver))
     if server_ret != 0 or (LooseVersion(server_ver) < LooseVersion('1.12.3')):
         logger.error("Don't support this Docker server version. "
                      "Docker server should be updated to at least 1.12.3.")
     if client_ret == 0:
-        logger.debug("docker client version: {}".format(client_ver))
+        logger.debug('docker client version: {}'.format(client_ver))
     if client_ret != 0 or (LooseVersion(client_ver) < LooseVersion('1.12.3')):
         logger.error("Don't support this Docker client version. "
                      "Docker client should be updated to at least 1.12.3.")
@@ -188,25 +188,25 @@ def add_hosts_info(ip, hostnames):
 def get_hardware_info(logger=None):
     pod_file = os.path.join(dt_cfg.dovetail_config['config_dir'],
                             dt_cfg.dovetail_config['pod_file'])
-    logger.info("Get hardware info of all nodes list in file {} ..."
+    logger.info('Get hardware info of all nodes list in file {} ...'
                 .format(pod_file))
     result_dir = dt_cfg.dovetail_config['result_dir']
     info_file_path = os.path.join(result_dir, 'sut_hardware_info')
     all_info_file = os.path.join(result_dir, 'all_hosts_info.json')
     inventory_file = os.path.join(result_dir, 'inventory.ini')
     if not get_inventory_file(pod_file, inventory_file, logger):
-        logger.error("Failed to get SUT hardware info.")
+        logger.error('Failed to get SUT hardware info.')
         return None
-    ret, msg = exec_cmd("cd {} && ansible all -m setup -i {} --tree {}"
+    ret, msg = exec_cmd('cd {} && ansible all -m setup -i {} --tree {}'
                         .format(constants.USERCONF_PATH, inventory_file,
                                 info_file_path), verbose=False)
     if not os.path.exists(info_file_path) or ret != 0:
-        logger.error("Failed to get SUT hardware info.")
+        logger.error('Failed to get SUT hardware info.')
         return None
     if not combine_files(info_file_path, all_info_file, logger):
-        logger.error("Failed to get all hardware info.")
+        logger.error('Failed to get all hardware info.')
         return None
-    logger.info("Hardware info of all nodes are stored in file {}."
+    logger.info('Hardware info of all nodes are stored in file {}.'
                 .format(all_info_file))
     return all_info_file
 
@@ -234,13 +234,13 @@ def get_inventory_file(pod_file, inventory_file, logger=None):
                                  .format(pod_file))
                     return False
                 out_f.write(host_info)
-        logger.debug("Ansible inventory file is {}.".format(inventory_file))
+        logger.debug('Ansible inventory file is {}.'.format(inventory_file))
         return True
     except KeyError as e:
-        logger.exception("KeyError {}.".format(e))
+        logger.exception('KeyError {}.'.format(e))
         return False
     except Exception:
-        logger.exception("Failed to read file {}.".format(pod_file))
+        logger.exception('Failed to read file {}.'.format(pod_file))
         return False
 
 
@@ -253,13 +253,13 @@ def combine_files(file_path, result_file, logger=None):
             with open(absolute_file_path, 'r') as f:
                 all_info[info_file] = json.load(f)
         except Exception:
-            logger.error("Failed to read file {}.".format(absolute_file_path))
+            logger.error('Failed to read file {}.'.format(absolute_file_path))
             return None
     try:
         with open(result_file, 'w') as f:
             f.write(json.dumps(all_info))
     except Exception:
-        logger.exception("Failed to write file {}.".format(result_file))
+        logger.exception('Failed to write file {}.'.format(result_file))
         return None
     return result_file
 
@@ -267,13 +267,13 @@ def combine_files(file_path, result_file, logger=None):
 def get_openstack_endpoint(logger=None):
     https_enabled = check_https_enabled(logger)
     insecure = os.getenv('OS_INSECURE')
-    if https_enabled and insecure and insecure.lower() == "true":
+    if https_enabled and insecure and insecure.lower() == 'true':
         os_utils = OS_Utils(verify=False)
     else:
         os_utils = OS_Utils()
     res_endpoints, msg_endpoints = os_utils.search_endpoints()
     if not res_endpoints:
-        logger.error("Failed to list endpoints. Exception message, {}"
+        logger.error('Failed to list endpoints. Exception message, {}'
                      .format(msg_endpoints))
         return None
     endpoints_info = []
@@ -282,7 +282,7 @@ def get_openstack_endpoint(logger=None):
         res_services, msg_services = os_utils.search_services(
             service_id=item['service_id'])
         if not res_services:
-            logger.error("Failed to list services. Exception message, {}"
+            logger.error('Failed to list services. Exception message, {}'
                          .format(msg_services))
             return None
         endpoint['Service Type'] = msg_services[0]['service_type']
@@ -294,41 +294,43 @@ def get_openstack_endpoint(logger=None):
     try:
         with open(result_file, 'w') as f:
             json.dump(endpoints_info, f)
-            logger.debug("Record all endpoint info into file {}."
+            logger.debug('Record all endpoint info into file {}.'
                          .format(result_file))
             return endpoints_info
     except Exception:
-        logger.exception("Failed to write endpoint info into file.")
+        logger.exception('Failed to write endpoint info into file.')
         return None
 
 
 def check_cacert_file(cacert, logger=None):
     if not os.path.isfile(cacert):
-        logger.error("OS_CACERT is {}, but the file does not exist."
+        logger.error('OS_CACERT is {}, but the file does not exist.'
                      .format(cacert))
         return False
     if not dt_cfg.dovetail_config['config_dir'] == os.path.dirname(cacert):
-        logger.error("Credential file must be put under {}, "
-                     "which can be mounted into other container."
+        logger.error('Credential file must be put under {}, '
+                     'which can be mounted into other container.'
                      .format(dt_cfg.dovetail_config['config_dir']))
         return False
     return True
 
 
 def get_hosts_info(logger=None):
-    hosts_config = ""
+    hosts_config = ''
     hosts_config_file = os.path.join(dt_cfg.dovetail_config['config_dir'],
                                      'hosts.yaml')
     if not os.path.isfile(hosts_config_file):
+        logger.warn('There is no hosts file {}. This may cause some issues '
+                    'with domain name resolution.'.format(hosts_config_file))
         return hosts_config
     with open(hosts_config_file) as f:
         hosts_yaml = yaml.safe_load(f)
         if not hosts_yaml:
-            logger.debug("File {} is empty.".format(hosts_config_file))
+            logger.debug('File {} is empty.'.format(hosts_config_file))
             return hosts_config
         hosts_info = hosts_yaml.get('hosts_info', None)
         if not hosts_info:
-            logger.error("There is no key hosts_info in file {}"
+            logger.error('There is no key hosts_info in file {}'
                          .format(hosts_config_file))
             return hosts_config
         for ip, hostnames in hosts_info.iteritems():
@@ -353,7 +355,7 @@ def read_yaml_file(file_path, logger=None):
             content = yaml.safe_load(f)
             return content
     except Exception as e:
-        logger.exception("Failed to read file {}, exception: {}"
+        logger.exception('Failed to read file {}, exception: {}'
                          .format(file_path, e))
         return None
 
@@ -367,7 +369,7 @@ def read_plain_file(file_path, logger=None):
             content = f.read()
             return content
     except Exception as e:
-        logger.exception("Failed to read file {}, exception: {}"
+        logger.exception('Failed to read file {}, exception: {}'
                          .format(file_path, e))
         return None
 
@@ -380,8 +382,26 @@ def get_value_from_dict(key_path, input_dict):
     """
     if not isinstance(key_path, str) or not isinstance(input_dict, dict):
         return None
-    for key in key_path.split("."):
+    for key in key_path.split('.'):
         input_dict = input_dict.get(key)
         if not input_dict:
             return None
     return input_dict
+
+
+def get_openstack_info(logger):
+    """
+    When the sut is an OpenStack deployment, its software and hardware info
+    are needed.
+    Software info is the endpoint list.
+    Hardware info is every node's cpu, disk ...
+    """
+    openrc = os.path.join(dt_cfg.dovetail_config['config_dir'],
+                          dt_cfg.dovetail_config['env_file'])
+    if not os.path.isfile(openrc):
+        logger.error('File {} does not exist.'.format(openrc))
+        return
+    source_env(openrc)
+    get_hosts_info(logger)
+    get_openstack_endpoint(logger)
+    get_hardware_info(logger)
index ff5908c..639a030 100644 (file)
@@ -5,3 +5,5 @@ proposed_tests:
   testcases_list:
     mandatory:
     optional:
+      - functest.k8s.conformance
+      - functest.k8s.smoke
index c44047f..5866aa3 100644 (file)
@@ -4,29 +4,45 @@
 {% set testcase = testcase or '' %}
 {% set deploy_scenario = deploy_scenario or 'unknown' %}
 {% set dovetail_home = dovetail_home or '' %}
+{% set debug = debug or 'false' %}
+{% set build_tag = build_tag or '' %}
+{% set cacert_volume = '' %}
+{% if cacert %}
+    {% set cacert_volume = ' -v ' + cacert + ':' + cacert %}
+{% endif %}
+{% set openrc_file = '/tmp/admin_rc.sh' %}
+{% set result_dir = '/home/opnfv/bottlenecks/results' %}
+{% set config_dir = '/home/opnfv/userconfig' %}
+{% set image_file = '/tmp/yardstick.img' %}
 
 bottlenecks:
   image_name: opnfv/bottlenecks
   docker_tag: latest
   opts: '-id --privileged=true'
-  envs: '-e DEPLOY_SCENARIO={{deploy_scenario}} -e Yardstick_TAG=stable -e OUTPUT_FILE={{testcase}}.out'
+  envs: '-e DEPLOY_SCENARIO={{deploy_scenario}} -e Yardstick_TAG=stable
+         -e OUTPUT_FILE={{testcase}}.out -e CI_DEBUG={{debug}}
+         -e BUILD_TAG={{build_tag}}-{{testcase}}'
   volumes:
     - '-v /var/run/docker.sock:/var/run/docker.sock'
     - '-v {{dovetail_home}}/results/bottlenecks:/tmp'
+    - '-v {{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
+    - {{cacert_volume}}
+    - '-v {{dovetail_home}}:{{config_dir}}'
+    - '-v {{dovetail_home}}/results:{{result_dir}}'
   config:
-    dir: '/home/opnfv/userconfig'
+    dir: {{config_dir}}
   pre_condition:
-    - 'cp /home/opnfv/userconfig/images/ubuntu-16.04-server-cloudimg-amd64-disk1.img /tmp/yardstick.img'
+    - 'cp {{config_dir}}/images/ubuntu-16.04-server-cloudimg-amd64-disk1.img {{image_file}}'
   cmds:
     - 'python /home/opnfv/bottlenecks/testsuites/run_testsuite.py testcase {{validate_testcase}} False'
   post_condition:
-    - 'mkdir -p /home/opnfv/bottlenecks/results'
-    - 'cp /tmp/bottlenecks.log /home/opnfv/bottlenecks/results'
-    - 'cp /tmp/bottlenecks.stress.ping.out /home/opnfv/bottlenecks/results'
-    - 'rm /tmp/yardstick.img'
+    - 'mkdir -p {{result_dir}}'
+    - 'cp /tmp/bottlenecks.log {{result_dir}}'
+    - 'cp /tmp/bottlenecks.stress.ping.out {{result_dir}}'
+    - 'rm {{image_file}}'
   result:
-    dir: '/home/opnfv/bottlenecks/results'
-  openrc: '/tmp/admin_rc.sh'
+    dir: {{result_dir}}
+  openrc: {{openrc_file}}
   extra_container:
     - 'Bottlenecks-Yardstick'
     - 'Bottlenecks-ELK'
index ca36fe5..ed6433b 100644 (file)
@@ -31,6 +31,7 @@ testarea_supported:
   - tempest
   - vnf
   - vping
+  - k8s
 
 # used for testcase cmd template in jinja2 format
 # we have two variables available now
diff --git a/etc/conf/functest-k8s_config.yml b/etc/conf/functest-k8s_config.yml
new file mode 100644 (file)
index 0000000..e717ef9
--- /dev/null
@@ -0,0 +1,31 @@
+---
+
+{% set validate_testcase = validate_testcase or '' %}
+{% set testcase = testcase or '' %}
+{% set dovetail_home = dovetail_home or '' %}
+{% set debug = debug or 'false' %}
+{% set build_tag = build_tag or '' %}
+{% set openrc_file = '/home/opnfv/functest/conf/env_file' %}
+{% set kube_file = '/root/.kube/config' %}
+{% set result_dir = '/home/opnfv/functest/results' %}
+
+functest-k8s:
+  image_name: opnfv/functest-kubernetes-healthcheck
+  docker_tag: gambia
+  opts: '-id'
+  envs: '-e INSTALLER_TYPE=unknown -e DEPLOY_SCENARIO=k8-deploy -e NODE_NAME=unknown
+         -e TEST_DB_URL=file:///home/opnfv/functest/results/functest_results.txt
+         -e CI_DEBUG={{debug}} -e BUILD_TAG={{build_tag}}-{{testcase}}'
+  volumes:
+    - '-v {{dovetail_home}}/pre_config/k8.creds:{{openrc_file}}'
+    - '-v {{dovetail_home}}/pre_config/admin.conf:{{kube_file}}'
+    - '-v {{dovetail_home}}/results/:{{result_dir}}'
+  pre_condition:
+    - 'echo test for precondition in functest'
+  cmds:
+    - 'run_tests -t {{validate_testcase}} -r'
+  post_condition:
+    - 'echo test for postcondition in functest'
+  result:
+    dir: {{result_dir}}
+  openrc: {{openrc_file}}
index 631e832..451b167 100644 (file)
@@ -1,22 +1,40 @@
 ---
 
 {% set validate_testcase = validate_testcase or '' %}
+{% set testcase = testcase or '' %}
 {% set deploy_scenario = deploy_scenario or 'unknown' %}
 {% set os_insecure = os_insecure or 'False' %}
 {% set os_verify = '' %}
 {% if os_insecure == 'True' %}
     {% set os_verify = ' -e OS_VERIFY= ' %}
 {% endif %}
+{% set dovetail_home = dovetail_home or '' %}
+{% set debug = debug or 'false' %}
+{% set build_tag = build_tag or '' %}
+{% set cacert_volume = '' %}
+{% if cacert %}
+    {% set cacert_volume = ' -v ' + cacert + ':' + cacert %}
+{% endif %}
+{% set openrc_file = '/home/opnfv/functest/conf/env_file' %}
+{% set result_dir = '/home/opnfv/functest/results' %}
+{% set config_dir = '/home/opnfv/userconfig' %}
+{% set images_dir = '/home/opnfv/functest/images' %}
 
 functest:
   image_name: opnfv/functest-smoke
   docker_tag: gambia
   opts: '-id --privileged=true'
   envs: '{{os_verify}} -e INSTALLER_TYPE=unknown -e DEPLOY_SCENARIO={{deploy_scenario}} -e NODE_NAME=unknown
-         -e TEST_DB_URL=file:///home/opnfv/functest/results/functest_results.txt'
+         -e TEST_DB_URL=file://{{result_dir}}/functest_results.txt
+         -e CI_DEBUG={{debug}} -e BUILD_TAG={{build_tag}}-{{testcase}}'
+  volumes:
+    - '-v {{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
+    - {{cacert_volume}}
+    - '-v {{dovetail_home}}:{{config_dir}}'
+    - '-v {{dovetail_home}}/results:{{result_dir}}'
+    - '-v {{dovetail_home}}/images:{{images_dir}}'
   config:
-    dir: '/home/opnfv/userconfig'
-    images: '/home/opnfv/functest/images'
+    dir: {{config_dir}}
   pre_condition:
     - 'echo test for precondition in functest'
   cmds:
@@ -24,5 +42,5 @@ functest:
   post_condition:
     - 'echo test for postcondition in functest'
   result:
-    dir: '/home/opnfv/functest/results'
-  openrc: '/home/opnfv/functest/conf/env_file'
+    dir: {{result_dir}}
+  openrc: {{openrc_file}}
index 1043665..764ca94 100644 (file)
@@ -9,25 +9,41 @@
 {% if os_insecure == 'True' %}
     {% set os_verify = ' -e OS_VERIFY= ' %}
 {% endif %}
+{% set dovetail_home = dovetail_home or '' %}
+{% set debug = debug or 'false' %}
+{% set build_tag = build_tag or '' %}
+{% set cacert_volume = '' %}
+{% if cacert %}
+    {% set cacert_volume = ' -v ' + cacert + ':' + cacert %}
+{% endif %}
+{% set openrc_file = '/etc/yardstick/openstack.creds' %}
+{% set result_dir = '/tmp/yardstick' %}
+{% set config_dir = '/home/opnfv/userconfig' %}
 
 yardstick:
   image_name: opnfv/yardstick
   docker_tag: latest
   opts: '-id --privileged=true'
-  envs: "{{os_verify}} -e YARDSTICK_BRANCH=fraser"
+  envs: "{{os_verify}} -e YARDSTICK_BRANCH=fraser -e CI_DEBUG={{debug}}
+         -e BUILD_TAG={{build_tag}}-{{testcase}}"
+  volumes:
+    - '-v {{dovetail_home}}/pre_config/env_config.sh:{{openrc_file}}'
+    - {{cacert_volume}}
+    - '-v {{dovetail_home}}:{{config_dir}}'
+    - '-v {{dovetail_home}}/results:{{result_dir}}'
   config:
-    dir: '/home/opnfv/userconfig'
+    dir: {{config_dir}}
   pre_condition:
     - 'echo this is pre_condition'
   cmds:
-    - "cd /home/opnfv/repos/yardstick && source /etc/yardstick/openstack.creds &&
+    - "cd /home/opnfv/repos/yardstick && source {{openrc_file}} &&
          yardstick task start tests/opnfv/test_cases/{{validate_testcase}}.yaml
-         --output-file /tmp/yardstick/{{testcase}}.out
-         --task-args '{'file': '/home/opnfv/userconfig/pre_config/pod.yaml',
+         --output-file {{result_dir}}/{{testcase}}.out
+         --task-args '{'file': '{{config_dir}}/pre_config/pod.yaml',
                        'attack_host': {{attack_host}},
                        'attack_process': {{attack_process}}}'"
   post_condition:
     - 'echo this is post_condition'
   result:
-    dir: '/tmp/yardstick'
-  openrc: '/etc/yardstick/openstack.creds'
+    dir: {{result_dir}}
+  openrc: {{openrc_file}}
diff --git a/etc/testcase/functest.k8s.conformance.yml b/etc/testcase/functest.k8s.conformance.yml
new file mode 100644 (file)
index 0000000..db85342
--- /dev/null
@@ -0,0 +1,15 @@
+---
+functest.k8s.conformance:
+  name: functest.k8s.conformance
+  objective: Validate the deployed k8s cluster is conformance.
+  validate:
+    type: functest-k8s
+    testcase: k8s_conformance
+    image_name: opnfv/functest-kubernetes-smoke
+  report:
+    source_archive_files:
+      - functest-kubernetes.log
+    dest_archive_files:
+      - k8s_logs/functest.k8s.conformance.log
+    check_results_file: 'functest_results.txt'
+    sub_testcase_list:
diff --git a/etc/testcase/functest.k8s.smoke.yml b/etc/testcase/functest.k8s.smoke.yml
new file mode 100644 (file)
index 0000000..cedc022
--- /dev/null
@@ -0,0 +1,15 @@
+---
+functest.k8s.smoke:
+  name: functest.k8s.smoke
+  objective: Validate the deployed k8s cluster is accessible.
+  validate:
+    type: functest-k8s
+    testcase: k8s_smoke
+    image_name: opnfv/functest-kubernetes-healthcheck
+  report:
+    source_archive_files:
+      - functest-kubernetes.log
+    dest_archive_files:
+      - k8s_logs/functest.k8s.smoke.log
+    check_results_file: 'functest_results.txt'
+    sub_testcase_list: