Calculate checksum for input VNF 67/67067/11
authorStamatis Katsaounis <mokats@intracom-telecom.com>
Tue, 19 Feb 2019 10:38:10 +0000 (12:38 +0200)
committerDan Xu <xudan16@huawei.com>
Wed, 13 Mar 2019 10:48:45 +0000 (10:48 +0000)
This patch adds checksum information inside ONAP related test case run
results. The checksum is produced by the VNF input which can either be
a CSAR file or an archive of Heat templates.

Change-Id: I0ed58bdc9cc4031da08fd2ac220ef294520ef447
Signed-off-by: Stamatis Katsaounis <mokats@intracom-telecom.com>
docs/testing/user/userguide/vnf_test_guide.rst
dovetail/report.py
dovetail/test_runner.py
dovetail/tests/unit/test_report.py
dovetail/tests/unit/test_test_runner.py
etc/conf/onap-vvp_config.yml
etc/userconfig/env_config.sh.onap.sample

index 72b5fa4..63ed04b 100644 (file)
@@ -82,11 +82,13 @@ all Dovetail related config files and results files:
 
 For example, here we set Dovetail home directory to be ``${HOME}/dovetail``.
 Afterwards, we will create a directory named ``pre_config`` inside this directory
-to store all Dovetail config related files:
+to store all Dovetail config related files and a directory named ``results``, where
+test results are going to be saved:
 
 .. code-block:: bash
 
    $ mkdir -p ${DOVETAIL_HOME}/pre_config
+   $ mkdir -p ${DOVETAIL_HOME}/results
 
 
 There should be a file `env_config.sh` inside this directory to provide some info.
@@ -99,20 +101,17 @@ For TOSCA based VNFs, it should look like this:
    export CSAR_FILE="/path/to/VNF/copied/in/container/name.csar"
 
 
-For HEAT based VNFs, it should create `vnf_dir` under `pre_config` and copy all
-HEAT template VNF packages to `vnf_dir`.
-
-.. code-block:: bash
-
-   $ mkdir -p ${DOVETAIL_HOME}/pre_config/vnf_dir
-
+For HEAT based VNFs, the user should copy an archive of the HEAT template VNF
+packages to `pre_config`. The archive must be in gzip tar (tar.gz) format.
+In addition, the archive must contain only a directory with the same name
+(e.g. vnf_a.tar.gz must only include a directory named vnf_a).
 
 Configuration file `env_config.sh` should look like this for HEAT based VNFs:
 
 .. code-block:: bash
 
    $ cat ${DOVETAIL_HOME}/pre_config/env_config.sh
-   export VNF_DIRECTORY="/path/to/pre_config/vnf_dir"
+   export VNF_ARCHIVE_NAME="vnf_archive_name"
 
 
 Use the command below to create a Dovetail container and get access to its shell:
index 86f941d..556fc76 100644 (file)
@@ -12,6 +12,7 @@
 from __future__ import division
 
 import collections
+import hashlib
 import json
 import re
 import os
@@ -70,6 +71,25 @@ class Report(object):
         if checker is not None:
             checker.check(testcase, db_result)
 
+    @staticmethod
+    def get_checksum(vnf_type):
+        if vnf_type == 'tosca':
+            path = os.path.join(dt_cfg.dovetail_config['config_dir'],
+                                os.getenv('CSAR_FILE'))
+        elif vnf_type == 'heat':
+            path = os.path.join(
+                dt_cfg.dovetail_config['config_dir'],
+                os.getenv('VNF_ARCHIVE_NAME') + '.tar.gz')
+
+        checksum = hashlib.sha256()
+
+        if os.path.isfile(path):
+            with open(path, 'rb') as f:
+                for chunk in iter(lambda: f.read(4096), b''):
+                    checksum.update(chunk)
+
+        return checksum.hexdigest()
+
     def generate_json(self, testcase_list, duration):
         report_obj = {}
         # egeokun: using a hardcoded string instead of pbr version for
