Add the ObjectDefaults structure

This change adds the ObjectDefaults structure, a KMIP 2.0 addition
that is used to specify default attribute values for KMIP managed
objects. A unit test suite is included to cover the new structure.
This commit is contained in:
Peter Hamilton 2019-04-09 09:43:02 -04:00 committed by Peter Hamilton
parent 790abc85cb
commit dae68f7e46
2 changed files with 833 additions and 0 deletions

View File

@ -39,6 +39,7 @@ from kmip.core.primitives import ByteString
from kmip.core.primitives import Integer from kmip.core.primitives import Integer
from kmip.core.primitives import Enumeration from kmip.core.primitives import Enumeration
from kmip.core import utils
from kmip.core.utils import BytearrayStream from kmip.core.utils import BytearrayStream
@ -3628,3 +3629,214 @@ class RevocationReason(Struct):
if not isinstance(self.revocation_message, TextString): if not isinstance(self.revocation_message, TextString):
msg = "TextString expect" msg = "TextString expect"
raise TypeError(msg) raise TypeError(msg)
class ObjectDefaults(primitives.Struct):
"""
A structure containing default object values used by the server.
This is intended for use with KMIP 2.0+.
Attributes:
object_type: An ObjectType enumeration identifying the type to which
the defaults pertain.
attributes: An Attributes structure containing attribute values that
are defaults for an object type.
"""
def __init__(self, object_type=None, attributes=None):
"""
Construct an ObjectDefaults structure.
Args:
object_type (enum): An ObjectType enumeration identifying the type
to which the defaults pertain. Optional, defaults to None.
Required for read/write.
attributes (structure): An Attributes structure containing
attribute values that are defaults for an object type.
Optional, defaults to None. Required for read/write.
"""
super(ObjectDefaults, self).__init__(tag=enums.Tags.OBJECT_DEFAULTS)
self._object_type = None
self._attributes = None
self.object_type = object_type
self.attributes = attributes
@property
def object_type(self):
if self._object_type:
return self._object_type.value
else:
return None
@object_type.setter
def object_type(self, value):
if value is None:
self._object_type = None
elif isinstance(value, enums.ObjectType):
self._object_type = primitives.Enumeration(
enums.ObjectType,
value=value,
tag=enums.Tags.OBJECT_TYPE
)
else:
raise TypeError("Object type must be an ObjectType enumeration.")
@property
def attributes(self):
return self._attributes
@attributes.setter
def attributes(self, value):
if value is None:
self._attributes = None
elif isinstance(value, Attributes):
self._attributes = value
else:
raise TypeError("Attributes must be an Attributes structure.")
def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_2_0):
"""
Read the data encoding the ObjectDefaults structure and decode it into
its constituent parts.
Args:
input_buffer (stream): A data stream containing encoded object
data, supporting a read method; usually a BytearrayStream
object.
kmip_version (KMIPVersion): An enumeration defining the KMIP
version with which the object will be decoded. Optional,
defaults to KMIP 2.0.
Raises:
InvalidKmipEncoding: Raised if the object type or attributes are
missing from the encoding.
VersionNotSupported: Raised when a KMIP version is provided that
does not support the ObjectDefaults structure.
"""
if kmip_version < enums.KMIPVersion.KMIP_2_0:
raise exceptions.VersionNotSupported(
"KMIP {} does not support the ObjectDefaults object.".format(
kmip_version.value
)
)
super(ObjectDefaults, self).read(
input_buffer,
kmip_version=kmip_version
)
local_buffer = utils.BytearrayStream(input_buffer.read(self.length))
if self.is_tag_next(enums.Tags.OBJECT_TYPE, local_buffer):
self._object_type = primitives.Enumeration(
enums.ObjectType,
tag=enums.Tags.OBJECT_TYPE
)
self._object_type.read(local_buffer, kmip_version=kmip_version)
else:
raise exceptions.InvalidKmipEncoding(
"The ObjectDefaults encoding is missing the object type "
"enumeration."
)
if self.is_tag_next(enums.Tags.ATTRIBUTES, local_buffer):
self._attributes = Attributes()
self._attributes.read(local_buffer, kmip_version=kmip_version)
else:
raise exceptions.InvalidKmipEncoding(
"The ObjectDefaults encoding is missing the attributes "
"structure."
)
self.is_oversized(local_buffer)
def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_2_0):
"""
Write the ObjectDefaults structure encoding to the data stream.
Args:
output_buffer (stream): A data stream in which to encode
Attributes structure data, supporting a write method.
kmip_version (enum): A KMIPVersion enumeration defining the KMIP
version with which the object will be encoded. Optional,
defaults to KMIP 2.0.
Raises:
InvalidField: Raised if the object type or attributes fields are
not defined.
VersionNotSupported: Raised when a KMIP version is provided that
does not support the ObjectDefaults structure.
"""
if kmip_version < enums.KMIPVersion.KMIP_2_0:
raise exceptions.VersionNotSupported(
"KMIP {} does not support the ObjectDefaults object.".format(
kmip_version.value
)
)
local_buffer = BytearrayStream()
if self._object_type:
self._object_type.write(local_buffer, kmip_version=kmip_version)
else:
raise exceptions.InvalidField(
"The ObjectDefaults structure is missing the object type "
"field."
)
if self._attributes:
self._attributes.write(local_buffer, kmip_version=kmip_version)
else:
raise exceptions.InvalidField(
"The ObjectDefaults structure is missing the attributes field."
)
self.length = local_buffer.length()
super(ObjectDefaults, self).write(
output_buffer,
kmip_version=kmip_version
)
output_buffer.write(local_buffer.buffer)
def __repr__(self):
o = "object_type={}".format(
'{}'.format(
self.object_type
) if self.object_type else None
)
a = "attributes={}".format(
'{}'.format(repr(self.attributes)) if self.attributes else None
)
values = ", ".join([o, a])
return "ObjectDefaults({})".format(values)
def __str__(self):
o = '"object_type": {}'.format(
"{}".format(
self.object_type
) if self.object_type else None
)
a = '"attributes": {}'.format(
"{}".format(str(self.attributes)) if self.attributes else None
)
values = ", ".join([o, a])
return '{' + values + '}'
def __eq__(self, other):
if isinstance(other, ObjectDefaults):
if self.object_type != other.object_type:
return False
elif self.attributes != other.attributes:
return False
else:
return True
else:
return NotImplemented
def __ne__(self, other):
if isinstance(other, ObjectDefaults):
return not (self == other)
else:
return NotImplemented

