congress/congress/tests/api/test_datasource_model.py
Anusha Ramineni 1d3f4bfb50 Refactor datasource synchronizer
This commit adds the following :
1. Move datasource_synchronizer to seperate class
2. Moved add_datasource and delete_datasource to DSManagerService class
TODO(ramineni): move other datasource management related operations to
   DSManagerService class
3. Add support to sync single datasource
4. synchronizer to be started as part of DSManagerService to avoid running
synchronizer on non-datasource node.

Partially-Implements blueprint refactor-synchronizer
Change-Id: I643a0c299695a794469553cc5fb73e8d1bceec7d
2017-01-16 12:13:06 +05:30

199 lines
7.9 KiB
Python

# Copyright (c) 2015 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_config import cfg
from six.moves import reduce
from congress.api import webservice
from congress.datasources import nova_driver
from congress import exception
from congress.tests.api import base as api_base
from congress.tests import base
from congress.tests import helper
class TestDatasourceModel(base.SqlTestCase):
def setUp(self):
super(TestDatasourceModel, self).setUp()
services = api_base.setup_config(with_fake_datasource=False)
self.datasource_model = services['api']['api-datasource']
self.data = services['data']
self.node = services['node']
self.engine = services['engine']
self.ds_manager = services['ds_manager']
self.datasource = self._get_datasource_request()
self.ds_manager.add_datasource(self.datasource)
def tearDown(self):
super(TestDatasourceModel, self).tearDown()
self.node.stop()
def _get_datasource_request(self):
# leave ID out--generated during creation
return {'name': 'datasource1',
'driver': 'fake_datasource',
'description': 'hello world!',
'enabled': True,
'type': None,
'config': {'auth_url': 'foo',
'username': 'armax',
'password': '<hidden>',
'tenant_name': 'armax'}}
def test_get_items(self):
dinfo = self.datasource_model.get_items(None)['results']
self.assertEqual(1, len(dinfo))
datasource2 = self._get_datasource_request()
datasource2['name'] = 'datasource2'
self.ds_manager.add_datasource(datasource2)
dinfo = self.datasource_model.get_items(None)['results']
self.assertEqual(2, len(dinfo))
del dinfo[0]['id']
self.assertEqual(self.datasource, dinfo[0])
def test_add_item(self):
datasource3 = self._get_datasource_request()
datasource3['name'] = 'datasource_test_3'
self.datasource_model.add_item(datasource3, {})
ds_obj = self.node.service_object('datasource_test_3')
obj = self.engine.policy_object('datasource_test_3')
self.assertIsNotNone(obj.schema)
self.assertEqual('datasource_test_3', obj.name)
self.assertIsNotNone(ds_obj)
def test_add_item_duplicate(self):
self.assertRaises(webservice.DataModelException,
self.datasource_model.add_item,
self.datasource, {})
def test_add_item_invalid_tablename(self):
datasource = self._get_datasource_request()
datasource['name'] = "invalid-table-name"
self.assertRaises(webservice.DataModelException,
self.datasource_model.add_item,
datasource, {})
def test_delete_item(self):
datasource = self._get_datasource_request()
datasource['name'] = 'test_datasource'
d_id, dinfo = self.datasource_model.add_item(datasource, {})
self.assertTrue(self.engine.assert_policy_exists('test_datasource'))
context = {'ds_id': d_id}
self.datasource_model.delete_item(None, {}, context=context)
ds_obj = self.node.service_object('test_datasource')
self.assertIsNone(ds_obj)
self.assertRaises(exception.PolicyRuntimeException,
self.engine.assert_policy_exists, 'test_datasource')
self.assertRaises(exception.DatasourceNotFound,
self.node.get_datasource, d_id)
def test_delete_item_invalid_datasource(self):
context = {'ds_id': 'fake'}
self.assertRaises(webservice.DataModelException,
self.datasource_model.delete_item,
None, {}, context=context)
def test_datasource_api_model_execute(self):
def _execute_api(client, action, action_args):
positional_args = action_args.get('positional', [])
named_args = action_args.get('named', {})
method = reduce(getattr, action.split('.'), client)
method(*positional_args, **named_args)
class NovaClient(object):
def __init__(self, testkey):
self.testkey = testkey
def _get_testkey(self):
return self.testkey
def disconnect(self, arg1, arg2, arg3):
self.testkey = "arg1=%s arg2=%s arg3=%s" % (arg1, arg2, arg3)
def disconnect_all(self):
self.testkey = "action_has_no_args"
nova_client = NovaClient("testing")
args = helper.datasource_openstack_args()
nova = nova_driver.NovaDriver('nova', args=args)
nova.nova_client = nova_client
nova.update_from_datasource = mock.MagicMock()
nova._execute_api = _execute_api
self.node.register_service(nova)
execute_action = self.datasource_model.execute_action
# Positive test: valid body args, ds_id
context = {'ds_id': 'nova'}
body = {'name': 'disconnect',
'args': {'positional': ['value1', 'value2'],
'named': {'arg3': 'value3'}}}
request = helper.FakeRequest(body)
result = execute_action({}, context, request)
self.assertEqual(result, {})
expected_result = "arg1=value1 arg2=value2 arg3=value3"
f = nova.nova_client._get_testkey
helper.retry_check_function_return_value(f, expected_result)
# Positive test: no body args
context = {'ds_id': 'nova'}
body = {'name': 'disconnect_all'}
request = helper.FakeRequest(body)
result = execute_action({}, context, request)
self.assertEqual(result, {})
expected_result = "action_has_no_args"
f = nova.nova_client._get_testkey
helper.retry_check_function_return_value(f, expected_result)
# Negative test: invalid ds_id
context = {'ds_id': 'unknown_ds'}
self.assertRaises(webservice.DataModelException, execute_action,
{}, context, request)
# Negative test: no ds_id
context = {}
self.assertRaises(webservice.DataModelException, execute_action,
{}, context, request)
# Negative test: empty body
context = {'ds_id': 'nova'}
bad_request = helper.FakeRequest({})
self.assertRaises(webservice.DataModelException, execute_action,
{}, context, bad_request)
# Negative test: no body name/action
context = {'ds_id': 'nova'}
body = {'args': {'positional': ['value1', 'value2'],
'named': {'arg3': 'value3'}}}
bad_request = helper.FakeRequest(body)
self.assertRaises(webservice.DataModelException, execute_action,
{}, context, bad_request)
# Positive test with retry: no body args
cfg.CONF.dse.execute_action_retry = True
context = {'ds_id': 'nova'}
body = {'name': 'disconnect_all'}
request = helper.FakeRequest(body)
result = execute_action({}, context, request)
self.assertEqual(result, {})
expected_result = "action_has_no_args"
f = nova.nova_client._get_testkey
helper.retry_check_function_return_value(f, expected_result)