@@ -83,6 +103,7 @@ class Report(object):
         vnf_type = dt_cfg.dovetail_config.get('vnf_type')
         if vnf_type:
             report_obj['vnf_type'] = vnf_type
+            report_obj['vnf_checksum'] = self.get_checksum(vnf_type)
 
         report_obj['testcases_list'] = []
         if not testcase_list:
index 00cc99e..44233e1 100644 (file)
@@ -132,7 +132,7 @@ class DockerRunner(Runner):
         config_item['cacert'] = os.getenv('OS_CACERT')
         config_item['host_url'] = os.getenv('HOST_URL')
         config_item['csar_file'] = os.getenv('CSAR_FILE')
-        config_item['heat_templates_dir'] = os.getenv('VNF_DIRECTORY')
+        config_item['heat_templates_archive'] = os.getenv('VNF_ARCHIVE_NAME')
         return config_item
 
     def _update_config(self, testcase, update_pod=True):
index be56e15..e44c6ac 100644 (file)
@@ -225,7 +225,9 @@ class ReportTesting(unittest.TestCase):
 
     @patch('dovetail.report.datetime.datetime')
     @patch('dovetail.report.dt_cfg')
-    def test_generate_json_no_list(self, mock_config, mock_datetime):
+    @patch.object(dt_report.Report, 'get_checksum')
+    def test_generate_json_no_list(self, mock_checksum, mock_config,
+                                   mock_datetime):
         logger_obj = Mock()
         report = dt_report.Report()
         report.logger = logger_obj
@@ -238,12 +240,14 @@ class ReportTesting(unittest.TestCase):
         utc_obj = Mock()
         utc_obj.strftime.return_value = '2018-01-13 13:13:13 UTC'
         mock_datetime.utcnow.return_value = utc_obj
+        mock_checksum.return_value = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
 
         result = report.generate_json([], duration)
         expected = {
             'version': '2018.09',
             'build_tag': 'build_tag',
             'vnf_type': 'tosca',
+            'vnf_checksum': 'da39a3ee5e6b4b0d3255bfef95601890afd80709',
             'test_date': '2018-01-13 13:13:13 UTC',
             'duration': duration,
             'testcases_list': []
@@ -1466,3 +1470,44 @@ class ReportTesting(unittest.TestCase):
         dt_report.OnapVvpChecker.check(testcase_obj, result)
 
         testcase_obj.passed.assert_called_once_with('PASS')
+
+    @patch('dovetail.report.dt_cfg')
+    @patch('dovetail.report.os.path')
+    @patch('__builtin__.open')
+    @patch('dovetail.report.os.getenv')
+    def test_get_checksum_tosca(self, mock_env, mock_open, mock_path,
+                                mock_config):
+        mock_config.dovetail_config = {
+            'config_dir': 'config_dir'
+        }
+        mock_env.return_value = 'csar_file'
+        file_obj = Mock()
+        file_obj.read.return_value = 'info'
+        file_obj.__exit__ = Mock()
+        file_obj.__enter__ = Mock()
+        mock_open.return_value = file_obj
+        mock_path.isdir.return_value = False
+        mock_path.isfile.return_value = True
+
+        dt_report.Report.get_checksum('tosca')
+
+    @patch('dovetail.report.dt_cfg')
+    @patch('dovetail.report.os.path')
+    @patch('dovetail.report.os.walk')
+    @patch('__builtin__.open')
+    @patch('dovetail.report.os.getenv')
+    def test_get_checksum_heat(self, mock_env, mock_open, mock_walk, mock_path,
+                               mock_config):
+        mock_config.dovetail_config = {
+            'config_dir': 'config_dir'
+        }
+        mock_env.return_value = 'heat_templates_archive'
+        file_obj = Mock()
+        file_obj.read.return_value = 'info'
+        file_obj.__exit__ = Mock()
+        file_obj.__enter__ = Mock()
+        mock_open.return_value = file_obj
+        mock_path.isdir.return_value = True
+        mock_walk.return_value = [('root', ['dir'], ['file'])]
+
+        dt_report.Report.get_checksum('heat')
index 345dfd6..a40e3cb 100644 (file)
@@ -324,7 +324,7 @@ class TestRunnerTesting(unittest.TestCase):
     def test_add_testcase_info(self, mock_os, mock_config):
         mock_os.getenv.side_effect = ['os_insecure', 'dovetail_home', 'debug',
                                       'os_cacert', 'host_url', 'csar_file',
-                                      'heat_templates_dir']
+                                      'heat_templates_archive']
         mock_os.environ = {'DEPLOY_SCENARIO': 'deploy_scenario'}
         mock_config.dovetail_config = {'build_tag': 'build_tag'}
 
