# Copyright 2013 Red Hat, 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. import datetime import iso8601 from oslo_utils import timeutils import six from oslo_versionedobjects import base as obj_base from oslo_versionedobjects import fields from oslo_versionedobjects import test class FakeFieldType(fields.FieldType): def coerce(self, obj, attr, value): return '*%s*' % value def to_primitive(self, obj, attr, value): return '!%s!' % value def from_primitive(self, obj, attr, value): return value[1:-1] class TestField(test.TestCase): def setUp(self): super(TestField, self).setUp() self.field = fields.Field(FakeFieldType()) self.coerce_good_values = [('foo', '*foo*')] self.coerce_bad_values = [] self.to_primitive_values = [('foo', '!foo!')] self.from_primitive_values = [('!foo!', 'foo')] def test_coerce_good_values(self): for in_val, out_val in self.coerce_good_values: self.assertEqual(out_val, self.field.coerce('obj', 'attr', in_val)) def test_coerce_bad_values(self): for in_val in self.coerce_bad_values: self.assertRaises((TypeError, ValueError), self.field.coerce, 'obj', 'attr', in_val) def test_to_primitive(self): for in_val, prim_val in self.to_primitive_values: self.assertEqual(prim_val, self.field.to_primitive('obj', 'attr', in_val)) def test_from_primitive(self): class ObjectLikeThing(object): _context = 'context' for prim_val, out_val in self.from_primitive_values: self.assertEqual(out_val, self.field.from_primitive( ObjectLikeThing, 'attr', prim_val)) def test_stringify(self): self.assertEqual('123', self.field.stringify(123)) class TestString(TestField): def setUp(self): super(TestField, self).setUp() self.field = fields.StringField() self.coerce_good_values = [ ('foo', 'foo'), (1, '1'), (1.0, '1.0'), (True, 'True')] if six.PY2: self.coerce_good_values += [(long(1), '1')] self.coerce_bad_values = [None] self.to_primitive_values = self.coerce_good_values[0:1] self.from_primitive_values = self.coerce_good_values[0:1] def test_stringify(self): self.assertEqual("'123'", self.field.stringify(123)) class TestInteger(TestField): def setUp(self): super(TestField, self).setUp() self.field = fields.IntegerField() self.coerce_good_values = [(1, 1), ('1', 1)] self.coerce_bad_values = ['foo', None] self.to_primitive_values = self.coerce_good_values[0:1] self.from_primitive_values = self.coerce_good_values[0:1] class TestFloat(TestField): def setUp(self): super(TestFloat, self).setUp() self.field = fields.FloatField() self.coerce_good_values = [(1.1, 1.1), ('1.1', 1.1)] self.coerce_bad_values = ['foo', None] self.to_primitive_values = self.coerce_good_values[0:1] self.from_primitive_values = self.coerce_good_values[0:1] class TestBoolean(TestField): def setUp(self): super(TestField, self).setUp() self.field = fields.BooleanField() self.coerce_good_values = [(True, True), (False, False), (1, True), ('foo', True), (0, False), ('', False)] self.coerce_bad_values = [] self.to_primitive_values = self.coerce_good_values[0:2] self.from_primitive_values = self.coerce_good_values[0:2] class TestDateTime(TestField): def setUp(self): super(TestDateTime, self).setUp() self.dt = datetime.datetime(1955, 11, 5, tzinfo=iso8601.iso8601.Utc()) self.field = fields.DateTimeField() self.coerce_good_values = [(self.dt, self.dt), (timeutils.isotime(self.dt), self.dt)] self.coerce_bad_values = [1, 'foo'] self.to_primitive_values = [(self.dt, timeutils.isotime(self.dt))] self.from_primitive_values = [(timeutils.isotime(self.dt), self.dt)] def test_stringify(self): self.assertEqual( '1955-11-05T18:00:00Z', self.field.stringify( datetime.datetime(1955, 11, 5, 18, 0, 0, tzinfo=iso8601.iso8601.Utc()))) class TestDateTimeNoTzinfo(TestField): def setUp(self): super(TestDateTimeNoTzinfo, self).setUp() self.dt = datetime.datetime(1955, 11, 5) self.field = fields.DateTimeField(tzinfo_aware=False) self.coerce_good_values = [(self.dt, self.dt), (timeutils.isotime(self.dt), self.dt)] self.coerce_bad_values = [1, 'foo'] self.to_primitive_values = [(self.dt, timeutils.isotime(self.dt))] self.from_primitive_values = [ ( timeutils.isotime(self.dt), self.dt, ) ] def test_stringify(self): self.assertEqual( '1955-11-05T18:00:00Z', self.field.stringify( datetime.datetime(1955, 11, 5, 18, 0, 0))) class TestDict(TestField): def setUp(self): super(TestDict, self).setUp() self.field = fields.Field(fields.Dict(FakeFieldType())) self.coerce_good_values = [({'foo': 'bar'}, {'foo': '*bar*'}), ({'foo': 1}, {'foo': '*1*'})] self.coerce_bad_values = [{1: 'bar'}, 'foo'] self.to_primitive_values = [({'foo': 'bar'}, {'foo': '!bar!'})] self.from_primitive_values = [({'foo': '!bar!'}, {'foo': 'bar'})] def test_stringify(self): self.assertEqual("{key=val}", self.field.stringify({'key': 'val'})) class TestDictOfStrings(TestField): def setUp(self): super(TestDictOfStrings, self).setUp() self.field = fields.DictOfStringsField() self.coerce_good_values = [({'foo': 'bar'}, {'foo': 'bar'}), ({'foo': 1}, {'foo': '1'})] self.coerce_bad_values = [{1: 'bar'}, {'foo': None}, 'foo'] self.to_primitive_values = [({'foo': 'bar'}, {'foo': 'bar'})] self.from_primitive_values = [({'foo': 'bar'}, {'foo': 'bar'})] def test_stringify(self): self.assertEqual("{key='val'}", self.field.stringify({'key': 'val'})) class TestDictOfIntegers(TestField): def setUp(self): super(TestDictOfIntegers, self).setUp() self.field = fields.DictOfIntegersField() self.coerce_good_values = [({'foo': '42'}, {'foo': 42}), ({'foo': 4.2}, {'foo': 4})] self.coerce_bad_values = [{1: 'bar'}, {'foo': 'boo'}, 'foo', {'foo': None}] self.to_primitive_values = [({'foo': 42}, {'foo': 42})] self.from_primitive_values = [({'foo': 42}, {'foo': 42})] def test_stringify(self): self.assertEqual("{key=42}", self.field.stringify({'key': 42})) class TestDictOfStringsNone(TestField): def setUp(self): super(TestDictOfStringsNone, self).setUp() self.field = fields.DictOfNullableStringsField() self.coerce_good_values = [({'foo': 'bar'}, {'foo': 'bar'}), ({'foo': 1}, {'foo': '1'}), ({'foo': None}, {'foo': None})] self.coerce_bad_values = [{1: 'bar'}, 'foo'] self.to_primitive_values = [({'foo': 'bar'}, {'foo': 'bar'})] self.from_primitive_values = [({'foo': 'bar'}, {'foo': 'bar'})] def test_stringify(self): self.assertEqual("{k2=None,key='val'}", self.field.stringify({'k2': None, 'key': 'val'})) class TestListOfDictOfNullableStringsField(TestField): def setUp(self): super(TestListOfDictOfNullableStringsField, self).setUp() self.field = fields.ListOfDictOfNullableStringsField() self.coerce_good_values = [([{'f': 'b', 'f1': 'b1'}, {'f2': 'b2'}], [{'f': 'b', 'f1': 'b1'}, {'f2': 'b2'}]), ([{'f': 1}, {'f1': 'b1'}], [{'f': '1'}, {'f1': 'b1'}]), ([{'foo': None}], [{'foo': None}])] self.coerce_bad_values = [[{1: 'a'}], ['ham', 1], ['eggs']] self.to_primitive_values = [([{'f': 'b'}, {'f1': 'b1'}, {'f2': None}], [{'f': 'b'}, {'f1': 'b1'}, {'f2': None}])] self.from_primitive_values = [([{'f': 'b'}, {'f1': 'b1'}, {'f2': None}], [{'f': 'b'}, {'f1': 'b1'}, {'f2': None}])] def test_stringify(self): self.assertEqual("[{f=None,f1='b1'},{f2='b2'}]", self.field.stringify( [{'f': None, 'f1': 'b1'}, {'f2': 'b2'}])) class TestList(TestField): def setUp(self): super(TestList, self).setUp() self.field = fields.Field(fields.List(FakeFieldType())) self.coerce_good_values = [(['foo', 'bar'], ['*foo*', '*bar*'])] self.coerce_bad_values = ['foo'] self.to_primitive_values = [(['foo'], ['!foo!'])] self.from_primitive_values = [(['!foo!'], ['foo'])] def test_stringify(self): self.assertEqual('[123]', self.field.stringify([123])) class TestListOfStrings(TestField): def setUp(self): super(TestListOfStrings, self).setUp() self.field = fields.ListOfStringsField() self.coerce_good_values = [(['foo', 'bar'], ['foo', 'bar'])] self.coerce_bad_values = ['foo'] self.to_primitive_values = [(['foo'], ['foo'])] self.from_primitive_values = [(['foo'], ['foo'])] def test_stringify(self): self.assertEqual("['abc']", self.field.stringify(['abc'])) class TestSet(TestField): def setUp(self): super(TestSet, self).setUp() self.field = fields.Field(fields.Set(FakeFieldType())) self.coerce_good_values = [(set(['foo', 'bar']), set(['*foo*', '*bar*']))] self.coerce_bad_values = [['foo'], {'foo': 'bar'}] self.to_primitive_values = [(set(['foo']), tuple(['!foo!']))] self.from_primitive_values = [(tuple(['!foo!']), set(['foo']))] def test_stringify(self): self.assertEqual('set([123])', self.field.stringify(set([123]))) class TestSetOfIntegers(TestField): def setUp(self): super(TestSetOfIntegers, self).setUp() self.field = fields.SetOfIntegersField() self.coerce_good_values = [(set(['1', 2]), set([1, 2]))] self.coerce_bad_values = [set(['foo'])] self.to_primitive_values = [(set([1]), tuple([1]))] self.from_primitive_values = [(tuple([1]), set([1]))] def test_stringify(self): self.assertEqual('set([1,2])', self.field.stringify(set([1, 2]))) class TestListOfSetsOfIntegers(TestField): def setUp(self): super(TestListOfSetsOfIntegers, self).setUp() self.field = fields.ListOfSetsOfIntegersField() self.coerce_good_values = [([set(['1', 2]), set([3, '4'])], [set([1, 2]), set([3, 4])])] self.coerce_bad_values = [[set(['foo'])]] self.to_primitive_values = [([set([1])], [tuple([1])])] self.from_primitive_values = [([tuple([1])], [set([1])])] def test_stringify(self): self.assertEqual('[set([1,2])]', self.field.stringify([set([1, 2])])) class TestObject(TestField): def setUp(self): super(TestObject, self).setUp() @obj_base.VersionedObjectRegistry.register class TestableObject(obj_base.VersionedObject): fields = { 'uuid': fields.StringField(), } def __eq__(self, value): # NOTE(danms): Be rather lax about this equality thing to # satisfy the assertEqual() in test_from_primitive(). We # just want to make sure the right type of object is re-created return value.__class__.__name__ == TestableObject.__name__ class OtherTestableObject(obj_base.VersionedObject): pass test_inst = TestableObject() self._test_cls = TestableObject self.field = fields.Field(fields.Object('TestableObject')) self.coerce_good_values = [(test_inst, test_inst)] self.coerce_bad_values = [OtherTestableObject(), 1, 'foo'] self.to_primitive_values = [(test_inst, test_inst.obj_to_primitive())] self.from_primitive_values = [(test_inst.obj_to_primitive(), test_inst), (test_inst, test_inst)] def test_stringify(self): obj = self._test_cls(uuid='fake-uuid') self.assertEqual('TestableObject(fake-uuid)', self.field.stringify(obj))