Changeset 624916e in trunk
- Timestamp:
- 2020-12-11T00:47:47Z (4 years ago)
- Branches:
- master
- Children:
- 51e5067
- Parents:
- 8b890d25 (diff), d096cc54 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - git-author:
- Jean-Paul Calderone <exarkun@…> (2020-12-11 00:47:47)
- git-committer:
- GitHub <noreply@…> (2020-12-11 00:47:47)
- Files:
-
- 3 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified docs/configuration.rst ¶
r8b890d25 r624916e 76 76 ========== 77 77 78 A node can be a client/server , an introducer, or a statistics gatherer.78 A node can be a client/server or an introducer. 79 79 80 80 Client/server nodes provide one or more of the following services: … … 593 593 If provided, the node will attempt to connect to and use the given helper 594 594 for uploads. See :doc:`helper` for details. 595 596 ``stats_gatherer.furl = (FURL string, optional)``597 598 If provided, the node will connect to the given stats gatherer and599 provide it with operational statistics.600 595 601 596 ``shares.needed = (int, optional) aka "k", default 3`` -
TabularUnified docs/stats.rst ¶
r8b890d25 r624916e 243 243 sometimes be negative due to wraparound of the kernel's counter. 244 244 245 **stats.load_monitor.\***246 247 When enabled, the "load monitor" continually schedules a one-second248 callback, and measures how late the response is. This estimates system load249 (if the system is idle, the response should be on time). This is only250 enabled if a stats-gatherer is configured.251 252 avg_load253 average "load" value (seconds late) over the last minute254 255 max_load256 maximum "load" value over the last minute257 258 245 259 246 Using Munin To Graph Stats Values -
TabularUnified newsfragments/3549.removed ¶
r8b890d25 r624916e 1 The stats gatherer has been removed. The ``[client]stats_gatherer.furl`` configuration item in ``tahoe.cfg`` is no longer allowed.1 The stats gatherer, broken since at least Tahoe-LAFS 1.13.0, has been removed. The ``[client]stats_gatherer.furl`` configuration item in ``tahoe.cfg`` is no longer allowed. The Tahoe-LAFS project recommends using a third-party metrics aggregation tool instead. -
TabularUnified src/allmydata/immutable/checker.py ¶
r8b890d25 r624916e 1 """ 2 Ported to Python 3. 3 """ 4 from __future__ import absolute_import 5 from __future__ import division 6 from __future__ import print_function 7 from __future__ import unicode_literals 8 9 from future.utils import PY2 10 if PY2: 11 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 12 1 13 from zope.interface import implementer 2 14 from twisted.internet import defer -
TabularUnified src/allmydata/immutable/repairer.py ¶
r8b890d25 r624916e 1 """ 2 Ported to Python 3. 3 """ 4 from __future__ import absolute_import 5 from __future__ import division 6 from __future__ import print_function 7 from __future__ import unicode_literals 8 9 from future.utils import PY2 10 if PY2: 11 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 12 1 13 from zope.interface import implementer 2 14 from twisted.internet import defer -
TabularUnified src/allmydata/introducer/client.py ¶
r8b890d25 r624916e 1 from past.builtins import unicode, long 1 """ 2 Ported to Python 3. 3 """ 4 from __future__ import absolute_import 5 from __future__ import division 6 from __future__ import print_function 7 from __future__ import unicode_literals 8 9 from future.utils import PY2 10 if PY2: 11 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 12 from past.builtins import long 13 2 14 from six import ensure_text 3 15 … … 28 40 sequencer, cache_filepath): 29 41 self._tub = tub 30 if isinstance(introducer_furl, unicode):42 if isinstance(introducer_furl, str): 31 43 introducer_furl = introducer_furl.encode("utf-8") 32 44 self.introducer_furl = introducer_furl 33 45 34 assert type(nickname) is unicode46 assert isinstance(nickname, str) 35 47 self._nickname = nickname 36 48 self._my_version = my_version … … 115 127 def _save_announcements(self): 116 128 announcements = [] 117 for _, value in self._inbound_announcements.items():129 for value in self._inbound_announcements.values(): 118 130 ann, key_s, time_stamp = value 119 131 # On Python 2, bytes strings are encoded into YAML Unicode strings. … … 126 138 announcements.append(server_params) 127 139 announcement_cache_yaml = yamlutil.safe_dump(announcements) 128 if isinstance(announcement_cache_yaml, unicode):140 if isinstance(announcement_cache_yaml, str): 129 141 announcement_cache_yaml = announcement_cache_yaml.encode("utf-8") 130 142 self._cache_filepath.setContent(announcement_cache_yaml) … … 171 183 self._subscribed_service_names.add(service_name) 172 184 self._maybe_subscribe() 173 for index,(ann,key_s,when) in self._inbound_announcements.items():185 for index,(ann,key_s,when) in list(self._inbound_announcements.items()): 174 186 precondition(isinstance(key_s, bytes), key_s) 175 187 servicename = index[0] … … 216 228 217 229 # publish all announcements with the new seqnum and nonce 218 for service_name,ann_d in self._outbound_announcements.items():230 for service_name,ann_d in list(self._outbound_announcements.items()): 219 231 ann_d["seqnum"] = current_seqnum 220 232 ann_d["nonce"] = current_nonce … … 228 240 return 229 241 # this re-publishes everything. The Introducer ignores duplicates 230 for ann_t in self._published_announcements.values():242 for ann_t in list(self._published_announcements.values()): 231 243 self._debug_counts["outbound_message"] += 1 232 244 self._debug_outstanding += 1 … … 268 280 # for ASCII values, simplejson might give us unicode *or* bytes 269 281 if "nickname" in ann and isinstance(ann["nickname"], bytes): 270 ann["nickname"] = unicode(ann["nickname"])282 ann["nickname"] = str(ann["nickname"]) 271 283 nick_s = ann.get("nickname",u"").encode("utf-8") 272 284 lp2 = self.log(format="announcement for nickname '%(nick)s', service=%(svc)s: %(ann)s", -
TabularUnified src/allmydata/introducer/common.py ¶
r8b890d25 r624916e 1 """ 2 Ported to Python 3. 3 """ 4 from __future__ import absolute_import 5 from __future__ import division 6 from __future__ import print_function 7 from __future__ import unicode_literals 8 9 from future.utils import PY2 10 if PY2: 11 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 12 1 13 import re 2 14 from allmydata.crypto.util import remove_prefix -
TabularUnified src/allmydata/introducer/server.py ¶
r8b890d25 r624916e 1 """ 2 Ported to Python 3. 3 """ 4 5 from __future__ import absolute_import 6 from __future__ import division 7 from __future__ import print_function 8 from __future__ import unicode_literals 9 10 11 from future.utils import PY2 12 if PY2: 13 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 1 14 from past.builtins import long 2 from six import ensure_ str, ensure_text15 from six import ensure_text 3 16 4 17 import time, os.path, textwrap … … 158 171 # expected keys are: version, nickname, app-versions, my-version, 159 172 # oldest-supported 160 self._subscribers = {}173 self._subscribers = dictutil.UnicodeKeyDict({}) 161 174 162 175 self._debug_counts = {"inbound_message": 0, … … 182 195 """Return a list of AnnouncementDescriptor for all announcements""" 183 196 announcements = [] 184 for (index, (_, canary, ann, when)) in self._announcements.items():197 for (index, (_, canary, ann, when)) in list(self._announcements.items()): 185 198 ad = AnnouncementDescriptor(when, index, canary, ann) 186 199 announcements.append(ad) … … 190 203 """Return a list of SubscriberDescriptor objects for all subscribers""" 191 204 s = [] 192 for service_name, subscriptions in self._subscribers.items():193 for rref,(subscriber_info,when) in subscriptions.items():205 for service_name, subscriptions in list(self._subscribers.items()): 206 for rref,(subscriber_info,when) in list(subscriptions.items()): 194 207 # note that if the subscriber didn't do Tub.setLocation, 195 208 # tubid will be None. Also, subscribers do not tell us which … … 282 295 self.log("introducer: subscription[%s] request at %s" 283 296 % (service_name, subscriber), umid="U3uzLg") 284 service_name = ensure_ str(service_name)297 service_name = ensure_text(service_name) 285 298 subscriber_info = dictutil.UnicodeKeyDict({ 286 299 ensure_text(k): v for (k, v) in subscriber_info.items() … … 308 321 subscriber.notifyOnDisconnect(_remove) 309 322 323 # Make sure types are correct: 324 for k in self._announcements: 325 assert isinstance(k[0], type(service_name)) 326 310 327 # now tell them about any announcements they're interested in 311 assert {type(service_name)}.issuperset(312 set(type(k[0]) for k in self._announcements)), (313 service_name, self._announcements.keys()314 )315 328 announcements = set( [ ann_t 316 329 for idx,(ann_t,canary,ann,when) -
TabularUnified src/allmydata/scripts/tahoe_add_alias.py ¶
r8b890d25 r624916e 1 1 from __future__ import print_function 2 from __future__ import unicode_literals 2 3 3 4 import os.path … … 11 12 from allmydata.scripts.common import get_aliases 12 13 from allmydata.util.fileutil import move_into_place 13 from allmydata.util.encodingutil import unicode_to_output, quote_output14 from allmydata.util.encodingutil import quote_output, quote_output_u 14 15 15 16 … … 49 50 old_aliases = get_aliases(nodedir) 50 51 if alias in old_aliases: 51 print("Alias %s already exists!" % quote_output(alias), file=stderr)52 show_output(stderr, "Alias {alias} already exists!", alias=alias) 52 53 return 1 53 54 aliasfile = os.path.join(nodedir, "private", "aliases") … … 55 56 56 57 add_line_to_aliasfile(aliasfile, alias, cap) 57 58 print("Alias %s added" % quote_output(alias), file=stdout) 58 show_output(stdout, "Alias {alias} added", alias=alias) 59 59 return 0 60 60 … … 76 76 old_aliases = get_aliases(nodedir) 77 77 if alias in old_aliases: 78 print("Alias %s already exists!" % quote_output(alias), file=stderr)78 show_output(stderr, "Alias {alias} already exists!", alias=alias) 79 79 return 1 80 80 … … 94 94 95 95 add_line_to_aliasfile(aliasfile, alias, new_uri) 96 show_output(stdout, "Alias {alias} created", alias=alias) 97 return 0 96 98 97 print("Alias %s created" % (quote_output(alias),), file=stdout) 98 return 0 99 100 def show_output(fp, template, **kwargs): 101 """ 102 Print to just about anything. 103 104 :param fp: A file-like object to which to print. This handles the case 105 where ``fp`` declares a support encoding with the ``encoding`` 106 attribute (eg sys.stdout on Python 3). It handles the case where 107 ``fp`` declares no supported encoding via ``None`` for its 108 ``encoding`` attribute (eg sys.stdout on Python 2 when stdout is not a 109 tty). It handles the case where ``fp`` declares an encoding that does 110 not support all of the characters in the output by forcing the 111 "namereplace" error handler. It handles the case where there is no 112 ``encoding`` attribute at all (eg StringIO.StringIO) by writing 113 utf-8-encoded bytes. 114 """ 115 assert isinstance(template, unicode) 116 117 # On Python 3 fp has an encoding attribute under all real usage. On 118 # Python 2, the encoding attribute is None if stdio is not a tty. The 119 # test suite often passes StringIO which has no such attribute. Make 120 # allowances for this until the test suite is fixed and Python 2 is no 121 # more. 122 try: 123 encoding = fp.encoding or "utf-8" 124 except AttributeError: 125 has_encoding = False 126 encoding = "utf-8" 127 else: 128 has_encoding = True 129 130 output = template.format(**{ 131 k: quote_output_u(v, encoding=encoding) 132 for (k, v) 133 in kwargs.items() 134 }) 135 safe_output = output.encode(encoding, "namereplace") 136 if has_encoding: 137 safe_output = safe_output.decode(encoding) 138 print(safe_output, file=fp) 99 139 100 140 … … 112 152 113 153 154 def _escape_format(t): 155 """ 156 _escape_format(t).format() == t 157 158 :param unicode t: The text to escape. 159 """ 160 return t.replace("{", "{{").replace("}", "}}") 161 162 114 163 def list_aliases(options): 115 nodedir = options['node-directory'] 116 stdout = options.stdout 117 stderr = options.stderr 118 119 data = _get_alias_details(nodedir) 120 121 max_width = max([len(quote_output(name)) for name in data.keys()] + [0]) 122 fmt = "%" + str(max_width) + "s: %s" 123 rc = 0 164 """ 165 Show aliases that exist. 166 """ 167 data = _get_alias_details(options['node-directory']) 124 168 125 169 if options['json']: 126 try: 127 # XXX why are we presuming utf-8 output? 128 print(json.dumps(data, indent=4).decode('utf-8'), file=stdout) 129 except (UnicodeEncodeError, UnicodeDecodeError): 130 print(json.dumps(data, indent=4), file=stderr) 131 rc = 1 170 output = _escape_format(json.dumps(data, indent=4).decode("ascii")) 132 171 else: 133 for name, details in data.items(): 134 dircap = details['readonly'] if options['readonly-uri'] else details['readwrite'] 135 try: 136 print(fmt % (unicode_to_output(name), unicode_to_output(dircap.decode('utf-8'))), file=stdout) 137 except (UnicodeEncodeError, UnicodeDecodeError): 138 print(fmt % (quote_output(name), quote_output(dircap)), file=stderr) 139 rc = 1 172 def dircap(details): 173 return ( 174 details['readonly'] 175 if options['readonly-uri'] 176 else details['readwrite'] 177 ).decode("utf-8") 140 178 141 if rc == 1: 142 print("\nThis listing included aliases or caps that could not be converted to the terminal" \ 143 "\noutput encoding. These are shown using backslash escapes and in quotes.", file=stderr) 144 return rc 179 def format_dircap(name, details): 180 return fmt % (name, dircap(details)) 181 182 max_width = max([len(quote_output(name)) for name in data.keys()] + [0]) 183 fmt = "%" + str(max_width) + "s: %s" 184 output = "\n".join(list( 185 format_dircap(name, details) 186 for name, details 187 in data.items() 188 )) 189 190 if output: 191 # Show whatever we computed. Skip this if there is no output to avoid 192 # a spurious blank line. 193 show_output(options.stdout, output) 194 195 return 0 -
TabularUnified src/allmydata/storage_client.py ¶
r8b890d25 r624916e 562 562 563 563 *nickname* is optional. 564 565 The furl will be a Unicode string on Python 3; on Python 2 it will be 566 either a native (bytes) string or a Unicode string. 564 567 """ 565 568 furl = furl.encode("utf-8") -
TabularUnified src/allmydata/test/cli/common.py ¶
r8b890d25 r624916e 1 1 from ...util.encodingutil import unicode_to_argv 2 2 from ...scripts import runner 3 from ..common_util import ReallyEqualMixin, run_cli 3 from ..common_util import ReallyEqualMixin, run_cli, run_cli_unicode 4 4 5 5 def parse_options(basedir, command, args): … … 11 11 12 12 class CLITestMixin(ReallyEqualMixin): 13 def do_cli(self, verb, *args, **kwargs): 13 """ 14 A mixin for use with ``GridTestMixin`` to execute CLI commands against 15 nodes created by methods of that mixin. 16 """ 17 def do_cli_unicode(self, verb, argv, client_num=0, **kwargs): 18 """ 19 Run a Tahoe-LAFS CLI command. 20 21 :param verb: See ``run_cli_unicode``. 22 23 :param argv: See ``run_cli_unicode``. 24 25 :param int client_num: The number of the ``GridTestMixin``-created 26 node against which to execute the command. 27 28 :param kwargs: Additional keyword arguments to pass to 29 ``run_cli_unicode``. 30 """ 14 31 # client_num is used to execute client CLI commands on a specific 15 32 # client. 16 client_num = kwargs.get("client_num", 0) 33 client_dir = self.get_clientdir(i=client_num) 34 nodeargs = [ u"--node-directory", client_dir ] 35 return run_cli_unicode(verb, argv, nodeargs=nodeargs, **kwargs) 36 37 38 def do_cli(self, verb, *args, **kwargs): 39 """ 40 Like ``do_cli_unicode`` but work with ``bytes`` everywhere instead of 41 ``unicode``. 42 43 Where possible, prefer ``do_cli_unicode``. 44 """ 45 # client_num is used to execute client CLI commands on a specific 46 # client. 47 client_num = kwargs.pop("client_num", 0) 17 48 client_dir = unicode_to_argv(self.get_clientdir(i=client_num)) 18 nodeargs = [ "--node-directory", client_dir ]19 return run_cli(verb, nodeargs=nodeargs, *args, **kwargs)49 nodeargs = [ b"--node-directory", client_dir ] 50 return run_cli(verb, *args, nodeargs=nodeargs, **kwargs) -
TabularUnified src/allmydata/test/cli/test_alias.py ¶
r8b890d25 r624916e 1 1 import json 2 from mock import patch3 2 4 3 from twisted.trial import unittest 5 4 from twisted.internet.defer import inlineCallbacks 6 5 7 from allmydata.util.encodingutil import unicode_to_argv8 6 from allmydata.scripts.common import get_aliases 9 7 from allmydata.test.no_network import GridTestMixin 10 8 from .common import CLITestMixin 11 from ..common_util import skip_if_cannot_represent_argv9 from allmydata.util import encodingutil 12 10 13 11 # see also test_create_alias … … 16 14 17 15 @inlineCallbacks 18 def test_list(self): 19 self.basedir = "cli/ListAlias/test_list" 16 def _check_create_alias(self, alias, encoding): 17 """ 18 Verify that ``tahoe create-alias`` can be used to create an alias named 19 ``alias`` when argv is encoded using ``encoding``. 20 21 :param unicode alias: The alias to try to create. 22 23 :param NoneType|str encoding: The name of an encoding to force the 24 ``create-alias`` implementation to use. This simulates the 25 effects of setting LANG and doing other locale-foolishness without 26 actually having to mess with this process's global locale state. 27 If this is ``None`` then the encoding used will be ascii but the 28 stdio objects given to the code under test will not declare any 29 encoding (this is like Python 2 when stdio is not a tty). 30 31 :return Deferred: A Deferred that fires with success if the alias can 32 be created and that creation is reported on stdout appropriately 33 encoded or with failure if something goes wrong. 34 """ 35 self.basedir = self.mktemp() 20 36 self.set_up_grid(oneshare=True) 21 37 22 rc, stdout, stderr = yield self.do_cli( 23 "create-alias", 24 unicode_to_argv(u"tahoe"), 38 # We can pass an encoding into the test utilities to invoke the code 39 # under test but we can't pass such a parameter directly to the code 40 # under test. Instead, that code looks at io_encoding. So, 41 # monkey-patch that value to our desired value here. This is the code 42 # that most directly takes the place of messing with LANG or the 43 # locale module. 44 self.patch(encodingutil, "io_encoding", encoding or "ascii") 45 46 rc, stdout, stderr = yield self.do_cli_unicode( 47 u"create-alias", 48 [alias], 49 encoding=encoding, 25 50 ) 26 51 27 self.failUnless(unicode_to_argv(u"Alias 'tahoe' created") in stdout) 28 self.failIf(stderr) 52 # Make sure the result of the create-alias command is as we want it to 53 # be. 54 self.assertEqual(u"Alias '{}' created\n".format(alias), stdout) 55 self.assertEqual("", stderr) 56 self.assertEqual(0, rc) 57 58 # Make sure it had the intended side-effect, too - an alias created in 59 # the node filesystem state. 29 60 aliases = get_aliases(self.get_clientdir()) 30 self. failUnless(u"tahoe" inaliases)31 self. failUnless(aliases[u"tahoe"].startswith("URI:DIR2:"))61 self.assertIn(alias, aliases) 62 self.assertTrue(aliases[alias].startswith(u"URI:DIR2:")) 32 63 33 rc, stdout, stderr = yield self.do_cli("list-aliases", "--json") 64 # And inspect the state via the user interface list-aliases command 65 # too. 66 rc, stdout, stderr = yield self.do_cli_unicode( 67 u"list-aliases", 68 [u"--json"], 69 encoding=encoding, 70 ) 34 71 35 72 self.assertEqual(0, rc) 36 73 data = json.loads(stdout) 37 self.assertIn( u"tahoe", data)38 data = data[ u"tahoe"]39 self.assertIn( "readwrite", data)40 self.assertIn( "readonly", data)74 self.assertIn(alias, data) 75 data = data[alias] 76 self.assertIn(u"readwrite", data) 77 self.assertIn(u"readonly", data) 41 78 42 @inlineCallbacks 43 def test_list_ unicode_mismatch_json(self):79 80 def test_list_none(self): 44 81 """ 45 pretty hack-y test, but we want to cover the 'except' on Unicode 46 errors paths and I can't come up with a nicer way to trigger 47 this 82 An alias composed of all ASCII-encodeable code points can be created when 83 stdio aren't clearly marked with an encoding. 48 84 """ 49 self.basedir = "cli/ListAlias/test_list_unicode_mismatch_json" 50 skip_if_cannot_represent_argv(u"tahoe\u263A") 51 self.set_up_grid(oneshare=True) 52 53 rc, stdout, stderr = yield self.do_cli( 54 "create-alias", 55 unicode_to_argv(u"tahoe\u263A"), 85 return self._check_create_alias( 86 u"tahoe", 87 encoding=None, 56 88 ) 57 89 58 self.failUnless(unicode_to_argv(u"Alias 'tahoe\u263A' created") in stdout)59 self.failIf(stderr)60 90 61 booms = [] 62 63 def boom(out, indent=4): 64 if not len(booms): 65 booms.append(out) 66 raise UnicodeEncodeError("foo", u"foo", 3, 5, "foo") 67 return str(out) 68 69 with patch("allmydata.scripts.tahoe_add_alias.json.dumps", boom): 70 aliases = get_aliases(self.get_clientdir()) 71 self.failUnless(u"tahoe\u263A" in aliases) 72 self.failUnless(aliases[u"tahoe\u263A"].startswith("URI:DIR2:")) 73 74 rc, stdout, stderr = yield self.do_cli("list-aliases", "--json") 75 76 self.assertEqual(1, rc) 77 self.assertIn("could not be converted", stderr) 78 79 @inlineCallbacks 80 def test_list_unicode_mismatch(self): 81 self.basedir = "cli/ListAlias/test_list_unicode_mismatch" 82 skip_if_cannot_represent_argv(u"tahoe\u263A") 83 self.set_up_grid(oneshare=True) 84 85 rc, stdout, stderr = yield self.do_cli( 86 "create-alias", 87 unicode_to_argv(u"tahoe\u263A"), 91 def test_list_ascii(self): 92 """ 93 An alias composed of all ASCII-encodeable code points can be created when 94 the active encoding is ASCII. 95 """ 96 return self._check_create_alias( 97 u"tahoe", 98 encoding="ascii", 88 99 ) 89 100 90 def boom(out):91 print("boom {}".format(out))92 return out93 raise UnicodeEncodeError("foo", u"foo", 3, 5, "foo")94 101 95 with patch("allmydata.scripts.tahoe_add_alias.unicode_to_output", boom): 96 self.failUnless(unicode_to_argv(u"Alias 'tahoe\u263A' created") in stdout) 97 self.failIf(stderr) 98 aliases = get_aliases(self.get_clientdir()) 99 self.failUnless(u"tahoe\u263A" in aliases) 100 self.failUnless(aliases[u"tahoe\u263A"].startswith("URI:DIR2:")) 102 def test_list_latin_1(self): 103 """ 104 An alias composed of all Latin-1-encodeable code points can be created 105 when the active encoding is Latin-1. 101 106 102 rc, stdout, stderr = yield self.do_cli("list-aliases") 107 This is very similar to ``test_list_utf_8`` but the assumption of 108 UTF-8 is nearly ubiquitous and explicitly exercising the codepaths 109 with a UTF-8-incompatible encoding helps flush out unintentional UTF-8 110 assumptions. 111 """ 112 return self._check_create_alias( 113 u"taho\N{LATIN SMALL LETTER E WITH ACUTE}", 114 encoding="latin-1", 115 ) 103 116 104 self.assertEqual(1, rc) 105 self.assertIn("could not be converted", stderr) 117 118 def test_list_utf_8(self): 119 """ 120 An alias composed of all UTF-8-encodeable code points can be created when 121 the active encoding is UTF-8. 122 """ 123 return self._check_create_alias( 124 u"tahoe\N{SNOWMAN}", 125 encoding="utf-8", 126 ) -
TabularUnified src/allmydata/test/cli/test_cp.py ¶
r8b890d25 r624916e 662 662 # a local directory without a specified file name. 663 663 # https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2027 664 self.basedir = "cli/Cp/ cp_verbose"664 self.basedir = "cli/Cp/ticket_2027" 665 665 self.set_up_grid(oneshare=True) 666 666 -
TabularUnified src/allmydata/test/common.py ¶
r8b890d25 r624916e 11 11 "skipIf", 12 12 ] 13 14 from past.builtins import chr as byteschr 13 15 14 16 import os, random, struct … … 1058 1060 offset = 0x0c+0x44+sharedatasize-1 1059 1061 1060 newdata = data[:offset] + chr(ord(data[offset])^0xFF) + data[offset+1:]1062 newdata = data[:offset] + byteschr(ord(data[offset:offset+1])^0xFF) + data[offset+1:] 1061 1063 if debug: 1062 1064 log.msg("testing: flipping all bits of byte at offset %d: %r, newdata: %r" % (offset, data[offset], newdata[offset])) … … 1086 1088 if debug: 1087 1089 log.msg("original data: %r" % (data,)) 1088 return data[:0x0c+0x221] + chr(ord(data[0x0c+0x221])^0x02) + data[0x0c+0x2210+1:]1090 return data[:0x0c+0x221] + byteschr(ord(data[0x0c+0x221:0x0c+0x221+1])^0x02) + data[0x0c+0x2210+1:] 1089 1091 1090 1092 def _corrupt_block_hashes(data, debug=False): -
TabularUnified src/allmydata/test/common_util.py ¶
r8b890d25 r624916e 6 6 from random import randrange 7 7 from six.moves import StringIO 8 from io import ( 9 TextIOWrapper, 10 BytesIO, 11 ) 8 12 9 13 from twisted.internet import reactor, defer … … 36 40 raise unittest.SkipTest("A non-ASCII argv could not be encoded on this platform.") 37 41 38 def run_cli(verb, *args, **kwargs): 39 precondition(not [True for arg in args if not isinstance(arg, str)], 40 "arguments to do_cli must be strs -- convert using unicode_to_argv", args=args) 41 nodeargs = kwargs.get("nodeargs", []) 42 43 def _getvalue(io): 44 """ 45 Read out the complete contents of a file-like object. 46 """ 47 io.seek(0) 48 return io.read() 49 50 51 def run_cli_bytes(verb, *args, **kwargs): 52 """ 53 Run a Tahoe-LAFS CLI command specified as bytes. 54 55 Most code should prefer ``run_cli_unicode`` which deals with all the 56 necessary encoding considerations. This helper still exists so that novel 57 misconfigurations can be explicitly tested (for example, receiving UTF-8 58 bytes when the system encoding claims to be ASCII). 59 60 :param bytes verb: The command to run. For example, ``b"create-node"``. 61 62 :param [bytes] args: The arguments to pass to the command. For example, 63 ``(b"--hostname=localhost",)``. 64 65 :param [bytes] nodeargs: Extra arguments to pass to the Tahoe executable 66 before ``verb``. 67 68 :param bytes stdin: Text to pass to the command via stdin. 69 70 :param NoneType|str encoding: The name of an encoding which stdout and 71 stderr will be configured to use. ``None`` means stdout and stderr 72 will accept bytes and unicode and use the default system encoding for 73 translating between them. 74 """ 75 nodeargs = kwargs.pop("nodeargs", []) 76 encoding = kwargs.pop("encoding", None) 77 precondition( 78 all(isinstance(arg, bytes) for arg in [verb] + nodeargs + list(args)), 79 "arguments to run_cli must be bytes -- convert using unicode_to_argv", 80 verb=verb, 81 args=args, 82 nodeargs=nodeargs, 83 ) 42 84 argv = nodeargs + [verb] + list(args) 43 85 stdin = kwargs.get("stdin", "") 44 stdout = StringIO() 45 stderr = StringIO() 86 if encoding is None: 87 # The original behavior, the Python 2 behavior, is to accept either 88 # bytes or unicode and try to automatically encode or decode as 89 # necessary. This works okay for ASCII and if LANG is set 90 # appropriately. These aren't great constraints so we should move 91 # away from this behavior. 92 stdout = StringIO() 93 stderr = StringIO() 94 else: 95 # The new behavior, the Python 3 behavior, is to accept unicode and 96 # encode it using a specific encoding. For older versions of Python 97 # 3, the encoding is determined from LANG (bad) but for newer Python 98 # 3, the encoding is always utf-8 (good). Tests can pass in different 99 # encodings to exercise different behaviors. 100 stdout = TextIOWrapper(BytesIO(), encoding) 101 stderr = TextIOWrapper(BytesIO(), encoding) 46 102 d = defer.succeed(argv) 47 103 d.addCallback(runner.parse_or_exit_with_explanation, stdout=stdout) … … 50 106 stdout=stdout, stderr=stderr) 51 107 def _done(rc): 52 return 0, stdout.getvalue(), stderr.getvalue()108 return 0, _getvalue(stdout), _getvalue(stderr) 53 109 def _err(f): 54 110 f.trap(SystemExit) 55 return f.value.code, stdout.getvalue(), stderr.getvalue()111 return f.value.code, _getvalue(stdout), _getvalue(stderr) 56 112 d.addCallbacks(_done, _err) 57 113 return d 114 115 116 def run_cli_unicode(verb, argv, nodeargs=None, stdin=None, encoding=None): 117 """ 118 Run a Tahoe-LAFS CLI command. 119 120 :param unicode verb: The command to run. For example, ``u"create-node"``. 121 122 :param [unicode] argv: The arguments to pass to the command. For example, 123 ``[u"--hostname=localhost"]``. 124 125 :param [unicode] nodeargs: Extra arguments to pass to the Tahoe executable 126 before ``verb``. 127 128 :param unicode stdin: Text to pass to the command via stdin. 129 130 :param NoneType|str encoding: The name of an encoding to use for all 131 bytes/unicode conversions necessary *and* the encoding to cause stdio 132 to declare with its ``encoding`` attribute. ``None`` means ASCII will 133 be used and no declaration will be made at all. 134 """ 135 if nodeargs is None: 136 nodeargs = [] 137 precondition( 138 all(isinstance(arg, unicode) for arg in [verb] + nodeargs + argv), 139 "arguments to run_cli_unicode must be unicode", 140 verb=verb, 141 nodeargs=nodeargs, 142 argv=argv, 143 ) 144 codec = encoding or "ascii" 145 encode = lambda t: None if t is None else t.encode(codec) 146 d = run_cli_bytes( 147 encode(verb), 148 nodeargs=list(encode(arg) for arg in nodeargs), 149 stdin=encode(stdin), 150 encoding=encoding, 151 *list(encode(arg) for arg in argv) 152 ) 153 def maybe_decode(result): 154 code, stdout, stderr = result 155 if isinstance(stdout, bytes): 156 stdout = stdout.decode(codec) 157 if isinstance(stderr, bytes): 158 stderr = stderr.decode(codec) 159 return code, stdout, stderr 160 d.addCallback(maybe_decode) 161 return d 162 163 164 run_cli = run_cli_bytes 165 58 166 59 167 def parse_cli(*argv): -
TabularUnified src/allmydata/test/test_repairer.py ¶
r8b890d25 r624916e 1 1 # -*- coding: utf-8 -*- 2 """ 3 Ported to Python 3. 4 """ 2 5 from __future__ import print_function 6 from __future__ import absolute_import 7 from __future__ import division 8 from __future__ import unicode_literals 9 10 from future.utils import PY2 11 if PY2: 12 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 3 13 4 14 from allmydata.test import common … … 63 73 c1 = self.g.clients[1] 64 74 c0.encoding_params['max_segment_size'] = 12 65 d = c0.upload(upload.Data(common.TEST_DATA, convergence= ""))75 d = c0.upload(upload.Data(common.TEST_DATA, convergence=b"")) 66 76 def _stash_uri(ur): 67 77 self.uri = ur.get_uri() … … 465 475 466 476 d.addCallback(lambda ignored: 467 self.delete_shares_numbered(self.uri, range(3, 10+1)))477 self.delete_shares_numbered(self.uri, list(range(3, 10+1)))) 468 478 d.addCallback(lambda ignored: download_to_data(self.c1_filenode)) 469 479 d.addCallback(lambda newdata: … … 477 487 d = self.upload_and_stash() 478 488 d.addCallback(lambda ignored: 479 self.delete_shares_numbered(self.uri, range(7)))489 self.delete_shares_numbered(self.uri, list(range(7)))) 480 490 d.addCallback(lambda ignored: self._stash_counts()) 481 491 d.addCallback(lambda ignored: … … 510 520 511 521 d.addCallback(lambda ignored: 512 self.delete_shares_numbered(self.uri, range(3, 10+1)))522 self.delete_shares_numbered(self.uri, list(range(3, 10+1)))) 513 523 d.addCallback(lambda ignored: download_to_data(self.c1_filenode)) 514 524 d.addCallback(lambda newdata: … … 528 538 # happiness setting. 529 539 def _delete_some_servers(ignored): 530 for i in xrange(7):540 for i in range(7): 531 541 self.g.remove_server(self.g.servers_by_number[i].my_nodeid) 532 542 … … 641 651 # unless it has already repaired the previously-corrupted share. 642 652 def _then_delete_7_and_try_a_download(unused=None): 643 shnums = range(10)653 shnums = list(range(10)) 644 654 shnums.remove(shnum) 645 655 random.shuffle(shnums) … … 680 690 self.set_up_grid() 681 691 c0 = self.g.clients[0] 682 DATA = "a"*135692 DATA = b"a"*135 683 693 c0.encoding_params['k'] = 22 684 694 c0.encoding_params['n'] = 66 685 d = c0.upload(upload.Data(DATA, convergence= ""))695 d = c0.upload(upload.Data(DATA, convergence=b"")) 686 696 def _then(ur): 687 697 self.uri = ur.get_uri() -
TabularUnified src/allmydata/test/test_system.py ¶
r8b890d25 r624916e 2564 2564 def _run_in_subprocess(ignored, verb, *args, **kwargs): 2565 2565 stdin = kwargs.get("stdin") 2566 # XXX https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3548 2566 2567 env = kwargs.get("env", os.environ) 2567 2568 # Python warnings from the child process don't matter. -
TabularUnified src/allmydata/util/_python3.py ¶
r8b890d25 r624916e 36 36 "allmydata.crypto.util", 37 37 "allmydata.hashtree", 38 "allmydata.immutable.checker", 38 39 "allmydata.immutable.downloader", 39 40 "allmydata.immutable.downloader.common", … … 50 51 "allmydata.immutable.literal", 51 52 "allmydata.immutable.offloaded", 53 "allmydata.immutable.repairer", 52 54 "allmydata.immutable.upload", 53 55 "allmydata.interfaces", 56 "allmydata.introducer.client", 57 "allmydata.introducer.common", 54 58 "allmydata.introducer.interfaces", 59 "allmydata.introducer.server", 55 60 "allmydata.monitor", 56 61 "allmydata.mutable.checker", … … 152 157 "allmydata.test.test_pipeline", 153 158 "allmydata.test.test_python3", 159 "allmydata.test.test_repairer", 154 160 "allmydata.test.test_spans", 155 161 "allmydata.test.test_statistics", -
TabularUnified src/allmydata/util/encodingutil.py ¶
r8b890d25 r624916e 252 252 253 253 ESCAPABLE_8BIT = re.compile( br'[^ !#\x25-\x5B\x5D-\x5F\x61-\x7E]', re.DOTALL) 254 255 def quote_output_u(*args, **kwargs): 256 """ 257 Like ``quote_output`` but always return ``unicode``. 258 """ 259 result = quote_output(*args, **kwargs) 260 if isinstance(result, unicode): 261 return result 262 return result.decode(kwargs.get("encoding", None) or io_encoding) 263 254 264 255 265 def quote_output(s, quotemarks=True, quote_newlines=None, encoding=None): -
TabularUnified src/allmydata/web/statistics.xhtml ¶
r8b890d25 r624916e 13 13 14 14 <ul> 15 <li>Load Average: <t:transparent t:render="load_average" /></li>16 <li>Peak Load: <t:transparent t:render="peak_load" /></li>17 15 <li>Files Uploaded (immutable): <t:transparent t:render="uploads" /></li> 18 16 <li>Files Downloaded (immutable): <t:transparent t:render="downloads" /></li> -
TabularUnified src/allmydata/web/status.py ¶
r8b890d25 r624916e 1567 1567 1568 1568 @renderer 1569 def load_average(self, req, tag):1570 return tag(str(self._stats["stats"].get("load_monitor.avg_load")))1571 1572 @renderer1573 def peak_load(self, req, tag):1574 return tag(str(self._stats["stats"].get("load_monitor.max_load")))1575 1576 @renderer1577 1569 def uploads(self, req, tag): 1578 1570 files = self._stats["counters"].get("uploader.files_uploaded", 0)
Note: See TracChangeset
for help on using the changeset viewer.