196 lines
8.0 KiB
Python
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())
|