mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 05:28:04 +00:00
Merge pull request #1005 from tahoe-lafs/3634.cli-tests-python-3
Start porting CLI tests to Python 3 Fixes ticket:3634
This commit is contained in:
commit
28662eef0e
0
newsfragments/3634.minor
Normal file
0
newsfragments/3634.minor
Normal file
@ -229,19 +229,19 @@ def get_alias(aliases, path_unicode, default):
|
|||||||
precondition(isinstance(path_unicode, str), path_unicode)
|
precondition(isinstance(path_unicode, str), path_unicode)
|
||||||
|
|
||||||
from allmydata import uri
|
from allmydata import uri
|
||||||
path = path_unicode.encode('utf-8').strip(" ")
|
path = path_unicode.encode('utf-8').strip(b" ")
|
||||||
if uri.has_uri_prefix(path):
|
if uri.has_uri_prefix(path):
|
||||||
# We used to require "URI:blah:./foo" in order to get a subpath,
|
# We used to require "URI:blah:./foo" in order to get a subpath,
|
||||||
# stripping out the ":./" sequence. We still allow that for compatibility,
|
# stripping out the ":./" sequence. We still allow that for compatibility,
|
||||||
# but now also allow just "URI:blah/foo".
|
# but now also allow just "URI:blah/foo".
|
||||||
sep = path.find(":./")
|
sep = path.find(b":./")
|
||||||
if sep != -1:
|
if sep != -1:
|
||||||
return path[:sep], path[sep+3:]
|
return path[:sep], path[sep+3:]
|
||||||
sep = path.find("/")
|
sep = path.find(b"/")
|
||||||
if sep != -1:
|
if sep != -1:
|
||||||
return path[:sep], path[sep+1:]
|
return path[:sep], path[sep+1:]
|
||||||
return path, ""
|
return path, b""
|
||||||
colon = path.find(":")
|
colon = path.find(b":")
|
||||||
if colon == -1:
|
if colon == -1:
|
||||||
# no alias
|
# no alias
|
||||||
if default == None:
|
if default == None:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from six.moves import cStringIO as StringIO
|
from io import BytesIO
|
||||||
from six.moves import urllib, http_client
|
from six.moves import urllib, http_client
|
||||||
import six
|
import six
|
||||||
import allmydata # for __full_version__
|
import allmydata # for __full_version__
|
||||||
@ -38,9 +38,9 @@ class BadResponse(object):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def do_http(method, url, body=""):
|
def do_http(method, url, body=b""):
|
||||||
if isinstance(body, str):
|
if isinstance(body, bytes):
|
||||||
body = StringIO(body)
|
body = BytesIO(body)
|
||||||
elif isinstance(body, six.text_type):
|
elif isinstance(body, six.text_type):
|
||||||
raise TypeError("do_http body must be a bytestring, not unicode")
|
raise TypeError("do_http body must be a bytestring, not unicode")
|
||||||
else:
|
else:
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from past.builtins import unicode
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import codecs
|
import codecs
|
||||||
import json
|
|
||||||
|
|
||||||
from allmydata.util.assertutil import precondition
|
from allmydata.util.assertutil import precondition
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ from allmydata.scripts.common_http import do_http, check_http_error
|
|||||||
from allmydata.scripts.common import get_aliases
|
from allmydata.scripts.common import get_aliases
|
||||||
from allmydata.util.fileutil import move_into_place
|
from allmydata.util.fileutil import move_into_place
|
||||||
from allmydata.util.encodingutil import quote_output, quote_output_u
|
from allmydata.util.encodingutil import quote_output, quote_output_u
|
||||||
|
from allmydata.util import jsonbytes as json
|
||||||
|
|
||||||
|
|
||||||
def add_line_to_aliasfile(aliasfile, alias, cap):
|
def add_line_to_aliasfile(aliasfile, alias, cap):
|
||||||
@ -52,7 +54,7 @@ def add_alias(options):
|
|||||||
show_output(stderr, "Alias {alias} already exists!", alias=alias)
|
show_output(stderr, "Alias {alias} already exists!", alias=alias)
|
||||||
return 1
|
return 1
|
||||||
aliasfile = os.path.join(nodedir, "private", "aliases")
|
aliasfile = os.path.join(nodedir, "private", "aliases")
|
||||||
cap = uri.from_string_dirnode(cap).to_string()
|
cap = unicode(uri.from_string_dirnode(cap).to_string(), 'utf-8')
|
||||||
|
|
||||||
add_line_to_aliasfile(aliasfile, alias, cap)
|
add_line_to_aliasfile(aliasfile, alias, cap)
|
||||||
show_output(stdout, "Alias {alias} added", alias=alias)
|
show_output(stdout, "Alias {alias} added", alias=alias)
|
||||||
@ -92,7 +94,7 @@ def create_alias(options):
|
|||||||
|
|
||||||
# probably check for others..
|
# probably check for others..
|
||||||
|
|
||||||
add_line_to_aliasfile(aliasfile, alias, new_uri)
|
add_line_to_aliasfile(aliasfile, alias, unicode(new_uri, "utf-8"))
|
||||||
show_output(stdout, "Alias {alias} created", alias=alias)
|
show_output(stdout, "Alias {alias} created", alias=alias)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -167,7 +169,10 @@ def list_aliases(options):
|
|||||||
data = _get_alias_details(options['node-directory'])
|
data = _get_alias_details(options['node-directory'])
|
||||||
|
|
||||||
if options['json']:
|
if options['json']:
|
||||||
output = _escape_format(json.dumps(data, indent=4).decode("ascii"))
|
dumped = json.dumps(data, indent=4)
|
||||||
|
if isinstance(dumped, bytes):
|
||||||
|
dumped = dumped.decode("utf-8")
|
||||||
|
output = _escape_format(dumped)
|
||||||
else:
|
else:
|
||||||
def dircap(details):
|
def dircap(details):
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from future.builtins import chr
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import urllib
|
from urllib.parse import urlencode, quote as url_quote
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@ -25,12 +27,12 @@ def _get_json_for_fragment(options, fragment, method='GET', post_args=None):
|
|||||||
if method == 'POST':
|
if method == 'POST':
|
||||||
if post_args is None:
|
if post_args is None:
|
||||||
raise ValueError("Must pass post_args= for POST method")
|
raise ValueError("Must pass post_args= for POST method")
|
||||||
body = urllib.urlencode(post_args)
|
body = urlencode(post_args)
|
||||||
else:
|
else:
|
||||||
body = ''
|
body = ''
|
||||||
if post_args is not None:
|
if post_args is not None:
|
||||||
raise ValueError("post_args= only valid for POST method")
|
raise ValueError("post_args= only valid for POST method")
|
||||||
resp = do_http(method, url, body=body)
|
resp = do_http(method, url, body=body.encode("utf-8"))
|
||||||
if isinstance(resp, BadResponse):
|
if isinstance(resp, BadResponse):
|
||||||
# specifically NOT using format_http_error() here because the
|
# specifically NOT using format_http_error() here because the
|
||||||
# URL is pretty sensitive (we're doing /uri/<key>).
|
# URL is pretty sensitive (we're doing /uri/<key>).
|
||||||
@ -48,7 +50,7 @@ def _get_json_for_fragment(options, fragment, method='GET', post_args=None):
|
|||||||
def _get_json_for_cap(options, cap):
|
def _get_json_for_cap(options, cap):
|
||||||
return _get_json_for_fragment(
|
return _get_json_for_fragment(
|
||||||
options,
|
options,
|
||||||
'uri/%s?t=json' % urllib.quote(cap),
|
'uri/%s?t=json' % url_quote(cap),
|
||||||
)
|
)
|
||||||
|
|
||||||
def pretty_progress(percent, size=10, ascii=False):
|
def pretty_progress(percent, size=10, ascii=False):
|
||||||
@ -74,8 +76,8 @@ def pretty_progress(percent, size=10, ascii=False):
|
|||||||
|
|
||||||
# unicode 0x2581 -> 2589 are vertical bar chunks, like rainbarf uses
|
# unicode 0x2581 -> 2589 are vertical bar chunks, like rainbarf uses
|
||||||
# and following are narrow -> wider bars
|
# and following are narrow -> wider bars
|
||||||
part = unichr(0x258f - part) # for smooth bar
|
part = chr(0x258f - part) # for smooth bar
|
||||||
# part = unichr(0x2581 + part) # for neater-looking thing
|
# part = chr(0x2581 + part) # for neater-looking thing
|
||||||
|
|
||||||
# hack for 100+ full so we don't print extra really-narrow/high bar
|
# hack for 100+ full so we don't print extra really-narrow/high bar
|
||||||
if percent >= 100.0:
|
if percent >= 100.0:
|
||||||
|
@ -55,5 +55,5 @@ class CLITestMixin(ReallyEqualMixin):
|
|||||||
verb = ensure_str(verb)
|
verb = ensure_str(verb)
|
||||||
args = [ensure_str(arg) for arg in args]
|
args = [ensure_str(arg) for arg in args]
|
||||||
client_dir = ensure_str(self.get_clientdir(i=client_num))
|
client_dir = ensure_str(self.get_clientdir(i=client_num))
|
||||||
nodeargs = [ b"--node-directory", client_dir ]
|
nodeargs = [ "--node-directory", client_dir ]
|
||||||
return run_cli(verb, *args, nodeargs=nodeargs, **kwargs)
|
return run_cli(verb, *args, nodeargs=nodeargs, **kwargs)
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
"""
|
||||||
|
Ported to Python 3.
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from future.utils import PY2
|
||||||
|
if PY2:
|
||||||
|
from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
@ -59,7 +71,7 @@ class ListAlias(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||||||
# the node filesystem state.
|
# the node filesystem state.
|
||||||
aliases = get_aliases(self.get_clientdir())
|
aliases = get_aliases(self.get_clientdir())
|
||||||
self.assertIn(alias, aliases)
|
self.assertIn(alias, aliases)
|
||||||
self.assertTrue(aliases[alias].startswith(u"URI:DIR2:"))
|
self.assertTrue(aliases[alias].startswith(b"URI:DIR2:"))
|
||||||
|
|
||||||
# And inspect the state via the user interface list-aliases command
|
# And inspect the state via the user interface list-aliases command
|
||||||
# too.
|
# too.
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
|
"""
|
||||||
|
Ported to Python 3.
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from future.utils import PY2
|
||||||
|
if PY2:
|
||||||
|
from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
|
||||||
|
from six import ensure_text
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import mock
|
import mock
|
||||||
import json
|
|
||||||
import tempfile
|
import tempfile
|
||||||
from six.moves import StringIO
|
from io import BytesIO, StringIO
|
||||||
from os.path import join
|
from os.path import join
|
||||||
from UserDict import UserDict
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
@ -22,6 +33,7 @@ from allmydata.immutable.downloader.status import DownloadStatus
|
|||||||
from allmydata.mutable.publish import PublishStatus
|
from allmydata.mutable.publish import PublishStatus
|
||||||
from allmydata.mutable.retrieve import RetrieveStatus
|
from allmydata.mutable.retrieve import RetrieveStatus
|
||||||
from allmydata.mutable.servermap import UpdateStatus
|
from allmydata.mutable.servermap import UpdateStatus
|
||||||
|
from allmydata.util import jsonbytes as json
|
||||||
|
|
||||||
from ..no_network import GridTestMixin
|
from ..no_network import GridTestMixin
|
||||||
from ..common_web import do_http
|
from ..common_web import do_http
|
||||||
@ -60,9 +72,8 @@ class ProgressBar(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class _FakeOptions(UserDict, object):
|
class _FakeOptions(dict):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_FakeOptions, self).__init__()
|
|
||||||
self._tmp = tempfile.mkdtemp()
|
self._tmp = tempfile.mkdtemp()
|
||||||
os.mkdir(join(self._tmp, 'private'), 0o777)
|
os.mkdir(join(self._tmp, 'private'), 0o777)
|
||||||
with open(join(self._tmp, 'private', 'api_auth_token'), 'w') as f:
|
with open(join(self._tmp, 'private', 'api_auth_token'), 'w') as f:
|
||||||
@ -86,7 +97,7 @@ class Integration(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||||||
|
|
||||||
# upload something
|
# upload something
|
||||||
c0 = self.g.clients[0]
|
c0 = self.g.clients[0]
|
||||||
data = MutableData("data" * 100)
|
data = MutableData(b"data" * 100)
|
||||||
filenode = yield c0.create_mutable_file(data)
|
filenode = yield c0.create_mutable_file(data)
|
||||||
self.uri = filenode.get_uri()
|
self.uri = filenode.get_uri()
|
||||||
|
|
||||||
@ -97,8 +108,8 @@ class Integration(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||||||
d = self.do_cli('status')# '--verbose')
|
d = self.do_cli('status')# '--verbose')
|
||||||
|
|
||||||
def _check(ign):
|
def _check(ign):
|
||||||
code, stdout, stdin = ign
|
code, stdout, stderr = ign
|
||||||
self.assertEqual(code, 0)
|
self.assertEqual(code, 0, stderr)
|
||||||
self.assertTrue('Skipped 1' in stdout)
|
self.assertTrue('Skipped 1' in stdout)
|
||||||
d.addCallback(_check)
|
d.addCallback(_check)
|
||||||
return d
|
return d
|
||||||
@ -124,18 +135,18 @@ class CommandStatus(unittest.TestCase):
|
|||||||
@mock.patch('sys.stdout', StringIO())
|
@mock.patch('sys.stdout', StringIO())
|
||||||
def test_no_operations(self, http):
|
def test_no_operations(self, http):
|
||||||
values = [
|
values = [
|
||||||
StringIO(json.dumps({
|
StringIO(ensure_text(json.dumps({
|
||||||
"active": [],
|
"active": [],
|
||||||
"recent": [],
|
"recent": [],
|
||||||
})),
|
}))),
|
||||||
StringIO(json.dumps({
|
StringIO(ensure_text(json.dumps({
|
||||||
"counters": {
|
"counters": {
|
||||||
"bytes_downloaded": 0,
|
"bytes_downloaded": 0,
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"node.uptime": 0,
|
"node.uptime": 0,
|
||||||
}
|
}
|
||||||
})),
|
}))),
|
||||||
]
|
]
|
||||||
http.side_effect = lambda *args, **kw: values.pop(0)
|
http.side_effect = lambda *args, **kw: values.pop(0)
|
||||||
do_status(self.options)
|
do_status(self.options)
|
||||||
@ -145,14 +156,14 @@ class CommandStatus(unittest.TestCase):
|
|||||||
def test_simple(self, http):
|
def test_simple(self, http):
|
||||||
recent_items = active_items = [
|
recent_items = active_items = [
|
||||||
UploadStatus(),
|
UploadStatus(),
|
||||||
DownloadStatus("abcd", 12345),
|
DownloadStatus(b"abcd", 12345),
|
||||||
PublishStatus(),
|
PublishStatus(),
|
||||||
RetrieveStatus(),
|
RetrieveStatus(),
|
||||||
UpdateStatus(),
|
UpdateStatus(),
|
||||||
FakeStatus(),
|
FakeStatus(),
|
||||||
]
|
]
|
||||||
values = [
|
values = [
|
||||||
StringIO(json.dumps({
|
BytesIO(json.dumps({
|
||||||
"active": list(
|
"active": list(
|
||||||
marshal_json(item)
|
marshal_json(item)
|
||||||
for item
|
for item
|
||||||
@ -163,15 +174,15 @@ class CommandStatus(unittest.TestCase):
|
|||||||
for item
|
for item
|
||||||
in recent_items
|
in recent_items
|
||||||
),
|
),
|
||||||
})),
|
}).encode("utf-8")),
|
||||||
StringIO(json.dumps({
|
BytesIO(json.dumps({
|
||||||
"counters": {
|
"counters": {
|
||||||
"bytes_downloaded": 0,
|
"bytes_downloaded": 0,
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"node.uptime": 0,
|
"node.uptime": 0,
|
||||||
}
|
}
|
||||||
})),
|
}).encode("utf-8")),
|
||||||
]
|
]
|
||||||
http.side_effect = lambda *args, **kw: values.pop(0)
|
http.side_effect = lambda *args, **kw: values.pop(0)
|
||||||
do_status(self.options)
|
do_status(self.options)
|
||||||
|
@ -141,7 +141,9 @@ PORTED_MODULES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
PORTED_TEST_MODULES = [
|
PORTED_TEST_MODULES = [
|
||||||
|
"allmydata.test.cli.test_alias",
|
||||||
"allmydata.test.cli.test_create",
|
"allmydata.test.cli.test_create",
|
||||||
|
"allmydata.test.cli.test_status",
|
||||||
|
|
||||||
"allmydata.test.mutable.test_checker",
|
"allmydata.test.mutable.test_checker",
|
||||||
"allmydata.test.mutable.test_datahandle",
|
"allmydata.test.mutable.test_datahandle",
|
||||||
|
Loading…
Reference in New Issue
Block a user