@@ -335,7 +335,7 @@ class TestRunnerTesting(unittest.TestCase):
             'dovetail_home': 'dovetail_home', 'debug': 'debug',
             'build_tag': 'build_tag', 'cacert': 'os_cacert',
             'host_url': 'host_url', 'csar_file': 'csar_file',
-            'heat_templates_dir': 'heat_templates_dir'
+            'heat_templates_archive': 'heat_templates_archive'
         }
         result = t_runner.FunctestRunner._add_testcase_info(self.testcase)
 
@@ -344,7 +344,7 @@ class TestRunnerTesting(unittest.TestCase):
         mock_os.getenv.assert_has_calls([
             call('OS_INSECURE'), call('DOVETAIL_HOME'), call('DEBUG'),
             call('OS_CACERT'), call('HOST_URL'), call('CSAR_FILE'),
-            call('VNF_DIRECTORY')])
+            call('VNF_ARCHIVE_NAME')])
         self.assertEquals(expected, result)
 
     @patch('dovetail.test_runner.dt_utils')
index a7d08ea..67d21fa 100644 (file)
@@ -1,8 +1,8 @@
 ---
 
 {% set build_tag = build_tag or '' %}
-{% set heat_templates_dir = heat_templates_dir or '' %}
-{% set result_dir = '/reports' %}
+{% set heat_templates_archive = heat_templates_archive or '' %}
+{% set result_dir = '/vvp/reports' %}
 
 onap-vvp:
   image_name: nexus3.onap.org:10001/onap/vvp/validation-scripts
@@ -10,11 +10,11 @@ onap-vvp:
   opts: '-td --entrypoint=""'
   shell: '/bin/ash'
   volumes:
-    - '-v {{heat_templates_dir}}:/template'
+    - '-v {{dovetail_home}}/pre_config/{{heat_templates_archive}}.tar.gz:/tmp/{{heat_templates_archive}}.tar.gz'
     - '-v {{dovetail_home}}/results:{{result_dir}}'
   pre_condition:
-    - 'echo this is pre_condition'
+    - 'tar xf /tmp/{{heat_templates_archive}}.tar.gz -C /vvp'
   cmds:
-    - 'pytest --template-directory=/template --output-directory=/reports --report-format=json --continue-on-failure'
+    - 'pytest tests --template-directory=/vvp/{{heat_templates_archive}} --output-directory={{result_dir}} --report-format=json --continue-on-failure'
   post_condition:
     - 'echo this is post_condition'
index 5f7a2e6..4f173a6 100644 (file)
@@ -8,5 +8,5 @@ export CSAR_FILE="/opt/test.csar"
 
 ## Special environment parameters for Heat validation tests.
 
-# The VNF directory should be put at $DOVETAIL_HOME/pre_config.
-export VNF_DIRECTORY="/path/to/pre_config/vnf_dir"
+# The VNF archive should be put at $DOVETAIL_HOME/pre_config.
+export VNF_ARCHIVE_NAME="vnf_archive_name"