Convert dict keys received in _ClientChannel from byte to str

When executing in debug mode, the arguments passed to [1] are stored
in a dictionary populated with bytes instead of strings. When in [2]
"record" is created and updated [3], the values contained in "msg[1]"
are not updated in "record"

This patch converts all keys in byte format to string (Python 3).

[1] 130d7155c4/oslo_privsep/comm.py (L128)
[2] 130d7155c4/oslo_privsep/daemon.py (L210)
[3] b5409dacc4/Lib/logging/__init__.py (L415)

Change-Id: Idec9ecc9fcc8c5b6779e0194a16cd861c7895d7e
Closes-Bug: #1816804
This commit is contained in:
Rodolfo Alonso Hernandez 2019-02-20 16:40:44 +00:00
parent d84c76108b
commit c9cec8e87b
2 changed files with 38 additions and 1 deletions

View File

@ -59,6 +59,7 @@ import threading
import eventlet
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import encodeutils
from oslo_utils import importutils
import six
@ -207,7 +208,9 @@ class _ClientChannel(comm.ClientChannel):
def out_of_band(self, msg):
if msg[0] == Message.LOG:
# (LOG, LogRecord __dict__)
record = pylogging.makeLogRecord(msg[1])
message = {encodeutils.safe_decode(k): v
for k, v in msg[1].items()}
record = pylogging.makeLogRecord(message)
if LOG.isEnabledFor(record.levelno):
LOG.logger.handle(record)
else:

View File

@ -23,9 +23,11 @@ import time
from oslo_log import formatters
from oslo_log import log as logging
from oslotest import base
import six
import testtools
from oslo_privsep import capabilities
from oslo_privsep import comm
from oslo_privsep import daemon
from oslo_privsep.tests import testctx
@ -178,3 +180,35 @@ class WithContextTest(testctx.TestContextTestCase):
self.assertRaisesRegex(
NameError, 'undecorated not exported',
testctx.context._wrap, undecorated)
class ClientChannelTestCase(base.BaseTestCase):
DICT = {
'string_1': ('tuple_1', six.b('tuple_2')),
six.b('byte_1'): ['list_1', 'list_2'],
}
EXPECTED = {
'string_1': ('tuple_1', six.b('tuple_2')),
'byte_1': ['list_1', 'list_2'],
}
def setUp(self):
super(ClientChannelTestCase, self).setUp()
with mock.patch.object(comm.ClientChannel, '__init__'), \
mock.patch.object(daemon._ClientChannel, 'exchange_ping'):
self.client_channel = daemon._ClientChannel(mock.ANY)
def test_out_of_band_log_message(self):
message = [daemon.Message.LOG, self.DICT]
with mock.patch.object(pylogging, 'makeLogRecord') as mock_make_log, \
mock.patch.object(daemon.LOG, 'isEnabledFor',
return_value=False):
self.client_channel.out_of_band(message)
mock_make_log.assert_called_once_with(self.EXPECTED)
def test_out_of_band_not_log_message(self):
with mock.patch.object(daemon.LOG, 'warning') as mock_warning:
self.client_channel.out_of_band([daemon.Message.PING])
mock_warning.assert_called_once()