Support to specify docker image for each test case 69/54369/8
authorxudan <xudan16@huawei.com>
Fri, 23 Mar 2018 04:03:58 +0000 (00:03 -0400)
committerGeorg Kunz <georg.kunz@ericsson.com>
Tue, 10 Apr 2018 10:21:02 +0000 (10:21 +0000)
1. Currently each type of test cases will use one docker image.
2. For example,
   Functest test cases use opnfv/functest-restapi:euphrates
   Yardstick uses opnfv/yardstick:opnfv-5.1.0
3. It needs to support to specify the docker image for each test case.
4. For example,
   vping test cases use opnfv/functest-smoke:euphrates
   sdnvpn uses opnfv/functest-features:euphrates
5. The benefit of this is that these docker images are well verified
   by Functest CI and from Functest plan, they may not support
   functest-restapi docker image in its future release.

JIRA: DOVETAIL-638

Change-Id: I8a30eea2233aeff809af2e241b6c939194397832
Signed-off-by: xudan <xudan16@huawei.com>
dovetail/container.py
dovetail/test_runner.py
dovetail/utils/dovetail_utils.py
etc/conf/functest_config.yml
etc/testcase/sdnvpn.tc000.yml
etc/testcase/sdnvpn.tc001.yml
etc/testcase/sdnvpn.tc002.yml
etc/testcase/sdnvpn.tc003.yml
etc/testcase/sdnvpn.tc004.yml
etc/testcase/sdnvpn.tc008.yml
etc/testcase/vnf.tc001.yml

index 4feed80..b77f491 100644 (file)
@@ -17,8 +17,6 @@ from utils.dovetail_config import DovetailConfig as dt_cfg
 class Container(object):
 
     container_list = {}
-    has_pull_latest_image = {'yardstick': False, 'functest': False,
-                             'bottlenecks': False, 'vnftest': False}
 
     logger = None
 
@@ -37,14 +35,23 @@ class Container(object):
         return cls.container_list[type]
 
     @classmethod
-    def get_docker_image(cls, type):
-        try:
-            return '%s:%s' % (dt_cfg.dovetail_config[type]['image_name'],
-                              dt_cfg.dovetail_config[type]['docker_tag'])
-        except KeyError as e:
-            cls.logger.exception(
-                'There is no key {} in {} config file.'.format(e, type))
-            return None
+    def _get_config(cls, field, project_cfg, testcase_cfg):
+        value = dt_utils.get_value_from_dict(field, testcase_cfg)
+        if not value:
+            value = dt_utils.get_value_from_dict(field, project_cfg)
+            if not value:
+                cls.logger.error("Couldn't find key {}.".format(field))
+                return None
+        return value
+
+    @classmethod
+    def get_docker_image(cls, testcase):
+        project_cfg = dt_cfg.dovetail_config[testcase.validate_type()]
+        testcase_cfg = testcase.testcase['validate']
+
+        name = cls._get_config('image_name', project_cfg, testcase_cfg)
+        tag = cls._get_config('docker_tag', project_cfg, testcase_cfg)
+        return "{}:{}".format(name, tag) if name and tag else None
 
     # get the openrc_volume for creating the container
     @classmethod
@@ -132,9 +139,9 @@ class Container(object):
         return "%s %s" % (log_vol, key_vol)
 
     @classmethod
-    def create(cls, type, testcase_name):
+    def create(cls, type, testcase_name, docker_image):
         dovetail_config = dt_cfg.dovetail_config
-        docker_image = cls.get_docker_image(type)
+        opts = dovetail_config[type]['opts']
 
         # credentials file openrc.sh is neccessary
         openrc = cls.openrc_volume(type)
@@ -255,18 +262,12 @@ class Container(object):
         return True
 
     @classmethod
-    def pull_image(cls, validate_type):
-        docker_image = cls.get_docker_image(validate_type)
+    def pull_image(cls, docker_image):
         if not docker_image:
             return None
-        if cls.has_pull_latest_image[validate_type] is True:
-            cls.logger.debug(
-                '{} is already the latest one.'.format(docker_image))
-            return docker_image
         old_image_id = cls.get_image_id(docker_image)
         if not cls.pull_image_only(docker_image):
             return None
