diff --git a/kmip/core/messages/payloads/get_attribute_list.py b/kmip/core/messages/payloads/get_attribute_list.py index d7de060..c1eff8e 100644 --- a/kmip/core/messages/payloads/get_attribute_list.py +++ b/kmip/core/messages/payloads/get_attribute_list.py @@ -16,6 +16,7 @@ import six from kmip.core import enums +from kmip.core import exceptions from kmip.core import primitives from kmip.core import utils @@ -66,59 +67,67 @@ class GetAttributeListRequestPayload(primitives.Struct): tag=enums.Tags.UNIQUE_IDENTIFIER ) else: - raise TypeError("unique identifier must be a string") + raise TypeError("Unique identifier must be a string.") - def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): + def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the GetAttributeList request payload and decode it into its constituent parts. Args: - istream (stream): A data stream containing encoded object data, - supporting a read method; usually a BytearrayStream object. + 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 1.0. """ super(GetAttributeListRequestPayload, self).read( - istream, + input_buffer, kmip_version=kmip_version ) - tstream = utils.BytearrayStream(istream.read(self.length)) + local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) - if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, tstream): + if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_buffer): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER ) - self._unique_identifier.read(tstream, kmip_version=kmip_version) + self._unique_identifier.read( + local_buffer, + kmip_version=kmip_version + ) else: self._unique_identifier = None - self.is_oversized(tstream) + self.is_oversized(local_buffer) - def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): + def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Write the data encoding the GetAttributeList request payload to a stream. Args: - ostream (stream): A data stream in which to encode object data, - supporting a write method; usually a BytearrayStream object. + output_buffer (stream): A data stream in which to encode object + data, supporting a write method; usually a BytearrayStream + object. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be encoded. Optional, defaults to KMIP 1.0. """ - tstream = utils.BytearrayStream() + local_buffer = utils.BytearrayStream() if self._unique_identifier: - self._unique_identifier.write(tstream, kmip_version=kmip_version) + self._unique_identifier.write( + local_buffer, + kmip_version=kmip_version + ) - self.length = tstream.length() + self.length = local_buffer.length() super(GetAttributeListRequestPayload, self).write( - ostream, + output_buffer, kmip_version=kmip_version ) - ostream.write(tstream.buffer) + output_buffer.write(local_buffer.buffer) def __repr__(self): uid = "unique_identifier={0}".format(self.unique_identifier) @@ -199,7 +208,7 @@ class GetAttributeListResponsePayload(primitives.Struct): tag=enums.Tags.UNIQUE_IDENTIFIER ) else: - raise TypeError("unique identifier must be a string") + raise TypeError("Unique identifier must be a string.") @property def attribute_names(self): @@ -221,7 +230,7 @@ class GetAttributeListResponsePayload(primitives.Struct): name = value[i] if not isinstance(name, six.string_types): raise TypeError( - "attribute_names must be a list of strings; " + "Attribute names must be a list of strings; " "item {0} has type {1}".format(i + 1, type(name)) ) if name not in names: @@ -235,69 +244,104 @@ class GetAttributeListResponsePayload(primitives.Struct): ) ) else: - raise TypeError("attribute_names must be a list of strings") + raise TypeError("Attribute names must be a list of strings.") - def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): + def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the GetAttributeList response payload and decode it into its constituent parts. Args: - istream (stream): A data stream containing encoded object data, - supporting a read method; usually a BytearrayStream object. + 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 1.0. + + Raises: + InvalidKmipEncoding: Raised if the unique identifier or attribute + names are missing from the encoded payload. """ super(GetAttributeListResponsePayload, self).read( - istream, + input_buffer, kmip_version=kmip_version ) - tstream = utils.BytearrayStream(istream.read(self.length)) + local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) - if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, tstream): + if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_buffer): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER ) - self._unique_identifier.read(tstream, kmip_version=kmip_version) + self._unique_identifier.read( + local_buffer, + kmip_version=kmip_version + ) else: - self._unique_identifier = None + raise exceptions.InvalidKmipEncoding( + "The GetAttributeList response payload encoding is missing " + "the unique identifier." + ) names = list() - while self.is_tag_next(enums.Tags.ATTRIBUTE_NAME, tstream): + while self.is_tag_next(enums.Tags.ATTRIBUTE_NAME, local_buffer): name = primitives.TextString(tag=enums.Tags.ATTRIBUTE_NAME) - name.read(tstream, kmip_version=kmip_version) + name.read(local_buffer, kmip_version=kmip_version) names.append(name) + if len(names) == 0: + raise exceptions.InvalidKmipEncoding( + "The GetAttributeList response payload encoding is missing " + "the attribute names." + ) self._attribute_names = names - self.is_oversized(tstream) + self.is_oversized(local_buffer) - def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): + def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Write the data encoding the GetAttributeList response payload to a stream. Args: - ostream (stream): A data stream in which to encode object data, - supporting a write method; usually a BytearrayStream object. + output_buffer (stream): A data stream in which to encode object + data, supporting a write method; usually a BytearrayStream + object. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be encoded. Optional, defaults to KMIP 1.0. + + Raises: + InvalidField: Raised if the unique identifier or attribute name + are not defined. """ - tstream = utils.BytearrayStream() + local_buffer = utils.BytearrayStream() if self._unique_identifier: - self._unique_identifier.write(tstream, kmip_version=kmip_version) + self._unique_identifier.write( + local_buffer, + kmip_version=kmip_version + ) + else: + raise exceptions.InvalidField( + "The GetAttributeList response payload is missing the unique " + "identifier field." + ) - for attribute_name in self._attribute_names: - attribute_name.write(tstream, kmip_version=kmip_version) + if self._attribute_names: + for attribute_name in self._attribute_names: + attribute_name.write(local_buffer, kmip_version=kmip_version) + else: + raise exceptions.InvalidField( + "The GetAttributeList response payload is missing the " + "attribute names field." + ) - self.length = tstream.length() + self.length = local_buffer.length() super(GetAttributeListResponsePayload, self).write( - ostream, + output_buffer, kmip_version=kmip_version ) - ostream.write(tstream.buffer) + output_buffer.write(local_buffer.buffer) def __repr__(self): unique_identifier = "unique_identifier={0}".format( diff --git a/kmip/tests/unit/core/messages/payloads/test_get_attribute_list.py b/kmip/tests/unit/core/messages/payloads/test_get_attribute_list.py index a45822b..6f68f14 100644 --- a/kmip/tests/unit/core/messages/payloads/test_get_attribute_list.py +++ b/kmip/tests/unit/core/messages/payloads/test_get_attribute_list.py @@ -16,6 +16,7 @@ import testtools from kmip.core import enums +from kmip.core import exceptions from kmip.core import primitives from kmip.core import utils @@ -93,7 +94,7 @@ class TestGetAttributeListRequestPayload(testtools.TestCase): args = (payload, 'unique_identifier', 0) self.assertRaisesRegex( TypeError, - "unique identifier must be a string", + "Unique identifier must be a string.", setattr, *args ) @@ -441,7 +442,7 @@ class TestGetAttributeListResponsePayload(testtools.TestCase): args = (payload, 'unique_identifier', 0) self.assertRaisesRegex( TypeError, - "unique identifier must be a string", + "Unique identifier must be a string.", setattr, *args ) @@ -489,7 +490,7 @@ class TestGetAttributeListResponsePayload(testtools.TestCase): args = (payload, 'attribute_names', 0) self.assertRaisesRegex( TypeError, - "attribute_names must be a list of strings", + "Attribute names must be a list of strings.", setattr, *args ) @@ -508,7 +509,7 @@ class TestGetAttributeListResponsePayload(testtools.TestCase): ) self.assertRaisesRegex( TypeError, - "attribute_names must be a list of strings; " + "Attribute names must be a list of strings; " "item 2 has type {0}".format(type(0)), setattr, *args @@ -584,70 +585,43 @@ class TestGetAttributeListResponsePayload(testtools.TestCase): def test_read_with_no_unique_identifier(self): """ - Test that a GetAttributeList response payload with no ID can be read - from a data stream. + Test that an InvalidKmipEncoding error is raised when a + GetAttributeList response payload is read from a data stream with no + unique identifier. """ payload = payloads.GetAttributeListResponsePayload() self.assertEqual(None, payload._unique_identifier) self.assertEqual(list(), payload._attribute_names) - payload.read(self.encoding_sans_unique_identifier) - - self.assertEqual(None, payload.unique_identifier) - self.assertEqual(None, payload._unique_identifier) - self.assertEqual( - set(self.attribute_names), - set(payload.attribute_names) + args = (self.encoding_sans_unique_identifier, ) + self.assertRaisesRegex( + exceptions.InvalidKmipEncoding, + "The GetAttributeList response payload encoding is missing the " + "unique identifier.", + payload.read, + *args ) - for attribute_name in self.attribute_names: - self.assertIn( - primitives.TextString( - value=attribute_name, - tag=enums.Tags.ATTRIBUTE_NAME - ), - payload._attribute_names - ) def test_read_with_no_attribute_names(self): """ - Test that a GetAttributeList response payload with no attribute names - can be read from a data stream. + Test that an InvalidKmipEncoding error is raised when a + GetAttributeList response payload is read from a data stream with no + attribute names. """ payload = payloads.GetAttributeListResponsePayload() self.assertEqual(None, payload._unique_identifier) self.assertEqual(list(), payload._attribute_names) - payload.read(self.encoding_sans_attribute_names) - - self.assertEqual(self.unique_identifier, payload.unique_identifier) - self.assertEqual( - primitives.TextString( - value=self.unique_identifier, - tag=enums.Tags.UNIQUE_IDENTIFIER - ), - payload._unique_identifier + args = (self.encoding_sans_attribute_names, ) + self.assertRaisesRegex( + exceptions.InvalidKmipEncoding, + "The GetAttributeList response payload encoding is missing the " + "attribute names.", + payload.read, + *args ) - self.assertEqual(list(), payload.attribute_names) - self.assertEqual(list(), payload._attribute_names) - - def test_read_with_no_content(self): - """ - Test that a GetAttributeList response payload with no ID or attribute - names can be read from a data stream. - """ - payload = payloads.GetAttributeListResponsePayload() - - self.assertEqual(None, payload._unique_identifier) - self.assertEqual(list(), payload._attribute_names) - - payload.read(self.empty_encoding) - - self.assertEqual(None, payload.unique_identifier) - self.assertEqual(None, payload._unique_identifier) - self.assertEqual(list(), payload.attribute_names) - self.assertEqual(list(), payload._attribute_names) def test_write(self): """ @@ -666,51 +640,39 @@ class TestGetAttributeListResponsePayload(testtools.TestCase): def test_write_with_no_unique_identifier(self): """ - Test that a GetAttributeList response payload with no ID can be - written to a data stream. + Test that an InvalidField error is raised when a GetAttributeList + response payload is written to a data stream with no unique identifier. """ payload = payloads.GetAttributeListResponsePayload( None, self.attribute_names ) - stream = utils.BytearrayStream() - payload.write(stream) - - self.assertEqual( - len(self.encoding_sans_unique_identifier), - len(stream) - ) - self.assertEqual( - str(self.encoding_sans_unique_identifier), - str(stream) + args = (utils.BytearrayStream(), ) + self.assertRaisesRegex( + exceptions.InvalidField, + "The GetAttributeList response payload is missing the unique " + "identifier field.", + payload.write, + *args ) def test_write_with_no_attribute_names(self): """ - Test that a GetAttributeList response payload with no attribute names - can be written to a data stream. + Test that an InvalidField error is raised when a GetAttributeList + response payload is written to a data stream with no attribute names. """ payload = payloads.GetAttributeListResponsePayload( self.unique_identifier, None ) - stream = utils.BytearrayStream() - payload.write(stream) - - self.assertEqual(len(self.encoding_sans_attribute_names), len(stream)) - self.assertEqual(str(self.encoding_sans_attribute_names), str(stream)) - - def test_write_with_no_content(self): - """ - Test that a GetAttributeList response payload with no ID or attribute - names can be written to a data stream. - """ - payload = payloads.GetAttributeListResponsePayload() - stream = utils.BytearrayStream() - payload.write(stream) - - self.assertEqual(len(self.empty_encoding), len(stream)) - self.assertEqual(str(self.empty_encoding), str(stream)) + args = (utils.BytearrayStream(), ) + self.assertRaisesRegex( + exceptions.InvalidField, + "The GetAttributeList response payload is missing the attribute " + "names field.", + payload.write, + *args + ) def test_repr(self): """