From 680163193353c466c24748f3c8a829872b5a7cc6 Mon Sep 17 00:00:00 2001 From: Richard Theis Date: Fri, 18 Mar 2016 13:51:45 -0500 Subject: [PATCH] Consistent resource.prop for timestamps and booleans (orchestration) This patch set updates all orchestration objects to use consistent resource.prop for timestamps and booleans. In particular, the following changes were made: - Clarify documentation for timestamp and boolean attributes - Use 'is_' prefix and boolean type for boolean attributes - Use '_at' suffix and timestamp type for timestamp attributes Change-Id: Ic84a481a25e845ad3e05ffeefb55d56371b571bc Partial-Bug: #1544584 --- openstack/orchestration/v1/resource.py | 7 +++++-- openstack/orchestration/v1/stack.py | 20 +++++++++++-------- .../unit/orchestration/v1/test_resource.py | 8 ++++++-- .../tests/unit/orchestration/v1/test_stack.py | 16 ++++++++++----- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/openstack/orchestration/v1/resource.py b/openstack/orchestration/v1/resource.py index c0259790..4d86fa8d 100644 --- a/openstack/orchestration/v1/resource.py +++ b/openstack/orchestration/v1/resource.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +from openstack import format from openstack.orchestration import orchestration_service from openstack import resource @@ -29,12 +30,13 @@ class Resource(resource.Resource): allow_update = False # Properties - name = resource.prop('resource_name') #: A list of dictionaries containing links relevant to the resource. links = resource.prop('links') #: ID of the logical resource, usually the literal name of the resource #: as it appears in the stack template. logical_resource_id = resource.prop('logical_resource_id') + #: Name of the resource. + name = resource.prop('resource_name') #: ID of the physical resource (if any) that backs up the resource. For #: example, it contains a nova server ID if the resource is a nova #: server. @@ -50,4 +52,5 @@ class Resource(resource.Resource): #: A string that explains why the resource is in its current status. status_reason = resource.prop('resource_status_reason') #: Timestamp of the last update made to the resource. - updated_at = resource.prop('updated_time') + #: *Type: datetime object parsed from ISO 8601 formatted string* + updated_at = resource.prop('updated_time', type=format.ISO8601) diff --git a/openstack/orchestration/v1/stack.py b/openstack/orchestration/v1/stack.py index 0c47cc1d..0bf45189 100644 --- a/openstack/orchestration/v1/stack.py +++ b/openstack/orchestration/v1/stack.py @@ -11,6 +11,7 @@ # under the License. from openstack import exceptions +from openstack import format from openstack.orchestration import orchestration_service from openstack import resource from openstack import utils @@ -32,25 +33,27 @@ class Stack(resource.Resource): allow_delete = True # Properties - name = resource.prop('stack_name') #: Placeholder for AWS compatible template listing capabilities #: required by the stack. capabilities = resource.prop('capabilities') #: Timestamp of the stack creation. - created_at = resource.prop('creation_time') - #: A text decription of the stack. + #: *Type: datetime object parsed from ISO 8601 formatted string* + created_at = resource.prop('creation_time', type=format.ISO8601) + #: A text description of the stack. description = resource.prop('description') #: Whether the stack will support a rollback operation on stack - #: create/update failures. - disable_rollback = resource.prop('disable_rollback', type=bool) - #: A list of dictionaris containing links relevant to the stack. + #: create/update failures. *Type: bool* + is_rollback_disabled = resource.prop('disable_rollback', type=bool) + #: A list of dictionaries containing links relevant to the stack. links = resource.prop('links') + #: Name of the stack. + name = resource.prop('stack_name') #: Placeholder for future extensions where stack related events #: can be published. notification_topics = resource.prop('notification_topics') #: A dictionary containing output keys and values from the stack, if any. outputs = resource.prop('outputs') - #: A ditionary containing the parameter names and values for the stack. + #: A dictionary containing the parameter names and values for the stack. parameters = resource.prop('parameters', type=dict) #: A string representation of the stack status, e.g. ``CREATE_COMPLETED``. status = resource.prop('stack_status') @@ -64,7 +67,8 @@ class Stack(resource.Resource): #: Stack operation timeout in minutes. timeout_mins = resource.prop('timeout_mins') #: Timestamp of last update on the stack. - updated_at = resource.prop('updated_time') + #: *Type: datetime object parsed from ISO 8601 formatted string* + updated_at = resource.prop('updated_time', type=format.ISO8601) def _action(self, session, body): """Perform stack actions""" diff --git a/openstack/tests/unit/orchestration/v1/test_resource.py b/openstack/tests/unit/orchestration/v1/test_resource.py index 5a66a914..86d0afbc 100644 --- a/openstack/tests/unit/orchestration/v1/test_resource.py +++ b/openstack/tests/unit/orchestration/v1/test_resource.py @@ -10,6 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime + import testtools from openstack.orchestration.v1 import resource @@ -32,7 +34,7 @@ FAKE = { 'resource_type': 'OS::Heat::FakeResource', 'status': 'CREATE_COMPLETE', 'status_reason': 'state changed', - 'updated_time': '2015-05-05T07:26:00Z', + 'updated_time': '2015-03-09T12:15:57.233772', } @@ -62,4 +64,6 @@ class TestResource(testtools.TestCase): self.assertEqual(FAKE['resource_type'], sot.resource_type) self.assertEqual(FAKE['status'], sot.status) self.assertEqual(FAKE['status_reason'], sot.status_reason) - self.assertEqual(FAKE['updated_time'], sot.updated_at) + dt = datetime.datetime(2015, 3, 9, 12, 15, 57, 233772).replace( + tzinfo=None) + self.assertEqual(dt, sot.updated_at.replace(tzinfo=None)) diff --git a/openstack/tests/unit/orchestration/v1/test_stack.py b/openstack/tests/unit/orchestration/v1/test_stack.py index 16fb5324..5e99bffa 100644 --- a/openstack/tests/unit/orchestration/v1/test_stack.py +++ b/openstack/tests/unit/orchestration/v1/test_stack.py @@ -10,6 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime + import mock import six import testtools @@ -23,7 +25,7 @@ FAKE_ID = 'ce8ae86c-9810-4cb1-8888-7fb53bc523bf' FAKE_NAME = 'test_stack' FAKE = { 'capabilities': '1', - 'creation_time': '2', + 'creation_time': '2015-03-09T12:15:57.233772', 'description': '3', 'disable_rollback': True, 'id': FAKE_ID, @@ -39,7 +41,7 @@ FAKE = { 'template_description': '13', 'template_url': 'http://www.example.com/wordpress.yaml', 'timeout_mins': '14', - 'updated_time': '15', + 'updated_time': '2015-03-09T12:30:00.000000', } FAKE_CREATE_RESPONSE = { 'stack': { @@ -67,9 +69,11 @@ class TestStack(testtools.TestCase): def test_make_it(self): sot = stack.Stack(FAKE) self.assertEqual(FAKE['capabilities'], sot.capabilities) - self.assertEqual(FAKE['creation_time'], sot.created_at) + dt = datetime.datetime(2015, 3, 9, 12, 15, 57, 233772).replace( + tzinfo=None) + self.assertEqual(dt, sot.created_at.replace(tzinfo=None)) self.assertEqual(FAKE['description'], sot.description) - self.assertEqual(FAKE['disable_rollback'], sot.disable_rollback) + self.assertTrue(sot.is_rollback_disabled) self.assertEqual(FAKE['id'], sot.id) self.assertEqual(FAKE['links'], sot.links) self.assertEqual(FAKE['notification_topics'], @@ -85,7 +89,9 @@ class TestStack(testtools.TestCase): self.assertEqual(FAKE['template_url'], sot.template_url) self.assertEqual(FAKE['timeout_mins'], sot.timeout_mins) - self.assertEqual(FAKE['updated_time'], sot.updated_at) + dt = datetime.datetime(2015, 3, 9, 12, 30, 00, 000000).replace( + tzinfo=None) + self.assertEqual(dt, sot.updated_at.replace(tzinfo=None)) def test_create(self): resp = mock.Mock()