451 lines
20 KiB
Python
451 lines
20 KiB
Python
# Copyright 2014
|
|
# The Cloudscaling Group, Inc.
|
|
#
|
|
# 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 sqlalchemy.orm import exc as orm_exception
|
|
|
|
from ec2api.api import validator
|
|
from ec2api.db import api as db_api
|
|
from ec2api import exception
|
|
from ec2api.tests.unit import base
|
|
from ec2api.tests.unit import fakes
|
|
from ec2api.tests.unit import matchers
|
|
|
|
|
|
class DbApiTestCase(base.DbTestCase):
|
|
|
|
def setUp(self):
|
|
super(DbApiTestCase, self).setUp()
|
|
self.context = mock.NonCallableMock(
|
|
project_id=fakes.random_os_id())
|
|
self.other_context = mock.NonCallableMock(
|
|
project_id=fakes.random_os_id())
|
|
|
|
def test_add_item(self):
|
|
new_item = {'os_id': fakes.random_os_id(),
|
|
'vpc_id': fakes.random_ec2_id('fake_vpc'),
|
|
'str_attr': 'fake_str',
|
|
'int_attr': 1234,
|
|
'bool_attr': True,
|
|
'dict_attr': {'key1': 'val1',
|
|
'key2': 'val2'},
|
|
'list_attr': ['fake_str', 1234, True, {'key': 'val'}, []]}
|
|
item = db_api.add_item(self.context, 'fake', new_item)
|
|
self.assertIn('id', item)
|
|
self.assertIsNotNone(item['id'])
|
|
item_id = item.pop('id')
|
|
self.assertTrue(validator.validate_ec2_id(item_id, '', ['fake']))
|
|
self.assertThat(item, matchers.DictMatches(new_item,
|
|
orderless_lists=True))
|
|
|
|
item = db_api.get_item_by_id(self.context, item_id)
|
|
new_item['id'] = item_id
|
|
self.assertThat(item, matchers.DictMatches(new_item,
|
|
orderless_lists=True))
|
|
|
|
def test_add_item_defaults(self):
|
|
def do_check(new_item):
|
|
item = db_api.add_item(self.context, 'fake', new_item)
|
|
item_id = item.pop('id')
|
|
if 'id' in new_item:
|
|
new_item_id = new_item.pop('id')
|
|
self.assertNotEqual(new_item_id, item_id)
|
|
new_item.setdefault('os_id', None)
|
|
new_item.setdefault('vpc_id', None)
|
|
self.assertThat(item, matchers.DictMatches(new_item,
|
|
orderless_lists=True))
|
|
|
|
do_check({})
|
|
do_check({'os_id': fakes.random_os_id()})
|
|
do_check({'vpc_id': fakes.random_ec2_id('fake_vpc')})
|
|
do_check({'id': fakes.random_ec2_id('fake')})
|
|
|
|
def test_add_item_with_same_os_id(self):
|
|
# NOTE(ft): check normal update item on add
|
|
os_id = fakes.random_os_id()
|
|
item1 = db_api.add_item(self.context, 'fake',
|
|
{'os_id': os_id,
|
|
'key': 'val1',
|
|
'key1': 'val'})
|
|
item_id = item1['id']
|
|
item2 = db_api.add_item(self.context, 'fake',
|
|
{'os_id': os_id,
|
|
'key': 'val2',
|
|
'key2': 'val'})
|
|
expected_item = {'id': item_id,
|
|
'os_id': os_id,
|
|
'vpc_id': None,
|
|
'key': 'val2',
|
|
'key1': 'val',
|
|
'key2': 'val'}
|
|
self.assertThat(item2, matchers.DictMatches(expected_item))
|
|
|
|
def test_add_item_isolation(self):
|
|
os_id = fakes.random_os_id()
|
|
db_api.add_item(self.context, 'fake', {'os_id': os_id})
|
|
self.assertRaises(
|
|
orm_exception.NoResultFound,
|
|
db_api.add_item, self.context, 'fake1', {'os_id': os_id})
|
|
self.assertRaises(
|
|
orm_exception.NoResultFound,
|
|
db_api.add_item, self.other_context, 'fake', {'os_id': os_id})
|
|
|
|
def test_add_item_id(self):
|
|
os_id = fakes.random_os_id()
|
|
item_id = db_api.add_item_id(self.context, 'fake', os_id)
|
|
self.assertTrue(validator.validate_ec2_id(item_id, '', ['fake']))
|
|
item = db_api.get_item_by_id(self.context, item_id)
|
|
self.assertIsNone(item)
|
|
item = db_api.add_item(self.context, 'fake', {'os_id': os_id})
|
|
self.assertThat(item, matchers.DictMatches({'id': item_id,
|
|
'os_id': os_id,
|
|
'vpc_id': None}))
|
|
# NOTE(ft): add os_id when item exists
|
|
item_id = db_api.add_item_id(self.context, 'fake', os_id)
|
|
self.assertEqual(item_id, item['id'])
|
|
|
|
# NOTE(ft): add os_id when id exists
|
|
os_id = fakes.random_os_id()
|
|
item_id1 = db_api.add_item_id(self.context, 'fake', os_id)
|
|
item_id2 = db_api.add_item_id(self.context, 'fake', os_id)
|
|
self.assertEqual(item_id1, item_id2)
|
|
|
|
def test_update_item(self):
|
|
item = db_api.add_item(self.context, 'fake', {'key': 'val1',
|
|
'key1': 'val'})
|
|
item['key'] = 'val2'
|
|
item.pop('key1')
|
|
item['key2'] = 'val'
|
|
item_id = item['id']
|
|
db_api.update_item(self.context, item)
|
|
item = db_api.get_item_by_id(self.context, item_id)
|
|
self.assertThat(item, matchers.DictMatches({'id': item_id,
|
|
'os_id': None,
|
|
'vpc_id': None,
|
|
'key': 'val2',
|
|
'key2': 'val'}))
|
|
|
|
def test_update_item_invalid(self):
|
|
self.assertRaises(orm_exception.NoResultFound,
|
|
db_api.update_item,
|
|
self.context,
|
|
{'id': fakes.random_ec2_id('fake'),
|
|
'key': 'val'})
|
|
|
|
def test_update_item_os_id(self):
|
|
item = db_api.add_item(self.context, 'fake', {})
|
|
item['os_id'] = 'fake_os_id'
|
|
db_api.update_item(self.context, item)
|
|
item = db_api.get_item_by_id(self.context, item['id'])
|
|
self.assertThat({'os_id': 'fake_os_id'},
|
|
matchers.IsSubDictOf(item))
|
|
item['os_id'] = 'other_fake_os_id'
|
|
self.assertRaises(exception.EC2DBInvalidOsIdUpdate,
|
|
db_api.update_item,
|
|
self.context, item)
|
|
item['os_id'] = None
|
|
self.assertRaises(exception.EC2DBInvalidOsIdUpdate,
|
|
db_api.update_item,
|
|
self.context, item)
|
|
|
|
def test_delete_item(self):
|
|
item = db_api.add_item(self.context, 'fake', {})
|
|
db_api.delete_item(self.context, item['id'])
|
|
item = db_api.get_item_by_id(self.context, item['id'])
|
|
self.assertIsNone(item)
|
|
|
|
# NOTE(ft): delete not existing item should pass quitely
|
|
db_api.delete_item(self.context, fakes.random_ec2_id('fake'))
|
|
|
|
item = db_api.add_item(self.context, 'fake', {})
|
|
db_api.delete_item(self.other_context, item['id'])
|
|
item = db_api.get_item_by_id(self.context, item['id'])
|
|
self.assertIsNotNone(item)
|
|
|
|
def _setup_items(self):
|
|
db_api.add_item(self.context, 'fake', {})
|
|
db_api.add_item(self.context, 'fake', {'is_public': True})
|
|
db_api.add_item(self.context, 'fake1', {'os_id': fakes.random_os_id()})
|
|
db_api.add_item(self.other_context, 'fake', {})
|
|
db_api.add_item(self.other_context, 'fake', {'is_public': False})
|
|
db_api.add_item(self.other_context, 'fake', {'is_public': True})
|
|
db_api.add_item(self.other_context, 'fake1',
|
|
{'is_public': False,
|
|
'os_id': fakes.random_os_id()})
|
|
|
|
def test_get_items(self):
|
|
self._setup_items()
|
|
|
|
items = db_api.get_items(self.context, 'fake')
|
|
self.assertEqual(2, len(items))
|
|
items = db_api.get_items(self.context, 'fake0')
|
|
self.assertEqual(0, len(items))
|
|
|
|
def test_get_item_by_id(self):
|
|
self._setup_items()
|
|
item_id = db_api.get_items(self.context, 'fake')[0]['id']
|
|
other_item_id = db_api.get_items(self.other_context, 'fake')[0]['id']
|
|
|
|
item = db_api.get_item_by_id(self.context, item_id)
|
|
self.assertThat(item, matchers.DictMatches({'id': item_id,
|
|
'os_id': None,
|
|
'vpc_id': None}))
|
|
item = db_api.get_item_by_id(self.context, other_item_id)
|
|
self.assertIsNone(item)
|
|
item = db_api.get_item_by_id(self.context, fakes.random_ec2_id('fake'))
|
|
self.assertIsNone(item)
|
|
|
|
def test_get_items_by_ids(self):
|
|
self._setup_items()
|
|
fake_kind_items = db_api.get_items(self.context, 'fake')
|
|
fake1_kind_items = db_api.get_items(self.context, 'fake1')
|
|
item_id = fake_kind_items[0]['id']
|
|
other_item_id = db_api.get_items(self.other_context, 'fake')[0]['id']
|
|
|
|
items = db_api.get_items_by_ids(self.context, [])
|
|
self.assertEqual(0, len(items))
|
|
items = db_api.get_items_by_ids(self.context, set([]))
|
|
self.assertEqual(0, len(items))
|
|
items = db_api.get_items_by_ids(self.context,
|
|
[i['id'] for i in fake_kind_items])
|
|
self.assertEqual(2, len(items))
|
|
items = db_api.get_items_by_ids(
|
|
self.context, (fake_kind_items[0]['id'],
|
|
fake1_kind_items[0]['id']))
|
|
self.assertEqual(2, len(items))
|
|
items = db_api.get_items_by_ids(self.context, (item_id,))
|
|
self.assertEqual(1, len(items))
|
|
self.assertEqual(item_id, items[0]['id'])
|
|
items = db_api.get_items_by_ids(self.context, (other_item_id,))
|
|
self.assertEqual(0, len(items))
|
|
items = db_api.get_items_by_ids(self.context,
|
|
(item_id, other_item_id))
|
|
self.assertEqual(1, len(items))
|
|
items = db_api.get_items_by_ids(self.context,
|
|
(fakes.random_ec2_id('fake')),)
|
|
self.assertEqual(0, len(items))
|
|
items = db_api.get_items_by_ids(self.context,
|
|
(item_id, fakes.random_ec2_id('fake')))
|
|
self.assertEqual(1, len(items))
|
|
|
|
def test_get_items_ids(self):
|
|
self._setup_items()
|
|
item = db_api.get_items(self.context, 'fake1')[0]
|
|
other_item = db_api.get_items(self.other_context, 'fake1')[0]
|
|
items_ids = db_api.get_items_ids(self.context, 'fake1',
|
|
item_os_ids=[item['os_id'],
|
|
other_item['os_id']])
|
|
self.assertThat(items_ids,
|
|
matchers.ListMatches(
|
|
[(item['id'], item['os_id']),
|
|
(other_item['id'], other_item['os_id'])],
|
|
orderless_lists=True))
|
|
items_ids = db_api.get_items_ids(self.context, 'fake',
|
|
item_os_ids=[item['os_id']])
|
|
self.assertEqual(0, len(items_ids))
|
|
|
|
item_ids = db_api.get_items_ids(self.context, 'fake1',
|
|
item_ids=[item['id'],
|
|
other_item['id']])
|
|
self.assertThat(item_ids,
|
|
matchers.ListMatches(
|
|
[(item['id'], item['os_id']),
|
|
(other_item['id'], other_item['os_id'])],
|
|
orderless_lists=True))
|
|
items_ids = db_api.get_items_ids(self.context, 'fake',
|
|
item_ids=[item['id']])
|
|
self.assertEqual(0, len(items_ids))
|
|
|
|
def test_get_public_items(self):
|
|
self._setup_items()
|
|
items = db_api.get_public_items(self.context, 'fake')
|
|
self.assertEqual(2, len(items))
|
|
public_item_ids = [i['id'] for i in items]
|
|
|
|
items = db_api.get_public_items(self.context, 'fake', public_item_ids)
|
|
self.assertEqual(2, len(items))
|
|
items = db_api.get_public_items(self.context, 'fake',
|
|
[public_item_ids[0]])
|
|
self.assertEqual(1, len(items))
|
|
items = db_api.get_public_items(self.context, 'fake',
|
|
(public_item_ids[1],))
|
|
self.assertEqual(1, len(items))
|
|
items = db_api.get_public_items(self.context, 'fake1',
|
|
[public_item_ids[0]])
|
|
self.assertEqual(0, len(items))
|
|
items = db_api.get_public_items(self.context, 'fake',
|
|
fakes.random_ec2_id('fake'))
|
|
self.assertEqual(0, len(items))
|
|
items = db_api.get_public_items(self.context, 'fake0', [])
|
|
self.assertEqual(0, len(items))
|
|
|
|
def test_add_tags(self):
|
|
item1_id = fakes.random_ec2_id('fake')
|
|
item2_id = fakes.random_ec2_id('fake')
|
|
item3_id = fakes.random_ec2_id('fake')
|
|
tag1_01 = {'item_id': item1_id,
|
|
'key': 'key1',
|
|
'value': None}
|
|
tag1_1 = {'item_id': item1_id,
|
|
'key': 'key1',
|
|
'value': 'val'}
|
|
tag1_2 = {'item_id': item1_id,
|
|
'key': 'key2',
|
|
'value': 'val'}
|
|
tag1_3 = {'item_id': item1_id,
|
|
'key': 'key3',
|
|
'value': 'val'}
|
|
tag2_1 = {'item_id': item2_id,
|
|
'key': 'key1',
|
|
'value': None}
|
|
tag2_2 = {'item_id': item2_id,
|
|
'key': 'key2',
|
|
'value': 'val'}
|
|
tag3_1 = {'item_id': item3_id,
|
|
'key': 'key1',
|
|
'value': 'val'}
|
|
tag3_3 = {'item_id': item3_id,
|
|
'key': 'key3',
|
|
'value': 'val'}
|
|
db_api.add_tags(self.context, [tag1_01, tag2_1,
|
|
tag1_2, tag2_2])
|
|
db_api.add_tags(self.context, [tag1_1, tag3_1,
|
|
tag1_3, tag3_3])
|
|
tags = db_api.get_tags(self.context)
|
|
self.assertThat(tags,
|
|
matchers.ListMatches([tag1_1, tag1_2, tag1_3,
|
|
tag2_1, tag2_2,
|
|
tag3_1, tag3_3],
|
|
orderless_lists=True))
|
|
|
|
def test_add_tags_isolation(self):
|
|
item_id = fakes.random_ec2_id('fake')
|
|
tag1 = {'item_id': item_id,
|
|
'key': 'key1',
|
|
'value': 'val1'}
|
|
tag2 = {'item_id': item_id,
|
|
'key': 'key2',
|
|
'value': 'val2'}
|
|
db_api.add_tags(self.context, [tag1, tag2])
|
|
db_api.add_tags(self.other_context, [{'item_id': item_id,
|
|
'key': 'key1',
|
|
'value': 'val1_1'},
|
|
{'item_id': item_id,
|
|
'key': 'key3',
|
|
'value': 'val3'}])
|
|
tags = db_api.get_tags(self.context)
|
|
self.assertThat(tags, matchers.ListMatches([tag1, tag2],
|
|
orderless_lists=True))
|
|
|
|
def test_get_tags(self):
|
|
item1_id = fakes.random_ec2_id('fake')
|
|
item2_id = fakes.random_ec2_id('fake')
|
|
item3_id = fakes.random_ec2_id('fake1')
|
|
tag1 = {'item_id': item1_id,
|
|
'key': 'key1',
|
|
'value': 'val1'}
|
|
tag2 = {'item_id': item2_id,
|
|
'key': 'key2',
|
|
'value': 'val2'}
|
|
tag3 = {'item_id': item3_id,
|
|
'key': 'key3',
|
|
'value': 'val3'}
|
|
db_api.add_tags(self.context, [tag1, tag2, tag3])
|
|
|
|
self.assertThat(db_api.get_tags(self.context),
|
|
matchers.ListMatches([tag1, tag2, tag3],
|
|
orderless_lists=True))
|
|
self.assertThat(db_api.get_tags(self.context, ('fake',)),
|
|
matchers.ListMatches([tag1, tag2],
|
|
orderless_lists=True))
|
|
self.assertThat(db_api.get_tags(self.context, ('fake',),
|
|
[item1_id, item2_id]),
|
|
matchers.ListMatches([tag1, tag2],
|
|
orderless_lists=True))
|
|
self.assertThat(db_api.get_tags(self.context, ('fake',), (item1_id,)),
|
|
matchers.ListMatches([tag1],
|
|
orderless_lists=True))
|
|
self.assertThat(db_api.get_tags(self.context, ('fake',), (item3_id,)),
|
|
matchers.ListMatches([]))
|
|
self.assertThat(db_api.get_tags(self.context,
|
|
item_ids=(item1_id, item3_id)),
|
|
matchers.ListMatches([tag1, tag3],
|
|
orderless_lists=True))
|
|
self.assertThat(db_api.get_tags(self.context, ('fake', 'fake1'),
|
|
(item2_id, item3_id)),
|
|
matchers.ListMatches([tag2, tag3],
|
|
orderless_lists=True))
|
|
|
|
def test_delete_tags(self):
|
|
item1_id = fakes.random_ec2_id('fake')
|
|
item2_id = fakes.random_ec2_id('fake')
|
|
item3_id = fakes.random_ec2_id('fake1')
|
|
tag1_1 = {'item_id': item1_id,
|
|
'key': 'key1',
|
|
'value': 'val_a'}
|
|
tag1_2 = {'item_id': item1_id,
|
|
'key': 'key2',
|
|
'value': 'val_b'}
|
|
tag2_1 = {'item_id': item2_id,
|
|
'key': 'key1',
|
|
'value': 'val_c'}
|
|
tag2_2 = {'item_id': item2_id,
|
|
'key': 'key2',
|
|
'value': 'val_a'}
|
|
tag3_1 = {'item_id': item3_id,
|
|
'key': 'key1',
|
|
'value': 'val_b'}
|
|
tag3_2 = {'item_id': item3_id,
|
|
'key': 'key2',
|
|
'value': 'val_d'}
|
|
db_api.add_tags(self.context, [tag1_1, tag2_1, tag3_1,
|
|
tag1_2, tag2_2, tag3_2])
|
|
|
|
def do_check(*tag_list):
|
|
self.assertThat(db_api.get_tags(self.context),
|
|
matchers.ListMatches(tag_list,
|
|
orderless_lists=True))
|
|
db_api.add_tags(self.context, [tag1_1, tag2_1, tag3_1,
|
|
tag1_2, tag2_2, tag3_2])
|
|
|
|
db_api.delete_tags(self.context, [])
|
|
do_check(tag1_1, tag1_2, tag2_1, tag2_2, tag3_1, tag3_2)
|
|
|
|
db_api.delete_tags(self.context, [item1_id])
|
|
do_check(tag2_1, tag2_2, tag3_1, tag3_2)
|
|
|
|
db_api.delete_tags(self.context, [item1_id, item3_id])
|
|
do_check(tag2_1, tag2_2)
|
|
|
|
db_api.delete_tags(self.context, [item1_id, item2_id, item3_id],
|
|
[{'key': 'key1'},
|
|
{'value': 'val_d'},
|
|
{'key': 'key2',
|
|
'value': 'val_b'}])
|
|
do_check(tag2_2)
|
|
|
|
def test_delete_tags_isolation(self):
|
|
item_id = fakes.random_ec2_id('fake')
|
|
tag1 = {'item_id': item_id,
|
|
'key': 'key',
|
|
'value': 'val1'}
|
|
db_api.add_tags(self.context, [tag1])
|
|
tag2 = {'item_id': item_id,
|
|
'key': 'key',
|
|
'value': 'val2'}
|
|
db_api.add_tags(self.other_context, [tag2])
|
|
db_api.delete_tags(self.context, item_id)
|
|
self.assertThat(db_api.get_tags(self.other_context),
|
|
matchers.ListMatches([tag2]))
|