Add aggregates tests
* DB unit tests * objects unit tests * functional tests * tempest Change-Id: Ifb44bad51c0541105dcec091ee734d0cbba804ca
This commit is contained in:
parent
7baf214cd2
commit
b17fbb9a28
87
mogan/tests/functional/api/v1/test_aggregates.py
Normal file
87
mogan/tests/functional/api/v1/test_aggregates.py
Normal file
@ -0,0 +1,87 @@
|
||||
# Copyright 2017 Huawei Technologies Co., Ltd.
|
||||
#
|
||||
# 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 mock
|
||||
import six
|
||||
|
||||
from mogan.tests.functional.api import v1 as v1_test
|
||||
|
||||
|
||||
class TestAggregate(v1_test.APITestV1):
|
||||
|
||||
AGGREGATE_UUIDS = ['ff28b5a2-73e5-431c-b4b7-1b96b74bca7b',
|
||||
'94baf80e-2bae-4c3e-8dab-38b5441e7097',
|
||||
'4bcfff85-c55a-493b-b544-b6c90b8fb397',
|
||||
'e50fb289-4ee1-47dd-b371-6ca39af12888']
|
||||
|
||||
def setUp(self):
|
||||
super(TestAggregate, self).setUp()
|
||||
self.headers = self.gen_headers(self.context, roles="admin")
|
||||
|
||||
@mock.patch('oslo_utils.uuidutils.generate_uuid')
|
||||
def _prepare_aggregates(self, mocked):
|
||||
mocked.side_effect = self.AGGREGATE_UUIDS
|
||||
for i in six.moves.xrange(4):
|
||||
body = {"name": "test" + str(i),
|
||||
"metadata": {"k1": "v1"}}
|
||||
self.post_json('/aggregates', body,
|
||||
headers=self.headers, status=201)
|
||||
|
||||
def test_aggregate_post(self):
|
||||
body = {"name": "test",
|
||||
"metadata": {"k1": "v1"}}
|
||||
resp = self.post_json(
|
||||
'/aggregates', body, headers=self.headers, status=201)
|
||||
resp = resp.json
|
||||
self.assertEqual('test', resp['name'])
|
||||
self.assertEqual({'k1': 'v1'}, resp['metadata'])
|
||||
self.assertIn('uuid', resp)
|
||||
self.assertIn('links', resp)
|
||||
|
||||
def test_aggregate_get_all(self):
|
||||
self._prepare_aggregates()
|
||||
resp = self.get_json('/aggregates', headers=self.headers)
|
||||
self.assertEqual(4, len(resp['aggregates']))
|
||||
|
||||
def test_aggregate_get_one(self):
|
||||
self._prepare_aggregates()
|
||||
resp = self.get_json('/aggregates/' + self.AGGREGATE_UUIDS[0],
|
||||
headers=self.headers)
|
||||
self.assertEqual('test0', resp['name'])
|
||||
self.assertEqual({'k1': 'v1'}, resp['metadata'])
|
||||
|
||||
def test_aggregate_delete(self):
|
||||
self._prepare_aggregates()
|
||||
resp = self.get_json('/aggregates', headers=self.headers)
|
||||
self.assertEqual(4, len(resp['aggregates']))
|
||||
self.delete('/aggregates/' + self.AGGREGATE_UUIDS[0],
|
||||
headers=self.headers, status=204)
|
||||
resp = self.get_json('/aggregates', headers=self.headers)
|
||||
self.assertEqual(3, len(resp['aggregates']))
|
||||
|
||||
def test_aggregate_update(self):
|
||||
self._prepare_aggregates()
|
||||
resp = self.get_json('/aggregates/' + self.AGGREGATE_UUIDS[0],
|
||||
headers=self.headers)
|
||||
self.assertEqual('test0', resp['name'])
|
||||
self.patch_json('/aggregates/' + self.AGGREGATE_UUIDS[0],
|
||||
[{'path': '/name', 'value': 'updated_name',
|
||||
'op': 'replace'},
|
||||
{'path': '/metadata/k2', 'value': 'v2',
|
||||
'op': 'add'}],
|
||||
headers=self.headers, status=200)
|
||||
resp = self.get_json('/aggregates/' + self.AGGREGATE_UUIDS[0],
|
||||
headers=self.headers)
|
||||
self.assertEqual('updated_name', resp['name'])
|
||||
self.assertItemsEqual({'k1': 'v1', 'k2': 'v2'}, resp['metadata'])
|
78
mogan/tests/tempest/api/test_aggregates.py
Normal file
78
mogan/tests/tempest/api/test_aggregates.py
Normal file
@ -0,0 +1,78 @@
|
||||
# Copyright 2017 Huawei Technologies Co., Ltd.
|
||||
#
|
||||
# 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 import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from mogan.tests.tempest.api import base
|
||||
|
||||
|
||||
class BaremetalComputeAPIAggregatesTest(base.BaseBaremetalComputeTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(BaremetalComputeAPIAggregatesTest, cls).resource_setup()
|
||||
aggregate_body = {
|
||||
"name": "tempest-test-aggregate",
|
||||
"metadata": {"k1": "v1"}
|
||||
}
|
||||
cls.aggregate = cls.baremetal_compute_client.create_aggregate(
|
||||
**aggregate_body)
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
super(BaremetalComputeAPIAggregatesTest, cls).resource_cleanup()
|
||||
cls.aggregate = cls.baremetal_compute_client.delete_aggregate(
|
||||
cls.aggregate['uuid'])
|
||||
|
||||
@decorators.idempotent_id('82d94aab-62f1-4d85-bcb6-5c360f84d9b4')
|
||||
def test_aggregate_create(self):
|
||||
aggregate_body = {
|
||||
"name": "test-aggregate",
|
||||
"metadata": {"k1": "v1"}
|
||||
}
|
||||
aggregate = self.baremetal_compute_client.create_aggregate(
|
||||
**aggregate_body)
|
||||
self.assertEqual("test-aggregate", aggregate['name'])
|
||||
self.assertItemsEqual({'k1': 'v1'}, aggregate['metadata'])
|
||||
self.aggregate = self.baremetal_compute_client.delete_aggregate(
|
||||
aggregate['uuid'])
|
||||
|
||||
@decorators.idempotent_id('c7062d65-09f7-4efa-8852-3ac543416c31')
|
||||
def test_aggregate_show(self):
|
||||
aggregate = self.baremetal_compute_client.show_aggregate(
|
||||
self.aggregate['uuid'])
|
||||
self.assertEqual("tempest-test-aggregate", aggregate['name'])
|
||||
self.assertItemsEqual({'k1': 'v1'}, aggregate['metadata'])
|
||||
|
||||
@decorators.idempotent_id('a0520c12-4e7d-46ac-a0bc-c4c42fe3a344')
|
||||
def test_aggregates_list(self):
|
||||
aggregates = self.baremetal_compute_client.list_aggregates()
|
||||
self.assertEqual(1, len(aggregates))
|
||||
aggregate = aggregates[0]
|
||||
self.assertEqual("tempest-test-aggregate", aggregate['name'])
|
||||
self.assertItemsEqual({'k1': 'v1'}, aggregate['metadata'])
|
||||
|
||||
@decorators.idempotent_id('65614c7e-a1d9-4d1b-aa9a-6893616c0cc1')
|
||||
def test_aggregate_delete(self):
|
||||
aggregate_body = {
|
||||
"name": "test-aggregate1",
|
||||
"metadata": {"k1": "v1"}
|
||||
}
|
||||
aggregate = self.baremetal_compute_client.create_aggregate(
|
||||
**aggregate_body)
|
||||
self.aggregate = self.baremetal_compute_client.delete_aggregate(
|
||||
aggregate['uuid'])
|
||||
self.assertRaises(lib_exc.NotFound,
|
||||
self.baremetal_compute_client.show_aggregate,
|
||||
aggregate['uuid'])
|
@ -234,6 +234,36 @@ class BaremetalComputeClient(rest_client.RestClient):
|
||||
body = self.deserialize(body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
def list_aggregates(self):
|
||||
uri = '%s/aggregates' % self.uri_prefix
|
||||
resp, body = self.get(uri)
|
||||
self.expected_success(200, resp.status)
|
||||
body = self.deserialize(body)['aggregates']
|
||||
return rest_client.ResponseBodyList(resp, body)
|
||||
|
||||
def show_aggregate(self, aggregate_uuid):
|
||||
uri = '%s/aggregates/%s' % (self.uri_prefix, aggregate_uuid)
|
||||
resp, body = self.get(uri)
|
||||
self.expected_success(200, resp.status)
|
||||
body = self.deserialize(body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
def delete_aggregate(self, aggregate_uuid):
|
||||
uri = "%s/aggregates/%s" % (self.uri_prefix, aggregate_uuid)
|
||||
resp, body = self.delete(uri)
|
||||
self.expected_success(204, resp.status)
|
||||
if body:
|
||||
body = self.deserialize(body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
def create_aggregate(self, **kwargs):
|
||||
uri = "%s/aggregates" % self.uri_prefix
|
||||
body = self.serialize(kwargs)
|
||||
resp, body = self.post(uri, body)
|
||||
self.expected_success(201, resp.status)
|
||||
body = self.deserialize(body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
|
||||
class BaremetalNodeClient(rest_client.RestClient):
|
||||
version = '1'
|
||||
@ -297,6 +327,17 @@ class BaremetalNodeClient(rest_client.RestClient):
|
||||
self.update_bm_node(node_id, updates)
|
||||
|
||||
|
||||
class BaremetalAggregateClient(rest_client.RestClient):
|
||||
version = '1'
|
||||
uri_prefix = "v1"
|
||||
|
||||
def deserialize(self, body):
|
||||
return json.loads(body.replace("\n", ""))
|
||||
|
||||
def serialize(self, body):
|
||||
return json.dumps(body)
|
||||
|
||||
|
||||
class Manager(manager.Manager):
|
||||
|
||||
load_clients = [
|
||||
|
75
mogan/tests/unit/db/test_aggregates.py
Normal file
75
mogan/tests/unit/db/test_aggregates.py
Normal file
@ -0,0 +1,75 @@
|
||||
# Copyright 2017 Huawei Technologies Co.,LTD.
|
||||
# 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.
|
||||
|
||||
"""Tests for manipulating Aggregates via the DB API"""
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
|
||||
from mogan.common import exception
|
||||
from mogan.tests.unit.db import base
|
||||
from mogan.tests.unit.db import utils
|
||||
|
||||
|
||||
class DbAggregateTestCase(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(DbAggregateTestCase, self).setUp()
|
||||
self.aggregate = utils.create_test_aggregate()
|
||||
|
||||
def test_create_aggregate(self):
|
||||
utils.create_test_aggregate(name='testing')
|
||||
|
||||
def test_create_aggregate_already_exists(self):
|
||||
self.assertRaises(exception.AggregateNameExists,
|
||||
utils.create_test_aggregate,
|
||||
name=self.aggregate['name'])
|
||||
|
||||
def test_get_aggregate_list(self):
|
||||
uuids = [self.aggregate['uuid']]
|
||||
for i in range(1, 6):
|
||||
aggregate = utils.create_test_aggregate(
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
name=six.text_type(i))
|
||||
uuids.append(six.text_type(aggregate['uuid']))
|
||||
res = self.dbapi.aggregate_get_all(self.context)
|
||||
res_uuids = [r['uuid'] for r in res]
|
||||
six.assertCountEqual(self, uuids, res_uuids)
|
||||
|
||||
def test_get_aggregate(self):
|
||||
aggregate = self.dbapi.aggregate_get(
|
||||
self.context, self.aggregate['uuid'])
|
||||
|
||||
self.assertEqual(self.aggregate['uuid'], aggregate['uuid'])
|
||||
|
||||
def test_get_aggregate_that_does_not_exist(self):
|
||||
self.assertRaises(exception.AggregateNotFound,
|
||||
self.dbapi.aggregate_get,
|
||||
self.context,
|
||||
uuidutils.generate_uuid())
|
||||
|
||||
def test_destroy_aggregate(self):
|
||||
self.dbapi.aggregate_destroy(self.context, self.aggregate['id'])
|
||||
|
||||
self.assertRaises(exception.AggregateNotFound,
|
||||
self.dbapi.aggregate_destroy,
|
||||
self.context,
|
||||
self.aggregate['id'])
|
||||
|
||||
def test_destroy_aggregate_that_does_not_exist(self):
|
||||
self.assertRaises(exception.AggregateNotFound,
|
||||
self.dbapi.aggregate_destroy,
|
||||
self.context,
|
||||
uuidutils.generate_uuid())
|
@ -175,3 +175,32 @@ def create_test_quota(context={}, **kw):
|
||||
dbapi = db_api.get_instance()
|
||||
|
||||
return dbapi.quota_create(context, quota)
|
||||
|
||||
|
||||
def get_test_aggregate(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 123),
|
||||
'uuid': kw.get('uuid', uuidutils.generate_uuid()),
|
||||
'name': kw.get('name', 'test'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
'created_at': kw.get('created_at'),
|
||||
}
|
||||
|
||||
|
||||
def create_test_aggregate(context={}, **kw):
|
||||
"""Create test aggregate entry in DB and return the DB object.
|
||||
|
||||
Function to be used to create test Aggregate objects in the database.
|
||||
|
||||
:param context: The request context, for access checks.
|
||||
:param kw: kwargs with overriding values for aggregate's attributes.
|
||||
:returns: Test Aggregate DB object.
|
||||
|
||||
"""
|
||||
agg = get_test_aggregate(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del agg['id']
|
||||
dbapi = db_api.get_instance()
|
||||
|
||||
return dbapi.aggregate_create(context, agg)
|
||||
|
69
mogan/tests/unit/objects/test_aggregate.py
Normal file
69
mogan/tests/unit/objects/test_aggregate.py
Normal file
@ -0,0 +1,69 @@
|
||||
#
|
||||
# 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 mock
|
||||
from oslo_context import context
|
||||
|
||||
from mogan import objects
|
||||
from mogan.tests.unit.db import base
|
||||
from mogan.tests.unit.db import utils
|
||||
|
||||
|
||||
class TestAggregateObject(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAggregateObject, self).setUp()
|
||||
self.ctxt = context.get_admin_context()
|
||||
self.fake_aggregate = utils.get_test_aggregate(context=self.ctxt)
|
||||
self.fake_aggregate['metadetails'] = {}
|
||||
|
||||
def test_get(self):
|
||||
uuid = self.fake_aggregate['uuid']
|
||||
with mock.patch.object(self.dbapi, 'aggregate_get',
|
||||
autospec=True) as mock_aggregate_get:
|
||||
mock_aggregate_get.return_value = self.fake_aggregate
|
||||
aggregate = objects.Aggregate.get(self.context, uuid)
|
||||
mock_aggregate_get.assert_called_once_with(self.context, uuid)
|
||||
self.assertEqual(self.context, aggregate._context)
|
||||
|
||||
def test_create(self):
|
||||
with mock.patch.object(self.dbapi, 'aggregate_create',
|
||||
autospec=True) as mock_aggregate_create:
|
||||
mock_aggregate_create.return_value = self.fake_aggregate
|
||||
aggregate = objects.Aggregate(self.context, **self.fake_aggregate)
|
||||
values = aggregate.obj_get_changes()
|
||||
aggregate.create(self.context)
|
||||
mock_aggregate_create.assert_called_once_with(self.context, values)
|
||||
self.assertEqual(self.fake_aggregate['uuid'], aggregate['uuid'])
|
||||
|
||||
def test_destroy(self):
|
||||
agg_id = self.fake_aggregate['id']
|
||||
with mock.patch.object(self.dbapi, 'aggregate_destroy',
|
||||
autospec=True) as mock_aggregate_destroy:
|
||||
mock_aggregate_destroy.return_value = self.fake_aggregate
|
||||
aggregate = objects.Aggregate(self.context, **self.fake_aggregate)
|
||||
aggregate.destroy(self.context)
|
||||
mock_aggregate_destroy.assert_called_once_with(
|
||||
self.context, agg_id)
|
||||
|
||||
def test_save(self):
|
||||
id = self.fake_aggregate['id']
|
||||
with mock.patch.object(self.dbapi, 'aggregate_update',
|
||||
autospec=True) as mock_aggregate_update:
|
||||
aggregate = objects.Aggregate(self.context, **self.fake_aggregate)
|
||||
aggregate.name = 'changed_name'
|
||||
updates = aggregate.obj_get_changes()
|
||||
aggregate.save(self.context)
|
||||
mock_aggregate_update.return_value = self.fake_aggregate
|
||||
mock_aggregate_update.assert_called_once_with(
|
||||
self.context, id, updates)
|
Loading…
Reference in New Issue
Block a user