Changeset a0a39d3 in trunk
- Timestamp:
- 2020-11-26T02:27:49Z (5 years ago)
- Branches:
- master
- Children:
- 4450a7a4
- Parents:
- da0fe23 (diff), fba386c (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. - Files:
-
- 13 added
- 3 deleted
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified .github/workflows/ci.yml ¶
rda0fe23 ra0a39d3 22 22 steps: 23 23 24 # Get vcpython27 on Windows + Python 2.7, to build zfec24 # Get vcpython27 on Windows + Python 2.7, to build netifaces 25 25 # extension. See https://chocolatey.org/packages/vcpython27 and 26 26 # https://github.com/crazy-max/ghaction-chocolatey … … 79 79 steps: 80 80 81 # Get vcpython27 for Windows + Python 2.7, to build netifaces 82 # extension. See https://chocolatey.org/packages/vcpython27 and 83 # https://github.com/crazy-max/ghaction-chocolatey 84 - name: Install MSVC 9.0 for Python 2.7 [Windows] 85 if: matrix.os == 'windows-latest' && matrix.python-version == '2.7' 86 uses: crazy-max/ghaction-chocolatey@v1 87 with: 88 args: install vcpython27 89 81 90 - name: Install Tor [Ubuntu] 82 91 if: matrix.os == 'ubuntu-latest' … … 92 101 with: 93 102 args: install tor 94 95 - name: Install MSVC 9.0 for Python 2.7 [Windows]96 if: matrix.os == 'windows-latest' && matrix.python-version == '2.7'97 uses: crazy-max/ghaction-chocolatey@v198 with:99 args: install vcpython27100 103 101 104 - name: Check out Tahoe-LAFS sources … … 142 145 steps: 143 146 144 # Get vcpython27 on Windows + Python 2.7, to build zfec147 # Get vcpython27 for Windows + Python 2.7, to build netifaces 145 148 # extension. See https://chocolatey.org/packages/vcpython27 and 146 149 # https://github.com/crazy-max/ghaction-chocolatey -
TabularUnified docs/INSTALL.rst ¶
rda0fe23 ra0a39d3 40 40 41 41 If you are on a Mac, you can either follow these instructions, or use the 42 pre-packaged bundle described in :doc:`OS-X`. The Tahoe project hosts 43 pre-compiled "wheels" for all dependencies, so use the ``--find-links=`` 44 option described below to avoid needing a compiler. 42 pre-packaged bundle described in :doc:`OS-X`. 45 43 46 44 Many Linux distributions include Tahoe-LAFS packages. Debian and Ubuntu users … … 55 53 56 54 If you don't use a pre-packaged copy of Tahoe, you can build it yourself. 57 You'll need Python2.7, pip, and virtualenv. On unix-like platforms, you will 58 need a C compiler, the Python development headers, and some libraries 59 (libffi-dev and libssl-dev). 55 You'll need Python2.7, pip, and virtualenv. 56 Tahoe-LAFS depends on some libraries which require a C compiler to build. 57 However, for many platforms, PyPI hosts already-built packages of libraries. 58 59 If there is no already-built package for your platform, 60 you will need a C compiler, 61 the Python development headers, 62 and some libraries (libffi-dev and libssl-dev). 60 63 61 64 On a modern Debian/Ubuntu-derived distribution, this command will get you … … 65 68 66 69 On OS-X, install pip and virtualenv as described below. If you want to 67 compile the dependencies yourself (instead of using ``--find-links`` to take 68 advantage of the pre-compiled ones we host), you'll also need to install 70 compile the dependencies yourself, you'll also need to install 69 71 Xcode and its command-line tools. 70 72 … … 151 153 New python executable in ~/venv/bin/python2.7 152 154 Installing setuptools, pip, wheel...done. 153 155 154 156 % venv/bin/pip install -U pip setuptools 155 157 Downloading/unpacking pip from https://pypi.python.org/... 156 158 ... 157 159 Successfully installed pip setuptools 158 160 159 161 % venv/bin/pip install tahoe-lafs 160 162 Collecting tahoe-lafs … … 162 164 Installing collected packages: ... 163 165 Successfully installed ... 164 166 165 167 % venv/bin/tahoe --version 166 168 tahoe-lafs: 1.14.0 167 169 foolscap: ... 168 170 169 171 % 170 171 On OS-X, instead of ``pip install tahoe-lafs``, use this command to take172 advantage of the hosted pre-compiled wheels::173 174 venv/bin/pip install --find-links=https://tahoe-lafs.org/deps tahoe-lafs175 176 172 177 173 Install From a Source Tarball … … 183 179 New python executable in ~/venv/bin/python2.7 184 180 Installing setuptools, pip, wheel...done. 185 181 186 182 % venv/bin/pip install https://tahoe-lafs.org/downloads/tahoe-lafs-1.14.0.tar.bz2 187 183 Collecting https://tahoe-lafs.org/downloads/tahoe-lafs-1.14.0.tar.bz2 … … 189 185 Installing collected packages: ... 190 186 Successfully installed ... 191 187 192 188 % venv/bin/tahoe --version 193 189 tahoe-lafs: 1.14.0 … … 214 210 215 211 % git clone https://github.com/tahoe-lafs/tahoe-lafs.git 216 212 217 213 % cd tahoe-lafs 218 214 219 215 % virtualenv venv 220 216 221 217 % venv/bin/pip install --editable .[test] 222 218 Obtaining file::~/tahoe-lafs 223 219 ... 224 220 Successfully installed ... 225 221 226 222 % venv/bin/tahoe --version 227 223 tahoe-lafs: 1.14.0.post34.dev0 … … 283 279 ... 284 280 Ran 1186 tests in 423.179s 285 281 286 282 PASSED (skips=7, expectedFailures=3, successes=1176) 287 283 __________________________ summary ___________________________________ -
TabularUnified docs/windows.rst ¶
rda0fe23 ra0a39d3 34 34 into this virtualenv:: 35 35 36 PS C:\Users\me> venv\Scripts\pip install --find-links=https://tahoe-lafs.org/deps/tahoe-lafs36 PS C:\Users\me> venv\Scripts\pip install tahoe-lafs 37 37 Collecting tahoe-lafs 38 38 ... … … 70 70 git checkout):: 71 71 72 $ venv\Scripts\pip install --find-links=https://tahoe-lafs.org/deps/.72 $ venv\Scripts\pip install . 73 73 74 74 If you're planning to hack on the source code, you might want to add … … 78 78 ------------ 79 79 80 Tahoe-LAFS depends upon several packages that use compiled C code 81 (such as zfec). This code must be built separately for each platform 82 (Windows, OS-X, and different flavors of Linux). 83 84 Pre-compiled "wheels" of all Tahoe's dependencies are hosted on the 85 tahoe-lafs.org website in the ``deps/`` directory. The ``--find-links=`` 86 argument (used in the examples above) instructs ``pip`` to look at that URL 87 for dependencies. This should avoid the need for anything to be compiled 88 during the install. 80 Tahoe-LAFS depends upon several packages that use compiled C code (such as zfec). 81 This code must be built separately for each platform (Windows, OS-X, and different flavors of Linux). 82 Fortunately, this is now done by upstream packages for most platforms. 83 The result is that a C compiler is usually not required to install Tahoe-LAFS. -
TabularUnified integration/util.py ¶
rda0fe23 ra0a39d3 258 258 config_path = join(node_dir, 'tahoe.cfg') 259 259 config = get_config(config_path) 260 set_config(config, 'node', 'log_gatherer.furl', flog_gatherer) 260 set_config( 261 config, 262 u'node', 263 u'log_gatherer.furl', 264 flog_gatherer.decode("utf-8"), 265 ) 261 266 write_config(config_path, config) 262 267 created_d.addCallback(created) -
TabularUnified nix/overlays.nix ¶
rda0fe23 ra0a39d3 16 16 # is too old. 17 17 pyutil = python-super.callPackage ./pyutil.nix { }; 18 19 # Need a newer version of Twisted, too. 20 twisted = python-super.callPackage ./twisted.nix { }; 18 21 }; 19 22 }; -
TabularUnified setup.py ¶
rda0fe23 ra0a39d3 99 99 # specified by Twisted[conch]. Since this would be the *whole point* of 100 100 # an sftp extra in Tahoe-LAFS, there is no point in having one. 101 "Twisted[tls,conch] >= 18.4.0", 101 # * Twisted 19.10 introduces Site.getContentFile which we use to get 102 # temporary upload files placed into a per-node temporary directory. 103 "Twisted[tls,conch] >= 19.10.0", 102 104 103 105 "PyYAML >= 3.11", -
TabularUnified src/allmydata/client.py ¶
rda0fe23 ra0a39d3 39 39 hashutil, base32, pollmixin, log, idlib, 40 40 yamlutil, configutil, 41 fileutil, 41 42 ) 42 43 from allmydata.util.encodingutil import get_filesystem_encoding … … 520 521 str(allmydata.__full_version__), 521 522 str(_Client.OLDEST_SUPPORTED_VERSION), 522 list(node.get_app_versions()),523 523 partial(_sequencer, config), 524 524 introducer_cache_filepath, … … 1071 1071 self._key_generator.set_default_keysize(keysize) 1072 1072 1073 def _get_tempdir(self): 1074 """ 1075 Determine the path to the directory where temporary files for this node 1076 should be written. 1077 1078 :return bytes: The path which will exist and be a directory. 1079 """ 1080 tempdir_config = self.config.get_config("node", "tempdir", "tmp") 1081 if isinstance(tempdir_config, bytes): 1082 tempdir_config = tempdir_config.decode('utf-8') 1083 tempdir = self.config.get_config_path(tempdir_config) 1084 if not os.path.exists(tempdir): 1085 fileutil.make_dirs(tempdir) 1086 return tempdir 1087 1073 1088 def init_web(self, webport): 1074 1089 self.log("init_web(webport=%s)", args=(webport,)) … … 1078 1093 staticdir_config = self.config.get_config("node", "web.static", "public_html") 1079 1094 staticdir = self.config.get_config_path(staticdir_config) 1080 ws = WebishServer(self, webport, nodeurl_path, staticdir) 1095 ws = WebishServer( 1096 self, 1097 webport, 1098 self._get_tempdir(), 1099 nodeurl_path, 1100 staticdir, 1101 ) 1081 1102 ws.setServiceParent(self) 1082 1103 -
TabularUnified src/allmydata/introducer/client.py ¶
rda0fe23 ra0a39d3 25 25 def __init__(self, tub, introducer_furl, 26 26 nickname, my_version, oldest_supported, 27 app_versions,sequencer, cache_filepath):27 sequencer, cache_filepath): 28 28 self._tub = tub 29 29 self.introducer_furl = introducer_furl … … 33 33 self._my_version = my_version 34 34 self._oldest_supported = oldest_supported 35 self._app_versions = app_versions36 35 self._sequencer = sequencer 37 36 self._cache_filepath = cache_filepath 38 37 39 self._my_subscriber_info = { 40 "version": 0, 41 "nickname": self._nickname, 42 "app-versions": self._app_versions, 43 "my-version": self._my_version, 44 "oldest-supported": self._oldest_supported, 45 } 38 self._my_subscriber_info = { "version": 0, 39 "nickname": self._nickname, 40 "app-versions": [], 41 "my-version": self._my_version, 42 "oldest-supported": self._oldest_supported, 43 } 46 44 47 45 self._outbound_announcements = {} # not signed … … 192 190 # publish(), each time we make a change 193 191 "nickname": self._nickname, 194 "app-versions": self._app_versions,192 "app-versions": [], 195 193 "my-version": self._my_version, 196 194 "oldest-supported": self._oldest_supported, -
TabularUnified src/allmydata/mutable/layout.py ¶
rda0fe23 ra0a39d3 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 # Omit dict so Python 3 changes don't leak into API callers on Python 2. 12 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, list, object, range, str, max, min # noqa: F401 1 13 from past.utils import old_div 2 14 … … 1745 1757 1746 1758 def _read(self, readvs, force_remote=False): 1747 unsatisfiable = list(filter(lambda x: x[0] + x[1] > len(self._data), readvs))1759 unsatisfiable = [x for x in readvs if x[0] + x[1] > len(self._data)] 1748 1760 # TODO: It's entirely possible to tweak this so that it just 1749 1761 # fulfills the requests that it can, and not demand that all -
TabularUnified src/allmydata/mutable/repairer.py ¶
rda0fe23 ra0a39d3 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 1 12 2 13 from zope.interface import implementer -
TabularUnified src/allmydata/mutable/retrieve.py ¶
rda0fe23 ra0a39d3 1 from past.builtins import unicode 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 # Don't import bytes and str, to prevent API leakage 12 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, dict, list, object, range, max, min # noqa: F401 2 13 3 14 import time … … 750 761 blockhashes = dict(enumerate(blockhashes)) 751 762 self.log("the reader gave me the following blockhashes: %s" % \ 752 blockhashes.keys())763 list(blockhashes.keys())) 753 764 self.log("the reader gave me the following sharehashes: %s" % \ 754 sharehashes.keys())765 list(sharehashes.keys())) 755 766 bht = self._block_hash_trees[reader.shnum] 756 767 … … 909 920 910 921 def notify_server_corruption(self, server, shnum, reason): 911 if isinstance(reason, unicode):922 if isinstance(reason, str): 912 923 reason = reason.encode("utf-8") 913 924 storage_server = server.get_storage_server() -
TabularUnified src/allmydata/mutable/servermap.py ¶
rda0fe23 ra0a39d3 1 """ 2 Ported to Python 3. 3 """ 1 4 from __future__ import print_function 2 5 from __future__ import absolute_import 6 from __future__ import division 7 from __future__ import unicode_literals 8 9 from future.utils import PY2 10 if PY2: 11 # Doesn't import str to prevent API leakage on Python 2 12 from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, max, min # noqa: F401 3 13 from past.builtins import unicode 4 14 … … 189 199 print("servermap:", file=out) 190 200 191 for ( (server, shnum), (verinfo, timestamp) ) in self._known_shares.items():201 for ( (server, shnum), (verinfo, timestamp) ) in list(self._known_shares.items()): 192 202 (seqnum, root_hash, IV, segsize, datalength, k, N, prefix, 193 203 offsets_tuple) = verinfo … … 227 237 timestamp) tuples.""" 228 238 versionmap = DictOfSets() 229 for ( (server, shnum), (verinfo, timestamp) ) in self._known_shares.items():239 for ( (server, shnum), (verinfo, timestamp) ) in list(self._known_shares.items()): 230 240 versionmap.add(verinfo, (shnum, server, timestamp)) 231 241 return versionmap … … 246 256 versionmap = self.make_versionmap() 247 257 all_shares = {} 248 for verinfo, shares in versionmap.items():258 for verinfo, shares in list(versionmap.items()): 249 259 s = set() 250 260 for (shnum, server, timestamp) in shares: … … 272 282 versionmap = self.make_versionmap() 273 283 bits = [] 274 for (verinfo, shares) in versionmap.items():284 for (verinfo, shares) in list(versionmap.items()): 275 285 vstr = self.summarize_version(verinfo) 276 286 shnums = set([shnum for (shnum, server, timestamp) in shares]) … … 283 293 versionmap = self.make_versionmap() 284 294 recoverable_versions = set() 285 for (verinfo, shares) in versionmap.items():295 for (verinfo, shares) in list(versionmap.items()): 286 296 (seqnum, root_hash, IV, segsize, datalength, k, N, prefix, 287 297 offsets_tuple) = verinfo … … 299 309 300 310 unrecoverable_versions = set() 301 for (verinfo, shares) in versionmap.items():311 for (verinfo, shares) in list(versionmap.items()): 302 312 (seqnum, root_hash, IV, segsize, datalength, k, N, prefix, 303 313 offsets_tuple) = verinfo … … 333 343 unrecoverable = set() 334 344 highest_recoverable_seqnum = -1 335 for (verinfo, shares) in versionmap.items():345 for (verinfo, shares) in list(versionmap.items()): 336 346 (seqnum, root_hash, IV, segsize, datalength, k, N, prefix, 337 347 offsets_tuple) = verinfo … … 668 678 ds = [] 669 679 670 for shnum,datav in datavs.items():680 for shnum,datav in list(datavs.items()): 671 681 data = datav[0] 672 682 reader = MDMFSlotReadProxy(ss, -
TabularUnified src/allmydata/node.py ¶
rda0fe23 ra0a39d3 20 20 import types 21 21 import errno 22 import tempfile23 22 from base64 import b32decode, b32encode 24 23 … … 29 28 from twisted.application import service 30 29 from twisted.python.failure import Failure 31 from twisted.python.compat import nativeString32 from foolscap.api import Tub, app_versions 30 from foolscap.api import Tub 31 33 32 import foolscap.logging.log 34 from allmydata.version_checks import get_package_versions, get_package_versions_string 33 35 34 from allmydata.util import log 36 35 from allmydata.util import fileutil, iputil 37 from allmydata.util.assertutil import _assert38 36 from allmydata.util.fileutil import abspath_expanduser_unicode 39 37 from allmydata.util.encodingutil import get_filesystem_encoding, quote_output 40 38 from allmydata.util import configutil 39 40 from . import ( 41 __full_version__, 42 ) 41 43 42 44 def _common_valid_config(): … … 80 82 }) 81 83 82 # Add our application versions to the data that Foolscap's LogPublisher83 # reports.84 for thing, things_version in list(get_package_versions().items()):85 app_versions.add_version(thing, things_version)86 87 84 # group 1 will be addr (dotted quad string), group 3 if any will be portnum (string) 88 85 ADDR_RE = re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$") … … 233 230 """ 234 231 return _Config(parser, portnumfile, basedir, fname, write_new_config) 235 236 237 def get_app_versions():238 """239 :returns: dict of versions important to Foolscap240 """241 return dict(app_versions.versions)242 232 243 233 … … 833 823 self._tor_provider = tor_provider 834 824 835 self.init_tempdir()836 837 825 self.create_log_tub() 838 826 self.logSource = "Node" … … 852 840 self.control_tub.setServiceParent(self) 853 841 854 self.log("Node constructed. " + get_package_versions_string())842 self.log("Node constructed. " + __full_version__) 855 843 iputil.increase_rlimits() 856 844 … … 860 848 """ 861 849 return len(self.tub.getListeners()) > 0 862 863 def init_tempdir(self):864 """865 Initialize/create a directory for temporary files.866 """867 tempdir_config = self.config.get_config("node", "tempdir", "tmp")868 if isinstance(tempdir_config, bytes):869 tempdir_config = tempdir_config.decode('utf-8')870 tempdir = self.config.get_config_path(tempdir_config)871 if not os.path.exists(tempdir):872 fileutil.make_dirs(tempdir)873 tempfile.tempdir = nativeString(tempdir)874 # this should cause twisted.web.http (which uses875 # tempfile.TemporaryFile) to put large request bodies in the given876 # directory. Without this, the default temp dir is usually /tmp/,877 # which is frequently too small.878 temp_fd, test_name = tempfile.mkstemp()879 _assert(os.path.dirname(test_name) == tempdir, test_name, tempdir)880 os.close(temp_fd) # avoid leak of unneeded fd881 850 882 851 # pull this outside of Node's __init__ too, see: -
TabularUnified src/allmydata/scripts/runner.py ¶
rda0fe23 ra0a39d3 8 8 from twisted.internet import defer, task, threads 9 9 10 from allmydata.version_checks import get_package_versions_string11 10 from allmydata.scripts.common import get_default_nodedir 12 11 from allmydata.scripts import debug, create_node, cli, \ … … 20 19 ) 21 20 21 from .. import ( 22 __full_version__, 23 ) 24 22 25 _default_nodedir = get_default_nodedir() 23 26 … … 78 81 79 82 def opt_version(self): 80 print( get_package_versions_string(debug=True), file=self.stdout)83 print(__full_version__, file=self.stdout) 81 84 self.no_command_needed = True 82 85 83 def opt_version_and_path(self): 84 print(get_package_versions_string(show_paths=True, debug=True), file=self.stdout) 85 self.no_command_needed = True 86 opt_version_and_path = opt_version 86 87 87 88 opt_eliot_destination = opt_eliot_destination -
TabularUnified src/allmydata/test/cli/test_cli.py ¶
rda0fe23 ra0a39d3 1267 1267 stdout = StringIO() 1268 1268 self.failUnlessRaises(SystemExit, self.parse, ["--version"], stdout) 1269 self.failUnlessIn(allmydata.__ appname__ + ":", stdout.getvalue())1269 self.failUnlessIn(allmydata.__full_version__, stdout.getvalue()) 1270 1270 # but "tahoe SUBCOMMAND --version" should be rejected 1271 1271 self.failUnlessRaises(usage.UsageError, self.parse, -
TabularUnified src/allmydata/test/common.py ¶
rda0fe23 ra0a39d3 111 111 my_version = attr.ib() 112 112 oldest_supported = attr.ib() 113 app_versions = attr.ib()114 113 sequencer = attr.ib() 115 114 cache_filepath = attr.ib() … … 1152 1151 * trial-compatible mktemp method 1153 1152 * unittest2-compatible assertRaises helper 1154 * Automatic cleanup of tempfile.tempdir mutation (pervasive through the 1155 Tahoe-LAFS test suite). 1153 * Automatic cleanup of tempfile.tempdir mutation (once pervasive through 1154 the Tahoe-LAFS test suite, perhaps gone now but someone should verify 1155 this). 1156 1156 """ 1157 1157 def setUp(self): -
TabularUnified src/allmydata/test/no_network.py ¶
rda0fe23 ra0a39d3 362 362 """ 363 363 if self._setup_errors: 364 raise self._setup_errors[0].value364 self._setup_errors[0].raiseException() 365 365 366 366 @defer.inlineCallbacks -
TabularUnified src/allmydata/test/test_client.py ¶
rda0fe23 ra0a39d3 42 42 from allmydata.node import OldConfigError, UnescapedHashError, create_node_dir 43 43 from allmydata.frontends.auth import NeedRootcapLookupScheme 44 from allmydata.version_checks import (45 get_package_versions_string,46 )47 44 from allmydata import client 48 45 from allmydata.storage_client import ( … … 622 619 self.failUnless("." in str(allmydata.__full_version__), 623 620 "non-numeric version in '%s'" % allmydata.__version__) 624 all_versions = get_package_versions_string()625 self.failUnless(allmydata.__appname__ in all_versions)626 621 # also test stats 627 622 stats = c.get_stats() -
TabularUnified src/allmydata/test/test_introducer.py ¶
rda0fe23 ra0a39d3 156 156 def test_create(self): 157 157 ic = IntroducerClient(None, "introducer.furl", u"my_nickname", 158 "my_version", "oldest_version", {},fakeseq,158 "my_version", "oldest_version", fakeseq, 159 159 FilePath(self.mktemp())) 160 160 self.failUnless(isinstance(ic, IntroducerClient)) … … 189 189 ic1 = IntroducerClient(None, 190 190 "introducer.furl", u"my_nickname", 191 "ver23", "oldest_version", {},fakeseq,191 "ver23", "oldest_version", fakeseq, 192 192 FilePath(self.mktemp())) 193 193 # we use a second client just to create a different-looking … … 195 195 ic2 = IntroducerClient(None, 196 196 "introducer.furl", u"my_nickname", 197 "ver24","oldest_version", {},fakeseq,197 "ver24","oldest_version",fakeseq, 198 198 FilePath(self.mktemp())) 199 199 announcements = [] … … 299 299 ic1 = IntroducerClient(None, 300 300 "introducer.furl", u"my_nickname", 301 "ver23", "oldest_version", {},realseq,301 "ver23", "oldest_version", realseq, 302 302 FilePath(self.mktemp())) 303 303 furl1 = "pb://62ubehyunnyhzs7r6vdonnm2hpi52w6y@127.0.0.1:36106/gydnp" … … 397 397 tub2.setServiceParent(self.parent) 398 398 c = IntroducerClient(tub2, ifurl, 399 u"nickname", "version", "oldest", {},fakeseq,399 u"nickname", "version", "oldest", fakeseq, 400 400 FilePath(self.mktemp())) 401 401 furl1 = "pb://onug64tu@127.0.0.1:123/short" # base32("short") … … 478 478 NICKNAME % str(i), 479 479 "version", "oldest", 480 {"component": "component-v1"},fakeseq,480 fakeseq, 481 481 FilePath(self.mktemp())) 482 482 received_announcements[c] = {} … … 738 738 introducer = IntroducerService() 739 739 tub = introducer_furl = None 740 app_versions = {"whizzy": "fizzy"}741 740 client_v2 = IntroducerClient(tub, introducer_furl, NICKNAME % u"v2", 742 "my_version", "oldest", app_versions,741 "my_version", "oldest", 743 742 fakeseq, FilePath(self.mktemp())) 744 743 #furl1 = "pb://62ubehyunnyhzs7r6vdonnm2hpi52w6y@127.0.0.1:0/swissnum" … … 752 751 s0 = subs[0] 753 752 self.failUnlessEqual(s0.service_name, "storage") 754 self.failUnlessEqual(s0.app_versions, app_versions)755 753 self.failUnlessEqual(s0.nickname, NICKNAME % u"v2") 756 754 self.failUnlessEqual(s0.version, "my_version") … … 761 759 introducer = IntroducerService() 762 760 tub = introducer_furl = None 763 app_versions = {"whizzy": "fizzy"}764 761 client_v2 = IntroducerClient(tub, introducer_furl, u"nick-v2", 765 "my_version", "oldest", app_versions,762 "my_version", "oldest", 766 763 fakeseq, FilePath(self.mktemp())) 767 764 furl1 = "pb://62ubehyunnyhzs7r6vdonnm2hpi52w6y@127.0.0.1:0/swissnum" … … 777 774 self.assertThat(a[0].canary, Is(canary0)) 778 775 self.failUnlessEqual(a[0].index, ("storage", public_key_str)) 779 self.failUnlessEqual(a[0].announcement["app-versions"], app_versions)780 776 self.failUnlessEqual(a[0].nickname, u"nick-v2") 781 777 self.failUnlessEqual(a[0].service_name, "storage") … … 855 851 yield flushEventualQueue() 856 852 ic2 = IntroducerClient(None, "introducer.furl", u"my_nickname", 857 "my_version", "oldest_version", {},fakeseq,853 "my_version", "oldest_version", fakeseq, 858 854 ic._cache_filepath) 859 855 announcements = {} … … 955 951 listenOnUnused(tub) 956 952 c = IntroducerClient(tub, self.introducer_furl, 957 u"nickname-client", "version", "oldest", {},953 u"nickname-client", "version", "oldest", 958 954 fakeseq, FilePath(self.mktemp())) 959 955 announcements = {} … … 1028 1024 "0.0.0", 1029 1025 "1.2.3", 1030 {},1031 1026 (0, u"i am a nonce"), 1032 1027 "invalid", -
TabularUnified src/allmydata/test/test_log.py ¶
rda0fe23 ra0a39d3 10 10 from __future__ import print_function 11 11 12 from future.utils import PY2 12 from future.utils import PY2, native_str 13 13 if PY2: 14 14 from 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 … … 155 155 self.assertEqual([m[2] for m in self.messages], 156 156 ["grand", "par1", "par2", "msg1", "msg1"]) 157 158 def test_native_string_keys(self): 159 """Keyword argument keys are all native strings.""" 160 class LoggingObject17(tahoe_log.PrefixingLogMixin): 161 pass 162 163 obj = LoggingObject17() 164 # Native string by default: 165 obj.log(hello="world") 166 # Will be Unicode on Python 2: 167 obj.log(**{"my": "message"}) 168 for message in self.messages: 169 for k in message[-1].keys(): 170 self.assertIsInstance(k, native_str) -
TabularUnified src/allmydata/test/test_runner.py ¶
rda0fe23 ra0a39d3 13 13 from twisted.internet.defer import ( 14 14 inlineCallbacks, 15 returnValue,16 15 DeferredList, 17 16 ) … … 21 20 ) 22 21 from allmydata.util import fileutil, pollmixin 23 from allmydata.util.encodingutil import unicode_to_argv, unicode_to_output, \ 24 get_filesystem_encoding 22 from allmydata.util.encodingutil import unicode_to_argv, unicode_to_output 25 23 from allmydata.test import common_util 26 from allmydata.version_checks import normalized_version27 24 import allmydata 28 from allmydata import __appname__29 25 from .common_util import parse_cli, run_cli 30 26 from .cli_node_api import ( … … 59 55 60 56 class RunBinTahoeMixin(object): 61 62 @inlineCallbacks63 def find_import_location(self):64 res = yield self.run_bintahoe(["--version-and-path"])65 out, err, rc_or_sig = res66 self.assertEqual(rc_or_sig, 0, res)67 lines = out.splitlines()68 tahoe_pieces = lines[0].split()69 self.assertEqual(tahoe_pieces[0], "%s:" % (__appname__,), (tahoe_pieces, res))70 returnValue(tahoe_pieces[-1].strip("()"))71 72 57 def run_bintahoe(self, args, stdin=None, python_options=[], env=None): 73 58 command = sys.executable … … 87 72 88 73 class BinTahoe(common_util.SignalMixin, unittest.TestCase, RunBinTahoeMixin): 89 @inlineCallbacks90 def test_the_right_code(self):91 # running "tahoe" in a subprocess should find the same code that92 # holds this test file, else something is weird93 test_path = os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))94 bintahoe_import_path = yield self.find_import_location()95 96 same = (bintahoe_import_path == test_path)97 if not same:98 msg = ("My tests and my 'tahoe' executable are using different paths.\n"99 "tahoe: %r\n"100 "tests: %r\n"101 "( according to the test source filename %r)\n" %102 (bintahoe_import_path, test_path, srcfile))103 104 if (not isinstance(rootdir, unicode) and105 rootdir.decode(get_filesystem_encoding(), 'replace') != rootdir):106 msg += ("However, this may be a false alarm because the import path\n"107 "is not representable in the filesystem encoding.")108 raise unittest.SkipTest(msg)109 else:110 msg += "Please run the tests in a virtualenv that includes both the Tahoe-LAFS library and the 'tahoe' executable."111 self.fail(msg)112 113 def test_path(self):114 d = self.run_bintahoe(["--version-and-path"])115 def _cb(res):116 out, err, rc_or_sig = res117 self.failUnlessEqual(rc_or_sig, 0, str(res))118 119 # Fail unless the __appname__ package is *this* version *and*120 # was loaded from *this* source directory.121 122 required_verstr = str(allmydata.__version__)123 124 self.failIfEqual(required_verstr, "unknown",125 "We don't know our version, because this distribution didn't come "126 "with a _version.py and 'setup.py update_version' hasn't been run.")127 128 srcdir = os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))129 info = repr((res, allmydata.__appname__, required_verstr, srcdir))130 131 appverpath = out.split(')')[0]132 (appverfull, path) = appverpath.split('] (')133 (appver, comment) = appverfull.split(' [')134 (branch, full_version) = comment.split(': ')135 (app, ver) = appver.split(': ')136 137 self.failUnlessEqual(app, allmydata.__appname__, info)138 norm_ver = normalized_version(ver)139 norm_required = normalized_version(required_verstr)140 self.failUnlessEqual(norm_ver, norm_required, info)141 self.failUnlessEqual(path, srcdir, info)142 self.failUnlessEqual(branch, allmydata.branch)143 self.failUnlessEqual(full_version, allmydata.full_version)144 d.addCallback(_cb)145 return d146 147 74 def test_unicode_arguments_and_output(self): 148 75 tricky = u"\u2621" … … 166 93 def _cb(res): 167 94 out, err, rc_or_sig = res 168 self. failUnlessEqual(rc_or_sig, 0, str(res))169 self. failUnless(out.startswith(allmydata.__appname__+':'), str(res))95 self.assertEqual(rc_or_sig, 0, str(res)) 96 self.assertTrue(out.startswith(allmydata.__appname__ + '/'), str(res)) 170 97 d.addCallback(_cb) 171 98 return d -
TabularUnified src/allmydata/test/web/test_introducer.py ¶
rda0fe23 ra0a39d3 128 128 self, 129 129 soup, 130 u"%s: %s" % (allmydata.__appname__, allmydata.__version__),130 allmydata.__full_version__, 131 131 ) 132 132 assert_soup_has_text(self, soup, u"no peers!") -
TabularUnified src/allmydata/test/web/test_web.py ¶
rda0fe23 ra0a39d3 7 7 from bs4 import BeautifulSoup 8 8 9 from twisted.python.filepath import ( 10 FilePath, 11 ) 9 12 from twisted.application import service 10 13 from twisted.internet import defer … … 317 320 self.clock = Clock() 318 321 self.fakeTime = 86460 # 1d 0h 1m 0s 319 self.ws = webish.WebishServer(self.s, "0", staticdir=self.staticdir, 320 clock=self.clock, now_fn=lambda:self.fakeTime) 322 tempdir = FilePath(self.mktemp()) 323 tempdir.makedirs() 324 self.ws = webish.WebishServer( 325 self.s, 326 "0", 327 tempdir=tempdir.path, 328 staticdir=self.staticdir, 329 clock=self.clock, 330 now_fn=lambda:self.fakeTime, 331 ) 321 332 self.ws.setServiceParent(self.s) 322 333 self.webish_port = self.ws.getPortnum() -
TabularUnified src/allmydata/test/web/test_webish.py ¶
rda0fe23 ra0a39d3 5 5 from uuid import ( 6 6 uuid4, 7 ) 8 from errno import ( 9 EACCES, 10 ) 11 from io import ( 12 BytesIO, 13 ) 14 15 from hypothesis import ( 16 given, 17 ) 18 from hypothesis.strategies import ( 19 integers, 7 20 ) 8 21 … … 13 26 MatchesAll, 14 27 Not, 15 ) 16 28 IsInstance, 29 HasLength, 30 ) 31 32 from twisted.python.runtime import ( 33 platform, 34 ) 17 35 from twisted.python.filepath import ( 18 36 FilePath, … … 31 49 from ...webish import ( 32 50 TahoeLAFSRequest, 33 tahoe_lafs_site,51 TahoeLAFSSite, 34 52 ) 35 53 … … 97 115 class TahoeLAFSSiteTests(SyncTestCase): 98 116 """ 99 Tests for the ``Site`` created by ``tahoe_lafs_site``.117 Tests for ``TahoeLAFSSite``. 100 118 """ 101 119 def _test_censoring(self, path, censored): … … 113 131 logPath = self.mktemp() 114 132 115 site = tahoe_lafs_site(Resource(), logPath=logPath)133 site = TahoeLAFSSite(self.mktemp(), Resource(), logPath=logPath) 116 134 site.startFactory() 117 135 … … 170 188 b"/uri?uri=[CENSORED]", 171 189 ) 190 191 def _create_request(self, tempdir): 192 """ 193 Create and return a new ``TahoeLAFSRequest`` hooked up to a 194 ``TahoeLAFSSite``. 195 196 :param bytes tempdir: The temporary directory to give to the site. 197 198 :return TahoeLAFSRequest: The new request instance. 199 """ 200 site = TahoeLAFSSite(tempdir.path, Resource(), logPath=self.mktemp()) 201 site.startFactory() 202 203 channel = DummyChannel() 204 channel.site = site 205 request = TahoeLAFSRequest(channel) 206 return request 207 208 @given(integers(min_value=0, max_value=1024 * 1024 - 1)) 209 def test_small_content(self, request_body_size): 210 """ 211 A request body smaller than 1 MiB is kept in memory. 212 """ 213 tempdir = FilePath(self.mktemp()) 214 request = self._create_request(tempdir) 215 request.gotLength(request_body_size) 216 self.assertThat( 217 request.content, 218 IsInstance(BytesIO), 219 ) 220 221 def _large_request_test(self, request_body_size): 222 """ 223 Assert that when a request with a body of of the given size is received 224 its content is written to the directory the ``TahoeLAFSSite`` is 225 configured with. 226 """ 227 tempdir = FilePath(self.mktemp()) 228 tempdir.makedirs() 229 request = self._create_request(tempdir) 230 231 # So. Bad news. The temporary file for the uploaded content is 232 # unnamed (and this isn't even necessarily a bad thing since it is how 233 # you get automatic on-process-exit cleanup behavior on POSIX). It's 234 # not visible by inspecting the filesystem. It has no name we can 235 # discover. Then how do we verify it is written to the right place? 236 # The question itself is meaningless if we try to be too precise. It 237 # *has* no filesystem location. However, it is still stored *on* some 238 # filesystem. We still want to make sure it is on the filesystem we 239 # specified because otherwise it might be on a filesystem that's too 240 # small or undesirable in some other way. 241 # 242 # I don't know of any way to ask a file descriptor which filesystem 243 # it's on, either, though. It might be the case that the [f]statvfs() 244 # result could be compared somehow to infer the filesystem but 245 # ... it's not clear what the failure modes might be there, across 246 # different filesystems and runtime environments. 247 # 248 # Another approach is to make the temp directory unwriteable and 249 # observe the failure when an attempt is made to create a file there. 250 # This is hardly a lovely solution but at least it's kind of simple. 251 # 252 # It would be nice if it worked consistently cross-platform but on 253 # Windows os.chmod is more or less broken. 254 if platform.isWindows(): 255 request.gotLength(request_body_size) 256 self.assertThat( 257 tempdir.children(), 258 HasLength(1), 259 ) 260 else: 261 tempdir.chmod(0o550) 262 with self.assertRaises(OSError) as ctx: 263 request.gotLength(request_body_size) 264 raise Exception( 265 "OSError not raised, instead tempdir.children() = {}".format( 266 tempdir.children(), 267 ), 268 ) 269 270 self.assertThat( 271 ctx.exception.errno, 272 Equals(EACCES), 273 ) 274 275 def test_unknown_request_size(self): 276 """ 277 A request body with an unknown size is written to a file in the temporary 278 directory passed to ``TahoeLAFSSite``. 279 """ 280 self._large_request_test(None) 281 282 @given(integers(min_value=1024 * 1024)) 283 def test_large_request(self, request_body_size): 284 """ 285 A request body of 1 MiB or more is written to a file in the temporary 286 directory passed to ``TahoeLAFSSite``. 287 """ 288 self._large_request_test(request_body_size) 289 172 290 173 291 def param(name, value): -
TabularUnified src/allmydata/util/_python3.py ¶
rda0fe23 ra0a39d3 57 57 "allmydata.mutable.common", 58 58 "allmydata.mutable.filenode", 59 "allmydata.mutable.layout", 59 60 "allmydata.mutable.publish", 61 "allmydata.mutable.repairer", 62 "allmydata.mutable.retrieve", 63 "allmydata.mutable.servermap", 60 64 "allmydata.node", 61 65 "allmydata.storage_client", … … 156 160 "allmydata.test.test_uri", 157 161 "allmydata.test.test_util", 158 "allmydata.test.test_version",159 162 ] -
TabularUnified src/allmydata/util/log.py ¶
rda0fe23 ra0a39d3 12 12 if PY2: 13 13 from 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 14 from six import ensure_str 14 15 15 16 from pyutil import nummedobj … … 56 57 if pmsgid is None: 57 58 pmsgid = self._grandparentmsgid 59 kwargs = {ensure_str(k): v for (k, v) in kwargs.items()} 58 60 msgid = log.msg(msg, facility=facility, parent=pmsgid, *args, **kwargs) 59 61 if self._parentmsgid is None: -
TabularUnified src/allmydata/web/introweb.py ¶
rda0fe23 ra0a39d3 7 7 import allmydata 8 8 import json 9 from allmydata.version_checks import get_package_versions_string10 9 from allmydata.util import idlib 11 10 from allmydata.web.common import ( … … 90 89 self.node_data_dict = { 91 90 "my_nodeid": idlib.nodeid_b2a(self.introducer_node.nodeid), 92 "version": get_package_versions_string(),91 "version": allmydata.__full_version__, 93 92 "import_path": str(allmydata).replace("/", "/ "), # XXX kludge for wrapping 94 93 "rendered_at": render_time(time.time()), -
TabularUnified src/allmydata/web/root.py ¶
rda0fe23 ra0a39d3 22 22 23 23 import allmydata # to display import path 24 from allmydata.version_checks import get_package_versions_string25 24 from allmydata.util import log 26 25 from allmydata.interfaces import IFileNode … … 567 566 @renderer 568 567 def version(self, req, tag): 569 return tag( get_package_versions_string())568 return tag(allmydata.__full_version__) 570 569 571 570 @renderer -
TabularUnified src/allmydata/webish.py ¶
rda0fe23 ra0a39d3 1 1 from six import ensure_str 2 2 3 import re, time 4 5 from functools import ( 6 partial, 7 ) 3 import re, time, tempfile 4 8 5 from cgi import ( 9 6 FieldStorage, 7 ) 8 from io import ( 9 BytesIO, 10 10 ) 11 11 … … 151 151 152 152 153 tahoe_lafs_site = partial( 154 Site, 155 requestFactory=TahoeLAFSRequest, 156 logFormatter=_logFormatter, 157 ) 153 class TahoeLAFSSite(Site, object): 154 """ 155 The HTTP protocol factory used by Tahoe-LAFS. 156 157 Among the behaviors provided: 158 159 * A configurable temporary directory where large request bodies can be 160 written so they don't stay in memory. 161 162 * A log formatter that writes some access logs but omits capability 163 strings to help keep them secret. 164 """ 165 requestFactory = TahoeLAFSRequest 166 167 def __init__(self, tempdir, *args, **kwargs): 168 Site.__init__(self, *args, logFormatter=_logFormatter, **kwargs) 169 self._tempdir = tempdir 170 171 def getContentFile(self, length): 172 if length is None or length >= 1024 * 1024: 173 return tempfile.TemporaryFile(dir=self._tempdir) 174 return BytesIO() 158 175 159 176 … … 161 178 name = "webish" 162 179 163 def __init__(self, client, webport, nodeurl_path=None, staticdir=None,180 def __init__(self, client, webport, tempdir, nodeurl_path=None, staticdir=None, 164 181 clock=None, now_fn=time.time): 165 182 service.MultiService.__init__(self) … … 171 188 172 189 self.root = root.Root(client, clock, now_fn) 173 self.buildServer(webport, nodeurl_path, staticdir)190 self.buildServer(webport, tempdir, nodeurl_path, staticdir) 174 191 175 192 # If set, clock is a twisted.internet.task.Clock that the tests … … 181 198 self.root.putChild(b"storage-plugins", StoragePlugins(client)) 182 199 183 def buildServer(self, webport, nodeurl_path, staticdir):200 def buildServer(self, webport, tempdir, nodeurl_path, staticdir): 184 201 self.webport = webport 185 self.site = tahoe_lafs_site(self.root)202 self.site = TahoeLAFSSite(tempdir, self.root) 186 203 self.staticdir = staticdir # so tests can check 187 204 if staticdir: … … 261 278 service.MultiService.__init__(self) 262 279 self.root = introweb.IntroducerRoot(introducer) 263 self.buildServer(webport, nodeurl_path, staticdir)280 self.buildServer(webport, tempfile.tempdir, nodeurl_path, staticdir)
Note: See TracChangeset
for help on using the changeset viewer.