congress/congress/tests/dse2/test_datasource.py

196 lines
8.0 KiB
Python

# Copyright (c) 2014 OpenStack Foundation
#
# 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 __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import mock
from oslo_db import exception as db_exc
from congress.db import datasources as datasource_db
from congress.dse2 import dse_node
from congress import exception as congressException
from congress.tests.api import base as api_base
from congress.tests import base
from congress.tests import fake_datasource
class TestDataSource(base.SqlTestCase):
def setUp(self):
super(TestDataSource, self).setUp()
config = api_base.setup_config(with_fake_datasource=False, api=False,
policy=False)
self.dseNode = config['node']
self.ds_manager = config['ds_manager']
def _get_datasource_request(self):
# leave ID out--generated during creation
return {'name': 'aaron',
'driver': 'fake_datasource',
'description': 'hello world!',
'enabled': True,
'type': None,
'config': {'auth_url': 'foo',
'username': 'armax',
'password': 'password',
'tenant_name': 'armax'}}
def test_add_datasource(self):
req = self._get_datasource_request()
result = self.ds_manager.add_datasource(req)
# test equality of return value except for 'id' field
del(result['id'])
self.assertEqual(req, result)
# check that service actually on dseNode
services = self.dseNode.get_services()
self.assertEqual(len(services), 1)
self.assertEqual(services[0].service_id, req['name'])
self.assertIsInstance(services[0],
fake_datasource.FakeDataSource)
obj = self.dseNode.invoke_service_rpc(
req['name'], 'get_status', {'source_id': None, 'params': None})
self.assertIsNotNone(obj)
@mock.patch.object(datasource_db, 'add_datasource')
def test_add_datasource_db_error(self, add_ds):
add_ds.side_effect = db_exc.DBError('Error in db.')
req = self._get_datasource_request()
self.assertRaises(congressException.DatasourceCreationError,
self.ds_manager.add_datasource, req)
@mock.patch.object(dse_node.DseNode, 'register_service')
def test_add_datasource_synchronizer_error(self, register_ds):
register_ds.side_effect = Exception('Error in registering service')
req = self._get_datasource_request()
self.assertRaises(congressException.DatasourceCreationError,
self.ds_manager.add_datasource, req)
ds = datasource_db.get_datasource_by_name(req['name'])
self.assertIsNone(ds)
def test_get_datasource(self):
req = self._get_datasource_request()
ds = self.ds_manager.add_datasource(req)
result = self.dseNode.get_datasource(ds['id'])
# test equality except for 'id' field
del(result['id'])
self.assertEqual(req, result)
def test_get_datasources(self):
req = self._get_datasource_request()
self.ds_manager.add_datasource(req)
result = self.dseNode.get_datasources()
self.assertEqual(len(result), 1)
result = result[0]
# test equality except for 'id' field
del(result['id'])
self.assertEqual(req, result)
def test_get_datasources2(self):
req1 = self._get_datasource_request()
req1['name'] = 'datasource1'
result1 = self.ds_manager.add_datasource(req1)
req2 = self._get_datasource_request()
req2['name'] = 'datasource2'
result2 = self.ds_manager.add_datasource(req2)
# check results of add_datasource
for key, value in req1.items():
self.assertEqual(value, result1[key])
for key, value in req2.items():
self.assertEqual(value, result2[key])
# check services actually on dseNode
services = self.dseNode.get_services()
self.assertEqual(len(services), 2)
self.assertEqual(set([s.service_id for s in services]),
set(['datasource1', 'datasource2']))
self.assertIsInstance(services[0],
fake_datasource.FakeDataSource)
self.assertIsInstance(services[1],
fake_datasource.FakeDataSource)
# check results of get_datasources
resultall = self.dseNode.get_datasources()
self.assertEqual(len(resultall), 2)
# check equality except for 'id' field
byname = {x['name']: x for x in resultall}
for x in byname.values():
del(x['id'])
self.assertEqual(byname, {'datasource1': req1, 'datasource2': req2})
def test_get_datasources_hide_secret(self):
req = self._get_datasource_request()
self.ds_manager.add_datasource(req)
result = self.dseNode.get_datasources(filter_secret=True)
result = result[0]
# check equality except that 'config'/'password' is hidden
req['config']['password'] = "<hidden>"
del(result['id'])
self.assertEqual(result, req)
def test_create_datasource_duplicate_name(self):
req = self._get_datasource_request()
self.ds_manager.add_datasource(req)
self.assertRaises(congressException.DatasourceNameInUse,
self.ds_manager.add_datasource, req)
def test_delete_datasource(self):
req = self._get_datasource_request()
result = self.ds_manager.add_datasource(req)
self.ds_manager.delete_datasource(result)
# check that service is actually deleted
services = self.dseNode.get_services()
self.assertEqual(len(services), 0)
self.assertRaises(
congressException.NotFound, self.dseNode.invoke_service_rpc,
req['name'], 'get_status', {'source_id': None, 'params': None})
# TODO(thinrichs): test that we've actually removed
# the row from the DB
# TODO(dse2): this test relies on coordination between dseNode and
# policy engine. Much harder in distributed system. Need to decide
# if we want that kind of invariant and if so implement it.
# def test_delete_datasource_error(self):
# req = self._get_datasource_request()
# req['driver'] = 'fake_datasource'
# req['config'] = {'auth_url': 'foo',
# 'username': 'armax',
# 'password': 'password',
# 'tenant_name': 'armax'}
# # let driver generate this for us.
# del req['id']
# result = self.datasource_mgr.add_datasource(req)
# engine = self.dseNode.service_object('engine')
# engine.create_policy('alice')
# engine.insert('p(x) :- %s:q(x)' % req['name'], 'alice')
# self.assertRaises(exception.DanglingReference,
# self.datasource_mgr.delete_datasource,
# result['id'])
def test_delete_invalid_datasource(self):
req = self._get_datasource_request()
req['id'] = 'fake-id'
self.assertRaises(congressException.DatasourceNotFound,
self.ds_manager.delete_datasource, req)
# TODO(dse2): Doesn't seem like we need this (or it will be moved to API).
# def test_get_driver_schema(self):
# schema = self.datasource_mgr.get_driver_schema(
# 'fake_datasource')
# self.assertEqual(
# schema,
# fake_datasource.FakeDataSource.get_schema())