Commit Graph

3554 Commits

Author SHA1 Message Date
Jean-Paul Calderone
538cefed3d Update Twisted Web-based render to use our request
Also to do one other thing Twisted Web does for resources automatically -
handle UnsupportedMethod
2020-10-21 08:51:45 -04:00
Jean-Paul Calderone
637bb2e576 De-Nevow `render` 2020-10-21 08:51:25 -04:00
Jean-Paul Calderone
7f02128973 [wip] test form posts 2020-10-21 08:29:41 -04:00
Jean-Paul Calderone
0dcc3e13c0 Remove unused imports 2020-10-21 08:21:29 -04:00
Jean-Paul Calderone
7ca8ede88c Merge remote-tracking branch 'origin/master' into 3428.dont-return-deferred-to-twistedweb.2 2020-10-21 07:35:10 -04:00
Jean-Paul Calderone
7ce2122e71 one more reference 2020-10-21 07:26:12 -04:00
Jean-Paul Calderone
d8b6e36c6f docstring for StaticResource 2020-10-21 07:23:16 -04:00
Jean-Paul Calderone
1ed74604c7 Use twisted.web.server.Request instead of DummyRequest in the tests
Always prefer the real thing if possible
2020-10-21 07:15:36 -04:00
Jean-Paul Calderone
3192715e37 everything newstyle 2020-10-19 14:37:03 -04:00
Jean-Paul Calderone
a9e9efb336 direct tests for @render_exception 2020-10-19 14:26:12 -04:00
Jean-Paul Calderone
72e60f8301 Fix imports 2020-10-18 11:12:44 -04:00
Jean-Paul Calderone
e710fd883a Add a Twisted Web-based renderer and start using it on Python 3
This could be the thing that eventually replaces the Nevow-based testing
renderer on Python 2 as well.
2020-10-18 11:00:57 -04:00
Jean-Paul Calderone
fc1f43c7a3 How does it go without the type check
This is for py36:

> TypeError: helper_furl must be bytes, got 'pb://kl5iekm6itcyjejirxva2upthepsasnn@bogus:1234/frekgeq7gsongibyeuvzmvqoyf4h5pcx' instead
2020-10-16 19:07:28 -04:00
Jean-Paul Calderone
a403d25146 Merge remote-tracking branch 'origin/master' into 3468.offloaded-test-coverage 2020-10-16 14:34:35 -04:00
Jean-Paul Calderone
85bb0a7834 Get rid of the original token-based authorization helper
It was only used by magic-folder and that's gone now.  We have a different
authorization helper for other things now, allmydata.web.private.
2020-10-16 14:14:15 -04:00
Itamar Turner-Trauring
6aa96bbb8d Port test_node.py to Python 3. 2020-10-16 11:23:38 -04:00
Itamar Turner-Trauring
f7a89f76e7 All tests pass on Python 3. 2020-10-16 11:20:10 -04:00
Itamar Turner-Trauring
51d472e221 More progress towards passing tests on Python 3. 2020-10-16 11:13:11 -04:00
Itamar Turner-Trauring
bcd7cdf86f Some passing tests on Python 3. 2020-10-16 10:47:49 -04:00
Jean-Paul Calderone
32051f93b9 Merge remote-tracking branch 'origin/master' into 3428.dont-return-deferred-to-twistedweb.2 2020-10-16 10:37:54 -04:00
Itamar Turner-Trauring
c2fe5a65a6
Merge pull request #847 from tahoe-lafs/3459.test-checker-python-3
Port test_checker.py to Python 3

Fixes ticket:3459
2020-10-16 10:31:25 -04:00
Jean-Paul Calderone
a73a919a20 flakes 2020-10-16 10:22:42 -04:00
Jean-Paul Calderone
a1f1f00be7 Use the more feaetureful rendering helper 2020-10-16 09:53:30 -04:00
Jean-Paul Calderone
f733a244aa Just gonna produce text instead 2020-10-16 09:52:26 -04:00
Jean-Paul Calderone
07246b3509 Render requests more thoroughly 2020-10-16 09:52:10 -04:00
Jean-Paul Calderone
69c7c40510 handle Deferred from render 2020-10-16 09:51:42 -04:00
Jean-Paul Calderone
733d393a07
Merge pull request #840 from tahoe-lafs/3454.unskip-test_python3
Unskip the Python 3 porting test on Python 2

Fixes: ticket:3454
2020-10-15 17:32:59 -04:00
Jean-Paul Calderone
4d56b5f4ed
Merge pull request #858 from tahoe-lafs/3471.immediate-localwrapper
Allow LocalWrapper to be immediate

Fixes: ticket:3471
2020-10-15 13:15:35 -04:00
Jean-Paul Calderone
2960a270ce Declare and document what LocalWrapper is/does 2020-10-15 12:00:03 -04:00
Itamar Turner-Trauring
707ab50606 Test BytesJSONEncoder with Unicode. 2020-10-15 08:37:09 -04:00
Itamar Turner-Trauring
b658a66e7f Merge remote-tracking branch 'origin/master' into 3459.test-checker-python-3 2020-10-15 08:32:53 -04:00
Itamar Turner-Trauring
b094a00458
Merge pull request #860 from tahoe-lafs/3473-mutable-tests-part-1-python-3
Port allmydata.mutable.tests to Python 3: part 1 of N

