summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/unit/rpc/test_common.py76
-rw-r--r--tests/unit/rpc/test_kombu.py14
-rw-r--r--tests/unit/test_lockutils.py2
-rw-r--r--tests/unit/test_rootwrap.py202
-rw-r--r--tests/unit/test_timeutils.py55
-rw-r--r--tests/unit/test_version.py27
6 files changed, 347 insertions, 29 deletions
diff --git a/tests/unit/rpc/test_common.py b/tests/unit/rpc/test_common.py
index 6f8b7ff..fd59929 100644
--- a/tests/unit/rpc/test_common.py
+++ b/tests/unit/rpc/test_common.py
@@ -236,3 +236,79 @@ class RpcCommonTestCase(test_utils.BaseTestCase):
self.assertRaises(rpc_common.ClientException, naughty)
self.assertRaises(ValueError, really_naughty)
+
+ def test_serialize_msg_v1(self):
+ self.stubs.Set(rpc_common, '_SEND_RPC_ENVELOPE', False)
+ msg = {'foo': 'bar'}
+ self.assertEqual(msg, rpc_common.serialize_msg(msg))
+
+ def test_serialize_msg_v2(self):
+ self.stubs.Set(rpc_common, '_SEND_RPC_ENVELOPE', True)
+ msg = {'foo': 'bar'}
+ s_msg = {'oslo.version': rpc_common._RPC_ENVELOPE_VERSION,
+ 'oslo.message': jsonutils.dumps(msg)}
+ serialized = rpc_common.serialize_msg(msg)
+
+ self.assertEqual(s_msg, rpc_common.serialize_msg(msg))
+
+ self.assertEqual(msg, rpc_common.deserialize_msg(serialized))
+
+ def test_deserialize_msg_no_envelope(self):
+ self.assertEqual(1, rpc_common.deserialize_msg(1))
+ self.assertEqual([], rpc_common.deserialize_msg([]))
+ self.assertEqual({}, rpc_common.deserialize_msg({}))
+ self.assertEqual('foo', rpc_common.deserialize_msg('foo'))
+
+ def test_deserialize_msg_bad_version(self):
+ s_msg = {'oslo.version': '8675309.0',
+ 'oslo.message': 'whatever'}
+
+ self.assertRaises(rpc_common.UnsupportedRpcEnvelopeVersion,
+ rpc_common.deserialize_msg, s_msg)
+
+ def test_safe_log_sanitizes_globals(self):
+ def logger_method(msg, data):
+ self.assertEquals('<SANITIZED>', data['_context_auth_token'])
+ self.assertEquals('<SANITIZED>', data['auth_token'])
+
+ data = {'_context_auth_token': 'banana',
+ 'auth_token': 'cheese'}
+ rpc_common._safe_log(logger_method, 'foo', data)
+
+ def test_safe_log_sanitizes_set_admin_password(self):
+ def logger_method(msg, data):
+ self.assertEquals('<SANITIZED>', data['args']['new_pass'])
+
+ data = {'_context_auth_token': 'banana',
+ 'auth_token': 'cheese',
+ 'method': 'set_admin_password',
+ 'args': {'new_pass': 'gerkin'}}
+ rpc_common._safe_log(logger_method, 'foo', data)
+
+ def test_safe_log_sanitizes_run_instance(self):
+ def logger_method(msg, data):
+ self.assertEquals('<SANITIZED>', data['args']['admin_password'])
+
+ data = {'_context_auth_token': 'banana',
+ 'auth_token': 'cheese',
+ 'method': 'run_instance',
+ 'args': {'admin_password': 'gerkin'}}
+ rpc_common._safe_log(logger_method, 'foo', data)
+
+ def test_safe_log_sanitizes_cells_route_message(self):
+ def logger_method(msg, data):
+ vals = data['args']['message']['args']['method_info']
+ self.assertEquals('<SANITIZED>', vals['method_kwargs']['password'])
+
+ meth_info = {'method_args': ['aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'],
+ 'method': 'set_admin_password',
+ 'method_kwargs': {'password': 'this_password_is_visible'}}
+ data = {'method': 'route_message',
+ 'args': {'routing_path': 'a.fake.path',
+ 'direction': 'down',
+ 'message': {'args': {'is_broadcast': False,
+ 'service_name': 'compute',
+ 'method_info': meth_info},
+ 'method': 'run_service_api_method'},
+ 'dest_cell_name': 'cell!0001'}}
+ rpc_common._safe_log(logger_method, 'foo', data)
diff --git a/tests/unit/rpc/test_kombu.py b/tests/unit/rpc/test_kombu.py
index 5da05de..921415d 100644
--- a/tests/unit/rpc/test_kombu.py
+++ b/tests/unit/rpc/test_kombu.py
@@ -118,7 +118,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
self.received_message = message
conn.declare_topic_consumer('a_topic', _callback)
- conn.topic_send('a_topic', message)
+ conn.topic_send('a_topic', rpc_common.serialize_msg(message))
conn.consume(limit=1)
conn.close()
@@ -138,7 +138,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
conn.declare_topic_consumer('a_topic', _callback,
exchange_name="foorbar")
- conn.topic_send('a_topic', message)
+ conn.topic_send('a_topic', rpc_common.serialize_msg(message))
conn.consume(limit=1)
conn.close()
@@ -162,7 +162,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
conn.declare_topic_consumer('a_topic', _callback1, queue_name='queue1')
conn.declare_topic_consumer('a_topic', _callback2, queue_name='queue2')
- conn.topic_send('a_topic', message)
+ conn.topic_send('a_topic', rpc_common.serialize_msg(message))
conn.consume(limit=2)
conn.close()
@@ -192,7 +192,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
exchange_name="abc")
conn.declare_topic_consumer('a_topic', _callback2, queue_name='queue2',
exchange_name="abc")
- conn.topic_send('a_topic', message)
+ conn.topic_send('a_topic', rpc_common.serialize_msg(message))
conn.consume(limit=2)
conn.close()
@@ -222,7 +222,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
exchange_name="abc")
conn.declare_topic_consumer('a_topic', _callback2, queue_name='queue2',
exchange_name="def")
- conn.topic_send('a_topic', message)
+ conn.topic_send('a_topic', rpc_common.serialize_msg(message))
conn.consume(limit=2)
conn.close()
@@ -241,7 +241,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
self.received_message = message
conn.declare_direct_consumer('a_direct', _callback)
- conn.direct_send('a_direct', message)
+ conn.direct_send('a_direct', rpc_common.serialize_msg(message))
conn.consume(limit=1)
conn.close()
@@ -438,7 +438,7 @@ class RpcKombuTestCase(common.BaseRpcAMQPTestCase):
self.received_message = message
conn.declare_direct_consumer('a_direct', _callback)
- conn.direct_send('a_direct', message)
+ conn.direct_send('a_direct', rpc_common.serialize_msg(message))
info = _raise_exc_stub(self.stubs, 1, conn.connection,
'drain_events', 'foo timeout foo')
diff --git a/tests/unit/test_lockutils.py b/tests/unit/test_lockutils.py
index 5f50217..d6fbd8b 100644
--- a/tests/unit/test_lockutils.py
+++ b/tests/unit/test_lockutils.py
@@ -27,6 +27,7 @@ from eventlet import greenthread
from eventlet import greenpool
from openstack.common import lockutils
+from openstack.common import testutils
from tests import utils as test_utils
@@ -128,6 +129,7 @@ class LockTestCase(test_utils.BaseTestCase):
if os.path.exists(tempdir):
shutil.rmtree(tempdir)
+ @testutils.skip_test("Regularly fails, see bug #1095957")
def test_synchronized_externally(self):
"""We can lock across multiple processes"""
tempdir = tempfile.mkdtemp()
diff --git a/tests/unit/test_rootwrap.py b/tests/unit/test_rootwrap.py
new file mode 100644
index 0000000..2391005
--- /dev/null
+++ b/tests/unit/test_rootwrap.py
@@ -0,0 +1,202 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC
+#
+# 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 ConfigParser
+import logging
+import logging.handlers
+import os
+import stubout
+import subprocess
+import unittest
+
+from openstack.common.rootwrap import filters
+from openstack.common.rootwrap import wrapper
+
+
+class RootwrapTestCase(unittest.TestCase):
+
+ def setUp(self):
+ super(RootwrapTestCase, self).setUp()
+ self.stubs = stubout.StubOutForTesting()
+ self.filters = [
+ filters.RegExpFilter("/bin/ls", "root", 'ls', '/[a-z]+'),
+ filters.CommandFilter("/usr/bin/foo_bar_not_exist", "root"),
+ filters.RegExpFilter("/bin/cat", "root", 'cat', '/[a-z]+'),
+ filters.CommandFilter("/nonexistent/cat", "root"),
+ filters.CommandFilter("/bin/cat", "root") # Keep this one last
+ ]
+
+ def test_RegExpFilter_match(self):
+ usercmd = ["ls", "/root"]
+ filtermatch = wrapper.match_filter(self.filters, usercmd)
+ self.assertFalse(filtermatch is None)
+ self.assertEqual(filtermatch.get_command(usercmd),
+ ["/bin/ls", "/root"])
+
+ def test_RegExpFilter_reject(self):
+ usercmd = ["ls", "root"]
+ self.assertRaises(wrapper.NoFilterMatched,
+ wrapper.match_filter, self.filters, usercmd)
+
+ def test_missing_command(self):
+ valid_but_missing = ["foo_bar_not_exist"]
+ invalid = ["foo_bar_not_exist_and_not_matched"]
+ self.assertRaises(wrapper.FilterMatchNotExecutable,
+ wrapper.match_filter,
+ self.filters, valid_but_missing)
+ self.assertRaises(wrapper.NoFilterMatched,
+ wrapper.match_filter, self.filters, invalid)
+
+ def _test_DnsmasqFilter(self, filter_class, config_file_arg):
+ usercmd = ['env', config_file_arg + '=A', 'NETWORK_ID=foobar',
+ 'dnsmasq', 'foo']
+ f = filter_class("/usr/bin/dnsmasq", "root")
+ self.assertTrue(f.match(usercmd))
+ self.assertEqual(f.get_command(usercmd), ['/usr/bin/dnsmasq', 'foo'])
+ env = f.get_environment(usercmd)
+ self.assertEqual(env.get(config_file_arg), 'A')
+ self.assertEqual(env.get('NETWORK_ID'), 'foobar')
+
+ def test_DnsmasqFilter(self):
+ self._test_DnsmasqFilter(filters.DnsmasqFilter, 'CONFIG_FILE')
+
+ def test_DeprecatedDnsmasqFilter(self):
+ self._test_DnsmasqFilter(filters.DeprecatedDnsmasqFilter, 'FLAGFILE')
+
+ def test_KillFilter(self):
+ if not os.path.exists("/proc/%d" % os.getpid()):
+ self.skipTest("Test requires /proc filesystem (procfs)")
+ p = subprocess.Popen(["cat"], stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ try:
+ f = filters.KillFilter("root", "/bin/cat", "-9", "-HUP")
+ f2 = filters.KillFilter("root", "/usr/bin/cat", "-9", "-HUP")
+ usercmd = ['kill', '-ALRM', p.pid]
+ # Incorrect signal should fail
+ self.assertFalse(f.match(usercmd) or f2.match(usercmd))
+ usercmd = ['kill', p.pid]
+ # Providing no signal should fail
+ self.assertFalse(f.match(usercmd) or f2.match(usercmd))
+ # Providing matching signal should be allowed
+ usercmd = ['kill', '-9', p.pid]
+ self.assertTrue(f.match(usercmd) or f2.match(usercmd))
+
+ f = filters.KillFilter("root", "/bin/cat")
+ f2 = filters.KillFilter("root", "/usr/bin/cat")
+ usercmd = ['kill', os.getpid()]
+ # Our own PID does not match /bin/sleep, so it should fail
+ self.assertFalse(f.match(usercmd) or f2.match(usercmd))
+ usercmd = ['kill', 999999]
+ # Nonexistent PID should fail
+ self.assertFalse(f.match(usercmd) or f2.match(usercmd))
+ usercmd = ['kill', p.pid]
+ # Providing no signal should work
+ self.assertTrue(f.match(usercmd) or f2.match(usercmd))
+ finally:
+ # Terminate the "cat" process and wait for it to finish
+ p.terminate()
+ p.wait()
+
+ def test_KillFilter_no_raise(self):
+ """Makes sure ValueError from bug 926412 is gone"""
+ f = filters.KillFilter("root", "")
+ # Providing anything other than kill should be False
+ usercmd = ['notkill', 999999]
+ self.assertFalse(f.match(usercmd))
+ # Providing something that is not a pid should be False
+ usercmd = ['kill', 'notapid']
+ self.assertFalse(f.match(usercmd))
+
+ def test_KillFilter_deleted_exe(self):
+ """Makes sure deleted exe's are killed correctly"""
+ # See bug #967931.
+ def fake_readlink(blah):
+ return '/bin/commandddddd (deleted)'
+
+ f = filters.KillFilter("root", "/bin/commandddddd")
+ usercmd = ['kill', 1234]
+ # Providing no signal should work
+ self.stubs.Set(os, 'readlink', fake_readlink)
+ self.assertTrue(f.match(usercmd))
+
+ def test_ReadFileFilter(self):
+ goodfn = '/good/file.name'
+ f = filters.ReadFileFilter(goodfn)
+ usercmd = ['cat', '/bad/file']
+ self.assertFalse(f.match(['cat', '/bad/file']))
+ usercmd = ['cat', goodfn]
+ self.assertEqual(f.get_command(usercmd), ['/bin/cat', goodfn])
+ self.assertTrue(f.match(usercmd))
+
+ def test_exec_dirs_search(self):
+ # This test supposes you have /bin/cat or /usr/bin/cat locally
+ f = filters.CommandFilter("cat", "root")
+ usercmd = ['cat', '/f']
+ self.assertTrue(f.match(usercmd))
+ self.assertTrue(f.get_command(usercmd,
+ exec_dirs=['/bin', '/usr/bin'])
+ in (['/bin/cat', '/f'], ['/usr/bin/cat', '/f']))
+
+ def test_skips(self):
+ # Check that all filters are skipped and that the last matches
+ usercmd = ["cat", "/"]
+ filtermatch = wrapper.match_filter(self.filters, usercmd)
+ self.assertTrue(filtermatch is self.filters[-1])
+
+ def test_RootwrapConfig(self):
+ raw = ConfigParser.RawConfigParser()
+
+ # Empty config should raise ConfigParser.Error
+ self.assertRaises(ConfigParser.Error, wrapper.RootwrapConfig, raw)
+
+ # Check default values
+ raw.set('DEFAULT', 'filters_path', '/a,/b')
+ config = wrapper.RootwrapConfig(raw)
+ self.assertEqual(config.filters_path, ['/a', '/b'])
+ self.assertEqual(config.exec_dirs, os.environ["PATH"].split(':'))
+ self.assertFalse(config.use_syslog)
+ self.assertEqual(config.syslog_log_facility,
+ logging.handlers.SysLogHandler.LOG_SYSLOG)
+ self.assertEqual(config.syslog_log_level, logging.ERROR)
+
+ # Check general values
+ raw.set('DEFAULT', 'exec_dirs', '/a,/x')
+ config = wrapper.RootwrapConfig(raw)
+ self.assertEqual(config.exec_dirs, ['/a', '/x'])
+
+ raw.set('DEFAULT', 'use_syslog', 'oui')
+ self.assertRaises(ValueError, wrapper.RootwrapConfig, raw)
+ raw.set('DEFAULT', 'use_syslog', 'true')
+ config = wrapper.RootwrapConfig(raw)
+ self.assertTrue(config.use_syslog)
+
+ raw.set('DEFAULT', 'syslog_log_facility', 'moo')
+ self.assertRaises(ValueError, wrapper.RootwrapConfig, raw)
+ raw.set('DEFAULT', 'syslog_log_facility', 'local0')
+ config = wrapper.RootwrapConfig(raw)
+ self.assertEqual(config.syslog_log_facility,
+ logging.handlers.SysLogHandler.LOG_LOCAL0)
+ raw.set('DEFAULT', 'syslog_log_facility', 'LOG_AUTH')
+ config = wrapper.RootwrapConfig(raw)
+ self.assertEqual(config.syslog_log_facility,
+ logging.handlers.SysLogHandler.LOG_AUTH)
+
+ raw.set('DEFAULT', 'syslog_log_level', 'bar')
+ self.assertRaises(ValueError, wrapper.RootwrapConfig, raw)
+ raw.set('DEFAULT', 'syslog_log_level', 'INFO')
+ config = wrapper.RootwrapConfig(raw)
+ self.assertEqual(config.syslog_log_level, logging.INFO)
diff --git a/tests/unit/test_timeutils.py b/tests/unit/test_timeutils.py
index 8236032..1407f29 100644
--- a/tests/unit/test_timeutils.py
+++ b/tests/unit/test_timeutils.py
@@ -27,14 +27,10 @@ from openstack.common import timeutils
class TimeUtilsTest(unittest.TestCase):
def setUp(self):
- utc_timezone = iso8601.iso8601.UTC
self.skynet_self_aware_time_str = '1997-08-29T06:14:00Z'
- self.skynet_self_aware_time = datetime.datetime(1997, 8, 29, 6, 14, 0,
- tzinfo=utc_timezone)
- self.one_minute_before = datetime.datetime(1997, 8, 29, 6, 13, 0,
- tzinfo=iso8601.iso8601.UTC)
- self.one_minute_after = datetime.datetime(1997, 8, 29, 6, 15, 0,
- tzinfo=iso8601.iso8601.UTC)
+ self.skynet_self_aware_time = datetime.datetime(1997, 8, 29, 6, 14, 0)
+ self.one_minute_before = datetime.datetime(1997, 8, 29, 6, 13, 0)
+ self.one_minute_after = datetime.datetime(1997, 8, 29, 6, 15, 0)
self.skynet_self_aware_time_perfect_str = '1997-08-29T06:14:00.000000'
self.skynet_self_aware_time_perfect = datetime.datetime(1997, 8, 29,
6, 14, 0)
@@ -50,7 +46,9 @@ class TimeUtilsTest(unittest.TestCase):
def test_parse_isotime(self):
expect = timeutils.parse_isotime(self.skynet_self_aware_time_str)
- self.assertEqual(self.skynet_self_aware_time, expect)
+ skynet_self_aware_time_utc = self.skynet_self_aware_time.replace(
+ tzinfo=iso8601.iso8601.UTC)
+ self.assertEqual(skynet_self_aware_time_utc, expect)
def test_strtime(self):
expect = timeutils.strtime(self.skynet_self_aware_time_perfect)
@@ -67,31 +65,52 @@ class TimeUtilsTest(unittest.TestCase):
t = timeutils.parse_strtime(s)
self.assertEqual(orig_t, t)
- def test_is_older_than(self):
+ def _test_is_older_than(self, fn):
+ strptime = datetime.datetime.strptime
with mock.patch('datetime.datetime') as datetime_mock:
datetime_mock.utcnow.return_value = self.skynet_self_aware_time
- expect_true = timeutils.is_older_than(self.one_minute_before, 59)
+ datetime_mock.strptime = strptime
+ expect_true = timeutils.is_older_than(fn(self.one_minute_before),
+ 59)
self.assertTrue(expect_true)
- expect_false = timeutils.is_older_than(self.one_minute_before, 60)
+ expect_false = timeutils.is_older_than(fn(self.one_minute_before),
+ 60)
self.assertFalse(expect_false)
- expect_false = timeutils.is_older_than(self.one_minute_before, 61)
+ expect_false = timeutils.is_older_than(fn(self.one_minute_before),
+ 61)
self.assertFalse(expect_false)
- def test_is_newer_than(self):
+ def test_is_older_than_datetime(self):
+ self._test_is_older_than(lambda x: x)
+
+ def test_is_older_than_str(self):
+ self._test_is_older_than(timeutils.strtime)
+
+ def _test_is_newer_than(self, fn):
+ strptime = datetime.datetime.strptime
with mock.patch('datetime.datetime') as datetime_mock:
datetime_mock.utcnow.return_value = self.skynet_self_aware_time
- expect_true = timeutils.is_newer_than(self.one_minute_after, 59)
+ datetime_mock.strptime = strptime
+ expect_true = timeutils.is_newer_than(fn(self.one_minute_after),
+ 59)
self.assertTrue(expect_true)
- expect_false = timeutils.is_newer_than(self.one_minute_after, 60)
+ expect_false = timeutils.is_newer_than(fn(self.one_minute_after),
+ 60)
self.assertFalse(expect_false)
- expect_false = timeutils.is_newer_than(self.one_minute_after, 61)
+ expect_false = timeutils.is_newer_than(fn(self.one_minute_after),
+ 61)
self.assertFalse(expect_false)
+ def test_is_newer_than_datetime(self):
+ self._test_is_newer_than(lambda x: x)
+
+ def test_is_newer_than_str(self):
+ self._test_is_newer_than(timeutils.strtime)
+
def test_utcnow_ts(self):
skynet_self_aware_timestamp = 872835240
dt = datetime.datetime.utcfromtimestamp(skynet_self_aware_timestamp)
- expect = dt.replace(tzinfo=iso8601.iso8601.UTC)
- self.assertEqual(self.skynet_self_aware_time, expect)
+ self.assertEqual(self.skynet_self_aware_time, dt)
with mock.patch('datetime.datetime') as datetime_mock:
datetime_mock.utcnow.return_value = self.skynet_self_aware_time
ts = timeutils.utcnow_ts()
diff --git a/tests/unit/test_version.py b/tests/unit/test_version.py
index 8e60f51..c67ccde 100644
--- a/tests/unit/test_version.py
+++ b/tests/unit/test_version.py
@@ -42,23 +42,23 @@ class DeferredVersionTestCase(BaseTestCase):
super(DeferredVersionTestCase, self).setUp()
self.conf = ConfigOpts()
- def test_deferred_version(self):
+ def test_cached_version(self):
class MyVersionInfo(version.VersionInfo):
def _generate_version(self):
return "5.5.5.5"
deferred_string = MyVersionInfo("openstack").\
- deferred_version_string()
+ cached_version_string()
self.conf([], project="project", prog="prog", version=deferred_string)
self.assertEquals("5.5.5.5", str(self.conf.version))
- def test_print_deferred_version(self):
+ def test_print_cached_version(self):
class MyVersionInfo(version.VersionInfo):
def _generate_version(self):
return "5.5.5.5"
deferred_string = MyVersionInfo("openstack")\
- .deferred_version_string()
+ .cached_version_string()
self.stubs.Set(sys, 'stderr', StringIO.StringIO())
self.assertRaises(SystemExit,
self.conf, ['--version'],
@@ -66,3 +66,22 @@ class DeferredVersionTestCase(BaseTestCase):
prog="prog",
version=deferred_string)
self.assertEquals("5.5.5.5", sys.stderr.getvalue().strip())
+
+ def test_print_cached_version_with_long_string(self):
+ my_version = "11111222223333344444555556666677777888889999900000"
+
+ class MyVersionInfo(version.VersionInfo):
+ def _generate_version(self):
+ return my_version
+
+ deferred_string = MyVersionInfo("openstack")\
+ .cached_version_string()
+
+ for i in range(50):
+ self.stubs.Set(sys, 'stderr', StringIO.StringIO())
+ self.assertRaises(SystemExit,
+ self.conf, ['--version'],
+ project="project",
+ prog="prog",
+ version=deferred_string)
+ self.assertEquals(my_version, sys.stderr.getvalue().strip())