Merge "Fix v2 requests to non-bleeding edge servers"
This commit is contained in:
@@ -21,6 +21,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
import uuid
|
||||
|
||||
import six
|
||||
@@ -36,6 +37,8 @@ from glanceclient import exc
|
||||
from glanceclient.openstack.common import importutils
|
||||
from glanceclient.openstack.common import strutils
|
||||
|
||||
_memoized_property_lock = threading.Lock()
|
||||
|
||||
|
||||
# Decorator for cli-args
|
||||
def arg(*args, **kwargs):
|
||||
@@ -367,3 +370,18 @@ def integrity_iter(iter, checksum):
|
||||
raise IOError(errno.EPIPE,
|
||||
'Corrupt image download. Checksum was %s expected %s' %
|
||||
(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
|
||||
# under the License.
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.common import http
|
||||
from glanceclient.common import utils
|
||||
@@ -38,50 +37,21 @@ class Client(object):
|
||||
self.http_client = http.HTTPClient(utils.strip_version(endpoint),
|
||||
*args, **kwargs)
|
||||
self.schemas = schemas.Controller(self.http_client)
|
||||
image_model = self._get_image_model()
|
||||
self.images = images.Controller(self.http_client,
|
||||
image_model)
|
||||
self.image_tags = image_tags.Controller(self.http_client, image_model)
|
||||
|
||||
self.images = images.Controller(self.http_client, self.schemas)
|
||||
self.image_tags = image_tags.Controller(self.http_client,
|
||||
self.schemas)
|
||||
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 = (
|
||||
metadefs.ResourceTypeController(self.http_client,
|
||||
resource_type_model))
|
||||
metadefs.ResourceTypeController(self.http_client, self.schemas))
|
||||
|
||||
property_model = self._get_metadefs_property_model()
|
||||
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 = (
|
||||
metadefs.ObjectController(self.http_client, object_model))
|
||||
metadefs.ObjectController(self.http_client, self.schemas))
|
||||
|
||||
namespace_model = self._get_metadefs_namespace_model()
|
||||
self.metadefs_namespace = (
|
||||
metadefs.NamespaceController(self.http_client, namespace_model))
|
||||
|
||||
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)
|
||||
metadefs.NamespaceController(self.http_client, self.schemas))
|
||||
|
@@ -13,11 +13,21 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
|
||||
class Controller(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
url = '/v2/images/%s/members' % image_id
|
||||
|
@@ -13,11 +13,21 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
|
||||
class Controller(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
"""
|
||||
|
@@ -21,14 +21,20 @@ import warlock
|
||||
from glanceclient.common import utils
|
||||
from glanceclient import exc
|
||||
from glanceclient.openstack.common import strutils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
|
||||
|
||||
class Controller(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
"""Retrieve a listing of Image objects
|
||||
|
@@ -19,14 +19,20 @@ import warlock
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.openstack.common import strutils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
|
||||
|
||||
class NamespaceController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
"""Create a namespace.
|
||||
@@ -75,7 +81,7 @@ class NamespaceController(object):
|
||||
|
||||
url = '/v2/metadefs/namespaces/{0}{1}'.format(namespace, query_params)
|
||||
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
|
||||
body.pop('self', None)
|
||||
return self.model(**body)
|
||||
@@ -141,9 +147,14 @@ class NamespaceController(object):
|
||||
|
||||
|
||||
class ResourceTypeController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
"""Associate a resource type with a namespace."""
|
||||
@@ -184,9 +195,14 @@ class ResourceTypeController(object):
|
||||
|
||||
|
||||
class PropertyController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
"""Create a property.
|
||||
@@ -259,9 +275,14 @@ class PropertyController(object):
|
||||
|
||||
|
||||
class ObjectController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_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):
|
||||
"""Create an object.
|
||||
|
@@ -18,6 +18,8 @@ import json
|
||||
import six
|
||||
import testtools
|
||||
|
||||
from glanceclient.v2.schemas import Schema
|
||||
|
||||
|
||||
class FakeAPI(object):
|
||||
def __init__(self, fixtures):
|
||||
@@ -60,6 +62,15 @@ class FakeAPI(object):
|
||||
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):
|
||||
def __init__(self, headers, body=None,
|
||||
version=1.0, status=200, reason="Ok"):
|
||||
|
@@ -13,7 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from mox3 import mox
|
||||
import testtools
|
||||
|
||||
from glanceclient.v2 import client
|
||||
@@ -23,21 +22,9 @@ class ClientTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
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):
|
||||
super(ClientTest, self).tearDown()
|
||||
self.mock.UnsetStubs()
|
||||
|
||||
def test_endpoint(self):
|
||||
gc = client.Client("http://example.com")
|
||||
|
@@ -15,10 +15,9 @@
|
||||
|
||||
import errno
|
||||
import json
|
||||
import testtools
|
||||
|
||||
import six
|
||||
import warlock
|
||||
import testtools
|
||||
|
||||
from glanceclient import exc
|
||||
from glanceclient.v2 import images
|
||||
@@ -39,7 +38,31 @@ _PUBLIC_ID = '857806e7-05b6-48e0-9d40-cb0e6fb727b9'
|
||||
_SHARED_ID = '331ac905-2a38-44c5-a83d-653db8f08313'
|
||||
_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: {
|
||||
'GET': (
|
||||
{},
|
||||
@@ -325,36 +348,43 @@ fixtures = {
|
||||
}
|
||||
|
||||
|
||||
fake_schema = {
|
||||
'name': 'image',
|
||||
'properties': {
|
||||
'id': {},
|
||||
'name': {},
|
||||
'locations': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'object',
|
||||
schema_fixtures = {
|
||||
'image': {
|
||||
'GET': (
|
||||
{},
|
||||
{
|
||||
'name': 'image',
|
||||
'properties': {
|
||||
'metadata': {'type': 'object'},
|
||||
'url': {'type': 'string'},
|
||||
'id': {},
|
||||
'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):
|
||||
def setUp(self):
|
||||
super(TestController, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.controller = images.Controller(self.api, FakeModel)
|
||||
self.api = utils.FakeAPI(data_fixtures)
|
||||
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||
self.controller = images.Controller(self.api, self.schema_api)
|
||||
|
||||
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())
|
||||
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', images[0].id)
|
||||
self.assertEqual('image-1', images[0].name)
|
||||
@@ -362,7 +392,7 @@ class TestController(testtools.TestCase):
|
||||
self.assertEqual('image-2', images[1].name)
|
||||
|
||||
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))
|
||||
self.assertEqual('3a4560a1-e585-443e-9b39-553b46ec92d1', images[0].id)
|
||||
self.assertEqual('image-1', images[0].name)
|
||||
@@ -571,7 +601,7 @@ class TestController(testtools.TestCase):
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
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...
|
||||
self.assertEqual('image-1', image.name)
|
||||
|
||||
@@ -590,7 +620,7 @@ class TestController(testtools.TestCase):
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
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...
|
||||
self.assertEqual('image-1', image.name)
|
||||
|
||||
@@ -609,7 +639,7 @@ class TestController(testtools.TestCase):
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
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...
|
||||
self.assertEqual('image-3', image.name)
|
||||
|
||||
@@ -622,8 +652,8 @@ class TestController(testtools.TestCase):
|
||||
expect_hdrs = {
|
||||
'Content-Type': 'application/openstack-images-v2.1-json-patch',
|
||||
}
|
||||
expect_body = '[{"path": "/barney", "value": "miller", ' \
|
||||
'"op": "replace"}]'
|
||||
expect_body = ('[{"path": "/barney", "value": "miller", '
|
||||
'"op": "replace"}]')
|
||||
expect = [
|
||||
('GET', '/v2/images/%s' % image_id, {}, None),
|
||||
('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(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...
|
||||
self.assertEqual('image-3', image.name)
|
||||
|
||||
@@ -652,7 +682,7 @@ class TestController(testtools.TestCase):
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
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...
|
||||
self.assertEqual('image-3', image.name)
|
||||
|
||||
@@ -741,7 +771,7 @@ class TestController(testtools.TestCase):
|
||||
image_id = 'a2b83adc-888e-11e3-8872-78acc0b951d8'
|
||||
new_loc = {'url': 'http://foo.com/', 'metadata': {'spam': 'ham'}}
|
||||
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[new_loc['url']] = new_loc
|
||||
mod_patch = [{'path': '/locations', 'op': 'replace',
|
||||
|
@@ -15,8 +15,6 @@
|
||||
|
||||
import testtools
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.v2 import image_members
|
||||
from tests import utils
|
||||
|
||||
@@ -25,7 +23,7 @@ IMAGE = '3a4560a1-e585-443e-9b39-553b46ec92d1'
|
||||
MEMBER = '11223344-5566-7788-9911-223344556677'
|
||||
|
||||
|
||||
fixtures = {
|
||||
data_fixtures = {
|
||||
'/v2/images/{image}/members'.format(image=IMAGE): {
|
||||
'GET': (
|
||||
{},
|
||||
@@ -58,20 +56,31 @@ fixtures = {
|
||||
'status': 'accepted'
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fake_schema = {'name': 'member', 'properties': {'image_id': {},
|
||||
'member_id': {}}}
|
||||
FakeModel = warlock.model_factory(fake_schema)
|
||||
schema_fixtures = {
|
||||
'member': {
|
||||
'GET': (
|
||||
{},
|
||||
{
|
||||
'name': 'member',
|
||||
'properties': {
|
||||
'image_id': {},
|
||||
'member_id': {}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestController(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(TestController, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.controller = image_members.Controller(self.api, FakeModel)
|
||||
self.api = utils.FakeAPI(data_fixtures)
|
||||
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||
self.controller = image_members.Controller(self.api, self.schema_api)
|
||||
|
||||
def test_list_image_members(self):
|
||||
image_id = IMAGE
|
||||
|
@@ -15,8 +15,6 @@
|
||||
|
||||
import testtools
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.v2 import metadefs
|
||||
from tests import utils
|
||||
|
||||
@@ -59,7 +57,7 @@ def _get_namespace_fixture(ns_name, rt_name=RESOURCE_TYPE1, **kwargs):
|
||||
|
||||
return ns
|
||||
|
||||
fixtures = {
|
||||
data_fixtures = {
|
||||
"/v2/metadefs/namespaces?limit=20": {
|
||||
"GET": (
|
||||
{},
|
||||
@@ -271,230 +269,243 @@ fixtures = {
|
||||
"updated_at": "2014-08-14T09:07:06Z",
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fake_namespace_schema = {
|
||||
"additionalProperties": False,
|
||||
"definitions": {
|
||||
"property": {
|
||||
"additionalProperties": {
|
||||
"required": [
|
||||
"title",
|
||||
"type"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"additionalItems": {
|
||||
"type": "boolean"
|
||||
schema_fixtures = {
|
||||
"metadefs/namespace":
|
||||
{
|
||||
"GET": (
|
||||
{},
|
||||
{
|
||||
"additionalProperties": False,
|
||||
"definitions": {
|
||||
"property": {
|
||||
"additionalProperties": {
|
||||
"required": [
|
||||
"title",
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
"positiveInteger": {
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"positiveIntegerDefault0": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/positiveInteger"
|
||||
},
|
||||
{
|
||||
"default": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"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",
|
||||
"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": {
|
||||
"$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": {
|
||||
"$ref": "#/definitions/property"
|
||||
},
|
||||
"required": {
|
||||
"$ref": "#/definitions/stringArray"
|
||||
"display_name": {
|
||||
"type": "string",
|
||||
"description": "The user friendly name for the "
|
||||
"namespace. Used by UI if available.",
|
||||
"maxLength": 80
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"created_at": {
|
||||
"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": "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):
|
||||
def setUp(self):
|
||||
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,
|
||||
FakeNamespaceModel)
|
||||
self.schema_api)
|
||||
|
||||
def test_list_namespaces(self):
|
||||
namespaces = list(self.controller.list())
|
||||
|
@@ -16,8 +16,6 @@
|
||||
import six
|
||||
import testtools
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.v2 import metadefs
|
||||
from tests import utils
|
||||
|
||||
@@ -50,8 +48,7 @@ def _get_object_fixture(ns_name, obj_name, **kwargs):
|
||||
"description": "DESCRIPTION",
|
||||
"maximum": 1000000,
|
||||
"title": "Quota: CPU Period"
|
||||
},
|
||||
},
|
||||
}},
|
||||
"schema": "/v2/schemas/metadefs/object",
|
||||
"created_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
|
||||
|
||||
fixtures = {
|
||||
data_fixtures = {
|
||||
"/v2/metadefs/namespaces/%s/objects" % NAMESPACE1: {
|
||||
"GET": (
|
||||
{},
|
||||
@@ -98,166 +95,174 @@ fixtures = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fake_object_schema = {
|
||||
"additionalProperties": False,
|
||||
"definitions": {
|
||||
"property": {
|
||||
"additionalProperties": {
|
||||
"required": [
|
||||
"title",
|
||||
"type"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"additionalItems": {
|
||||
"type": "boolean"
|
||||
schema_fixtures = {
|
||||
"metadefs/object": {
|
||||
"GET": (
|
||||
{},
|
||||
{
|
||||
"additionalProperties": False,
|
||||
"definitions": {
|
||||
"property": {
|
||||
"additionalProperties": {
|
||||
"required": [
|
||||
"title",
|
||||
"type"
|
||||
],
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"title": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": {},
|
||||
"minLength": {
|
||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
||||
"self": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"$ref": "#/definitions/stringArray"
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
"properties": {
|
||||
"$ref": "#/definitions/property"
|
||||
},
|
||||
"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"
|
||||
],
|
||||
"schema": {
|
||||
"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):
|
||||
def setUp(self):
|
||||
super(TestObjectController, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.controller = metadefs.ObjectController(self.api,
|
||||
FakeObjectModel)
|
||||
self.api = utils.FakeAPI(data_fixtures)
|
||||
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||
self.controller = metadefs.ObjectController(self.api, self.schema_api)
|
||||
|
||||
def test_list_object(self):
|
||||
objects = list(self.controller.list(NAMESPACE1))
|
||||
|
@@ -15,8 +15,6 @@
|
||||
|
||||
import testtools
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.v2 import metadefs
|
||||
from tests import utils
|
||||
|
||||
@@ -25,7 +23,7 @@ PROPERTY1 = 'Property1'
|
||||
PROPERTY2 = 'Property2'
|
||||
PROPERTYNEW = 'PropertyNew'
|
||||
|
||||
fixtures = {
|
||||
data_fixtures = {
|
||||
"/v2/metadefs/namespaces/%s/properties" % NAMESPACE1: {
|
||||
"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):
|
||||
def setUp(self):
|
||||
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,
|
||||
FakePropertyModel)
|
||||
self.schema_api)
|
||||
|
||||
def test_list_property(self):
|
||||
properties = list(self.controller.list(NAMESPACE1))
|
||||
|
@@ -15,8 +15,6 @@
|
||||
|
||||
import testtools
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.v2 import metadefs
|
||||
from tests import utils
|
||||
|
||||
@@ -28,7 +26,7 @@ RESOURCE_TYPE4 = 'ResourceType4'
|
||||
RESOURCE_TYPENEW = 'ResourceTypeNew'
|
||||
|
||||
|
||||
fixtures = {
|
||||
data_fixtures = {
|
||||
"/v2/metadefs/namespaces/%s/resource_types" % NAMESPACE1: {
|
||||
"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):
|
||||
def setUp(self):
|
||||
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,
|
||||
FakeRTModel)
|
||||
self.schema_api)
|
||||
|
||||
def test_list_resource_types(self):
|
||||
resource_types = list(self.controller.list())
|
||||
|
@@ -14,7 +14,6 @@
|
||||
# under the License.
|
||||
|
||||
import testtools
|
||||
import warlock
|
||||
|
||||
from glanceclient.v2 import image_tags
|
||||
from tests import utils
|
||||
@@ -24,7 +23,7 @@ IMAGE = '3a4560a1-e585-443e-9b39-553b46ec92d1'
|
||||
TAG = 'tag01'
|
||||
|
||||
|
||||
fixtures = {
|
||||
data_fixtures = {
|
||||
'/v2/images/{image}/tags/{tag_value}'.format(image=IMAGE, tag_value=TAG): {
|
||||
'DELETE': (
|
||||
{},
|
||||
@@ -37,19 +36,25 @@ fixtures = {
|
||||
'tag_value': TAG
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fake_schema = {'name': 'image', 'properties': {'image_id': {}, 'tags': {}}}
|
||||
FakeModel = warlock.model_factory(fake_schema)
|
||||
schema_fixtures = {
|
||||
'tag': {
|
||||
'GET': (
|
||||
{},
|
||||
{'name': 'image', 'properties': {'image_id': {}, 'tags': {}}}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestController(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(TestController, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.controller = image_tags.Controller(self.api, FakeModel)
|
||||
self.api = utils.FakeAPI(data_fixtures)
|
||||
self.schema_api = utils.FakeSchemaAPI(schema_fixtures)
|
||||
self.controller = image_tags.Controller(self.api, self.schema_api)
|
||||
|
||||
def test_update_image_tag(self):
|
||||
image_id = IMAGE
|
||||
|
Reference in New Issue
Block a user