Fix artifact init case.

In case artifact's field is defined to be
nullable=false and also doesn't have any
default, we had a problem:
While creating new artifact of this type
with a value for this field we got:

"BadRequest <artifact_name> field: <field_name>.
value: [None]. Exception.

That happened although a field value was provided.
This kind of error is expected if the field does
not get any value at creation, but not expected
if value is provided.

The following patch suggest a fix for that.
closes-bug: #1775502

Change-Id: I642249f067ab853b4b7d56a8da4db5809ee414c6
This commit is contained in:
idanaroz 2018-05-30 07:39:09 -06:00 committed by Idan Narotzki
parent c73fe300f5
commit f7387cbcf6
5 changed files with 77 additions and 3 deletions

View File

@ -239,6 +239,9 @@ class Engine(object):
'created_at': timeutils.utcnow(),
'updated_at': timeutils.utcnow()
}
for k, v in values.items():
init_values[k] = v
af = artifact_type.init_artifact(context, init_values)
# acquire scoped lock and execute artifact create
with self._create_scoped_lock(context, type_name, af.name,

View File

@ -0,0 +1,56 @@
# Copyright (c) 2016 Mirantis, Inc.
#
# 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.
from oslo_versionedobjects import fields
from glare.objects import base as base_artifact
from glare.objects.meta import wrappers
Field = wrappers.Field.init
Dict = wrappers.DictField.init
List = wrappers.ListField.init
Blob = wrappers.BlobField.init
Folder = wrappers.FolderField.init
class NonNullableFieldsArtifact(base_artifact.BaseArtifact):
"""For testing purposes: check the case of creating artifact that
has nullable=false field without any default
"""
fields = {
'int_not_nullable_with_default': Field(fields.IntegerField,
nullable=False, default=0,
required_on_activate=False),
'int_not_nullable_without_default': Field(fields.IntegerField,
nullable=False)
}
@classmethod
def get_type_name(cls):
return "non_nullable_fields_artifact"
@classmethod
def get_display_type_name(cls):
return "not Nullable Fields Artifact"
def to_dict(self):
res = self.obj_to_primitive()['versioned_object.data']
res['__some_meta_information__'] = res['name'].upper()
return res
@classmethod
def format_all(cls, values):
values['__some_meta_information__'] = values['name'].upper()
return values

View File

@ -150,6 +150,18 @@ class TestArtifactCreate(base.BaseTestArtifactAPI):
self.assertRaises(exc.BadRequest, self.controller.create,
self.req, 'sample_artifact', values)
def test_create_artifact_with_nullable_false_field(self):
values = {'name': 'art1', 'int_not_nullable_without_default': 1}
res = self.controller.create(self.req,
'non_nullable_fields_artifact', values)
self.assertEqual(1, res['int_not_nullable_without_default'])
self.assertEqual(0, res['int_not_nullable_with_default'])
values = {'name': 'art2'}
self.assertRaises(exc.BadRequest, self.controller.create,
self.req, 'non_nullable_fields_artifact', values)
def test_create_artifact_blob(self):
values = {'name': 'test', 'blob': 'DATA'}
self.assertRaises(exc.BadRequest, self.controller.create,

View File

@ -80,10 +80,12 @@ class BaseTestCase(testtools.TestCase):
custom_artifact_types_modules=[
'glare.tests.sample_artifact',
'glare.tests.hooks_artifact',
'glare.tests.unpacking_artifact'
'glare.tests.unpacking_artifact',
'glare.tests.non_nullable_fields_artifact'
],
enabled_artifact_types=[
'unpacking_artifact', 'hooks_artifact', 'sample_artifact',
'non_nullable_fields_artifact', 'unpacking_artifact',
'hooks_artifact', 'sample_artifact',
'images', 'heat_templates', 'heat_environments',
'murano_packages', 'tosca_templates']
)

View File

@ -27,7 +27,8 @@ class TestMultistore(base.BaseTestCase):
'murano_packages': 'vsphere',
'sample_artifact': 'database',
'hooks_artifact': 'database',
'unpacking_artifact': 'database'}
'unpacking_artifact': 'database',
'non_nullable_fields_artifact': 'database'}
# create engine and register new artifact types
engine.Engine()