View File

@ -4522,3 +4522,624 @@ class TestKeyWrappingSpecification(testtools.TestCase):
observed = str(key_wrapping_specification) observed = str(key_wrapping_specification)
self.assertEqual(expected, observed) self.assertEqual(expected, observed)
class TestObjectDefaults(testtools.TestCase):
def setUp(self):
super(TestObjectDefaults, self).setUp()
# This encoding matches the following set of values:
#
# ObjectDefaults
# Object Type - Symmetric Key
# Attributes
# Cryptographic Algorithm - AES
# Cryptographic Length - 128
# Cryptographic Usage Mask - Encrypt | Decrypt
self.full_encoding = utils.BytearrayStream(
b'\x42\x01\x53\x01\x00\x00\x00\x48'
b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00'
b'\x42\x01\x25\x01\x00\x00\x00\x30'
b'\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00'
b'\x42\x00\x2A\x02\x00\x00\x00\x04\x00\x00\x00\x80\x00\x00\x00\x00'
b'\x42\x00\x2C\x02\x00\x00\x00\x04\x00\x00\x00\x0C\x00\x00\x00\x00'
)
# This encoding matches the following set of values:
#
# ObjectDefaults
# Attributes
# Cryptographic Algorithm - AES
# Cryptographic Length - 128
# Cryptographic Usage Mask - Encrypt | Decrypt
self.no_object_type_encoding = utils.BytearrayStream(
b'\x42\x01\x53\x01\x00\x00\x00\x38'
b'\x42\x01\x25\x01\x00\x00\x00\x30'
b'\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00'
b'\x42\x00\x2A\x02\x00\x00\x00\x04\x00\x00\x00\x80\x00\x00\x00\x00'
b'\x42\x00\x2C\x02\x00\x00\x00\x04\x00\x00\x00\x0C\x00\x00\x00\x00'
)
# This encoding matches the following set of values:
#
# ObjectDefaults
# Object Type - Symmetric Key
self.no_attributes_encoding = utils.BytearrayStream(
b'\x42\x01\x53\x01\x00\x00\x00\x10'
b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00'
)
def tearDown(self):
super(TestObjectDefaults, self).tearDown()
def test_invalid_object_type(self):
"""
Test that a TypeError is raised when an invalid value is used to set
the object type of an ObjectDefaults structure.
"""
kwargs = {"object_type": 0}
self.assertRaisesRegex(
TypeError,
"Object type must be an ObjectType enumeration.",
objects.ObjectDefaults,
**kwargs
)
args = (objects.ObjectDefaults(), "object_type", 0)
self.assertRaisesRegex(
TypeError,
"Object type must be an ObjectType enumeration.",
setattr,
*args
)
def test_invalid_attributes(self):
"""
Test that a TypeError is raised when an invalid value is used to set
the attributes of an ObjectDefaults structure.
"""
kwargs = {"attributes": 0}
self.assertRaisesRegex(
TypeError,
"Attributes must be an Attributes structure.",
objects.ObjectDefaults,
**kwargs
)
args = (objects.ObjectDefaults(), "attributes", 0)
self.assertRaisesRegex(
TypeError,
"Attributes must be an Attributes structure.",
setattr,
*args
)
def test_read(self):
"""
Test that an ObjectDefaults structure can be correctly read in from a
data stream.
"""
object_defaults = objects.ObjectDefaults()
self.assertIsNone(object_defaults.object_type)
self.assertIsNone(object_defaults.attributes)
object_defaults.read(
self.full_encoding,
kmip_version=enums.KMIPVersion.KMIP_2_0
)
self.assertEqual(
enums.ObjectType.SYMMETRIC_KEY,
object_defaults.object_type
)
self.assertEqual(
objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
),
object_defaults.attributes
)
def test_read_unsupported_kmip_version(self):
"""
Test that a VersionNotSupported error is raised during the decoding of
an ObjectDefaults structure when the structure is read for an
unsupported KMIP version.
"""
object_defaults = objects.ObjectDefaults()
args = (self.full_encoding, )
kwargs = {"kmip_version": enums.KMIPVersion.KMIP_1_4}
self.assertRaisesRegex(
exceptions.VersionNotSupported,
"KMIP 1.4 does not support the ObjectDefaults object.",
object_defaults.read,
*args,
**kwargs
)
def test_read_missing_object_type(self):
"""
Test that an InvalidKmipEncoding error is raised during the decoding
of an ObjectDefaults structure when the object type is missing from
the encoding.
"""
object_defaults = objects.ObjectDefaults()
self.assertIsNone(object_defaults.object_type)
args = (self.no_object_type_encoding, )
self.assertRaisesRegex(
exceptions.InvalidKmipEncoding,
"The ObjectDefaults encoding is missing the object type "
"enumeration.",
object_defaults.read,
*args
)
def test_read_missing_attributes(self):
"""
Test that an InvalidKmipEncoding error is raised during the decoding
of an ObjectDefaults structure when the attributes structure is missing
from the encoding.
"""
object_defaults = objects.ObjectDefaults()
self.assertIsNone(object_defaults.attributes)
args = (self.no_attributes_encoding, )
self.assertRaisesRegex(
exceptions.InvalidKmipEncoding,
"The ObjectDefaults encoding is missing the attributes structure.",
object_defaults.read,
*args
)
def test_write(self):
"""
Test that an ObjectDefaults structure can be written to a data stream.
"""
object_defaults = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
buffer = utils.BytearrayStream()
object_defaults.write(buffer, kmip_version=enums.KMIPVersion.KMIP_2_0)
self.assertEqual(len(self.full_encoding), len(buffer))
self.assertEqual(str(self.full_encoding), str(buffer))
def test_write_unsupported_kmip_version(self):
"""
Test that a VersionNotSupported error is raised during the encoding of
an ObjectDefaults structure when the structure is written for an
unsupported KMIP version.
"""
object_defaults = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
args = (utils.BytearrayStream(), )
kwargs = {"kmip_version": enums.KMIPVersion.KMIP_1_4}
self.assertRaisesRegex(
exceptions.VersionNotSupported,
"KMIP 1.4 does not support the ObjectDefaults object.",
object_defaults.write,
*args,
**kwargs
)
def test_write_missing_object_type(self):
"""
Test that an InvalidField error is raised during the encoding of an
ObjectDefaults structure when the structure is missing the object
type field.
"""
object_defaults = objects.ObjectDefaults(
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
args = (utils.BytearrayStream(), )
self.assertRaisesRegex(
exceptions.InvalidField,
"The ObjectDefaults structure is missing the object type field.",
object_defaults.write,
*args
)
def test_write_missing_attributes(self):
"""
Test that an InvalidField error is raised during the encoding of an
ObjectDefaults structure when the structure is missing the attributes
field.
"""
object_defaults = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY
)
args = (utils.BytearrayStream(), )
self.assertRaisesRegex(
exceptions.InvalidField,
"The ObjectDefaults structure is missing the attributes field.",
object_defaults.write,
*args
)
def test_repr(self):
"""
Test that repr can be applied to an ObjectDefaults structure.
"""
object_defaults = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
o = "object_type=ObjectType.SYMMETRIC_KEY"
a1e = "enum=CryptographicAlgorithm"
a1v = "value=CryptographicAlgorithm.AES"
a1t = "tag=Tags.CRYPTOGRAPHIC_ALGORITHM"
a1a = ", ".join([a1e, a1v, a1t])
a1 = "Enumeration({})".format(a1a)
a2 = "Integer(value=128)"
a3 = "Integer(value=12)"
aa = ", ".join([a1, a2, a3])
t = "tag=Tags.ATTRIBUTES"
a = "attributes=Attributes(attributes=[{}], {})".format(aa, t)
r = "ObjectDefaults({}, {})".format(o, a)
self.assertEqual(r, repr(object_defaults))
def test_str(self):
"""
Test that str can be applied to an ObjectDefaults structure.
"""
object_defaults = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
o = '"object_type": ObjectType.SYMMETRIC_KEY'
aa = '{"attributes": [CryptographicAlgorithm.AES, 128, 12]}'
a = '"attributes": {}'.format(aa)
r = "{" + "{}, {}".format(o, a) + "}"
self.assertEqual(r, str(object_defaults))
def test_equal_on_equal(self):
"""
Test that the equality operator returns True when comparing two
ObjectDefaults structures with the same data.
"""
a = objects.ObjectDefaults()
b = objects.ObjectDefaults()
self.assertTrue(a == b)
self.assertTrue(b == a)
a = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
b = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
self.assertTrue(a == b)
self.assertTrue(b == a)
def test_equal_on_not_equal_object_type(self):
"""
Test that the equality operator returns False when comparing two
ObjectDefaults structures with different object type fields.
"""
a = objects.ObjectDefaults(object_type=enums.ObjectType.SYMMETRIC_KEY)
b = objects.ObjectDefaults(object_type=enums.ObjectType.PUBLIC_KEY)
self.assertFalse(a == b)
self.assertFalse(b == a)
def test_equal_on_not_equal_attributes(self):
"""
Test that the equality operator returns False when comparing two
ObjectDefaults structures with different attributes fields.
"""
a = objects.ObjectDefaults(
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
)
]
)
)
b = objects.ObjectDefaults(
attributes=objects.Attributes(
attributes=[
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
)
]
)
)
self.assertFalse(a == b)
self.assertFalse(b == a)
def test_equal_on_type_mismatch(self):
"""
Test that the equality operator returns False when comparing two
ObjectDefaults structures with different types.
"""
a = objects.ObjectDefaults()
b = "invalid"
self.assertFalse(a == b)
self.assertFalse(b == a)
def test_not_equal_on_equal(self):
"""
Test that the inequality operator returns False when comparing two
ObjectDefaults structures with the same data.
"""
a = objects.ObjectDefaults()
b = objects.ObjectDefaults()
self.assertFalse(a != b)
self.assertFalse(b != a)
a = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
b = objects.ObjectDefaults(
object_type=enums.ObjectType.SYMMETRIC_KEY,
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
),
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
),
primitives.Integer(
value=(
enums.CryptographicUsageMask.ENCRYPT.value |
enums.CryptographicUsageMask.DECRYPT.value
),
tag=enums.Tags.CRYPTOGRAPHIC_USAGE_MASK
)
]
)
)
self.assertFalse(a != b)
self.assertFalse(b != a)
def test_not_equal_on_not_equal_object_type(self):
"""
Test that the inequality operator returns True when comparing two
ObjectDefaults structures with different object type fields.
"""
a = objects.ObjectDefaults(object_type=enums.ObjectType.SYMMETRIC_KEY)
b = objects.ObjectDefaults(object_type=enums.ObjectType.PUBLIC_KEY)
self.assertTrue(a != b)
self.assertTrue(b != a)
def test_not_equal_on_not_equal_attributes(self):
"""
Test that the inequality operator returns True when comparing two
ObjectDefaults structures with different attributes fields.
"""
a = objects.ObjectDefaults(
attributes=objects.Attributes(
attributes=[
primitives.Enumeration(
enums.CryptographicAlgorithm,
value=enums.CryptographicAlgorithm.AES,
tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM
)
]
)
)
b = objects.ObjectDefaults(
attributes=objects.Attributes(
attributes=[
primitives.Integer(
value=128,
tag=enums.Tags.CRYPTOGRAPHIC_LENGTH
)
]
)
)
self.assertTrue(a != b)
self.assertTrue(b != a)
def test_not_equal_on_type_mismatch(self):
"""
Test that the inequality operator returns True when comparing two
ObjectDefaults structures with different types.
"""
a = objects.ObjectDefaults()
b = "invalid"
self.assertTrue(a != b)
self.assertTrue(b != a)