Drop bay and baymodel
Change-Id: Ib85e4fda8e4ac467bd49590dc72ba5913bb9a19d Signed-off-by: Diogo Guerra <diogo.filipe.tomas.guerra@cern.ch>
This commit is contained in:
parent
246c3f5544
commit
dc7f0ba4aa
@ -18,10 +18,6 @@ import struct
|
||||
from tempest.lib.common.utils import data_utils
|
||||
|
||||
from magnum_tempest_plugin.common import config
|
||||
from magnum_tempest_plugin.tests.api.v1.models import bay_model
|
||||
from magnum_tempest_plugin.tests.api.v1.models import baymodel_model
|
||||
from magnum_tempest_plugin.tests.api.v1.models import baymodelpatch_model
|
||||
from magnum_tempest_plugin.tests.api.v1.models import baypatch_model
|
||||
from magnum_tempest_plugin.tests.api.v1.models import cert_model
|
||||
from magnum_tempest_plugin.tests.api.v1.models import cluster_model
|
||||
from magnum_tempest_plugin.tests.api.v1.models import cluster_template_model
|
||||
@ -91,237 +87,6 @@ def gen_no_proxy():
|
||||
return ",".join(gen_random_ip() for x in range(3))
|
||||
|
||||
|
||||
def baymodel_data(**kwargs):
|
||||
"""Generates random baymodel data
|
||||
|
||||
Keypair and image id cannot be random for the baymodel to be valid due to
|
||||
validations for the presence of keypair and image id prior to baymodel
|
||||
creation.
|
||||
|
||||
:param keypair_id: keypair name
|
||||
:param image_id: image id or name
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
data = {
|
||||
"name": data_utils.rand_name('bay'),
|
||||
"coe": "kubernetes",
|
||||
"tls_disabled": False,
|
||||
"network_driver": None,
|
||||
"volume_driver": None,
|
||||
"labels": {},
|
||||
"public": False,
|
||||
"dns_nameserver": "8.8.8.8",
|
||||
"flavor_id": data_utils.rand_name('bay'),
|
||||
"master_flavor_id": data_utils.rand_name('bay'),
|
||||
"external_network_id": config.Config.nic_id,
|
||||
"keypair_id": data_utils.rand_name('bay'),
|
||||
"image_id": data_utils.rand_name('bay')
|
||||
}
|
||||
|
||||
data.update(kwargs)
|
||||
model = baymodel_model.BayModelEntity.from_dict(data)
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def baymodel_replace_patch_data(path, value=data_utils.rand_name('bay')):
|
||||
"""Generates random baymodel patch data
|
||||
|
||||
:param path: path to replace
|
||||
:param value: value to replace in patch
|
||||
:returns: BayModelPatchCollection with generated data
|
||||
"""
|
||||
|
||||
data = [{
|
||||
"path": path,
|
||||
"value": value,
|
||||
"op": "replace"
|
||||
}]
|
||||
return baymodelpatch_model.BayModelPatchCollection.from_dict(data)
|
||||
|
||||
|
||||
def baymodel_remove_patch_data(path):
|
||||
"""Generates baymodel patch data by removing value
|
||||
|
||||
:param path: path to remove
|
||||
:returns: BayModelPatchCollection with generated data
|
||||
"""
|
||||
|
||||
data = [{
|
||||
"path": path,
|
||||
"op": "remove"
|
||||
}]
|
||||
return baymodelpatch_model.BayModelPatchCollection.from_dict(data)
|
||||
|
||||
|
||||
def baymodel_data_with_valid_keypair_image_flavor():
|
||||
"""Generates random baymodel data with valid keypair,image and flavor
|
||||
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
return baymodel_data(keypair_id=config.Config.keypair_name,
|
||||
image_id=config.Config.image_id,
|
||||
flavor_id=config.Config.flavor_id,
|
||||
master_flavor_id=config.Config.master_flavor_id)
|
||||
|
||||
|
||||
def baymodel_data_with_missing_image():
|
||||
"""Generates random baymodel data with missing image
|
||||
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
return baymodel_data(keypair_id=config.Config.keypair_name,
|
||||
flavor_id=config.Config.flavor_id,
|
||||
master_flavor_id=config.Config.master_flavor_id)
|
||||
|
||||
|
||||
def baymodel_data_with_missing_flavor():
|
||||
"""Generates random baymodel data with missing flavor
|
||||
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
return baymodel_data(keypair_id=config.Config.keypair_name,
|
||||
image_id=config.Config.image_id)
|
||||
|
||||
|
||||
def baymodel_data_with_missing_keypair():
|
||||
"""Generates random baymodel data with missing keypair
|
||||
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
return baymodel_data(image_id=config.Config.image_id,
|
||||
flavor_id=config.Config.flavor_id,
|
||||
master_flavor_id=config.Config.master_flavor_id)
|
||||
|
||||
|
||||
def baymodel_valid_data_with_specific_coe(coe):
|
||||
"""Generates random baymodel data with valid keypair and image
|
||||
|
||||
:param coe: coe
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
return baymodel_data(keypair_id=config.Config.keypair_name,
|
||||
image_id=config.Config.image_id, coe=coe)
|
||||
|
||||
|
||||
def valid_kubernetes_baymodel(is_public=False):
|
||||
"""Generates a valid kubernetes baymodel with valid data
|
||||
|
||||
:returns: BayModelEntity with generated data
|
||||
"""
|
||||
|
||||
return baymodel_data(image_id=config.Config.image_id,
|
||||
flavor_id=config.Config.flavor_id, public=is_public,
|
||||
dns_nameserver=config.Config.dns_nameserver,
|
||||
master_flavor_id=config.Config.master_flavor_id,
|
||||
keypair_id=config.Config.keypair_name,
|
||||
coe="kubernetes",
|
||||
cluster_distro=None,
|
||||
external_network_id=config.Config.nic_id,
|
||||
http_proxy=None, https_proxy=None, no_proxy=None,
|
||||
network_driver=None, volume_driver=None, labels={},
|
||||
tls_disabled=False)
|
||||
|
||||
|
||||
def bay_data(name=data_utils.rand_name('bay'),
|
||||
baymodel_id=data_utils.rand_uuid(),
|
||||
node_count=random_int(1, 5), discovery_url=gen_random_ip(),
|
||||
bay_create_timeout=random_int(1, 30),
|
||||
master_count=random_int(1, 5)):
|
||||
"""Generates random bay data
|
||||
|
||||
BayModel_id cannot be random for the bay to be valid due to
|
||||
validations for the presence of baymodel prior to baymodel
|
||||
creation.
|
||||
|
||||
:param name: bay name (must be unique)
|
||||
:param baymodel_id: baymodel unique id (must already exist)
|
||||
:param node_count: number of agents for bay
|
||||
:param discovery_url: url provided for node discovery
|
||||
:param bay_create_timeout: timeout in minutes for bay create
|
||||
:param master_count: number of master nodes for the bay
|
||||
:returns: BayEntity with generated data
|
||||
"""
|
||||
|
||||
data = {
|
||||
"name": name,
|
||||
"baymodel_id": baymodel_id,
|
||||
"node_count": node_count,
|
||||
"discovery_url": None,
|
||||
"bay_create_timeout": bay_create_timeout,
|
||||
"master_count": master_count
|
||||
}
|
||||
model = bay_model.BayEntity.from_dict(data)
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def valid_bay_data(baymodel_id, name=data_utils.rand_name('bay'), node_count=1,
|
||||
master_count=1, bay_create_timeout=None):
|
||||
"""Generates random bay data with valid
|
||||
|
||||
:param baymodel_id: baymodel unique id that already exists
|
||||
:param name: bay name (must be unique)
|
||||
:param node_count: number of agents for bay
|
||||
:returns: BayEntity with generated data
|
||||
"""
|
||||
|
||||
return bay_data(baymodel_id=baymodel_id, name=name,
|
||||
master_count=master_count, node_count=node_count,
|
||||
bay_create_timeout=bay_create_timeout)
|
||||
|
||||
|
||||
def bay_name_patch_data(name=data_utils.rand_name('bay')):
|
||||
"""Generates random baymodel patch data
|
||||
|
||||
:param name: name to replace in patch
|
||||
:returns: BayPatchCollection with generated data
|
||||
"""
|
||||
|
||||
data = [{
|
||||
"path": "/name",
|
||||
"value": name,
|
||||
"op": "replace"
|
||||
}]
|
||||
return baypatch_model.BayPatchCollection.from_dict(data)
|
||||
|
||||
|
||||
def bay_api_addy_patch_data(address='0.0.0.0'):
|
||||
"""Generates random bay patch data
|
||||
|
||||
:param name: name to replace in patch
|
||||
:returns: BayPatchCollection with generated data
|
||||
"""
|
||||
|
||||
data = [{
|
||||
"path": "/api_address",
|
||||
"value": address,
|
||||
"op": "replace"
|
||||
}]
|
||||
return baypatch_model.BayPatchCollection.from_dict(data)
|
||||
|
||||
|
||||
def bay_node_count_patch_data(node_count=2):
|
||||
"""Generates random bay patch data
|
||||
|
||||
:param name: name to replace in patch
|
||||
:returns: BayPatchCollection with generated data
|
||||
"""
|
||||
|
||||
data = [{
|
||||
"path": "/node_count",
|
||||
"value": node_count,
|
||||
"op": "replace"
|
||||
}]
|
||||
return baypatch_model.BayPatchCollection.from_dict(data)
|
||||
|
||||
|
||||
def cert_data(cluster_uuid, csr_data):
|
||||
data = {
|
||||
"cluster_uuid": cluster_uuid,
|
||||
|
@ -15,8 +15,6 @@ from tempest.common import credentials_factory as common_creds
|
||||
|
||||
from magnum_tempest_plugin.common import client
|
||||
from magnum_tempest_plugin.common import config
|
||||
from magnum_tempest_plugin.tests.api.v1.clients import bay_client
|
||||
from magnum_tempest_plugin.tests.api.v1.clients import baymodel_client
|
||||
from magnum_tempest_plugin.tests.api.v1.clients import cert_client
|
||||
from magnum_tempest_plugin.tests.api.v1.clients import cluster_client
|
||||
from magnum_tempest_plugin.tests.api.v1.clients import cluster_template_client
|
||||
@ -32,11 +30,7 @@ class Manager(clients.Manager):
|
||||
self.auth_provider.orig_base_url = self.auth_provider.base_url
|
||||
self.auth_provider.base_url = self.bypassed_base_url
|
||||
auth = self.auth_provider
|
||||
if request_type == 'baymodel':
|
||||
self.client = baymodel_client.BayModelClient(auth)
|
||||
elif request_type == 'bay':
|
||||
self.client = bay_client.BayClient(auth)
|
||||
elif request_type == 'cert':
|
||||
if request_type == 'cert':
|
||||
self.client = cert_client.CertClient(auth)
|
||||
elif request_type == 'cluster_template':
|
||||
self.client = cluster_template_client.ClusterTemplateClient(auth)
|
||||
|
@ -1,170 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from oslo_log import log as logging
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from magnum_tempest_plugin.common import client
|
||||
from magnum_tempest_plugin.common import utils
|
||||
from magnum_tempest_plugin.tests.api.v1.models import bay_model
|
||||
|
||||
|
||||
class BayClient(client.MagnumClient):
|
||||
"""Encapsulates REST calls and maps JSON to/from models"""
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@classmethod
|
||||
def bays_uri(cls, filters=None):
|
||||
"""Construct bays uri with optional filters
|
||||
|
||||
:param filters: Optional k:v dict that's converted to url query
|
||||
:returns: url string
|
||||
"""
|
||||
|
||||
url = "/bays"
|
||||
if filters:
|
||||
url = cls.add_filters(url, filters)
|
||||
return url
|
||||
|
||||
@classmethod
|
||||
def bay_uri(cls, bay_id):
|
||||
"""Construct bay uri
|
||||
|
||||
:param bay_id: bay uuid or name
|
||||
:returns: url string
|
||||
"""
|
||||
|
||||
return "{0}/{1}".format(cls.bays_uri(), bay_id)
|
||||
|
||||
def list_bays(self, filters=None, **kwargs):
|
||||
"""Makes GET /bays request and returns BayCollection
|
||||
|
||||
Abstracts REST call to return all bays
|
||||
|
||||
:param filters: Optional k:v dict that's converted to url query
|
||||
:returns: response object and BayCollection object
|
||||
"""
|
||||
|
||||
resp, body = self.get(self.bays_uri(filters), **kwargs)
|
||||
return self.deserialize(resp, body, bay_model.BayCollection)
|
||||
|
||||
def get_bay(self, bay_id, **kwargs):
|
||||
"""Makes GET /bay request and returns BayEntity
|
||||
|
||||
Abstracts REST call to return a single bay based on uuid or name
|
||||
|
||||
:param bay_id: bay uuid or name
|
||||
:returns: response object and BayCollection object
|
||||
"""
|
||||
|
||||
resp, body = self.get(self.bay_uri(bay_id))
|
||||
return self.deserialize(resp, body, bay_model.BayEntity)
|
||||
|
||||
def post_bay(self, model, **kwargs):
|
||||
"""Makes POST /bay request and returns BayEntity
|
||||
|
||||
Abstracts REST call to create new bay
|
||||
|
||||
:param model: BayEntity
|
||||
:returns: response object and BayEntity object
|
||||
"""
|
||||
|
||||
resp, body = self.post(
|
||||
self.bays_uri(),
|
||||
body=model.to_json(), **kwargs)
|
||||
return self.deserialize(resp, body, bay_model.BayEntity)
|
||||
|
||||
def patch_bay(self, bay_id, baypatch_listmodel, **kwargs):
|
||||
"""Makes PATCH /bay request and returns BayEntity
|
||||
|
||||
Abstracts REST call to update bay attributes
|
||||
|
||||
:param bay_id: UUID of bay
|
||||
:param baypatch_listmodel: BayPatchCollection
|
||||
:returns: response object and BayEntity object
|
||||
"""
|
||||
|
||||
resp, body = self.patch(
|
||||
self.bay_uri(bay_id),
|
||||
body=baypatch_listmodel.to_json(), **kwargs)
|
||||
return self.deserialize(resp, body, bay_model.BayEntity)
|
||||
|
||||
def delete_bay(self, bay_id, **kwargs):
|
||||
"""Makes DELETE /bay request and returns response object
|
||||
|
||||
Abstracts REST call to delete bay based on uuid or name
|
||||
|
||||
:param bay_id: UUID or name of bay
|
||||
:returns: response object
|
||||
"""
|
||||
|
||||
return self.delete(self.bay_uri(bay_id), **kwargs)
|
||||
|
||||
def wait_for_bay_to_delete(self, bay_id):
|
||||
utils.wait_for_condition(
|
||||
lambda: self.does_bay_not_exist(bay_id), 10, 600)
|
||||
|
||||
def wait_for_created_bay(self, bay_id, delete_on_error=True):
|
||||
try:
|
||||
utils.wait_for_condition(
|
||||
lambda: self.does_bay_exist(bay_id), 10, 1800)
|
||||
except Exception:
|
||||
# In error state. Clean up the bay id if desired
|
||||
self.LOG.error('Bay %s entered an exception state.', bay_id)
|
||||
if delete_on_error:
|
||||
self.LOG.error('We will attempt to delete bays now.')
|
||||
self.delete_bay(bay_id)
|
||||
self.wait_for_bay_to_delete(bay_id)
|
||||
raise
|
||||
|
||||
def wait_for_final_state(self, bay_id):
|
||||
utils.wait_for_condition(
|
||||
lambda: self.is_bay_in_final_state(bay_id), 10, 1800)
|
||||
|
||||
def is_bay_in_final_state(self, bay_id):
|
||||
try:
|
||||
resp, model = self.get_bay(bay_id)
|
||||
if model.status in ['CREATED', 'CREATE_COMPLETE',
|
||||
'ERROR', 'CREATE_FAILED']:
|
||||
self.LOG.info('Bay %s succeeded.', bay_id)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except exceptions.NotFound:
|
||||
self.LOG.warning('Bay %s is not found.', bay_id)
|
||||
return False
|
||||
|
||||
def does_bay_exist(self, bay_id):
|
||||
try:
|
||||
resp, model = self.get_bay(bay_id)
|
||||
if model.status in ['CREATED', 'CREATE_COMPLETE']:
|
||||
self.LOG.info('Bay %s is created.', bay_id)
|
||||
return True
|
||||
elif model.status in ['ERROR', 'CREATE_FAILED']:
|
||||
self.LOG.error('Bay %s is in fail state.', bay_id)
|
||||
raise exceptions.ServerFault(
|
||||
"Got into an error condition: %s for %s",
|
||||
(model.status, bay_id))
|
||||
else:
|
||||
return False
|
||||
except exceptions.NotFound:
|
||||
self.LOG.warning('Bay %s is not found.', bay_id)
|
||||
return False
|
||||
|
||||
def does_bay_not_exist(self, bay_id):
|
||||
try:
|
||||
self.get_bay(bay_id)
|
||||
except exceptions.NotFound:
|
||||
self.LOG.warning('Bay %s is not found.', bay_id)
|
||||
return True
|
||||
return False
|
@ -1,105 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from magnum_tempest_plugin.common import client
|
||||
from magnum_tempest_plugin.tests.api.v1.models import baymodel_model
|
||||
|
||||
|
||||
class BayModelClient(client.MagnumClient):
|
||||
"""Encapsulates REST calls and maps JSON to/from models"""
|
||||
|
||||
@classmethod
|
||||
def baymodels_uri(cls, filters=None):
|
||||
"""Construct baymodels uri with optional filters
|
||||
|
||||
:param filters: Optional k:v dict that's converted to url query
|
||||
:returns: url string
|
||||
"""
|
||||
|
||||
url = "/baymodels"
|
||||
if filters:
|
||||
url = cls.add_filters(url, filters)
|
||||
return url
|
||||
|
||||
@classmethod
|
||||
def baymodel_uri(cls, baymodel_id):
|
||||
"""Construct baymodel uri
|
||||
|
||||
:param baymodel_id: baymodel uuid or name
|
||||
:returns: url string
|
||||
"""
|
||||
|
||||
return "{0}/{1}".format(cls.baymodels_uri(), baymodel_id)
|
||||
|
||||
def list_baymodels(self, filters=None, **kwargs):
|
||||
"""Makes GET /baymodels request and returns BayModelCollection
|
||||
|
||||
Abstracts REST call to return all baymodels
|
||||
|
||||
:param filters: Optional k:v dict that's converted to url query
|
||||
:returns: response object and BayModelCollection object
|
||||
"""
|
||||
|
||||
resp, body = self.get(self.baymodels_uri(filters), **kwargs)
|
||||
return self.deserialize(resp, body, baymodel_model.BayModelCollection)
|
||||
|
||||
def get_baymodel(self, baymodel_id, **kwargs):
|
||||
"""Makes GET /baymodel request and returns BayModelEntity
|
||||
|
||||
Abstracts REST call to return a single baymodel based on uuid or name
|
||||
|
||||
:param baymodel_id: baymodel uuid or name
|
||||
:returns: response object and BayModelCollection object
|
||||
"""
|
||||
|
||||
resp, body = self.get(self.baymodel_uri(baymodel_id))
|
||||
return self.deserialize(resp, body, baymodel_model.BayModelEntity)
|
||||
|
||||
def post_baymodel(self, model, **kwargs):
|
||||
"""Makes POST /baymodel request and returns BayModelEntity
|
||||
|
||||
Abstracts REST call to create new baymodel
|
||||
|
||||
:param model: BayModelEntity
|
||||
:returns: response object and BayModelEntity object
|
||||
"""
|
||||
|
||||
resp, body = self.post(
|
||||
self.baymodels_uri(),
|
||||
body=model.to_json(), **kwargs)
|
||||
return self.deserialize(resp, body, baymodel_model.BayModelEntity)
|
||||
|
||||
def patch_baymodel(self, baymodel_id, baymodelpatch_listmodel, **kwargs):
|
||||
"""Makes PATCH /baymodel request and returns BayModelEntity
|
||||
|
||||
Abstracts REST call to update baymodel attributes
|
||||
|
||||
:param baymodel_id: UUID of baymodel
|
||||
:param baymodelpatch_listmodel: BayModelPatchCollection
|
||||
:returns: response object and BayModelEntity object
|
||||
"""
|
||||
|
||||
resp, body = self.patch(
|
||||
self.baymodel_uri(baymodel_id),
|
||||
body=baymodelpatch_listmodel.to_json(), **kwargs)
|
||||
return self.deserialize(resp, body, baymodel_model.BayModelEntity)
|
||||
|
||||
def delete_baymodel(self, baymodel_id, **kwargs):
|
||||
"""Makes DELETE /baymodel request and returns response object
|
||||
|
||||
Abstracts REST call to delete baymodel based on uuid or name
|
||||
|
||||
:param baymodel_id: UUID or name of baymodel
|
||||
:returns: response object
|
||||
"""
|
||||
|
||||
return self.delete(self.baymodel_uri(baymodel_id), **kwargs)
|
@ -1,30 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from magnum_tempest_plugin.common import models
|
||||
|
||||
|
||||
class BayData(models.BaseModel):
|
||||
"""Data that encapsulates bay attributes"""
|
||||
pass
|
||||
|
||||
|
||||
class BayEntity(models.EntityModel):
|
||||
"""Entity Model that represents a single instance of BayData"""
|
||||
ENTITY_NAME = 'bay'
|
||||
MODEL_TYPE = BayData
|
||||
|
||||
|
||||
class BayCollection(models.CollectionModel):
|
||||
"""Collection Model that represents a list of BayData objects"""
|
||||
COLLECTION_NAME = 'baylists'
|
||||
MODEL_TYPE = BayData
|
@ -1,30 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from magnum_tempest_plugin.common import models
|
||||
|
||||
|
||||
class BayModelData(models.BaseModel):
|
||||
"""Data that encapsulates baymodel attributes"""
|
||||
pass
|
||||
|
||||
|
||||
class BayModelEntity(models.EntityModel):
|
||||
"""Entity Model that represents a single instance of BayModelData"""
|
||||
ENTITY_NAME = 'baymodel'
|
||||
MODEL_TYPE = BayModelData
|
||||
|
||||
|
||||
class BayModelCollection(models.CollectionModel):
|
||||
"""Collection Model that represents a list of BayModelData objects"""
|
||||
COLLECTION_NAME = 'baymodellists'
|
||||
MODEL_TYPE = BayModelData
|
@ -1,76 +0,0 @@
|
||||
# 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
|
||||
|
||||
from magnum_tempest_plugin.common import models
|
||||
|
||||
|
||||
class BayModelPatchData(models.BaseModel):
|
||||
"""Data that encapsulates baymodelpatch attributes"""
|
||||
pass
|
||||
|
||||
|
||||
class BayModelPatchEntity(models.EntityModel):
|
||||
"""Entity Model that represents a single instance of BayModelPatchData"""
|
||||
ENTITY_NAME = 'baymodelpatch'
|
||||
MODEL_TYPE = BayModelPatchData
|
||||
|
||||
|
||||
class BayModelPatchCollection(models.CollectionModel):
|
||||
"""Collection Model that represents a list of BayModelPatchData objects"""
|
||||
MODEL_TYPE = BayModelPatchData
|
||||
COLLECTION_NAME = 'baymodelpatchlist'
|
||||
|
||||
def to_json(self):
|
||||
"""Converts BayModelPatchCollection to json
|
||||
|
||||
Retrieves list from COLLECTION_NAME attribute and converts each object
|
||||
to dict, appending it to a list. Then converts the entire list to json
|
||||
|
||||
This is required due to COLLECTION_NAME holding a list of objects that
|
||||
needed to be converted to dict individually
|
||||
|
||||
:returns: json object
|
||||
"""
|
||||
|
||||
data = getattr(self, BayModelPatchCollection.COLLECTION_NAME)
|
||||
collection = []
|
||||
for d in data:
|
||||
collection.append(d.to_dict())
|
||||
return json.dumps(collection)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
"""Converts dict to BayModelPatchData
|
||||
|
||||
Converts data dict to list of BayModelPatchData objects and stores it
|
||||
in COLLECTION_NAME
|
||||
|
||||
Example of dict data:
|
||||
|
||||
[{
|
||||
"path": "/name",
|
||||
"value": "myname",
|
||||
"op": "replace"
|
||||
}]
|
||||
|
||||
:param data: dict of patch data
|
||||
:returns: json object
|
||||
"""
|
||||
|
||||
model = cls()
|
||||
collection = []
|
||||
for d in data:
|
||||
collection.append(cls.MODEL_TYPE.from_dict(d))
|
||||
setattr(model, cls.COLLECTION_NAME, collection)
|
||||
return model
|
@ -1,76 +0,0 @@
|
||||
# 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
|
||||
|
||||
from magnum_tempest_plugin.common import models
|
||||
|
||||
|
||||
class BayPatchData(models.BaseModel):
|
||||
"""Data that encapsulates baypatch attributes"""
|
||||
pass
|
||||
|
||||
|
||||
class BayPatchEntity(models.EntityModel):
|
||||
"""Entity Model that represents a single instance of BayPatchData"""
|
||||
ENTITY_NAME = 'baypatch'
|
||||
MODEL_TYPE = BayPatchData
|
||||
|
||||
|
||||
class BayPatchCollection(models.CollectionModel):
|
||||
"""Collection Model that represents a list of BayPatchData objects"""
|
||||
MODEL_TYPE = BayPatchData
|
||||
COLLECTION_NAME = 'baypatchlist'
|
||||
|
||||
def to_json(self):
|
||||
"""Converts BayPatchCollection to json
|
||||
|
||||
Retrieves list from COLLECTION_NAME attribute and converts each object
|
||||
to dict, appending it to a list. Then converts the entire list to json
|
||||
|
||||
This is required due to COLLECTION_NAME holding a list of objects that
|
||||
needed to be converted to dict individually
|
||||
|
||||
:returns: json object
|
||||
"""
|
||||
|
||||
data = getattr(self, BayPatchCollection.COLLECTION_NAME)
|
||||
collection = []
|
||||
for d in data:
|
||||
collection.append(d.to_dict())
|
||||
return json.dumps(collection)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
"""Converts dict to BayPatchData
|
||||
|
||||
Converts data dict to list of BayPatchData objects and stores it
|
||||
in COLLECTION_NAME
|
||||
|
||||
Example of dict data:
|
||||
|
||||
[{
|
||||
"path": "/name",
|
||||
"value": "myname",
|
||||
"op": "replace"
|
||||
}]
|
||||
|
||||
:param data: dict of patch data
|
||||
:returns: json object
|
||||
"""
|
||||
|
||||
model = cls()
|
||||
collection = []
|
||||
for d in data:
|
||||
collection.append(cls.MODEL_TYPE.from_dict(d))
|
||||
setattr(model, cls.COLLECTION_NAME, collection)
|
||||
return model
|
@ -1,216 +0,0 @@
|
||||
# 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 fixtures
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
import testtools
|
||||
|
||||
from magnum_tempest_plugin.common import config
|
||||
from magnum_tempest_plugin.common import datagen
|
||||
from magnum_tempest_plugin.tests.api import base
|
||||
|
||||
|
||||
class BayTest(base.BaseTempestTest):
|
||||
|
||||
"""Tests for bay CRUD."""
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BayTest, self).__init__(*args, **kwargs)
|
||||
self.bays = []
|
||||
self.creds = None
|
||||
self.keypair = None
|
||||
self.baymodel = None
|
||||
self.baymodel_client = None
|
||||
self.keypairs_client = None
|
||||
self.bay_client = None
|
||||
self.cert_client = None
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
super(BayTest, self).setUp()
|
||||
(self.creds, self.keypair) = self.get_credentials_with_keypair(
|
||||
type_of_creds='default')
|
||||
(self.baymodel_client,
|
||||
self.keypairs_client) = self.get_clients_with_existing_creds(
|
||||
creds=self.creds,
|
||||
type_of_creds='default',
|
||||
request_type='baymodel')
|
||||
(self.bay_client, _) = self.get_clients_with_existing_creds(
|
||||
creds=self.creds,
|
||||
type_of_creds='default',
|
||||
request_type='bay')
|
||||
(self.cert_client, _) = self.get_clients_with_existing_creds(
|
||||
creds=self.creds,
|
||||
type_of_creds='default',
|
||||
request_type='cert')
|
||||
model = datagen.valid_kubernetes_baymodel()
|
||||
_, self.baymodel = self._create_baymodel(model)
|
||||
|
||||
# NOTE (dimtruck) by default tempest sets timeout to 20 mins.
|
||||
# We need more time.
|
||||
test_timeout = 1800
|
||||
self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
|
||||
except Exception:
|
||||
self.tearDown()
|
||||
raise
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
bay_list = self.bays[:]
|
||||
for bay_id in bay_list:
|
||||
self._delete_bay(bay_id)
|
||||
self.bays.remove(bay_id)
|
||||
if self.baymodel:
|
||||
self._delete_baymodel(self.baymodel.uuid)
|
||||
finally:
|
||||
super(BayTest, self).tearDown()
|
||||
|
||||
def _create_baymodel(self, baymodel_model):
|
||||
self.LOG.debug('We will create a baymodel for %s', baymodel_model)
|
||||
resp, model = self.baymodel_client.post_baymodel(baymodel_model)
|
||||
return resp, model
|
||||
|
||||
def _delete_baymodel(self, baymodel_id):
|
||||
self.LOG.debug('We will delete a baymodel for %s', baymodel_id)
|
||||
resp, model = self.baymodel_client.delete_baymodel(baymodel_id)
|
||||
return resp, model
|
||||
|
||||
def _create_bay(self, bay_model, is_async=False):
|
||||
self.LOG.debug('We will create bay for %s', bay_model)
|
||||
headers = {'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'}
|
||||
if is_async:
|
||||
headers["OpenStack-API-Version"] = "container-infra 1.2"
|
||||
resp, model = self.bay_client.post_bay(bay_model, headers=headers)
|
||||
self.LOG.debug('Response: %s', resp)
|
||||
if is_async:
|
||||
self.assertEqual(202, resp.status)
|
||||
else:
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertIsNotNone(model.uuid)
|
||||
self.assertTrue(uuidutils.is_uuid_like(model.uuid))
|
||||
self.bays.append(model.uuid)
|
||||
self.bay_uuid = model.uuid
|
||||
if config.Config.copy_logs:
|
||||
self.addCleanup(self.copy_logs_handler(
|
||||
lambda: list(
|
||||
[self._get_bay_by_id(self.bay_uuid)[1].master_addresses,
|
||||
self._get_bay_by_id(self.bay_uuid)[1].node_addresses]),
|
||||
self.baymodel.coe,
|
||||
self.keypair))
|
||||
self.bay_client.wait_for_created_bay(model.uuid, delete_on_error=False)
|
||||
return resp, model
|
||||
|
||||
def _delete_bay(self, bay_id):
|
||||
self.LOG.debug('We will delete a bay for %s', bay_id)
|
||||
resp, model = self.bay_client.delete_bay(bay_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.bay_client.wait_for_bay_to_delete(bay_id)
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.cert_client.get_cert, bay_id)
|
||||
return resp, model
|
||||
|
||||
def _get_bay_by_id(self, bay_id):
|
||||
resp, model = self.bay_client.get_bay(bay_id)
|
||||
return resp, model
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_bay_for_nonexisting_baymodel(self):
|
||||
gen_model = datagen.valid_bay_data(baymodel_id='this-does-not-exist')
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.bay_client.post_bay, gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_bay_with_node_count_0(self):
|
||||
gen_model = datagen.valid_bay_data(
|
||||
baymodel_id=self.baymodel.uuid, node_count=0)
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.bay_client.post_bay, gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_bay_with_zero_masters(self):
|
||||
gen_model = datagen.valid_bay_data(baymodel_id=self.baymodel.uuid,
|
||||
master_count=0)
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.bay_client.post_bay, gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_bay_with_nonexisting_flavor(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, baymodel = self._create_baymodel(gen_model)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertIsNotNone(baymodel.uuid)
|
||||
|
||||
gen_model = datagen.valid_bay_data(baymodel_id=baymodel.uuid)
|
||||
gen_model.flavor_id = 'aaa'
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.bay_client.post_bay, gen_model)
|
||||
|
||||
resp, _ = self._delete_baymodel(baymodel.uuid)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_bay_with_nonexisting_keypair(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, baymodel = self._create_baymodel(gen_model)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertIsNotNone(baymodel.uuid)
|
||||
|
||||
gen_model = datagen.valid_bay_data(baymodel_id=baymodel.uuid)
|
||||
gen_model.keypair_id = 'aaa'
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.bay_client.post_bay, gen_model)
|
||||
|
||||
resp, _ = self._delete_baymodel(baymodel.uuid)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_bay_with_nonexisting_external_network(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, baymodel = self._create_baymodel(gen_model)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertIsNotNone(baymodel.uuid)
|
||||
|
||||
gen_model = datagen.valid_bay_data(baymodel_id=baymodel.uuid)
|
||||
gen_model.external_network_id = 'aaa'
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.bay_client.post_bay, gen_model)
|
||||
|
||||
resp, _ = self._delete_baymodel(baymodel.uuid)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_update_bay_for_nonexisting_bay(self):
|
||||
patch_model = datagen.bay_name_patch_data()
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.bay_client.patch_bay, 'fooo', patch_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_delete_bay_for_nonexisting_bay(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.bay_client.delete_bay, data_utils.rand_uuid())
|
@ -1,207 +0,0 @@
|
||||
# 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.
|
||||
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
import testtools
|
||||
|
||||
from magnum_tempest_plugin.common import datagen
|
||||
from magnum_tempest_plugin.tests.api import base
|
||||
|
||||
|
||||
class BayModelTest(base.BaseTempestTest):
|
||||
|
||||
"""Tests for baymodel CRUD."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BayModelTest, self).__init__(*args, **kwargs)
|
||||
self.baymodels = []
|
||||
self.baymodel_client = None
|
||||
self.keypairs_client = None
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
super(BayModelTest, self).setUp()
|
||||
(self.baymodel_client,
|
||||
self.keypairs_client) = self.get_clients_with_new_creds(
|
||||
type_of_creds='default',
|
||||
request_type='baymodel')
|
||||
except Exception:
|
||||
self.tearDown()
|
||||
raise
|
||||
|
||||
def tearDown(self):
|
||||
for baymodel_id in self.baymodels:
|
||||
self._delete_baymodel(baymodel_id)
|
||||
self.baymodels.remove(baymodel_id)
|
||||
super(BayModelTest, self).tearDown()
|
||||
|
||||
def _create_baymodel(self, baymodel_model):
|
||||
resp, model = self.baymodel_client.post_baymodel(baymodel_model)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.baymodels.append(model.uuid)
|
||||
return resp, model
|
||||
|
||||
def _delete_baymodel(self, baymodel_id):
|
||||
resp, model = self.baymodel_client.delete_baymodel(baymodel_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
return resp, model
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_list_baymodels(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
_, temp_model = self._create_baymodel(gen_model)
|
||||
resp, model = self.baymodel_client.list_baymodels()
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertGreater(len(model.baymodels), 0)
|
||||
self.assertIn(
|
||||
temp_model.uuid, list([x['uuid'] for x in model.baymodels]))
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_create_baymodel(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, model = self._create_baymodel(gen_model)
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_create_get_public_baymodel(self):
|
||||
gen_model = datagen.valid_kubernetes_baymodel(is_public=True)
|
||||
self.assertRaises(
|
||||
exceptions.Forbidden,
|
||||
self.baymodel_client.post_baymodel, gen_model)
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_update_baymodel_public_by_uuid(self):
|
||||
path = "/public"
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, old_model = self._create_baymodel(gen_model)
|
||||
|
||||
patch_model = datagen.baymodel_replace_patch_data(path, value=True)
|
||||
self.assertRaises(
|
||||
exceptions.Forbidden,
|
||||
self.baymodel_client.patch_baymodel, old_model.uuid, patch_model)
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_update_baymodel_by_uuid(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, old_model = self._create_baymodel(gen_model)
|
||||
|
||||
path = "/name"
|
||||
patch_model = datagen.baymodel_replace_patch_data(path)
|
||||
resp, new_model = self.baymodel_client.patch_baymodel(
|
||||
old_model.uuid, patch_model)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
resp, model = self.baymodel_client.get_baymodel(new_model.uuid)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(old_model.uuid, new_model.uuid)
|
||||
self.assertEqual(model.name, new_model.name)
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_delete_baymodel_by_uuid(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, model = self._create_baymodel(gen_model)
|
||||
resp, _ = self.baymodel_client.delete_baymodel(model.uuid)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.baymodels.remove(model.uuid)
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_delete_baymodel_by_name(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, model = self._create_baymodel(gen_model)
|
||||
resp, _ = self.baymodel_client.delete_baymodel(model.name)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.baymodels.remove(model.uuid)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_get_baymodel_by_uuid_404(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.baymodel_client.get_baymodel, data_utils.rand_uuid())
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_update_baymodel_404(self):
|
||||
path = "/name"
|
||||
patch_model = datagen.baymodel_replace_patch_data(path)
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.baymodel_client.patch_baymodel,
|
||||
data_utils.rand_uuid(), patch_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_delete_baymodel_404(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.baymodel_client.delete_baymodel, data_utils.rand_uuid())
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_get_baymodel_by_name_404(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.baymodel_client.get_baymodel, 'fooo')
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_update_baymodel_name_not_found(self):
|
||||
path = "/name"
|
||||
patch_model = datagen.baymodel_replace_patch_data(path)
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.baymodel_client.patch_baymodel, 'fooo', patch_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_delete_baymodel_by_name_404(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound,
|
||||
self.baymodel_client.get_baymodel, 'fooo')
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_baymodel_missing_image(self):
|
||||
gen_model = datagen.baymodel_data_with_missing_image()
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.baymodel_client.post_baymodel, gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_baymodel_missing_flavor(self):
|
||||
gen_model = datagen.baymodel_data_with_missing_flavor()
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.baymodel_client.post_baymodel, gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_update_baymodel_invalid_patch(self):
|
||||
# get json object
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, old_model = self._create_baymodel(gen_model)
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.baymodel_client.patch_baymodel, data_utils.rand_uuid(),
|
||||
gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_baymodel_invalid_network_driver(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
gen_model.network_driver = 'invalid_network_driver'
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.baymodel_client.post_baymodel, gen_model)
|
||||
|
||||
@testtools.testcase.attr('negative')
|
||||
def test_create_baymodel_invalid_volume_driver(self):
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
gen_model.volume_driver = 'invalid_volume_driver'
|
||||
self.assertRaises(
|
||||
exceptions.BadRequest,
|
||||
self.baymodel_client.post_baymodel, gen_model)
|
@ -1,80 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import testtools
|
||||
|
||||
from magnum_tempest_plugin.common import datagen
|
||||
from magnum_tempest_plugin.tests.api import base
|
||||
|
||||
|
||||
class BayModelAdminTest(base.BaseTempestTest):
|
||||
|
||||
"""Tests for baymodel admin operations."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BayModelAdminTest, self).__init__(*args, **kwargs)
|
||||
self.baymodels = []
|
||||
self.baymodel_client = None
|
||||
self.keypairs_client = None
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
super(BayModelAdminTest, self).setUp()
|
||||
(self.baymodel_client,
|
||||
self.keypairs_client) = self.get_clients_with_new_creds(
|
||||
type_of_creds='admin',
|
||||
request_type='baymodel')
|
||||
except Exception:
|
||||
self.tearDown()
|
||||
raise
|
||||
|
||||
def tearDown(self):
|
||||
for baymodel_id in self.baymodels:
|
||||
self._delete_baymodel(baymodel_id)
|
||||
self.baymodels.remove(baymodel_id)
|
||||
super(BayModelAdminTest, self).tearDown()
|
||||
|
||||
def _create_baymodel(self, baymodel_model):
|
||||
resp, model = self.baymodel_client.post_baymodel(baymodel_model)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.baymodels.append(model.uuid)
|
||||
return resp, model
|
||||
|
||||
def _delete_baymodel(self, baymodel_id):
|
||||
resp, model = self.baymodel_client.delete_baymodel(baymodel_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
return resp, model
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_create_get_public_baymodel(self):
|
||||
gen_model = datagen.valid_kubernetes_baymodel(is_public=True)
|
||||
resp, model = self._create_baymodel(gen_model)
|
||||
|
||||
resp, model = self.baymodel_client.get_baymodel(model.uuid)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(model.public)
|
||||
|
||||
@testtools.testcase.attr('positive')
|
||||
def test_update_baymodel_public_by_uuid(self):
|
||||
path = "/public"
|
||||
gen_model = datagen.baymodel_data_with_valid_keypair_image_flavor()
|
||||
resp, old_model = self._create_baymodel(gen_model)
|
||||
|
||||
patch_model = datagen.baymodel_replace_patch_data(path, value=True)
|
||||
resp, new_model = self.baymodel_client.patch_baymodel(
|
||||
old_model.uuid, patch_model)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
resp, model = self.baymodel_client.get_baymodel(new_model.uuid)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(model.public)
|
Loading…
Reference in New Issue
Block a user