summaryrefslogtreecommitdiffstats
path: root/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/db/sqlalchemy/test_sqlalchemy.py57
-rw-r--r--tests/unit/db/test_api.py12
-rw-r--r--tests/unit/plugin/__init__.py14
-rw-r--r--tests/unit/plugin/test_callback_plugin.py92
-rw-r--r--tests/unit/rpc/test_common.py2
-rw-r--r--tests/unit/rpc/test_kombu.py1
-rw-r--r--tests/unit/rpc/test_zmq.py1
-rw-r--r--tests/unit/test_plugin.py118
-rw-r--r--tests/unit/test_rootwrap.py127
9 files changed, 160 insertions, 264 deletions
diff --git a/tests/unit/db/sqlalchemy/test_sqlalchemy.py b/tests/unit/db/sqlalchemy/test_sqlalchemy.py
index 46a0cb2..48d6cf7 100644
--- a/tests/unit/db/sqlalchemy/test_sqlalchemy.py
+++ b/tests/unit/db/sqlalchemy/test_sqlalchemy.py
@@ -52,15 +52,15 @@ sql_max_overflow=50
sql_connection_debug=60
sql_connection_trace=True
""")])
- test_utils.CONF(['--config-file', paths[0]])
- self.assertEquals(test_utils.CONF.database.connection, 'x://y.z')
- self.assertEquals(test_utils.CONF.database.min_pool_size, 10)
- self.assertEquals(test_utils.CONF.database.max_pool_size, 20)
- self.assertEquals(test_utils.CONF.database.max_retries, 30)
- self.assertEquals(test_utils.CONF.database.retry_interval, 40)
- self.assertEquals(test_utils.CONF.database.max_overflow, 50)
- self.assertEquals(test_utils.CONF.database.connection_debug, 60)
- self.assertEquals(test_utils.CONF.database.connection_trace, True)
+ self.conf(['--config-file', paths[0]])
+ self.assertEquals(self.conf.database.connection, 'x://y.z')
+ self.assertEquals(self.conf.database.min_pool_size, 10)
+ self.assertEquals(self.conf.database.max_pool_size, 20)
+ self.assertEquals(self.conf.database.max_retries, 30)
+ self.assertEquals(self.conf.database.retry_interval, 40)
+ self.assertEquals(self.conf.database.max_overflow, 50)
+ self.assertEquals(self.conf.database.connection_debug, 60)
+ self.assertEquals(self.conf.database.connection_trace, True)
def test_session_parameters(self):
paths = self.create_tempfiles([('test', """[database]
@@ -74,16 +74,16 @@ connection_debug=60
connection_trace=True
pool_timeout=7
""")])
- test_utils.CONF(['--config-file', paths[0]])
- self.assertEquals(test_utils.CONF.database.connection, 'x://y.z')
- self.assertEquals(test_utils.CONF.database.min_pool_size, 10)
- self.assertEquals(test_utils.CONF.database.max_pool_size, 20)
- self.assertEquals(test_utils.CONF.database.max_retries, 30)
- self.assertEquals(test_utils.CONF.database.retry_interval, 40)
- self.assertEquals(test_utils.CONF.database.max_overflow, 50)
- self.assertEquals(test_utils.CONF.database.connection_debug, 60)
- self.assertEquals(test_utils.CONF.database.connection_trace, True)
- self.assertEquals(test_utils.CONF.database.pool_timeout, 7)
+ self.conf(['--config-file', paths[0]])
+ self.assertEquals(self.conf.database.connection, 'x://y.z')
+ self.assertEquals(self.conf.database.min_pool_size, 10)
+ self.assertEquals(self.conf.database.max_pool_size, 20)
+ self.assertEquals(self.conf.database.max_retries, 30)
+ self.assertEquals(self.conf.database.retry_interval, 40)
+ self.assertEquals(self.conf.database.max_overflow, 50)
+ self.assertEquals(self.conf.database.connection_debug, 60)
+ self.assertEquals(self.conf.database.connection_trace, True)
+ self.assertEquals(self.conf.database.pool_timeout, 7)
def test_dbapi_database_deprecated_parameters(self):
paths = self.create_tempfiles([('test',
@@ -97,17 +97,16 @@ pool_timeout=7
'sqlalchemy_max_overflow=101\n'
'sqlalchemy_pool_timeout=5\n'
)])
-
- test_utils.CONF(['--config-file', paths[0]])
- self.assertEquals(test_utils.CONF.database.connection,
+ self.conf(['--config-file', paths[0]])
+ self.assertEquals(self.conf.database.connection,
'fake_connection')
- self.assertEquals(test_utils.CONF.database.idle_timeout, 100)
- self.assertEquals(test_utils.CONF.database.min_pool_size, 99)
- self.assertEquals(test_utils.CONF.database.max_pool_size, 199)
- self.assertEquals(test_utils.CONF.database.max_retries, 22)
- self.assertEquals(test_utils.CONF.database.retry_interval, 17)
- self.assertEquals(test_utils.CONF.database.max_overflow, 101)
- self.assertEquals(test_utils.CONF.database.pool_timeout, 5)
+ self.assertEquals(self.conf.database.idle_timeout, 100)
+ self.assertEquals(self.conf.database.min_pool_size, 99)
+ self.assertEquals(self.conf.database.max_pool_size, 199)
+ self.assertEquals(self.conf.database.max_retries, 22)
+ self.assertEquals(self.conf.database.retry_interval, 17)
+ self.assertEquals(self.conf.database.max_overflow, 101)
+ self.assertEquals(self.conf.database.pool_timeout, 5)
class SessionErrorWrapperTestCase(test_base.DbTestCase):
diff --git a/tests/unit/db/test_api.py b/tests/unit/db/test_api.py
index f6e0d4c..2a8db3b 100644
--- a/tests/unit/db/test_api.py
+++ b/tests/unit/db/test_api.py
@@ -40,9 +40,9 @@ class DBAPITestCase(test_utils.BaseTestCase):
'dbapi_use_tpool=True\n'
)])
- test_utils.CONF(['--config-file', paths[0]])
- self.assertEquals(test_utils.CONF.database.backend, 'test_123')
- self.assertEquals(test_utils.CONF.database.use_tpool, True)
+ self.conf(['--config-file', paths[0]])
+ self.assertEquals(self.conf.database.backend, 'test_123')
+ self.assertEquals(self.conf.database.use_tpool, True)
def test_dbapi_parameters(self):
paths = self.create_tempfiles([('test',
@@ -51,9 +51,9 @@ class DBAPITestCase(test_utils.BaseTestCase):
'use_tpool=True\n'
)])
- test_utils.CONF(['--config-file', paths[0]])
- self.assertEquals(test_utils.CONF.database.backend, 'test_123')
- self.assertEquals(test_utils.CONF.database.use_tpool, True)
+ self.conf(['--config-file', paths[0]])
+ self.assertEquals(self.conf.database.backend, 'test_123')
+ self.assertEquals(self.conf.database.use_tpool, True)
def test_dbapi_api_class_method_and_tpool_false(self):
backend_mapping = {'test_known': 'tests.unit.db.test_api'}
diff --git a/tests/unit/plugin/__init__.py b/tests/unit/plugin/__init__.py
deleted file mode 100644
index b706747..0000000
--- a/tests/unit/plugin/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2012 OpenStack Foundation.
-# All Rights Reserved.
-#
-# 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.
diff --git a/tests/unit/plugin/test_callback_plugin.py b/tests/unit/plugin/test_callback_plugin.py
deleted file mode 100644
index 3f3fd63..0000000
--- a/tests/unit/plugin/test_callback_plugin.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright 2012 OpenStack Foundation.
-# All Rights Reserved.
-#
-# 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 pkg_resources
-
-from openstack.common.notifier import api as notifier_api
-from openstack.common.plugin import callbackplugin
-from openstack.common.plugin import pluginmanager
-from tests import utils as test_utils
-
-userdatastring = "magic user data string"
-
-
-class TestCBP(callbackplugin.CallbackPlugin):
-
- def callback1(self, context, message, userdata):
- self.callback1count += 1
-
- def callback2(self, context, message, userdata):
- self.callback2count += 1
-
- def callback3(self, context, message, userdata):
- self.callback3count += 1
- self.userdata = userdata
-
- def __init__(self, service_name):
- super(TestCBP, self).__init__(service_name)
- self.callback1count = 0
- self.callback2count = 0
- self.callback3count = 0
-
- self._add_callback(self.callback1, 'type1', None)
- self._add_callback(self.callback2, 'type1', None)
- self._add_callback(self.callback3, 'type2', 'magic user data string')
-
-
-class CallbackTestCase(test_utils.BaseTestCase):
- """Tests for the callback plugin convenience class."""
-
- def test_callback_plugin_subclass(self):
-
- class MockEntrypoint(pkg_resources.EntryPoint):
- def load(self):
- return TestCBP
-
- def mock_iter_entry_points(_t):
- return [MockEntrypoint("fake", "fake", ["fake"])]
-
- self.stubs.Set(pkg_resources, 'iter_entry_points',
- mock_iter_entry_points)
-
- plugmgr = pluginmanager.PluginManager("testproject", "testservice")
- plugmgr.load_plugins()
- self.assertEqual(len(plugmgr.plugins), 1)
- plugin = plugmgr.plugins[0]
- self.assertEqual(len(plugin.notifiers), 1)
-
- notifier_api.notify('contextarg', 'publisher_id', 'type1',
- notifier_api.WARN, dict(a=3))
-
- self.assertEqual(plugin.callback1count, 1)
- self.assertEqual(plugin.callback2count, 1)
- self.assertEqual(plugin.callback3count, 0)
-
- notifier_api.notify('contextarg', 'publisher_id', 'type2',
- notifier_api.WARN, dict(a=3))
-
- self.assertEqual(plugin.callback1count, 1)
- self.assertEqual(plugin.callback2count, 1)
- self.assertEqual(plugin.callback3count, 1)
- self.assertEqual(plugin.userdata, userdatastring)
-
- plugin._remove_callback(plugin.callback1)
-
- notifier_api.notify('contextarg', 'publisher_id', 'type1',
- notifier_api.WARN, dict(a=3))
-
- self.assertEqual(plugin.callback1count, 1)
- self.assertEqual(plugin.callback2count, 2)
- self.assertEqual(plugin.callback3count, 1)
diff --git a/tests/unit/rpc/test_common.py b/tests/unit/rpc/test_common.py
index c2432f4..6f32005 100644
--- a/tests/unit/rpc/test_common.py
+++ b/tests/unit/rpc/test_common.py
@@ -108,7 +108,7 @@ class RpcCommonTestCase(test_utils.BaseTestCase):
'__unicode__': str_override})
new_ex_type.__module__ = '%s_Remote' % e.__class__.__module__
e.__class__ = new_ex_type
- raise e
+ raise
try:
raise_remote_exception()
diff --git a/tests/unit/rpc/test_kombu.py b/tests/unit/rpc/test_kombu.py
index 2476008..54f8389 100644
--- a/tests/unit/rpc/test_kombu.py
+++ b/tests/unit/rpc/test_kombu.py
@@ -71,6 +71,7 @@ class KombuStubs:
@staticmethod
def setUp(self):
if kombu:
+ self.conf = FLAGS
self.config(fake_rabbit=True)
self.config(rpc_response_timeout=5)
self.rpc = impl_kombu
diff --git a/tests/unit/rpc/test_zmq.py b/tests/unit/rpc/test_zmq.py
index b0f0262..c87a040 100644
--- a/tests/unit/rpc/test_zmq.py
+++ b/tests/unit/rpc/test_zmq.py
@@ -60,6 +60,7 @@ class _RpcZmqBaseTestCase(common.BaseRpcTestCase):
self.reactor = None
self.rpc = impl_zmq
+ self.conf = FLAGS
self.config(rpc_zmq_bind_address='127.0.0.1')
self.config(rpc_zmq_host='127.0.0.1')
self.config(rpc_response_timeout=5)
diff --git a/tests/unit/test_plugin.py b/tests/unit/test_plugin.py
deleted file mode 100644
index fd653d7..0000000
--- a/tests/unit/test_plugin.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright 2012 OpenStack Foundation.
-# All Rights Reserved.
-#
-# 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 pkg_resources
-
-from openstack.common.notifier import api as notifier_api
-from openstack.common.plugin import plugin
-from openstack.common.plugin import pluginmanager
-from tests import utils
-
-
-class SimpleNotifier(object):
- def __init__(self):
- self.message_list = []
-
- def notify(self, context, message):
- self.context = context
- self.message_list.append(message)
-
-
-class ManagerTestCase(utils.BaseTestCase):
- def test_constructs(self):
- manager1 = pluginmanager.PluginManager("testproject", "testservice")
- self.assertNotEqual(manager1, False)
-
-
-class NotifyTestCase(utils.BaseTestCase):
- """Test case for the plugin notification interface."""
-
- def test_add_notifier(self):
- notifier1 = SimpleNotifier()
- notifier2 = SimpleNotifier()
- notifier3 = SimpleNotifier()
-
- testplugin = plugin.Plugin('service')
- testplugin._add_notifier(notifier1)
- testplugin._add_notifier(notifier2)
- self.assertEqual(len(testplugin.notifiers), 2)
-
- testplugin._add_notifier(notifier3)
- self.assertEqual(len(testplugin.notifiers), 3)
-
- def test_notifier_action(self):
- def mock_iter_entry_points(_t):
- return [MockEntrypoint("fake", "fake", ["fake"])]
-
- self.stubs.Set(pkg_resources, 'iter_entry_points',
- mock_iter_entry_points)
-
- plugmgr = pluginmanager.PluginManager("testproject", "testservice")
- plugmgr.load_plugins()
- self.assertEqual(len(plugmgr.plugins), 1)
- self.assertEqual(len(plugmgr.plugins[0].notifiers), 1)
- notifier = plugmgr.plugins[0].notifiers[0]
-
- notifier_api.notify('contextarg', 'publisher_id', 'event_type',
- notifier_api.WARN, dict(a=3))
-
- self.assertEqual(len(notifier.message_list), 1)
-
-
-class StubControllerExtension(object):
- name = 'stubextension'
- alias = 'stubby'
-
-
-class TestPluginClass(plugin.Plugin):
-
- def __init__(self, service_name):
- super(TestPluginClass, self).__init__(service_name)
- self._add_api_extension_descriptor(StubControllerExtension)
- notifier1 = SimpleNotifier()
- self._add_notifier(notifier1)
-
-
-class MockEntrypoint(pkg_resources.EntryPoint):
- def load(self):
- return TestPluginClass
-
-
-class MockExtManager():
- def __init__(self):
- self.descriptors = []
-
- def load_extension(self, descriptor):
- self.descriptors.append(descriptor)
-
-
-class APITestCase(utils.BaseTestCase):
- """Test case for the plugin api extension interface."""
- def test_add_extension(self):
- def mock_load(_s):
- return TestPluginClass()
-
- def mock_iter_entry_points(_t):
- return [MockEntrypoint("fake", "fake", ["fake"])]
-
- self.stubs.Set(pkg_resources, 'iter_entry_points',
- mock_iter_entry_points)
-
- mgr = MockExtManager()
- plugmgr = pluginmanager.PluginManager("testproject", "testservice")
- plugmgr.load_plugins()
- plugmgr.plugin_extension_factory(mgr)
-
- self.assertTrue(StubControllerExtension in mgr.descriptors)
diff --git a/tests/unit/test_rootwrap.py b/tests/unit/test_rootwrap.py
index 0e08b5e..02789ec 100644
--- a/tests/unit/test_rootwrap.py
+++ b/tests/unit/test_rootwrap.py
@@ -61,10 +61,11 @@ class RootwrapTestCase(utils.BaseTestCase):
self.assertRaises(wrapper.NoFilterMatched,
wrapper.match_filter, self.filters, invalid)
- def _test_DnsmasqFilter(self, filter_class, config_file_arg):
+ def _test_EnvFilter_as_DnsMasq(self, config_file_arg):
usercmd = ['env', config_file_arg + '=A', 'NETWORK_ID=foobar',
'dnsmasq', 'foo']
- f = filter_class("/usr/bin/dnsmasq", "root")
+ f = filters.EnvFilter("env", "root", config_file_arg + '=A',
+ 'NETWORK_ID=', "/usr/bin/dnsmasq")
self.assertTrue(f.match(usercmd))
self.assertEqual(f.get_command(usercmd), ['/usr/bin/dnsmasq', 'foo'])
env = f.get_environment(usercmd)
@@ -72,10 +73,68 @@ class RootwrapTestCase(utils.BaseTestCase):
self.assertEqual(env.get('NETWORK_ID'), 'foobar')
def test_DnsmasqFilter(self):
- self._test_DnsmasqFilter(filters.DnsmasqFilter, 'CONFIG_FILE')
+ self._test_EnvFilter_as_DnsMasq('CONFIG_FILE')
def test_DeprecatedDnsmasqFilter(self):
- self._test_DnsmasqFilter(filters.DeprecatedDnsmasqFilter, 'FLAGFILE')
+ self._test_EnvFilter_as_DnsMasq('FLAGFILE')
+
+ def test_EnvFilter(self):
+ envset = ['A=/some/thing', 'B=somethingelse']
+ envcmd = ['env'] + envset
+ realcmd = ['sleep', '10']
+ usercmd = envcmd + realcmd
+
+ f = filters.EnvFilter("env", "root", "A=", "B=ignored", "sleep")
+ # accept with leading env
+ self.assertTrue(f.match(envcmd + ["sleep"]))
+ # accept without leading env
+ self.assertTrue(f.match(envset + ["sleep"]))
+
+ # any other command does not match
+ self.assertFalse(f.match(envcmd + ["sleep2"]))
+ self.assertFalse(f.match(envset + ["sleep2"]))
+
+ # accept any trailing arguments
+ self.assertTrue(f.match(usercmd))
+
+ # require given environment variables to match
+ self.assertFalse(f.match([envcmd, 'C=ELSE']))
+ self.assertFalse(f.match(['env', 'C=xx']))
+ self.assertFalse(f.match(['env', 'A=xx']))
+
+ # require env command to be given
+ # (otherwise CommandFilters should match
+ self.assertFalse(f.match(realcmd))
+ # require command to match
+ self.assertFalse(f.match(envcmd))
+ self.assertFalse(f.match(envcmd[1:]))
+
+ # ensure that the env command is stripped when executing
+ self.assertEqual(f.exec_args(usercmd), realcmd)
+ env = f.get_environment(usercmd)
+ # check that environment variables are set
+ self.assertEqual(env.get('A'), '/some/thing')
+ self.assertEqual(env.get('B'), 'somethingelse')
+ self.assertFalse('sleep' in env.keys())
+
+ def test_EnvFilter_without_leading_env(self):
+ envset = ['A=/some/thing', 'B=somethingelse']
+ envcmd = ['env'] + envset
+ realcmd = ['sleep', '10']
+
+ f = filters.EnvFilter("sleep", "root", "A=", "B=ignored")
+
+ # accept without leading env
+ self.assertTrue(f.match(envset + ["sleep"]))
+
+ self.assertEqual(f.get_command(envcmd + realcmd), realcmd)
+ self.assertEqual(f.get_command(envset + realcmd), realcmd)
+
+ env = f.get_environment(envset + realcmd)
+ # check that environment variables are set
+ self.assertEqual(env.get('A'), '/some/thing')
+ self.assertEqual(env.get('B'), 'somethingelse')
+ self.assertFalse('sleep' in env.keys())
def test_KillFilter(self):
if not os.path.exists("/proc/%d" % os.getpid()):
@@ -169,6 +228,66 @@ class RootwrapTestCase(utils.BaseTestCase):
self.assertEqual(f.get_command(usercmd), ['/bin/cat', goodfn])
self.assertTrue(f.match(usercmd))
+ def test_IpFilter_non_netns(self):
+ f = filters.IpFilter('/sbin/ip', 'root')
+ self.assertTrue(f.match(['ip', 'link', 'list']))
+
+ def _test_IpFilter_netns_helper(self, action):
+ f = filters.IpFilter('/sbin/ip', 'root')
+ self.assertTrue(f.match(['ip', 'link', action]))
+
+ def test_IpFilter_netns_add(self):
+ self._test_IpFilter_netns_helper('add')
+
+ def test_IpFilter_netns_delete(self):
+ self._test_IpFilter_netns_helper('delete')
+
+ def test_IpFilter_netns_list(self):
+ self._test_IpFilter_netns_helper('list')
+
+ def test_IpNetnsExecFilter_match(self):
+ f = filters.IpNetnsExecFilter('/sbin/ip', 'root')
+ self.assertTrue(
+ f.match(['ip', 'netns', 'exec', 'foo', 'ip', 'link', 'list']))
+
+ def test_IpNetnsExecFilter_nomatch(self):
+ f = filters.IpNetnsExecFilter('/sbin/ip', 'root')
+ self.assertFalse(f.match(['ip', 'link', 'list']))
+
+ # verify that at least a NS is given
+ self.assertFalse(f.match(['ip', 'netns', 'exec']))
+
+ def test_IpNetnsExecFilter_nomatch_nonroot(self):
+ f = filters.IpNetnsExecFilter('/sbin/ip', 'user')
+ self.assertFalse(
+ f.match(['ip', 'netns', 'exec', 'foo', 'ip', 'link', 'list']))
+
+ def test_match_filter_recurses_exec_command_filter_matches(self):
+ filter_list = [filters.IpNetnsExecFilter('/sbin/ip', 'root'),
+ filters.IpFilter('/sbin/ip', 'root')]
+ args = ['ip', 'netns', 'exec', 'foo', 'ip', 'link', 'list']
+
+ self.assertIsNotNone(wrapper.match_filter(filter_list, args))
+
+ def test_match_filter_recurses_exec_command_matches_user(self):
+ filter_list = [filters.IpNetnsExecFilter('/sbin/ip', 'root'),
+ filters.IpFilter('/sbin/ip', 'user')]
+ args = ['ip', 'netns', 'exec', 'foo', 'ip', 'link', 'list']
+
+ # Currently ip netns exec requires root, so verify that
+ # no non-root filter is matched, as that would escalate privileges
+ self.assertRaises(wrapper.NoFilterMatched,
+ wrapper.match_filter, filter_list, args)
+
+ def test_match_filter_recurses_exec_command_filter_does_not_match(self):
+ filter_list = [filters.IpNetnsExecFilter('/sbin/ip', 'root'),
+ filters.IpFilter('/sbin/ip', 'root')]
+ args = ['ip', 'netns', 'exec', 'foo', 'ip', 'netns', 'exec', 'bar',
+ 'ip', 'link', 'list']
+
+ self.assertRaises(wrapper.NoFilterMatched,
+ wrapper.match_filter, filter_list, args)
+
def test_exec_dirs_search(self):
# This test supposes you have /bin/cat or /usr/bin/cat locally
f = filters.CommandFilter("cat", "root")