diff options
author | asteroide <thomas.duval@orange.com> | 2015-09-01 16:03:26 +0200 |
---|---|---|
committer | asteroide <thomas.duval@orange.com> | 2015-09-01 16:04:53 +0200 |
commit | 92fd2dbfb672d7b2b1cdfd5dd5cf89f7716b3e12 (patch) | |
tree | 7ba22297042019e7363fa1d4ad26d1c32c5908c6 /keystone-moon/keystone/tests/unit/common | |
parent | 26e753254f3e43399cc76e62892908b7742415e8 (diff) |
Update Keystone code from official Github repository with branch Master on 09/01/2015.
Change-Id: I0ff6099e6e2580f87f502002a998bbfe12673498
Diffstat (limited to 'keystone-moon/keystone/tests/unit/common')
5 files changed, 224 insertions, 119 deletions
diff --git a/keystone-moon/keystone/tests/unit/common/test_connection_pool.py b/keystone-moon/keystone/tests/unit/common/test_connection_pool.py index 74d0420c..3813e033 100644 --- a/keystone-moon/keystone/tests/unit/common/test_connection_pool.py +++ b/keystone-moon/keystone/tests/unit/common/test_connection_pool.py @@ -10,9 +10,11 @@ # License for the specific language governing permissions and limitations # under the License. +import threading import time import mock +import six from six.moves import queue import testtools from testtools import matchers @@ -117,3 +119,17 @@ class TestConnectionPool(core.TestCase): # after it is available. connection_pool.put_nowait(conn) _acquire_connection() + + +class TestMemcacheClientOverrides(core.BaseTestCase): + + def test_client_stripped_of_threading_local(self): + """threading.local overrides are restored for _MemcacheClient""" + client_class = _memcache_pool._MemcacheClient + # get the genuine thread._local from MRO + thread_local = client_class.__mro__[2] + self.assertTrue(thread_local is threading.local) + for field in six.iterkeys(thread_local.__dict__): + if field not in ('__dict__', '__weakref__'): + self.assertNotEqual(id(getattr(thread_local, field, None)), + id(getattr(client_class, field, None))) diff --git a/keystone-moon/keystone/tests/unit/common/test_injection.py b/keystone-moon/keystone/tests/unit/common/test_injection.py index 86bb3c24..b4c23a84 100644 --- a/keystone-moon/keystone/tests/unit/common/test_injection.py +++ b/keystone-moon/keystone/tests/unit/common/test_injection.py @@ -21,6 +21,7 @@ from keystone.tests import unit as tests class TestDependencyInjection(tests.BaseTestCase): def setUp(self): super(TestDependencyInjection, self).setUp() + dependency.reset() self.addCleanup(dependency.reset) def test_dependency_injection(self): @@ -210,62 +211,6 @@ class TestDependencyInjection(tests.BaseTestCase): self.assertFalse(dependency._REGISTRY) - def test_optional_dependency_not_provided(self): - requirement_name = uuid.uuid4().hex - - @dependency.optional(requirement_name) - class C1(object): - pass - - c1_inst = C1() - - dependency.resolve_future_dependencies() - - self.assertIsNone(getattr(c1_inst, requirement_name)) - - def test_optional_dependency_provided(self): - requirement_name = uuid.uuid4().hex - - @dependency.optional(requirement_name) - class C1(object): - pass - - @dependency.provider(requirement_name) - class P1(object): - pass - - c1_inst = C1() - p1_inst = P1() - - dependency.resolve_future_dependencies() - - self.assertIs(getattr(c1_inst, requirement_name), p1_inst) - - def test_optional_and_required(self): - p1_name = uuid.uuid4().hex - p2_name = uuid.uuid4().hex - optional_name = uuid.uuid4().hex - - @dependency.provider(p1_name) - @dependency.requires(p2_name) - @dependency.optional(optional_name) - class P1(object): - pass - - @dependency.provider(p2_name) - @dependency.requires(p1_name) - class P2(object): - pass - - p1 = P1() - p2 = P2() - - dependency.resolve_future_dependencies() - - self.assertIs(getattr(p1, p2_name), p2) - self.assertIs(getattr(p2, p1_name), p1) - self.assertIsNone(getattr(p1, optional_name)) - def test_get_provider(self): # Can get the instance of a provider using get_provider diff --git a/keystone-moon/keystone/tests/unit/common/test_ldap.py b/keystone-moon/keystone/tests/unit/common/test_ldap.py index 41568890..d3ce8cd2 100644 --- a/keystone-moon/keystone/tests/unit/common/test_ldap.py +++ b/keystone-moon/keystone/tests/unit/common/test_ldap.py @@ -11,23 +11,24 @@ # License for the specific language governing permissions and limitations # under the License. +import os +import tempfile import uuid +import fixtures import ldap.dn import mock from oslo_config import cfg from testtools import matchers -import os -import shutil -import tempfile - +from keystone.common import driver_hints from keystone.common import ldap as ks_ldap from keystone.common.ldap import core as common_ldap_core from keystone.tests import unit as tests from keystone.tests.unit import default_fixtures from keystone.tests.unit import fakeldap + CONF = cfg.CONF @@ -218,9 +219,7 @@ class LDAPDeleteTreeTest(tests.TestCase): def config_overrides(self): super(LDAPDeleteTreeTest, self).config_overrides() - self.config_fixture.config( - group='identity', - driver='keystone.identity.backends.ldap.Identity') + self.config_fixture.config(group='identity', driver='ldap') def config_files(self): config_files = super(LDAPDeleteTreeTest, self).config_files() @@ -311,8 +310,7 @@ class SslTlsTest(tests.TestCase): def test_certdir_trust_tls(self): # We need this to actually exist, so we create a tempdir. - certdir = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, certdir) + certdir = self.useFixture(fixtures.TempDir()).path self.config_fixture.config(group='ldap', url='ldap://localhost', use_tls=True, @@ -340,8 +338,7 @@ class SslTlsTest(tests.TestCase): def test_certdir_trust_ldaps(self): # We need this to actually exist, so we create a tempdir. - certdir = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, certdir) + certdir = self.useFixture(fixtures.TempDir()).path self.config_fixture.config(group='ldap', url='ldaps://localhost', use_tls=False, @@ -372,9 +369,7 @@ class LDAPPagedResultsTest(tests.TestCase): def config_overrides(self): super(LDAPPagedResultsTest, self).config_overrides() - self.config_fixture.config( - group='identity', - driver='keystone.identity.backends.ldap.Identity') + self.config_fixture.config(group='identity', driver='ldap') def config_files(self): config_files = super(LDAPPagedResultsTest, self).config_files() @@ -500,3 +495,68 @@ class CommonLdapTestCase(tests.BaseTestCase): py_result = ks_ldap.convert_ldap_result(result) # The user name should still be a string value. self.assertEqual(user_name, py_result[0][1]['user_name'][0]) + + +class LDAPFilterQueryCompositionTest(tests.TestCase): + """These test cases test LDAP filter generation.""" + + def setUp(self): + super(LDAPFilterQueryCompositionTest, self).setUp() + + self.base_ldap = ks_ldap.BaseLdap(self.config_fixture.conf) + + # The tests need an attribute mapping to use. + self.attribute_name = uuid.uuid4().hex + self.filter_attribute_name = uuid.uuid4().hex + self.base_ldap.attribute_mapping = { + self.attribute_name: self.filter_attribute_name + } + + def test_return_query_with_no_hints(self): + hints = driver_hints.Hints() + # NOTE: doesn't have to be a real query, we just need to make sure the + # same string is returned if there are no hints. + query = uuid.uuid4().hex + self.assertEqual(query, + self.base_ldap.filter_query(hints=hints, query=query)) + + # make sure the default query is an empty string + self.assertEqual('', self.base_ldap.filter_query(hints=hints)) + + def test_filter_with_empty_query_and_hints_set(self): + hints = driver_hints.Hints() + username = uuid.uuid4().hex + hints.add_filter(name=self.attribute_name, + value=username, + comparator='equals', + case_sensitive=False) + expected_ldap_filter = '(&(%s=%s))' % ( + self.filter_attribute_name, username) + self.assertEqual(expected_ldap_filter, + self.base_ldap.filter_query(hints=hints)) + + def test_filter_with_both_query_and_hints_set(self): + hints = driver_hints.Hints() + # NOTE: doesn't have to be a real query, we just need to make sure the + # filter string is concatenated correctly + query = uuid.uuid4().hex + username = uuid.uuid4().hex + expected_result = '(&%(query)s(%(user_name_attr)s=%(username)s))' % ( + {'query': query, + 'user_name_attr': self.filter_attribute_name, + 'username': username}) + hints.add_filter(self.attribute_name, username) + self.assertEqual(expected_result, + self.base_ldap.filter_query(hints=hints, query=query)) + + def test_filter_with_hints_and_query_is_none(self): + hints = driver_hints.Hints() + username = uuid.uuid4().hex + hints.add_filter(name=self.attribute_name, + value=username, + comparator='equals', + case_sensitive=False) + expected_ldap_filter = '(&(%s=%s))' % ( + self.filter_attribute_name, username) + self.assertEqual(expected_ldap_filter, + self.base_ldap.filter_query(hints=hints, query=None)) diff --git a/keystone-moon/keystone/tests/unit/common/test_notifications.py b/keystone-moon/keystone/tests/unit/common/test_notifications.py index 55dd556d..2d872733 100644 --- a/keystone-moon/keystone/tests/unit/common/test_notifications.py +++ b/keystone-moon/keystone/tests/unit/common/test_notifications.py @@ -23,10 +23,9 @@ from pycadf import cadftaxonomy from pycadf import cadftype from pycadf import eventfactory from pycadf import resource as cadfresource -import testtools -from keystone.common import dependency from keystone import notifications +from keystone.tests import unit from keystone.tests.unit import test_v3 @@ -53,7 +52,7 @@ def register_callback(operation, resource_type=EXP_RESOURCE_TYPE): return callback -class AuditNotificationsTestCase(testtools.TestCase): +class AuditNotificationsTestCase(unit.BaseTestCase): def setUp(self): super(AuditNotificationsTestCase, self).setUp() self.config_fixture = self.useFixture(config_fixture.Config(CONF)) @@ -96,7 +95,7 @@ class AuditNotificationsTestCase(testtools.TestCase): DISABLED_OPERATION) -class NotificationsWrapperTestCase(testtools.TestCase): +class NotificationsWrapperTestCase(unit.BaseTestCase): def create_fake_ref(self): resource_id = uuid.uuid4().hex return resource_id, { @@ -174,14 +173,7 @@ class NotificationsWrapperTestCase(testtools.TestCase): self.assertFalse(callback.called) -class NotificationsTestCase(testtools.TestCase): - def setUp(self): - super(NotificationsTestCase, self).setUp() - - # these should use self.config_fixture.config(), but they haven't - # been registered yet - CONF.rpc_backend = 'fake' - CONF.notification_driver = ['fake'] +class NotificationsTestCase(unit.BaseTestCase): def test_send_notification(self): """Test the private method _send_notification to ensure event_type, @@ -324,7 +316,7 @@ class NotificationsForEntities(BaseNotificationTest): def test_create_project(self): project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) self._assert_last_note( project_ref['id'], CREATED_OPERATION, 'project') self._assert_last_audit(project_ref['id'], CREATED_OPERATION, @@ -371,8 +363,8 @@ class NotificationsForEntities(BaseNotificationTest): def test_delete_project(self): project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) - self.assignment_api.delete_project(project_ref['id']) + self.resource_api.create_project(project_ref['id'], project_ref) + self.resource_api.delete_project(project_ref['id']) self._assert_last_note( project_ref['id'], DELETED_OPERATION, 'project') self._assert_last_audit(project_ref['id'], DELETED_OPERATION, @@ -403,19 +395,19 @@ class NotificationsForEntities(BaseNotificationTest): def test_update_domain(self): domain_ref = self.new_domain_ref() - self.assignment_api.create_domain(domain_ref['id'], domain_ref) + self.resource_api.create_domain(domain_ref['id'], domain_ref) domain_ref['description'] = uuid.uuid4().hex - self.assignment_api.update_domain(domain_ref['id'], domain_ref) + self.resource_api.update_domain(domain_ref['id'], domain_ref) self._assert_last_note(domain_ref['id'], UPDATED_OPERATION, 'domain') self._assert_last_audit(domain_ref['id'], UPDATED_OPERATION, 'domain', cadftaxonomy.SECURITY_DOMAIN) def test_delete_domain(self): domain_ref = self.new_domain_ref() - self.assignment_api.create_domain(domain_ref['id'], domain_ref) + self.resource_api.create_domain(domain_ref['id'], domain_ref) domain_ref['enabled'] = False - self.assignment_api.update_domain(domain_ref['id'], domain_ref) - self.assignment_api.delete_domain(domain_ref['id']) + self.resource_api.update_domain(domain_ref['id'], domain_ref) + self.resource_api.delete_domain(domain_ref['id']) self._assert_last_note(domain_ref['id'], DELETED_OPERATION, 'domain') self._assert_last_audit(domain_ref['id'], DELETED_OPERATION, 'domain', cadftaxonomy.SECURITY_DOMAIN) @@ -542,19 +534,19 @@ class NotificationsForEntities(BaseNotificationTest): def test_disable_domain(self): domain_ref = self.new_domain_ref() - self.assignment_api.create_domain(domain_ref['id'], domain_ref) + self.resource_api.create_domain(domain_ref['id'], domain_ref) domain_ref['enabled'] = False - self.assignment_api.update_domain(domain_ref['id'], domain_ref) + self.resource_api.update_domain(domain_ref['id'], domain_ref) self._assert_notify_sent(domain_ref['id'], 'disabled', 'domain', public=False) def test_disable_of_disabled_domain_does_not_notify(self): domain_ref = self.new_domain_ref() domain_ref['enabled'] = False - self.assignment_api.create_domain(domain_ref['id'], domain_ref) + self.resource_api.create_domain(domain_ref['id'], domain_ref) # The domain_ref above is not changed during the create process. We # can use the same ref to perform the update. - self.assignment_api.update_domain(domain_ref['id'], domain_ref) + self.resource_api.update_domain(domain_ref['id'], domain_ref) self._assert_notify_not_sent(domain_ref['id'], 'disabled', 'domain', public=False) @@ -568,8 +560,8 @@ class NotificationsForEntities(BaseNotificationTest): def test_update_project(self): project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) - self.assignment_api.update_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) + self.resource_api.update_project(project_ref['id'], project_ref) self._assert_notify_sent( project_ref['id'], UPDATED_OPERATION, 'project', public=True) self._assert_last_audit(project_ref['id'], UPDATED_OPERATION, @@ -577,27 +569,27 @@ class NotificationsForEntities(BaseNotificationTest): def test_disable_project(self): project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) project_ref['enabled'] = False - self.assignment_api.update_project(project_ref['id'], project_ref) + self.resource_api.update_project(project_ref['id'], project_ref) self._assert_notify_sent(project_ref['id'], 'disabled', 'project', public=False) def test_disable_of_disabled_project_does_not_notify(self): project_ref = self.new_project_ref(domain_id=self.domain_id) project_ref['enabled'] = False - self.assignment_api.create_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) # The project_ref above is not changed during the create process. We # can use the same ref to perform the update. - self.assignment_api.update_project(project_ref['id'], project_ref) + self.resource_api.update_project(project_ref['id'], project_ref) self._assert_notify_not_sent(project_ref['id'], 'disabled', 'project', public=False) def test_update_project_does_not_send_disable(self): project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) project_ref['enabled'] = True - self.assignment_api.update_project(project_ref['id'], project_ref) + self.resource_api.update_project(project_ref['id'], project_ref) self._assert_last_note( project_ref['id'], UPDATED_OPERATION, 'project') self._assert_notify_not_sent(project_ref['id'], 'disabled', 'project') @@ -665,7 +657,7 @@ class TestEventCallbacks(test_v3.RestfulTestCase): def test_notification_received(self): callback = register_callback(CREATED_OPERATION, 'project') project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) self.assertTrue(callback.called) def test_notification_method_not_callable(self): @@ -694,14 +686,14 @@ class TestEventCallbacks(test_v3.RestfulTestCase): resource_type, self._project_deleted_callback) - def test_provider_event_callbacks_subscription(self): + def test_provider_event_callback_subscription(self): callback_called = [] - @dependency.provider('foo_api') + @notifications.listener class Foo(object): def __init__(self): self.event_callbacks = { - CREATED_OPERATION: {'project': [self.foo_callback]}} + CREATED_OPERATION: {'project': self.foo_callback}} def foo_callback(self, service, resource_type, operation, payload): @@ -710,24 +702,73 @@ class TestEventCallbacks(test_v3.RestfulTestCase): Foo() project_ref = self.new_project_ref(domain_id=self.domain_id) - self.assignment_api.create_project(project_ref['id'], project_ref) + self.resource_api.create_project(project_ref['id'], project_ref) self.assertEqual([True], callback_called) + def test_provider_event_callbacks_subscription(self): + callback_called = [] + + @notifications.listener + class Foo(object): + def __init__(self): + self.event_callbacks = { + CREATED_OPERATION: { + 'project': [self.callback_0, self.callback_1]}} + + def callback_0(self, service, resource_type, operation, payload): + # uses callback_called from the closure + callback_called.append('cb0') + + def callback_1(self, service, resource_type, operation, payload): + # uses callback_called from the closure + callback_called.append('cb1') + + Foo() + project_ref = self.new_project_ref(domain_id=self.domain_id) + self.resource_api.create_project(project_ref['id'], project_ref) + self.assertItemsEqual(['cb1', 'cb0'], callback_called) + def test_invalid_event_callbacks(self): - @dependency.provider('foo_api') + @notifications.listener class Foo(object): def __init__(self): self.event_callbacks = 'bogus' - self.assertRaises(ValueError, Foo) + self.assertRaises(AttributeError, Foo) def test_invalid_event_callbacks_event(self): - @dependency.provider('foo_api') + @notifications.listener class Foo(object): def __init__(self): self.event_callbacks = {CREATED_OPERATION: 'bogus'} - self.assertRaises(ValueError, Foo) + self.assertRaises(AttributeError, Foo) + + def test_using_an_unbound_method_as_a_callback_fails(self): + # NOTE(dstanek): An unbound method is when you reference a method + # from a class object. You'll get a method that isn't bound to a + # particular instance so there is no magic 'self'. You can call it, + # but you have to pass in the instance manually like: C.m(C()). + # If you reference the method from an instance then you get a method + # that effectively curries the self argument for you + # (think functools.partial). Obviously is we don't have an + # instance then we can't call the method. + @notifications.listener + class Foo(object): + def __init__(self): + self.event_callbacks = {CREATED_OPERATION: + {'project': Foo.callback}} + + def callback(self, *args): + pass + + # TODO(dstanek): it would probably be nice to fail early using + # something like: + # self.assertRaises(TypeError, Foo) + Foo() + project_ref = self.new_project_ref(domain_id=self.domain_id) + self.assertRaises(TypeError, self.resource_api.create_project, + project_ref['id'], project_ref) class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase): @@ -759,13 +800,14 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase): 'action': action, 'initiator': initiator, 'event': event, + 'event_type': event_type, 'send_notification_called': True} self._notifications.append(note) self.useFixture(mockpatch.PatchObject( notifications, '_send_audit_notification', fake_notify)) - def _assert_last_note(self, action, user_id): + def _assert_last_note(self, action, user_id, event_type=None): self.assertTrue(self._notifications) note = self._notifications[-1] self.assertEqual(note['action'], action) @@ -773,6 +815,8 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase): self.assertEqual(initiator.id, user_id) self.assertEqual(initiator.host.address, self.LOCAL_HOST) self.assertTrue(note['send_notification_called']) + if event_type: + self.assertEqual(note['event_type'], event_type) def _assert_event(self, role_id, project=None, domain=None, user=None, group=None, inherit=False): @@ -816,10 +860,10 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase): self.assertEqual(project, event.project) if domain: self.assertEqual(domain, event.domain) - if user: - self.assertEqual(user, event.user) if group: self.assertEqual(group, event.group) + elif user: + self.assertEqual(user, event.user) self.assertEqual(role_id, event.role) self.assertEqual(inherit, event.inherited_to_projects) @@ -857,12 +901,16 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase): user=None, group=None): self.put(url) action = "%s.%s" % (CREATED_OPERATION, self.ROLE_ASSIGNMENT) - self._assert_last_note(action, self.user_id) + event_type = '%s.%s.%s' % (notifications.SERVICE, + self.ROLE_ASSIGNMENT, CREATED_OPERATION) + self._assert_last_note(action, self.user_id, event_type) self._assert_event(role, project, domain, user, group) self.delete(url) action = "%s.%s" % (DELETED_OPERATION, self.ROLE_ASSIGNMENT) - self._assert_last_note(action, self.user_id) - self._assert_event(role, project, domain, user, group) + event_type = '%s.%s.%s' % (notifications.SERVICE, + self.ROLE_ASSIGNMENT, DELETED_OPERATION) + self._assert_last_note(action, self.user_id, event_type) + self._assert_event(role, project, domain, user, None) def test_user_project_grant(self): url = ('/projects/%s/users/%s/roles/%s' % @@ -874,14 +922,50 @@ class CadfNotificationsWrapperTestCase(test_v3.RestfulTestCase): def test_group_domain_grant(self): group_ref = self.new_group_ref(domain_id=self.domain_id) group = self.identity_api.create_group(group_ref) + self.identity_api.add_user_to_group(self.user_id, group['id']) url = ('/domains/%s/groups/%s/roles/%s' % (self.domain_id, group['id'], self.role_id)) self._test_role_assignment(url, self.role_id, domain=self.domain_id, + user=self.user_id, group=group['id']) + def test_add_role_to_user_and_project(self): + # A notification is sent when add_role_to_user_and_project is called on + # the assignment manager. + + project_ref = self.new_project_ref(self.domain_id) + project = self.resource_api.create_project( + project_ref['id'], project_ref) + tenant_id = project['id'] + + self.assignment_api.add_role_to_user_and_project( + self.user_id, tenant_id, self.role_id) + + self.assertTrue(self._notifications) + note = self._notifications[-1] + self.assertEqual(note['action'], 'created.role_assignment') + self.assertTrue(note['send_notification_called']) + + self._assert_event(self.role_id, project=tenant_id, user=self.user_id) + + def test_remove_role_from_user_and_project(self): + # A notification is sent when remove_role_from_user_and_project is + # called on the assignment manager. + + self.assignment_api.remove_role_from_user_and_project( + self.user_id, self.project_id, self.role_id) + + self.assertTrue(self._notifications) + note = self._notifications[-1] + self.assertEqual(note['action'], 'deleted.role_assignment') + self.assertTrue(note['send_notification_called']) + + self._assert_event(self.role_id, project=self.project_id, + user=self.user_id) + -class TestCallbackRegistration(testtools.TestCase): +class TestCallbackRegistration(unit.BaseTestCase): def setUp(self): super(TestCallbackRegistration, self).setUp() self.mock_log = mock.Mock() diff --git a/keystone-moon/keystone/tests/unit/common/test_utils.py b/keystone-moon/keystone/tests/unit/common/test_utils.py index 184c8141..e8bac3c0 100644 --- a/keystone-moon/keystone/tests/unit/common/test_utils.py +++ b/keystone-moon/keystone/tests/unit/common/test_utils.py @@ -150,7 +150,7 @@ class UtilsTestCase(tests.BaseTestCase): def test_pki_encoder(self): data = {'field': 'value'} json = jsonutils.dumps(data, cls=common_utils.PKIEncoder) - expected_json = b'{"field":"value"}' + expected_json = '{"field":"value"}' self.assertEqual(expected_json, json) |