439 lines
18 KiB
Python
439 lines
18 KiB
Python
#
|
|
# 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 testtools
|
|
|
|
from heat.common import identifier
|
|
|
|
|
|
class IdentifierTest(testtools.TestCase):
|
|
url_prefix = 'http://1.2.3.4/foo/'
|
|
|
|
def test_attrs(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('/p', hi.path)
|
|
|
|
def test_path_default(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i')
|
|
self.assertEqual('', hi.path)
|
|
|
|
def test_items(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertEqual('t', hi['tenant'])
|
|
self.assertEqual('s', hi['stack_name'])
|
|
self.assertEqual('i', hi['stack_id'])
|
|
self.assertEqual('/p', hi['path'])
|
|
|
|
def test_invalid_attr(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hi.identity['foo'] = 'bar'
|
|
self.assertRaises(AttributeError, getattr, hi, 'foo')
|
|
|
|
def test_invalid_item(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hi.identity['foo'] = 'bar'
|
|
self.assertRaises(KeyError, lambda o, k: o[k], hi, 'foo')
|
|
|
|
def test_stack_path(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertEqual('s/i', hi.stack_path())
|
|
|
|
def test_arn(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertEqual('arn:openstack:heat::t:stacks/s/i/p', hi.arn())
|
|
|
|
def test_arn_url(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertEqual('/arn%3Aopenstack%3Aheat%3A%3At%3Astacks%2Fs%2Fi%2Fp',
|
|
hi.arn_url_path())
|
|
|
|
def test_arn_id_int(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 42, 'p')
|
|
self.assertEqual('arn:openstack:heat::t:stacks/s/42/p', hi.arn())
|
|
|
|
def test_arn_parse(self):
|
|
arn = 'arn:openstack:heat::t:stacks/s/i/p'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('/p', hi.path)
|
|
|
|
def test_arn_url_parse(self):
|
|
url = self.url_prefix + 'arn%3Aopenstack%3Aheat%3A%3At%3Astacks/s/i/p'
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('/p', hi.path)
|
|
|
|
def test_arn_parse_path_default(self):
|
|
arn = 'arn:openstack:heat::t:stacks/s/i'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('', hi.path)
|
|
|
|
def test_arn_url_parse_default(self):
|
|
url = self.url_prefix + 'arn%3Aopenstack%3Aheat%3A%3At%3Astacks/s/i'
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('', hi.path)
|
|
|
|
def test_arn_parse_upper(self):
|
|
arn = 'ARN:openstack:heat::t:stacks/s/i/p'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('/p', hi.path)
|
|
|
|
def test_arn_url_parse_upper(self):
|
|
url = self.url_prefix + 'ARN%3Aopenstack%3Aheat%3A%3At%3Astacks/s/i/p'
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('/p', hi.path)
|
|
|
|
def test_arn_url_parse_qs(self):
|
|
url = self.url_prefix +\
|
|
'arn%3Aopenstack%3Aheat%3A%3At%3Astacks/s/i/p?foo=bar'
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual('t', hi.tenant)
|
|
self.assertEqual('s', hi.stack_name)
|
|
self.assertEqual('i', hi.stack_id)
|
|
self.assertEqual('/p', hi.path)
|
|
|
|
def test_arn_parse_arn_invalid(self):
|
|
arn = 'urn:openstack:heat::t:stacks/s/i'
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier.from_arn, arn)
|
|
|
|
def test_arn_url_parse_arn_invalid(self):
|
|
url = self.url_prefix + 'urn:openstack:heat::t:stacks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_parse_os_invalid(self):
|
|
arn = 'arn:aws:heat::t:stacks/s/i'
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier.from_arn, arn)
|
|
|
|
def test_arn_url_parse_os_invalid(self):
|
|
url = self.url_prefix + 'arn:aws:heat::t:stacks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_parse_heat_invalid(self):
|
|
arn = 'arn:openstack:cool::t:stacks/s/i'
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier.from_arn, arn)
|
|
|
|
def test_arn_url_parse_heat_invalid(self):
|
|
url = self.url_prefix + 'arn:openstack:cool::t:stacks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_parse_stacks_invalid(self):
|
|
arn = 'arn:openstack:heat::t:sticks/s/i'
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier.from_arn, arn)
|
|
|
|
def test_arn_url_parse_stacks_invalid(self):
|
|
url = self.url_prefix + 'arn%3Aopenstack%3Aheat%3A%3At%3Asticks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_parse_missing_field(self):
|
|
arn = 'arn:openstack:heat::t:stacks/s'
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier.from_arn, arn)
|
|
|
|
def test_arn_url_parse_missing_field(self):
|
|
url = self.url_prefix + 'arn%3Aopenstack%3Aheat%3A%3At%3Asticks/s/'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_parse_empty_field(self):
|
|
arn = 'arn:openstack:heat::t:stacks//i'
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier.from_arn, arn)
|
|
|
|
def test_arn_url_parse_empty_field(self):
|
|
url = self.url_prefix + 'arn%3Aopenstack%3Aheat%3A%3At%3Asticks//i'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_url_parse_leading_char(self):
|
|
url = self.url_prefix + 'Aarn%3Aopenstack%3Aheat%3A%3At%3Asticks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_url_parse_leading_space(self):
|
|
url = self.url_prefix + ' arn%3Aopenstack%3Aheat%3A%3At%3Asticks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_url_parse_badurl_proto(self):
|
|
url = 'htt://1.2.3.4/foo/arn%3Aopenstack%3Aheat%3A%3At%3Asticks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_url_parse_badurl_host(self):
|
|
url = 'http:///foo/arn%3Aopenstack%3Aheat%3A%3At%3Asticks/s/i/p'
|
|
self.assertRaises(ValueError,
|
|
identifier.HeatIdentifier.from_arn_url, url)
|
|
|
|
def test_arn_round_trip(self):
|
|
hii = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hio = identifier.HeatIdentifier.from_arn(hii.arn())
|
|
self.assertEqual(hii.tenant, hio.tenant)
|
|
self.assertEqual(hii.stack_name, hio.stack_name)
|
|
self.assertEqual(hii.stack_id, hio.stack_id)
|
|
self.assertEqual(hii.path, hio.path)
|
|
|
|
def test_arn_parse_round_trip(self):
|
|
arn = 'arn:openstack:heat::t:stacks/s/i/p'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual(arn, hi.arn())
|
|
|
|
def test_arn_url_parse_round_trip(self):
|
|
arn = '/arn%3Aopenstack%3Aheat%3A%3At%3Astacks%2Fs%2Fi%2Fp'
|
|
url = 'http://1.2.3.4/foo' + arn
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual(arn, hi.arn_url_path())
|
|
|
|
def test_dict_round_trip(self):
|
|
hii = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hio = identifier.HeatIdentifier(**dict(hii))
|
|
self.assertEqual(hii.tenant, hio.tenant)
|
|
self.assertEqual(hii.stack_name, hio.stack_name)
|
|
self.assertEqual(hii.stack_id, hio.stack_id)
|
|
self.assertEqual(hii.path, hio.path)
|
|
|
|
def test_url_path(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertEqual('t/stacks/s/i/p', hi.url_path())
|
|
|
|
def test_url_path_default(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i')
|
|
self.assertEqual('t/stacks/s/i', hi.url_path())
|
|
|
|
def test_url_path_with_unicode_path(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', u'\u5de5')
|
|
self.assertEqual('t/stacks/s/i/%E5%B7%A5', hi.url_path())
|
|
|
|
def test_tenant_escape(self):
|
|
hi = identifier.HeatIdentifier(':/', 's', 'i')
|
|
self.assertEqual(':/', hi.tenant)
|
|
self.assertEqual('%3A%2F/stacks/s/i', hi.url_path())
|
|
self.assertEqual('arn:openstack:heat::%3A%2F:stacks/s/i', hi.arn())
|
|
|
|
def test_name_escape(self):
|
|
hi = identifier.HeatIdentifier('t', ':%', 'i')
|
|
self.assertEqual(':%', hi.stack_name)
|
|
self.assertEqual('t/stacks/%3A%25/i', hi.url_path())
|
|
self.assertEqual('arn:openstack:heat::t:stacks/%3A%25/i', hi.arn())
|
|
|
|
def test_id_escape(self):
|
|
hi = identifier.HeatIdentifier('t', 's', ':/')
|
|
self.assertEqual(':/', hi.stack_id)
|
|
self.assertEqual('t/stacks/s/%3A%2F', hi.url_path())
|
|
self.assertEqual('arn:openstack:heat::t:stacks/s/%3A%2F', hi.arn())
|
|
|
|
def test_path_escape(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', ':/')
|
|
self.assertEqual('/:/', hi.path)
|
|
self.assertEqual('t/stacks/s/i/%3A/', hi.url_path())
|
|
self.assertEqual('arn:openstack:heat::t:stacks/s/i/%3A/', hi.arn())
|
|
|
|
def test_tenant_decode(self):
|
|
arn = 'arn:openstack:heat::%3A%2F:stacks/s/i'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual(':/', hi.tenant)
|
|
|
|
def test_url_tenant_decode(self):
|
|
enc_arn = 'arn%3Aopenstack%3Aheat%3A%3A%253A%252F%3Astacks%2Fs%2Fi'
|
|
url = self.url_prefix + enc_arn
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual(':/', hi.tenant)
|
|
|
|
def test_name_decode(self):
|
|
arn = 'arn:openstack:heat::t:stacks/%3A%25/i'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual(':%', hi.stack_name)
|
|
|
|
def test_url_name_decode(self):
|
|
enc_arn = 'arn%3Aopenstack%3Aheat%3A%3At%3Astacks%2F%253A%2525%2Fi'
|
|
url = self.url_prefix + enc_arn
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual(':%', hi.stack_name)
|
|
|
|
def test_id_decode(self):
|
|
arn = 'arn:openstack:heat::t:stacks/s/%3A%2F'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual(':/', hi.stack_id)
|
|
|
|
def test_url_id_decode(self):
|
|
enc_arn = 'arn%3Aopenstack%3Aheat%3A%3At%3Astacks%2Fs%2F%253A%252F'
|
|
url = self.url_prefix + enc_arn
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual(':/', hi.stack_id)
|
|
|
|
def test_path_decode(self):
|
|
arn = 'arn:openstack:heat::t:stacks/s/i/%3A%2F'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual('/:/', hi.path)
|
|
|
|
def test_url_path_decode(self):
|
|
enc_arn = 'arn%3Aopenstack%3Aheat%3A%3At%3Astacks%2Fs%2Fi%2F%253A%252F'
|
|
url = self.url_prefix + enc_arn
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
self.assertEqual('/:/', hi.path)
|
|
|
|
def test_arn_escape_decode_round_trip(self):
|
|
hii = identifier.HeatIdentifier(':/', ':%', ':/', ':/')
|
|
hio = identifier.HeatIdentifier.from_arn(hii.arn())
|
|
self.assertEqual(hii.tenant, hio.tenant)
|
|
self.assertEqual(hii.stack_name, hio.stack_name)
|
|
self.assertEqual(hii.stack_id, hio.stack_id)
|
|
self.assertEqual(hii.path, hio.path)
|
|
|
|
def test_arn_decode_escape_round_trip(self):
|
|
arn = 'arn:openstack:heat::%3A%2F:stacks/%3A%25/%3A%2F/%3A/'
|
|
hi = identifier.HeatIdentifier.from_arn(arn)
|
|
self.assertEqual(arn, hi.arn())
|
|
|
|
def test_arn_url_decode_escape_round_trip(self):
|
|
enc_arn = "".join(['arn%3Aopenstack%3Aheat%3A%3A%253A%252F%3A',
|
|
'stacks%2F%253A%2525%2F%253A%252F%2F%253A'])
|
|
url = self.url_prefix + enc_arn
|
|
hi = identifier.HeatIdentifier.from_arn_url(url)
|
|
hi2 = identifier.HeatIdentifier.from_arn_url(self.url_prefix +
|
|
hi.arn_url_path())
|
|
self.assertEqual(hi, hi2)
|
|
|
|
def test_stack_name_slash(self):
|
|
self.assertRaises(ValueError, identifier.HeatIdentifier,
|
|
't', 's/s', 'i', 'p')
|
|
|
|
def test_equal(self):
|
|
hi1 = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hi2 = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertTrue(hi1 == hi2)
|
|
|
|
def test_equal_dict(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
self.assertTrue(hi == dict(hi))
|
|
self.assertTrue(dict(hi) == hi)
|
|
|
|
def test_not_equal(self):
|
|
hi1 = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hi2 = identifier.HeatIdentifier('t', 's', 'i', 'q')
|
|
self.assertFalse(hi1 == hi2)
|
|
self.assertFalse(hi2 == hi1)
|
|
|
|
def test_not_equal_dict(self):
|
|
hi1 = identifier.HeatIdentifier('t', 's', 'i', 'p')
|
|
hi2 = identifier.HeatIdentifier('t', 's', 'i', 'q')
|
|
self.assertFalse(hi1 == dict(hi2))
|
|
self.assertFalse(dict(hi1) == hi2)
|
|
self.assertFalse(hi1 == {'tenant': 't',
|
|
'stack_name': 's',
|
|
'stack_id': 'i'})
|
|
self.assertFalse({'tenant': 't',
|
|
'stack_name': 's',
|
|
'stack_id': 'i'} == hi1)
|
|
|
|
def test_path_components(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', 'p1/p2/p3')
|
|
self.assertEqual(['p1', 'p2', 'p3'], hi._path_components())
|
|
|
|
|
|
class ResourceIdentifierTest(testtools.TestCase):
|
|
def test_resource_init_no_path(self):
|
|
si = identifier.HeatIdentifier('t', 's', 'i')
|
|
ri = identifier.ResourceIdentifier(resource_name='r', **si)
|
|
self.assertEqual('/resources/r', ri.path)
|
|
|
|
def test_resource_init_path(self):
|
|
si = identifier.HeatIdentifier('t', 's', 'i')
|
|
pi = identifier.ResourceIdentifier(resource_name='p', **si)
|
|
ri = identifier.ResourceIdentifier(resource_name='r', **pi)
|
|
self.assertEqual('/resources/p/resources/r', ri.path)
|
|
|
|
def test_resource_init_from_dict(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', '/resources/r')
|
|
ri = identifier.ResourceIdentifier(**hi)
|
|
self.assertEqual(hi, ri)
|
|
|
|
def test_resource_stack(self):
|
|
si = identifier.HeatIdentifier('t', 's', 'i')
|
|
ri = identifier.ResourceIdentifier(resource_name='r', **si)
|
|
self.assertEqual(si, ri.stack())
|
|
|
|
def test_resource_id(self):
|
|
ri = identifier.ResourceIdentifier('t', 's', 'i', '', 'r')
|
|
self.assertEqual('r', ri.resource_name)
|
|
|
|
def test_resource_name_slash(self):
|
|
self.assertRaises(ValueError, identifier.ResourceIdentifier,
|
|
't', 's', 'i', 'p', 'r/r')
|
|
|
|
|
|
class EventIdentifierTest(testtools.TestCase):
|
|
def test_event_init_integer_id(self):
|
|
self._test_event_init('42')
|
|
|
|
def test_event_init_uuid_id(self):
|
|
self._test_event_init('a3455d8c-9f88-404d-a85b-5315293e67de')
|
|
|
|
def _test_event_init(self, event_id):
|
|
si = identifier.HeatIdentifier('t', 's', 'i')
|
|
pi = identifier.ResourceIdentifier(resource_name='p', **si)
|
|
ei = identifier.EventIdentifier(event_id=event_id, **pi)
|
|
self.assertEqual('/resources/p/events/{0}'.format(event_id), ei.path)
|
|
|
|
def test_event_init_from_dict(self):
|
|
hi = identifier.HeatIdentifier('t', 's', 'i', '/resources/p/events/42')
|
|
ei = identifier.EventIdentifier(**hi)
|
|
self.assertEqual(hi, ei)
|
|
|
|
def test_event_stack(self):
|
|
si = identifier.HeatIdentifier('t', 's', 'i')
|
|
pi = identifier.ResourceIdentifier(resource_name='r', **si)
|
|
ei = identifier.EventIdentifier(event_id='e', **pi)
|
|
self.assertEqual(si, ei.stack())
|
|
|
|
def test_event_resource(self):
|
|
si = identifier.HeatIdentifier('t', 's', 'i')
|
|
pi = identifier.ResourceIdentifier(resource_name='r', **si)
|
|
ei = identifier.EventIdentifier(event_id='e', **pi)
|
|
self.assertEqual(pi, ei.resource())
|
|
|
|
def test_resource_name(self):
|
|
ei = identifier.EventIdentifier('t', 's', 'i', '/resources/p', 'e')
|
|
self.assertEqual('p', ei.resource_name)
|
|
|
|
def test_event_id_integer(self):
|
|
self._test_event_id('42')
|
|
|
|
def test_event_id_uuid(self):
|
|
self._test_event_id('a3455d8c-9f88-404d-a85b-5315293e67de')
|
|
|
|
def _test_event_id(self, event_id):
|
|
ei = identifier.EventIdentifier('t', 's', 'i', '/resources/p',
|
|
event_id)
|
|
self.assertEqual(event_id, ei.event_id)
|