From 74051db5e31c64650916aac01991cc9d306ab15e Mon Sep 17 00:00:00 2001 From: Stamatis Katsaounis Date: Fri, 16 Nov 2018 16:41:10 +0200 Subject: Add missing unit tests for run file JIRA: DOVETAIL-724 This patch adds unit tests for run file methods of Dovetail which were missing. Change-Id: I1700c8c97430899abdc2b752a3dcbd4d09a334ac Signed-off-by: Stamatis Katsaounis --- .coveragerc | 6 + dovetail/run.py | 98 +++--- dovetail/tests/unit/cmd_config.yml | 24 ++ dovetail/tests/unit/test_run.py | 667 +++++++++++++++++++++++++++++++++++++ 4 files changed, 744 insertions(+), 51 deletions(-) create mode 100644 .coveragerc create mode 100644 dovetail/tests/unit/cmd_config.yml create mode 100644 dovetail/tests/unit/test_run.py diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..8777f5d0 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,6 @@ +[run] +omit = dovetail/tests/* +[report] +exclude_lines = + pass + main() diff --git a/dovetail/run.py b/dovetail/run.py index 9f109d45..9b4dade1 100755 --- a/dovetail/run.py +++ b/dovetail/run.py @@ -20,14 +20,9 @@ import click from container import Container from dovetail import constants from parser import Parser -from report import BottlenecksChecker, FunctestChecker, YardstickChecker -from report import VnftestChecker -from report import BottlenecksCrawler, FunctestCrawler, YardstickCrawler -from report import VnftestCrawler -from report import Report -from test_runner import DockerRunner, ShellRunner -from testcase import Testcase -from testcase import Testsuite +import report as dt_report +import test_runner as dt_test_runner +import testcase as dt_testcase from utils.dovetail_config import DovetailConfig as dt_cfg import utils.dovetail_logger as dt_logger import utils.dovetail_utils as dt_utils @@ -36,21 +31,21 @@ EXIT_RUN_FAILED = 2 def load_testsuite(testsuite): - Testsuite.load() - return Testsuite.get(testsuite) + dt_testcase.Testsuite.load() + return dt_testcase.Testsuite.get(testsuite) def run_test(testcase_list, report_flag, logger): - report = Report() + report = dt_report.Report() duration = 0 if not testcase_list: - logger.warning("No test case will be executed.") + logger.warning('No test case will be executed.') return start_time = time.time() for testcase_name in testcase_list: logger.info('>>[testcase]: {}'.format(testcase_name)) - testcase = Testcase.get(testcase_name) + testcase = dt_testcase.Testcase.get(testcase_name) run_testcase = True if run_testcase: @@ -59,12 +54,12 @@ def run_test(testcase_list, report_flag, logger): result = report.check_tc_result(testcase) if dt_cfg.dovetail_config['stop']: try: - if (not result or result['criteria'] == "FAIL"): - logger.info("Stop because {} failed".format(testcase_name)) + if (not result or result['criteria'] == 'FAIL'): + logger.info('Stop because {} failed'.format(testcase_name)) return except KeyError as e: - logger.error("There is no key {}.".format(e)) - logger.info("Stop because {} failed".format(testcase_name)) + logger.error('There is no key {}.'.format(e)) + logger.info('Stop because {} failed'.format(testcase_name)) return end_time = time.time() @@ -110,19 +105,19 @@ def filter_config(input_dict, logger): def create_logs(): Container.create_log() Parser.create_log() - Report.create_log() - FunctestCrawler.create_log() - YardstickCrawler.create_log() - VnftestCrawler.create_log() - BottlenecksCrawler.create_log() - FunctestChecker.create_log() - YardstickChecker.create_log() - VnftestChecker.create_log() - BottlenecksChecker.create_log() - Testcase.create_log() - Testsuite.create_log() - DockerRunner.create_log() - ShellRunner.create_log() + dt_report.Report.create_log() + dt_report.FunctestCrawler.create_log() + dt_report.YardstickCrawler.create_log() + dt_report.VnftestCrawler.create_log() + dt_report.BottlenecksCrawler.create_log() + dt_report.FunctestChecker.create_log() + dt_report.YardstickChecker.create_log() + dt_report.VnftestChecker.create_log() + dt_report.BottlenecksChecker.create_log() + dt_testcase.Testcase.create_log() + dt_testcase.Testsuite.create_log() + dt_test_runner.DockerRunner.create_log() + dt_test_runner.ShellRunner.create_log() def clean_results_dir(): @@ -132,26 +127,26 @@ def clean_results_dir(): cmd = 'sudo rm -rf %s/*' % (result_path) dt_utils.exec_cmd(cmd, exit_on_error=False, exec_msg_on=False) else: - print("result_dir in dovetail_config.yml is not a directory.") + print('result_dir in dovetail_config.yml is not a directory.') raise SystemExit(EXIT_RUN_FAILED) def get_result_path(): try: - dovetail_home = os.environ["DOVETAIL_HOME"] + dovetail_home = os.environ['DOVETAIL_HOME'] except Exception: print("ERROR: mandatory env variable 'DOVETAIL_HOME' is not found, " "please set in env_config.sh and source this file before " "running.") return None - result_path = os.path.join(dovetail_home, 'results') - dt_cfg.dovetail_config['result_dir'] = result_path + dt_cfg.dovetail_config['result_dir'] = os.path.join(dovetail_home, + 'results') dt_cfg.dovetail_config['images_dir'] = os.path.join(dovetail_home, 'images') - pre_config_path = os.path.join(dovetail_home, 'pre_config') - patch_set_path = os.path.join(dovetail_home, 'patches') - dt_cfg.dovetail_config['config_dir'] = pre_config_path - dt_cfg.dovetail_config['patch_dir'] = patch_set_path + dt_cfg.dovetail_config['config_dir'] = os.path.join(dovetail_home, + 'pre_config') + dt_cfg.dovetail_config['patch_dir'] = os.path.join(dovetail_home, + 'patches') return dovetail_home @@ -177,22 +172,22 @@ 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)) + 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']) + 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)) + logger.warn('There is no hosts file {}, may be some issues with ' + 'domain name resolution.'.format(hosts_file)) def parse_cli(logger=None, **kwargs): @@ -214,16 +209,16 @@ def parse_cli(logger=None, **kwargs): def check_testcase_list(testcase_list, logger=None): if testcase_list: for tc in testcase_list: - if tc not in Testcase.testcase_list: + if tc not in dt_testcase.Testcase.testcase_list: logger.error('Test case {} is not defined.'.format(tc)) return None return testcase_list - logger.error("There is no test case to be executed.") + logger.error('There is no test case to be executed.') return None def get_testcase_list(logger=None, **kwargs): - Testcase.load() + dt_testcase.Testcase.load() testcase_list = kwargs['testcase'] # If specify 'testcase' on the CLI, ignore 'testsuite' and 'testarea'. In @@ -239,12 +234,13 @@ def get_testcase_list(logger=None, **kwargs): if testsuite in dt_cfg.dovetail_config['testsuite_supported']: testsuite_validation = True origin_testarea = kwargs['testarea'] - testarea_validation, testarea = Testcase.check_testarea(origin_testarea) + testarea_validation, testarea = dt_testcase.Testcase.check_testarea( + origin_testarea) if testsuite_validation and testarea_validation: testsuite_yaml = load_testsuite(testsuite) - testcase_list = Testcase.get_testcases_for_testsuite(testsuite_yaml, - testarea) + testcase_list = dt_testcase.Testcase.get_testcases_for_testsuite( + testsuite_yaml, testarea) return check_testcase_list(testcase_list, logger) elif not testsuite_validation: logger.error('Test suite {} is not defined.'.format(testsuite)) @@ -255,7 +251,7 @@ def get_testcase_list(logger=None, **kwargs): def main(*args, **kwargs): """Dovetail compliance test entry!""" - build_tag = "daily-master-%s" % str(uuid.uuid1()) + build_tag = 'daily-master-%s' % str(uuid.uuid1()) dt_cfg.dovetail_config['build_tag'] = build_tag if not get_result_path(): return @@ -292,7 +288,7 @@ CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) if dovetail_config['cli']['options'] is not None: for key, value in dovetail_config['cli']['options'].items(): if value is not None: - for k, v in value.items(): + for _, v in value.items(): flags = v['flags'] v.pop('flags') v.pop('path', None) @@ -300,7 +296,7 @@ if dovetail_config['cli']['options'] is not None: if dovetail_config['cli']['arguments'] is not None: for key, value in dovetail_config['cli']['arguments'].items(): if value is not None: - for k, v in value.items(): + for _, v in value.items(): flags = v['flags'] v.pop('flags') v.pop('path', None) diff --git a/dovetail/tests/unit/cmd_config.yml b/dovetail/tests/unit/cmd_config.yml new file mode 100644 index 00000000..4a1439f6 --- /dev/null +++ b/dovetail/tests/unit/cmd_config.yml @@ -0,0 +1,24 @@ +--- +cli: + arguments: + config: + docker_tag: + flags: 'docker_tag' + path: + - 'functest/docker_tag' + control: + + options: + config: + control: + testsuite: + flags: + - '--testsuite' + debug: + flags: + - '--debug' + is_flag: 'True' + report: + flags: + - '--report' + is_flag: 'True' diff --git a/dovetail/tests/unit/test_run.py b/dovetail/tests/unit/test_run.py new file mode 100644 index 00000000..1e48fe69 --- /dev/null +++ b/dovetail/tests/unit/test_run.py @@ -0,0 +1,667 @@ +#!/usr/bin/env python +# +# Copyright (c) 2018 mokats@intracom-telecom.com and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +## + +import os +import unittest +import yaml +from mock import patch, call, Mock +from _pytest.monkeypatch import MonkeyPatch + +from dovetail.utils.dovetail_config import DovetailConfig + +monkeypatch = MonkeyPatch() +conf_path = os.path.abspath( + os.path.join(os.path.dirname(__file__))) +file_path = os.path.join(os.path.dirname(__file__), 'cmd_config.yml') +with open(file_path) as f: + extra_config = yaml.safe_load(f) +monkeypatch.setattr(DovetailConfig, 'load_config_files', Mock()) +monkeypatch.setattr(DovetailConfig, 'dovetail_config', extra_config) +from dovetail import run as dt_run # noqa: E402 +monkeypatch.undo() + +__author__ = 'Stamatis Katsaounis ' + + +class RunTesting(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + @patch('dovetail.run.dt_testcase.Testsuite') + def test_load_testsuite(self, mock_testsuite): + mock_testsuite.get.return_value = 'suite_a' + + result = dt_run.load_testsuite('testsuite') + + mock_testsuite.load.assert_called_once_with() + mock_testsuite.get.assert_called_once_with('testsuite') + self.assertEquals('suite_a', result) + + @patch('dovetail.run.dt_report.Report') + def test_run_test_no_list(self, mock_report): + logger = Mock() + mock_report.return_value = Mock() + + dt_run.run_test([], False, logger) + logger.warning.assert_called_once_with( + "No test case will be executed.") + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_report.Report') + @patch('dovetail.run.dt_testcase.Testcase') + @patch('dovetail.run.time') + def test_run_test(self, mock_time, mock_testcase, mock_report, + mock_config): + logger = Mock() + report_obj = Mock() + mock_report.return_value = report_obj + mock_time.time.side_effect = [42, 84] + testcase_name = 'testcase' + testcase_obj = Mock() + mock_testcase.get.return_value = testcase_obj + mock_config.dovetail_config = {'stop': True} + report_obj.check_tc_result.return_value = {'criteria': 'PASS'} + + dt_run.run_test([testcase_name], True, logger) + + mock_time.time.assert_has_calls([call(), call()]) + logger.info.assert_called_once_with( + '>>[testcase]: {}'.format(testcase_name)) + mock_testcase.get.assert_called_once_with(testcase_name) + testcase_obj.run.assert_called_once_with() + report_obj.check_tc_result.assert_called_once_with(testcase_obj) + report_obj.generate.assert_called_once_with([testcase_name], 42) + report_obj.save_logs.assert_called_once_with() + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_report.Report') + @patch('dovetail.run.dt_testcase.Testcase') + @patch('dovetail.run.time') + def test_run_test_fail(self, mock_time, mock_testcase, mock_report, + mock_config): + logger = Mock() + report_obj = Mock() + mock_report.return_value = report_obj + testcase_name = 'testcase' + testcase_obj = Mock() + mock_testcase.get.return_value = testcase_obj + mock_config.dovetail_config = {'stop': True} + report_obj.check_tc_result.return_value = {'criteria': 'FAIL'} + + dt_run.run_test([testcase_name], True, logger) + + mock_time.time.assert_called_once_with() + logger.info.assert_has_calls([ + call('>>[testcase]: {}'.format(testcase_name)), + call('Stop because {} failed'.format(testcase_name))]) + mock_testcase.get.assert_called_once_with(testcase_name) + testcase_obj.run.assert_called_once_with() + report_obj.check_tc_result.assert_called_once_with(testcase_obj) + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_report.Report') + @patch('dovetail.run.dt_testcase.Testcase') + @patch('dovetail.run.time') + def test_run_test_fail_key_error(self, mock_time, mock_testcase, + mock_report, mock_config): + logger = Mock() + report_obj = Mock() + mock_report.return_value = report_obj + mock_time.time.return_value = 42 + testcase_name = 'testcase' + testcase_obj = Mock() + mock_testcase.get.return_value = testcase_obj + mock_config.dovetail_config = {'stop': True} + report_obj.check_tc_result.return_value = {'key': 'value'} + + dt_run.run_test([testcase_name], True, logger) + + mock_time.time.assert_called_once_with() + logger.info.assert_has_calls([ + call('>>[testcase]: {}'.format(testcase_name)), + call('Stop because {} failed'.format(testcase_name))]) + logger.error.assert_called_once_with("There is no key 'criteria'.") + mock_testcase.get.assert_called_once_with(testcase_name) + testcase_obj.run.assert_called_once_with() + report_obj.check_tc_result.assert_called_once_with(testcase_obj) + + @patch('dovetail.run.dt_cfg') + def test_filter_config(self, mock_config): + mock_config.dovetail_config = { + 'cli': { + 'key_a': { + 'config': { + 'config_key': {'path': 'a'}, + 'KEY_UPPER': {'path': 'b'} + } + }, + 'key_b': {}, + 'key_c': { + 'config': None + }, + 'key_d': { + 'invalid': {} + } + } + } + input_dict = { + 'config_key': 'c', + 'key_upper': 'd' + } + expected_dict = { + 'config_key': {'path': 'a', 'value': 'c'}, + 'KEY_UPPER': {'path': 'b', 'value': 'd'} + } + + result = dt_run.filter_config(input_dict, Mock()) + + self.assertEquals(expected_dict, result) + + @patch('dovetail.run.dt_cfg') + def test_filter_config_none(self, mock_config): + mock_config.dovetail_config = {'cli': {}} + result = dt_run.filter_config({}, Mock()) + + self.assertEquals(None, result) + + @patch('dovetail.run.dt_cfg') + def test_filter_config_keyerror(self, mock_config): + mock_config.dovetail_config = { + 'cli': { + 'key_a': { + 'config': { + 'config_key': {'invalid': 'a'} + } + } + } + } + input_dict = {'config_key': 'c'} + logger = Mock() + + with self.assertRaises(SystemExit) as cm: + dt_run.filter_config(input_dict, logger) + + logger.exception.assert_called_once_with("KeyError 'path'.") + expected = cm.exception + self.assertEqual(expected.code, 2) + + @patch('dovetail.run.Container') + @patch('dovetail.run.Parser') + @patch('dovetail.run.dt_report') + @patch('dovetail.run.dt_test_runner') + @patch('dovetail.run.dt_testcase') + def test_create_logs(self, mock_testcase, mock_test_runner, mock_report, + mock_parser, mock_container): + + dt_run.create_logs() + + mock_container.create_log.assert_called_once_with() + mock_parser.create_log.assert_called_once_with() + mock_report.Report.create_log.assert_called_once_with() + mock_report.FunctestCrawler.create_log.assert_called_once_with() + mock_report.YardstickCrawler.create_log.assert_called_once_with() + mock_report.VnftestCrawler.create_log.assert_called_once_with() + mock_report.BottlenecksCrawler.create_log.assert_called_once_with() + mock_report.FunctestChecker.create_log.assert_called_once_with() + mock_report.YardstickChecker.create_log.assert_called_once_with() + mock_report.VnftestChecker.create_log.assert_called_once_with() + mock_report.BottlenecksChecker.create_log.assert_called_once_with() + mock_testcase.Testcase.create_log.assert_called_once_with() + mock_testcase.Testsuite.create_log.assert_called_once_with() + mock_test_runner.DockerRunner.create_log.assert_called_once_with() + mock_test_runner.ShellRunner.create_log.assert_called_once_with() + + @patch('dovetail.run.dt_utils') + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.os') + def test_clean_results_dir(self, mock_os, mock_config, mock_utils): + mock_config.dovetail_config = {'result_dir': 'value'} + mock_os.path.exists.return_value = True + mock_os.path.isdir.return_value = True + + dt_run.clean_results_dir() + + mock_os.path.exists.assert_called_once_with('value') + mock_os.path.isdir.assert_called_once_with('value') + mock_utils.exec_cmd.assert_called_once_with( + 'sudo rm -rf value/*', exit_on_error=False, exec_msg_on=False) + + @patch('dovetail.run.dt_utils') + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.os') + def test_clean_results_dir_error(self, mock_os, mock_config, mock_utils): + mock_config.dovetail_config = {'result_dir': 'value'} + mock_os.path.exists.return_value = True + mock_os.path.isdir.return_value = False + + with self.assertRaises(SystemExit) as cm: + dt_run.clean_results_dir() + + mock_os.path.exists.assert_called_once_with('value') + mock_os.path.isdir.assert_called_once_with('value') + expected = cm.exception + self.assertEqual(expected.code, 2) + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.os') + def test_get_result_path(self, mock_os, mock_config): + dovetail_home = 'dovetail_home' + mock_os.environ = {'DOVETAIL_HOME': dovetail_home} + mock_os.path.join.side_effect = [ + 'result_path', 'images_dir', 'pre_config_path', 'patch_set_path'] + mock_config.dovetail_config = {} + + result = dt_run.get_result_path() + + mock_os.path.join.assert_has_calls([ + call(dovetail_home, 'results'), + call(dovetail_home, 'images'), + call(dovetail_home, 'pre_config'), + call(dovetail_home, 'patches')]) + expected_dict = { + 'result_dir': 'result_path', + 'images_dir': 'images_dir', + 'config_dir': 'pre_config_path', + 'patch_dir': 'patch_set_path'} + self.assertEquals(expected_dict, mock_config.dovetail_config) + self.assertEquals(dovetail_home, result) + + @patch('dovetail.run.os') + def test_get_result_path_exception(self, mock_os): + mock_os.environ = {} + + result = dt_run.get_result_path() + + self.assertEquals(None, result) + + @patch('dovetail.run.constants') + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_utils') + @patch('dovetail.run.os') + def test_copy_userconfig_files(self, mock_os, mock_utils, mock_config, + mock_constants): + mock_config.dovetail_config = {'config_dir': 'value'} + mock_os.path.isdir.return_value = False + mock_constants.USERCONF_PATH = 'value' + logger = Mock() + + dt_run.copy_userconfig_files(logger) + + mock_os.path.isdir.assert_called_once_with('value') + mock_os.makedirs.assert_called_once_with('value') + mock_utils.exec_cmd.assert_called_once_with( + 'sudo cp -r value/* value', logger, exit_on_error=False) + + @patch('dovetail.run.constants') + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_utils') + @patch('dovetail.run.os') + def test_copy_patch_files(self, mock_os, mock_utils, mock_config, + mock_constants): + mock_config.dovetail_config = {'patch_dir': 'value'} + mock_os.path.isdir.return_value = False + mock_constants.PATCH_PATH = 'value' + logger = Mock() + + dt_run.copy_patch_files(logger) + + mock_os.path.isdir.assert_called_once_with('value') + mock_os.makedirs.assert_called_once_with('value') + 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() + mock_os.environ = {} + + dt_run.update_deploy_scenario(logger, deploy_scenario='a') + + 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): + mock_config.dovetail_config = {} + logger = Mock() + + dt_run.parse_cli(logger=logger, + offline='a', + no_clean='b', + stop='c', + mandatory='d', + optional='e', + no_api_validation=True) + expected_dict = { + 'offline': 'a', + 'noclean': 'b', + 'stop': 'c', + 'mandatory': 'd', + 'optional': 'e', + 'no_api_validation': True + } + + logger.warning.assert_called_once_with( + 'Strict API response validation DISABLED.') + self.assertEquals(expected_dict, mock_config.dovetail_config) + + @patch('dovetail.run.dt_cfg') + @patch.object(dt_run, 'filter_config') + def test_cli_with_validation(self, mock_filter, mock_config): + mock_config.dovetail_config = {} + + dt_run.parse_cli(offline='a', + no_clean='b', + stop='c', + mandatory='d', + optional='e', + no_api_validation=False) + expected_dict = { + 'offline': 'a', + 'noclean': 'b', + 'stop': 'c', + 'mandatory': 'd', + 'optional': 'e', + 'no_api_validation': False + } + + self.assertEquals(expected_dict, mock_config.dovetail_config) + + def test_check_testcase_list_not_in_list(self): + logger = Mock() + + result = dt_run.check_testcase_list(['testcase'], logger) + + logger.error.assert_called_once_with( + 'Test case testcase is not defined.') + self.assertEquals(None, result) + + def test_check_testcase_list_none(self): + logger = Mock() + result = dt_run.check_testcase_list(None, logger) + + logger.error.assert_called_once_with( + 'There is no test case to be executed.') + self.assertEquals(None, result) + + @patch('dovetail.run.dt_testcase.Testcase') + def test_check_testcase_list(self, mock_testcase): + testcase_list = ['testcase'] + mock_testcase.testcase_list = testcase_list + + result = dt_run.check_testcase_list(testcase_list) + + self.assertEquals(testcase_list, result) + + @patch('dovetail.run.dt_testcase.Testcase') + @patch.object(dt_run, 'check_testcase_list') + def test_get_testcase_list_check(self, mock_check, mock_testcase): + testcase_list = ['testcase'] + mock_check.return_value = testcase_list + + result = dt_run.get_testcase_list(testcase=testcase_list) + + mock_check.assert_called_once_with(testcase_list, None) + mock_testcase.load.assert_called_once_with() + self.assertEquals(testcase_list, result) + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_testcase.Testcase') + @patch.object(dt_run, 'check_testcase_list') + @patch.object(dt_run, 'load_testsuite') + def test_get_testcase_list(self, mock_load, mock_check, mock_testcase, + mock_config): + mock_config.dovetail_config = {'testsuite_supported': ['suite']} + testcase_list = ['testcase'] + mock_testcase.check_testarea.return_value = (True, 'area') + mock_load.return_value = 'testsuite_yaml' + mock_testcase.get_testcases_for_testsuite.return_value = testcase_list + mock_check.return_value = testcase_list + + result = dt_run.get_testcase_list( + testcase=None, testsuite='suite', testarea='area') + + mock_testcase.load.assert_called_once_with() + mock_testcase.check_testarea.assert_called_once_with('area') + mock_load.assert_called_once_with('suite') + mock_testcase.get_testcases_for_testsuite.assert_called_once_with( + 'testsuite_yaml', 'area') + mock_check.assert_called_once_with(testcase_list, None) + self.assertEquals(testcase_list, result) + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_testcase.Testcase') + def test_get_testcase_list_no_testsuite(self, mock_testcase, mock_config): + logger = Mock() + mock_config.dovetail_config = {'testsuite_supported': []} + mock_testcase.check_testarea.return_value = (True, 'area') + + result = dt_run.get_testcase_list( + logger, testcase=None, testsuite='suite', testarea='area') + + mock_testcase.load.assert_called_once_with() + mock_testcase.check_testarea.assert_called_once_with('area') + logger.error.assert_called_once_with( + 'Test suite suite is not defined.') + self.assertEquals(None, result) + + @patch('dovetail.run.dt_cfg') + @patch('dovetail.run.dt_testcase.Testcase') + def test_get_testcase_list_no_testarea(self, mock_testcase, mock_config): + logger = Mock() + mock_config.dovetail_config = {'testsuite_supported': ['suite']} + mock_testcase.check_testarea.return_value = (False, 'area') + + result = dt_run.get_testcase_list( + logger, testcase=None, testsuite='suite', testarea='area') + + mock_testcase.load.assert_called_once_with() + mock_testcase.check_testarea.assert_called_once_with('area') + logger.error.assert_called_once_with( + 'Test area area is not defined.') + self.assertEquals(None, result) + + @patch('dovetail.run.os') + @patch('dovetail.run.uuid') + @patch('dovetail.run.dt_logger') + @patch('dovetail.run.dt_cfg') + @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, '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): + mock_config.dovetail_config = {} + mock_os.environ = {} + logger_obj = Mock() + logger_temp_obj = Mock() + logger_temp_obj.getLogger.return_value = logger_obj + mock_logger.Logger.return_value = logger_temp_obj + mock_uuid.uuid1.return_value = 42 + mock_get_result.return_value = True + testcase_list = ['testcase'] + mock_get_list.return_value = testcase_list + kwargs_dict = { + 'debug': True, + 'report': True, + 'testsuite': 'testsuite', + 'docker_tag': '2.0.0' + } + + with self.assertRaises(SystemExit) as cm: + dt_run.main([ + '--testsuite=testsuite', '--debug', '--report', '2.0.0']) + expected = cm.exception + + logger_temp_obj.getLogger.assert_called_once_with() + mock_logger.Logger.assert_called_once_with('run') + mock_uuid.uuid1.assert_called_once_with() + self.assertEquals({'build_tag': 'daily-master-42'}, + mock_config.dovetail_config) + mock_get_result.assert_called_once_with() + mock_clean.assert_called_once_with() + self.assertEquals({'DEBUG': 'true'}, mock_os.environ) + mock_create_logs.assert_called_once_with() + logger_obj.info.assert_has_calls([ + call('================================================'), + call('Dovetail compliance: testsuite!'), + call('================================================'), + 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) + self.assertEquals(expected.code, 0) + + @patch('dovetail.run.uuid') + @patch('dovetail.run.dt_cfg') + @patch.object(dt_run, 'get_result_path') + def test_main_no_results_path(self, mock_get_result, mock_config, + mock_uuid): + mock_config.dovetail_config = {} + mock_uuid.uuid1.return_value = 42 + mock_get_result.return_value = False + + with self.assertRaises(SystemExit) as cm: + dt_run.main(['2.0.0']) + expected = cm.exception + + mock_uuid.uuid1.assert_called_once_with() + self.assertEquals({'build_tag': 'daily-master-42'}, + mock_config.dovetail_config) + mock_get_result.assert_called_once_with() + self.assertEquals(expected.code, 0) + + @patch('dovetail.run.os') + @patch('dovetail.run.uuid') + @patch('dovetail.run.dt_logger') + @patch('dovetail.run.dt_cfg') + @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, '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, + mock_get_result, mock_utils, mock_config, + mock_logger, mock_uuid, mock_os): + mock_config.dovetail_config = {} + mock_os.environ = {} + logger_obj = Mock() + logger_temp_obj = Mock() + logger_temp_obj.getLogger.return_value = logger_obj + mock_logger.Logger.return_value = logger_temp_obj + mock_uuid.uuid1.return_value = 42 + mock_get_result.return_value = True + mock_get_list.return_value = None + kwargs_dict = { + 'debug': True, + 'report': True, + 'testsuite': 'testsuite', + 'docker_tag': '2.0.0' + } + + with self.assertRaises(SystemExit) as cm: + dt_run.main([ + '--testsuite=testsuite', '--debug', '--report', '2.0.0']) + expected = cm.exception + self.assertEquals(expected.code, 2) + + logger_temp_obj.getLogger.assert_called_once_with() + mock_logger.Logger.assert_called_once_with('run') + mock_uuid.uuid1.assert_called_once_with() + self.assertEquals({'build_tag': 'daily-master-42'}, + mock_config.dovetail_config) + mock_get_result.assert_called_once_with() + mock_clean.assert_called_once_with() + self.assertEquals({'DEBUG': 'true'}, mock_os.environ) + mock_create_logs.assert_called_once_with() + logger_obj.info.assert_has_calls([ + call('================================================'), + call('Dovetail compliance: testsuite!'), + call('================================================'), + 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) -- cgit 1.2.3-korg