Fix serialisation of different HOT parameter types

This patch adds a custom wsme type which correctly handles the
serialisation of different parameter types found in Heat templates.

Change-Id: I8be67a52430adfe7327f387179fecb2bc40ec9ff
This commit is contained in:
Dougal Matthews 2014-08-21 17:18:56 +01:00 committed by Jay Dobies
parent f2000d43f0
commit e9f4f586a1
3 changed files with 71 additions and 3 deletions

View File

@ -20,11 +20,12 @@ the internal Tuskar domain model.
import datetime
import logging
import six
from wsme import types as wtypes
from tuskar.api.controllers.v2 import types as v2types
from tuskar.manager import models as manager_models
LOG = logging.getLogger(__name__)
@ -72,10 +73,10 @@ class PlanParameter(Base):
name = wtypes.text
label = wtypes.text
default = wtypes.text
default = v2types.MultiType(wtypes.text, six.integer_types, list, dict)
description = wtypes.text
hidden = bool
value = wtypes.text
value = v2types.MultiType(wtypes.text, six.integer_types, list, dict)
@classmethod
def from_tuskar_model(cls, param):

View File

@ -0,0 +1,40 @@
# 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 wsme
from wsme import types as wtypes
class MultiType(wtypes.UserType):
"""A complex type that represents one or more types.
Used for validating that a value is an instance of one of the types.
:param *types: Variable-length list of types.
"""
def __init__(self, *types):
self.types = types
def __str__(self):
return ' | '.join(map(str, self.types))
def validate(self, value):
for t in self.types:
if t is wsme.types.text and isinstance(value, wsme.types.bytes):
value = value.decode()
if isinstance(value, t):
return value
else:
raise ValueError(
_("Wrong type. Expected '%(type)s', got '%(value)s'")
% {'type': self.types, 'value': type(value)})

View File

@ -98,6 +98,33 @@ class PlansTests(base.TestCase):
mock_retrieve.assert_called_once_with('qwerty12345')
self.assertEqual(response.status_int, 404)
@mock.patch('tuskar.manager.plan.PlansManager.retrieve_plan')
def test_get_one_with_parameters(self, mock_retrieve):
# Setup
p = manager_models.DeploymentPlan('a', 'n', 'd')
p.add_parameters(
manager_models.PlanParameter(
name="Param 1", label="1", default=2, hidden=False,
description="1", value=1, param_type=int),
manager_models.PlanParameter(
name="Param 2", label="2", default=['a', ], hidden=False,
description="2", value=['a', 'b'], param_type=list),
manager_models.PlanParameter(
name="Param 3", label="3", default={'a': 2}, hidden=False,
description="3", value={'a': 1}, param_type=dict),
)
mock_retrieve.return_value = p
# Test
url = URL_PLANS + '/' + 'qwerty12345'
response = self.app.get(url)
result = response.json
# Verify
mock_retrieve.assert_called_once_with('qwerty12345')
self.assertEqual(response.status_int, 200)
self.assertEqual(result['name'], 'n')
@mock.patch('tuskar.manager.plan.PlansManager.delete_plan')
def test_delete(self, mock_delete):
# Test