Remove flavor API
Uses should get flavor from Nova. Change-Id: Id26d71811f94cdcf4ff188c021d4ed5613eeb8cd
This commit is contained in:
parent
feb982547a
commit
910519127d
@ -6,17 +6,7 @@
|
|||||||
"version": "5.7"
|
"version": "5.7"
|
||||||
},
|
},
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "6",
|
"id": "6"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/9f8dd5eacb074c9f87d2d822c9092aa5/flavors/6",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/6",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "b76a6a76-748b-4064-adec-4c9e6c9abd68",
|
"id": "b76a6a76-748b-4064-adec-4c9e6c9abd68",
|
||||||
"links": [
|
"links": [
|
||||||
|
@ -17,17 +17,7 @@
|
|||||||
"version": "5.7"
|
"version": "5.7"
|
||||||
},
|
},
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "6",
|
"id": "6"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/9f8dd5eacb074c9f87d2d822c9092aa5/flavors/6",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/6",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
||||||
"ip": [
|
"ip": [
|
||||||
@ -65,17 +55,7 @@
|
|||||||
"message": "Failed to create User port for instance b76a6a76-748b-4064-adec-4c9e6c9abd68"
|
"message": "Failed to create User port for instance b76a6a76-748b-4064-adec-4c9e6c9abd68"
|
||||||
},
|
},
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "6",
|
"id": "6"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/9f8dd5eacb074c9f87d2d822c9092aa5/flavors/6",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/6",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "b76a6a76-748b-4064-adec-4c9e6c9abd68",
|
"id": "b76a6a76-748b-4064-adec-4c9e6c9abd68",
|
||||||
"links": [
|
"links": [
|
||||||
|
@ -6,17 +6,7 @@
|
|||||||
"version": "5.7"
|
"version": "5.7"
|
||||||
},
|
},
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "6",
|
"id": "6"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/9f8dd5eacb074c9f87d2d822c9092aa5/flavors/6",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/6",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
||||||
"ip": [
|
"ip": [
|
||||||
|
@ -20,17 +20,7 @@
|
|||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"encrypted_rpc_messaging": true,
|
"encrypted_rpc_messaging": true,
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "d2",
|
"id": "d2"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/2afa58fd5db34fd8b7b659d997a5341f/flavors/d2",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/d2",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
||||||
"ip": [
|
"ip": [
|
||||||
@ -82,17 +72,7 @@
|
|||||||
"message": "Failed to create User port for instance b76a6a76-748b-4064-adec-4c9e6c9abd68"
|
"message": "Failed to create User port for instance b76a6a76-748b-4064-adec-4c9e6c9abd68"
|
||||||
},
|
},
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "6",
|
"id": "6"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/2afa58fd5db34fd8b7b659d997a5341f/flavors/6",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/6",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "b76a6a76-748b-4064-adec-4c9e6c9abd68",
|
"id": "b76a6a76-748b-4064-adec-4c9e6c9abd68",
|
||||||
"links": [
|
"links": [
|
||||||
|
@ -19,17 +19,7 @@
|
|||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"encrypted_rpc_messaging": true,
|
"encrypted_rpc_messaging": true,
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "d2",
|
"id": "d2"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/2afa58fd5db34fd8b7b659d997a5341f/flavors/d2",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/d2",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"guest_status": {
|
"guest_status": {
|
||||||
"state_description": "healthy"
|
"state_description": "healthy"
|
||||||
|
@ -16,17 +16,7 @@
|
|||||||
"version": "5.7"
|
"version": "5.7"
|
||||||
},
|
},
|
||||||
"flavor": {
|
"flavor": {
|
||||||
"id": "6",
|
"id": "6"
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/v1.0/9f8dd5eacb074c9f87d2d822c9092aa5/flavors/6",
|
|
||||||
"rel": "self"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "https://127.0.0.1:8779/flavors/6",
|
|
||||||
"rel": "bookmark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
"id": "7de1bed8-6983-4d46-9a52-0abfbb0d27a2",
|
||||||
"ip": [
|
"ip": [
|
||||||
|
@ -658,4 +658,4 @@ In the API response, note that the additional key
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
RESP BODY: {"instance": {"status": "ACTIVE", "updated": "2017-01-09T18:29:00", "name": "m10", "links": [{"href": "https://192.168.126.130:8779/v1.0/56cca8484d3e48869126ada4f355c284/instances/514ef051-0bf7-48a5-adcf-071d4a6625fb", "rel": "self"}, {"href": "https://192.168.126.130:8779/instances/514ef051-0bf7-48a5-adcf-071d4a6625fb", "rel": "bookmark"}], "created": "2017-01-09T18:28:56", "region": "RegionOne", "server_id": "2452263e-3d33-48ec-8f24-2851fe74db28", "id": "514ef051-0bf7-48a5-adcf-071d4a6625fb", "volume": {"used": 0.11, "size": 3}, "volume_id": "cee2e17b-80fa-48e5-a488-da8b7809373a", "flavor": {"id": "25", "links": [{"href": "https://192.168.126.130:8779/v1.0/56cca8484d3e48869126ada4f355c284/flavors/25", "rel": "self"}, {"href": "https://192.168.126.130:8779/flavors/25", "rel": "bookmark"}]}, "datastore": {"version": "5.6", "type": "mysql"}, "encrypted_rpc_messaging": false}}
|
RESP BODY: {"instance": {"status": "ACTIVE", "updated": "2017-01-09T18:29:00", "name": "m10", "links": [{"href": "https://192.168.126.130:8779/v1.0/56cca8484d3e48869126ada4f355c284/instances/514ef051-0bf7-48a5-adcf-071d4a6625fb", "rel": "self"}, {"href": "https://192.168.126.130:8779/instances/514ef051-0bf7-48a5-adcf-071d4a6625fb", "rel": "bookmark"}], "created": "2017-01-09T18:28:56", "region": "RegionOne", "server_id": "2452263e-3d33-48ec-8f24-2851fe74db28", "id": "514ef051-0bf7-48a5-adcf-071d4a6625fb", "volume": {"used": 0.11, "size": 3}, "volume_id": "cee2e17b-80fa-48e5-a488-da8b7809373a", "flavor": {"id": "25"}, "datastore": {"version": "5.6", "type": "mysql"}, "encrypted_rpc_messaging": false}}
|
||||||
|
@ -113,11 +113,7 @@ Create and use incremental backups
|
|||||||
| created | 2014-03-19T14:10:56 |
|
| created | 2014-03-19T14:10:56 |
|
||||||
| datastore | {u'version': u'mysql-5.5', u'type': u'mysql'} |
|
| datastore | {u'version': u'mysql-5.5', u'type': u'mysql'} |
|
||||||
| datastore_version | mysql-5.5 |
|
| datastore_version | mysql-5.5 |
|
||||||
| flavor | {u'id': u'10', u'links': |
|
| flavor | {u'id': u'10'} |
|
||||||
| | [{u'href': u'https://10.125.1.135:8779/v1.0/ |
|
|
||||||
| | 626734041baa4254ae316de52a20b390/flavors/10', u'rel': |
|
|
||||||
| | u'self'}, {u'href': u'https://10.125.1.135:8779/ |
|
|
||||||
| | flavors/10', u'rel': u'bookmark'}]} |
|
|
||||||
| id | a3680953-eea9-4cf2-918b-5b8e49d7e1b3 |
|
| id | a3680953-eea9-4cf2-918b-5b8e49d7e1b3 |
|
||||||
| name | guest2 |
|
| name | guest2 |
|
||||||
| status | BUILD |
|
| status | BUILD |
|
||||||
|
@ -102,10 +102,7 @@ class ClusterView(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _build_flavor_info(self, flavor_id):
|
def _build_flavor_info(self, flavor_id):
|
||||||
return {
|
return {"id": flavor_id}
|
||||||
"id": flavor_id,
|
|
||||||
"links": create_links("flavors", self.req, flavor_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ClusterInstanceDetailView(InstanceDetailView):
|
class ClusterInstanceDetailView(InstanceDetailView):
|
||||||
|
@ -20,7 +20,6 @@ from trove.common import wsgi
|
|||||||
from trove.configuration.service import ConfigurationsController
|
from trove.configuration.service import ConfigurationsController
|
||||||
from trove.configuration.service import ParametersController
|
from trove.configuration.service import ParametersController
|
||||||
from trove.datastore.service import DatastoreController
|
from trove.datastore.service import DatastoreController
|
||||||
from trove.flavor.service import FlavorController
|
|
||||||
from trove.instance.service import InstanceController
|
from trove.instance.service import InstanceController
|
||||||
from trove.limits.service import LimitsController
|
from trove.limits.service import LimitsController
|
||||||
from trove.module.service import ModuleController
|
from trove.module.service import ModuleController
|
||||||
@ -35,7 +34,6 @@ class API(wsgi.Router):
|
|||||||
self._instance_router(mapper)
|
self._instance_router(mapper)
|
||||||
self._cluster_router(mapper)
|
self._cluster_router(mapper)
|
||||||
self._datastore_router(mapper)
|
self._datastore_router(mapper)
|
||||||
self._flavor_router(mapper)
|
|
||||||
self._versions_router(mapper)
|
self._versions_router(mapper)
|
||||||
self._limits_router(mapper)
|
self._limits_router(mapper)
|
||||||
self._backups_router(mapper)
|
self._backups_router(mapper)
|
||||||
@ -168,17 +166,6 @@ class API(wsgi.Router):
|
|||||||
action="delete",
|
action="delete",
|
||||||
conditions={'method': ['DELETE']})
|
conditions={'method': ['DELETE']})
|
||||||
|
|
||||||
def _flavor_router(self, mapper):
|
|
||||||
flavor_resource = FlavorController().create_resource()
|
|
||||||
mapper.connect("/{tenant_id}/flavors",
|
|
||||||
controller=flavor_resource,
|
|
||||||
action="index",
|
|
||||||
conditions={'method': ['GET']})
|
|
||||||
mapper.connect("/{tenant_id}/flavors/{id}",
|
|
||||||
controller=flavor_resource,
|
|
||||||
action="show",
|
|
||||||
conditions={'method': ['GET']})
|
|
||||||
|
|
||||||
def _limits_router(self, mapper):
|
def _limits_router(self, mapper):
|
||||||
limits_resource = LimitsController().create_resource()
|
limits_resource = LimitsController().create_resource()
|
||||||
mapper.connect("/{tenant_id}/limits",
|
mapper.connect("/{tenant_id}/limits",
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
# Copyright 2010-2012 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from trove.common import exception
|
|
||||||
from trove.common import policy
|
|
||||||
from trove.common import wsgi
|
|
||||||
from trove.flavor import models
|
|
||||||
from trove.flavor import views
|
|
||||||
|
|
||||||
|
|
||||||
class FlavorController(wsgi.Controller):
|
|
||||||
"""Controller for flavor functionality."""
|
|
||||||
|
|
||||||
def show(self, req, tenant_id, id):
|
|
||||||
"""Return a single flavor."""
|
|
||||||
context = req.environ[wsgi.CONTEXT_KEY]
|
|
||||||
self._validate_flavor_id(id)
|
|
||||||
flavor = models.Flavor(context=context, flavor_id=id)
|
|
||||||
# Flavors do not bind to a particular tenant.
|
|
||||||
# Only authorize the current tenant.
|
|
||||||
policy.authorize_on_tenant(context, 'flavor:show')
|
|
||||||
# Pass in the request to build accurate links.
|
|
||||||
return wsgi.Result(views.FlavorView(flavor, req).data(), 200)
|
|
||||||
|
|
||||||
def index(self, req, tenant_id):
|
|
||||||
"""Return all flavors."""
|
|
||||||
context = req.environ[wsgi.CONTEXT_KEY]
|
|
||||||
policy.authorize_on_tenant(context, 'flavor:index')
|
|
||||||
flavors = models.Flavors(context=context)
|
|
||||||
return wsgi.Result(views.FlavorsView(flavors, req).data(), 200)
|
|
||||||
|
|
||||||
def _validate_flavor_id(self, id):
|
|
||||||
if isinstance(id, six.string_types):
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
if int(id) != float(id):
|
|
||||||
raise exception.NotFound(uuid=id)
|
|
||||||
except ValueError:
|
|
||||||
raise exception.NotFound(uuid=id)
|
|
@ -72,13 +72,8 @@ class InstanceView(object):
|
|||||||
def _build_flavor_info(self):
|
def _build_flavor_info(self):
|
||||||
return {
|
return {
|
||||||
"id": self.instance.flavor_id,
|
"id": self.instance.flavor_id,
|
||||||
"links": self._build_flavor_links()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def _build_flavor_links(self):
|
|
||||||
return create_links("flavors", self.req,
|
|
||||||
self.instance.flavor_id)
|
|
||||||
|
|
||||||
def _build_master_info(self):
|
def _build_master_info(self):
|
||||||
return {
|
return {
|
||||||
"id": self.instance.slave_of_id,
|
"id": self.instance.slave_of_id,
|
||||||
|
@ -36,6 +36,7 @@ from trove.common.utils import poll_until
|
|||||||
from trove.datastore import models as datastore_models
|
from trove.datastore import models as datastore_models
|
||||||
from trove import tests
|
from trove import tests
|
||||||
from trove.tests.config import CONFIG
|
from trove.tests.config import CONFIG
|
||||||
|
from trove.tests import util
|
||||||
from trove.tests.util.check import AttrCheck
|
from trove.tests.util.check import AttrCheck
|
||||||
from trove.tests.util import create_dbaas_client
|
from trove.tests.util import create_dbaas_client
|
||||||
from trove.tests.util import test_config
|
from trove.tests.util import test_config
|
||||||
@ -88,6 +89,7 @@ class InstanceTestInfo(object):
|
|||||||
self.user_context = None # A regular user context
|
self.user_context = None # A regular user context
|
||||||
self.users = None # The users created on the instance.
|
self.users = None # The users created on the instance.
|
||||||
self.consumer = create_usage_verifier()
|
self.consumer = create_usage_verifier()
|
||||||
|
self.flavors = None # The cache of Nova flavors.
|
||||||
|
|
||||||
def find_default_flavor(self):
|
def find_default_flavor(self):
|
||||||
if EPHEMERAL_SUPPORT:
|
if EPHEMERAL_SUPPORT:
|
||||||
@ -96,15 +98,17 @@ class InstanceTestInfo(object):
|
|||||||
else:
|
else:
|
||||||
flavor_name = CONFIG.values.get('instance_flavor_name', 'm1.tiny')
|
flavor_name = CONFIG.values.get('instance_flavor_name', 'm1.tiny')
|
||||||
|
|
||||||
flavors = self.dbaas.find_flavors_by_name(flavor_name)
|
flavor = None
|
||||||
assert_equal(len(flavors), 1,
|
flavor_href = None
|
||||||
"Number of flavors with name '%s' "
|
|
||||||
"found was '%d'." % (flavor_name, len(flavors)))
|
|
||||||
|
|
||||||
flavor = flavors[0]
|
for item in self.flavors:
|
||||||
flavor_href = self.dbaas.find_flavor_self_href(flavor)
|
if item.name == flavor_name:
|
||||||
assert_true(flavor_href is not None,
|
flavor = item
|
||||||
"Flavor href '%s' not found!" % flavor_name)
|
flavor_href = item.id
|
||||||
|
break
|
||||||
|
|
||||||
|
asserts.assert_is_not_none(flavor)
|
||||||
|
asserts.assert_is_not_none(flavor_href)
|
||||||
|
|
||||||
return flavor, flavor_href
|
return flavor, flavor_href
|
||||||
|
|
||||||
@ -190,11 +194,10 @@ class CheckInstance(AttrCheck):
|
|||||||
if 'flavor' not in self.instance:
|
if 'flavor' not in self.instance:
|
||||||
self.fail("'flavor' not found in instance.")
|
self.fail("'flavor' not found in instance.")
|
||||||
else:
|
else:
|
||||||
allowed_attrs = ['id', 'links']
|
allowed_attrs = ['id']
|
||||||
self.contains_allowed_attrs(
|
self.contains_allowed_attrs(
|
||||||
self.instance['flavor'], allowed_attrs,
|
self.instance['flavor'], allowed_attrs,
|
||||||
msg="Flavor")
|
msg="Flavor")
|
||||||
self.links(self.instance['flavor']['links'])
|
|
||||||
|
|
||||||
def datastore(self):
|
def datastore(self):
|
||||||
if 'datastore' not in self.instance:
|
if 'datastore' not in self.instance:
|
||||||
@ -315,6 +318,10 @@ class TestInstanceSetup(object):
|
|||||||
instance_info.user = CONFIG.users.find_user(reqs)
|
instance_info.user = CONFIG.users.find_user(reqs)
|
||||||
|
|
||||||
instance_info.dbaas = create_dbaas_client(instance_info.user)
|
instance_info.dbaas = create_dbaas_client(instance_info.user)
|
||||||
|
|
||||||
|
instance_info.nova_client = util.create_nova_client(instance_info.user)
|
||||||
|
instance_info.flavors = instance_info.nova_client.flavors.list()
|
||||||
|
|
||||||
global dbaas
|
global dbaas
|
||||||
dbaas = instance_info.dbaas
|
dbaas = instance_info.dbaas
|
||||||
|
|
||||||
@ -563,10 +570,16 @@ class CreateInstanceFail(object):
|
|||||||
instance_name = "instance-failure-with-no-ephemeral-flavor"
|
instance_name = "instance-failure-with-no-ephemeral-flavor"
|
||||||
databases = []
|
databases = []
|
||||||
flavor_name = CONFIG.values.get('instance_flavor_name', 'm1.tiny')
|
flavor_name = CONFIG.values.get('instance_flavor_name', 'm1.tiny')
|
||||||
flavors = dbaas.find_flavors_by_name(flavor_name)
|
|
||||||
|
flavor_id = None
|
||||||
|
for item in instance_info.flavors:
|
||||||
|
if item.name == flavor_name:
|
||||||
|
flavor_id = item.id
|
||||||
|
|
||||||
|
asserts.assert_is_not_none(flavor_id)
|
||||||
|
|
||||||
assert_raises(exceptions.BadRequest, dbaas.instances.create,
|
assert_raises(exceptions.BadRequest, dbaas.instances.create,
|
||||||
instance_name, flavors[0].id, None, databases,
|
instance_name, flavor_id, None, databases,
|
||||||
nics=instance_info.nics)
|
nics=instance_info.nics)
|
||||||
assert_equal(400, dbaas.last_http_code)
|
assert_equal(400, dbaas.last_http_code)
|
||||||
|
|
||||||
|
@ -367,11 +367,6 @@ class ResizeInstanceTest(ActionTestBase):
|
|||||||
def flavor_id(self):
|
def flavor_id(self):
|
||||||
return instance_info.dbaas_flavor_href
|
return instance_info.dbaas_flavor_href
|
||||||
|
|
||||||
def get_flavor_href(self, flavor_id=2):
|
|
||||||
res = instance_info.dbaas.find_flavor_and_self_href(flavor_id)
|
|
||||||
_, dbaas_flavor_href = res
|
|
||||||
return dbaas_flavor_href
|
|
||||||
|
|
||||||
def wait_for_resize(self):
|
def wait_for_resize(self):
|
||||||
def is_finished_resizing():
|
def is_finished_resizing():
|
||||||
instance = self.instance
|
instance = self.instance
|
||||||
@ -399,7 +394,12 @@ class ResizeInstanceTest(ActionTestBase):
|
|||||||
def test_instance_resize_to_ephemeral_in_volume_support_should_fail(self):
|
def test_instance_resize_to_ephemeral_in_volume_support_should_fail(self):
|
||||||
flavor_name = CONFIG.values.get('instance_bigger_eph_flavor_name',
|
flavor_name = CONFIG.values.get('instance_bigger_eph_flavor_name',
|
||||||
'eph.rd-smaller')
|
'eph.rd-smaller')
|
||||||
flavors = self.dbaas.find_flavors_by_name(flavor_name)
|
flavor_id = None
|
||||||
|
for item in instance_info.flavors:
|
||||||
|
if item.name == flavor_name:
|
||||||
|
flavor_id = item.id
|
||||||
|
|
||||||
|
asserts.assert_is_not_none(flavor_id)
|
||||||
|
|
||||||
def is_active():
|
def is_active():
|
||||||
return self.instance.status in CONFIG.running_status
|
return self.instance.status in CONFIG.running_status
|
||||||
@ -409,36 +409,42 @@ class ResizeInstanceTest(ActionTestBase):
|
|||||||
|
|
||||||
asserts.assert_raises(HTTPNotImplemented,
|
asserts.assert_raises(HTTPNotImplemented,
|
||||||
self.dbaas.instances.resize_instance,
|
self.dbaas.instances.resize_instance,
|
||||||
self.instance_id, flavors[0].id)
|
self.instance_id, flavor_id)
|
||||||
|
|
||||||
@test(enabled=EPHEMERAL_SUPPORT)
|
@test(enabled=EPHEMERAL_SUPPORT)
|
||||||
def test_instance_resize_to_non_ephemeral_flavor_should_fail(self):
|
def test_instance_resize_to_non_ephemeral_flavor_should_fail(self):
|
||||||
flavor_name = CONFIG.values.get('instance_bigger_flavor_name',
|
flavor_name = CONFIG.values.get('instance_bigger_flavor_name',
|
||||||
'm1-small')
|
'm1-small')
|
||||||
flavors = self.dbaas.find_flavors_by_name(flavor_name)
|
flavor_id = None
|
||||||
|
for item in instance_info.flavors:
|
||||||
|
if item.name == flavor_name:
|
||||||
|
flavor_id = item.id
|
||||||
|
|
||||||
|
asserts.assert_is_not_none(flavor_id)
|
||||||
asserts.assert_raises(BadRequest, self.dbaas.instances.resize_instance,
|
asserts.assert_raises(BadRequest, self.dbaas.instances.resize_instance,
|
||||||
self.instance_id, flavors[0].id)
|
self.instance_id, flavor_id)
|
||||||
|
|
||||||
def obtain_flavor_ids(self):
|
def obtain_flavor_ids(self):
|
||||||
old_id = self.instance.flavor['id']
|
old_id = self.instance.flavor['id']
|
||||||
self.expected_old_flavor_id = old_id
|
self.expected_old_flavor_id = old_id
|
||||||
res = instance_info.dbaas.find_flavor_and_self_href(old_id)
|
|
||||||
self.expected_dbaas_flavor, _ = res
|
|
||||||
if EPHEMERAL_SUPPORT:
|
if EPHEMERAL_SUPPORT:
|
||||||
flavor_name = CONFIG.values.get('instance_bigger_eph_flavor_name',
|
flavor_name = CONFIG.values.get('instance_bigger_eph_flavor_name',
|
||||||
'eph.rd-smaller')
|
'eph.rd-smaller')
|
||||||
else:
|
else:
|
||||||
flavor_name = CONFIG.values.get('instance_bigger_flavor_name',
|
flavor_name = CONFIG.values.get('instance_bigger_flavor_name',
|
||||||
'm1.small')
|
'm1.small')
|
||||||
flavors = self.dbaas.find_flavors_by_name(flavor_name)
|
|
||||||
asserts.assert_equal(len(flavors), 1,
|
new_flavor = None
|
||||||
"Number of flavors with name '%s' "
|
for item in instance_info.flavors:
|
||||||
"found was '%d'." % (flavor_name,
|
if item.name == flavor_name:
|
||||||
len(flavors)))
|
new_flavor = item
|
||||||
flavor = flavors[0]
|
break
|
||||||
|
|
||||||
|
asserts.assert_is_not_none(new_flavor)
|
||||||
|
|
||||||
self.old_dbaas_flavor = instance_info.dbaas_flavor
|
self.old_dbaas_flavor = instance_info.dbaas_flavor
|
||||||
instance_info.dbaas_flavor = flavor
|
instance_info.dbaas_flavor = new_flavor
|
||||||
self.expected_new_flavor_id = flavor.id
|
self.expected_new_flavor_id = new_flavor.id
|
||||||
|
|
||||||
@test(depends_on=[test_instance_resize_same_size_should_fail])
|
@test(depends_on=[test_instance_resize_same_size_should_fail])
|
||||||
def test_status_changed_to_resize(self):
|
def test_status_changed_to_resize(self):
|
||||||
@ -447,14 +453,14 @@ class ResizeInstanceTest(ActionTestBase):
|
|||||||
self.obtain_flavor_ids()
|
self.obtain_flavor_ids()
|
||||||
self.dbaas.instances.resize_instance(
|
self.dbaas.instances.resize_instance(
|
||||||
self.instance_id,
|
self.instance_id,
|
||||||
self.get_flavor_href(flavor_id=self.expected_new_flavor_id))
|
self.expected_new_flavor_id)
|
||||||
asserts.assert_equal(202, self.dbaas.last_http_code)
|
asserts.assert_equal(202, self.dbaas.last_http_code)
|
||||||
|
|
||||||
# (WARNING) IF THE RESIZE IS WAY TOO FAST THIS WILL FAIL
|
# (WARNING) IF THE RESIZE IS WAY TOO FAST THIS WILL FAIL
|
||||||
assert_unprocessable(
|
assert_unprocessable(
|
||||||
self.dbaas.instances.resize_instance,
|
self.dbaas.instances.resize_instance,
|
||||||
self.instance_id,
|
self.instance_id,
|
||||||
self.get_flavor_href(flavor_id=self.expected_new_flavor_id))
|
self.expected_new_flavor_id)
|
||||||
|
|
||||||
@test(depends_on=[test_status_changed_to_resize])
|
@test(depends_on=[test_status_changed_to_resize])
|
||||||
@time_out(TIME_OUT_TIME)
|
@time_out(TIME_OUT_TIME)
|
||||||
@ -493,9 +499,8 @@ class ResizeInstanceTest(ActionTestBase):
|
|||||||
|
|
||||||
@test(depends_on=[test_make_sure_mysql_is_running_after_resize])
|
@test(depends_on=[test_make_sure_mysql_is_running_after_resize])
|
||||||
def test_instance_has_new_flavor_after_resize(self):
|
def test_instance_has_new_flavor_after_resize(self):
|
||||||
actual = self.get_flavor_href(self.instance.flavor['id'])
|
actual = self.instance.flavor['id']
|
||||||
expected = self.get_flavor_href(flavor_id=self.expected_new_flavor_id)
|
asserts.assert_equal(actual, self.expected_new_flavor_id)
|
||||||
asserts.assert_equal(actual, expected)
|
|
||||||
|
|
||||||
|
|
||||||
@test(depends_on_classes=[ResizeInstanceTest],
|
@test(depends_on_classes=[ResizeInstanceTest],
|
||||||
|
@ -1,293 +0,0 @@
|
|||||||
# Copyright 2014 Rackspace
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
|
|
||||||
from proboscis.asserts import fail
|
|
||||||
from six.moves.urllib.parse import urlparse
|
|
||||||
from troveclient.compat.client import TroveHTTPClient
|
|
||||||
|
|
||||||
from trove.tests.config import CONFIG
|
|
||||||
|
|
||||||
print_req = True
|
|
||||||
|
|
||||||
|
|
||||||
def shorten_url(url):
|
|
||||||
parsed = urlparse(url)
|
|
||||||
if parsed.query:
|
|
||||||
method_url = parsed.path + '?' + parsed.query
|
|
||||||
else:
|
|
||||||
method_url = parsed.path
|
|
||||||
return method_url
|
|
||||||
|
|
||||||
|
|
||||||
class SnippetWriter(object):
|
|
||||||
|
|
||||||
def __init__(self, conf, get_replace_list):
|
|
||||||
self.conf = conf
|
|
||||||
self.get_replace_list = get_replace_list
|
|
||||||
|
|
||||||
def output_request(self, user_details, name, url, output_headers, body,
|
|
||||||
content_type, method, static_auth_token=True):
|
|
||||||
headers = []
|
|
||||||
parsed = urlparse(url)
|
|
||||||
method_url = shorten_url(url)
|
|
||||||
headers.append("%s %s HTTP/1.1" % (method, method_url))
|
|
||||||
headers.append("User-Agent: %s" % output_headers['User-Agent'])
|
|
||||||
headers.append("Host: %s" % parsed.netloc)
|
|
||||||
# static_auth_token option for documentation purposes
|
|
||||||
if static_auth_token:
|
|
||||||
output_token = '87c6033c-9ff6-405f-943e-2deb73f278b7'
|
|
||||||
else:
|
|
||||||
output_token = output_headers['X-Auth-Token']
|
|
||||||
headers.append("X-Auth-Token: %s" % output_token)
|
|
||||||
headers.append("Accept: %s" % output_headers['Accept'])
|
|
||||||
print("OUTPUT HEADERS: %s" % output_headers)
|
|
||||||
headers.append("Content-Type: %s" % output_headers['Content-Type'])
|
|
||||||
self.write_file(user_details, name, "-%s-http.txt" % content_type, url,
|
|
||||||
method, "request", output='\n'.join(headers))
|
|
||||||
|
|
||||||
pretty_body = self.format_body(body, content_type)
|
|
||||||
self.write_file(user_details, name, ".%s" % content_type, url,
|
|
||||||
method, "request", output=pretty_body)
|
|
||||||
|
|
||||||
def output_response(self, user_details, name, content_type, url, method,
|
|
||||||
resp, body):
|
|
||||||
version = "1.1" # if resp.version == 11 else "1.0"
|
|
||||||
lines = [
|
|
||||||
["HTTP/%s %s %s" % (version, resp.status, resp.reason)],
|
|
||||||
["Content-Type: %s" % resp['content-type']],
|
|
||||||
]
|
|
||||||
if 'via' in resp:
|
|
||||||
lines.append(["Via: %s" % resp['via']])
|
|
||||||
lines.append(["Content-Length: %s" % resp['content-length']])
|
|
||||||
lines.append(["Date: Mon, 18 Mar 2013 19:09:17 GMT"])
|
|
||||||
if 'server' in resp:
|
|
||||||
lines.append(["Server: %s" % resp["server"]])
|
|
||||||
|
|
||||||
new_lines = [x[0] for x in lines]
|
|
||||||
joined_lines = '\n'.join(new_lines)
|
|
||||||
|
|
||||||
self.write_file(user_details, name, "-%s-http.txt" % content_type, url,
|
|
||||||
method, "response", output=joined_lines)
|
|
||||||
|
|
||||||
if body:
|
|
||||||
pretty_body = self.format_body(body, content_type)
|
|
||||||
self.write_file(user_details, name, ".%s" % content_type, url,
|
|
||||||
method, "response", output=pretty_body)
|
|
||||||
|
|
||||||
def format_body(self, body, content_type):
|
|
||||||
assert content_type == 'json'
|
|
||||||
try:
|
|
||||||
if self.conf['replace_dns_hostname']:
|
|
||||||
before = r'\"hostname\": \"[a-zA-Z0-9-_\.]*\"'
|
|
||||||
after = '\"hostname\": \"%s\"' % self.conf[
|
|
||||||
'replace_dns_hostname']
|
|
||||||
body = re.sub(before, after, body)
|
|
||||||
return json.dumps(json.loads(body), sort_keys=True, indent=4)
|
|
||||||
except Exception:
|
|
||||||
return body or ''
|
|
||||||
|
|
||||||
def write_request_file(self, user_details, name, content_type, url, method,
|
|
||||||
req_headers, request_body):
|
|
||||||
if print_req:
|
|
||||||
print("\t%s req url:%s" % (content_type, url))
|
|
||||||
print("\t%s req method:%s" % (content_type, method))
|
|
||||||
print("\t%s req headers:%s" % (content_type, req_headers))
|
|
||||||
print("\t%s req body:%s" % (content_type, request_body))
|
|
||||||
self.output_request(user_details, name, url, req_headers, request_body,
|
|
||||||
content_type, method)
|
|
||||||
|
|
||||||
def write_response_file(self, user_details, name, content_type, url,
|
|
||||||
method, resp, resp_content):
|
|
||||||
if print_req:
|
|
||||||
print("\t%s resp:%s" % (content_type, resp))
|
|
||||||
print("\t%s resp content:%s" % (content_type, resp_content))
|
|
||||||
self.output_response(user_details, name, content_type, url, method,
|
|
||||||
resp, resp_content)
|
|
||||||
|
|
||||||
def write_file(self, user_details, name, content_type, url, method,
|
|
||||||
in_or_out, output):
|
|
||||||
output = output.replace(user_details['tenant'], '1234')
|
|
||||||
if self.conf['replace_host']:
|
|
||||||
output = output.replace(user_details['api_url'],
|
|
||||||
self.conf['replace_host'])
|
|
||||||
pre_host_port = urlparse(user_details['service_url']).netloc
|
|
||||||
post_host = urlparse(self.conf['replace_host']).netloc
|
|
||||||
output = output.replace(pre_host_port, post_host)
|
|
||||||
output = output.replace("fake_host", "hostname")
|
|
||||||
output = output.replace("FAKE_", "")
|
|
||||||
for resource in self.get_replace_list():
|
|
||||||
output = output.replace(str(resource[0]), str(resource[1]))
|
|
||||||
filename = "%s/db-%s-%s%s" % (self.conf['directory'],
|
|
||||||
name.replace('_', '-'), in_or_out,
|
|
||||||
content_type)
|
|
||||||
self._write_file(filename, output)
|
|
||||||
|
|
||||||
def _write_file(self, filename, output):
|
|
||||||
empty = len(output.strip()) == 0
|
|
||||||
# Manipulate actual data to appease doc niceness checks
|
|
||||||
actual = [line.rstrip() for line in output.split("\n")]
|
|
||||||
if not empty and actual[len(actual) - 1] != '':
|
|
||||||
actual.append("")
|
|
||||||
|
|
||||||
def goofy_diff(a, b):
|
|
||||||
diff = []
|
|
||||||
for i in range(len(a)):
|
|
||||||
if i < len(b):
|
|
||||||
if a[i].rstrip() != b[i].rstrip():
|
|
||||||
diff.append('Expected line %d :%s\n'
|
|
||||||
' Actual line %d :%s'
|
|
||||||
% (i + 1, a[i], i + 1, b[i]))
|
|
||||||
else:
|
|
||||||
diff.append("Expected line %d :%s" % (i + 1, a[i]))
|
|
||||||
for j in range(len(b) - len(a)):
|
|
||||||
i2 = len(a) + j
|
|
||||||
diff.append(" Actual line %d :%s" % (i2 + 1, b[i2]))
|
|
||||||
return diff
|
|
||||||
|
|
||||||
def write_actual_file():
|
|
||||||
# Always write the file.
|
|
||||||
with open(filename, "w") as file:
|
|
||||||
for line in actual:
|
|
||||||
file.write("%s\n" % line)
|
|
||||||
|
|
||||||
def assert_output_matches():
|
|
||||||
if os.path.isfile(filename):
|
|
||||||
with open(filename, 'r') as original_file:
|
|
||||||
original = original_file.read()
|
|
||||||
if empty:
|
|
||||||
fail('Error: output missing in new snippet generation '
|
|
||||||
'for %s. Old content follows:\n"""%s"""'
|
|
||||||
% (filename, original))
|
|
||||||
elif filename.endswith('.json'):
|
|
||||||
assert_json_matches(original)
|
|
||||||
else:
|
|
||||||
assert_file_matches(original)
|
|
||||||
elif not empty:
|
|
||||||
fail('Error: new file necessary where there was no file '
|
|
||||||
'before. Filename=%s\nContent follows:\n"""%s"""'
|
|
||||||
% (filename, output))
|
|
||||||
|
|
||||||
def assert_file_matches(original):
|
|
||||||
expected = original.split('\n')
|
|
||||||
# Remove the last item which will look like a duplicated
|
|
||||||
# file ending newline
|
|
||||||
expected.pop()
|
|
||||||
diff = '\n'.join(goofy_diff(expected, actual))
|
|
||||||
if diff:
|
|
||||||
fail('Error: output files differ for %s:\n%s'
|
|
||||||
% (filename, diff))
|
|
||||||
|
|
||||||
def order_json(json_obj):
|
|
||||||
"""Sort the json object so that it can be compared properly."""
|
|
||||||
if isinstance(json_obj, list):
|
|
||||||
return sorted(order_json(elem) for elem in json_obj)
|
|
||||||
if isinstance(json_obj, dict):
|
|
||||||
return sorted(
|
|
||||||
(key, order_json(value))
|
|
||||||
for key, value in json_obj.items())
|
|
||||||
else:
|
|
||||||
return json_obj
|
|
||||||
|
|
||||||
def assert_json_matches(original):
|
|
||||||
try:
|
|
||||||
expected_json = json.loads(original)
|
|
||||||
actual_json = json.loads(output)
|
|
||||||
except ValueError:
|
|
||||||
fail('Invalid json!\nExpected: %s\nActual: %s'
|
|
||||||
% (original, output))
|
|
||||||
|
|
||||||
if order_json(expected_json) != order_json(actual_json):
|
|
||||||
# Re-Use the same failure output if the json is different
|
|
||||||
assert_file_matches(original)
|
|
||||||
|
|
||||||
if not os.environ.get('TESTS_FIX_EXAMPLES'):
|
|
||||||
assert_output_matches()
|
|
||||||
elif not empty:
|
|
||||||
write_actual_file()
|
|
||||||
|
|
||||||
|
|
||||||
# This method is mixed into the client class.
|
|
||||||
# It requires the following fields: snippet_writer, content_type, and
|
|
||||||
# "name," the last of which must be set before each call.
|
|
||||||
def write_to_snippet(self, args, kwargs, resp, body):
|
|
||||||
if self.name is None:
|
|
||||||
raise RuntimeError("'name' not set before call.")
|
|
||||||
url = args[0]
|
|
||||||
method = args[1]
|
|
||||||
request_headers = kwargs['headers']
|
|
||||||
request_body = kwargs.get('body', None)
|
|
||||||
response_headers = resp
|
|
||||||
response_body = body
|
|
||||||
|
|
||||||
# Log request
|
|
||||||
user_details = {
|
|
||||||
'api_url': self.service_url,
|
|
||||||
'service_url': self.service_url,
|
|
||||||
'tenant': self.tenant,
|
|
||||||
}
|
|
||||||
self.snippet_writer.write_request_file(user_details, self.name,
|
|
||||||
self.content_type, url, method,
|
|
||||||
request_headers, request_body)
|
|
||||||
self.snippet_writer.write_response_file(user_details, self.name,
|
|
||||||
self.content_type, url, method,
|
|
||||||
response_headers, response_body)
|
|
||||||
|
|
||||||
# Create a short url to assert against.
|
|
||||||
short_url = url
|
|
||||||
base_url = self.service_url
|
|
||||||
for prefix in (base_url):
|
|
||||||
if short_url.startswith(prefix):
|
|
||||||
short_url = short_url[len(prefix):]
|
|
||||||
self.old_info = {
|
|
||||||
'url': shorten_url(short_url),
|
|
||||||
'method': method,
|
|
||||||
'request_headers': request_headers,
|
|
||||||
'request_body': request_body,
|
|
||||||
'response_headers': response_headers,
|
|
||||||
'response_body': response_body
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def add_fake_response_headers(headers):
|
|
||||||
"""
|
|
||||||
Fakes other items that would appear if you were using, just to make up
|
|
||||||
an example, a proxy.
|
|
||||||
"""
|
|
||||||
conf = CONFIG.examples
|
|
||||||
if 'via' in conf and 'via' not in headers:
|
|
||||||
headers['via'] = conf['via']
|
|
||||||
if 'server' in conf and 'server' not in headers:
|
|
||||||
headers['server'] = conf['server']
|
|
||||||
if 'date' not in headers:
|
|
||||||
date_string = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
|
|
||||||
headers['date'] = date_string
|
|
||||||
|
|
||||||
|
|
||||||
class JsonClient(TroveHTTPClient):
|
|
||||||
|
|
||||||
content_type = 'json'
|
|
||||||
|
|
||||||
def http_log(self, args, kwargs, resp, body):
|
|
||||||
add_fake_response_headers(resp)
|
|
||||||
self.pretty_log(args, kwargs, resp, body)
|
|
||||||
|
|
||||||
def write_snippet():
|
|
||||||
return write_to_snippet(self, args, kwargs, resp, body.decode())
|
|
||||||
|
|
||||||
self.write_snippet = write_snippet
|
|
File diff suppressed because it is too large
Load Diff
@ -183,6 +183,7 @@ class InstanceTestInfo(object):
|
|||||||
self.helper_user = None # Test helper user if exists.
|
self.helper_user = None # Test helper user if exists.
|
||||||
self.helper_database = None # Test helper database if exists.
|
self.helper_database = None # Test helper database if exists.
|
||||||
self.admin_user = None
|
self.admin_user = None
|
||||||
|
self.flavors = None
|
||||||
|
|
||||||
|
|
||||||
class LogOnFail(type):
|
class LogOnFail(type):
|
||||||
@ -368,6 +369,8 @@ class TestRunner(object):
|
|||||||
inst_ids = [self.instance_info.id]
|
inst_ids = [self.instance_info.id]
|
||||||
self.register_debug_inst_ids(inst_ids)
|
self.register_debug_inst_ids(inst_ids)
|
||||||
|
|
||||||
|
self.instance_info.flavors = self.nova_client.flavors.list()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fail(cls, message):
|
def fail(cls, message):
|
||||||
asserts.fail(message)
|
asserts.fail(message)
|
||||||
@ -817,12 +820,14 @@ class TestRunner(object):
|
|||||||
return {"flavorRef": flavor_id, "volume": {"size": volume_size}}
|
return {"flavorRef": flavor_id, "volume": {"size": volume_size}}
|
||||||
|
|
||||||
def get_flavor(self, flavor_name):
|
def get_flavor(self, flavor_name):
|
||||||
flavors = self.auth_client.find_flavors_by_name(flavor_name)
|
flavor = None
|
||||||
self.assert_equal(
|
for item in self.instance_info.flavors:
|
||||||
1, len(flavors),
|
if item.name == flavor_name:
|
||||||
"Unexpected number of flavors with name '%s' found." % flavor_name)
|
flavor = item
|
||||||
|
|
||||||
return flavors[0]
|
asserts.assert_is_not_none(flavor)
|
||||||
|
|
||||||
|
return flavor
|
||||||
|
|
||||||
def get_instance_flavor(self, fault_num=None):
|
def get_instance_flavor(self, fault_num=None):
|
||||||
name_format = 'instance%s%s_flavor_name'
|
name_format = 'instance%s%s_flavor_name'
|
||||||
@ -841,7 +846,7 @@ class TestRunner(object):
|
|||||||
return self.get_flavor(flavor_name)
|
return self.get_flavor(flavor_name)
|
||||||
|
|
||||||
def get_flavor_href(self, flavor):
|
def get_flavor_href(self, flavor):
|
||||||
return self.auth_client.find_flavor_self_href(flavor)
|
return flavor.id
|
||||||
|
|
||||||
def copy_dict(self, d, ignored_keys=None):
|
def copy_dict(self, d, ignored_keys=None):
|
||||||
return {k: v for k, v in d.items()
|
return {k: v for k, v in d.items()
|
||||||
@ -980,11 +985,10 @@ class CheckInstance(AttrCheck):
|
|||||||
if 'flavor' not in self.instance:
|
if 'flavor' not in self.instance:
|
||||||
self.fail("'flavor' not found in instance.")
|
self.fail("'flavor' not found in instance.")
|
||||||
else:
|
else:
|
||||||
allowed_attrs = ['id', 'links']
|
allowed_attrs = ['id']
|
||||||
self.contains_allowed_attrs(
|
self.contains_allowed_attrs(
|
||||||
self.instance['flavor'], allowed_attrs,
|
self.instance['flavor'], allowed_attrs,
|
||||||
msg="Flavor")
|
msg="Flavor")
|
||||||
self.links(self.instance['flavor']['links'])
|
|
||||||
|
|
||||||
def datastore(self):
|
def datastore(self):
|
||||||
if 'datastore' not in self.instance:
|
if 'datastore' not in self.instance:
|
||||||
|
@ -140,7 +140,6 @@ class ClusterInstanceDetailViewTest(trove_testtools.TestCase):
|
|||||||
super(ClusterInstanceDetailViewTest, self).tearDown()
|
super(ClusterInstanceDetailViewTest, self).tearDown()
|
||||||
|
|
||||||
@patch.object(ClusterInstanceDetailView, '_build_links')
|
@patch.object(ClusterInstanceDetailView, '_build_links')
|
||||||
@patch.object(ClusterInstanceDetailView, '_build_flavor_links')
|
|
||||||
@patch.object(ClusterInstanceDetailView, '_build_configuration_info')
|
@patch.object(ClusterInstanceDetailView, '_build_configuration_info')
|
||||||
def test_data(self, *args):
|
def test_data(self, *args):
|
||||||
view = ClusterInstanceDetailView(self.instance, self.req)
|
view = ClusterInstanceDetailView(self.instance, self.req)
|
||||||
@ -154,7 +153,6 @@ class ClusterInstanceDetailViewTest(trove_testtools.TestCase):
|
|||||||
self.assertNotIn('ip', result['instance'])
|
self.assertNotIn('ip', result['instance'])
|
||||||
|
|
||||||
@patch.object(ClusterInstanceDetailView, '_build_links')
|
@patch.object(ClusterInstanceDetailView, '_build_links')
|
||||||
@patch.object(ClusterInstanceDetailView, '_build_flavor_links')
|
|
||||||
@patch.object(ClusterInstanceDetailView, '_build_configuration_info')
|
@patch.object(ClusterInstanceDetailView, '_build_configuration_info')
|
||||||
def test_data_ip(self, *args):
|
def test_data_ip(self, *args):
|
||||||
self.instance.hostname = None
|
self.instance.hostname = None
|
||||||
|
@ -41,10 +41,8 @@ class InstanceDetailViewTest(trove_testtools.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(InstanceDetailViewTest, self).setUp()
|
super(InstanceDetailViewTest, self).setUp()
|
||||||
self.build_links_method = InstanceView._build_links
|
self.build_links_method = InstanceView._build_links
|
||||||
self.build_flavor_links_method = InstanceView._build_flavor_links
|
|
||||||
self.build_config_method = InstanceDetailView._build_configuration_info
|
self.build_config_method = InstanceDetailView._build_configuration_info
|
||||||
InstanceView._build_links = Mock()
|
InstanceView._build_links = Mock()
|
||||||
InstanceView._build_flavor_links = Mock()
|
|
||||||
InstanceDetailView._build_configuration_info = Mock()
|
InstanceDetailView._build_configuration_info = Mock()
|
||||||
self.instance = Mock()
|
self.instance = Mock()
|
||||||
self.instance.created = 'Yesterday'
|
self.instance.created = 'Yesterday'
|
||||||
@ -79,7 +77,6 @@ class InstanceDetailViewTest(trove_testtools.TestCase):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(InstanceDetailViewTest, self).tearDown()
|
super(InstanceDetailViewTest, self).tearDown()
|
||||||
InstanceView._build_links = self.build_links_method
|
InstanceView._build_links = self.build_links_method
|
||||||
InstanceView._build_flavor_links = self.build_flavor_links_method
|
|
||||||
InstanceDetailView._build_configuration_info = self.build_config_method
|
InstanceDetailView._build_configuration_info = self.build_config_method
|
||||||
|
|
||||||
def test_data_hostname(self):
|
def test_data_hostname(self):
|
||||||
|
@ -67,37 +67,6 @@ class TestClient(object):
|
|||||||
resp, body = self.real_client.client.last_response
|
resp, body = self.real_client.client.last_response
|
||||||
return resp.status
|
return resp.status
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def find_flavor_self_href(flavor):
|
|
||||||
self_links = [link for link in flavor.links if link['rel'] == 'self']
|
|
||||||
asserts.assert_true(len(self_links) > 0, "Flavor had no self href!")
|
|
||||||
flavor_href = self_links[0]['href']
|
|
||||||
asserts.assert_false(flavor_href is None,
|
|
||||||
"Flavor link self href missing.")
|
|
||||||
return flavor_href
|
|
||||||
|
|
||||||
def find_flavors_by(self, condition, flavor_manager=None):
|
|
||||||
flavor_manager = flavor_manager or self.flavors
|
|
||||||
flavors = flavor_manager.list()
|
|
||||||
return [flavor for flavor in flavors if condition(flavor)]
|
|
||||||
|
|
||||||
def find_flavors_by_name(self, name, flavor_manager=None):
|
|
||||||
return self.find_flavors_by(lambda flavor: flavor.name == name,
|
|
||||||
flavor_manager)
|
|
||||||
|
|
||||||
def find_flavors_by_ram(self, ram, flavor_manager=None):
|
|
||||||
return self.find_flavors_by(lambda flavor: flavor.ram == ram,
|
|
||||||
flavor_manager)
|
|
||||||
|
|
||||||
def find_flavor_and_self_href(self, flavor_id, flavor_manager=None):
|
|
||||||
"""Given an ID, returns flavor and its self href."""
|
|
||||||
flavor_manager = flavor_manager or self.flavors
|
|
||||||
asserts.assert_false(flavor_id is None)
|
|
||||||
flavor = flavor_manager.get(flavor_id)
|
|
||||||
asserts.assert_false(flavor is None)
|
|
||||||
flavor_href = self.find_flavor_self_href(flavor)
|
|
||||||
return flavor, flavor_href
|
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
if item == "__setstate__":
|
if item == "__setstate__":
|
||||||
raise AttributeError(item)
|
raise AttributeError(item)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user