From 82818f29502ac60d62fd2198617360c244f3bbf3 Mon Sep 17 00:00:00 2001 From: Daniel Vaccaro-Senna Date: Wed, 9 Dec 2020 10:28:51 +0000 Subject: [PATCH 1/4] issue/29 updated tests to include non-string props --- kubedriver/pkg_info.json | 2 +- tests/unit/infrastructure/test_driver.py | 6 ++++++ .../simple-deploy-objects/objects/simple.yaml | 1 + tests/unit/kegd/test_manager.py | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/kubedriver/pkg_info.json b/kubedriver/pkg_info.json index 58c137b..034ef3f 100644 --- a/kubedriver/pkg_info.json +++ b/kubedriver/pkg_info.json @@ -1,4 +1,4 @@ { "version": "0.0.6.dev0", - "ignition-version": "2.0.4" + "ignition-version": "2.0.5.dev0" } diff --git a/tests/unit/infrastructure/test_driver.py b/tests/unit/infrastructure/test_driver.py index 366640c..662e96b 100644 --- a/tests/unit/infrastructure/test_driver.py +++ b/tests/unit/infrastructure/test_driver.py @@ -61,6 +61,8 @@ def __mock_properties(self): properties['propA'] = {'type': 'string', 'value': 'A'} properties['propB'] = {'type': 'string', 'value': 'B'} properties['propC'] = {'type': 'string', 'value': 'C'} + properties['propD'] = {'type': 'integer', 'value': 1} + properties['propE'] = {'type': 'map', 'value': {'A': 'ValueA'}} properties_map = PropValueMap(properties) system_properties = {} system_properties['resourceId'] = {'type': 'string', 'value': '123'} @@ -106,6 +108,10 @@ def test_create_infrastructure_templates_with_properties(self): 'propA': 'A', 'propB': 'B', 'propC': 'C', + 'propD': '1', + 'propE': { + 'A': 'ValueA' + }, 'systemProperties': { 'resourceId': '123', 'resourceName': 'Resource-A', diff --git a/tests/unit/kegd/test_kegd_files/simple-deploy-objects/objects/simple.yaml b/tests/unit/kegd/test_kegd_files/simple-deploy-objects/objects/simple.yaml index 845faaf..7a56418 100644 --- a/tests/unit/kegd/test_kegd_files/simple-deploy-objects/objects/simple.yaml +++ b/tests/unit/kegd/test_kegd_files/simple-deploy-objects/objects/simple.yaml @@ -4,3 +4,4 @@ metadata: name: {{ system_properties.resource_subdomain }}-a data: propertyA: {{ propertyA }} + propertyB: "Include a number - {{ propertyB }}" diff --git a/tests/unit/kegd/test_manager.py b/tests/unit/kegd/test_manager.py index 58a1541..e498528 100644 --- a/tests/unit/kegd/test_manager.py +++ b/tests/unit/kegd/test_manager.py @@ -35,7 +35,8 @@ def generate_render_context(): 'resourceName': 'just-testing', } resource_properties = { - 'propertyA': 'A property' + 'propertyA': 'A property', + 'propertyB': 123 } request_properties = {} deployment_location = {} From 69415935c91c188f8ff740a6554398c1bc05ba17 Mon Sep 17 00:00:00 2001 From: Daniel Vaccaro-Senna Date: Wed, 9 Dec 2020 14:12:40 +0000 Subject: [PATCH 2/4] issue/29 ensure in/outputs retain type. Add tests --- docs/user-guide/extracting-outputs.md | 2 - kubedriver/keg/model/v1alpha1_keg.py | 5 +- .../output_extraction_handler.py | 2 +- ...1_keg_deployment_strategy_report_status.py | 2 +- .../output_extraction_result_holder.py | 2 +- kubedriver/kubeclient/os_api_ctl.py | 2 +- kubedriver/sandbox/sandbox.py | 3 +- tests/unit/infrastructure/test_driver.py | 14 -- .../test_kegd_files/check-inputs/kegd.yaml | 6 + .../check-inputs/objects/simple.yaml | 6 + .../check-inputs/scripts/outputs.py | 19 ++ .../test_kegd_files/return-outputs/kegd.yaml | 6 + .../return-outputs/objects/simple.yaml | 6 + .../return-outputs/scripts/outputs.py | 13 ++ tests/unit/kegd/test_processor.py | 206 ++++++++++++++++++ tests/utils/mem_persistence_mock.py | 52 +++-- 16 files changed, 306 insertions(+), 40 deletions(-) create mode 100644 tests/unit/kegd/test_kegd_files/check-inputs/kegd.yaml create mode 100644 tests/unit/kegd/test_kegd_files/check-inputs/objects/simple.yaml create mode 100644 tests/unit/kegd/test_kegd_files/check-inputs/scripts/outputs.py create mode 100644 tests/unit/kegd/test_kegd_files/return-outputs/kegd.yaml create mode 100644 tests/unit/kegd/test_kegd_files/return-outputs/objects/simple.yaml create mode 100644 tests/unit/kegd/test_kegd_files/return-outputs/scripts/outputs.py create mode 100644 tests/unit/kegd/test_processor.py diff --git a/docs/user-guide/extracting-outputs.md b/docs/user-guide/extracting-outputs.md index 04559ff..e476bde 100644 --- a/docs/user-guide/extracting-outputs.md +++ b/docs/user-guide/extracting-outputs.md @@ -101,8 +101,6 @@ To set the value of an output, use the `setOutput` (or `set_output`) function on resultBuilder.setOutput('propertyName', 'propertyValue') ``` -Any value passed to `setOutput` will be converted to a string (using the `str()` method). - To return a field from an object, first retrieve the object and then set the output: ```python diff --git a/kubedriver/keg/model/v1alpha1_keg.py b/kubedriver/keg/model/v1alpha1_keg.py index b8cc951..df2a174 100644 --- a/kubedriver/keg/model/v1alpha1_keg.py +++ b/kubedriver/keg/model/v1alpha1_keg.py @@ -23,7 +23,6 @@ def __init__(self, api_version=None, kind=None, metadata=None, status=None): self._api_version = None self._kind = None self._metadata = None - self._Status = None self._status = None if api_version is not None: self.api_version = api_version @@ -63,8 +62,8 @@ def status(self): return self._status @status.setter - def status(self, Status): - self._Status = Status + def status(self, status): + self._status = status def to_dict(self): return to_dict(self) diff --git a/kubedriver/kegd/action_handlers/output_extraction_handler.py b/kubedriver/kegd/action_handlers/output_extraction_handler.py index 07e4ddf..c8cc2e5 100644 --- a/kubedriver/kegd/action_handlers/output_extraction_handler.py +++ b/kubedriver/kegd/action_handlers/output_extraction_handler.py @@ -43,7 +43,7 @@ def handle(self, operation_name, keg_name, keg_status, location_context, output_ #Make a copy of the outputs so they are clean (in case the holder has been contaminated) outputs = {} for k, v in result_holder.outputs.items(): - outputs[k] = str(v) + outputs[k] = v return OutputExtractionResult.success(outputs) def __load_composition(self, keg_status, api_ctl, helm_client): diff --git a/kubedriver/kegd/model/v1alpha1_keg_deployment_strategy_report_status.py b/kubedriver/kegd/model/v1alpha1_keg_deployment_strategy_report_status.py index 27ef77d..839e3dd 100644 --- a/kubedriver/kegd/model/v1alpha1_keg_deployment_strategy_report_status.py +++ b/kubedriver/kegd/model/v1alpha1_keg_deployment_strategy_report_status.py @@ -12,7 +12,7 @@ class V1alpha1KegdStrategyReportStatus(object): 'state': 'str', 'phase': 'str', 'errors': 'list[str]', - 'outputs': 'dict(str, str)', + 'outputs': 'dict(str, object)', 'delta': 'V1alpha1KegdCompositionDelta' } diff --git a/kubedriver/kegd/scripting/output_extraction_result_holder.py b/kubedriver/kegd/scripting/output_extraction_result_holder.py index cbc0ed3..51ae919 100644 --- a/kubedriver/kegd/scripting/output_extraction_result_holder.py +++ b/kubedriver/kegd/scripting/output_extraction_result_holder.py @@ -21,7 +21,7 @@ def setOutput(self, output_name, output_value): self.set_output(output_name, output_value) def set_output(self, output_name, output_value): - self.outputs[output_name] = str(output_value) + self.outputs[output_name] = output_value def decode(self, encoded_value, encoding='utf-8'): if encoded_value == None: diff --git a/kubedriver/kubeclient/os_api_ctl.py b/kubedriver/kubeclient/os_api_ctl.py index 9a08578..8af93ff 100644 --- a/kubedriver/kubeclient/os_api_ctl.py +++ b/kubedriver/kubeclient/os_api_ctl.py @@ -11,7 +11,7 @@ def __init__(self, base_kube_client, default_namespace=DEFAULT_NAMESPACE): self.default_namespace = default_namespace def __get_resource_client(self, api_version, kind): - return self.dynamic_client.resources.get(api_version=api_version, kind=kind) + return self.dynamic_client.resources.get(api_version=api_version, kind=kind) def create_object(self, object_config, default_namespace=None): resource_client = self.__get_resource_client(object_config.api_version, object_config.kind) diff --git a/kubedriver/sandbox/sandbox.py b/kubedriver/sandbox/sandbox.py index e6646ca..ff9db16 100644 --- a/kubedriver/sandbox/sandbox.py +++ b/kubedriver/sandbox/sandbox.py @@ -1,6 +1,6 @@ import logging from RestrictedPython import compile_restricted_exec, safe_builtins -from RestrictedPython.Guards import guarded_unpack_sequence +from RestrictedPython.Guards import guarded_unpack_sequence, guarded_iter_unpack_sequence from RestrictedPython.Eval import default_guarded_getiter from RestrictedPython.PrintCollector import PrintCollector from .exceptions import CompileError, ExecuteError @@ -54,6 +54,7 @@ def run(self, script, file_name='', inputs=None): def __build_builtins(self): builtins = safe_builtins.copy() builtins['_unpack_sequence_'] = guarded_unpack_sequence + builtins['_iter_unpack_sequence_'] = guarded_iter_unpack_sequence builtins['_getiter_'] = default_guarded_getiter builtins['_getitem_'] = safer_getitem return builtins diff --git a/tests/unit/infrastructure/test_driver.py b/tests/unit/infrastructure/test_driver.py index 662e96b..af1b679 100644 --- a/tests/unit/infrastructure/test_driver.py +++ b/tests/unit/infrastructure/test_driver.py @@ -25,20 +25,6 @@ dataValue: A ''' -class ObjectConfigurationMatcher: - - def __init__(self, expected_conf): - self.expected_conf = expected_conf - - def __eq__(self, other): - return other.conf == self.expected_conf - - def __str__(self): - return str(self.expected_conf) - - def __repr__(self): - return f'{self.__class__.__name__}({self.expected_conf!r})' - class TestInfrastructureDriver():#unittest.TestCase): diff --git a/tests/unit/kegd/test_kegd_files/check-inputs/kegd.yaml b/tests/unit/kegd/test_kegd_files/check-inputs/kegd.yaml new file mode 100644 index 0000000..c79a9b2 --- /dev/null +++ b/tests/unit/kegd/test_kegd_files/check-inputs/kegd.yaml @@ -0,0 +1,6 @@ +compose: + - name: Create + deploy: + - objects: + file: simple.yaml + getOutputs: outputs.py \ No newline at end of file diff --git a/tests/unit/kegd/test_kegd_files/check-inputs/objects/simple.yaml b/tests/unit/kegd/test_kegd_files/check-inputs/objects/simple.yaml new file mode 100644 index 0000000..845faaf --- /dev/null +++ b/tests/unit/kegd/test_kegd_files/check-inputs/objects/simple.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ system_properties.resource_subdomain }}-a +data: + propertyA: {{ propertyA }} diff --git a/tests/unit/kegd/test_kegd_files/check-inputs/scripts/outputs.py b/tests/unit/kegd/test_kegd_files/check-inputs/scripts/outputs.py new file mode 100644 index 0000000..0c749af --- /dev/null +++ b/tests/unit/kegd/test_kegd_files/check-inputs/scripts/outputs.py @@ -0,0 +1,19 @@ +def getOutputs(keg, props, resultBuilder, log, *args, **kwargs): + resultBuilder.setOutput('string', props['string_input']) + resultBuilder.setOutput('integer', props['integer_input']) + resultBuilder.setOutput('float', props['float_input']) + resultBuilder.setOutput('timestamp', props['timestamp_input']) + resultBuilder.setOutput('boolean', props['boolean_input']) + resultBuilder.setOutput('map', props['map_input']) + for k,v in props['map_input'].items(): + resultBuilder.setOutput('map_' + k, v) + resultBuilder.setOutput('list', props['list_input']) + i = 0 + for v in props['list_input']: + resultBuilder.setOutput('list_' + str(i), v) + i = i + 1 + resultBuilder.setOutput('custom', props['custom_input']) + + + + \ No newline at end of file diff --git a/tests/unit/kegd/test_kegd_files/return-outputs/kegd.yaml b/tests/unit/kegd/test_kegd_files/return-outputs/kegd.yaml new file mode 100644 index 0000000..c79a9b2 --- /dev/null +++ b/tests/unit/kegd/test_kegd_files/return-outputs/kegd.yaml @@ -0,0 +1,6 @@ +compose: + - name: Create + deploy: + - objects: + file: simple.yaml + getOutputs: outputs.py \ No newline at end of file diff --git a/tests/unit/kegd/test_kegd_files/return-outputs/objects/simple.yaml b/tests/unit/kegd/test_kegd_files/return-outputs/objects/simple.yaml new file mode 100644 index 0000000..845faaf --- /dev/null +++ b/tests/unit/kegd/test_kegd_files/return-outputs/objects/simple.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ system_properties.resource_subdomain }}-a +data: + propertyA: {{ propertyA }} diff --git a/tests/unit/kegd/test_kegd_files/return-outputs/scripts/outputs.py b/tests/unit/kegd/test_kegd_files/return-outputs/scripts/outputs.py new file mode 100644 index 0000000..3d0a74a --- /dev/null +++ b/tests/unit/kegd/test_kegd_files/return-outputs/scripts/outputs.py @@ -0,0 +1,13 @@ +def getOutputs(keg, props, resultBuilder, log, *args, **kwargs): + resultBuilder.setOutput('string', 'A string') + resultBuilder.setOutput('integer', 123) + resultBuilder.setOutput('float', 1.23) + resultBuilder.setOutput('timestamp', '2020-11-24T11:49:33.305403Z') + resultBuilder.setOutput('boolean', True) + resultBuilder.setOutput('map', {'A': 1, 'B': 2}) + resultBuilder.setOutput('list', ['A', 'B']) + resultBuilder.setOutput('custom', {'name': 'Testing', 'age': 42}) + + + + \ No newline at end of file diff --git a/tests/unit/kegd/test_processor.py b/tests/unit/kegd/test_processor.py new file mode 100644 index 0000000..4ffc9fe --- /dev/null +++ b/tests/unit/kegd/test_processor.py @@ -0,0 +1,206 @@ +import unittest +import os +import kubedriver.kegd.model as kegd_model +import tests.unit.kegd.test_kegd_files as test_kegd_files +import inspect +import tests.utils as testutils +from unittest.mock import MagicMock +from ignition.service.templating import Jinja2TemplatingService +from kubedriver.resourcedriver import ExtendedResourceTemplateContext, NameManager +from kubedriver.kegd.manager import KegdStrategyLocationManager +from kubedriver.kegd.processor import KegdStrategyLocationProcessor +from kubedriver.kegd.properties import KegDeploymentProperties +from kubedriver.kegd.strategy_files import KegDeploymentStrategyFiles +from kubedriver.kegd.jobs import ProcessStrategyJob +from kubedriver.kegd.model.strategy_execution import StrategyExecution, TaskGroup + + +test_kegd_files_path = os.path.dirname(inspect.getfile(test_kegd_files)) + +def get_kegd_files(name): + path = os.path.join(test_kegd_files_path, name) + if not os.path.exists(path): + raise ValueError(f'Path does not exists: {path}') + return KegDeploymentStrategyFiles(os.path.join(test_kegd_files_path, name)) + +strategy_reader = kegd_model.DeploymentStrategyFileReader( + KegDeploymentProperties(), + None, + kegd_model.DeploymentStrategyParser() +) + +def parse_strategy(strategy_file): + return strategy_reader.read(strategy_file, {}) + +render_context_builder = ExtendedResourceTemplateContext(NameManager()) + +def generate_render_context(): + system_properties = { + 'resourceId': '123', + 'resourceName': 'just-testing', + } + resource_properties = { + 'propertyA': 'A property', + 'propertyB': 123 + } + request_properties = {} + deployment_location = {} + return render_context_builder.build(system_properties, resource_properties, request_properties, deployment_location) + +class TestKegdStrategyLocationProcessor(unittest.TestCase): + + def setUp(self): + self.kube_location = MagicMock(default_object_namespace='default', driver_namespace='driver') + self.templating = Jinja2TemplatingService() + self.keg_persister = testutils.mem_persistence_mock.create() + self.kegd_persister = testutils.mem_persistence_mock.create() + self.api_ctl = MagicMock() + self.context = MagicMock(kube_location=self.kube_location, keg_persister=self.keg_persister, kegd_persister=self.kegd_persister, api_ctl=self.api_ctl) + self.processor = KegdStrategyLocationProcessor(self.context, self.templating) + self.manager = KegdStrategyLocationManager(KegDeploymentProperties(), self.context, self.templating) + + def test_deploy_object(self): + render_context = generate_render_context() + keg_name = render_context['system_properties']['resourceName'] + kegd_files = get_kegd_files('simple-deploy-objects') + kegd_strategy = parse_strategy(kegd_files.get_strategy_file()) + job = self.manager.build_process_strategy_job( + keg_name=keg_name, + kegd_strategy=kegd_strategy, + operation_name='Create', + kegd_files=kegd_files, + render_context=render_context + ) + self.processor.handle_process_strategy_job(job) + # Check Keg created + keg_status = self.keg_persister.get(keg_name) + self.assertEqual(len(keg_status.composition.objects), 1) + object_status = keg_status.composition.objects[0] + self.assertEqual(object_status.group, 'v1') + self.assertEqual(object_status.kind, 'ConfigMap') + self.assertEqual(object_status.namespace, 'default') + self.assertEqual(object_status.name, render_context['system_properties']['resource_subdomain'] + '-a') + self.assertEqual(object_status.uid, self.api_ctl.create_object.return_value.metadata.uid) + self.assertEqual(object_status.state, 'Created') + self.assertEqual(object_status.error, None) + self.assertEqual(object_status.tags, { + 'DeployedOn': ['Create'] + }) + # Check Kegd + kegd_status = self.kegd_persister.get(job.request_id) + self.assertEqual(kegd_status.uid, job.request_id) + self.assertEqual(kegd_status.keg_name, keg_name) + self.assertEqual(kegd_status.operation, 'Create') + self.assertEqual(kegd_status.run_cleanup, False) + self.assertEqual(kegd_status.task_groups, ['Create']) + self.assertEqual(kegd_status.state, 'Complete') + self.assertEqual(kegd_status.phase, 'End') + self.assertEqual(kegd_status.errors, []) + self.assertEqual(kegd_status.outputs, None) + # Check object created + self.api_ctl.create_object.assert_called_once_with( + ObjectConfigurationMatcher({ + 'apiVersion': 'v1', + 'kind': 'ConfigMap', + 'metadata': { + 'name': 'just-testing-123-a', + 'labels': { + 'app.kubernetes.io/managed-by': 'kubedriver.alm', + 'keg.kubedriver.alm/keg': 'just-testing' + } + }, + 'data': { + 'propertyA': 'A property', + 'propertyB': 'Include a number - 123' + } + }) + ) + + def test_get_outputs(self): + render_context = generate_render_context() + render_context['string_input'] = 'A string input' + render_context['integer_input'] = 27 + render_context['float_input'] = 2.7 + render_context['boolean_input'] = False + render_context['timestamp_input'] = '2020-11-24T11:49:33.305403Z' + render_context['map_input'] = {'A': 'ValueA', 'B': 2} + render_context['list_input'] = ['A', 'B'] + render_context['custom_input'] = {'name': 'Testing', 'age': 42} + keg_name = render_context['system_properties']['resourceName'] + kegd_files = get_kegd_files('check-inputs') + kegd_strategy = parse_strategy(kegd_files.get_strategy_file()) + job = self.manager.build_process_strategy_job( + keg_name=keg_name, + kegd_strategy=kegd_strategy, + operation_name='Create', + kegd_files=kegd_files, + render_context=render_context + ) + self.api_ctl.safe_read_object.return_value = (True, MockObject({})) + self.processor.handle_process_strategy_job(job) + # Check Kegd + kegd_status = self.kegd_persister.get(job.request_id) + self.assertEqual(kegd_status.outputs, { + 'string': 'A string input', + 'integer': 27, + 'float': 2.7, + 'boolean': False, + 'timestamp': '2020-11-24T11:49:33.305403Z', + 'map': {'A': 'ValueA', 'B': 2}, + 'map_A': 'ValueA', + 'map_B': 2, + 'list': ['A', 'B'], + 'list_0': 'A', + 'list_1': 'B', + 'custom': {'name': 'Testing', 'age': 42} + }) + + + def test_property_inputs_to_scripts(self): + render_context = generate_render_context() + keg_name = render_context['system_properties']['resourceName'] + kegd_files = get_kegd_files('return-outputs') + kegd_strategy = parse_strategy(kegd_files.get_strategy_file()) + job = self.manager.build_process_strategy_job( + keg_name=keg_name, + kegd_strategy=kegd_strategy, + operation_name='Create', + kegd_files=kegd_files, + render_context=render_context + ) + self.api_ctl.safe_read_object.return_value = (True, MockObject({})) + self.processor.handle_process_strategy_job(job) + # Check Kegd + kegd_status = self.kegd_persister.get(job.request_id) + self.assertEqual(kegd_status.outputs, { + 'string': 'A string', + 'integer': 123, + 'float': 1.23, + 'boolean': True, + 'timestamp': '2020-11-24T11:49:33.305403Z', + 'map': {'A': 1, 'B': 2}, + 'list': ['A', 'B'], + 'custom': {'name': 'Testing', 'age': 42} + }) + +class MockObject: + + def __init__(self, data): + self.data = data + + def to_dict(self): + return self.data + +class ObjectConfigurationMatcher: + + def __init__(self, expected_data): + self.expected_data = expected_data + + def __eq__(self, other): + return other.data == self.expected_data + + def __str__(self): + return str(self.expected_data) + + def __repr__(self): + return f'{self.__class__.__name__}({self.expected_data!r})' diff --git a/tests/utils/mem_persistence_mock.py b/tests/utils/mem_persistence_mock.py index 92e46be..37cb467 100644 --- a/tests/utils/mem_persistence_mock.py +++ b/tests/utils/mem_persistence_mock.py @@ -1,5 +1,7 @@ import copy +import uuid from .copy_args_mock import CopyArgsMagicMock +from kubedriver.persistence.exceptions import RecordNotFoundError def create(): mock_persistence = CopyArgsMagicMock() @@ -11,27 +13,45 @@ class MemoryPersistenceWorker(): def __init__(self, *args, **kwargs): self.store = {} + self.uids = {} def bind_to(self, mock): mock.create.side_effect = self.create mock.get.side_effect = self.get mock.delete.side_effect = self.delete mock.update.side_effect = self.update - - def create(self, group_record): - self.store[group_record.uid] = copy.deepcopy(group_record) - - def get(self, uid): - if uid not in self.store: - raise ValueError('Mock persistence has not been configured with group with uid: {0}'.format(uid)) - return copy.deepcopy(self.store[uid]) - - def delete(self, uid): - if uid not in self.store: - raise ValueError('Mock persistence has not been configured with group with uid: {0}'.format(uid)) + mock.build_record_reference.side_effect = self.build_record_reference + mock.get_record_uid.side_effect = self.get_record_uid + + def build_record_reference(self, uid, record_name): + return { + 'apiVersion': 'v1', + 'kind': 'ConfigMap', + 'metadata': { + 'name': record_name, + 'namespace': 'mem', + 'uid': uid + } + } + + def get_record_uid(self, record_name): + return self.uids[record_name] + + def create(self, record_name, record_data, labels=None): + self.store[record_name] = copy.deepcopy(record_data) + self.uids[record_name] = str(uuid.uuid4()) + + def get(self, record_name): + if record_name not in self.store: + raise RecordNotFoundError('Mock persistence has not been configured with record_name: {0}'.format(record_name)) + return copy.deepcopy(self.store[record_name]) + + def delete(self, record_name): + if record_name not in self.store: + raise RecordNotFoundError('Mock persistence has not been configured with record_name: {0}'.format(record_name)) self.store.pop(uid) - def update(self, group_record): - if group_record.uid not in self.store: - raise ValueError('Mock persistence has not been configured with group with uid: {0}'.format(uid)) - self.store[group_record.uid] = copy.deepcopy(group_record) + def update(self, record_name, record_data): + if record_name not in self.store: + raise RecordNotFoundError('Mock persistence has not been configured with record_name: {0}'.format(record_name)) + self.store[record_name] = copy.deepcopy(record_data) From 4b1f3359511249aca5c4a00475568aee43340268 Mon Sep 17 00:00:00 2001 From: Daniel Vaccaro-Senna Date: Fri, 11 Dec 2020 18:54:37 +0000 Subject: [PATCH 3/4] Rename test method --- tests/unit/kegd/test_processor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/kegd/test_processor.py b/tests/unit/kegd/test_processor.py index 4ffc9fe..15acfb0 100644 --- a/tests/unit/kegd/test_processor.py +++ b/tests/unit/kegd/test_processor.py @@ -34,7 +34,7 @@ def parse_strategy(strategy_file): render_context_builder = ExtendedResourceTemplateContext(NameManager()) -def generate_render_context(): +def generate_base_render_context(): system_properties = { 'resourceId': '123', 'resourceName': 'just-testing', @@ -60,7 +60,7 @@ def setUp(self): self.manager = KegdStrategyLocationManager(KegDeploymentProperties(), self.context, self.templating) def test_deploy_object(self): - render_context = generate_render_context() + render_context = generate_base_render_context() keg_name = render_context['system_properties']['resourceName'] kegd_files = get_kegd_files('simple-deploy-objects') kegd_strategy = parse_strategy(kegd_files.get_strategy_file()) @@ -117,7 +117,7 @@ def test_deploy_object(self): ) def test_get_outputs(self): - render_context = generate_render_context() + render_context = generate_base_render_context() render_context['string_input'] = 'A string input' render_context['integer_input'] = 27 render_context['float_input'] = 2.7 @@ -157,7 +157,7 @@ def test_get_outputs(self): def test_property_inputs_to_scripts(self): - render_context = generate_render_context() + render_context = generate_base_render_context() keg_name = render_context['system_properties']['resourceName'] kegd_files = get_kegd_files('return-outputs') kegd_strategy = parse_strategy(kegd_files.get_strategy_file()) From 017e8349ddb42f90b7eb3439eaf69d241b40c663 Mon Sep 17 00:00:00 2001 From: Daniel Vaccaro-Senna Date: Fri, 11 Dec 2020 18:56:25 +0000 Subject: [PATCH 4/4] Correct test method names --- tests/unit/kegd/test_processor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/kegd/test_processor.py b/tests/unit/kegd/test_processor.py index 15acfb0..72c3a69 100644 --- a/tests/unit/kegd/test_processor.py +++ b/tests/unit/kegd/test_processor.py @@ -116,7 +116,7 @@ def test_deploy_object(self): }) ) - def test_get_outputs(self): + def test_property_inputs_to_scripts(self): render_context = generate_base_render_context() render_context['string_input'] = 'A string input' render_context['integer_input'] = 27 @@ -156,7 +156,7 @@ def test_get_outputs(self): }) - def test_property_inputs_to_scripts(self): + def test_return_outputs(self): render_context = generate_base_render_context() keg_name = render_context['system_properties']['resourceName'] kegd_files = get_kegd_files('return-outputs')