Fix v2 requests to non-bleeding edge servers
In the case where v2 requests are sent to a server which is not running head of tree which includes the v2 metadef code some 404 cases need to be handled to enable standard requests to complete. This patch aslo improves fetching schemas -- they are now only fetched as needed. Change-Id: I8c871f11b909337bd7df19b77e606772dbc634b2 Closes-bug: #1367326
This commit is contained in:

committed by
Stuart McLaren

parent
fde99a0a4d
commit
97b1506bdb
@@ -21,6 +21,7 @@ import json
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import six
|
import six
|
||||||
@@ -36,6 +37,8 @@ from glanceclient import exc
|
|||||||
from glanceclient.openstack.common import importutils
|
from glanceclient.openstack.common import importutils
|
||||||
from glanceclient.openstack.common import strutils
|
from glanceclient.openstack.common import strutils
|
||||||
|
|
||||||
|
_memoized_property_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
# Decorator for cli-args
|
# Decorator for cli-args
|
||||||
def arg(*args, **kwargs):
|
def arg(*args, **kwargs):
|
||||||
@@ -367,3 +370,18 @@ def integrity_iter(iter, checksum):
|
|||||||
raise IOError(errno.EPIPE,
|
raise IOError(errno.EPIPE,
|
||||||
'Corrupt image download. Checksum was %s expected %s' %
|
'Corrupt image download. Checksum was %s expected %s' %
|
||||||
(md5sum, checksum))
|
(md5sum, checksum))
|
||||||
|
|
||||||
|
|
||||||
|
def memoized_property(fn):
|
||||||
|
attr_name = '_lazy_once_' + fn.__name__
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _memoized_property(self):
|
||||||
|
if hasattr(self, attr_name):
|
||||||
|
return getattr(self, attr_name)
|
||||||
|
else:
|
||||||
|
with _memoized_property_lock:
|
||||||
|
if not hasattr(self, attr_name):
|
||||||
|
setattr(self, attr_name, fn(self))
|
||||||
|
return getattr(self, attr_name)
|
||||||
|
return _memoized_property
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.common import http
|
from glanceclient.common import http
|
||||||
from glanceclient.common import utils
|
from glanceclient.common import utils
|
||||||
@@ -38,50 +37,21 @@ class Client(object):
|
|||||||
self.http_client = http.HTTPClient(utils.strip_version(endpoint),
|
self.http_client = http.HTTPClient(utils.strip_version(endpoint),
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
self.schemas = schemas.Controller(self.http_client)
|
self.schemas = schemas.Controller(self.http_client)
|
||||||
image_model = self._get_image_model()
|
|
||||||
self.images = images.Controller(self.http_client,
|
self.images = images.Controller(self.http_client, self.schemas)
|
||||||
image_model)
|
self.image_tags = image_tags.Controller(self.http_client,
|
||||||
self.image_tags = image_tags.Controller(self.http_client, image_model)
|
self.schemas)
|
||||||
self.image_members = image_members.Controller(self.http_client,
|
self.image_members = image_members.Controller(self.http_client,
|
||||||
self._get_member_model())
|
self.schemas)
|
||||||
|
|
||||||
resource_type_model = self._get_metadefs_resource_type_model()
|
|
||||||
self.metadefs_resource_type = (
|
self.metadefs_resource_type = (
|
||||||
metadefs.ResourceTypeController(self.http_client,
|
metadefs.ResourceTypeController(self.http_client, self.schemas))
|
||||||
resource_type_model))
|
|
||||||
|
|
||||||
property_model = self._get_metadefs_property_model()
|
|
||||||
self.metadefs_property = (
|
self.metadefs_property = (
|
||||||
metadefs.PropertyController(self.http_client, property_model))
|
metadefs.PropertyController(self.http_client, self.schemas))
|
||||||
|
|
||||||
object_model = self._get_metadefs_object_model()
|
|
||||||
self.metadefs_object = (
|
self.metadefs_object = (
|
||||||
metadefs.ObjectController(self.http_client, object_model))
|
metadefs.ObjectController(self.http_client, self.schemas))
|
||||||
|
|
||||||
namespace_model = self._get_metadefs_namespace_model()
|
|
||||||
self.metadefs_namespace = (
|
self.metadefs_namespace = (
|
||||||
metadefs.NamespaceController(self.http_client, namespace_model))
|
metadefs.NamespaceController(self.http_client, self.schemas))
|
||||||
|
|
||||||
def _get_image_model(self):
|
|
||||||
schema = self.schemas.get('image')
|
|
||||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
|
||||||
|
|
||||||
def _get_member_model(self):
|
|
||||||
schema = self.schemas.get('member')
|
|
||||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
|
||||||
|
|
||||||
def _get_metadefs_namespace_model(self):
|
|
||||||
schema = self.schemas.get('metadefs/namespace')
|
|
||||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
|
||||||
|
|
||||||
def _get_metadefs_resource_type_model(self):
|
|
||||||
schema = self.schemas.get('metadefs/resource_type')
|
|
||||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
|
||||||
|
|
||||||
def _get_metadefs_property_model(self):
|
|
||||||
schema = self.schemas.get('metadefs/property')
|
|
||||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
|
||||||
|
|
||||||
def _get_metadefs_object_model(self):
|
|
||||||
schema = self.schemas.get('metadefs/object')
|
|
||||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
|
||||||
|
@@ -13,11 +13,21 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import warlock
|
||||||
|
|
||||||
|
from glanceclient.common import utils
|
||||||
|
from glanceclient.v2 import schemas
|
||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('member')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def list(self, image_id):
|
def list(self, image_id):
|
||||||
url = '/v2/images/%s/members' % image_id
|
url = '/v2/images/%s/members' % image_id
|
||||||
|
@@ -13,11 +13,21 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import warlock
|
||||||
|
|
||||||
|
from glanceclient.common import utils
|
||||||
|
from glanceclient.v2 import schemas
|
||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('image')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def update(self, image_id, tag_value):
|
def update(self, image_id, tag_value):
|
||||||
"""
|
"""
|
||||||
|
@@ -21,14 +21,20 @@ import warlock
|
|||||||
from glanceclient.common import utils
|
from glanceclient.common import utils
|
||||||
from glanceclient import exc
|
from glanceclient import exc
|
||||||
from glanceclient.openstack.common import strutils
|
from glanceclient.openstack.common import strutils
|
||||||
|
from glanceclient.v2 import schemas
|
||||||
|
|
||||||
DEFAULT_PAGE_SIZE = 20
|
DEFAULT_PAGE_SIZE = 20
|
||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('image')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def list(self, **kwargs):
|
def list(self, **kwargs):
|
||||||
"""Retrieve a listing of Image objects
|
"""Retrieve a listing of Image objects
|
||||||
|
@@ -19,14 +19,20 @@ import warlock
|
|||||||
|
|
||||||
from glanceclient.common import utils
|
from glanceclient.common import utils
|
||||||
from glanceclient.openstack.common import strutils
|
from glanceclient.openstack.common import strutils
|
||||||
|
from glanceclient.v2 import schemas
|
||||||
|
|
||||||
DEFAULT_PAGE_SIZE = 20
|
DEFAULT_PAGE_SIZE = 20
|
||||||
|
|
||||||
|
|
||||||
class NamespaceController(object):
|
class NamespaceController(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('metadefs/namespace')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def create(self, **kwargs):
|
def create(self, **kwargs):
|
||||||
"""Create a namespace.
|
"""Create a namespace.
|
||||||
@@ -75,7 +81,7 @@ class NamespaceController(object):
|
|||||||
|
|
||||||
url = '/v2/metadefs/namespaces/{0}{1}'.format(namespace, query_params)
|
url = '/v2/metadefs/namespaces/{0}{1}'.format(namespace, query_params)
|
||||||
resp, body = self.http_client.get(url)
|
resp, body = self.http_client.get(url)
|
||||||
#NOTE(bcwaldon): remove 'self' for now until we have an elegant
|
# NOTE(bcwaldon): remove 'self' for now until we have an elegant
|
||||||
# way to pass it into the model constructor without conflict
|
# way to pass it into the model constructor without conflict
|
||||||
body.pop('self', None)
|
body.pop('self', None)
|
||||||
return self.model(**body)
|
return self.model(**body)
|
||||||
@@ -141,9 +147,14 @@ class NamespaceController(object):
|
|||||||
|
|
||||||
|
|
||||||
class ResourceTypeController(object):
|
class ResourceTypeController(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('metadefs/resource_type')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def associate(self, namespace, **kwargs):
|
def associate(self, namespace, **kwargs):
|
||||||
"""Associate a resource type with a namespace."""
|
"""Associate a resource type with a namespace."""
|
||||||
@@ -184,9 +195,14 @@ class ResourceTypeController(object):
|
|||||||
|
|
||||||
|
|
||||||
class PropertyController(object):
|
class PropertyController(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('metadefs/property')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def create(self, namespace, **kwargs):
|
def create(self, namespace, **kwargs):
|
||||||
"""Create a property.
|
"""Create a property.
|
||||||
@@ -259,9 +275,14 @@ class PropertyController(object):
|
|||||||
|
|
||||||
|
|
||||||
class ObjectController(object):
|
class ObjectController(object):
|
||||||
def __init__(self, http_client, model):
|
def __init__(self, http_client, schema_client):
|
||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.model = model
|
self.schema_client = schema_client
|
||||||
|
|
||||||
|
@utils.memoized_property
|
||||||
|
def model(self):
|
||||||
|
schema = self.schema_client.get('metadefs/object')
|
||||||
|
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||||
|
|
||||||
def create(self, namespace, **kwargs):
|
def create(self, namespace, **kwargs):
|
||||||
"""Create an object.
|
"""Create an object.
|
||||||
|
@@ -18,6 +18,8 @@ import json
|
|||||||
import six
|
import six
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
|
from glanceclient.v2.schemas import Schema
|
||||||
|
|
||||||
|
|
||||||
class FakeAPI(object):
|
class FakeAPI(object):
|
||||||
def __init__(self, fixtures):
|
def __init__(self, fixtures):
|
||||||
@@ -60,6 +62,15 @@ class FakeAPI(object):
|
|||||||
return self._request('HEAD', *args, **kwargs)
|
return self._request('HEAD', *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeSchemaAPI(FakeAPI):
|
||||||
|
def __init__(cls, *args):
|
||||||
|
super(FakeSchemaAPI, cls).__init__(*args)
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
_, raw_schema = self._request('GET', *args, **kwargs)
|
||||||
|
return Schema(raw_schema)
|
||||||
|
|
||||||
|
|
||||||
class RawRequest(object):
|
class RawRequest(object):
|
||||||
def __init__(self, headers, body=None,
|
def __init__(self, headers, body=None,
|
||||||
version=1.0, status=200, reason="Ok"):
|
version=1.0, status=200, reason="Ok"):
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from mox3 import mox
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from glanceclient.v2 import client
|
from glanceclient.v2 import client
|
||||||
@@ -23,21 +22,9 @@ class ClientTest(testtools.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(ClientTest, self).setUp()
|
super(ClientTest, self).setUp()
|
||||||
self.mock = mox.Mox()
|
|
||||||
self.mock.StubOutWithMock(client.Client, '_get_image_model')
|
|
||||||
self.mock.StubOutWithMock(client.Client, '_get_member_model')
|
|
||||||
self.mock.StubOutWithMock(client.Client,
|
|
||||||
'_get_metadefs_namespace_model')
|
|
||||||
self.mock.StubOutWithMock(client.Client,
|
|
||||||
'_get_metadefs_resource_type_model')
|
|
||||||
self.mock.StubOutWithMock(client.Client,
|
|
||||||
'_get_metadefs_property_model')
|
|
||||||
self.mock.StubOutWithMock(client.Client,
|
|
||||||
'_get_metadefs_object_model')
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(ClientTest, self).tearDown()
|
super(ClientTest, self).tearDown()
|
||||||
self.mock.UnsetStubs()
|
|
||||||
|
|
||||||
def test_endpoint(self):
|
def test_endpoint(self):
|
||||||
gc = client.Client("http://example.com")
|
gc = client.Client("http://example.com")
|
||||||
|
@@ -15,10 +15,9 @@
|
|||||||
|
|
||||||
import errno
|
import errno
|
||||||
import json
|
import json
|
||||||
import testtools
|
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import warlock
|
import testtools
|
||||||
|
|
||||||
from glanceclient import exc
|
from glanceclient import exc
|
||||||
from glanceclient.v2 import images
|
from glanceclient.v2 import images
|
||||||
@@ -39,7 +38,31 @@ _PUBLIC_ID = '857806e7-05b6-48e0-9d40-cb0e6fb727b9'
|
|||||||
_SHARED_ID = '331ac905-2a38-44c5-a83d-653db8f08313'
|
_SHARED_ID = '331ac905-2a38-44c5-a83d-653db8f08313'
|
||||||
_STATUS_REJECTED_ID = 'f3ea56ff-d7e4-4451-998c-1e3d33539c8e'
|
_STATUS_REJECTED_ID = 'f3ea56ff-d7e4-4451-998c-1e3d33539c8e'
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
|
'/v2/schemas/image': {
|
||||||
|
'GET': (
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
'name': 'image',
|
||||||
|
'properties': {
|
||||||
|
'id': {},
|
||||||
|
'name': {},
|
||||||
|
'locations': {
|
||||||
|
'type': 'array',
|
||||||
|
'items': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'metadata': {'type': 'object'},
|
||||||
|
'url': {'type': 'string'},
|
||||||
|
},
|
||||||
|
'required': ['url', 'metadata'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'additionalProperties': {'type': 'string'}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
'/v2/images?limit=%d' % images.DEFAULT_PAGE_SIZE: {
|
'/v2/images?limit=%d' % images.DEFAULT_PAGE_SIZE: {
|
||||||
'GET': (
|
'GET': (
|
||||||
{},
|
{},
|
||||||
@@ -325,36 +348,43 @@ fixtures = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fake_schema = {
|
schema_fixtures = {
|
||||||
'name': 'image',
|
'image': {
|
||||||
'properties': {
|
'GET': (
|
||||||
'id': {},
|
{},
|
||||||
'name': {},
|
{
|
||||||
'locations': {
|
'name': 'image',
|
||||||
'type': 'array',
|
|
||||||
'items': {
|
|
||||||
'type': 'object',
|
|
||||||
'properties': {
|
'properties': {
|
||||||
'metadata': {'type': 'object'},
|
'id': {},
|
||||||
'url': {'type': 'string'},
|
'name': {},
|
||||||
|
'locations': {
|
||||||
|
'type': 'array',
|
||||||
|
'items': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'metadata': {'type': 'object'},
|
||||||
|
'url': {'type': 'string'},
|
||||||
|
},
|
||||||
|
'required': ['url', 'metadata'],
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
'required': ['url', 'metadata'],
|
'additionalProperties': {'type': 'string'}
|
||||||
},
|
}
|
||||||
},
|
)
|
||||||
},
|
}
|
||||||
'additionalProperties': {'type': 'string'}
|
|
||||||
}
|
}
|
||||||
FakeModel = warlock.model_factory(fake_schema)
|
|
||||||
|
|
||||||
|
|
||||||
class TestController(testtools.TestCase):
|
class TestController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestController, self).setUp()
|
super(TestController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
self.controller = images.Controller(self.api, FakeModel)
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
|
self.controller = images.Controller(self.api, self.schema_api)
|
||||||
|
|
||||||
def test_list_images(self):
|
def test_list_images(self):
|
||||||
#NOTE(bcwaldon): cast to list since the controller returns a generator
|
# NOTE(bcwaldon):cast to list since the controller returns a generator
|
||||||
images = list(self.controller.list())
|
images = list(self.controller.list())
|
||||||
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', images[0].id)
|
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', images[0].id)
|
||||||
self.assertEqual('image-1', images[0].name)
|
self.assertEqual('image-1', images[0].name)
|
||||||
@@ -362,7 +392,7 @@ class TestController(testtools.TestCase):
|
|||||||
self.assertEqual('image-2', images[1].name)
|
self.assertEqual('image-2', images[1].name)
|
||||||
|
|
||||||
def test_list_images_paginated(self):
|
def test_list_images_paginated(self):
|
||||||
#NOTE(bcwaldon): cast to list since the controller returns a generator
|
# NOTE(bcwaldon):cast to list since the controller returns a generator
|
||||||
images = list(self.controller.list(page_size=1))
|
images = list(self.controller.list(page_size=1))
|
||||||
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', images[0].id)
|
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', images[0].id)
|
||||||
self.assertEqual('image-1', images[0].name)
|
self.assertEqual('image-1', images[0].name)
|
||||||
@@ -571,7 +601,7 @@ class TestController(testtools.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(image_id, image.id)
|
self.assertEqual(image_id, image.id)
|
||||||
#NOTE(bcwaldon): due to limitations of our fake api framework, the name
|
# NOTE(bcwaldon):due to limitations of our fake api framework, the name
|
||||||
# will not actually change - yet in real life it will...
|
# will not actually change - yet in real life it will...
|
||||||
self.assertEqual('image-1', image.name)
|
self.assertEqual('image-1', image.name)
|
||||||
|
|
||||||
@@ -590,7 +620,7 @@ class TestController(testtools.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(image_id, image.id)
|
self.assertEqual(image_id, image.id)
|
||||||
#NOTE(bcwaldon): due to limitations of our fake api framework, the name
|
# NOTE(bcwaldon):due to limitations of our fake api framework, the name
|
||||||
# will not actually change - yet in real life it will...
|
# will not actually change - yet in real life it will...
|
||||||
self.assertEqual('image-1', image.name)
|
self.assertEqual('image-1', image.name)
|
||||||
|
|
||||||
@@ -609,7 +639,7 @@ class TestController(testtools.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(image_id, image.id)
|
self.assertEqual(image_id, image.id)
|
||||||
#NOTE(bcwaldon): due to limitations of our fake api framework, the name
|
# NOTE(bcwaldon):due to limitations of our fake api framework, the name
|
||||||
# will not actually change - yet in real life it will...
|
# will not actually change - yet in real life it will...
|
||||||
self.assertEqual('image-3', image.name)
|
self.assertEqual('image-3', image.name)
|
||||||
|
|
||||||
@@ -622,8 +652,8 @@ class TestController(testtools.TestCase):
|
|||||||
expect_hdrs = {
|
expect_hdrs = {
|
||||||
'Content-Type': 'application/openstack-images-v2.1-json-patch',
|
'Content-Type': 'application/openstack-images-v2.1-json-patch',
|
||||||
}
|
}
|
||||||
expect_body = '[{"path": "/barney", "value": "miller", ' \
|
expect_body = ('[{"path": "/barney", "value": "miller", '
|
||||||
'"op": "replace"}]'
|
'"op": "replace"}]')
|
||||||
expect = [
|
expect = [
|
||||||
('GET', '/v2/images/%s' % image_id, {}, None),
|
('GET', '/v2/images/%s' % image_id, {}, None),
|
||||||
('PATCH', '/v2/images/%s' % image_id, expect_hdrs, expect_body),
|
('PATCH', '/v2/images/%s' % image_id, expect_hdrs, expect_body),
|
||||||
@@ -631,7 +661,7 @@ class TestController(testtools.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(image_id, image.id)
|
self.assertEqual(image_id, image.id)
|
||||||
#NOTE(bcwaldon): due to limitations of our fake api framework, the name
|
# NOTE(bcwaldon):due to limitations of our fake api framework, the name
|
||||||
# will not actually change - yet in real life it will...
|
# will not actually change - yet in real life it will...
|
||||||
self.assertEqual('image-3', image.name)
|
self.assertEqual('image-3', image.name)
|
||||||
|
|
||||||
@@ -652,7 +682,7 @@ class TestController(testtools.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expect, self.api.calls)
|
self.assertEqual(expect, self.api.calls)
|
||||||
self.assertEqual(image_id, image.id)
|
self.assertEqual(image_id, image.id)
|
||||||
#NOTE(bcwaldon): due to limitations of our fake api framework, the name
|
# NOTE(bcwaldon):due to limitations of our fake api framework, the name
|
||||||
# will not actually change - yet in real life it will...
|
# will not actually change - yet in real life it will...
|
||||||
self.assertEqual('image-3', image.name)
|
self.assertEqual('image-3', image.name)
|
||||||
|
|
||||||
@@ -741,7 +771,7 @@ class TestController(testtools.TestCase):
|
|||||||
image_id = 'a2b83adc-888e-11e3-8872-78acc0b951d8'
|
image_id = 'a2b83adc-888e-11e3-8872-78acc0b951d8'
|
||||||
new_loc = {'url': 'http://foo.com/', 'metadata': {'spam': 'ham'}}
|
new_loc = {'url': 'http://foo.com/', 'metadata': {'spam': 'ham'}}
|
||||||
fixture_idx = '/v2/images/%s' % (image_id)
|
fixture_idx = '/v2/images/%s' % (image_id)
|
||||||
orig_locations = fixtures[fixture_idx]['GET'][1]['locations']
|
orig_locations = data_fixtures[fixture_idx]['GET'][1]['locations']
|
||||||
loc_map = dict([(l['url'], l) for l in orig_locations])
|
loc_map = dict([(l['url'], l) for l in orig_locations])
|
||||||
loc_map[new_loc['url']] = new_loc
|
loc_map[new_loc['url']] = new_loc
|
||||||
mod_patch = [{'path': '/locations', 'op': 'replace',
|
mod_patch = [{'path': '/locations', 'op': 'replace',
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.v2 import image_members
|
from glanceclient.v2 import image_members
|
||||||
from tests import utils
|
from tests import utils
|
||||||
|
|
||||||
@@ -25,7 +23,7 @@ IMAGE = '3a4560a1-e585-443e-9b39-553b46ec92d1'
|
|||||||
MEMBER = '11223344-5566-7788-9911-223344556677'
|
MEMBER = '11223344-5566-7788-9911-223344556677'
|
||||||
|
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
'/v2/images/{image}/members'.format(image=IMAGE): {
|
'/v2/images/{image}/members'.format(image=IMAGE): {
|
||||||
'GET': (
|
'GET': (
|
||||||
{},
|
{},
|
||||||
@@ -58,20 +56,31 @@ fixtures = {
|
|||||||
'status': 'accepted'
|
'status': 'accepted'
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schema_fixtures = {
|
||||||
fake_schema = {'name': 'member', 'properties': {'image_id': {},
|
'member': {
|
||||||
'member_id': {}}}
|
'GET': (
|
||||||
FakeModel = warlock.model_factory(fake_schema)
|
{},
|
||||||
|
{
|
||||||
|
'name': 'member',
|
||||||
|
'properties': {
|
||||||
|
'image_id': {},
|
||||||
|
'member_id': {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestController(testtools.TestCase):
|
class TestController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestController, self).setUp()
|
super(TestController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
self.controller = image_members.Controller(self.api, FakeModel)
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
|
self.controller = image_members.Controller(self.api, self.schema_api)
|
||||||
|
|
||||||
def test_list_image_members(self):
|
def test_list_image_members(self):
|
||||||
image_id = IMAGE
|
image_id = IMAGE
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.v2 import metadefs
|
from glanceclient.v2 import metadefs
|
||||||
from tests import utils
|
from tests import utils
|
||||||
|
|
||||||
@@ -59,7 +57,7 @@ def _get_namespace_fixture(ns_name, rt_name=RESOURCE_TYPE1, **kwargs):
|
|||||||
|
|
||||||
return ns
|
return ns
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
"/v2/metadefs/namespaces?limit=20": {
|
"/v2/metadefs/namespaces?limit=20": {
|
||||||
"GET": (
|
"GET": (
|
||||||
{},
|
{},
|
||||||
@@ -271,230 +269,243 @@ fixtures = {
|
|||||||
"updated_at": "2014-08-14T09:07:06Z",
|
"updated_at": "2014-08-14T09:07:06Z",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_namespace_schema = {
|
schema_fixtures = {
|
||||||
"additionalProperties": False,
|
"metadefs/namespace":
|
||||||
"definitions": {
|
{
|
||||||
"property": {
|
"GET": (
|
||||||
"additionalProperties": {
|
{},
|
||||||
"required": [
|
{
|
||||||
"title",
|
"additionalProperties": False,
|
||||||
"type"
|
"definitions": {
|
||||||
],
|
"property": {
|
||||||
"type": "object",
|
"additionalProperties": {
|
||||||
"properties": {
|
"required": [
|
||||||
"additionalItems": {
|
"title",
|
||||||
"type": "boolean"
|
"type"
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"additionalItems": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"enum": {
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"default": {},
|
||||||
|
"minLength": {
|
||||||
|
"$ref": "#/definitions/"
|
||||||
|
"positiveIntegerDefault0"
|
||||||
|
},
|
||||||
|
"required": {
|
||||||
|
"$ref": "#/definitions/stringArray"
|
||||||
|
},
|
||||||
|
"maximum": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"minItems": {
|
||||||
|
"$ref": "#/definitions/"
|
||||||
|
"positiveIntegerDefault0"
|
||||||
|
},
|
||||||
|
"readonly": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"minimum": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"maxItems": {
|
||||||
|
"$ref": "#/definitions/"
|
||||||
|
"positiveInteger"
|
||||||
|
},
|
||||||
|
"maxLength": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
"uniqueItems": {
|
||||||
|
"default": False,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"pattern": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "regex"
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enum": {
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"array",
|
||||||
|
"boolean",
|
||||||
|
"integer",
|
||||||
|
"number",
|
||||||
|
"object",
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"array",
|
||||||
|
"boolean",
|
||||||
|
"integer",
|
||||||
|
"number",
|
||||||
|
"object",
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
},
|
},
|
||||||
"enum": {
|
"positiveIntegerDefault0": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stringArray": {
|
||||||
|
"uniqueItems": True,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
"description": {
|
"positiveInteger": {
|
||||||
"type": "string"
|
"minimum": 0,
|
||||||
},
|
"type": "integer"
|
||||||
"title": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"default": {},
|
|
||||||
"minLength": {
|
|
||||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
|
||||||
},
|
|
||||||
"required": {
|
|
||||||
"$ref": "#/definitions/stringArray"
|
|
||||||
},
|
|
||||||
"maximum": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"minItems": {
|
|
||||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
|
||||||
},
|
|
||||||
"readonly": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"minimum": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"maxItems": {
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
"maxLength": {
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
"uniqueItems": {
|
|
||||||
"default": False,
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"pattern": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "regex"
|
|
||||||
},
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"enum": {
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"enum": [
|
|
||||||
"array",
|
|
||||||
"boolean",
|
|
||||||
"integer",
|
|
||||||
"number",
|
|
||||||
"object",
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"enum": [
|
|
||||||
"array",
|
|
||||||
"boolean",
|
|
||||||
"integer",
|
|
||||||
"number",
|
|
||||||
"object",
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"positiveIntegerDefault0": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
},
|
||||||
{
|
"required": [
|
||||||
"default": 0
|
"namespace"
|
||||||
}
|
],
|
||||||
]
|
"name": "namespace",
|
||||||
},
|
|
||||||
"stringArray": {
|
|
||||||
"uniqueItems": True,
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"positiveInteger": {
|
|
||||||
"minimum": 0,
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"namespace"
|
|
||||||
],
|
|
||||||
"name": "namespace",
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Provides a user friendly description of the "
|
|
||||||
"namespace.",
|
|
||||||
"maxLength": 500
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Date and time of the last namespace modification "
|
|
||||||
"(READ-ONLY)",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"visibility": {
|
|
||||||
"enum": [
|
|
||||||
"public",
|
|
||||||
"private"
|
|
||||||
],
|
|
||||||
"type": "string",
|
|
||||||
"description": "Scope of namespace accessibility."
|
|
||||||
},
|
|
||||||
"self": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"objects": {
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Provides a user friendly description "
|
||||||
|
"of the namespace.",
|
||||||
|
"maxLength": 500
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Date and time of the last namespace "
|
||||||
|
"modification (READ-ONLY)",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"visibility": {
|
||||||
|
"enum": [
|
||||||
|
"public",
|
||||||
|
"private"
|
||||||
|
],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Scope of namespace accessibility."
|
||||||
|
},
|
||||||
|
"self": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"objects": {
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"properties": {
|
||||||
|
"$ref": "#/definitions/property"
|
||||||
|
},
|
||||||
|
"required": {
|
||||||
|
"$ref": "#/definitions/stringArray"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Owner of the namespace.",
|
||||||
|
"maxLength": 255
|
||||||
|
},
|
||||||
|
"resource_types": {
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"prefix": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"metadata_type": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"$ref": "#/definitions/property"
|
"$ref": "#/definitions/property"
|
||||||
},
|
},
|
||||||
"required": {
|
"display_name": {
|
||||||
"$ref": "#/definitions/stringArray"
|
"type": "string",
|
||||||
|
"description": "The user friendly name for the "
|
||||||
|
"namespace. Used by UI if available.",
|
||||||
|
"maxLength": 80
|
||||||
},
|
},
|
||||||
"name": {
|
"created_at": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"description": "Date and time of namespace creation "
|
||||||
|
"(READ-ONLY)",
|
||||||
|
"format": "date-time"
|
||||||
},
|
},
|
||||||
"description": {
|
"namespace": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The unique namespace text.",
|
||||||
|
"maxLength": 80
|
||||||
|
},
|
||||||
|
"protected": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "If true, namespace will not be "
|
||||||
|
"deletable."
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"type": "array"
|
),
|
||||||
},
|
|
||||||
"owner": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Owner of the namespace.",
|
|
||||||
"maxLength": 255
|
|
||||||
},
|
|
||||||
"resource_types": {
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"prefix": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"metadata_type": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"$ref": "#/definitions/property"
|
|
||||||
},
|
|
||||||
"display_name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The user friendly name for the namespace. Used by"
|
|
||||||
" UI if available.",
|
|
||||||
"maxLength": 80
|
|
||||||
},
|
|
||||||
"created_at": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Date and time of namespace creation (READ-ONLY)",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"namespace": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The unique namespace text.",
|
|
||||||
"maxLength": 80
|
|
||||||
},
|
|
||||||
"protected": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "If true, namespace will not be deletable."
|
|
||||||
},
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FakeNamespaceModel = warlock.model_factory(fake_namespace_schema)
|
|
||||||
|
|
||||||
|
|
||||||
class TestNamespaceController(testtools.TestCase):
|
class TestNamespaceController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestNamespaceController, self).setUp()
|
super(TestNamespaceController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
self.controller = metadefs.NamespaceController(self.api,
|
self.controller = metadefs.NamespaceController(self.api,
|
||||||
FakeNamespaceModel)
|
self.schema_api)
|
||||||
|
|
||||||
def test_list_namespaces(self):
|
def test_list_namespaces(self):
|
||||||
namespaces = list(self.controller.list())
|
namespaces = list(self.controller.list())
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
import six
|
import six
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.v2 import metadefs
|
from glanceclient.v2 import metadefs
|
||||||
from tests import utils
|
from tests import utils
|
||||||
|
|
||||||
@@ -50,8 +48,7 @@ def _get_object_fixture(ns_name, obj_name, **kwargs):
|
|||||||
"description": "DESCRIPTION",
|
"description": "DESCRIPTION",
|
||||||
"maximum": 1000000,
|
"maximum": 1000000,
|
||||||
"title": "Quota: CPU Period"
|
"title": "Quota: CPU Period"
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
"schema": "/v2/schemas/metadefs/object",
|
"schema": "/v2/schemas/metadefs/object",
|
||||||
"created_at": "2014-08-14T09:07:06Z",
|
"created_at": "2014-08-14T09:07:06Z",
|
||||||
"updated_at": "2014-08-14T09:07:06Z",
|
"updated_at": "2014-08-14T09:07:06Z",
|
||||||
@@ -61,7 +58,7 @@ def _get_object_fixture(ns_name, obj_name, **kwargs):
|
|||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
"/v2/metadefs/namespaces/%s/objects" % NAMESPACE1: {
|
"/v2/metadefs/namespaces/%s/objects" % NAMESPACE1: {
|
||||||
"GET": (
|
"GET": (
|
||||||
{},
|
{},
|
||||||
@@ -98,166 +95,174 @@ fixtures = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schema_fixtures = {
|
||||||
fake_object_schema = {
|
"metadefs/object": {
|
||||||
"additionalProperties": False,
|
"GET": (
|
||||||
"definitions": {
|
{},
|
||||||
"property": {
|
{
|
||||||
"additionalProperties": {
|
"additionalProperties": False,
|
||||||
"required": [
|
"definitions": {
|
||||||
"title",
|
"property": {
|
||||||
"type"
|
"additionalProperties": {
|
||||||
],
|
"required": [
|
||||||
"type": "object",
|
"title",
|
||||||
"properties": {
|
"type"
|
||||||
"additionalItems": {
|
],
|
||||||
"type": "boolean"
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"additionalItems": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"enum": {
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"default": {},
|
||||||
|
"minLength": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
"Default0"
|
||||||
|
},
|
||||||
|
"required": {
|
||||||
|
"$ref": "#/definitions/stringArray"
|
||||||
|
},
|
||||||
|
"maximum": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"minItems": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
"Default0"
|
||||||
|
},
|
||||||
|
"readonly": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"minimum": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"maxItems": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
"maxLength": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
"uniqueItems": {
|
||||||
|
"default": False,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"pattern": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "regex"
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enum": {
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"array",
|
||||||
|
"boolean",
|
||||||
|
"integer",
|
||||||
|
"number",
|
||||||
|
"object",
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"array",
|
||||||
|
"boolean",
|
||||||
|
"integer",
|
||||||
|
"number",
|
||||||
|
"object",
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
},
|
},
|
||||||
"enum": {
|
"positiveIntegerDefault0": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stringArray": {
|
||||||
|
"uniqueItems": True,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
|
"positiveInteger": {
|
||||||
|
"minimum": 0,
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"name": "object",
|
||||||
|
"properties": {
|
||||||
|
"created_at": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Date and time of object creation "
|
||||||
|
"(READ-ONLY)",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"title": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"default": {},
|
"self": {
|
||||||
"minLength": {
|
"type": "string"
|
||||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
|
||||||
},
|
},
|
||||||
"required": {
|
"required": {
|
||||||
"$ref": "#/definitions/stringArray"
|
"$ref": "#/definitions/stringArray"
|
||||||
},
|
},
|
||||||
"maximum": {
|
"properties": {
|
||||||
"type": "number"
|
"$ref": "#/definitions/property"
|
||||||
},
|
},
|
||||||
"minItems": {
|
"schema": {
|
||||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
|
||||||
},
|
|
||||||
"readonly": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"minimum": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"maxItems": {
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
"maxLength": {
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
"uniqueItems": {
|
|
||||||
"default": False,
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"pattern": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "regex"
|
|
||||||
},
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"enum": {
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"enum": [
|
|
||||||
"array",
|
|
||||||
"boolean",
|
|
||||||
"integer",
|
|
||||||
"number",
|
|
||||||
"object",
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"enum": [
|
|
||||||
"array",
|
|
||||||
"boolean",
|
|
||||||
"integer",
|
|
||||||
"number",
|
|
||||||
"object",
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Date and time of the last object "
|
||||||
|
"modification (READ-ONLY)",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"type": "object"
|
)
|
||||||
},
|
|
||||||
"positiveIntegerDefault0": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"stringArray": {
|
|
||||||
"uniqueItems": True,
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"positiveInteger": {
|
|
||||||
"minimum": 0,
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name"
|
|
||||||
],
|
|
||||||
"name": "object",
|
|
||||||
"properties": {
|
|
||||||
"created_at": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Date and time of object creation (READ-ONLY)",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"self": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"required": {
|
|
||||||
"$ref": "#/definitions/stringArray"
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"$ref": "#/definitions/property"
|
|
||||||
},
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Date and time of the last object modification "
|
|
||||||
"(READ-ONLY)",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FakeObjectModel = warlock.model_factory(fake_object_schema)
|
|
||||||
|
|
||||||
|
|
||||||
class TestObjectController(testtools.TestCase):
|
class TestObjectController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestObjectController, self).setUp()
|
super(TestObjectController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
self.controller = metadefs.ObjectController(self.api,
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
FakeObjectModel)
|
self.controller = metadefs.ObjectController(self.api, self.schema_api)
|
||||||
|
|
||||||
def test_list_object(self):
|
def test_list_object(self):
|
||||||
objects = list(self.controller.list(NAMESPACE1))
|
objects = list(self.controller.list(NAMESPACE1))
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.v2 import metadefs
|
from glanceclient.v2 import metadefs
|
||||||
from tests import utils
|
from tests import utils
|
||||||
|
|
||||||
@@ -25,7 +23,7 @@ PROPERTY1 = 'Property1'
|
|||||||
PROPERTY2 = 'Property2'
|
PROPERTY2 = 'Property2'
|
||||||
PROPERTYNEW = 'PropertyNew'
|
PROPERTYNEW = 'PropertyNew'
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
"/v2/metadefs/namespaces/%s/properties" % NAMESPACE1: {
|
"/v2/metadefs/namespaces/%s/properties" % NAMESPACE1: {
|
||||||
"GET": (
|
"GET": (
|
||||||
{},
|
{},
|
||||||
@@ -108,134 +106,140 @@ fixtures = {
|
|||||||
{},
|
{},
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fake_property_schema = {
|
|
||||||
"additionalProperties": False,
|
|
||||||
"definitions": {
|
|
||||||
"positiveIntegerDefault0": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"stringArray": {
|
|
||||||
"minItems": 1,
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"uniqueItems": True,
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"positiveInteger": {
|
|
||||||
"minimum": 0,
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"title",
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"name": "property",
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"minLength": {
|
|
||||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
|
||||||
},
|
|
||||||
"enum": {
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"minimum": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"maxItems": {
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
"maxLength": {
|
|
||||||
"$ref": "#/definitions/positiveInteger"
|
|
||||||
},
|
|
||||||
"uniqueItems": {
|
|
||||||
"default": False,
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"additionalItems": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"default": {},
|
|
||||||
"pattern": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "regex"
|
|
||||||
},
|
|
||||||
"required": {
|
|
||||||
"$ref": "#/definitions/stringArray"
|
|
||||||
},
|
|
||||||
"maximum": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"minItems": {
|
|
||||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
|
||||||
},
|
|
||||||
"readonly": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"enum": {
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"enum": [
|
|
||||||
"array",
|
|
||||||
"boolean",
|
|
||||||
"integer",
|
|
||||||
"number",
|
|
||||||
"object",
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"enum": [
|
|
||||||
"array",
|
|
||||||
"boolean",
|
|
||||||
"integer",
|
|
||||||
"number",
|
|
||||||
"object",
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FakePropertyModel = warlock.model_factory(fake_property_schema)
|
|
||||||
|
schema_fixtures = {
|
||||||
|
"metadefs/property": {
|
||||||
|
"GET": (
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
"additionalProperties": False,
|
||||||
|
"definitions": {
|
||||||
|
"positiveIntegerDefault0": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stringArray": {
|
||||||
|
"minItems": 1,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"uniqueItems": True,
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"positiveInteger": {
|
||||||
|
"minimum": 0,
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"title",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"name": "property",
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"minLength": {
|
||||||
|
"$ref": "#/definitions/positiveIntegerDefault0"
|
||||||
|
},
|
||||||
|
"enum": {
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"minimum": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"maxItems": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
"maxLength": {
|
||||||
|
"$ref": "#/definitions/positiveInteger"
|
||||||
|
},
|
||||||
|
"uniqueItems": {
|
||||||
|
"default": False,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"additionalItems": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"default": {},
|
||||||
|
"pattern": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "regex"
|
||||||
|
},
|
||||||
|
"required": {
|
||||||
|
"$ref": "#/definitions/stringArray"
|
||||||
|
},
|
||||||
|
"maximum": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"minItems": {
|
||||||
|
"$ref": "#/definitions/positiveIntegerDefault0"
|
||||||
|
},
|
||||||
|
"readonly": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enum": {
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"array",
|
||||||
|
"boolean",
|
||||||
|
"integer",
|
||||||
|
"number",
|
||||||
|
"object",
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"array",
|
||||||
|
"boolean",
|
||||||
|
"integer",
|
||||||
|
"number",
|
||||||
|
"object",
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestPropertyController(testtools.TestCase):
|
class TestPropertyController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPropertyController, self).setUp()
|
super(TestPropertyController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
self.controller = metadefs.PropertyController(self.api,
|
self.controller = metadefs.PropertyController(self.api,
|
||||||
FakePropertyModel)
|
self.schema_api)
|
||||||
|
|
||||||
def test_list_property(self):
|
def test_list_property(self):
|
||||||
properties = list(self.controller.list(NAMESPACE1))
|
properties = list(self.controller.list(NAMESPACE1))
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.v2 import metadefs
|
from glanceclient.v2 import metadefs
|
||||||
from tests import utils
|
from tests import utils
|
||||||
|
|
||||||
@@ -28,7 +26,7 @@ RESOURCE_TYPE4 = 'ResourceType4'
|
|||||||
RESOURCE_TYPENEW = 'ResourceTypeNew'
|
RESOURCE_TYPENEW = 'ResourceTypeNew'
|
||||||
|
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
"/v2/metadefs/namespaces/%s/resource_types" % NAMESPACE1: {
|
"/v2/metadefs/namespaces/%s/resource_types" % NAMESPACE1: {
|
||||||
"GET": (
|
"GET": (
|
||||||
{},
|
{},
|
||||||
@@ -84,64 +82,76 @@ fixtures = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fake_resource_type_schema = {
|
|
||||||
"name": "resource_type",
|
|
||||||
"properties": {
|
|
||||||
"prefix": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Specifies the prefix to use for the given "
|
|
||||||
"resource type. Any properties in the namespace "
|
|
||||||
"should be prefixed with this prefix when being "
|
|
||||||
"applied to the specified resource type. Must "
|
|
||||||
"include prefix separator (e.g. a colon :).",
|
|
||||||
"maxLength": 80
|
|
||||||
},
|
|
||||||
"properties_target": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Some resource types allow more than one "
|
|
||||||
"key / value pair per instance. For example, "
|
|
||||||
"Cinder allows user and image metadata on volumes. "
|
|
||||||
"Only the image properties metadata is evaluated "
|
|
||||||
"by Nova (scheduling or drivers). This property "
|
|
||||||
"allows a namespace target to remove the "
|
|
||||||
"ambiguity.",
|
|
||||||
"maxLength": 80
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Resource type names should be aligned with Heat "
|
|
||||||
"resource types whenever possible: http://docs."
|
|
||||||
"openstack.org/developer/heat/template_guide/"
|
|
||||||
"openstack.html",
|
|
||||||
"maxLength": 80
|
|
||||||
},
|
|
||||||
"created_at": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Date and time of resource type association"
|
|
||||||
" (READ-ONLY)",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Date and time of the last resource type "
|
|
||||||
"association modification (READ-ONLY)",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FakeRTModel = warlock.model_factory(fake_resource_type_schema)
|
|
||||||
|
schema_fixtures = {
|
||||||
|
"metadefs/resource_type": {
|
||||||
|
"GET": (
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
"name": "resource_type",
|
||||||
|
"properties": {
|
||||||
|
"prefix": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Specifies the prefix to use for the "
|
||||||
|
"given resource type. Any properties "
|
||||||
|
"in the namespace should be prefixed "
|
||||||
|
"with this prefix when being applied "
|
||||||
|
"to the specified resource type. Must "
|
||||||
|
"include prefix separator (e.g. a "
|
||||||
|
"colon :).",
|
||||||
|
"maxLength": 80
|
||||||
|
},
|
||||||
|
"properties_target": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Some resource types allow more than "
|
||||||
|
"one key / value pair per instance. "
|
||||||
|
"For example, Cinder allows user and "
|
||||||
|
"image metadata on volumes. Only the "
|
||||||
|
"image properties metadata is "
|
||||||
|
"evaluated by Nova (scheduling or "
|
||||||
|
"drivers). This property allows a "
|
||||||
|
"namespace target to remove the "
|
||||||
|
"ambiguity.",
|
||||||
|
"maxLength": 80
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Resource type names should be "
|
||||||
|
"aligned with Heat resource types "
|
||||||
|
"whenever possible: http://docs."
|
||||||
|
"openstack.org/developer/heat/"
|
||||||
|
"template_guide/openstack.html",
|
||||||
|
"maxLength": 80
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Date and time of resource type "
|
||||||
|
"association (READ-ONLY)",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Date and time of the last resource "
|
||||||
|
"type association modification "
|
||||||
|
"(READ-ONLY)",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestResoureTypeController(testtools.TestCase):
|
class TestResoureTypeController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestResoureTypeController, self).setUp()
|
super(TestResoureTypeController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
self.controller = metadefs.ResourceTypeController(self.api,
|
self.controller = metadefs.ResourceTypeController(self.api,
|
||||||
FakeRTModel)
|
self.schema_api)
|
||||||
|
|
||||||
def test_list_resource_types(self):
|
def test_list_resource_types(self):
|
||||||
resource_types = list(self.controller.list())
|
resource_types = list(self.controller.list())
|
||||||
|
@@ -14,7 +14,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
import warlock
|
|
||||||
|
|
||||||
from glanceclient.v2 import image_tags
|
from glanceclient.v2 import image_tags
|
||||||
from tests import utils
|
from tests import utils
|
||||||
@@ -24,7 +23,7 @@ IMAGE = '3a4560a1-e585-443e-9b39-553b46ec92d1'
|
|||||||
TAG = 'tag01'
|
TAG = 'tag01'
|
||||||
|
|
||||||
|
|
||||||
fixtures = {
|
data_fixtures = {
|
||||||
'/v2/images/{image}/tags/{tag_value}'.format(image=IMAGE, tag_value=TAG): {
|
'/v2/images/{image}/tags/{tag_value}'.format(image=IMAGE, tag_value=TAG): {
|
||||||
'DELETE': (
|
'DELETE': (
|
||||||
{},
|
{},
|
||||||
@@ -37,19 +36,25 @@ fixtures = {
|
|||||||
'tag_value': TAG
|
'tag_value': TAG
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schema_fixtures = {
|
||||||
fake_schema = {'name': 'image', 'properties': {'image_id': {}, 'tags': {}}}
|
'tag': {
|
||||||
FakeModel = warlock.model_factory(fake_schema)
|
'GET': (
|
||||||
|
{},
|
||||||
|
{'name': 'image', 'properties': {'image_id': {}, 'tags': {}}}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestController(testtools.TestCase):
|
class TestController(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestController, self).setUp()
|
super(TestController, self).setUp()
|
||||||
self.api = utils.FakeAPI(fixtures)
|
self.api = utils.FakeAPI(data_fixtures)
|
||||||
self.controller = image_tags.Controller(self.api, FakeModel)
|
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||||
|
self.controller = image_tags.Controller(self.api, self.schema_api)
|
||||||
|
|
||||||
def test_update_image_tag(self):
|
def test_update_image_tag(self):
|
||||||
image_id = IMAGE
|
image_id = IMAGE
|
||||||
|
Reference in New Issue
Block a user