-        cls.has_pull_latest_image[validate_type] = True
         new_image_id = cls.get_image_id(docker_image)
         if not new_image_id:
             cls.logger.error(
@@ -281,12 +282,6 @@ class Container(object):
             cls.remove_image(old_image_id)
         return docker_image
 
-    @classmethod
-    def check_image_exist(cls, validate_type):
-        docker_image = cls.get_docker_image(validate_type)
-        image_id = cls.get_image_id(docker_image)
-        return image_id
-
     @classmethod
     def check_container_exist(cls, container_name):
         cmd = ('sudo docker ps -aq -f name={}'.format(container_name))
index 26b85a1..b059047 100644 (file)
@@ -51,14 +51,15 @@ class DockerRunner(object):
         return dest_path
 
     def run(self):
+        docker_image = Container.get_docker_image(self.testcase)
         if dt_cfg.dovetail_config['offline']:
-            exist = Container.check_image_exist(self.testcase.validate_type())
+            exist = Container.get_image_id(docker_image)
             if not exist:
                 self.logger.error("{} image doesn't exist, can't run offline."
                                   .format(self.testcase.validate_type()))
                 return
         else:
-            if not Container.pull_image(self.testcase.validate_type()):
+            if not Container.pull_image(docker_image):
                 self.logger.error("Failed to pull the image.")
                 return
         # for sdnvpn, there is a need to download needed images to config_dir
@@ -71,7 +72,7 @@ class DockerRunner(object):
                 self.logger.error('Image {} not found.'.format(img_name))
                 return
         container_id = Container.create(self.testcase.validate_type(),
-                                        self.testcase.name())
+                                        self.testcase.name(), docker_image)
         if not container_id:
             self.logger.error('Failed to create container.')
             return
index dc7dbaf..4a3d852 100644 (file)
@@ -408,3 +408,20 @@ def read_plain_file(file_path, logger=None):
         logger.exception("Failed to read file {}, exception: {}"
                          .format(file_path, e))
         return None
+
+
+def get_value_from_dict(key_path, input_dict):
+    """
+    Returns the value of a key in input_dict
+    key_path must be given in string format with dots
+    Example: result.dir
+    """
+    if not isinstance(key_path, str):
+        return None
+    for key in key_path.split("."):
+        if not isinstance(input_dict, dict):
+            return None
+        input_dict = input_dict.get(key)
+        if not input_dict:
+            return None
+    return input_dict
index e5f21a9..f76bac4 100644 (file)
@@ -1,6 +1,6 @@
 ---
 functest:
-  image_name: opnfv/functest-restapi
+  image_name: opnfv/functest-smoke
   docker_tag: euphrates
   opts: '-id --privileged=true'
   envs: '-e INSTALLER_TYPE=unknown -e DEPLOY_SCENARIO=unknown -e NODE_NAME=unknown
index 8a4d6bf..4b1acf2 100644 (file)
@@ -5,6 +5,7 @@ dovetail.sdnvpn.tc000:
   validate:
     type: functest
     testcase: bgpvpn
+    image_name: opnfv/functest-features
     pre_condition:
       - "sed -i 's/networking_bgpvpn_tempest/networking_bgpvpn_tempest-r networking_bgpvpn_tempest.tests.api.test_bgpvpn.BgpvpnTest*/' /usr/lib/python2.7/site-packages/sdnvpn/test/functest/tempest.py"
       - 'cp /home/opnfv/userconfig/pre_config/testcases.yaml /usr/lib/python2.7/site-packages/functest/ci/testcases.yaml'
index 698b0d2..a5f9fd0 100644 (file)
@@ -5,6 +5,7 @@ dovetail.sdnvpn.tc001:
   validate:
     type: functest
     testcase: bgpvpn
+    image_name: opnfv/functest-features
     pre_copy:
       exist_src_file: sdnvpn_config_testcase1.yaml
       dest_path: /usr/lib/python2.7/site-packages/sdnvpn/test/functest/config.yaml
index 4823ee5..06f4d65 100644 (file)
@@ -5,6 +5,7 @@ dovetail.sdnvpn.tc002:
   validate:
     type: functest
     testcase: bgpvpn
+    image_name: opnfv/functest-features
     pre_copy:
       exist_src_file: sdnvpn_config_testcase2.yaml
       dest_path: /usr/lib/python2.7/site-packages/sdnvpn/test/functest/config.yaml
index fbf13ca..e609390 100644 (file)
@@ -5,6 +5,7 @@ dovetail.sdnvpn.tc003:
   validate:
     type: functest
     testcase: bgpvpn
+    image_name: opnfv/functest-features
     pre_copy:
       exist_src_file: sdnvpn_config_testcase3.yaml
       dest_path: /usr/lib/python2.7/site-packages/sdnvpn/test/functest/config.yaml
index 5f44f12..f3628b8 100644 (file)
@@ -5,6 +5,7 @@ dovetail.sdnvpn.tc004:
   validate:
     type: functest
     testcase: bgpvpn
+    image_name: opnfv/functest-features
     pre_copy:
       exist_src_file: sdnvpn_config_testcase4.yaml
       dest_path: /usr/lib/python2.7/site-packages/sdnvpn/test/functest/config.yaml
index d818bf1..7119022 100644 (file)
@@ -5,6 +5,7 @@ dovetail.sdnvpn.tc008:
   validate:
     type: functest
     testcase: bgpvpn
+    image_name: opnfv/functest-features
     pre_copy:
       exist_src_file: sdnvpn_config_testcase8.yaml
       dest_path: /usr/lib/python2.7/site-packages/sdnvpn/test/functest/config.yaml
index d2a8d70..5fe02fb 100644 (file)
@@ -5,5 +5,6 @@ dovetail.vnf.tc001:
   validate:
     type: functest
     testcase: cloudify_ims
+    image_name: opnfv/functest-vnf
   report:
     sub_testcase_list: