Browse Source

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
Rodolfo Alonso Hernandez 1 month ago
parent
commit
c9cec8e87b
2 changed files with 38 additions and 1 deletions
  1. 4
    1
      oslo_privsep/daemon.py
  2. 34
    0
      oslo_privsep/tests/test_daemon.py

+ 4
- 1
oslo_privsep/daemon.py View File

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

+ 34
- 0
oslo_privsep/tests/test_daemon.py View File

@@ -23,9 +23,11 @@ import time
23 23
 from oslo_log import formatters
24 24
 from oslo_log import log as logging
25 25
 from oslotest import base
26
+import six
26 27
 import testtools
27 28
 
28 29
 from oslo_privsep import capabilities
30
+from oslo_privsep import comm
29 31
 from oslo_privsep import daemon
30 32
 from oslo_privsep.tests import testctx
31 33
 
@@ -178,3 +180,35 @@ class WithContextTest(testctx.TestContextTestCase):
178 180
         self.assertRaisesRegex(
179 181
             NameError, 'undecorated not exported',
180 182
             testctx.context._wrap, undecorated)
183
+
184
+
185
+class ClientChannelTestCase(base.BaseTestCase):
186
+
187
+    DICT = {
188
+        'string_1': ('tuple_1', six.b('tuple_2')),
189
+        six.b('byte_1'): ['list_1', 'list_2'],
190
+    }
191
+
192
+    EXPECTED = {
193
+        'string_1': ('tuple_1', six.b('tuple_2')),
194
+        'byte_1': ['list_1', 'list_2'],
195
+    }
196
+
197
+    def setUp(self):
198
+        super(ClientChannelTestCase, self).setUp()
199
+        with mock.patch.object(comm.ClientChannel, '__init__'), \
200
+                mock.patch.object(daemon._ClientChannel, 'exchange_ping'):
201
+            self.client_channel = daemon._ClientChannel(mock.ANY)
202
+
203
+    def test_out_of_band_log_message(self):
204
+        message = [daemon.Message.LOG, self.DICT]
205
+        with mock.patch.object(pylogging, 'makeLogRecord') as mock_make_log, \
206
+                mock.patch.object(daemon.LOG, 'isEnabledFor',
207
+                                  return_value=False):
208
+            self.client_channel.out_of_band(message)
209
+            mock_make_log.assert_called_once_with(self.EXPECTED)
210
+
211
+    def test_out_of_band_not_log_message(self):
212
+        with mock.patch.object(daemon.LOG, 'warning') as mock_warning:
213
+            self.client_channel.out_of_band([daemon.Message.PING])
214
+            mock_warning.assert_called_once()

Loading…
Cancel
Save