Fixes ticket:3473
2020-10-15 08:27:45 -04:00
Itamar Turner-Trauring
fecbbb6733 Port to Python 3. 2020-10-14 16:05:02 -04:00
Itamar Turner-Trauring
7faea936df Tests pass on Python 3. 2020-10-14 16:03:53 -04:00
Itamar Turner-Trauring
b5e54f2ed2 Port to Python 3. 2020-10-14 15:50:02 -04:00
Itamar Turner-Trauring
fa92fde04a Port to Python 3. 2020-10-14 15:46:37 -04:00
Itamar Turner-Trauring
43f5a25ec2 Tests pass on Python 3. 2020-10-14 15:45:09 -04:00
Jean-Paul Calderone
40e0ef0fad Directly test CHKCheckerAndUEBFetcher cases 2020-10-14 12:02:56 -04:00
Jean-Paul Calderone
b0159a898e Parameterize the callRemote scheduling 2020-10-14 11:08:40 -04:00
Jean-Paul Calderone
9a18843bb1 finish the comment 2020-10-14 10:58:50 -04:00
Jean-Paul Calderone
555b751af0 Further expand existing test coverage by reducing fake quantities
Helper_fake_upload is replaced by more narrowly focused CHKUploadHelper_fake
2020-10-14 10:58:50 -04:00
Jean-Paul Calderone
4e46f9ae12 expand the already-uploaded test for the helper to cover more
shrink the amount of fake code being used and increase the amount of real code
being used
2020-10-14 10:58:50 -04:00
Jean-Paul Calderone
ef11eeb4a2 exercise concurrent upload 2020-10-14 10:58:50 -04:00
Chad Whitacre
a0963fc2da Keep future.builtins imports consistent
- remove int from a stock import
- comment a non-stock import
2020-10-13 08:39:25 -04:00
Chad Whitacre
574c63d350 Port immutable.offloaded to Python 3 2020-10-12 07:25:44 -04:00
Itamar Turner-Trauring
17f0676b3f
Merge branch 'master' into 3459.test-checker-python-3 2020-10-09 10:22:17 -04:00
Ross Patterson
95f2d53f92 chore(refs #3455) Address feedback, BBB comments
https://github.com/tahoe-lafs/tahoe-lafs/pull/845#issuecomment-704469561
2020-10-07 12:28:41 -07:00
Chad Whitacre
e78afd877c
Merge pull request #846 from tahoe-lafs/3456.tweak-docstring
Tweak docstring on FakeCanary
2020-10-06 06:19:54 -04:00
Ross Patterson
e89bbe1601
Merge pull request #845 from tahoe-lafs/3455.python-3-port-node-round1
3455: Round 1 of porting `allmydata.node`
2020-10-05 08:32:28 -07:00
Itamar Turner-Trauring
dd863a003f Port test_checker.py to Python 3. 2020-10-05 11:12:06 -04:00
Itamar Turner-Trauring
96231fab5f Support bytes in JSON output. 2020-10-05 11:01:11 -04:00
Chad Whitacre
ad4d7f7612 Tweak docstring
Since this class is used in multiple test modules now, it makes sense to
keep it in common_util instead of test_storage.
2020-10-05 08:34:41 -04:00
Chad Whitacre
2fe2acf4c7
Merge pull request #842 from tahoe-lafs/3456.bye-bye-common_py3
Fold common_py3 back into other files
2020-10-05 08:03:18 -04:00
Ross Patterson
f1da68f340 feat(py3): Fix config from string compatibility
I did an audit of the code base and AFAICT the `node.config_from_string(...)` is only
used internally.  Much of that usage is in tests where most of the usages feed in
non-specific, simple `"..."` string literals (IOW, bytes under py2, unicode under py3) while one
test module used `b"..."` byte string literals.  Given all that it seems to me that the
best goal would be to use simple string literals throughout the usage of
`node.config_from_string(...)` and have only one special case in that function to handle
the difference between versions.

I just discovered that running the test with `TEST_SUITE=allmydata` doesn't run the
tests in `allmydata.test.test_node` but running them with
`TEST_SUITE=allmydata.test.test_node` does run them.  I'm trying to figure out why that
is, but in the meantime here are the differences in the Python 3 test output when
running just the `allmydata.test.test_node` tests.  This changes converts 11 tests from
errros to success, changes the specific errors for others and improves coverage a bit:

```diff
--- ../../.tox/make-test-py3-all-old.log	2020-10-01 11:56:15.428609940 -0700
+++ ../../.tox/make-test-py3-all-new.log	2020-10-01 11:56:55.052792565 -0700
@@ -95,9 +95,9 @@
     tor_provider,
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/introducer/server.py", line 87, in __init__
     node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 734, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 739, in __init__
     self.setup_logging()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 826, in setup_logging
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 831, in setup_logging
     newmeth = types.UnboundMethodType(formatTimeTahoeStyle, ob, ob.__class__)
 builtins.AttributeError: module 'types' has no attribute 'UnboundMethodType'

@@ -158,53 +158,29 @@
 (#.### secs)
 allmydata.test.test_node.TestCase.test_config_required ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestCase.test_location1 ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 112, in test_location1
-    tub_location="192.0.2.0:1234")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
-    tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestCase.test_location1 ... [OK]
 (#.### secs)
 allmydata.test.test_node.TestCase.test_location2 ... Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 117, in test_location2
     tub_location="192.0.2.0:1234,example.org:8091")
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
     tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 65, in testing_tub
+    cert_filename='DEFAULT_CERTFILE_BLANK'
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 669, in create_main_tub
+    portlocation = _tub_portlocation(config)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 596, in _tub_portlocation
+    tubport = _convert_tub_port(file_tubport)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 552, in _convert_tub_port
+    if re.search(r'^\d+$', s):
+  File "/usr/lib/python3.6/re.py", line 182, in search
+    return _compile(pattern, flags).search(string)
+builtins.TypeError: cannot use a string pattern on a bytes-like object
 [ERROR]
 (#.### secs)
-allmydata.test.test_node.TestCase.test_location_auto_and_explicit ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 142, in test_location_auto_and_explicit
-    local_addresses=["127.0.0.1", "192.0.2.0", "example.com:4321"],
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
-    tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestCase.test_location_auto_and_explicit ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestCase.test_location_not_set ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 128, in test_location_not_set
-    local_addresses=["127.0.0.1", "192.0.2.0"],
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
-    tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestCase.test_location_not_set ... [OK]
 (#.### secs)
 allmydata.test.test_node.TestCase.test_logdir_is_str ... Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 340, in test_logdir_is_str
@@ -215,27 +191,31 @@
     storage_broker,
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/client.py", line 676, in __init__
     node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 734, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 739, in __init__
     self.setup_logging()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 826, in setup_logging
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 831, in setup_logging
     newmeth = types.UnboundMethodType(formatTimeTahoeStyle, ob, ob.__class__)
 builtins.AttributeError: module 'types' has no attribute 'UnboundMethodType'
 [ERROR]
 (#.### secs)
 allmydata.test.test_node.TestCase.test_private_config ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 259, in test_private_config
-    config = config_from_string(basedir, "", "")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 261, in test_private_config
+    self.assertEqual(config.get_private_config("already"), "secret")
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_synctest.py", line 434, in assertEqual
+    super(_Assertions, self).assertEqual(first, second, msg)
+  File "/usr/lib/python3.6/unittest/case.py", line 829, in assertEqual
+    assertion_func(first, second, msg=msg)
+  File "/usr/lib/python3.6/unittest/case.py", line 822, in _baseAssertEqual
+    raise self.failureException(msg)
+twisted.trial.unittest.FailTest: b'secret' != 'secret'
+[FAILURE]
 (#.### secs)
 allmydata.test.test_node.TestCase.test_private_config_missing ... [OK]
 (#.### secs)
 allmydata.test.test_node.TestCase.test_private_config_unreadable ... Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 213, in test_private_config_unreadable
     config.get_or_create_private_config("foo", "contents")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 369, in get_or_create_private_config
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 374, in get_or_create_private_config
     fileutil.write(privname, value)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/util/fileutil.py", line 275, in write
     f.write(data)
@@ -258,77 +238,33 @@
 (#.### secs)
 allmydata.test.test_node.TestCase.test_timestamp ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestCase.test_write_config_unwritable_file ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 288, in test_write_config_unwritable_file
-    config = config_from_string(basedir, "", "")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestCase.test_write_config_unwritable_file ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_disabled_port_not_tub ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 488, in test_disabled_port_not_tub
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_disabled_port_not_tub ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_disabled_tub_not_port ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 506, in test_disabled_tub_not_port
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_disabled_tub_not_port ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_empty_tub_location ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 470, in test_empty_tub_location
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_empty_tub_location ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_empty_tub_port ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 453, in test_empty_tub_port
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_empty_tub_port ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_parsing_all_disabled ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 439, in test_parsing_all_disabled
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_parsing_all_disabled ... [OK]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_parsing_defaults ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 392, in test_parsing_defaults
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_parsing_defaults ... [OK]
 (#.### secs)
 allmydata.test.test_node.TestMissingPorts.test_parsing_location_complex ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 415, in test_parsing_location_complex
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 418, in test_parsing_location_complex
+    tubport, tublocation = _tub_portlocation(config)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 596, in _tub_portlocation
+    tubport = _convert_tub_port(file_tubport)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 552, in _convert_tub_port
+    if re.search(r'^\d+$', s):
+  File "/usr/lib/python3.6/re.py", line 182, in search
+    return _compile(pattern, flags).search(string)
+builtins.TypeError: cannot use a string pattern on a bytes-like object
 [ERROR]
 (#.### secs)
-allmydata.test.test_node.TestMissingPorts.test_parsing_tcp ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 370, in test_parsing_tcp
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-[ERROR]
+allmydata.test.test_node.TestMissingPorts.test_parsing_tcp ... [OK]
 (#.### secs)

 ===============================================================================
@@ -415,9 +351,9 @@
     tor_provider,
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/introducer/server.py", line 87, in __init__
     node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 734, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 739, in __init__
     self.setup_logging()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 826, in setup_logging
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 831, in setup_logging
     newmeth = types.UnboundMethodType(formatTimeTahoeStyle, ob, ob.__class__)
 builtins.AttributeError: module 'types' has no attribute 'UnboundMethodType'

@@ -449,6 +385,20 @@

 allmydata.test.test_node.TestCase.test_config_items
 ===============================================================================
+[FAIL]
+Traceback (most recent call last):
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 261, in test_private_config
+    self.assertEqual(config.get_private_config("already"), "secret")
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_synctest.py", line 434, in assertEqual
+    super(_Assertions, self).assertEqual(first, second, msg)
+  File "/usr/lib/python3.6/unittest/case.py", line 829, in assertEqual
+    assertion_func(first, second, msg=msg)
+  File "/usr/lib/python3.6/unittest/case.py", line 822, in _baseAssertEqual
+    raise self.failureException(msg)
+twisted.trial.unittest.FailTest: b'secret' != 'secret'
+
+allmydata.test.test_node.TestCase.test_private_config
+===============================================================================
 [ERROR]
 Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 657, in test_disabled
@@ -503,62 +453,26 @@
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 112, in test_location1
-    tub_location="192.0.2.0:1234")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
-    tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestCase.test_location1
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 117, in test_location2
     tub_location="192.0.2.0:1234,example.org:8091")
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
     tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 65, in testing_tub
+    cert_filename='DEFAULT_CERTFILE_BLANK'
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 669, in create_main_tub
+    portlocation = _tub_portlocation(config)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 596, in _tub_portlocation
+    tubport = _convert_tub_port(file_tubport)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 552, in _convert_tub_port
+    if re.search(r'^\d+$', s):
+  File "/usr/lib/python3.6/re.py", line 182, in search
+    return _compile(pattern, flags).search(string)
+builtins.TypeError: cannot use a string pattern on a bytes-like object

 allmydata.test.test_node.TestCase.test_location2
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 142, in test_location_auto_and_explicit
-    local_addresses=["127.0.0.1", "192.0.2.0", "example.com:4321"],
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
-    tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestCase.test_location_auto_and_explicit
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 128, in test_location_not_set
-    local_addresses=["127.0.0.1", "192.0.2.0"],
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 99, in _test_location
-    tub = testing_tub(config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 53, in testing_tub
-    config = config_from_string(basedir, 'DEFAULT_PORTNUMFILE_BLANK', config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestCase.test_location_not_set
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 340, in test_logdir_is_str
     yield client.create_client(basedir)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
@@ -567,9 +481,9 @@
     storage_broker,
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/client.py", line 676, in __init__
     node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 734, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 739, in __init__
     self.setup_logging()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 826, in setup_logging
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 831, in setup_logging
     newmeth = types.UnboundMethodType(formatTimeTahoeStyle, ob, ob.__class__)
 builtins.AttributeError: module 'types' has no attribute 'UnboundMethodType'

@@ -577,19 +491,9 @@
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 259, in test_private_config
-    config = config_from_string(basedir, "", "")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestCase.test_private_config
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 213, in test_private_config_unreadable
     config.get_or_create_private_config("foo", "contents")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 369, in get_or_create_private_config
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 374, in get_or_create_private_config
     fileutil.write(privname, value)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/util/fileutil.py", line 275, in write
     f.write(data)
@@ -607,97 +511,21 @@
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 288, in test_write_config_unwritable_file
-    config = config_from_string(basedir, "", "")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestCase.test_write_config_unwritable_file
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 488, in test_disabled_port_not_tub
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_disabled_port_not_tub
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 506, in test_disabled_tub_not_port
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_disabled_tub_not_port
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 470, in test_empty_tub_location
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_empty_tub_location
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 453, in test_empty_tub_port
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_empty_tub_port
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 439, in test_parsing_all_disabled
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_parsing_all_disabled
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 392, in test_parsing_defaults
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_parsing_defaults
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 415, in test_parsing_location_complex
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 418, in test_parsing_location_complex
+    tubport, tublocation = _tub_portlocation(config)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 596, in _tub_portlocation
+    tubport = _convert_tub_port(file_tubport)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 552, in _convert_tub_port
+    if re.search(r'^\d+$', s):
+  File "/usr/lib/python3.6/re.py", line 182, in search
+    return _compile(pattern, flags).search(string)
+builtins.TypeError: cannot use a string pattern on a bytes-like object

 allmydata.test.test_node.TestMissingPorts.test_parsing_location_complex
-===============================================================================
-[ERROR]
-Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 370, in test_parsing_tcp
-    config = config_from_string(self.basedir, "portnum", config_data)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 209, in config_from_string
-    parser.readfp(BytesIO(config_str))
-builtins.TypeError: a bytes-like object is required, not 'str'
-
-allmydata.test.test_node.TestMissingPorts.test_parsing_tcp
 -------------------------------------------------------------------------------
-Ran 34 tests in 2.788s
+Ran 34 tests in 2.516s

-FAILED (failures=4, errors=21, successes=9)
+FAILED (failures=5, errors=9, successes=20)
 Name                                                 Stmts   Miss Branch BrPart  Cover   Missing
 ------------------------------------------------------------------------------------------------
 src/allmydata/__init__.py                               16      4      0      0    75%   18-22, 28-32
@@ -751,7 +579,7 @@
 src/allmydata/mutable/repairer.py                       57     37     18      0    29%   13, 15, 17, 19, 29-34, 65-71, 74-126, 129-131
 src/allmydata/mutable/retrieve.py                      489    411    120      0    13%   29-43, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 67-69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89-90, 105-160, 164, 167-171, 174-175, 186-193, 201-208, 211-212, 223-227, 230-232, 236-254, 257-275, 278-283, 286-332, 344-354, 362-454, 485-516, 529-540, 564-578, 586-597, 607-633, 643-663, 671-699, 712-729, 738-798, 806-829, 839-889, 897-905, 909-910, 919-941, 950-971, 981-994, 999-1005
 src/allmydata/mutable/servermap.py                     623    524    198      0    12%   26-38, 41-42, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 70, 72, 74, 76, 78, 80, 82, 116-124, 130-139, 142, 145, 148, 159-161, 165, 170-172, 175, 177, 180-181, 183, 186-199, 202, 206, 213, 217-220, 225-228, 231, 234-238, 243-252, 255-259, 263-265, 269-275, 280-290, 295-305, 311-315, 320-322, 328-350, 358-363, 370-372, 379, 390-450, 454, 457-461, 466-545, 549-557, 560-575, 578-593, 596-613, 623-638, 642-779, 787, 791-799, 803-804, 816-880, 883-904, 910-914, 919-920, 928-944, 960-974, 981-998, 1002-1012, 1020-1183, 1186-1205, 1209-1225, 1228-1229
-src/allmydata/node.py                                  388    106    146     39    69%   120, 132, 190, 211-213, 241, 243-245, 278, 284, 291-295, 303-306, 315, 320, 339, 341, 361, 368, 370, 377-379, 393-396, 422, 424, 449, 453, 490, 493, 500, 511-512, 547-549, 566, 574, 581, 583, 590-591, 597, 601, 612, 622-634, 679, 681, 736-750, 756, 764, 792-805, 808-809, 814-815, 827-846, 189->190, 204->208, 240->241, 242->243, 277->278, 314->315, 319->320, 338->339, 340->341, 360->361, 365->368, 391->393, 421->422, 423->424, 448->449, 451->453, 489->490, 492->493, 499->500, 510->511, 565->566, 567->570, 573->574, 575->578, 580->581, 582->583, 585->597, 589->590, 600->601, 603->606, 610->616, 611->612, 618->622, 673->679, 680->681, 763->764, 766->768, 821->830, 823->821
+src/allmydata/node.py                                  391     87    148     30    75%   20, 125, 137, 195, 246, 248-250, 283, 289, 308-311, 320, 325, 344, 346, 366, 373, 375, 382-384, 398-401, 427, 429, 454, 458, 495, 498, 505, 516-517, 606, 617, 634-638, 684, 686, 741-755, 761, 769, 797-810, 813-814, 819-820, 832-851, 19->20, 194->195, 209->213, 245->246, 247->248, 282->283, 319->320, 324->325, 343->344, 345->346, 365->366, 370->373, 396->398, 426->427, 428->429, 453->454, 456->458, 494->495, 497->498, 504->505, 515->516, 605->606, 616->617, 627->634, 678->684, 685->686, 768->769, 771->773, 826->835, 828->826
 src/allmydata/nodemaker.py                              97     71     38      0    21%   23-33, 36, 38, 41, 44-47, 49, 53-95, 98-115, 118-125, 129-138, 141-150
 src/allmydata/scripts/admin.py                          51     31      2      0    38%   9-14, 17-21, 25, 28, 31-37, 40-46, 56-57, 59, 61-66, 74-78
 src/allmydata/scripts/backupdb.py                      146    146     14      0     0%   1-341
@@ -810,7 +638,7 @@
 src/allmydata/util/dictutil.py                          38     22     12      1    34%   16, 21-24, 27-31, 34-38, 55-56, 59-60, 63-64, 71, 77-78, 12->16
 src/allmydata/util/eliotutil.py                        115     68     24      0    35%   82-85, 91-94, 104, 117-122, 129-139, 151, 155-159, 163-167, 179-186, 198-199, 202-210, 222-226, 231-247, 250, 266-294, 308-312
 src/allmydata/util/encodingutil.py                     217    123     80     12    36%   18, 37-38, 41, 43, 52-53, 69, 75-78, 102, 108, 114-122, 130-134, 145-155, 164, 173-175, 178-181, 187, 196-213, 217-231, 237-243, 279-282, 291-296, 314, 320-322, 327, 334-340, 343-355, 358-363, 366-367, 370-373, 379, 395-405, 412-420, 423, 429, 16->18, 36->37, 40->41, 42->43, 66->69, 72->74, 74->75, 278->279, 285->295, 288->291, 299->310, 319->320
-src/allmydata/util/fileutil.py                         343    244    120     13    25%   15, 23-25, 47-55, 71-85, 96-97, 100, 103, 106, 109, 115-116, 119-125, 128, 131, 134, 137-138, 142-145, 151-153, 158, 166-176, 179-184, 201-203, 214-237, 241-244, 247-254, 262, 279, 282-290, 293-304, 326, 328, 336-342, 348, 351, 358, 366-376, 382-400, 405, 410-426, 434-462, 486-529, 548-554, 566-568, 573-604, 608-612, 615-627, 633, 636-659, 13->15, 22->23, 200->201, 259->262, 325->326, 327->328, 332->336, 345->351, 347->348, 357->358, 380->382, 404->405, 571->573
+src/allmydata/util/fileutil.py                         343    243    120     13    25%   15, 23-25, 47-55, 71-85, 96-97, 100, 103, 106, 109, 115-116, 119-125, 128, 131, 134, 137-138, 142-145, 151-153, 158, 166-176, 179-184, 201-203, 214-237, 241-244, 247-254, 262, 282-290, 293-304, 326, 328, 336-342, 348, 351, 358, 366-376, 382-400, 405, 410-426, 434-462, 486-529, 548-554, 566-568, 573-604, 608-612, 615-627, 633, 636-659, 13->15, 22->23, 200->201, 259->262, 325->326, 327->328, 332->336, 345->351, 347->348, 357->358, 380->382, 404->405, 571->573
 src/allmydata/util/gcutil.py                            23      3      8      3    81%   20, 51-57, 19->20, 50->51, 64->exit
 src/allmydata/util/happinessutil.py                     77     62     42      1    13%   15, 25-54, 64-69, 82-92, 142-183, 207-223, 235-249, 13->15
 src/allmydata/util/hashutil.py                         157     76      8      1    50%   14, 40-42, 45-46, 49-56, 60-62, 66-68, 72-76, 118, 122, 126, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 174-176, 180-183, 187, 191, 195, 199, 204, 209-210, 214-215, 219, 223-228, 232, 236, 240, 244, 248-250, 254, 258, 262, 266, 270-271, 278, 282, 12->14
@@ -818,7 +646,7 @@
 src/allmydata/util/i2p_provider.py                     121     73     36      5    35%   44-67, 72-81, 85-135, 151-161, 168, 176-180, 183-184, 187, 193-216, 219, 226, 167->168, 175->176, 182->183, 186->187, 192->193
 src/allmydata/util/idlib.py                              5      2      0      0    60%   6, 9
 src/allmydata/util/iputil.py                           172     74     56     12    52%   14, 63-102, 123-140, 151-184, 209, 216, 229, 237-238, 242, 246, 254-257, 271-277, 328-329, 353-354, 13->14, 215->216, 220->242, 226->229, 234->220, 239->234, 245->246, 249->259, 265->261, 291->329, 295->328, 360->exit
-src/allmydata/util/log.py                               52     27     16      1    38%   13, 38-41, 46-48, 51-61, 67-75, 78, 12->13
+src/allmydata/util/log.py                               52     23     16      2    46%   13, 46-48, 51-61, 67-75, 78, 12->13, 39->41
 src/allmydata/util/mathutil.py                          12      3      2      1    71%   16, 25-26, 15->16
 src/allmydata/util/netstring.py                         35     24     12      1    26%   13, 31-54, 12->13
 src/allmydata/util/observer.py                          91     56     20      1    32%   14, 29-32, 36-38, 41, 44, 47, 50-54, 57-60, 63-66, 69-70, 79, 82, 93-97, 103, 106, 109, 112-113, 119-121, 134, 137-139, 142-145, 148-151, 154-157, 13->14
@@ -854,7 +682,7 @@
 src/allmydata/windows/fixups.py                        133    133     54      0     0%   1-237
 src/allmydata/windows/registry.py                       42     42     12      0     0%   1-77
 ------------------------------------------------------------------------------------------------
-TOTAL                                                27467  22018   8248    184    17%
+TOTAL                                                27470  21994   8250    176    17%

 12 files skipped due to complete coverage.
 make[#]: Leaving directory '/home/rpatterson/src/work/sfu/tahoe-lafs'
```
2020-10-04 21:52:27 -07:00
Ross Patterson
b2332b5bf1 fix(py3): Duplicate section name that py3 catches
Python 3 raises an exception that Python 2 doesn't and as such exposes malformed cfg/ini
contents used in the tests.

The test output diff shows that this mostly converts test `DuplicateSectionError` errors
to test errors with different exceptions which is reasonable for the type of fix this
is.  It does seem to reduce coverage which I'm guessing is because the malformed
contents were triggering error handling code paths that aren't triggered now, but I
haven't confirmed that.  I would think that to cover those cases we should write tests
that do that explicitly rather than accidentally.

```diff
--- ../../.tox/make-test-py3-all-old.log	2020-10-04 15:13:09.670578482 -0700
+++ ../../.tox/make-test-py3-all-new.log	2020-10-04 15:16:34.054975263 -0700
@@ -1835,7 +1835,7 @@
     raise self.failureException(msg)
 twisted.trial.unittest.FailTest: ['allmydata', 'allmydata.__main__', 'allm[5873 chars]try'] != set() : Some unported modules remain:
 Ported files: 96 / 292
-Ported lines: 27978 / 93480
+Ported lines: 27978 / 93482

 allmydata.test.test_python3.Python3PortingEffortTests.test_finished_porting
@@ -2166,11 +2166,11 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 685, in test_disabled_but_helper
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 687, in test_disabled_but_helper
     yield client.create_client(basedir)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_synctest.py", line 355, in __exit__
     self._expectedName, reason.getTraceback()),
-twisted.trial.unittest.FailTest: configparser.DuplicateSectionError raised instead of ValueError:
+twisted.trial.unittest.FailTest: builtins.NameError raised instead of ValueError:
  Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/internet/defer.py", line 1529, in _cancellableInlineCallbacks
     _inlineCallbacks(None, g, status)
@@ -2178,12 +2178,12 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 685, in test_disabled_but_helper
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 687, in test_disabled_but_helper
     yield client.create_client(basedir)
 --- <exception caught here> ---
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 685, in test_disabled_but_helper
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 687, in test_disabled_but_helper
     yield client.create_client(basedir)
-configparser.DuplicateSectionError: While reading from '/home/rpatterson/src/work/sfu/tahoe-lafs/_trial_temp/test_node/test_disabled_but_helper/tahoe.cfg' [line 10]: section 'node' already exists
+builtins.NameError: name 'unicode' is not defined

 allmydata.test.test_node.ClientNotListening.test_disabled_but_helper
@@ -2194,11 +2194,11 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 668, in test_disabled_but_storage
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 670, in test_disabled_but_storage
     yield client.create_client(basedir)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_synctest.py", line 355, in __exit__
     self._expectedName, reason.getTraceback()),
-twisted.trial.unittest.FailTest: configparser.DuplicateSectionError raised instead of ValueError:
+twisted.trial.unittest.FailTest: builtins.NameError raised instead of ValueError:
  Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/internet/defer.py", line 1529, in _cancellableInlineCallbacks
     _inlineCallbacks(None, g, status)
@@ -2206,12 +2206,12 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 668, in test_disabled_but_storage
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 670, in test_disabled_but_storage
     yield client.create_client(basedir)
 --- <exception caught here> ---
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 668, in test_disabled_but_storage
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 670, in test_disabled_but_storage
     yield client.create_client(basedir)
-configparser.DuplicateSectionError: While reading from '/home/rpatterson/src/work/sfu/tahoe-lafs/_trial_temp/test_node/test_disabled_but_storage/tahoe.cfg' [line 10]: section 'node' already exists
+builtins.NameError: name 'unicode' is not defined

 allmydata.test.test_node.ClientNotListening.test_disabled_but_storage
@@ -2222,7 +2222,7 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 739, in test_create_client_invalid_config
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 741, in test_create_client_invalid_config
     yield client.create_client(self.basedir)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_synctest.py", line 355, in __exit__
     self._expectedName, reason.getTraceback()),
@@ -2234,10 +2234,10 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 739, in test_create_client_invalid_config
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 741, in test_create_client_invalid_config
     yield client.create_client(self.basedir)
 --- <exception caught here> ---
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 739, in test_create_client_invalid_config
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 741, in test_create_client_invalid_config
     yield client.create_client(self.basedir)
 builtins.TypeError: startswith first arg must be str or a tuple of str, not bytes

@@ -2250,7 +2250,7 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 702, in test_port_none_introducer
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 704, in test_port_none_introducer
     yield create_introducer(basedir)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_synctest.py", line 355, in __exit__
     self._expectedName, reason.getTraceback()),
@@ -2262,10 +2262,10 @@
     result = result.throwExceptionIntoGenerator(g)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
     return g.throw(self.type, self.value, self.tb)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 702, in test_port_none_introducer
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 704, in test_port_none_introducer
     yield create_introducer(basedir)
 --- <exception caught here> ---
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 702, in test_port_none_introducer
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 704, in test_port_none_introducer
     yield create_introducer(basedir)
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/introducer/server.py", line 76, in create_introducer
     tor_provider,
@@ -7432,23 +7432,17 @@
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 655, in test_disabled
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 657, in test_disabled
     n = yield client.create_client(basedir)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/client.py", line 243, in create_client
-    config = read_config(basedir, u"client.port")
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/client.py", line 219, in read_config
-    _valid_config=_valid_config(),
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/node.py", line 187, in read_config
-    parser = configutil.get_config(config_fname)
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/util/configutil.py", line 50, in get_config
-    config.readfp(f)
-  File "/usr/lib/python3.6/configparser.py", line 764, in readfp
-    self.read_file(fp, source=filename)
-  File "/usr/lib/python3.6/configparser.py", line 718, in read_file
-    self._read(f, source)
-  File "/usr/lib/python3.6/configparser.py", line 1067, in _read
-    lineno)
-configparser.DuplicateSectionError: While reading from '/home/rpatterson/src/work/sfu/tahoe-lafs/_trial_temp/test_node/test_disabled/tahoe.cfg' [line 10]: section 'node' already exists
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
+    result = g.send(result)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/client.py", line 285, in create_client_from_config
+    introducer_clients = create_introducer_clients(config, main_tub, _introducer_factory)
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/client.py", line 519, in create_introducer_clients
+    introducer_cache_filepath,
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/introducer/client.py", line 29, in __init__
+    assert type(nickname) is unicode
+builtins.NameError: name 'unicode' is not defined

 allmydata.test.test_node.ClientNotListening.test_disabled
 ===============================================================================
@@ -7456,7 +7450,7 @@
 Traceback (most recent call last):
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 577, in test_listen_on_zero
     t = FakeTub()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 549, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 548, in __init__
     self.tubID = base64.b32encode("foo")
   File "/usr/lib/python3.6/base64.py", line 154, in b32encode
     s = memoryview(s).tobytes()
@@ -7466,9 +7460,9 @@
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 605, in test_multiple_ports
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 606, in test_multiple_ports
     t = FakeTub()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 549, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 548, in __init__
     self.tubID = base64.b32encode("foo")
   File "/usr/lib/python3.6/base64.py", line 154, in b32encode
     s = memoryview(s).tobytes()
@@ -7478,9 +7472,9 @@
 ===============================================================================
 [ERROR]
 Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 624, in test_tor_i2p_listeners
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 626, in test_tor_i2p_listeners
     t = FakeTub()
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 549, in __init__
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_node.py", line 548, in __init__
     self.tubID = base64.b32encode("foo")
   File "/usr/lib/python3.6/base64.py", line 154, in b32encode
     s = memoryview(s).tobytes()
@@ -8781,11 +8775,11 @@
 src/allmydata/immutable/downloader/__init__.py           7      1      2      1    78%   12, 11->12
 src/allmydata/immutable/downloader/common.py            14      1      2      1    88%   12, 11->12
 src/allmydata/immutable/downloader/fetcher.py          147      1     56      1    99%   12, 11->12
-src/allmydata/immutable/downloader/finder.py           143      9     40      5    92%   11, 88-89, 108, 115, 170-173, 10->11, 87->88, 107->108, 113->115, 165->exit
+src/allmydata/immutable/downloader/finder.py           143     11     40      5    91%   11, 88-89, 108, 115, 170-173, 231-232, 10->11, 87->88, 107->108, 113->115, 165->exit
 src/allmydata/immutable/downloader/node.py             282      9     66      9    94%   11, 170-172, 224-235, 271, 10->11, 43->exit, 60->68, 165->169, 169->170, 256->exit, 270->271, 517->exit, 537->exit
 src/allmydata/immutable/downloader/segmentation.py     118      1     22      1    99%   11, 10->11
-src/allmydata/immutable/downloader/share.py            453     15    154      8    96%   11, 210, 248-250, 354, 430-437, 518, 722-725, 862, 10->11, 209->210, 239->248, 352->354, 515->518, 660->663, 710->722, 762->exit
-src/allmydata/immutable/downloader/status.py           154      9     36      1    95%   11, 223, 226, 230, 232, 234, 274, 285, 287, 10->11
+src/allmydata/immutable/downloader/share.py            453     23    154     11    94%   11, 210, 239-250, 289-290, 354, 399-400, 430-437, 518, 722-725, 775, 862, 10->11, 209->210, 222->239, 288->289, 352->354, 397->399, 515->518, 660->663, 710->722, 762->exit, 774->775
+src/allmydata/immutable/downloader/status.py           154     12     36      1    93%   11, 65-67, 223, 226, 230, 232, 234, 274, 285, 287, 10->11
 src/allmydata/immutable/encode.py                      421     13    124     10    95%   114, 197-200, 278-280, 405, 412, 462, 509, 562, 687, 102->104, 113->114, 195->197, 404->405, 411->412, 461->462, 499->509, 505->511, 561->562, 685->687
 src/allmydata/immutable/filenode.py                    196     48     30      5    72%   77-78, 83, 85, 88, 94-101, 104-124, 127-172, 254, 258, 315, 40->42, 224->227, 227->229, 251->254, 257->258
 src/allmydata/immutable/happiness_upload.py            214      1    132      3    99%   15, 13->15, 213->211, 280->279
@@ -8808,7 +8802,7 @@
 src/allmydata/mutable/repairer.py                       57     37     18      0    29%   13, 15, 17, 19, 29-34, 65-71, 74-126, 129-131
 src/allmydata/mutable/retrieve.py                      489    123    120     33    71%   46, 48, 50, 52, 56, 58, 60, 62, 64, 89-90, 133, 186-193, 204-208, 211-212, 224-226, 231, 240, 251, 312, 318, 344-354, 377, 385-386, 399-400, 425-434, 490, 501, 515-516, 529-540, 564-578, 591-592, 629-630, 653-654, 674-675, 681-682, 698, 712-729, 758-760, 765, 772-774, 790-792, 871, 883, 909-910, 919-941, 965-966, 981-994, 999-1005, 129->133, 167->169, 169->171, 201->204, 223->224, 230->231, 237->239, 239->240, 243->247, 249->251, 309->312, 317->318, 376->377, 381->385, 391->394, 396->399, 424->425, 489->490, 499->501, 514->515, 590->591, 628->629, 652->653, 673->674, 677->687, 680->681, 687->694, 694->698, 755->764, 764->765, 868->871, 880->883, 964->965
 src/allmydata/mutable/servermap.py                     612    240    186     26    56%   45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 74, 130-139, 142, 148, 159-161, 175, 177, 183, 186-199, 206, 213, 217-220, 231, 234-238, 243-252, 255-259, 315, 328-350, 358-363, 370-372, 379, 429, 433, 443-447, 495, 498, 506-508, 514-516, 569-570, 603-611, 623-638, 718-721, 732-741, 792, 796, 803-804, 850-851, 872-874, 911-915, 929-945, 961-975, 982-999, 1003-1013, 1043-1045, 1050-1052, 1060-1064, 1069-1070, 1093-1100, 1106-1186, 1214-1215, 1232-1233, 313->315, 427->429, 432->433, 439->443, 459->461, 493->495, 497->498, 504->506, 509->514, 566->569, 597->603, 687->exit, 702->exit, 710->exit, 717->718, 727->732, 759->exit, 791->792, 795->796, 869->872, 1039->1043, 1047->1050, 1059->1060, 1066->1069, 1092->1093, 1213->1214
-src/allmydata/node.py                                  388     84    146     34    75%   120, 132, 190, 241, 243-245, 278, 284, 294-295, 303-306, 315, 320, 339, 341, 361, 393-396, 422, 449, 453, 490, 493, 500, 511-512, 548, 566, 574, 581, 583, 590-591, 601, 612, 629-633, 679, 681, 738-741, 747, 756, 764, 792-805, 808-809, 814-815, 825-846, 189->190, 240->241, 242->243, 277->278, 314->315, 319->320, 338->339, 340->341, 360->361, 391->393, 421->422, 448->449, 451->453, 489->490, 492->493, 499->500, 510->511, 537->535, 547->548, 565->566, 573->574, 580->581, 582->583, 589->590, 600->601, 611->612, 622->629, 673->679, 680->681, 737->738, 746->747, 763->764, 821->830, 823->821
+src/allmydata/node.py                                  388     84    146     33    75%   120, 132, 190, 241, 243-245, 278, 284, 294-295, 303-306, 315, 320, 339, 341, 361, 393-396, 422, 449, 453, 490, 493, 500, 511-512, 548, 566, 574, 581, 583, 590-591, 601, 612, 629-633, 679, 681, 738-741, 747, 756, 764, 792-805, 808-809, 814-815, 825-846, 189->190, 240->241, 242->243, 277->278, 314->315, 319->320, 338->339, 340->341, 360->361, 391->393, 421->422, 448->449, 451->453, 489->490, 492->493, 499->500, 510->511, 547->548, 565->566, 573->574, 580->581, 582->583, 589->590, 600->601, 611->612, 622->629, 673->679, 680->681, 737->738, 746->747, 763->764, 821->830, 823->821
 src/allmydata/nodemaker.py                              97     23     38     10    70%   49, 61, 66, 70, 81, 94, 107-115, 130-138, 141-150, 57->61, 65->66, 69->70, 79->81, 86->95, 90->94, 104->107, 124->exit, 129->130, 129->133
 src/allmydata/scripts/admin.py                          51     20      2      1    60%   9-14, 25, 28, 31-37, 40-46, 57, 59, 61-66, 56->57
 src/allmydata/scripts/backupdb.py                      146     91     14      1    36%   84-91, 94-96, 99, 103, 106, 111-114, 117-119, 122, 125, 128, 176-221, 231-242, 245-263, 266-272, 308-324, 327-333, 336-341, 306->308
@@ -8843,7 +8837,7 @@
 src/allmydata/storage/common.py                         24      1      4      2    89%   11, 10->11, 36->39
 src/allmydata/storage/crawler.py                       222      1     64      3    99%   16, 13->16, 96->99, 496->505
 src/allmydata/storage/expirer.py                       240      1     81      2    99%   9, 7->9, 250->exit
-src/allmydata/storage/immutable.py                     198      1     48      5    98%   12, 11->12, 142->140, 155->160, 187->197, 273->exit
+src/allmydata/storage/immutable.py                     198      2     48      6    97%   12, 101, 11->12, 100->101, 142->140, 155->160, 187->197, 273->exit
 src/allmydata/storage/lease.py                          35      1      4      1    95%   12, 11->12
 src/allmydata/storage/mutable.py                       289      8     90      6    96%   12, 162, 252, 289, 362-367, 11->12, 160->162, 247->252, 307->311, 354->362, 448->exit
 src/allmydata/storage/server.py                        371      9    120      9    96%   13, 92, 222, 243, 329, 349, 375, 422-423, 10->13, 91->92, 221->222, 241->243, 289->300, 317->329, 325->305, 346->349, 374->375
@@ -8905,7 +8899,7 @@
 src/allmydata/windows/fixups.py                        133    133     54      0     0%   1-237
 src/allmydata/windows/registry.py                       42     42     12      0     0%   1-77
 ------------------------------------------------------------------------------------------------
-TOTAL                                                27477  11786   8244    602    54%
+TOTAL                                                27477  11800   8244    605    54%

 18 files skipped due to complete coverage.
 + '[' '!' -z 1 ']'
```

Trac: refs #3455
2020-10-04 15:57:01 -07:00
Ross Patterson
3f297bf0e3 feat(py3): Fix test runner exception
The exception this addresses was preventing the test runner from running to completion
under Python 3, thus preventing using the full test suite to evaluate the impact of
porting efforts.

This change causes no regressions in the test suite under python 2.7 and only affects
tests AFAICT.  I added debug logging to check all the strings that seem to make it to
that point and I didn't see anything that looked like it needed to be decoded in
particular, so I think this change is relatively safe.

The traceback for reference

```
Traceback (most recent call last):
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/bin/trial", line 8, in <module>
    sys.exit(run())
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/scripts/trial.py", line 621, in run
    test_result = trialRunner.run(suite)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 998, in run
    return self._runWithoutDecoration(test, self._forceGarbageCollection)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 1025, in _runWithoutDecoration
    run()
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 1020, in <lambda>
    run = lambda: suite.run(result)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 253, in run
    TestSuite.run(self, result)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/_asyncrunner.py", line 38, in run
    test(result)
  File "/usr/lib/python3.6/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 212, in run
    super(LoggedSuite, self).run(result)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/_asyncrunner.py", line 38, in run
    test(result)
  File "/usr/lib/python3.6/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 185, in run
    test(result)
  File "/usr/lib/python3.6/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 185, in run
    test(result)
  File "/usr/lib/python3.6/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/runner.py", line 185, in run
    test(result)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/_asyncrunner.py", line 59, in __call__
    return self.run(result)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/twisted/trial/_asyncrunner.py", line 69, in run
    reporter._AdaptedReporter(result, self.__class__))
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36/lib/python3.6/site-packages/testtools/testcase.py", line 675, in run
    return run_test.run(result)
  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/eliotutil.py", line 110, in run_and_republish
    with RUN_TEST(name=self.id().decode("utf-8")).context() as action:
AttributeError: 'str' object has no attribute 'decode'
```
2020-10-04 15:57:01 -07:00
Itamar Turner-Trauring
963f9ba94b Closer to passing tests. 2020-10-02 11:01:24 -04:00
Itamar Turner-Trauring
f8f8329d70 More passing tests on Python 3. 2020-10-02 10:48:54 -04:00
Itamar Turner-Trauring
1088e5368d A little progress on passing tests. 2020-10-02 10:42:44 -04:00
Ross Patterson
ae1aab611d fix(py3): Match wiki porting conventions
Address feedback from PR pointing out that my python-future imports aren't matching the
conventions from the wiki.

Trac: refs #3448
2020-10-01 08:57:54 -07:00
Chad Whitacre
41fcd9673e Move SignalMixin and TimeMixin back to common_util
This concludes our service.
2020-09-30 23:31:33 -04:00
Chad Whitacre
93d4a8373f Move ReallyEqualMixin and s31e back to common_util
s31e = skip_if_cannot_represent_filename
2020-09-30 23:31:13 -04:00
Chad Whitacre
b75b48e68c Move FakeCanary to common_util
Couldn't bring myself to move it back to test_storage.
2020-09-30 23:29:08 -04:00
Chad Whitacre
23140b8b1c Move ShouldFailMixin back to common_util
There were originally two versions of this, one in common and another in
common_util. We moved both into common_py3 but then removed the one from
common, so here we move back to common_util, while allowing imports from
common to avoid a noisy changeset.
2020-09-30 23:01:46 -04:00
Chad Whitacre
2c2b61676c Move LoggingServiceParent back to common 2020-09-30 22:32:13 -04:00
Ross Patterson
fb87daad0b Merge branch 'master' into 3448.convert-only-unicode-to-str 2020-09-30 11:50:42 -07:00
Ross Patterson
362c121426 feat(py3): Convert unicode-only modules to str
Modules that reference `unicode` but do *not* reference `str` can safely be converted to
use `str` in a way that's closest to the way it should be done under Python 3 but that
is still Python 2 compatible [per
`python-future`](https://python-future.org/compatible_idioms.html?highlight=unicode#unicode).

This change results in 4 additional tests passing under Python 3 that weren't before,
one previous test error is now a failure, and more coverage in a few modules.  Here's
the diff of the output from running all tests under Python 3 before these changes and
after.  I've elided the irrelevant changes (time stamps, object ids, etc.):

```diff
--- .tox/make-test-py3-all-old.log	2020-09-27 20:56:55.761691130 -0700
+++ .tox/make-test-py3-all-new.log	2020-09-27 20:58:16.242075678 -0700
@@ -1,6 +1,6 @@
...
@@ -4218,7 +4218,7 @@
 [ERROR]
 (#.### secs)
 allmydata.test.mutable.test_version.Version.test_download_version ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/mutable/test_version.py", line 274, in test_download_version
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/mutable/test_version.py", line 279, in test_download_version
     d = self.publish_multiple()
   File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/mutable/util.py", line 372, in publish_multiple
     self._nodemaker = make_nodemaker(self._storage)
@@ -4438,40 +4438,26 @@
 allmydata.test.test_abbreviate.Abbreviate.test_time ... [OK]
 (#.### secs)
 allmydata.test.test_auth.AccountFileCheckerKeyTests.test_authenticated ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_auth.py", line 42, in setUp
-    abspath = abspath_expanduser_unicode(unicode(self.account_file.path))
-builtins.NameError: name 'unicode' is not defined
+Failure: twisted.cred.error.UnauthorizedLogin:
 [ERROR]
 (#.### secs)
 allmydata.test.test_auth.AccountFileCheckerKeyTests.test_missing_signature ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_auth.py", line 42, in setUp
-    abspath = abspath_expanduser_unicode(unicode(self.account_file.path))
-builtins.NameError: name 'unicode' is not defined
-[ERROR]
+  File "/home/rpatterson/src/work/sfu/tahoe-lafs/.tox/py36-coverage/lib/python3.6/site-packages/twisted/trial/_asynctest.py", line 75, in _eb
+    raise self.failureException(output)
+twisted.trial.unittest.FailTest:
+Expected: (<class 'twisted.conch.error.ValidPublicKey'>,)
+Got:
+[Failure instance: Traceback (failure with no frames): <class 'twisted.cred.error.UnauthorizedLogin'>:
+]
+[FAILURE]
 (#.### secs)
-allmydata.test.test_auth.AccountFileCheckerKeyTests.test_password_auth_user ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_auth.py", line 42, in setUp
-    abspath = abspath_expanduser_unicode(unicode(self.account_file.path))
-builtins.NameError: name 'unicode' is not defined
-[ERROR]
+allmydata.test.test_auth.AccountFileCheckerKeyTests.test_password_auth_user ... [OK]
 (#.### secs)
-allmydata.test.test_auth.AccountFileCheckerKeyTests.test_unknown_user ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_auth.py", line 42, in setUp
-    abspath = abspath_expanduser_unicode(unicode(self.account_file.path))
-builtins.NameError: name 'unicode' is not defined
-[ERROR]
+allmydata.test.test_auth.AccountFileCheckerKeyTests.test_unknown_user ... [OK]
 (#.### secs)
-allmydata.test.test_auth.AccountFileCheckerKeyTests.test_unrecognized_key ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_auth.py", line 42, in setUp
-    abspath = abspath_expanduser_unicode(unicode(self.account_file.path))
-builtins.NameError: name 'unicode' is not defined
-[ERROR]
+allmydata.test.test_auth.AccountFileCheckerKeyTests.test_unrecognized_key ... [OK]
 (#.### secs)
-allmydata.test.test_auth.AccountFileCheckerKeyTests.test_wrong_signature ... Traceback (most recent call last):
-  File "/home/rpatterson/src/work/sfu/tahoe-lafs/src/allmydata/test/test_auth.py", line 42, in setUp
-    abspath = abspath_expanduser_unicode(unicode(self.account_file.path))
-builtins.NameError: name 'unicode' is not defined
-[ERROR]
+allmydata.test.test_auth.AccountFileCheckerKeyTests.test_wrong_signature ... [OK]
 (#.### secs)
 allmydata.test.test_backupdb.BackupDB.test_basic ... [OK]
 (#.### secs)
@@ -4615,7 +4601,7 @@
 src/allmydata/crypto/util.py                            12      2      4      2    75%   13, 32, 12->13, 30->32
 src/allmydata/deep_stats.py                             83     63     26      0    18%   27-52, 56-58, 62-82, 86-91, 94, 97, 103-114, 117-121, 125-131, 135
 src/allmydata/dirnode.py                               525    420    178      0    15%   70-103, 112-116, 119-135, 140-143, 146-160, 165-173, 176-177, 180-205, 208-217, 223-229, 248-286, 293-299, 302, 310, 315, 318-324, 327-332, 336-340, 344-346, 355-406, 410, 413, 416, 419, 422, 425, 428, 431-433, 436, 439, 442, 445, 448-450, 453, 457, 459, 464, 469-472, 475-478, 481-484, 489-492, 498-501, 504-507, 510-518, 530-532, 539-555, 558-566, 570-589, 600-610, 613-620, 628-641, 646-652, 657-678, 693-714, 752-761, 765-770, 774-812, 819-820, 825, 828, 831, 836-839, 842-849, 852-853, 862-877, 880-881, 884-891, 894, 897-899
-src/allmydata/frontends/auth.py                        100     71     28      0    26%   21-22, 30-48, 51, 54-56, 59-70, 80-87, 100-110, 117-118, 121, 124-142, 147-150, 156-159
+src/allmydata/frontends/auth.py                        100     52     28      4    47%   21-22, 38, 41-44, 51, 54-56, 65-70, 80-87, 106-108, 117-118, 121, 124-142, 147-150, 156-159, 37->38, 40->41, 59->65, 101->106
 src/allmydata/frontends/ftpd.py                        255    254     84      0     1%   4-337
 src/allmydata/frontends/sftpd.py                      1211   1208    488      0     1%   4-2014
 src/allmydata/hashtree.py                              174    135     72      1    16%   59, 75-78, 106-108, 114-117, 123-126, 132-136, 142-149, 152-162, 165-169, 172, 175, 180, 183, 186, 218-232, 259-262, 295-306, 320-323, 326-331, 384-484, 58->59
@@ -4653,7 +4639,7 @@
 src/allmydata/scripts/admin.py                          51     31      2      0    38%   9-14, 17-21, 25, 28, 31-37, 40-46, 56-57, 59, 61-66, 74-78
 src/allmydata/scripts/backupdb.py                      146     91     14      1    36%   84-91, 94-96, 99, 103, 106, 111-114, 117-119, 122, 125, 128, 176-221, 231-242, 245-263, 266-272, 308-324, 327-333, 336-341, 306->308
 src/allmydata/scripts/cli.py                           259    124     46      6    46%   25-49, 69-72, 79-81, 103, 142-146, 175, 221-222, 258, 265-266, 284-285, 330-331, 338-341, 346-355, 361-362, 366-373, 388, 405, 417, 432, 449, 479-481, 484-486, 489-491, 494-496, 499-501, 504-515, 518-520, 523-525, 528-530, 533, 536-538, 541-543, 546-548, 551-553, 556-558, 561-563, 566-568, 571-573, 576-577, 60->exit, 61->exit, 174->175, 180->exit, 181->exit, 219->221
-src/allmydata/scripts/common.py                        153     74     60      4    48%   64, 82, 88, 100, 114-126, 130-152, 159-163, 168-169, 172, 177, 191-236, 240-241, 47->49, 63->64, 79->82, 87->88
+src/allmydata/scripts/common.py                        154     74     60      4    49%   69, 87, 93, 105, 119-131, 135-157, 164-168, 173-174, 177, 182, 196-241, 245-246, 52->54, 68->69, 84->87, 92->93
 src/allmydata/scripts/common_http.py                    77     58     20      0    20%   15-30, 34-36, 38, 42-83, 87, 90, 94-96, 101
 src/allmydata/scripts/create_node.py                   302    185    114      8    30%   24, 61-96, 99-111, 114-128, 136-139, 169-174, 191-194, 205-208, 224-229, 235, 242, 256-278, 289-292, 295-298, 329, 339, 347-380, 385-445, 448-450, 455-477, 223->224, 234->235, 241->242, 252->256, 288->289, 294->295, 328->329, 338->339
 src/allmydata/scripts/debug.py                         719    638    202      0     9%   14, 31-32, 35-49, 52-60, 63-142, 146-154, 157-164, 168-217, 220-304, 307-401, 407, 417, 437-465, 468-485, 488-602, 606, 609-611, 637-648, 653-656, 659, 683-689, 692-810, 813-842, 845-848, 851-865, 869, 888, 891-940, 946, 949-950, 957, 960-961, 967-972, 984-985, 999-1000, 1003-1004, 1020-1021, 1025-1031, 1046-1050
@@ -4661,10 +4647,10 @@
 src/allmydata/scripts/run_common.py                    135     18     24      6    85%   37, 41-46, 59-60, 149, 158, 192-193, 216-220, 226-227, 55->62, 135->exit, 135->exit, 148->149, 191->192, 225->226
 src/allmydata/scripts/runner.py                        138     53     42     11    56%   84-85, 91, 97-99, 104, 114, 123-132, 140, 146, 149-160, 174-181, 186, 189-190, 204-232, 248, 255, 31->36, 103->104, 113->114, 139->140, 145->146, 147->149, 185->186, 188->189, 202->204, 247->248, 254->255
 src/allmydata/scripts/slow_operation.py                 69     56     22      0    14%   15-44, 47-52, 55-61, 64-83
-src/allmydata/scripts/stats_gatherer.py                 41     25     10      0    31%   20-25, 62-86
+src/allmydata/scripts/stats_gatherer.py                 42     25     10      0    33%   25-30, 67-91
 src/allmydata/scripts/tahoe_add_alias.py               106     91     30      0    11%   20-32, 35-59, 63-98, 102-111, 115-144
 src/allmydata/scripts/tahoe_backup.py                  331    267     85      0    15%   20-35, 38-51, 54-58, 71-73, 76-152, 155-157, 160-161, 164-174, 178-209, 212-242, 246-274, 278-279, 287-311, 322-331, 336, 339, 342-351, 356, 359, 362-367, 372-374, 379, 384, 389, 398, 417-425, 428, 431-461, 469-480, 483-486, 500-504, 511-512, 525, 538-542, 545-549, 552-555, 558-561, 564, 571, 578, 586-594
-src/allmydata/scripts/tahoe_check.py                   263    235    121      0     7%   15, 20-100, 103-112, 120-129, 132-167, 170-173, 179-192, 195-256, 259-270, 277-323, 327-336, 339
+src/allmydata/scripts/tahoe_check.py                   264    235    121      0     8%   20, 25-105, 108-117, 125-134, 137-172, 175-178, 184-197, 200-261, 264-275, 282-328, 332-341, 344
 src/allmydata/scripts/tahoe_cp.py                      602    503    226      0    12%   22, 26, 30-31, 34-37, 40-41, 44-47, 50-53, 56-60, 63-70, 75-77, 80, 83, 86, 90-91, 94, 98-99, 102, 106-111, 114, 117-134, 138-142, 145-159, 162-172, 175-177, 180, 185-189, 192, 195-197, 200-203, 206, 210-214, 218-223, 230-233, 236, 239-253, 256-263, 266-297, 303, 307-309, 316, 320-323, 326-333, 336-350, 354-358, 361-397, 403-413, 416-433, 436-437, 440-454, 465-496, 504-580, 583, 589-630, 636-689, 693-698, 701-703, 706-719, 723-762, 765-775, 778-806, 810-818, 821-838, 842, 845-857, 862-863, 867
 src/allmydata/scripts/tahoe_get.py                      37     32     12      0    10%   9-45
 src/allmydata/scripts/tahoe_invite.py                   59     41      8      0    27%   27-31, 36-71, 76-101
@@ -4679,7 +4665,7 @@
 src/allmydata/scripts/tahoe_stop.py                     60     47     10      0    19%   16, 24-84
 src/allmydata/scripts/tahoe_unlink.py                   28     23      6      0    15%   12-40
 src/allmydata/scripts/tahoe_webopen.py                  27     24     12      0     8%   7-31
-src/allmydata/stats.py                                 242    156     54      3    33%   28-34, 37-40, 43-47, 50-64, 67-72, 101, 104-110, 113-125, 144-146, 154-155, 160-163, 169-174, 178-187, 191, 200-207, 210, 213-219, 222-228, 232-234, 237, 241, 246-250, 253, 256-257, 263-278, 281-285, 288-293, 299-325, 100->101, 143->144, 153->154
+src/allmydata/stats.py                                 242    156     54      3    33%   29-35, 38-41, 44-48, 51-65, 68-73, 102, 105-111, 114-126, 145-147, 155-156, 161-164, 170-175, 179-188, 192, 201-208, 211, 214-220, 223-229, 233-235, 238, 242, 247-251, 254, 257-258, 264-279, 282-286, 289-294, 300-326, 101->102, 144->145, 154->155
 src/allmydata/storage/common.py                         24      2      4      2    86%   11, 28, 10->11, 36->39
 src/allmydata/storage/crawler.py                       222    125     64      6    37%   16, 90, 111-113, 148-178, 192-193, 231, 244, 251, 275-312, 315-363, 377-384, 393, 416, 428, 445, 453, 488-492, 495-508, 13->16, 89->90, 96->99, 228->231, 248->251, 268->271
 src/allmydata/storage/expirer.py                       240    183     81      2    21%   9, 74-79, 119, 122, 125-167, 171-233, 236-253, 256-261, 264-266, 269-274, 280-284, 288-322, 388-435, 7->9, 71->74
@@ -4748,7 +4734,7 @@
 src/allmydata/windows/fixups.py                        133    133     54      0     0%   1-237
 src/allmydata/windows/registry.py                       42     42     12      0     0%   1-77
 ------------------------------------------------------------------------------------------------
-TOTAL                                                27427  20411   8234    294    22%
+TOTAL                                                27430  20392   8234    298    22%

 18 files skipped due to complete coverage.
 + '[' '!' -z 1 ']'
```

Trac: refs #3448, https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3448
2020-09-30 08:47:02 -07:00
Itamar Turner-Trauring
d797ca1162 Merge remote-tracking branch 'origin/master' into 3451.immutable-downloader-start-python-3 2020-09-30 11:42:58 -04:00
Itamar Turner-Trauring
df69ca8b5b
Merge pull request #836 from tahoe-lafs/3450.immutable-literal-python-3
Port allmydata.immutable.literal to Python 3 (and fix a bug)

Fixes ticket:3450
2020-09-30 11:39:07 -04:00
Jean-Paul Calderone
751bc14521 Always make the todo message a native string.
If the todo message isn't a native string, trial ignores it completely.  Awesome.
2020-09-30 11:11:44 -04:00
Itamar Turner-Trauring
87838dd2bb
Merge pull request #834 from tahoe-lafs/3449.interfaces-to-python-3
Port allmydata.introducer.interfaces to Python 3

Fixes ticket:3449
2020-09-29 11:05:18 -04:00
Itamar Turner-Trauring
b721e3c5f2 Fix missing test coverage in fetcher.py. 2020-09-29 10:51:21 -04:00
Sajith Sasidharan
9c8fb6f901
Merge pull request #781 from sajith/3382.remove-multi-format-page
Remove web.common.MultiFormatPage

Fixes ticket:3382
2020-09-28 21:28:23 -04:00
Itamar Turner-Trauring
c84a2ef869
Merge pull request #835 from tahoe-lafs/3417.audit-for-loops-mutable-dict-views-python-3
Audit for loops for mutable dict views bugs on Python 3

Fixes ticket:3417
2020-09-28 16:53:12 -04:00
Itamar Turner-Trauring
e3a9f5fa75 Test and bugfix for LiteralFileNode equality. 2020-09-28 16:49:30 -04:00
Itamar Turner-Trauring
7aa7716f3a Wrap with list(), just in case. 2020-09-28 15:44:29 -04:00
Jean-Paul Calderone
76ecae2e44 Merge remote-tracking branch 'origin/master' into 3382.remove-multi-format-page 2020-09-28 15:09:29 -04:00
Jean-Paul Calderone
6d14eb55b5
Merge pull request #832 from tahoe-lafs/3443.referrer-policy-tests
Add a test for referrer-policy

Fixes: ticket:3443
2020-09-28 15:04:55 -04:00
Itamar Turner-Trauring
5e6201aede
Merge pull request #833 from tahoe-lafs/3446.test-helper-python-3
Port test_helper.py to Python 3

Fixes ticket:3446
2020-09-28 11:35:15 -04:00
Jean-Paul Calderone
a5686de460 Don't claim behavior about *all* pages 2020-09-28 10:26:00 -04:00
Itamar Turner-Trauring
64516aac41 Port to Python 3. 2020-09-28 10:20:00 -04:00
Itamar Turner-Trauring
4e7e84796a
Merge pull request #829 from tahoe-lafs/3439.test-download-python-3
Port test_download.py to Python 3

Fixes ticket:3439
2020-09-28 09:59:53 -04:00
Chad Whitacre
afd28f3402
Merge pull request #823 from tahoe-lafs/3431.port-test_immutable
Port test_immutable to Python 3
2020-09-28 08:34:03 -04:00
Jean-Paul Calderone
60f531e970
Merge pull request #831 from tahoe-lafs/3438.test_introweb
Split `_test_introweb` into a separate suite

Fixes: ticket:3438
2020-09-27 19:14:24 -04:00
Itamar Turner-Trauring
21e3b355ec Finish porting to Python 3. 2020-09-25 14:03:25 -04:00
Itamar Turner-Trauring
565c48045e Closer to passing tests. 2020-09-25 13:28:59 -04:00
Itamar Turner-Trauring
9e5d5b5f8b Remove typo. 2020-09-25 13:16:47 -04:00
Itamar Turner-Trauring
47aa724c42 Merge remote-tracking branch 'origin/master' into 3439.test-download-python-3 2020-09-25 13:16:12 -04:00
Itamar Turner-Trauring
5e52691433
Merge pull request #827 from tahoe-lafs/3437.test-filenode-python-3
Port test_filenode.py to Python 3

Fixes ticket:3437
2020-09-25 13:15:30 -04:00
Sajith Sasidharan
569ac924ec
Merge pull request #825 from sajith/3436.remove-web-common-getxmlfile
Remove unused web.common.getxmlfile()

Fixes ticket:3436
2020-09-25 12:54:51 -04:00
Itamar Turner-Trauring
5d9a1a5ab5 Some progress towards passing tests. 2020-09-25 11:46:31 -04:00
Jean-Paul Calderone
8cdf5cbf26 unused import 2020-09-25 11:09:55 -04:00
Jean-Paul Calderone
2314a9f2f6 add a test for referrer-policy 2020-09-25 11:06:54 -04:00
Jean-Paul Calderone
3dddcd6f62 Remove assertions about Twisted Web's quoting behavior
It quotes stuff.  It's cool.  BeautifulSoup even looks at it for us and will
tell us if something is amiss.
2020-09-25 09:44:04 -04:00
Jean-Paul Calderone
dc15f19ee0 Merge remote-tracking branch 'origin/master' into 3382.remove-multi-format-page 2020-09-25 09:37:02 -04:00
Jean-Paul Calderone
44cc42351f remove duplicate request 2020-09-25 09:32:06 -04:00
Jean-Paul Calderone
05def35c26 nicer cleanup plus a comment 2020-09-25 09:31:57 -04:00
Jean-Paul Calderone
b218b5426b docstrings 2020-09-25 09:31:53 -04:00
Jean-Paul Calderone
dcb834c7a6 Merge remote-tracking branch 'origin/master' into 3438.test_introweb 2020-09-25 09:26:34 -04:00
Itamar Turner-Trauring
51709d5562
Merge pull request #817 from tahoe-lafs/3430-test-upload-python-3
Port test_upload.py to Python 3

Fixes ticket:3430
2020-09-24 16:57:38 -04:00
Jean-Paul Calderone
1c5f4e2bf0 Compatible with the interface I used in test_web.py 2020-09-24 11:08:18 -04:00
Jean-Paul Calderone
16ab1690de rewrite _test_introweb part of SystemTest as its own test suite 2020-09-24 11:08:18 -04:00
Jean-Paul Calderone
e981fea007 make FakeCanary more realistic 2020-09-24 11:08:18 -04:00
Itamar Turner-Trauring
26f28f341f Finish port to Python 3. 2020-09-24 11:03:42 -04:00
Itamar Turner-Trauring
5cd00d6f2e And even more tests passing in Python 3. 2020-09-24 10:55:47 -04:00
Itamar Turner-Trauring
37bc022edc Even more tests passing on Python 3. 2020-09-24 10:46:10 -04:00
Jean-Paul Calderone
f1bcf4eb07 remove unused imports 2020-09-24 10:42:57 -04:00
Itamar Turner-Trauring
d9036e83b2 More tests passing on Python 3. 2020-09-24 10:39:06 -04:00
Itamar Turner-Trauring
e7fe2f0a3f It imports on Python 3. 2020-09-24 10:32:41 -04:00
Jean-Paul Calderone
e7101b1711 Turn exceptions into error pages like Nevow does 2020-09-24 10:23:05 -04:00
Jean-Paul Calderone
34bade4091 Use the newly introduced helper instead of our own internal thing 2020-09-24 10:22:07 -04:00
Jean-Paul Calderone
ed049da34f Add a helper that can render a Page or a Resource 2020-09-24 10:21:18 -04:00
Chad Whitacre
06cd64c891 De-lint 2020-09-23 21:41:23 -04:00
Chad Whitacre
3ae927eab9 Respond to review
- Preserve int division
- Dial back the __future__ imports
2020-09-23 21:18:24 -04:00
Itamar Turner-Trauring
5a2728fa05 Finish port to Python 3. 2020-09-23 15:56:09 -04:00
Itamar Turner-Trauring
5790ae8ece Tests pass on Python 3. 2020-09-23 15:53:13 -04:00
Chad Whitacre
42eaf08a52 Remove duplicate import 2020-09-23 08:32:34 -04:00
Sajith Sasidharan
a413eb8626 Use BeautifulSoup in RenderSlashUri tests 2020-09-23 08:32:19 -04:00
Chad Whitacre
d21046fe9f A couple more cleanups
- attempt the same future imports in both common and common_util
- put an import in a better place
2020-09-23 08:31:08 -04:00
Chad Whitacre
9fccf37053 Make new code more idiomatic 2020-09-23 08:24:39 -04:00
Chad Whitacre
de48dff981 Dial back future imports in common_util.py
Don't set the plow too deep.
2020-09-23 08:19:07 -04:00
Sajith Sasidharan
704b36d7e1 Remove test for web.common.getxmlfile() 2020-09-22 21:15:58 -04:00
Chad Whitacre
0b6b4b69e9 Port test_immutable to Python 3 2020-09-22 08:36:39 -04:00
Sajith Sasidharan
136a70217c Remove unused import 2020-09-21 20:44:49 -04:00
Sajith Sasidharan
fd5436b867 Expect ErrorPage in RenderSlashUri tests 2020-09-21 18:34:53 -04:00
Jean-Paul Calderone
58c99d0c0c
Merge pull request #815 from tahoe-lafs/3422.directory-weberror
Handle exceptions raised by getChild and render_* in directory.py

Fixes: ticket:3422
2020-09-21 16:04:39 -04:00
Jean-Paul Calderone
0e139114f7 add a limited amount of missing test coverage for humanize_exception 2020-09-21 14:07:11 -04:00
Itamar Turner-Trauring
40b4244146 Port to Python 3. 2020-09-21 13:21:19 -04:00
Itamar Turner-Trauring
6fe68c792c Tests pass on Python 2 and 3. 2020-09-21 13:21:19 -04:00
Itamar Turner-Trauring
0cee40c009 Even more progress towards test_upload on Python 3. 2020-09-21 13:21:19 -04:00
Itamar Turner-Trauring
125a6855d6 More progress towards test_upload on Python 3. 2020-09-21 13:21:19 -04:00
Itamar Turner-Trauring
9f00343478 Some progress towards test_upload running on Python 3. 2020-09-21 13:21:19 -04:00
Itamar Turner-Trauring
139bcb1500
Merge pull request #814 from tahoe-lafs/3419.test-encode-python-3-trying-again
Port test_encode to Python 3

Fixes ticket:3419
2020-09-21 11:52:34 -04:00
Itamar Turner-Trauring
7c6e3104ac
Merge pull request #812 from tahoe-lafs/3416.test-encode-python-3
Port allmydata.test.no_network to Python 3

Fixes ticket:3416
2020-09-21 11:51:34 -04:00
Itamar Turner-Trauring
02b4ec8101 Get rid of stray print(). 2020-09-21 10:33:16 -04:00
Itamar Turner-Trauring
8ef2252bd4 Finish porting to Python 3. 2020-09-18 14:32:19 -04:00
Itamar Turner-Trauring
050388ee12 Work better on Python 3, until Nevow is gone. 2020-09-18 14:31:21 -04:00
Itamar Turner-Trauring
e75beb6eae
Merge pull request #811 from tahoe-lafs/3415.storage-server-python-3
Port allmydata.storage.server to Python 3

Fixes ticket:3415
2020-09-18 13:32:36 -04:00
Jean-Paul Calderone
9682e68528
Merge pull request #805 from jaraco/3408.print-functions
Convert print statements to print functions, even when commented

Fixes: ticket:3408
2020-09-18 12:59:44 -04:00
Itamar Turner-Trauring
7b302871e4 Python 2 tests pass again. 2020-09-18 11:41:28 -04:00
Itamar Turner-Trauring
c5ce988c7e Merge branch '3416.test-encode-python-3' into 3419.test-encode-python-3-trying-again 2020-09-18 11:33:15 -04:00
Itamar Turner-Trauring
1a4744d1f7 Merge branch '3415.storage-server-python-3' into 3416.test-encode-python-3 2020-09-18 11:32:45 -04:00
Itamar Turner-Trauring
02cb451a6b Fix failing tests. 2020-09-17 16:06:26 -04:00
Itamar Turner-Trauring
b784f9654c Merge branch '3415.storage-server-python-3' into 3416.test-encode-python-3 2020-09-17 13:12:46 -04:00
Itamar Turner-Trauring
cecbc260fa Fix order. 2020-09-17 11:43:35 -04:00
Itamar Turner-Trauring
498e69c72e Some progress. 2020-09-16 14:57:55 -04:00
Itamar Turner-Trauring
2588e757e5 Only semi-break the web service. 2020-09-16 14:42:39 -04:00
Itamar Turner-Trauring
833bc72ac3 Merge remote-tracking branch 'origin/master' into 3416.test-encode-python-3 2020-09-16 14:40:40 -04:00
Itamar Turner-Trauring
e8743a607f Fix failing tests. 2020-09-16 14:37:16 -04:00
Itamar Turner-Trauring
bea1d657f3 Better debug output. 2020-09-16 14:37:11 -04:00