2019-03-22 16:25:11 +00:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2014-09-03 01:22:59 +00:00
|
|
|
import os, shutil, sys, urllib, time, stat, urlparse
|
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-27 20:00:19 +00:00
|
|
|
|
2020-10-07 19:01:35 +00:00
|
|
|
# Python 2 compatibility
|
2020-10-01 15:57:54 +00:00
|
|
|
from future.utils import PY2
|
|
|
|
if PY2:
|
|
|
|
from future.builtins import str # noqa: F401
|
2019-03-24 14:04:00 +00:00
|
|
|
from six.moves import cStringIO as StringIO
|
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-27 20:00:19 +00:00
|
|
|
|
2007-03-12 23:28:37 +00:00
|
|
|
from twisted.internet import defer, reactor, protocol, error
|
2007-05-25 00:34:42 +00:00
|
|
|
from twisted.application import service, internet
|
2007-09-19 03:35:27 +00:00
|
|
|
from twisted.web import client as tw_client
|
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-27 20:00:19 +00:00
|
|
|
from twisted.python import log, procutils
|
|
|
|
from foolscap.api import Tub, fireEventually, flushEventualQueue
|
|
|
|
|
2008-07-16 20:14:39 +00:00
|
|
|
from allmydata import client, introducer
|
|
|
|
from allmydata.immutable import upload
|
2007-07-17 01:08:55 +00:00
|
|
|
from allmydata.scripts import create_node
|
2008-10-29 04:15:48 +00:00
|
|
|
from allmydata.util import fileutil, pollmixin
|
2010-07-22 00:14:18 +00:00
|
|
|
from allmydata.util.fileutil import abspath_expanduser_unicode
|
|
|
|
from allmydata.util.encodingutil import get_filesystem_encoding
|
2007-03-12 23:28:37 +00:00
|
|
|
|
2019-08-13 20:55:40 +00:00
|
|
|
class StallableHTTPGetterDiscarder(tw_client.HTTPPageGetter, object):
|
2007-09-19 03:35:27 +00:00
|
|
|
full_speed_ahead = False
|
|
|
|
_bytes_so_far = 0
|
|
|
|
stalled = None
|
|
|
|
def handleResponsePart(self, data):
|
|
|
|
self._bytes_so_far += len(data)
|
|
|
|
if not self.factory.do_stall:
|
|
|
|
return
|
|
|
|
if self.full_speed_ahead:
|
|
|
|
return
|
|
|
|
if self._bytes_so_far > 1e6+100:
|
|
|
|
if not self.stalled:
|
2019-03-22 16:25:11 +00:00
|
|
|
print("STALLING")
|
2007-09-19 03:35:27 +00:00
|
|
|
self.transport.pauseProducing()
|
|
|
|
self.stalled = reactor.callLater(10.0, self._resume_speed)
|
|
|
|
def _resume_speed(self):
|
2019-03-22 16:25:11 +00:00
|
|
|
print("RESUME SPEED")
|
2007-09-19 03:35:27 +00:00
|
|
|
self.stalled = None
|
|
|
|
self.full_speed_ahead = True
|
|
|
|
self.transport.resumeProducing()
|
|
|
|
def handleResponseEnd(self):
|
|
|
|
if self.stalled:
|
2019-03-22 16:25:11 +00:00
|
|
|
print("CANCEL")
|
2007-09-19 03:35:27 +00:00
|
|
|
self.stalled.cancel()
|
|
|
|
self.stalled = None
|
|
|
|
return tw_client.HTTPPageGetter.handleResponseEnd(self)
|
|
|
|
|
2019-08-13 20:55:40 +00:00
|
|
|
class StallableDiscardingHTTPClientFactory(tw_client.HTTPClientFactory, object):
|
2007-09-19 03:35:27 +00:00
|
|
|
protocol = StallableHTTPGetterDiscarder
|
|
|
|
|
|
|
|
def discardPage(url, stall=False, *args, **kwargs):
|
|
|
|
"""Start fetching the URL, but stall our pipe after the first 1MB.
|
|
|
|
Wait 10 seconds, then resume downloading (and discarding) everything.
|
|
|
|
"""
|
|
|
|
# adapted from twisted.web.client.getPage . We can't just wrap or
|
|
|
|
# subclass because it provides no way to override the HTTPClientFactory
|
|
|
|
# that it creates.
|
2014-09-03 01:22:59 +00:00
|
|
|
scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
|
|
|
|
assert scheme == 'http'
|
|
|
|
host, port = netloc, 80
|
|
|
|
if ":" in host:
|
|
|
|
host, port = host.split(":")
|
|
|
|
port = int(port)
|
2007-09-19 03:35:27 +00:00
|
|
|
factory = StallableDiscardingHTTPClientFactory(url, *args, **kwargs)
|
|
|
|
factory.do_stall = stall
|
|
|
|
reactor.connectTCP(host, port, factory)
|
|
|
|
return factory.deferred
|
|
|
|
|
2009-02-23 00:28:55 +00:00
|
|
|
class ChildDidNotStartError(Exception):
|
|
|
|
pass
|
|
|
|
|
2008-10-29 04:15:48 +00:00
|
|
|
class SystemFramework(pollmixin.PollMixin):
|
2010-06-08 01:35:28 +00:00
|
|
|
numnodes = 7
|
2007-03-12 23:28:37 +00:00
|
|
|
|
2007-07-17 01:08:55 +00:00
|
|
|
def __init__(self, basedir, mode):
|
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-27 20:00:19 +00:00
|
|
|
self.basedir = basedir = abspath_expanduser_unicode(str(basedir))
|
2010-07-22 00:14:18 +00:00
|
|
|
if not (basedir + os.path.sep).startswith(abspath_expanduser_unicode(u".") + os.path.sep):
|
2007-03-12 23:28:37 +00:00
|
|
|
raise AssertionError("safety issue: basedir must be a subdir")
|
2007-09-16 03:53:06 +00:00
|
|
|
self.testdir = testdir = os.path.join(basedir, "test")
|
|
|
|
if os.path.exists(testdir):
|
|
|
|
shutil.rmtree(testdir)
|
|
|
|
fileutil.make_dirs(testdir)
|
2007-03-12 23:28:37 +00:00
|
|
|
self.sparent = service.MultiService()
|
|
|
|
self.sparent.startService()
|
2007-05-30 00:39:39 +00:00
|
|
|
self.proc = None
|
2009-05-22 00:38:23 +00:00
|
|
|
self.tub = Tub()
|
2009-05-22 00:46:32 +00:00
|
|
|
self.tub.setOption("expose-remote-exception-types", False)
|
2007-05-30 00:39:39 +00:00
|
|
|
self.tub.setServiceParent(self.sparent)
|
2007-07-17 01:08:55 +00:00
|
|
|
self.mode = mode
|
2007-09-15 18:47:29 +00:00
|
|
|
self.failed = False
|
2007-10-11 09:20:20 +00:00
|
|
|
self.keepalive_file = None
|
2007-03-12 23:28:37 +00:00
|
|
|
|
|
|
|
def run(self):
|
2007-09-26 01:26:54 +00:00
|
|
|
framelog = os.path.join(self.basedir, "driver.log")
|
|
|
|
log.startLogging(open(framelog, "a"), setStdout=False)
|
|
|
|
log.msg("CHECK_MEMORY(mode=%s) STARTING" % self.mode)
|
2007-09-16 03:53:06 +00:00
|
|
|
#logfile = open(os.path.join(self.testdir, "log"), "w")
|
2007-05-30 00:39:39 +00:00
|
|
|
#flo = log.FileLogObserver(logfile)
|
|
|
|
#log.startLoggingWithObserver(flo.emit, setStdout=False)
|
2009-05-22 00:38:23 +00:00
|
|
|
d = fireEventually()
|
2007-05-30 00:39:39 +00:00
|
|
|
d.addCallback(lambda res: self.setUp())
|
2007-09-20 19:36:27 +00:00
|
|
|
d.addCallback(lambda res: self.record_initial_memusage())
|
|
|
|
d.addCallback(lambda res: self.make_nodes())
|
|
|
|
d.addCallback(lambda res: self.wait_for_client_connected())
|
2007-05-30 00:39:39 +00:00
|
|
|
d.addCallback(lambda res: self.do_test())
|
|
|
|
d.addBoth(self.tearDown)
|
|
|
|
def _err(err):
|
2007-09-15 18:47:29 +00:00
|
|
|
self.failed = err
|
2007-05-30 00:39:39 +00:00
|
|
|
log.err(err)
|
2019-03-22 16:25:11 +00:00
|
|
|
print(err)
|
2007-05-30 00:39:39 +00:00
|
|
|
d.addErrback(_err)
|
2007-09-15 18:47:29 +00:00
|
|
|
def _done(res):
|
|
|
|
reactor.stop()
|
|
|
|
return res
|
|
|
|
d.addBoth(_done)
|
2007-03-12 23:28:37 +00:00
|
|
|
reactor.run()
|
2007-09-15 18:47:29 +00:00
|
|
|
if self.failed:
|
2007-09-26 01:26:54 +00:00
|
|
|
# raiseException doesn't work for CopiedFailures
|
2007-09-15 18:47:29 +00:00
|
|
|
self.failed.raiseException()
|
2007-03-12 23:28:37 +00:00
|
|
|
|
2007-05-30 00:39:39 +00:00
|
|
|
def setUp(self):
|
2020-09-11 14:28:22 +00:00
|
|
|
#print("STARTING")
|
2007-07-17 01:08:55 +00:00
|
|
|
self.stats = {}
|
2007-09-16 03:53:06 +00:00
|
|
|
self.statsfile = open(os.path.join(self.basedir, "stats.out"), "a")
|
2016-04-27 04:54:45 +00:00
|
|
|
self.make_introducer()
|
|
|
|
d = self.start_client()
|
2007-05-30 00:39:39 +00:00
|
|
|
def _record_control_furl(control_furl):
|
|
|
|
self.control_furl = control_furl
|
2020-09-11 14:28:22 +00:00
|
|
|
#print("OBTAINING '%s'" % (control_furl,))
|
2007-05-30 00:39:39 +00:00
|
|
|
return self.tub.getReference(self.control_furl)
|
|
|
|
d.addCallback(_record_control_furl)
|
|
|
|
def _record_control(control_rref):
|
|
|
|
self.control_rref = control_rref
|
|
|
|
d.addCallback(_record_control)
|
|
|
|
def _ready(res):
|
2020-09-11 14:28:22 +00:00
|
|
|
#print("CLIENT READY")
|
2007-07-17 01:08:55 +00:00
|
|
|
pass
|
2007-05-30 00:39:39 +00:00
|
|
|
d.addCallback(_ready)
|
2007-03-12 23:28:37 +00:00
|
|
|
return d
|
|
|
|
|
2007-09-20 19:36:27 +00:00
|
|
|
def record_initial_memusage(self):
|
2019-03-22 16:25:11 +00:00
|
|
|
print()
|
|
|
|
print("Client started (no connections yet)")
|
2007-09-20 19:36:27 +00:00
|
|
|
d = self._print_usage()
|
|
|
|
d.addCallback(self.stash_stats, "init")
|
|
|
|
return d
|
|
|
|
|
|
|
|
def wait_for_client_connected(self):
|
2019-03-22 16:25:11 +00:00
|
|
|
print()
|
|
|
|
print("Client connecting to other nodes..")
|
2007-09-20 19:36:27 +00:00
|
|
|
return self.control_rref.callRemote("wait_for_client_connections",
|
|
|
|
self.numnodes+1)
|
|
|
|
|
2007-05-30 00:39:39 +00:00
|
|
|
def tearDown(self, passthrough):
|
2007-03-12 23:28:37 +00:00
|
|
|
# the client node will shut down in a few seconds
|
2014-08-17 14:36:57 +00:00
|
|
|
#os.remove(os.path.join(self.clientdir, client.Client.EXIT_TRIGGER_FILE))
|
2007-03-12 23:28:37 +00:00
|
|
|
log.msg("shutting down SystemTest services")
|
2007-10-11 09:20:20 +00:00
|
|
|
if self.keepalive_file and os.path.exists(self.keepalive_file):
|
2007-09-26 01:47:48 +00:00
|
|
|
age = time.time() - os.stat(self.keepalive_file)[stat.ST_MTIME]
|
|
|
|
log.msg("keepalive file at shutdown was %ds old" % age)
|
2007-05-30 00:39:39 +00:00
|
|
|
d = defer.succeed(None)
|
|
|
|
if self.proc:
|
|
|
|
d.addCallback(lambda res: self.kill_client())
|
|
|
|
d.addCallback(lambda res: self.sparent.stopService())
|
2009-05-22 00:38:23 +00:00
|
|
|
d.addCallback(lambda res: flushEventualQueue())
|
2007-07-17 01:08:55 +00:00
|
|
|
def _close_statsfile(res):
|
|
|
|
self.statsfile.close()
|
|
|
|
d.addCallback(_close_statsfile)
|
2007-05-30 00:39:39 +00:00
|
|
|
d.addCallback(lambda res: passthrough)
|
2007-03-12 23:28:37 +00:00
|
|
|
return d
|
|
|
|
|
2007-12-03 21:52:42 +00:00
|
|
|
def make_introducer(self):
|
|
|
|
iv_basedir = os.path.join(self.testdir, "introducer")
|
2007-05-25 00:34:42 +00:00
|
|
|
os.mkdir(iv_basedir)
|
2018-01-31 20:03:05 +00:00
|
|
|
self.introducer = introducer.IntroducerNode(basedir=iv_basedir)
|
|
|
|
self.introducer.setServiceParent(self)
|
2016-04-27 04:54:45 +00:00
|
|
|
self.introducer_furl = self.introducer.introducer_url
|
2007-03-12 23:28:37 +00:00
|
|
|
|
|
|
|
def make_nodes(self):
|
|
|
|
self.nodes = []
|
|
|
|
for i in range(self.numnodes):
|
2007-09-16 03:53:06 +00:00
|
|
|
nodedir = os.path.join(self.testdir, "node%d" % i)
|
2007-03-12 23:28:37 +00:00
|
|
|
os.mkdir(nodedir)
|
2011-08-25 20:11:16 +00:00
|
|
|
f = open(os.path.join(nodedir, "tahoe.cfg"), "w")
|
|
|
|
f.write("[client]\n"
|
|
|
|
"introducer.furl = %s\n"
|
|
|
|
"shares.happy = 1\n"
|
|
|
|
"[storage]\n"
|
|
|
|
% (self.introducer_furl,))
|
2007-09-19 19:59:32 +00:00
|
|
|
# the only tests for which we want the internal nodes to actually
|
|
|
|
# retain shares are the ones where somebody's going to download
|
|
|
|
# them.
|
|
|
|
if self.mode in ("download", "download-GET", "download-GET-slow"):
|
|
|
|
# retain shares
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
# for these tests, we tell the storage servers to pretend to
|
|
|
|
# accept shares, but really just throw them out, since we're
|
|
|
|
# only testing upload and not download.
|
2011-08-25 20:11:16 +00:00
|
|
|
f.write("debug_discard = true\n")
|
2007-09-19 19:59:32 +00:00
|
|
|
if self.mode in ("receive",):
|
|
|
|
# for this mode, the client-under-test gets all the shares,
|
|
|
|
# so our internal nodes can refuse requests
|
2011-08-25 20:11:16 +00:00
|
|
|
f.write("readonly = true\n")
|
|
|
|
f.close()
|
2018-01-31 20:03:05 +00:00
|
|
|
c = client.Client(basedir=nodedir)
|
|
|
|
c.setServiceParent(self)
|
2007-03-12 23:28:37 +00:00
|
|
|
self.nodes.append(c)
|
|
|
|
# the peers will start running, eventually they will connect to each
|
2007-12-03 21:52:42 +00:00
|
|
|
# other and the introducer
|
2007-03-12 23:28:37 +00:00
|
|
|
|
2007-03-23 05:22:00 +00:00
|
|
|
def touch_keepalive(self):
|
2007-09-26 01:26:54 +00:00
|
|
|
if os.path.exists(self.keepalive_file):
|
|
|
|
age = time.time() - os.stat(self.keepalive_file)[stat.ST_MTIME]
|
|
|
|
log.msg("touching keepalive file, was %ds old" % age)
|
2007-03-23 05:22:00 +00:00
|
|
|
f = open(self.keepalive_file, "w")
|
2007-05-25 00:34:42 +00:00
|
|
|
f.write("""\
|
|
|
|
If the node notices this file at startup, it will poll every 5 seconds and
|
|
|
|
terminate if the file is more than 10 seconds old, or if it has been deleted.
|
|
|
|
If the test harness has an internal failure and neglects to kill off the node
|
|
|
|
itself, this helps to avoid leaving processes lying around. The contents of
|
|
|
|
this file are ignored.
|
|
|
|
""")
|
2007-03-23 05:22:00 +00:00
|
|
|
f.close()
|
|
|
|
|
2007-03-12 23:28:37 +00:00
|
|
|
def start_client(self):
|
2007-05-30 00:39:39 +00:00
|
|
|
# this returns a Deferred that fires with the client's control.furl
|
2007-03-12 23:28:37 +00:00
|
|
|
log.msg("MAKING CLIENT")
|
2010-07-22 00:14:18 +00:00
|
|
|
# self.testdir is an absolute Unicode path
|
|
|
|
clientdir = self.clientdir = os.path.join(self.testdir, u"client")
|
|
|
|
clientdir_str = clientdir.encode(get_filesystem_encoding())
|
2007-07-17 01:08:55 +00:00
|
|
|
quiet = StringIO()
|
2011-08-25 20:11:16 +00:00
|
|
|
create_node.create_node({'basedir': clientdir}, out=quiet)
|
2007-03-12 23:28:37 +00:00
|
|
|
log.msg("DONE MAKING CLIENT")
|
2011-08-25 20:11:16 +00:00
|
|
|
# now replace tahoe.cfg
|
2008-05-08 23:49:27 +00:00
|
|
|
# set webport=0 and then ask the node what port it picked.
|
2011-08-25 20:11:16 +00:00
|
|
|
f = open(os.path.join(clientdir, "tahoe.cfg"), "w")
|
|
|
|
f.write("[node]\n"
|
|
|
|
"web.port = tcp:0:interface=127.0.0.1\n"
|
|
|
|
"[client]\n"
|
|
|
|
"introducer.furl = %s\n"
|
|
|
|
"shares.happy = 1\n"
|
|
|
|
"[storage]\n"
|
|
|
|
% (self.introducer_furl,))
|
2008-05-08 23:49:27 +00:00
|
|
|
|
2007-09-19 19:59:32 +00:00
|
|
|
if self.mode in ("upload-self", "receive"):
|
|
|
|
# accept and store shares, to trigger the memory consumption bugs
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
# don't accept any shares
|
2011-08-25 20:11:16 +00:00
|
|
|
f.write("readonly = true\n")
|
2007-09-19 19:59:32 +00:00
|
|
|
## also, if we do receive any shares, throw them away
|
2011-08-25 20:11:16 +00:00
|
|
|
#f.write("debug_discard = true")
|
2007-09-19 11:14:48 +00:00
|
|
|
if self.mode == "upload-self":
|
2008-02-05 21:16:01 +00:00
|
|
|
pass
|
2011-08-25 20:11:16 +00:00
|
|
|
f.close()
|
2007-05-25 00:34:42 +00:00
|
|
|
self.keepalive_file = os.path.join(clientdir,
|
2014-08-17 14:36:57 +00:00
|
|
|
client.Client.EXIT_TRIGGER_FILE)
|
2007-03-23 05:22:00 +00:00
|
|
|
# now start updating the mtime.
|
2007-05-25 00:34:42 +00:00
|
|
|
self.touch_keepalive()
|
2007-09-21 02:35:31 +00:00
|
|
|
ts = internet.TimerService(1.0, self.touch_keepalive)
|
2007-05-25 00:34:42 +00:00
|
|
|
ts.setServiceParent(self.sparent)
|
2007-03-12 23:28:37 +00:00
|
|
|
|
|
|
|
pp = ClientWatcher()
|
2007-05-30 00:39:39 +00:00
|
|
|
self.proc_done = pp.d = defer.Deferred()
|
2007-09-15 19:34:05 +00:00
|
|
|
logfile = os.path.join(self.basedir, "client.log")
|
2016-03-25 23:26:29 +00:00
|
|
|
tahoes = procutils.which("tahoe")
|
|
|
|
if not tahoes:
|
|
|
|
raise RuntimeError("unable to find a 'tahoe' executable")
|
|
|
|
cmd = [tahoes[0], "run", ".", "-l", logfile]
|
2007-03-12 23:28:37 +00:00
|
|
|
env = os.environ.copy()
|
2010-07-22 00:14:18 +00:00
|
|
|
self.proc = reactor.spawnProcess(pp, cmd[0], cmd, env, path=clientdir_str)
|
2007-03-12 23:28:37 +00:00
|
|
|
log.msg("CLIENT STARTED")
|
|
|
|
|
2007-05-30 00:39:39 +00:00
|
|
|
# now we wait for the client to get started. we're looking for the
|
|
|
|
# control.furl file to appear.
|
2007-12-17 23:39:54 +00:00
|
|
|
furl_file = os.path.join(clientdir, "private", "control.furl")
|
2008-05-08 23:49:27 +00:00
|
|
|
url_file = os.path.join(clientdir, "node.url")
|
2007-05-30 00:39:39 +00:00
|
|
|
def _check():
|
2007-09-15 18:47:29 +00:00
|
|
|
if pp.ended and pp.ended.value.status != 0:
|
|
|
|
# the twistd process ends normally (with rc=0) if the child
|
|
|
|
# is successfully launched. It ends abnormally (with rc!=0)
|
|
|
|
# if the child cannot be launched.
|
2009-02-23 00:28:55 +00:00
|
|
|
raise ChildDidNotStartError("process ended while waiting for startup")
|
2007-05-30 00:39:39 +00:00
|
|
|
return os.path.exists(furl_file)
|
|
|
|
d = self.poll(_check, 0.1)
|
|
|
|
# once it exists, wait a moment before we read from it, just in case
|
|
|
|
# it hasn't finished writing the whole thing. Ideally control.furl
|
|
|
|
# would be created in some atomic fashion, or made non-readable until
|
|
|
|
# it's ready, but I can't think of an easy way to do that, and I
|
|
|
|
# think the chances that we'll observe a half-write are pretty low.
|
|
|
|
def _stall(res):
|
|
|
|
d2 = defer.Deferred()
|
|
|
|
reactor.callLater(0.1, d2.callback, None)
|
|
|
|
return d2
|
|
|
|
d.addCallback(_stall)
|
|
|
|
def _read(res):
|
2008-05-08 23:49:27 +00:00
|
|
|
# read the node's URL
|
|
|
|
self.webish_url = open(url_file, "r").read().strip()
|
2008-05-09 01:01:31 +00:00
|
|
|
if self.webish_url[-1] == "/":
|
|
|
|
# trim trailing slash, since the rest of the code wants it gone
|
|
|
|
self.webish_url = self.webish_url[:-1]
|
2007-05-30 00:39:39 +00:00
|
|
|
f = open(furl_file, "r")
|
|
|
|
furl = f.read()
|
|
|
|
return furl.strip()
|
|
|
|
d.addCallback(_read)
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
2007-03-12 23:28:37 +00:00
|
|
|
def kill_client(self):
|
2007-05-30 00:39:39 +00:00
|
|
|
# returns a Deferred that fires when the process exits. This may only
|
|
|
|
# be called once.
|
2007-03-12 23:28:37 +00:00
|
|
|
try:
|
2007-09-16 03:53:06 +00:00
|
|
|
self.proc.signalProcess("INT")
|
2007-03-12 23:28:37 +00:00
|
|
|
except error.ProcessExitedAlready:
|
|
|
|
pass
|
2007-05-30 00:39:39 +00:00
|
|
|
return self.proc_done
|
|
|
|
|
|
|
|
|
|
|
|
def create_data(self, name, size):
|
2007-09-16 03:53:06 +00:00
|
|
|
filename = os.path.join(self.testdir, name + ".data")
|
2007-05-30 00:39:39 +00:00
|
|
|
f = open(filename, "wb")
|
|
|
|
block = "a" * 8192
|
|
|
|
while size > 0:
|
|
|
|
l = min(size, 8192)
|
|
|
|
f.write(block[:l])
|
|
|
|
size -= l
|
|
|
|
return filename
|
|
|
|
|
2007-07-17 01:08:55 +00:00
|
|
|
def stash_stats(self, stats, name):
|
|
|
|
self.statsfile.write("%s %s: %d\n" % (self.mode, name, stats['VmPeak']))
|
2007-09-16 03:53:06 +00:00
|
|
|
self.statsfile.flush()
|
2007-07-17 01:08:55 +00:00
|
|
|
self.stats[name] = stats['VmPeak']
|
|
|
|
|
2007-07-17 03:17:51 +00:00
|
|
|
def POST(self, urlpath, **fields):
|
|
|
|
url = self.webish_url + urlpath
|
|
|
|
sepbase = "boogabooga"
|
|
|
|
sep = "--" + sepbase
|
|
|
|
form = []
|
|
|
|
form.append(sep)
|
|
|
|
form.append('Content-Disposition: form-data; name="_charset"')
|
|
|
|
form.append('')
|
|
|
|
form.append('UTF-8')
|
|
|
|
form.append(sep)
|
|
|
|
for name, value in fields.iteritems():
|
|
|
|
if isinstance(value, tuple):
|
|
|
|
filename, value = value
|
|
|
|
form.append('Content-Disposition: form-data; name="%s"; '
|
|
|
|
'filename="%s"' % (name, filename))
|
|
|
|
else:
|
|
|
|
form.append('Content-Disposition: form-data; name="%s"' % name)
|
|
|
|
form.append('')
|
|
|
|
form.append(value)
|
|
|
|
form.append(sep)
|
|
|
|
form[-1] += "--"
|
|
|
|
body = "\r\n".join(form) + "\r\n"
|
|
|
|
headers = {"content-type": "multipart/form-data; boundary=%s" % sepbase,
|
|
|
|
}
|
2007-09-19 03:35:27 +00:00
|
|
|
return tw_client.getPage(url, method="POST", postdata=body,
|
|
|
|
headers=headers, followRedirect=False)
|
2007-07-17 03:17:51 +00:00
|
|
|
|
2007-09-19 03:35:27 +00:00
|
|
|
def GET_discard(self, urlpath, stall):
|
2007-09-19 01:56:05 +00:00
|
|
|
url = self.webish_url + urlpath + "?filename=dummy-get.out"
|
2007-09-19 03:35:27 +00:00
|
|
|
return discardPage(url, stall)
|
2007-09-19 01:56:05 +00:00
|
|
|
|
|
|
|
def _print_usage(self, res=None):
|
|
|
|
d = self.control_rref.callRemote("get_memory_usage")
|
|
|
|
def _print(stats):
|
2019-03-22 16:25:11 +00:00
|
|
|
print("VmSize: %9d VmPeak: %9d" % (stats["VmSize"],
|
|
|
|
stats["VmPeak"]))
|
2007-09-19 01:56:05 +00:00
|
|
|
return stats
|
|
|
|
d.addCallback(_print)
|
|
|
|
return d
|
|
|
|
|
|
|
|
def _do_upload(self, res, size, files, uris):
|
|
|
|
name = '%d' % size
|
2019-03-22 16:25:11 +00:00
|
|
|
print()
|
|
|
|
print("uploading %s" % name)
|
2007-09-19 01:56:05 +00:00
|
|
|
if self.mode in ("upload", "upload-self"):
|
2015-04-21 20:04:47 +00:00
|
|
|
d = self.control_rref.callRemote("upload_random_data_from_file",
|
|
|
|
size,
|
2011-08-25 20:11:16 +00:00
|
|
|
convergence="check-memory")
|
2007-09-19 01:56:05 +00:00
|
|
|
elif self.mode == "upload-POST":
|
|
|
|
data = "a" * size
|
2007-12-07 00:28:23 +00:00
|
|
|
url = "/uri"
|
2007-09-19 01:56:05 +00:00
|
|
|
d = self.POST(url, t="upload", file=("%d.data" % size, data))
|
2007-09-20 22:33:58 +00:00
|
|
|
elif self.mode in ("receive",
|
|
|
|
"download", "download-GET", "download-GET-slow"):
|
|
|
|
# mode=receive: upload the data from a local peer, so that the
|
2007-09-19 19:59:32 +00:00
|
|
|
# client-under-test receives and stores the shares
|
2007-09-20 22:33:58 +00:00
|
|
|
#
|
|
|
|
# mode=download*: upload the data from a local peer, then have
|
|
|
|
# the client-under-test download it.
|
|
|
|
#
|
|
|
|
# we need to wait until the uploading node has connected to all
|
|
|
|
# peers, since the wait_for_client_connections() above doesn't
|
|
|
|
# pay attention to our self.nodes[] and their connections.
|
2007-09-19 19:59:32 +00:00
|
|
|
files[name] = self.create_data(name, size)
|
|
|
|
u = self.nodes[0].getServiceNamed("uploader")
|
2007-09-20 22:33:58 +00:00
|
|
|
d = self.nodes[0].debug_wait_for_client_connections(self.numnodes+1)
|
2011-08-25 20:11:16 +00:00
|
|
|
d.addCallback(lambda res:
|
|
|
|
u.upload(upload.FileName(files[name],
|
|
|
|
convergence="check-memory")))
|
2012-05-22 15:50:36 +00:00
|
|
|
d.addCallback(lambda results: results.get_uri())
|
2007-09-19 01:56:05 +00:00
|
|
|
else:
|
2009-02-23 00:28:55 +00:00
|
|
|
raise ValueError("unknown mode=%s" % self.mode)
|
2007-09-19 01:56:05 +00:00
|
|
|
def _complete(uri):
|
|
|
|
uris[name] = uri
|
2019-03-22 16:25:11 +00:00
|
|
|
print("uploaded %s" % name)
|
2007-09-19 01:56:05 +00:00
|
|
|
d.addCallback(_complete)
|
|
|
|
return d
|
|
|
|
|
|
|
|
def _do_download(self, res, size, uris):
|
2007-09-19 03:35:27 +00:00
|
|
|
if self.mode not in ("download", "download-GET", "download-GET-slow"):
|
2007-09-19 01:56:05 +00:00
|
|
|
return
|
|
|
|
name = '%d' % size
|
2019-03-22 16:25:11 +00:00
|
|
|
print("downloading %s" % name)
|
2007-09-19 01:56:05 +00:00
|
|
|
uri = uris[name]
|
2007-09-19 03:35:27 +00:00
|
|
|
|
2007-09-19 01:56:05 +00:00
|
|
|
if self.mode == "download":
|
2015-04-21 20:04:47 +00:00
|
|
|
d = self.control_rref.callRemote("download_to_tempfile_and_delete",
|
|
|
|
uri)
|
2007-09-19 03:35:27 +00:00
|
|
|
elif self.mode == "download-GET":
|
|
|
|
url = "/uri/%s" % uri
|
|
|
|
d = self.GET_discard(urllib.quote(url), stall=False)
|
|
|
|
elif self.mode == "download-GET-slow":
|
2007-09-19 01:56:05 +00:00
|
|
|
url = "/uri/%s" % uri
|
2007-09-19 03:35:27 +00:00
|
|
|
d = self.GET_discard(urllib.quote(url), stall=True)
|
2007-09-19 01:56:05 +00:00
|
|
|
|
2007-09-19 03:35:27 +00:00
|
|
|
def _complete(res):
|
2019-03-22 16:25:11 +00:00
|
|
|
print("downloaded %s" % name)
|
2007-09-19 03:35:27 +00:00
|
|
|
return res
|
|
|
|
d.addCallback(_complete)
|
2007-09-19 01:56:05 +00:00
|
|
|
return d
|
|
|
|
|
2007-05-30 00:39:39 +00:00
|
|
|
def do_test(self):
|
2020-09-11 14:28:22 +00:00
|
|
|
#print("CLIENT STARTED")
|
|
|
|
#print("FURL", self.control_furl)
|
|
|
|
#print("RREF", self.control_rref)
|
|
|
|
#print()
|
2007-05-30 00:39:39 +00:00
|
|
|
kB = 1000; MB = 1000*1000
|
|
|
|
files = {}
|
|
|
|
uris = {}
|
2007-09-19 01:56:05 +00:00
|
|
|
|
|
|
|
d = self._print_usage()
|
2007-07-17 03:17:51 +00:00
|
|
|
d.addCallback(self.stash_stats, "0B")
|
2007-05-30 00:39:39 +00:00
|
|
|
|
|
|
|
for i in range(10):
|
2007-09-19 01:56:05 +00:00
|
|
|
d.addCallback(self._do_upload, 10*kB+i, files, uris)
|
|
|
|
d.addCallback(self._do_download, 10*kB+i, uris)
|
|
|
|
d.addCallback(self._print_usage)
|
2007-07-17 01:08:55 +00:00
|
|
|
d.addCallback(self.stash_stats, "10kB")
|
2007-05-30 00:39:39 +00:00
|
|
|
|
2007-07-17 01:08:55 +00:00
|
|
|
for i in range(3):
|
2007-09-19 01:56:05 +00:00
|
|
|
d.addCallback(self._do_upload, 10*MB+i, files, uris)
|
|
|
|
d.addCallback(self._do_download, 10*MB+i, uris)
|
|
|
|
d.addCallback(self._print_usage)
|
2007-07-17 01:08:55 +00:00
|
|
|
d.addCallback(self.stash_stats, "10MB")
|
|
|
|
|
2007-09-19 01:56:05 +00:00
|
|
|
for i in range(1):
|
|
|
|
d.addCallback(self._do_upload, 50*MB+i, files, uris)
|
|
|
|
d.addCallback(self._do_download, 50*MB+i, uris)
|
|
|
|
d.addCallback(self._print_usage)
|
2007-08-09 08:32:52 +00:00
|
|
|
d.addCallback(self.stash_stats, "50MB")
|
2007-05-30 00:39:39 +00:00
|
|
|
|
2007-08-15 19:55:11 +00:00
|
|
|
#for i in range(1):
|
2007-09-19 01:56:05 +00:00
|
|
|
# d.addCallback(self._do_upload, 100*MB+i, files, uris)
|
|
|
|
# d.addCallback(self._do_download, 100*MB+i, uris)
|
|
|
|
# d.addCallback(self._print_usage)
|
2007-08-15 19:55:11 +00:00
|
|
|
#d.addCallback(self.stash_stats, "100MB")
|
2007-08-09 18:30:33 +00:00
|
|
|
|
2007-05-30 00:39:39 +00:00
|
|
|
#d.addCallback(self.stall)
|
|
|
|
def _done(res):
|
2019-03-22 16:25:11 +00:00
|
|
|
print("FINISHING")
|
2007-05-30 00:39:39 +00:00
|
|
|
d.addCallback(_done)
|
|
|
|
return d
|
|
|
|
|
|
|
|
def stall(self, res):
|
|
|
|
d = defer.Deferred()
|
|
|
|
reactor.callLater(5, d.callback, None)
|
|
|
|
return d
|
2007-03-12 23:28:37 +00:00
|
|
|
|
|
|
|
|
2019-08-13 20:55:40 +00:00
|
|
|
class ClientWatcher(protocol.ProcessProtocol, object):
|
2007-09-15 03:16:57 +00:00
|
|
|
ended = False
|
2007-03-12 23:28:37 +00:00
|
|
|
def outReceived(self, data):
|
2019-03-22 16:25:11 +00:00
|
|
|
print("OUT:", data)
|
2007-03-12 23:28:37 +00:00
|
|
|
def errReceived(self, data):
|
2019-03-22 16:25:11 +00:00
|
|
|
print("ERR:", data)
|
2007-05-30 00:39:39 +00:00
|
|
|
def processEnded(self, reason):
|
2007-09-15 18:47:29 +00:00
|
|
|
self.ended = reason
|
2007-05-30 00:39:39 +00:00
|
|
|
self.d.callback(None)
|
2007-03-12 23:28:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2007-07-17 01:08:55 +00:00
|
|
|
mode = "upload"
|
|
|
|
if len(sys.argv) > 1:
|
|
|
|
mode = sys.argv[1]
|
2015-03-20 01:59:16 +00:00
|
|
|
if sys.maxint == 2147483647:
|
|
|
|
bits = "32"
|
|
|
|
elif sys.maxint == 9223372036854775807:
|
|
|
|
bits = "64"
|
|
|
|
else:
|
|
|
|
bits = "?"
|
2019-03-22 16:25:11 +00:00
|
|
|
print("%s-bit system (sys.maxint=%d)" % (bits, sys.maxint))
|
2007-09-16 03:53:06 +00:00
|
|
|
# put the logfile and stats.out in _test_memory/ . These stick around.
|
|
|
|
# put the nodes and other files in _test_memory/test/ . These are
|
|
|
|
# removed each time we run.
|
2007-07-17 01:08:55 +00:00
|
|
|
sf = SystemFramework("_test_memory", mode)
|
2007-03-12 23:28:37 +00:00
|
|
|
sf.run()
|