From a327e29a12a3bcdc47bfe2d50107e7e6c7310f16 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Sun, 18 Feb 2018 16:11:02 +0000 Subject: Add "render-only" option to "task" command This new option provides to the user the ability to output the rendered input files. This option could be useful in case the input files are Jinja2 templates, depending on input arguments. The user can preview the rendered input tasks files without executing them. JIRA: YARDSTICK-1020 Change-Id: Ib15ade7e1adcb29beae5e635fb5d02045c4432bb Signed-off-by: Rodolfo Alonso Hernandez --- yardstick/tests/unit/benchmark/core/test_task.py | 138 ++++++++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) (limited to 'yardstick/tests') diff --git a/yardstick/tests/unit/benchmark/core/test_task.py b/yardstick/tests/unit/benchmark/core/test_task.py index 25a7a64b3..253e9d8aa 100644 --- a/yardstick/tests/unit/benchmark/core/test_task.py +++ b/yardstick/tests/unit/benchmark/core/test_task.py @@ -8,15 +8,21 @@ ############################################################################## import copy +import io import os +import sys import mock +import six import unittest +import uuid from yardstick.benchmark.contexts import dummy from yardstick.benchmark.core import task from yardstick.common import constants as consts from yardstick.common import exceptions +from yardstick.common import task_template +from yardstick.common import utils class TaskTestCase(unittest.TestCase): @@ -177,7 +183,6 @@ class TaskTestCase(unittest.TestCase): 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml')) self.assertEqual(task_files[1], self.change_to_abspath( 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml')) - self.assertIsNone(task_args[0]) self.assertIsNone(task_args[1]) self.assertIsNone(task_args_fnames[0]) @@ -279,6 +284,27 @@ class TaskTestCase(unittest.TestCase): class TaskParserTestCase(unittest.TestCase): + TASK = """ +{% set value1 = value1 or 'var1' %} +{% set value2 = value2 or 'var2' %} +key1: {{ value1 }} +key2: + - {{ value2 }}""" + + TASK_RENDERED_1 = u""" + + +key1: var1 +key2: + - var2""" + + TASK_RENDERED_2 = u""" + + +key1: var3 +key2: + - var4""" + def setUp(self): self.parser = task.TaskParser('fake/path') self.scenario = { @@ -362,3 +388,113 @@ class TaskParserTestCase(unittest.TestCase): self.parser._change_node_names(scenario, [my_context]) self.assertEqual(scenario, expected_scenario) + + def test__parse_tasks(self): + task_obj = task.Task() + _uuid = uuid.uuid4() + task_obj.task_id = _uuid + task_files = ['/directory/task_file_name.yml'] + mock_parser = mock.Mock() + mock_parser.parse_task.return_value = {'rendered': 'File content'} + mock_args = mock.Mock() + mock_args.render_only = False + + tasks = task_obj._parse_tasks(mock_parser, task_files, mock_args, + ['arg1'], ['file_arg1']) + self.assertEqual( + [{'rendered': 'File content', 'case_name': 'task_file_name'}], + tasks) + mock_parser.parse_task.assert_called_once_with( + _uuid, 'arg1', 'file_arg1') + + @mock.patch.object(sys, 'exit') + @mock.patch.object(utils, 'write_file') + @mock.patch.object(utils, 'makedirs') + def test__parse_tasks_render_only(self, mock_makedirs, mock_write_file, + mock_exit): + task_obj = task.Task() + _uuid = uuid.uuid4() + task_obj.task_id = _uuid + task_files = ['/directory/task_file_name.yml'] + mock_parser = mock.Mock() + mock_parser.parse_task.return_value = {'rendered': 'File content'} + mock_args = mock.Mock() + mock_args.render_only = '/output_directory' + + task_obj._parse_tasks(mock_parser, task_files, mock_args, + ['arg1'], ['file_arg1']) + mock_makedirs.assert_called_once_with('/output_directory') + mock_write_file.assert_called_once_with( + '/output_directory/000-task_file_name.yml', 'File content') + mock_exit.assert_called_once_with(0) + + def test__render_task_no_args(self): + task_parser = task.TaskParser('task_file') + task_str = io.StringIO(six.text_type(self.TASK)) + with mock.patch.object(six.moves.builtins, 'open', + return_value=task_str) as mock_open: + parsed, rendered = task_parser._render_task(None, None) + + self.assertEqual(self.TASK_RENDERED_1, rendered) + self.assertEqual({'key1': 'var1', 'key2': ['var2']}, parsed) + mock_open.assert_called_once_with('task_file') + + def test__render_task_arguments(self): + task_parser = task.TaskParser('task_file') + task_str = io.StringIO(six.text_type(self.TASK)) + with mock.patch.object(six.moves.builtins, 'open', + return_value=task_str) as mock_open: + parsed, rendered = task_parser._render_task('value1: "var1"', None) + + self.assertEqual(self.TASK_RENDERED_1, rendered) + self.assertEqual({'key1': 'var1', 'key2': ['var2']}, parsed) + mock_open.assert_called_once_with('task_file') + + def test__render_task_file_arguments(self): + task_parser = task.TaskParser('task_file') + with mock.patch.object(six.moves.builtins, 'open') as mock_open: + mock_open.side_effect = ( + io.StringIO(six.text_type('value2: var4')), + io.StringIO(six.text_type(self.TASK)) + ) + parsed, rendered = task_parser._render_task('value1: "var3"', + 'args_file') + + self.assertEqual(self.TASK_RENDERED_2, rendered) + self.assertEqual({'key1': 'var3', 'key2': ['var4']}, parsed) + mock_open.assert_has_calls([mock.call('args_file'), + mock.call('task_file')]) + + def test__render_task_error_arguments(self): + with self.assertRaises(exceptions.TaskRenderArgumentError): + task.TaskParser('task_file')._render_task('value1="var3"', None) + + def test__render_task_error_task_file(self): + task_parser = task.TaskParser('task_file') + with mock.patch.object(six.moves.builtins, 'open') as mock_open: + mock_open.side_effect = ( + io.StringIO(six.text_type('value2: var4')), + IOError() + ) + with self.assertRaises(exceptions.TaskReadError): + task_parser._render_task('value1: "var3"', 'args_file') + + mock_open.assert_has_calls([mock.call('args_file'), + mock.call('task_file')]) + + def test__render_task_render_error(self): + task_parser = task.TaskParser('task_file') + with mock.patch.object(six.moves.builtins, 'open') as mock_open, \ + mock.patch.object(task_template.TaskTemplate, 'render', + side_effect=TypeError) as mock_render: + mock_open.side_effect = ( + io.StringIO(six.text_type('value2: var4')), + io.StringIO(six.text_type(self.TASK)) + ) + with self.assertRaises(exceptions.TaskRenderError): + task_parser._render_task('value1: "var3"', 'args_file') + + mock_open.assert_has_calls([mock.call('args_file'), + mock.call('task_file')]) + mock_render.assert_has_calls( + [mock.call(self.TASK, value1='var3', value2='var4')]) -- cgit 1.2.3-korg