diff --git a/blazarclient/exception.py b/blazarclient/exception.py index 9dd5968..8aa8791 100644 --- a/blazarclient/exception.py +++ b/blazarclient/exception.py @@ -76,3 +76,9 @@ class IncorrectLease(BlazarClientException): """Occurs if lease parameters are incorrect.""" message = _("The lease parameters are incorrect.") code = 409 + + +class DuplicatedLeaseParameters(BlazarClientException): + """Occurs if lease parameters are duplicated.""" + message = _("The lease parameters are duplicated.") + code = 400 diff --git a/blazarclient/tests/v1/__init__.py b/blazarclient/tests/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blazarclient/tests/v1/shell_commands/__init__.py b/blazarclient/tests/v1/shell_commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blazarclient/tests/v1/shell_commands/test_leases.py b/blazarclient/tests/v1/shell_commands/test_leases.py new file mode 100644 index 0000000..2ba7a06 --- /dev/null +++ b/blazarclient/tests/v1/shell_commands/test_leases.py @@ -0,0 +1,110 @@ +# Copyright (c) 2017 NTT Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import mock + +from blazarclient import exception +from blazarclient import shell +from blazarclient import tests +from blazarclient.v1.shell_commands import leases + + +class CreateLeaseTestCase(tests.TestCase): + + def setUp(self): + super(CreateLeaseTestCase, self).setUp() + self.cl = leases.CreateLease(shell.BlazarShell(), mock.Mock()) + + def test_args2body_correct_phys_res_params(self): + args = argparse.Namespace( + start='2020-07-24 20:00', + end='2020-08-09 22:30', + events=[], + name='lease-test', + reservations=[], + physical_reservations=[ + 'min=1,' + 'max=2,' + 'hypervisor_properties=' + '["and", [">=", "$vcpus", "2"], ' + '[">=", "$memory_mb", "2048"]],' + 'resource_properties=' + '["==", "$extra_key", "extra_value"]' + ] + ) + expected = { + 'start': '2020-07-24 20:00', + 'end': '2020-08-09 22:30', + 'events': [], + 'name': 'lease-test', + 'reservations': [ + { + 'min': '1', + 'max': '2', + 'hypervisor_properties': + '["and", [">=", "$vcpus", "2"], ' + '[">=", "$memory_mb", "2048"]]', + 'resource_properties': + '["==", "$extra_key", "extra_value"]', + 'resource_type': 'physical:host' + } + ] + } + self.assertDictEqual(self.cl.args2body(args), expected) + + def test_args2body_incorrect_phys_res_params(self): + args = argparse.Namespace( + start='2020-07-24 20:00', + end='2020-08-09 22:30', + events=[], + name='lease-test', + reservations=[], + physical_reservations=[ + 'incorrect_param=1,' + 'min=1,' + 'max=2,' + 'hypervisor_properties=' + '["and", [">=", "$vcpus", "2"], ' + '[">=", "$memory_mb", "2048"]],' + 'resource_properties=' + '["==", "$extra_key", "extra_value"]' + ] + ) + self.assertRaises(exception.IncorrectLease, + self.cl.args2body, + args) + + def test_args2body_duplicated_phys_res_params(self): + args = argparse.Namespace( + start='2020-07-24 20:00', + end='2020-08-09 22:30', + events=[], + name='lease-test', + reservations=[], + physical_reservations=[ + 'min=1,' + 'min=1,' + 'max=2,' + 'hypervisor_properties=' + '["and", [">=", "$vcpus", "2"], ' + '[">=", "$memory_mb", "2048"]],' + 'resource_properties=' + '["==", "$extra_key", "extra_value"]' + ] + ) + self.assertRaises(exception.DuplicatedLeaseParameters, + self.cl.args2body, + args) diff --git a/blazarclient/v1/shell_commands/leases.py b/blazarclient/v1/shell_commands/leases.py index 6f6c0b4..fe0be29 100644 --- a/blazarclient/v1/shell_commands/leases.py +++ b/blazarclient/v1/shell_commands/leases.py @@ -144,19 +144,22 @@ class CreateLease(command.CreateCommand): % phys_res_str) phys_res_info = {"min": "", "max": "", "hypervisor_properties": "", "resource_properties": ""} - prog = re.compile('^(\w+)=(\w+|\[[^]]+\])(?:,(.+))?$') + prog = re.compile('^(?:(.*),)?(%s)=(.*)$' + % "|".join(phys_res_info.keys())) def parse_params(params): match = prog.search(params) if match: self.log.info("Matches: %s", match.groups()) - k, v = match.group(1, 2) - if k in phys_res_info: + k, v = match.group(2, 3) + if not phys_res_info[k]: phys_res_info[k] = v else: - raise exception.IncorrectLease(err_msg) - if len(match.groups()) == 3 and match.group(3) is not None: - parse_params(match.group(3)) + raise exception.DuplicatedLeaseParameters(err_msg) + if match.group(1) is not None: + parse_params(match.group(1)) + else: + raise exception.IncorrectLease(err_msg) parse_params(phys_res_str) if not (phys_res_info['min'] and phys_res_info['max']):