tests: do not create legacy resources
This use custom created resource types instead of the Ceilometer legacy resource types, and kill the individual testing of those resources. Change-Id: I08eb305f426d5a1565c089e91bf5fe63faa14b14
This commit is contained in:
parent
09377bfc8a
commit
955591a042
@ -234,6 +234,22 @@
|
||||
"metrics": {"temperature": {"archive_policy_name": "low"}}
|
||||
}
|
||||
|
||||
- name: create-resource-type-instance
|
||||
request: |
|
||||
POST /v1/resource_type HTTP/1.1
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "instance",
|
||||
"attributes": {
|
||||
"display_name": {"type": "string", "required": true},
|
||||
"flavor_id": {"type": "string", "required": true},
|
||||
"image_ref": {"type": "string", "required": true},
|
||||
"host": {"type": "string", "required": true},
|
||||
"server_group": {"type": "string", "required": false}
|
||||
}
|
||||
}
|
||||
|
||||
- name: create-resource-instance
|
||||
request: |
|
||||
POST /v1/resource/instance HTTP/1.1
|
||||
|
@ -218,6 +218,17 @@ class ResourceClassMapper(object):
|
||||
class SQLAlchemyIndexer(indexer.IndexerDriver):
|
||||
_RESOURCE_TYPE_MANAGER = ResourceClassMapper()
|
||||
|
||||
@classmethod
|
||||
def _create_new_database(cls, url):
|
||||
"""Used by testing to create a new database."""
|
||||
purl = sqlalchemy_url.make_url(
|
||||
cls.dress_url(
|
||||
url))
|
||||
purl.database = purl.database + str(uuid.uuid4()).replace('-', '')
|
||||
new_url = str(purl)
|
||||
sqlalchemy_utils.create_database(new_url)
|
||||
return new_url
|
||||
|
||||
@staticmethod
|
||||
def dress_url(url):
|
||||
# If no explicit driver has been set, we default to pymysql
|
||||
|
@ -397,13 +397,7 @@ class TestCase(base.BaseTestCase):
|
||||
self.coord.start()
|
||||
|
||||
with self.coord.get_lock(b"gnocchi-tests-db-lock"):
|
||||
# Force upgrading using Alembic rather than creating the
|
||||
# database from scratch so we are sure we don't miss anything
|
||||
# in the Alembic upgrades. We have a test to check that
|
||||
# upgrades == create but it misses things such as custom CHECK
|
||||
# constraints.
|
||||
self.index.upgrade(nocreate=True,
|
||||
create_legacy_resource_types=True)
|
||||
self.index.upgrade()
|
||||
|
||||
self.coord.stop()
|
||||
|
||||
|
@ -20,11 +20,9 @@ import tempfile
|
||||
import threading
|
||||
import time
|
||||
from unittest import case
|
||||
import uuid
|
||||
import warnings
|
||||
|
||||
from gabbi import fixture
|
||||
import sqlalchemy.engine.url as sqlalchemy_url
|
||||
import sqlalchemy_utils
|
||||
|
||||
from gnocchi import indexer
|
||||
@ -103,14 +101,11 @@ class ConfigFixture(fixture.GabbiFixture):
|
||||
|
||||
# NOTE(jd) All of that is still very SQL centric but we only support
|
||||
# SQL for now so let's say it's good enough.
|
||||
url = sqlalchemy_url.make_url(
|
||||
sqlalchemy.SQLAlchemyIndexer.dress_url(
|
||||
conf.indexer.url))
|
||||
|
||||
url.database = url.database + str(uuid.uuid4()).replace('-', '')
|
||||
db_url = str(url)
|
||||
conf.set_override('url', db_url, 'indexer')
|
||||
sqlalchemy_utils.create_database(db_url)
|
||||
conf.set_override(
|
||||
'url',
|
||||
sqlalchemy.SQLAlchemyIndexer._create_new_database(
|
||||
conf.indexer.url),
|
||||
'indexer')
|
||||
|
||||
index = indexer.get_driver(conf)
|
||||
index.connect()
|
||||
|
@ -17,7 +17,10 @@ import abc
|
||||
import mock
|
||||
from oslo_db.sqlalchemy import test_migrations
|
||||
import six
|
||||
import sqlalchemy_utils
|
||||
|
||||
from gnocchi import indexer
|
||||
from gnocchi.indexer import sqlalchemy
|
||||
from gnocchi.indexer import sqlalchemy_base
|
||||
from gnocchi.tests import base
|
||||
|
||||
@ -34,6 +37,14 @@ class ModelsMigrationsSync(
|
||||
def setUp(self):
|
||||
super(ModelsMigrationsSync, self).setUp()
|
||||
self.db = mock.Mock()
|
||||
self.conf.set_override(
|
||||
'url',
|
||||
sqlalchemy.SQLAlchemyIndexer._create_new_database(
|
||||
self.conf.indexer.url),
|
||||
'indexer')
|
||||
self.index = indexer.get_driver(self.conf)
|
||||
self.index.connect()
|
||||
self.index.upgrade(nocreate=True, create_legacy_resource_types=True)
|
||||
|
||||
@staticmethod
|
||||
def get_metadata():
|
||||
@ -44,6 +55,8 @@ class ModelsMigrationsSync(
|
||||
|
||||
@staticmethod
|
||||
def db_sync(engine):
|
||||
# NOTE(jd) Nothing to do here as setUp() in the base class is already
|
||||
# creating table using upgrade
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
sqlalchemy_utils.drop_database(self.conf.indexer.url)
|
||||
super(ModelsMigrationsSync, self).tearDown()
|
||||
|
@ -228,52 +228,6 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
m = self.index.list_metrics(id=rc.metrics[0].id)
|
||||
self.assertEqual(m[0], rc.metrics[0])
|
||||
|
||||
def _do_test_create_instance(self, server_group=None, image_ref=None):
|
||||
r1 = uuid.uuid4()
|
||||
user = str(uuid.uuid4())
|
||||
project = str(uuid.uuid4())
|
||||
kwargs = {'server_group': server_group} if server_group else {}
|
||||
|
||||
rc = self.index.create_resource('instance', r1, user, project,
|
||||
flavor_id="1",
|
||||
image_ref=image_ref,
|
||||
host="foo",
|
||||
display_name="lol", **kwargs)
|
||||
self.assertIsNotNone(rc.started_at)
|
||||
self.assertIsNotNone(rc.revision_start)
|
||||
self.assertEqual({"id": r1,
|
||||
"revision_start": rc.revision_start,
|
||||
"revision_end": None,
|
||||
"type": "instance",
|
||||
"created_by_user_id": user,
|
||||
"created_by_project_id": project,
|
||||
"user_id": None,
|
||||
"project_id": None,
|
||||
"started_at": rc.started_at,
|
||||
"ended_at": None,
|
||||
"display_name": "lol",
|
||||
"server_group": server_group,
|
||||
"host": "foo",
|
||||
"image_ref": image_ref,
|
||||
"flavor_id": "1",
|
||||
"original_resource_id": None,
|
||||
"metrics": {}},
|
||||
rc.jsonify())
|
||||
rg = self.index.get_resource('generic', r1, with_metrics=True)
|
||||
self.assertEqual(rc.id, rg.id)
|
||||
self.assertEqual(rc.revision_start, rg.revision_start)
|
||||
self.assertEqual(rc.metrics, rg.metrics)
|
||||
|
||||
def test_create_instance(self):
|
||||
self._do_test_create_instance(image_ref='http://foo/bar')
|
||||
|
||||
def test_create_instance_with_server_group(self):
|
||||
self._do_test_create_instance('my_autoscaling_group',
|
||||
image_ref='http://foo/bar')
|
||||
|
||||
def test_create_instance_without_image_ref(self):
|
||||
self._do_test_create_instance(image_ref=None)
|
||||
|
||||
def test_delete_resource(self):
|
||||
r1 = uuid.uuid4()
|
||||
self.index.create_resource('generic', r1, str(uuid.uuid4()),
|
||||
@ -484,30 +438,40 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
self.assertEqual(e1, r.metrics[0].id)
|
||||
|
||||
def test_update_resource_attribute(self):
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
rtype = mgr.resource_type_from_dict(resource_type, {
|
||||
"col1": {"type": "string", "required": True,
|
||||
"min_length": 2, "max_length": 15}
|
||||
})
|
||||
r1 = uuid.uuid4()
|
||||
user = str(uuid.uuid4())
|
||||
project = str(uuid.uuid4())
|
||||
rc = self.index.create_resource('instance', r1, user, project,
|
||||
flavor_id="1",
|
||||
image_ref="http://foo/bar",
|
||||
host="foo",
|
||||
display_name="lol")
|
||||
rc = self.index.update_resource('instance', r1, host="bar")
|
||||
r = self.index.get_resource('instance', r1, with_metrics=True)
|
||||
# Create
|
||||
self.index.create_resource_type(rtype)
|
||||
|
||||
rc = self.index.create_resource(resource_type, r1, user, project,
|
||||
col1="foo")
|
||||
rc = self.index.update_resource(resource_type, r1, col1="foo")
|
||||
r = self.index.get_resource(resource_type, r1, with_metrics=True)
|
||||
self.assertEqual(rc, r)
|
||||
|
||||
def test_update_resource_no_change(self):
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
rtype = mgr.resource_type_from_dict(resource_type, {
|
||||
"col1": {"type": "string", "required": True,
|
||||
"min_length": 2, "max_length": 15}
|
||||
})
|
||||
self.index.create_resource_type(rtype)
|
||||
r1 = uuid.uuid4()
|
||||
user = str(uuid.uuid4())
|
||||
project = str(uuid.uuid4())
|
||||
rc = self.index.create_resource('instance', r1, user, project,
|
||||
flavor_id="1",
|
||||
image_ref="http://foo/bar",
|
||||
host="foo",
|
||||
display_name="lol")
|
||||
updated = self.index.update_resource('instance', r1, host="foo",
|
||||
rc = self.index.create_resource(resource_type, r1, user, project,
|
||||
col1="foo")
|
||||
updated = self.index.update_resource(resource_type, r1, col1="foo",
|
||||
create_revision=False)
|
||||
r = self.index.list_resources('instance',
|
||||
r = self.index.list_resources(resource_type,
|
||||
{"=": {"id": r1}},
|
||||
history=True)
|
||||
self.assertEqual(1, len(r))
|
||||
@ -518,28 +482,27 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
r1 = uuid.uuid4()
|
||||
user = str(uuid.uuid4())
|
||||
project = str(uuid.uuid4())
|
||||
self.index.create_resource('instance', r1, user, project,
|
||||
flavor_id="1",
|
||||
image_ref="http://foo/bar",
|
||||
host="foo",
|
||||
display_name="lol")
|
||||
self.index.create_resource('generic', r1, user, project)
|
||||
self.assertRaises(
|
||||
indexer.ResourceValueError,
|
||||
self.index.update_resource,
|
||||
'instance', r1,
|
||||
'generic', r1,
|
||||
ended_at=utils.datetime_utc(2010, 1, 1, 1, 1, 1))
|
||||
|
||||
def test_update_resource_unknown_attribute(self):
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
rtype = mgr.resource_type_from_dict(resource_type, {
|
||||
"col1": {"type": "string", "required": False,
|
||||
"min_length": 1, "max_length": 2},
|
||||
})
|
||||
self.index.create_resource_type(rtype)
|
||||
r1 = uuid.uuid4()
|
||||
self.index.create_resource('instance', r1, str(uuid.uuid4()),
|
||||
str(uuid.uuid4()),
|
||||
flavor_id="1",
|
||||
image_ref="http://foo/bar",
|
||||
host="foo",
|
||||
display_name="lol")
|
||||
self.index.create_resource(resource_type, r1,
|
||||
str(uuid.uuid4()), str(uuid.uuid4()))
|
||||
self.assertRaises(indexer.ResourceAttributeError,
|
||||
self.index.update_resource,
|
||||
'instance',
|
||||
resource_type,
|
||||
r1, foo="bar")
|
||||
|
||||
def test_update_non_existent_metric(self):
|
||||
@ -601,19 +564,25 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
"type": "generic",
|
||||
"metrics": {'bar': str(e2)}}, r.jsonify())
|
||||
|
||||
def test_delete_instance(self):
|
||||
def test_delete_resource_custom(self):
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {
|
||||
"flavor_id": {"type": "string",
|
||||
"min_length": 1,
|
||||
"max_length": 20,
|
||||
"required": True}
|
||||
}))
|
||||
r1 = uuid.uuid4()
|
||||
created = self.index.create_resource('instance', r1,
|
||||
created = self.index.create_resource(resource_type, r1,
|
||||
str(uuid.uuid4()),
|
||||
str(uuid.uuid4()),
|
||||
flavor_id="123",
|
||||
image_ref="foo",
|
||||
host="dwq",
|
||||
display_name="foobar")
|
||||
got = self.index.get_resource('instance', r1, with_metrics=True)
|
||||
flavor_id="foo")
|
||||
got = self.index.get_resource(resource_type, r1, with_metrics=True)
|
||||
self.assertEqual(created, got)
|
||||
self.index.delete_resource(r1)
|
||||
got = self.index.get_resource('instance', r1)
|
||||
got = self.index.get_resource(resource_type, r1)
|
||||
self.assertIsNone(got)
|
||||
|
||||
def test_list_resources_by_unknown_field(self):
|
||||
@ -659,14 +628,14 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
project = str(uuid.uuid4())
|
||||
g = self.index.create_resource('generic', r1, user, project,
|
||||
user, project)
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {}))
|
||||
r2 = uuid.uuid4()
|
||||
i = self.index.create_resource('instance', r2,
|
||||
i = self.index.create_resource(resource_type, r2,
|
||||
user, project,
|
||||
user, project,
|
||||
flavor_id="123",
|
||||
image_ref="foo",
|
||||
host="dwq",
|
||||
display_name="foobar")
|
||||
user, project)
|
||||
resources = self.index.list_resources(
|
||||
'generic',
|
||||
attribute_filter={"=": {"user_id": user}},
|
||||
@ -724,13 +693,13 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
r1 = uuid.uuid4()
|
||||
g = self.index.create_resource('generic', r1,
|
||||
str(uuid.uuid4()), str(uuid.uuid4()))
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {}))
|
||||
r2 = uuid.uuid4()
|
||||
i = self.index.create_resource('instance', r2,
|
||||
str(uuid.uuid4()), str(uuid.uuid4()),
|
||||
flavor_id="123",
|
||||
image_ref="foo",
|
||||
host="dwq",
|
||||
display_name="foobar")
|
||||
i = self.index.create_resource(resource_type, r2,
|
||||
str(uuid.uuid4()), str(uuid.uuid4()))
|
||||
resources = self.index.list_resources('generic')
|
||||
self.assertGreaterEqual(len(resources), 2)
|
||||
g_found = False
|
||||
@ -746,7 +715,7 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
else:
|
||||
self.fail("Some resources were not found")
|
||||
|
||||
resources = self.index.list_resources('instance')
|
||||
resources = self.index.list_resources(resource_type)
|
||||
self.assertGreaterEqual(len(resources), 1)
|
||||
for r in resources:
|
||||
if r.id == r2:
|
||||
@ -765,9 +734,19 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
'generic',
|
||||
attribute_filter={"=": {"id": "f00bar" * 50}})
|
||||
|
||||
def test_list_resource_instance_flavor_id_numeric(self):
|
||||
def test_list_resource_attribute_type_numeric(self):
|
||||
"""Test that we can pass an integer to filter on a string type."""
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {
|
||||
"flavor_id": {"type": "string",
|
||||
"min_length": 1,
|
||||
"max_length": 20,
|
||||
"required": False},
|
||||
}))
|
||||
r = self.index.list_resources(
|
||||
'instance', attribute_filter={"=": {"flavor_id": 1.0}})
|
||||
resource_type, attribute_filter={"=": {"flavor_id": 1.0}})
|
||||
self.assertEqual(0, len(r))
|
||||
|
||||
def test_list_resource_weird_date(self):
|
||||
@ -845,7 +824,7 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
key=operator.itemgetter("revision_start"))
|
||||
self.assertEqual([r1, r2], resources)
|
||||
|
||||
def test_list_resources_instance_with_history(self):
|
||||
def test_list_resources_custom_with_history(self):
|
||||
e1 = uuid.uuid4()
|
||||
e2 = uuid.uuid4()
|
||||
rid = uuid.uuid4()
|
||||
@ -854,6 +833,14 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
new_user = str(uuid.uuid4())
|
||||
new_project = str(uuid.uuid4())
|
||||
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {
|
||||
"col1": {"type": "string", "required": True,
|
||||
"min_length": 2, "max_length": 15}
|
||||
}))
|
||||
|
||||
self.index.create_metric(e1, user, project,
|
||||
archive_policy_name="low")
|
||||
self.index.create_metric(e2, user, project,
|
||||
@ -861,17 +848,14 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
self.index.create_metric(uuid.uuid4(), user, project,
|
||||
archive_policy_name="low")
|
||||
|
||||
r1 = self.index.create_resource('instance', rid, user, project,
|
||||
r1 = self.index.create_resource(resource_type, rid, user, project,
|
||||
user, project,
|
||||
flavor_id="123",
|
||||
image_ref="foo",
|
||||
host="dwq",
|
||||
display_name="foobar_history",
|
||||
col1="foo",
|
||||
metrics={'foo': e1, 'bar': e2}
|
||||
).jsonify()
|
||||
r2 = self.index.update_resource('instance', rid, user_id=new_user,
|
||||
r2 = self.index.update_resource(resource_type, rid, user_id=new_user,
|
||||
project_id=new_project,
|
||||
host="other",
|
||||
col1="bar",
|
||||
append_metrics=True).jsonify()
|
||||
|
||||
r1['revision_end'] = r2['revision_start']
|
||||
@ -880,8 +864,8 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
'bar': str(e2)}, r2['metrics'])
|
||||
self.assertEqual(new_user, r2['user_id'])
|
||||
self.assertEqual(new_project, r2['project_id'])
|
||||
self.assertEqual('other', r2['host'])
|
||||
resources = self.index.list_resources('instance', history=True,
|
||||
self.assertEqual('bar', r2['col1'])
|
||||
resources = self.index.list_resources(resource_type, history=True,
|
||||
details=False,
|
||||
attribute_filter={
|
||||
"=": {"id": rid}})
|
||||
@ -903,12 +887,12 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
started_at=utils.datetime_utc(2000, 1, 1, 23, 23, 23),
|
||||
ended_at=utils.datetime_utc(2000, 1, 3, 23, 23, 23))
|
||||
r2 = uuid.uuid4()
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {}))
|
||||
i = self.index.create_resource(
|
||||
'instance', r2, user, project,
|
||||
flavor_id="123",
|
||||
image_ref="foo",
|
||||
host="dwq",
|
||||
display_name="foobar",
|
||||
resource_type, r2, user, project,
|
||||
started_at=utils.datetime_utc(2000, 1, 1, 23, 23, 23),
|
||||
ended_at=utils.datetime_utc(2000, 1, 4, 23, 23, 23))
|
||||
resources = self.index.list_resources(
|
||||
@ -934,7 +918,7 @@ class TestIndexerDriver(tests_base.TestCase):
|
||||
self.fail("Some resources were not found")
|
||||
|
||||
resources = self.index.list_resources(
|
||||
'instance',
|
||||
resource_type,
|
||||
attribute_filter={
|
||||
">=": {
|
||||
"started_at": datetime.datetime(2000, 1, 1, 23, 23, 23)
|
||||
|
@ -499,12 +499,17 @@ class MetricTest(RestTest):
|
||||
self.assertIn('Invalid value for window', ret.text)
|
||||
|
||||
def test_get_resource_missing_named_metric_measure_aggregation(self):
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(resource_type, {
|
||||
"server_group": {"type": "string",
|
||||
"min_length": 1,
|
||||
"max_length": 40,
|
||||
"required": True}
|
||||
}))
|
||||
|
||||
attributes = {
|
||||
"started_at": "2014-01-03T02:02:02.000000",
|
||||
"host": "foo",
|
||||
"image_ref": "imageref!",
|
||||
"flavor_id": "123",
|
||||
"display_name": "myinstance",
|
||||
"server_group": str(uuid.uuid4()),
|
||||
}
|
||||
result = self.app.post_json("/v1/metric",
|
||||
@ -527,16 +532,17 @@ class MetricTest(RestTest):
|
||||
|
||||
attributes['id'] = str(uuid.uuid4())
|
||||
attributes['metrics'] = {'foo': metric1['id']}
|
||||
self.app.post_json("/v1/resource/instance",
|
||||
self.app.post_json("/v1/resource/" + resource_type,
|
||||
params=attributes)
|
||||
|
||||
attributes['id'] = str(uuid.uuid4())
|
||||
attributes['metrics'] = {'bar': metric2['id']}
|
||||
self.app.post_json("/v1/resource/instance",
|
||||
self.app.post_json("/v1/resource/" + resource_type,
|
||||
params=attributes)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/instance/metric/foo?aggregation=max",
|
||||
"/v1/aggregation/resource/%s/metric/foo?aggregation=max"
|
||||
% resource_type,
|
||||
params={"=": {"server_group": attributes['server_group']}})
|
||||
|
||||
measures = json.loads(result.text)
|
||||
@ -578,227 +584,19 @@ class MetricTest(RestTest):
|
||||
|
||||
|
||||
class ResourceTest(RestTest):
|
||||
|
||||
resource_scenarios = [
|
||||
('generic', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='generic')),
|
||||
('instance_disk', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"name": "disk-name",
|
||||
"instance_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
"name": "new-disk-name",
|
||||
},
|
||||
resource_type='instance_disk')),
|
||||
('instance_network_interface', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"name": "nic-name",
|
||||
"instance_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
"name": "new-nic-name",
|
||||
},
|
||||
resource_type='instance_network_interface')),
|
||||
('instance', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
# NOTE(jd) We test this one without user_id/project_id!
|
||||
# Just to test that use case. :)
|
||||
"host": "foo",
|
||||
"image_ref": "imageref!",
|
||||
"flavor_id": "123",
|
||||
"display_name": "myinstance",
|
||||
"server_group": "as_group",
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
"host": "fooz",
|
||||
"image_ref": "imageref!z",
|
||||
"flavor_id": "1234",
|
||||
"display_name": "myinstancez",
|
||||
"server_group": "new_as_group",
|
||||
},
|
||||
resource_type='instance')),
|
||||
# swift notifications contain UUID user_id
|
||||
('swift_account', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='swift_account')),
|
||||
# swift pollsters contain None user_id
|
||||
('swift_account_none_user', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": None,
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='swift_account')),
|
||||
# TODO(dbelova): add tests with None project ID when we'll add kwapi,
|
||||
# ipmi, hardware, etc. resources that are passed without project ID
|
||||
('volume', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"display_name": "test_volume",
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
"display_name": "myvolume",
|
||||
},
|
||||
resource_type='volume')),
|
||||
('ceph_account', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='ceph_account')),
|
||||
('network', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='network')),
|
||||
('identity', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='identity')),
|
||||
('ipmi', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='ipmi')),
|
||||
('stack', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='stack')),
|
||||
# image pollsters contain UUID user_id
|
||||
('image', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"name": "test-image",
|
||||
"container_format": "aki",
|
||||
"disk_format": "aki",
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='image')),
|
||||
# image pollsters contain None user_id
|
||||
('image_none_user', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": None,
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"name": "test-image2",
|
||||
"container_format": "aki",
|
||||
"disk_format": "aki",
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='image')),
|
||||
('host', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"host_name": "test-host",
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='host')),
|
||||
('host_disk', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"host_name": "test-host",
|
||||
"device_name": "test-device"
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='host_disk')),
|
||||
('host_network_interface', dict(
|
||||
attributes={
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"host_name": "test-host",
|
||||
"device_name": "test-device"
|
||||
},
|
||||
patchable_attributes={
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
},
|
||||
resource_type='host_network_interface')),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def generate_scenarios(cls):
|
||||
cls.scenarios = testscenarios.multiply_scenarios(
|
||||
cls.scenarios,
|
||||
cls.resource_scenarios)
|
||||
|
||||
def setUp(self):
|
||||
super(ResourceTest, self).setUp()
|
||||
# Copy attributes so we can modify them in each test :)
|
||||
self.attributes = self.attributes.copy()
|
||||
# Set an id in the attribute
|
||||
self.attributes['id'] = str(uuid.uuid4())
|
||||
self.attributes = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"started_at": "2014-01-03T02:02:02+00:00",
|
||||
"user_id": str(uuid.uuid4()),
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"name": "my-name",
|
||||
}
|
||||
self.patchable_attributes = {
|
||||
"ended_at": "2014-01-03T02:02:02+00:00",
|
||||
"name": "new-name",
|
||||
}
|
||||
self.resource = self.attributes.copy()
|
||||
# Set original_resource_id
|
||||
self.resource['original_resource_id'] = self.resource['id']
|
||||
@ -808,7 +606,6 @@ class ResourceTest(RestTest):
|
||||
else:
|
||||
self.resource['created_by_user_id'] = None
|
||||
self.resource['created_by_project_id'] = None
|
||||
self.resource['type'] = self.resource_type
|
||||
self.resource['ended_at'] = None
|
||||
self.resource['metrics'] = {}
|
||||
if 'user_id' not in self.resource:
|
||||
@ -816,6 +613,17 @@ class ResourceTest(RestTest):
|
||||
if 'project_id' not in self.resource:
|
||||
self.resource['project_id'] = None
|
||||
|
||||
mgr = self.index.get_resource_type_schema()
|
||||
self.resource_type = str(uuid.uuid4())
|
||||
self.index.create_resource_type(
|
||||
mgr.resource_type_from_dict(self.resource_type, {
|
||||
"name": {"type": "string",
|
||||
"min_length": 1,
|
||||
"max_length": 40,
|
||||
"required": True}
|
||||
}))
|
||||
self.resource['type'] = self.resource_type
|
||||
|
||||
@mock.patch.object(utils, 'utcnow')
|
||||
def test_post_resource(self, utcnow):
|
||||
utcnow.return_value = utils.datetime_utc(2014, 1, 1, 10, 23)
|
||||
@ -1752,10 +1560,9 @@ class ResourceTest(RestTest):
|
||||
|
||||
# NOTE(sileht): because the database is never cleaned between each test
|
||||
# we must ensure that the query will not match resources from an other
|
||||
# test, to achieve this we set a different server_group on each test.
|
||||
server_group = str(uuid.uuid4())
|
||||
if self.resource_type == 'instance':
|
||||
self.attributes['server_group'] = server_group
|
||||
# test, to achieve this we set a different name on each test.
|
||||
name = str(uuid.uuid4())
|
||||
self.attributes['name'] = name
|
||||
|
||||
self.attributes['metrics'] = {'foo': metric1['id']}
|
||||
self.app.post_json("/v1/resource/" + self.resource_type,
|
||||
@ -1769,14 +1576,11 @@ class ResourceTest(RestTest):
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/"
|
||||
+ self.resource_type + "/metric/foo?aggregation=max",
|
||||
params={"and":
|
||||
[{"=": {"server_group": server_group}},
|
||||
{"=": {"display_name": "myinstance"}}]},
|
||||
params={"=": {"name": name}},
|
||||
status=400)
|
||||
if self.resource_type == 'instance':
|
||||
self.assertIn(b"One of the metrics being aggregated doesn't have "
|
||||
b"matching granularity",
|
||||
result.body)
|
||||
self.assertIn(b"One of the metrics being aggregated doesn't have "
|
||||
b"matching granularity",
|
||||
result.body)
|
||||
|
||||
def test_get_res_named_metric_measure_aggregation_nooverlap(self):
|
||||
result = self.app.post_json("/v1/metric",
|
||||
@ -1794,10 +1598,9 @@ class ResourceTest(RestTest):
|
||||
|
||||
# NOTE(sileht): because the database is never cleaned between each test
|
||||
# we must ensure that the query will not match resources from an other
|
||||
# test, to achieve this we set a different server_group on each test.
|
||||
server_group = str(uuid.uuid4())
|
||||
if self.resource_type == 'instance':
|
||||
self.attributes['server_group'] = server_group
|
||||
# test, to achieve this we set a different name on each test.
|
||||
name = str(uuid.uuid4())
|
||||
self.attributes['name'] = name
|
||||
|
||||
self.attributes['metrics'] = {'foo': metric1['id']}
|
||||
self.app.post_json("/v1/resource/" + self.resource_type,
|
||||
@ -1811,35 +1614,25 @@ class ResourceTest(RestTest):
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/" + self.resource_type
|
||||
+ "/metric/foo?aggregation=max",
|
||||
params={"and":
|
||||
[{"=": {"server_group": server_group}},
|
||||
{"=": {"display_name": "myinstance"}}]},
|
||||
params={"=": {"name": name}},
|
||||
expect_errors=True)
|
||||
|
||||
if self.resource_type == 'instance':
|
||||
self.assertEqual(400, result.status_code, result.text)
|
||||
self.assertIn("No overlap", result.text)
|
||||
else:
|
||||
self.assertEqual(400, result.status_code)
|
||||
self.assertEqual(400, result.status_code, result.text)
|
||||
self.assertIn("No overlap", result.text)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/"
|
||||
+ self.resource_type + "/metric/foo?aggregation=min"
|
||||
+ "&needed_overlap=0",
|
||||
params={"and":
|
||||
[{"=": {"server_group": server_group}},
|
||||
{"=": {"display_name": "myinstance"}}]},
|
||||
params={"=": {"name": name}},
|
||||
expect_errors=True)
|
||||
|
||||
if self.resource_type == 'instance':
|
||||
self.assertEqual(200, result.status_code, result.text)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([['2013-01-01T00:00:00+00:00', 86400.0, 8.0],
|
||||
['2013-01-01T12:00:00+00:00', 3600.0, 8.0],
|
||||
['2013-01-01T12:00:00+00:00', 60.0, 8.0]],
|
||||
measures)
|
||||
else:
|
||||
self.assertEqual(400, result.status_code)
|
||||
self.assertEqual(200, result.status_code, result.text)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([['2013-01-01T00:00:00+00:00', 86400.0, 8.0],
|
||||
['2013-01-01T12:00:00+00:00', 3600.0, 8.0],
|
||||
['2013-01-01T12:00:00+00:00', 60.0, 8.0]],
|
||||
measures)
|
||||
|
||||
def test_get_res_named_metric_measure_aggregation_nominal(self):
|
||||
result = self.app.post_json("/v1/metric",
|
||||
@ -1862,10 +1655,9 @@ class ResourceTest(RestTest):
|
||||
|
||||
# NOTE(sileht): because the database is never cleaned between each test
|
||||
# we must ensure that the query will not match resources from an other
|
||||
# test, to achieve this we set a different server_group on each test.
|
||||
server_group = str(uuid.uuid4())
|
||||
if self.resource_type == 'instance':
|
||||
self.attributes['server_group'] = server_group
|
||||
# test, to achieve this we set a different name on each test.
|
||||
name = str(uuid.uuid4())
|
||||
self.attributes['name'] = name
|
||||
|
||||
self.attributes['metrics'] = {'foo': metric1['id']}
|
||||
self.app.post_json("/v1/resource/" + self.resource_type,
|
||||
@ -1879,54 +1671,39 @@ class ResourceTest(RestTest):
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/" + self.resource_type
|
||||
+ "/metric/foo?aggregation=max",
|
||||
params={"and":
|
||||
[{"=": {"server_group": server_group}},
|
||||
{"=": {"display_name": "myinstance"}}]},
|
||||
params={"=": {"name": name}},
|
||||
expect_errors=True)
|
||||
|
||||
if self.resource_type == 'instance':
|
||||
self.assertEqual(200, result.status_code, result.text)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([[u'2013-01-01T00:00:00+00:00', 86400.0, 16.0],
|
||||
[u'2013-01-01T12:00:00+00:00', 3600.0, 16.0],
|
||||
[u'2013-01-01T12:00:00+00:00', 60.0, 16.0]],
|
||||
measures)
|
||||
else:
|
||||
self.assertEqual(400, result.status_code)
|
||||
self.assertEqual(200, result.status_code, result.text)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([[u'2013-01-01T00:00:00+00:00', 86400.0, 16.0],
|
||||
[u'2013-01-01T12:00:00+00:00', 3600.0, 16.0],
|
||||
[u'2013-01-01T12:00:00+00:00', 60.0, 16.0]],
|
||||
measures)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/"
|
||||
+ self.resource_type + "/metric/foo?aggregation=min",
|
||||
params={"and":
|
||||
[{"=": {"server_group": server_group}},
|
||||
{"=": {"display_name": "myinstance"}}]},
|
||||
params={"=": {"name": name}},
|
||||
expect_errors=True)
|
||||
|
||||
if self.resource_type == 'instance':
|
||||
self.assertEqual(200, result.status_code)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([['2013-01-01T00:00:00+00:00', 86400.0, 0],
|
||||
['2013-01-01T12:00:00+00:00', 3600.0, 0],
|
||||
['2013-01-01T12:00:00+00:00', 60.0, 0]],
|
||||
measures)
|
||||
else:
|
||||
self.assertEqual(400, result.status_code)
|
||||
self.assertEqual(200, result.status_code)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([['2013-01-01T00:00:00+00:00', 86400.0, 0],
|
||||
['2013-01-01T12:00:00+00:00', 3600.0, 0],
|
||||
['2013-01-01T12:00:00+00:00', 60.0, 0]],
|
||||
measures)
|
||||
|
||||
def test_get_aggregated_measures_across_entities_no_match(self):
|
||||
result = self.app.post_json(
|
||||
"/v1/aggregation/resource/"
|
||||
+ self.resource_type + "/metric/foo?aggregation=min",
|
||||
params={"and":
|
||||
[{"=": {"server_group": "notexistentyet"}},
|
||||
{"=": {"display_name": "myinstance"}}]},
|
||||
params={"=": {"name": "none!"}},
|
||||
expect_errors=True)
|
||||
|
||||
if self.resource_type == 'instance':
|
||||
self.assertEqual(200, result.status_code)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([], measures)
|
||||
else:
|
||||
self.assertEqual(400, result.status_code)
|
||||
self.assertEqual(200, result.status_code)
|
||||
measures = json.loads(result.text)
|
||||
self.assertEqual([], measures)
|
||||
|
||||
def test_get_aggregated_measures_across_entities(self):
|
||||
result = self.app.post_json("/v1/metric",
|
||||
@ -1965,6 +1742,27 @@ class ResourceTest(RestTest):
|
||||
[u'2013-01-01T12:00:00+00:00', 60.0, 7.0]],
|
||||
measures)
|
||||
|
||||
def test_search_resources_with_like(self):
|
||||
result = self.app.post_json(
|
||||
"/v1/resource/" + self.resource_type,
|
||||
params=self.attributes)
|
||||
created_resource = json.loads(result.text)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/search/resource/" + self.resource_type,
|
||||
params={"like": {"name": "my%"}},
|
||||
status=200)
|
||||
|
||||
resources = json.loads(result.text)
|
||||
self.assertIn(created_resource, resources)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/search/resource/" + self.resource_type,
|
||||
params={"like": {"name": str(uuid.uuid4())}},
|
||||
status=200)
|
||||
resources = json.loads(result.text)
|
||||
self.assertEqual([], resources)
|
||||
|
||||
|
||||
class GenericResourceTest(RestTest):
|
||||
def test_list_resources_tied_to_user(self):
|
||||
@ -2015,35 +1813,3 @@ class GenericResourceTest(RestTest):
|
||||
"Invalid input: extra keys not allowed @ data["
|
||||
+ repr(u'wrongoperator') + "]",
|
||||
result.text)
|
||||
|
||||
def test_search_resources_with_like(self):
|
||||
attributes = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"started_at": "2014-01-03T02:02:02.000000",
|
||||
"host": "computenode42",
|
||||
"image_ref": "imageref!",
|
||||
"flavor_id": "123",
|
||||
"display_name": "myinstance",
|
||||
}
|
||||
result = self.app.post_json(
|
||||
"/v1/resource/instance",
|
||||
params=attributes)
|
||||
created_resource = json.loads(result.text)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/search/resource/instance",
|
||||
params={"like": {"host": "computenode%"}},
|
||||
status=200)
|
||||
|
||||
resources = json.loads(result.text)
|
||||
self.assertIn(created_resource, resources)
|
||||
|
||||
result = self.app.post_json(
|
||||
"/v1/search/resource/instance",
|
||||
params={"like": {"host": str(uuid.uuid4())}},
|
||||
status=200)
|
||||
resources = json.loads(result.text)
|
||||
self.assertEqual([], resources)
|
||||
|
||||
|
||||
ResourceTest.generate_scenarios()
|
||||
|
Loading…
Reference in New Issue
Block a user