From b4e6a756ebeb019048cb03a0562534870b772cae Mon Sep 17 00:00:00 2001 From: Stamatis Katsaounis Date: Tue, 19 Feb 2019 12:38:10 +0200 Subject: Calculate checksum for input VNF 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 --- docs/testing/user/userguide/vnf_test_guide.rst | 17 +++++----- dovetail/report.py | 21 ++++++++++++ dovetail/test_runner.py | 2 +- dovetail/tests/unit/test_report.py | 47 +++++++++++++++++++++++++- dovetail/tests/unit/test_test_runner.py | 6 ++-- etc/conf/onap-vvp_config.yml | 10 +++--- etc/userconfig/env_config.sh.onap.sample | 4 +-- 7 files changed, 86 insertions(+), 21 deletions(-) diff --git a/docs/testing/user/userguide/vnf_test_guide.rst b/docs/testing/user/userguide/vnf_test_guide.rst index 72b5fa4b..63ed04bf 100644 --- a/docs/testing/user/userguide/vnf_test_guide.rst +++ b/docs/testing/user/userguide/vnf_test_guide.rst @@ -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: diff --git a/dovetail/report.py b/dovetail/report.py index 86f941df..556fc76d 100644 --- a/dovetail/report.py +++ b/dovetail/report.py @@ -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: diff --git a/dovetail/test_runner.py b/dovetail/test_runner.py index 00cc99e5..44233e13 100644 --- a/dovetail/test_runner.py +++ b/dovetail/test_runner.py @@ -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): diff --git a/dovetail/tests/unit/test_report.py b/dovetail/tests/unit/test_report.py index be56e15c..e44c6ac8 100644 --- a/dovetail/tests/unit/test_report.py +++ b/dovetail/tests/unit/test_report.py @@ -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') diff --git a/dovetail/tests/unit/test_test_runner.py b/dovetail/tests/unit/test_test_runner.py index 345dfd65..a40e3cb1 100644 --- a/dovetail/tests/unit/test_test_runner.py +++ b/dovetail/tests/unit/test_test_runner.py @@ -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') diff --git a/etc/conf/onap-vvp_config.yml b/etc/conf/onap-vvp_config.yml index a7d08ea8..67d21fae 100644 --- a/etc/conf/onap-vvp_config.yml +++ b/etc/conf/onap-vvp_config.yml @@ -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' diff --git a/etc/userconfig/env_config.sh.onap.sample b/etc/userconfig/env_config.sh.onap.sample index 5f7a2e61..4f173a62 100644 --- a/etc/userconfig/env_config.sh.onap.sample +++ b/etc/userconfig/env_config.sh.onap.sample @@ -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" -- cgit 1.2.3-korg