cue/cue/tests/functional/api/v1/test_cluster.py

410 lines
18 KiB
Python

# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Authors: Davide Agnello <davide.agnello@hp.com>
#
# 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.
# Copyright [2014] Hewlett-Packard Development Company, L.P.
# limitations under the License.
"""
Tests for the API /cluster/ controller methods.
"""
import uuid
from cue.db.sqlalchemy import api as db_api
from cue.db.sqlalchemy import models
from cue import objects
from cue.tests.functional import api
from cue.tests.functional.api import api_utils
from cue.tests.functional import utils as test_utils
from oslo.config import cfg
CONF = cfg.CONF
class TestGetCluster(api.APITest,
api_utils.ClusterValidationMixin):
def setUp(self):
super(TestGetCluster, self).setUp()
def test_get_cluster_not_found(self):
"""test get non-existing cluster."""
data = self.get_json('/clusters/' + str(uuid.uuid4()),
headers=self.auth_headers, expect_errors=True)
self.assertEqual(404, data.status_code,
'Invalid status code value received.')
self.assertEqual('404 Not Found', data.status,
'Invalid status value received.')
self.assertIn('Cluster was not found',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_get_cluster_invalid_uuid_format(self):
"""test get cluster with invalid id uuid format."""
invalid_uuid = u"25c06c22.fadd.4c83-a515-974a29668ba9"
data = self.get_json('/clusters/' + invalid_uuid,
headers=self.auth_headers, expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertEqual('400 Bad Request', data.status,
'Invalid status value received.')
self.assertIn('badly formed cluster_id UUID string',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_get_cluster_invalid_uri(self):
"""test get cluster with invalid URI string.
Example: get /clusters/<cluster_id>/invalid_resource
"""
def test_get_cluster_valid_uri(self):
"""test get cluster with valid URI strings.
Examples (with and without end forward slash):
get /clusters/<cluster_id>
get /clusters/<cluster_id>/
"""
def test_get_cluster(self):
"""test get cluster on valid existing cluster."""
# create record for a new cluster in db
cluster = test_utils.create_db_test_cluster_from_objects_api(
self.context, name=self.cluster_name, size=3).as_dict()
data = self.get_json('/clusters/' + cluster['id'],
headers=self.auth_headers)
self.validate_cluster_values(cluster, data)
# verify all endpoints in cluster
all_endpoints = test_utils.get_endpoints_in_cluster(self.context,
cluster['id'])
self.validate_endpoint_values(all_endpoints, data["end_points"])
class TestDeleteCluster(api.APITest,
api_utils.ClusterValidationMixin):
def setUp(self):
super(TestDeleteCluster, self).setUp()
def test_delete_cluster_not_found(self):
"""test delete non-existing cluster."""
data = self.delete('/clusters/' + str(uuid.uuid4()),
headers=self.auth_headers, expect_errors=True)
self.assertEqual(404, data.status_code,
'Invalid status code value received.')
self.assertEqual('404 Not Found', data.status,
'Invalid status value received.')
self.assertIn('Cluster was not found',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_delete_cluster_invalid_uuid_format(self):
"""test delete cluster with invalid uuid format."""
invalid_uuid = u"25c06c22.fadd.4c83-a515-974a29668ba9"
data = self.delete('/clusters/' + invalid_uuid,
headers=self.auth_headers, expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertEqual('400 Bad Request', data.status,
'Invalid status value received.')
self.assertIn('badly formed cluster_id UUID string',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_deleted_cluster_already_deleted(self):
"""test delete cluster that has already been deleted."""
def test_delete_pending_cluster(self):
"""test delete cluster that is pending deletion."""
def test_delete_cluster(self):
"""test delete cluster on valid existing cluster."""
cluster = test_utils.create_db_test_cluster_from_objects_api(
self.context, name=self.cluster_name)
cluster_in_db = objects.Cluster.get_cluster_by_id(self.context,
cluster.id)
self.assertEqual(models.Status.BUILDING, cluster_in_db.status,
"Invalid cluster status value")
self.delete('/clusters/' + cluster.id, headers=self.auth_headers)
cluster_in_db = objects.Cluster.get_cluster_by_id(self.context,
cluster.id)
cluster.status = models.Status.DELETING
cluster.created_at = cluster_in_db.created_at
cluster.updated_at = cluster_in_db.updated_at
data = self.get_json('/clusters/' + cluster['id'],
headers=self.auth_headers)
cluster = cluster.as_dict()
self.validate_cluster_values(cluster, data)
class TestListClusters(api.APITest,
api_utils.ClusterValidationMixin):
def setUp(self):
super(TestListClusters, self).setUp()
def test_empty(self):
data = self.get_json('/clusters')
self.assertEqual([], data)
def test_one(self):
cluster = test_utils.create_db_test_cluster_from_objects_api(
self.context, name=self.cluster_name)
data = self.get_json('/clusters', headers=self.auth_headers)
# verify number of clusters received
self.assertEqual(len(data), 1, "Invalid number of clusters returned")
# verify cluster
self.validate_cluster_values(cluster.as_dict(), data[0])
# verify endpoints in cluster
all_endpoints = test_utils.get_endpoints_in_cluster(self.context,
cluster.id)
self.validate_endpoint_values(all_endpoints,
data[0]["end_points"])
def test_multiple(self):
num_of_clusters = 5
clusters = [test_utils.create_db_test_cluster_from_objects_api(
self.context,
name=self.cluster_name + '_' + str(i), size=i + 1) for i in
range(num_of_clusters)]
data = self.get_json('/clusters', headers=self.auth_headers)
# verify number of clusters received
self.assertEqual(len(data), num_of_clusters,
"Invalid number of clusters returned")
for i in range(num_of_clusters):
# verify cluster
self.validate_cluster_values(clusters[i].as_dict(), data[i])
# verify endpoints in cluster
all_endpoints = test_utils.get_endpoints_in_cluster(self.context,
clusters[i].id)
self.validate_endpoint_values(all_endpoints,
data[i]["end_points"])
class TestCreateCluster(api.APITest,
api_utils.ClusterValidationMixin):
def setUp(self):
super(TestCreateCluster, self).setUp()
def test_create_empty_body(self):
cluster_params = {}
#header = {'Content-Type': 'application/json'}
data = self.post_json('/clusters', params=cluster_params,
expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertEqual('400 Bad Request', data.status,
'Invalid status value received.')
self.assertIn('Invalid input for field/attribute',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_create_size_missing(self):
"""test create an empty cluster."""
api_cluster = test_utils.create_api_test_cluster(size=0)
request_body = api_cluster
# remove size field
del request_body['size']
data = self.post_json('/clusters', headers=self.auth_headers,
params=request_body,
expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertEqual('400 Bad Request', data.status,
'Invalid status value received.')
self.assertIn('Mandatory field missing',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_create_size_zero(self):
"""test create an empty cluster."""
api_cluster = test_utils.create_api_test_cluster(size=0)
data = self.post_json('/clusters', headers=self.auth_headers,
params=api_cluster,
expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertEqual('400 Bad Request', data.status,
'Invalid status value received.')
self.assertIn('Invalid cluster size provided',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_create_too_large(self):
"""test create cluster with size larger than limit."""
api_cluster = test_utils.create_api_test_cluster(
size=(CONF.api.max_cluster_size + 1))
data = self.post_json('/clusters', headers=self.auth_headers,
params=api_cluster, expect_errors=True)
self.assertEqual(413, data.status_code,
'Invalid status code value received.')
self.assertIn('Invalid cluster size, max size is: ' +
str(CONF.api.max_cluster_size),
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_create_size_one(self):
"""test create a cluster with one node.
Will verify cluster create from DB record then verifies cluster get
returns the same cluster from the API.
"""
api_cluster = test_utils.create_api_test_cluster(size=1)
data = self.post_json('/clusters', params=api_cluster,
headers=self.auth_headers, status=202)
cluster = objects.Cluster.get_cluster_by_id(self.context,
data.json["id"]).as_dict()
self.validate_cluster_values(cluster, data.json)
self.assertEqual(models.Status.BUILDING, data.json['status'])
data_api = self.get_json('/clusters/' + cluster['id'],
headers=self.auth_headers)
self.validate_cluster_values(cluster, data_api)
self.assertEqual(models.Status.BUILDING, data_api['status'])
def test_create_size_three(self):
"""test create a cluster with three nodes.
Will verify cluster create from DB record then verifies cluster get
returns the same cluster from the API.
"""
api_cluster = test_utils.create_api_test_cluster(size=3)
data = self.post_json('/clusters', params=api_cluster,
headers=self.auth_headers, status=202)
cluster = objects.Cluster.get_cluster_by_id(self.context,
data.json["id"]).as_dict()
self.validate_cluster_values(cluster, data.json)
self.assertEqual(models.Status.BUILDING, data.json['status'])
data_api = self.get_json('/clusters/' + cluster['id'],
headers=self.auth_headers)
self.validate_cluster_values(cluster, data_api)
self.assertEqual(models.Status.BUILDING, data_api['status'])
def test_create_invalid_size_format(self):
"""test with invalid formatted size parameter."""
api_cluster = test_utils.create_api_test_cluster(size="a")
data = self.post_json('/clusters', params=api_cluster,
headers=self.auth_headers, expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertEqual('400 Bad Request', data.status,
'Invalid status value received.')
self.assertIn('invalid literal for int() with base 10:',
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_create_network_id_size_not_one(self):
"""test create a cluster with size of network_id more than one."""
api_cluster = test_utils.create_api_test_cluster(network_id=(
[str(uuid.uuid4()), str(uuid.uuid4())]))
data = self.post_json('/clusters', headers=self.auth_headers,
params=api_cluster, expect_errors=True)
self.assertEqual(400, data.status_code,
'Invalid status code value received.')
self.assertIn("Invalid number of network_id's",
data.namespace["faultstring"],
'Invalid faultstring received.')
def test_create_two_clusters_verify_time_stamps(self):
"""test time stamps times at creation and delete."""
api_cluster_1 = test_utils.create_api_test_cluster()
api_cluster_2 = test_utils.create_api_test_cluster()
# Create two clusters
data_1 = self.post_json('/clusters', params=api_cluster_1,
headers=self.auth_headers, status=202)
data_2 = self.post_json('/clusters', params=api_cluster_2,
headers=self.auth_headers, status=202)
# retrieve cluster objects
cluster_1 = objects.Cluster.get_cluster_by_id(self.context,
data_1.json["id"])
cluster_2 = objects.Cluster.get_cluster_by_id(self.context,
data_2.json["id"])
# verify second cluster was created after first by created_at time
self.assertEqual(True, cluster_2.created_at > cluster_1.created_at,
"Second cluster was not created after first")
cluster_1_created_at = cluster_1.created_at
# issue delete request cluster for cluster_1
self.delete('/clusters/' + data_1.json["id"],
headers=self.auth_headers)
# retrieve cluster_1
cluster_1 = objects.Cluster.get_cluster_by_id(self.context,
data_1.json["id"])
# verify updated_at time is after created_at
self.assertEqual(True, cluster_1.updated_at > cluster_1.created_at,
"Cluster updated at time is invalid")
# verify created_at time did not change
self.assertEqual(cluster_1_created_at, cluster_1.created_at,
"Cluster created_at time has changed")
# delete cluster_1
cluster = objects.Cluster(deleted=True, status=models.Status.DELETED)
cluster.update(self.context, data_1.json["id"])
# retrieve deleted (soft) cluster
cluster_query = db_api.model_query(self.context, models.Cluster,
read_deleted=True).filter_by(
id=data_1.json["id"])
cluster_1 = cluster_query.one()
# verify deleted_at time is after created_at
self.assertEqual(True, cluster_1.deleted_at > cluster_1.created_at,
"Cluster deleted_at time is invalid")
# verify updated_at time is after deleted_at
self.assertEqual(True, cluster_1.updated_at > cluster_1.deleted_at,
"Cluster deleted_at time is invalid")
def test_create_invalid_volume_size(self):
"""test with invalid volume_size parameter."""
def test_create_invalid_parameter_set_id(self):
"""test with invalid parameter set: id."""
def test_create_invalid_parameter_set_status(self):
"""test with invalid parameter set: status."""
def test_create_invalid_parameter_set_created_at(self):
"""test with invalid parameter set: created_at."""
def test_create_invalid_parameter_set_updated_at(self):
"""test with invalid parameter set: updated_at."""
def test_create_invalid_parameter_set_deleted_at(self):
"""test with invalid parameter set: deleted_at."""