From 72744c9464309bc3fd402303c8f080801591e2ea Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Mon, 7 Dec 2020 09:47:48 -0500 Subject: [PATCH] more docstrings and properly support (and use) encoding=None throughout --- src/allmydata/test/cli/common.py | 21 ++++++++++++++++++ src/allmydata/test/cli/test_alias.py | 18 ++++++++++++++-- src/allmydata/test/common_util.py | 32 ++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/allmydata/test/cli/common.py b/src/allmydata/test/cli/common.py index 3da959604..d90b6a39f 100644 --- a/src/allmydata/test/cli/common.py +++ b/src/allmydata/test/cli/common.py @@ -10,7 +10,24 @@ def parse_options(basedir, command, args): return o class CLITestMixin(ReallyEqualMixin): + """ + A mixin for use with ``GridTestMixin`` to execute CLI commands against + nodes created by methods of that mixin. + """ def do_cli_unicode(self, verb, argv, client_num=0, **kwargs): + """ + Run a Tahoe-LAFS CLI command. + + :param verb: See ``run_cli_unicode``. + + :param argv: See ``run_cli_unicode``. + + :param int client_num: The number of the ``GridTestMixin``-created + node against which to execute the command. + + :param kwargs: Additional keyword arguments to pass to + ``run_cli_unicode``. + """ # client_num is used to execute client CLI commands on a specific # client. client_dir = self.get_clientdir(i=client_num) @@ -19,6 +36,10 @@ class CLITestMixin(ReallyEqualMixin): def do_cli(self, verb, *args, **kwargs): + """ + Like ``do_cli_unicode`` but work with ``bytes`` everywhere instead of + ``unicode``. + """ # client_num is used to execute client CLI commands on a specific # client. client_num = kwargs.pop("client_num", 0) diff --git a/src/allmydata/test/cli/test_alias.py b/src/allmydata/test/cli/test_alias.py index 67f438fa5..635ed0aba 100644 --- a/src/allmydata/test/cli/test_alias.py +++ b/src/allmydata/test/cli/test_alias.py @@ -20,10 +20,13 @@ class ListAlias(GridTestMixin, CLITestMixin, unittest.TestCase): :param unicode alias: The alias to try to create. - :param str encoding: The name of an encoding to force the + :param NoneType|str encoding: The name of an encoding to force the ``create-alias`` implementation to use. This simulates the effects of setting LANG and doing other locale-foolishness without actually having to mess with this process's global locale state. + If this is ``None`` then the encoding used will be ascii but the + stdio objects given to the code under test will not declare any + encoding (this is like Python 2 when stdio is not a tty). :return Deferred: A Deferred that fires with success if the alias can be created and that creation is reported on stdout appropriately @@ -38,7 +41,7 @@ class ListAlias(GridTestMixin, CLITestMixin, unittest.TestCase): # monkey-patch that value to our desired value here. This is the code # that most directly takes the place of messing with LANG or the # locale module. - self.patch(encodingutil, "io_encoding", encoding) + self.patch(encodingutil, "io_encoding", encoding or "ascii") rc, stdout, stderr = yield self.do_cli_unicode( u"create-alias", @@ -74,6 +77,17 @@ class ListAlias(GridTestMixin, CLITestMixin, unittest.TestCase): self.assertIn(u"readonly", data) + def test_list_none(self): + """ + An alias composed of all ASCII-encodeable code points can be created when + stdio aren't clearly marked with an encoding. + """ + return self._test_list( + u"tahoe", + encoding=None, + ) + + def test_list_ascii(self): """ An alias composed of all ASCII-encodeable code points can be created when diff --git a/src/allmydata/test/common_util.py b/src/allmydata/test/common_util.py index c6491d72e..c08dc03d5 100644 --- a/src/allmydata/test/common_util.py +++ b/src/allmydata/test/common_util.py @@ -91,6 +91,24 @@ def run_cli_bytes(verb, *args, **kwargs): def run_cli_unicode(verb, argv, nodeargs=None, stdin=None, encoding=None): + """ + Run a Tahoe-LAFS CLI command. + + :param unicode verb: The command to run. For example, ``u"create-node"``. + + :param [unicode] argv: The arguments to pass to the command. For example, + ``[u"--hostname=localhost"]``. + + :param [unicode] nodeargs: Extra arguments to pass to the Tahoe executable + before ``verb``. + + :param unicode stdin: Text to pass to the command via stdin. + + :param NoneType|str encoding: The name of an encoding to use for all + bytes/unicode conversions necessary *and* the encoding to cause stdio + to declare with its ``encoding`` attribute. ``None`` means ASCII will + be used and no declaration will be made at all. + """ if nodeargs is None: nodeargs = [] precondition( @@ -100,19 +118,21 @@ def run_cli_unicode(verb, argv, nodeargs=None, stdin=None, encoding=None): nodeargs=nodeargs, argv=argv, ) + codec = encoding or "ascii" + encode = lambda t: None if t is None else t.encode(codec) d = run_cli_bytes( - verb.encode(encoding), - nodeargs=list(arg.encode(encoding) for arg in nodeargs), - stdin=stdin, + encode(verb), + nodeargs=list(encode(arg) for arg in nodeargs), + stdin=encode(stdin), encoding=encoding, - *list(arg.encode(encoding) for arg in argv) + *list(encode(arg) for arg in argv) ) def maybe_decode(result): code, stdout, stderr = result if isinstance(stdout, bytes): - stdout = stdout.decode(encoding) + stdout = stdout.decode(codec) if isinstance(stderr, bytes): - stderr = stderr.decode(encoding) + stderr = stderr.decode(codec) return code, stdout, stderr d.addCallback(maybe_decode) return d