Merge "Fix v2 requests to non-bleeding edge servers"
This commit is contained in:
@@ -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