From f42c1aa8637cf878ecc8463c5006617adb043884 Mon Sep 17 00:00:00 2001 From: Jana Cupova Date: May 03 2022 10:47:47 +0000 Subject: Add as_string option to showOpts for raw string or dict output Fixes: https://pagure.io/koji/issue/3312 --- diff --git a/hub/kojihub.py b/hub/kojihub.py index 54c1fea..398961d 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -10859,10 +10859,17 @@ class RootExports(object): return None return context.session.session_data - def showOpts(self): - """Returns hub options""" + def showOpts(self, as_string=True): + """Returns hub options + + :param bool as_string: if True (default) returns hub options as raw string, + if False, returns hub options as dict + """ context.session.assertPerm('admin') - return "%r" % context.opts + if as_string: + return "%r" % context.opts + else: + return context.opts def getEvent(self, id): """ diff --git a/koji/xmlrpcplus.py b/koji/xmlrpcplus.py index 0ca2793..6a3ab1f 100644 --- a/koji/xmlrpcplus.py +++ b/koji/xmlrpcplus.py @@ -6,6 +6,7 @@ from __future__ import absolute_import import types +import re import six import six.moves.xmlrpc_client as xmlrpc_client @@ -50,6 +51,13 @@ class ExtendedMarshaller(xmlrpc_client.Marshaller): return xmlrpc_client.Marshaller.dump_int(self, value, write) dispatch[int] = dump_int + def dump_re(self, value, write): + return self._dump(repr(value), write) + if six.PY2: + dispatch[re._pattern_type] = dump_re + else: + dispatch[re.Pattern] = dump_re + if six.PY2: ExtendedMarshaller.dispatch[long] = ExtendedMarshaller.dump_int # noqa: F821 diff --git a/tests/test_hub/test_show_opts.py b/tests/test_hub/test_show_opts.py new file mode 100644 index 0000000..53ce4d3 --- /dev/null +++ b/tests/test_hub/test_show_opts.py @@ -0,0 +1,31 @@ +import mock +import unittest + +import re +import kojihub + +UP = kojihub.UpdateProcessor +IP = kojihub.InsertProcessor + + +class TestShowOpts(unittest.TestCase): + def setUp(self): + self.maxDiff = None + self.context = mock.patch('kojihub.context').start() + self.context.session.assertPerm = mock.MagicMock() + self.exports = kojihub.RootExports() + self.context.opts = {'MaxNameLengthInternal': 15, + 'RegexNameInternal.compiled': re.compile('^[A-Za-z0-9/_.+-]+$')} + + def tearDown(self): + mock.patch.stopall() + + def test_as_string(self): + rv = self.exports.showOpts() + self.assertEqual(rv, "{'MaxNameLengthInternal': 15, " + "'RegexNameInternal.compiled': re.compile('^[A-Za-z0-9/_.+-]+$')}") + + def test_as_dict(self): + rv = self.exports.showOpts(as_string=False) + self.assertEqual(rv, {'MaxNameLengthInternal': 15, + 'RegexNameInternal.compiled': re.compile('^[A-Za-z0-9/_.+-]+$')}) diff --git a/tests/test_lib/test_xmlrpcplus.py b/tests/test_lib/test_xmlrpcplus.py index 43974ef..af7ff30 100644 --- a/tests/test_lib/test_xmlrpcplus.py +++ b/tests/test_lib/test_xmlrpcplus.py @@ -2,6 +2,7 @@ from __future__ import absolute_import from six.moves import range import unittest +import re from six.moves import xmlrpc_client from koji import xmlrpcplus @@ -9,19 +10,21 @@ from koji import xmlrpcplus class TestDump(unittest.TestCase): + maxDiff = None + standard_data = [ - "Hello World", - 5, - 5.5, - None, - True, - False, - u'Hævē s°mə ŭnıčođė', - [1], - {"a": 1}, - ["fnord"], - {"a": ["b", 1, 2, None], "b": {"c": 1}}, - ] + "Hello World", + 5, + 5.5, + None, + True, + False, + u'Hævē s°mə ŭnıčođė', + [1], + {"a": 1}, + ["fnord"], + {"a": ["b", 1, 2, None], "b": {"c": 1}}, + ] def test_call(self): method = 'my_rpc_method' @@ -69,11 +72,11 @@ class TestDump(unittest.TestCase): self.assertEqual(method, None) long_data = [ - 2 ** 63 - 1, - -(2 ** 63), - [2**n - 1 for n in range(64)], - {"a": [2 ** 63 - 23, 5], "b": 2**63 - 42}, - ] + 2 ** 63 - 1, + -(2 ** 63), + [2**n - 1 for n in range(64)], + {"a": [2 ** 63 - 23, 5], "b": 2**63 - 42}, + ] def test_i8(self): for value in self.long_data: @@ -90,6 +93,24 @@ class TestDump(unittest.TestCase): self.assertEqual(params, value) self.assertEqual(method, method) + def test_dict_data(self): + dict_data = {'MaxNameLengthInternal': 15, + 'RegexNameInternal.compiled': re.compile('^[A-Za-z0-9/_.+-]+$')} + dist_data_output = ({'MaxNameLengthInternal': 15, + 'RegexNameInternal.compiled': "re.compile('^[A-Za-z0-9/_.+-]+$')"},) + dict_data = (dict_data,) + enc = xmlrpcplus.dumps(dict_data, methodresponse=1) + params, method = xmlrpc_client.loads(enc) + self.assertEqual(params, dist_data_output) + self.assertEqual(method, None) + # and as a call + method = "foomethod" + value = tuple(self.long_data) + enc = xmlrpcplus.dumps(value, methodname=method) + params, method = xmlrpc_client.loads(enc) + self.assertEqual(params, value) + self.assertEqual(method, method) + def test_overflow(self): value = (2**64,) with self.assertRaises(OverflowError): @@ -133,10 +154,10 @@ class TestDump(unittest.TestCase): def test_encoding(self): data = [ - 45, - ["hello", "world"], - {"a": 5.5, "b": [None]}, - ] + 45, + ["hello", "world"], + {"a": 5.5, "b": [None]}, + ] for value in data: value = (value,) enc = xmlrpcplus.dumps(value, methodresponse=1, encoding='us-ascii') @@ -149,14 +170,14 @@ class TestDump(unittest.TestCase): def test_no_i8(self): # we shouldn't use i8 if we don't have to data = [ - 23, - 42, - -1024, - 2 ** 31 - 1, - -2 ** 31, - [2**31 -1], - {"a": -2 ** 31, "b": 3.14}, - ] + 23, + 42, + -1024, + 2 ** 31 - 1, + -2 ** 31, + [2**31 - 1], + {"a": -2 ** 31, "b": 3.14}, + ] for value in data: value = (value,) enc = xmlrpcplus.dumps(value, methodresponse=1, encoding='us-ascii')