diff options
Diffstat (limited to 'test')
82 files changed, 638 insertions, 607 deletions
diff --git a/test/mitmproxy/console/__init__.py b/test/mitmproxy/console/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/mitmproxy/console/__init__.py diff --git a/test/mitmproxy/test_console_common.py b/test/mitmproxy/console/test_common.py index 219200e0..ac4e0209 100644 --- a/test/mitmproxy/test_console_common.py +++ b/test/mitmproxy/console/test_common.py @@ -1,13 +1,8 @@ -import os -from unittest.case import SkipTest -if os.name == "nt": - raise SkipTest("Skipped on Windows.") - - import mitmproxy.console.common as common -from . import tutils +from .. import tutils +@tutils.skip_appveyor def test_format_flow(): f = tutils.tflow(resp=True) assert common.format_flow(f, True) diff --git a/test/mitmproxy/test_console.py b/test/mitmproxy/console/test_console.py index 58a812a6..b68dd811 100644 --- a/test/mitmproxy/test_console.py +++ b/test/mitmproxy/console/test_console.py @@ -4,7 +4,7 @@ import netlib.tutils from mitmproxy import console from mitmproxy.console import common -from . import tutils +from .. import tutils class TestConsoleState: diff --git a/test/mitmproxy/test_console_help.py b/test/mitmproxy/console/test_help.py index 0589bd68..3c1cc57c 100644 --- a/test/mitmproxy/test_console_help.py +++ b/test/mitmproxy/console/test_help.py @@ -1,11 +1,8 @@ -import os -from unittest.case import SkipTest -if os.name == "nt": - raise SkipTest("Skipped on Windows.") - import mitmproxy.console.help as help +from .. import tutils +@tutils.skip_appveyor class TestHelp: def test_helptext(self): diff --git a/test/mitmproxy/test_console_palettes.py b/test/mitmproxy/console/test_palettes.py index b5d84ddd..a99730fa 100644 --- a/test/mitmproxy/test_console_palettes.py +++ b/test/mitmproxy/console/test_palettes.py @@ -1,10 +1,8 @@ -import os -from unittest.case import SkipTest -if os.name == "nt": - raise SkipTest("Skipped on Windows.") import mitmproxy.console.palettes as palettes +from .. import tutils +@tutils.skip_appveyor class TestPalette: def test_helptext(self): diff --git a/test/mitmproxy/test_console_pathedit.py b/test/mitmproxy/console/test_pathedit.py index e2c27b7c..107a48ac 100644 --- a/test/mitmproxy/test_console_pathedit.py +++ b/test/mitmproxy/console/test_pathedit.py @@ -2,7 +2,7 @@ import os from os.path import normpath from mitmproxy.console import pathedit -from . import tutils +from .. import tutils class TestPathCompleter: diff --git a/test/mitmproxy/data/har_extractor.har b/test/mitmproxy/data/har_extractor.har index 2f5099b3..6b5e2994 100644 --- a/test/mitmproxy/data/har_extractor.har +++ b/test/mitmproxy/data/har_extractor.har @@ -58,12 +58,12 @@ }, "headers": [ { - "name": "content-length", - "value": "7" - }, - { "name": "header-response", "value": "svalue" + }, + { + "name": "content-length", + "value": "7" } ], "headersSize": 44, @@ -75,4 +75,4 @@ ] } } -}
\ No newline at end of file +} diff --git a/test/mitmproxy/scripts/a.py b/test/mitmproxy/data/scripts/a.py index d4272ac8..d4272ac8 100644 --- a/test/mitmproxy/scripts/a.py +++ b/test/mitmproxy/data/scripts/a.py diff --git a/test/mitmproxy/scripts/a_helper.py b/test/mitmproxy/data/scripts/a_helper.py index e1f1c649..e1f1c649 100644 --- a/test/mitmproxy/scripts/a_helper.py +++ b/test/mitmproxy/data/scripts/a_helper.py diff --git a/test/mitmproxy/scripts/all.py b/test/mitmproxy/data/scripts/all.py index dad2aade..dad2aade 100644 --- a/test/mitmproxy/scripts/all.py +++ b/test/mitmproxy/data/scripts/all.py diff --git a/test/mitmproxy/scripts/concurrent_decorator.py b/test/mitmproxy/data/scripts/concurrent_decorator.py index cf3ab512..e017f605 100644 --- a/test/mitmproxy/scripts/concurrent_decorator.py +++ b/test/mitmproxy/data/scripts/concurrent_decorator.py @@ -1,6 +1,7 @@ import time from mitmproxy.script import concurrent + @concurrent def request(context, flow): time.sleep(0.1) diff --git a/test/mitmproxy/scripts/concurrent_decorator_err.py b/test/mitmproxy/data/scripts/concurrent_decorator_err.py index 071b8889..071b8889 100644 --- a/test/mitmproxy/scripts/concurrent_decorator_err.py +++ b/test/mitmproxy/data/scripts/concurrent_decorator_err.py diff --git a/test/mitmproxy/scripts/duplicate_flow.py b/test/mitmproxy/data/scripts/duplicate_flow.py index e13af786..e13af786 100644 --- a/test/mitmproxy/scripts/duplicate_flow.py +++ b/test/mitmproxy/data/scripts/duplicate_flow.py diff --git a/test/mitmproxy/scripts/loaderr.py b/test/mitmproxy/data/scripts/loaderr.py index 8dc4d56d..8dc4d56d 100644 --- a/test/mitmproxy/scripts/loaderr.py +++ b/test/mitmproxy/data/scripts/loaderr.py diff --git a/test/mitmproxy/scripts/reqerr.py b/test/mitmproxy/data/scripts/reqerr.py index e7c503a8..e7c503a8 100644 --- a/test/mitmproxy/scripts/reqerr.py +++ b/test/mitmproxy/data/scripts/reqerr.py diff --git a/test/mitmproxy/scripts/starterr.py b/test/mitmproxy/data/scripts/starterr.py index b217bdfe..b217bdfe 100644 --- a/test/mitmproxy/scripts/starterr.py +++ b/test/mitmproxy/data/scripts/starterr.py diff --git a/test/mitmproxy/scripts/stream_modify.py b/test/mitmproxy/data/scripts/stream_modify.py index e26d83f1..e26d83f1 100644 --- a/test/mitmproxy/scripts/stream_modify.py +++ b/test/mitmproxy/data/scripts/stream_modify.py diff --git a/test/mitmproxy/scripts/syntaxerr.py b/test/mitmproxy/data/scripts/syntaxerr.py index 219d6b84..219d6b84 100644 --- a/test/mitmproxy/scripts/syntaxerr.py +++ b/test/mitmproxy/data/scripts/syntaxerr.py diff --git a/test/mitmproxy/scripts/tcp_stream_modify.py b/test/mitmproxy/data/scripts/tcp_stream_modify.py index d7953ef9..d7953ef9 100644 --- a/test/mitmproxy/scripts/tcp_stream_modify.py +++ b/test/mitmproxy/data/scripts/tcp_stream_modify.py diff --git a/test/mitmproxy/scripts/unloaderr.py b/test/mitmproxy/data/scripts/unloaderr.py index fba02734..fba02734 100644 --- a/test/mitmproxy/scripts/unloaderr.py +++ b/test/mitmproxy/data/scripts/unloaderr.py diff --git a/test/mitmproxy/test_flow_export/locust_get.py b/test/mitmproxy/data/test_flow_export/locust_get.py index 632d5d53..632d5d53 100644 --- a/test/mitmproxy/test_flow_export/locust_get.py +++ b/test/mitmproxy/data/test_flow_export/locust_get.py diff --git a/test/mitmproxy/test_flow_export/locust_patch.py b/test/mitmproxy/data/test_flow_export/locust_patch.py index f64e0857..f64e0857 100644 --- a/test/mitmproxy/test_flow_export/locust_patch.py +++ b/test/mitmproxy/data/test_flow_export/locust_patch.py diff --git a/test/mitmproxy/test_flow_export/locust_post.py b/test/mitmproxy/data/test_flow_export/locust_post.py index df23476a..df23476a 100644 --- a/test/mitmproxy/test_flow_export/locust_post.py +++ b/test/mitmproxy/data/test_flow_export/locust_post.py diff --git a/test/mitmproxy/test_flow_export/locust_task_get.py b/test/mitmproxy/data/test_flow_export/locust_task_get.py index 03821cd8..03821cd8 100644 --- a/test/mitmproxy/test_flow_export/locust_task_get.py +++ b/test/mitmproxy/data/test_flow_export/locust_task_get.py diff --git a/test/mitmproxy/test_flow_export/locust_task_patch.py b/test/mitmproxy/data/test_flow_export/locust_task_patch.py index d425209c..d425209c 100644 --- a/test/mitmproxy/test_flow_export/locust_task_patch.py +++ b/test/mitmproxy/data/test_flow_export/locust_task_patch.py diff --git a/test/mitmproxy/test_flow_export/locust_task_post.py b/test/mitmproxy/data/test_flow_export/locust_task_post.py index 989df455..989df455 100644 --- a/test/mitmproxy/test_flow_export/locust_task_post.py +++ b/test/mitmproxy/data/test_flow_export/locust_task_post.py diff --git a/test/mitmproxy/test_flow_export/python_get.py b/test/mitmproxy/data/test_flow_export/python_get.py index af8f7c81..af8f7c81 100644 --- a/test/mitmproxy/test_flow_export/python_get.py +++ b/test/mitmproxy/data/test_flow_export/python_get.py diff --git a/test/mitmproxy/test_flow_export/python_patch.py b/test/mitmproxy/data/test_flow_export/python_patch.py index 159e802f..159e802f 100644 --- a/test/mitmproxy/test_flow_export/python_patch.py +++ b/test/mitmproxy/data/test_flow_export/python_patch.py diff --git a/test/mitmproxy/test_flow_export/python_post.py b/test/mitmproxy/data/test_flow_export/python_post.py index b13f6441..b13f6441 100644 --- a/test/mitmproxy/test_flow_export/python_post.py +++ b/test/mitmproxy/data/test_flow_export/python_post.py diff --git a/test/mitmproxy/test_flow_export/python_post_json.py b/test/mitmproxy/data/test_flow_export/python_post_json.py index 7e105bf6..6c1b9740 100644 --- a/test/mitmproxy/test_flow_export/python_post_json.py +++ b/test/mitmproxy/data/test_flow_export/python_post_json.py @@ -6,11 +6,13 @@ headers = { 'content-type': 'application/json', } + json = { - "name": "example", - "email": "example@example.com" + u'email': u'example@example.com', + u'name': u'example', } + response = requests.request( method='POST', url=url, diff --git a/test/mitmproxy/script/test_concurrent.py b/test/mitmproxy/script/test_concurrent.py index a9c9e153..c2f169ad 100644 --- a/test/mitmproxy/script/test_concurrent.py +++ b/test/mitmproxy/script/test_concurrent.py @@ -11,7 +11,7 @@ class Dummy: @tutils.skip_appveyor def test_concurrent(): - with Script(tutils.test_data.path("scripts/concurrent_decorator.py"), None) as s: + with Script(tutils.test_data.path("data/scripts/concurrent_decorator.py"), None) as s: def reply(): reply.acked.set() reply.acked = Event() @@ -27,6 +27,6 @@ def test_concurrent(): def test_concurrent_err(): - s = Script(tutils.test_data.path("scripts/concurrent_decorator_err.py"), None) + s = Script(tutils.test_data.path("data/scripts/concurrent_decorator_err.py"), None) with tutils.raises("Concurrent decorator not supported for 'start' method"): s.load() diff --git a/test/mitmproxy/script/test_script.py b/test/mitmproxy/script/test_script.py index a9b55977..fe98fab5 100644 --- a/test/mitmproxy/script/test_script.py +++ b/test/mitmproxy/script/test_script.py @@ -21,19 +21,19 @@ class TestParseCommand: def test_parse_args(self): with tutils.chdir(tutils.test_data.dirname): - assert Script.parse_command("scripts/a.py") == ["scripts/a.py"] - assert Script.parse_command("scripts/a.py foo bar") == ["scripts/a.py", "foo", "bar"] - assert Script.parse_command("scripts/a.py 'foo bar'") == ["scripts/a.py", "foo bar"] + assert Script.parse_command("data/scripts/a.py") == ["data/scripts/a.py"] + assert Script.parse_command("data/scripts/a.py foo bar") == ["data/scripts/a.py", "foo", "bar"] + assert Script.parse_command("data/scripts/a.py 'foo bar'") == ["data/scripts/a.py", "foo bar"] @tutils.skip_not_windows def test_parse_windows(self): with tutils.chdir(tutils.test_data.dirname): - assert Script.parse_command("scripts\\a.py") == ["scripts\\a.py"] - assert Script.parse_command("scripts\\a.py 'foo \\ bar'") == ["scripts\\a.py", 'foo \\ bar'] + assert Script.parse_command("data\\scripts\\a.py") == ["data\\scripts\\a.py"] + assert Script.parse_command("data\\scripts\\a.py 'foo \\ bar'") == ["data\\scripts\\a.py", 'foo \\ bar'] def test_simple(): - with tutils.chdir(tutils.test_data.path("scripts")): + with tutils.chdir(tutils.test_data.path("data/scripts")): s = Script("a.py --var 42", None) assert s.filename == "a.py" assert s.ns is None @@ -55,7 +55,7 @@ def test_simple(): def test_script_exception(): - with tutils.chdir(tutils.test_data.path("scripts")): + with tutils.chdir(tutils.test_data.path("data/scripts")): s = Script("syntaxerr.py", None) with tutils.raises(ScriptException): s.load() diff --git a/test/mitmproxy/test_app.py b/test/mitmproxy/test_app.py index 8d8ce271..4c9eff08 100644 --- a/test/mitmproxy/test_app.py +++ b/test/mitmproxy/test_app.py @@ -1,4 +1,4 @@ -from . import tutils, tservers +from . import tservers class TestApp(tservers.HTTPProxyTest): @@ -7,8 +7,7 @@ class TestApp(tservers.HTTPProxyTest): assert self.app("/").status_code == 200 def test_cert(self): - with tutils.tmpdir() as d: - for ext in ["pem", "p12"]: - resp = self.app("/cert/%s" % ext) - assert resp.status_code == 200 - assert resp.content + for ext in ["pem", "p12"]: + resp = self.app("/cert/%s" % ext) + assert resp.status_code == 200 + assert resp.content diff --git a/test/mitmproxy/test_contentview.py b/test/mitmproxy/test_contentview.py index c00afa5f..9142bdad 100644 --- a/test/mitmproxy/test_contentview.py +++ b/test/mitmproxy/test_contentview.py @@ -1,8 +1,8 @@ from mitmproxy.exceptions import ContentViewException from netlib.http import Headers from netlib.odict import ODict -import netlib.utils from netlib import encoding +from netlib.http import url import mitmproxy.contentviews as cv from . import tutils @@ -60,10 +60,10 @@ class TestContentView: assert f[0] == "Query" def test_view_urlencoded(self): - d = netlib.utils.urlencode([("one", "two"), ("three", "four")]) + d = url.encode([("one", "two"), ("three", "four")]) v = cv.ViewURLEncoded() assert v(d) - d = netlib.utils.urlencode([("adsfa", "")]) + d = url.encode([("adsfa", "")]) v = cv.ViewURLEncoded() assert v(d) diff --git a/test/mitmproxy/test_controller.py b/test/mitmproxy/test_controller.py index f7bf615a..83ad428e 100644 --- a/test/mitmproxy/test_controller.py +++ b/test/mitmproxy/test_controller.py @@ -2,7 +2,7 @@ from threading import Thread, Event from mock import Mock -from mitmproxy.controller import Reply, DummyReply, Channel, ServerThread, ServerMaster, Master +from mitmproxy import controller from six.moves import queue from mitmproxy.exceptions import Kill @@ -10,11 +10,15 @@ from mitmproxy.proxy import DummyServer from netlib.tutils import raises +class TMsg: + pass + + class TestMaster(object): def test_simple(self): - - class DummyMaster(Master): - def handle_panic(self, _): + class DummyMaster(controller.Master): + @controller.handler + def log(self, _): m.should_exit.set() def tick(self, timeout): @@ -23,14 +27,14 @@ class TestMaster(object): m = DummyMaster() assert not m.should_exit.is_set() - m.event_queue.put(("panic", 42)) + msg = TMsg() + msg.reply = controller.DummyReply() + m.event_queue.put(("log", msg)) m.run() assert m.should_exit.is_set() - -class TestServerMaster(object): - def test_simple(self): - m = ServerMaster() + def test_server_simple(self): + m = controller.Master() s = DummyServer(None) m.add_server(s) m.start() @@ -42,7 +46,7 @@ class TestServerMaster(object): class TestServerThread(object): def test_simple(self): m = Mock() - t = ServerThread(m) + t = controller.ServerThread(m) t.run() assert m.serve_forever.called @@ -50,7 +54,7 @@ class TestServerThread(object): class TestChannel(object): def test_tell(self): q = queue.Queue() - channel = Channel(q, Event()) + channel = controller.Channel(q, Event()) m = Mock() channel.tell("test", m) assert q.get() == ("test", m) @@ -66,21 +70,21 @@ class TestChannel(object): Thread(target=reply).start() - channel = Channel(q, Event()) + channel = controller.Channel(q, Event()) assert channel.ask("test", Mock()) == 42 def test_ask_shutdown(self): q = queue.Queue() done = Event() done.set() - channel = Channel(q, done) + channel = controller.Channel(q, done) with raises(Kill): channel.ask("test", Mock()) class TestDummyReply(object): def test_simple(self): - reply = DummyReply() + reply = controller.DummyReply() assert not reply.acked reply() assert reply.acked @@ -88,18 +92,18 @@ class TestDummyReply(object): class TestReply(object): def test_simple(self): - reply = Reply(42) + reply = controller.Reply(42) assert not reply.acked reply("foo") assert reply.acked assert reply.q.get() == "foo" def test_default(self): - reply = Reply(42) + reply = controller.Reply(42) reply() assert reply.q.get() == 42 def test_reply_none(self): - reply = Reply(42) + reply = controller.Reply(42) reply(None) assert reply.q.get() is None diff --git a/test/mitmproxy/test_dump.py b/test/mitmproxy/test_dump.py index ad4cee53..36b78168 100644 --- a/test/mitmproxy/test_dump.py +++ b/test/mitmproxy/test_dump.py @@ -64,14 +64,14 @@ class TestDumpMaster: f = tutils.tflow(req=netlib.tutils.treq(content=content)) l = Log("connect") l.reply = mock.MagicMock() - m.handle_log(l) - m.handle_clientconnect(f.client_conn) - m.handle_serverconnect(f.server_conn) - m.handle_request(f) + m.log(l) + m.clientconnect(f.client_conn) + m.serverconnect(f.server_conn) + m.request(f) if not f.error: f.response = HTTPResponse.wrap(netlib.tutils.tresp(content=content)) - f = m.handle_response(f) - m.handle_clientdisconnect(f.client_conn) + f = m.response(f) + m.clientdisconnect(f.client_conn) return f def _dummy_cycle(self, n, filt, content, **options): @@ -95,8 +95,8 @@ class TestDumpMaster: o = dump.Options(flow_detail=1) m = dump.DumpMaster(None, o, outfile=cs) f = tutils.tflow(err=True) - m.handle_request(f) - assert m.handle_error(f) + m.request(f) + assert m.error(f) assert "error" in cs.getvalue() def test_missing_content(self): @@ -105,10 +105,10 @@ class TestDumpMaster: m = dump.DumpMaster(None, o, outfile=cs) f = tutils.tflow() f.request.content = None - m.handle_request(f) + m.request(f) f.response = HTTPResponse.wrap(netlib.tutils.tresp()) f.response.content = None - m.handle_response(f) + m.response(f) assert "content missing" in cs.getvalue() def test_replay(self): @@ -160,7 +160,7 @@ class TestDumpMaster: assert o.verbosity == 2 def test_filter(self): - assert not "GET" in self._dummy_cycle(1, "~u foo", "", verbosity=1) + assert "GET" not in self._dummy_cycle(1, "~u foo", "", verbosity=1) def test_app(self): o = dump.Options(app=True) @@ -218,7 +218,7 @@ class TestDumpMaster: def test_script(self): ret = self._dummy_cycle( 1, None, "", - scripts=[tutils.test_data.path("scripts/all.py")], verbosity=1 + scripts=[tutils.test_data.path("data/scripts/all.py")], verbosity=1 ) assert "XCLIENTCONNECT" in ret assert "XSERVERCONNECT" in ret diff --git a/test/mitmproxy/test_examples.py b/test/mitmproxy/test_examples.py index c4b06f4b..607d6faf 100644 --- a/test/mitmproxy/test_examples.py +++ b/test/mitmproxy/test_examples.py @@ -3,7 +3,7 @@ import json import os from contextlib import contextmanager -from mitmproxy import utils, script +from mitmproxy import script from mitmproxy.proxy import config import netlib.utils from netlib import tutils as netutils diff --git a/test/mitmproxy/test_flow.py b/test/mitmproxy/test_flow.py index 3e78a5c4..1b1f03f9 100644 --- a/test/mitmproxy/test_flow.py +++ b/test/mitmproxy/test_flow.py @@ -4,7 +4,6 @@ from six.moves import cStringIO as StringIO import mock import netlib.utils -from netlib import odict from netlib.http import Headers from mitmproxy import filt, controller, tnetstring, flow from mitmproxy.exceptions import FlowReadException, ScriptException @@ -54,8 +53,8 @@ class TestStickyCookieState: assert s.domain_match("www.google.com", ".google.com") assert s.domain_match("google.com", ".google.com") - def test_handle_response(self): - c = "SSID=mooo; domain=.google.com, FOO=bar; Domain=.google.com; Path=/; "\ + def test_response(self): + c = "SSID=mooo; domain=.google.com, FOO=bar; Domain=.google.com; Path=/; " \ "Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; " s, f = self._response(c, "host") @@ -101,7 +100,7 @@ class TestStickyCookieState: assert len(s.jar[googlekey].keys()) == 1 assert s.jar[googlekey]["somecookie"].items()[0][1] == "newvalue" - def test_handle_request(self): + def test_request(self): s, f = self._response("SSID=mooo", "www.google.com") assert "cookie" not in f.request.headers s.handle_request(f) @@ -110,7 +109,7 @@ class TestStickyCookieState: class TestStickyAuthState: - def test_handle_response(self): + def test_response(self): s = flow.StickyAuthState(filt.parse(".*")) f = tutils.tflow(resp=True) f.request.headers["authorization"] = "foo" @@ -389,22 +388,22 @@ class TestFlow(object): del b["id"] assert a == b assert not f == f2 - assert not f is f2 + assert f is not f2 assert f.request.get_state() == f2.request.get_state() - assert not f.request is f2.request + assert f.request is not f2.request assert f.request.headers == f2.request.headers - assert not f.request.headers is f2.request.headers + assert f.request.headers is not f2.request.headers assert f.response.get_state() == f2.response.get_state() - assert not f.response is f2.response + assert f.response is not f2.response f = tutils.tflow(err=True) f2 = f.copy() - assert not f is f2 - assert not f.request is f2.request + assert f is not f2 + assert f.request is not f2.request assert f.request.headers == f2.request.headers - assert not f.request.headers is f2.request.headers + assert f.request.headers is not f2.request.headers assert f.error.get_state() == f2.error.get_state() - assert not f.error is f2.error + assert f.error is not f2.error def test_match(self): f = tutils.tflow(resp=True) @@ -461,25 +460,20 @@ class TestFlow(object): fm = flow.FlowMaster(None, s) f = tutils.tflow() f.intercept(mock.Mock()) - assert not f.reply.acked f.kill(fm) - assert f.reply.acked + for i in s.view: + assert "killed" in str(i.error) def test_killall(self): s = flow.State() fm = flow.FlowMaster(None, s) f = tutils.tflow() - fm.handle_request(f) - - f = tutils.tflow() - fm.handle_request(f) + f.intercept(fm) - for i in s.view: - assert not i.reply.acked s.killall(fm) for i in s.view: - assert i.reply.acked + assert "killed" in str(i.error) def test_accept_intercept(self): f = tutils.tflow() @@ -767,13 +761,13 @@ class TestFlowMaster: s = flow.State() fm = flow.FlowMaster(None, s) - fm.load_script(tutils.test_data.path("scripts/a.py")) - fm.load_script(tutils.test_data.path("scripts/a.py")) + fm.load_script(tutils.test_data.path("data/scripts/a.py")) + fm.load_script(tutils.test_data.path("data/scripts/a.py")) fm.unload_scripts() with tutils.raises(ScriptException): fm.load_script("nonexistent") try: - fm.load_script(tutils.test_data.path("scripts/starterr.py")) + fm.load_script(tutils.test_data.path("data/scripts/starterr.py")) except ScriptException as e: assert "ValueError" in str(e) assert len(fm.scripts) == 0 @@ -802,39 +796,39 @@ class TestFlowMaster: def test_script_reqerr(self): s = flow.State() fm = flow.FlowMaster(None, s) - fm.load_script(tutils.test_data.path("scripts/reqerr.py")) + fm.load_script(tutils.test_data.path("data/scripts/reqerr.py")) f = tutils.tflow() - fm.handle_clientconnect(f.client_conn) - assert fm.handle_request(f) + fm.clientconnect(f.client_conn) + assert fm.request(f) def test_script(self): s = flow.State() fm = flow.FlowMaster(None, s) - fm.load_script(tutils.test_data.path("scripts/all.py")) + fm.load_script(tutils.test_data.path("data/scripts/all.py")) f = tutils.tflow(resp=True) - fm.handle_clientconnect(f.client_conn) + fm.clientconnect(f.client_conn) assert fm.scripts[0].ns["log"][-1] == "clientconnect" - fm.handle_serverconnect(f.server_conn) + fm.serverconnect(f.server_conn) assert fm.scripts[0].ns["log"][-1] == "serverconnect" - fm.handle_request(f) + fm.request(f) assert fm.scripts[0].ns["log"][-1] == "request" - fm.handle_response(f) + fm.response(f) assert fm.scripts[0].ns["log"][-1] == "response" # load second script - fm.load_script(tutils.test_data.path("scripts/all.py")) + fm.load_script(tutils.test_data.path("data/scripts/all.py")) assert len(fm.scripts) == 2 - fm.handle_clientdisconnect(f.server_conn) + fm.clientdisconnect(f.server_conn) assert fm.scripts[0].ns["log"][-1] == "clientdisconnect" assert fm.scripts[1].ns["log"][-1] == "clientdisconnect" # unload first script fm.unload_scripts() assert len(fm.scripts) == 0 - fm.load_script(tutils.test_data.path("scripts/all.py")) + fm.load_script(tutils.test_data.path("data/scripts/all.py")) f.error = tutils.terr() - fm.handle_error(f) + fm.error(f) assert fm.scripts[0].ns["log"][-1] == "error" def test_duplicate_flow(self): @@ -859,23 +853,22 @@ class TestFlowMaster: fm.anticache = True fm.anticomp = True f = tutils.tflow(req=None) - fm.handle_clientconnect(f.client_conn) + fm.clientconnect(f.client_conn) f.request = HTTPRequest.wrap(netlib.tutils.treq()) - fm.handle_request(f) + fm.request(f) assert s.flow_count() == 1 f.response = HTTPResponse.wrap(netlib.tutils.tresp()) - fm.handle_response(f) - assert not fm.handle_response(None) + fm.response(f) assert s.flow_count() == 1 - fm.handle_clientdisconnect(f.client_conn) + fm.clientdisconnect(f.client_conn) f.error = Error("msg") f.error.reply = controller.DummyReply() - fm.handle_error(f) + fm.error(f) - fm.load_script(tutils.test_data.path("scripts/a.py")) + fm.load_script(tutils.test_data.path("data/scripts/a.py")) fm.shutdown() def test_client_playback(self): @@ -902,7 +895,7 @@ class TestFlowMaster: assert fm.state.flow_count() f.error = Error("error") - fm.handle_error(f) + fm.error(f) def test_server_playback(self): s = flow.State() @@ -983,12 +976,12 @@ class TestFlowMaster: fm.set_stickycookie(".*") f = tutils.tflow(resp=True) f.response.headers["set-cookie"] = "foo=bar" - fm.handle_request(f) - fm.handle_response(f) + fm.request(f) + fm.response(f) assert fm.stickycookie_state.jar - assert not "cookie" in f.request.headers + assert "cookie" not in f.request.headers f = f.copy() - fm.handle_request(f) + fm.request(f) assert f.request.headers["cookie"] == "foo=bar" def test_stickyauth(self): @@ -1003,12 +996,12 @@ class TestFlowMaster: fm.set_stickyauth(".*") f = tutils.tflow(resp=True) f.request.headers["authorization"] = "foo" - fm.handle_request(f) + fm.request(f) f = tutils.tflow(resp=True) assert fm.stickyauth_state.hosts - assert not "authorization" in f.request.headers - fm.handle_request(f) + assert "authorization" not in f.request.headers + fm.request(f) assert f.request.headers["authorization"] == "foo" def test_stream(self): @@ -1024,15 +1017,15 @@ class TestFlowMaster: f = tutils.tflow(resp=True) fm.start_stream(file(p, "ab"), None) - fm.handle_request(f) - fm.handle_response(f) + fm.request(f) + fm.response(f) fm.stop_stream() assert r()[0].response f = tutils.tflow() fm.start_stream(file(p, "ab"), None) - fm.handle_request(f) + fm.request(f) fm.shutdown() assert not r()[1].response @@ -1077,8 +1070,8 @@ class TestRequest: r.headers["if-modified-since"] = "test" r.headers["if-none-match"] = "test" r.anticache() - assert not "if-modified-since" in r.headers - assert not "if-none-match" in r.headers + assert "if-modified-since" not in r.headers + assert "if-none-match" not in r.headers def test_replace(self): r = HTTPRequest.wrap(netlib.tutils.treq()) @@ -1087,7 +1080,7 @@ class TestRequest: r.content = "afoob" assert r.replace("foo(?i)", "boo") == 4 assert r.path == "path/boo" - assert not "foo" in r.content + assert "foo" not in r.content assert r.headers["boo"] == "boo" def test_constrain_encoding(self): @@ -1129,7 +1122,7 @@ class TestResponse: r.headers["Foo"] = "fOo" r.content = "afoob" assert r.replace("foo(?i)", "boo") == 3 - assert not "foo" in r.content + assert "foo" not in r.content assert r.headers["boo"] == "boo" def test_get_content_type(self): @@ -1161,11 +1154,9 @@ class TestError: class TestClientConnection: - def test_state(self): - c = tutils.tclient_conn() - assert ClientConnection.from_state(c.get_state()).get_state() ==\ + assert ClientConnection.from_state(c.get_state()).get_state() == \ c.get_state() c2 = tutils.tclient_conn() diff --git a/test/mitmproxy/test_flow_export.py b/test/mitmproxy/test_flow_export.py index c252c5bd..9a263b1b 100644 --- a/test/mitmproxy/test_flow_export.py +++ b/test/mitmproxy/test_flow_export.py @@ -1,10 +1,9 @@ -import json from textwrap import dedent import re import netlib.tutils from netlib.http import Headers -from mitmproxy import flow_export +from mitmproxy.flow import export # heh from . import tutils @@ -21,49 +20,54 @@ def python_equals(testdata, text): assert clean_blanks(text).rstrip() == clean_blanks(d).rstrip() -req_get = lambda: netlib.tutils.treq(method='GET', content='', path=b"/path?a=foo&a=bar&b=baz") +def req_get(): + return netlib.tutils.treq(method='GET', content='', path=b"/path?a=foo&a=bar&b=baz") -req_post = lambda: netlib.tutils.treq(method='POST', headers=None) -req_patch = lambda: netlib.tutils.treq(method='PATCH', path=b"/path?query=param") +def req_post(): + return netlib.tutils.treq(method='POST', headers=()) + + +def req_patch(): + return netlib.tutils.treq(method='PATCH', path=b"/path?query=param") class TestExportCurlCommand(): def test_get(self): flow = tutils.tflow(req=req_get()) result = """curl -H 'header:qvalue' -H 'content-length:7' 'http://address/path?a=foo&a=bar&b=baz'""" - assert flow_export.curl_command(flow) == result + assert export.curl_command(flow) == result def test_post(self): flow = tutils.tflow(req=req_post()) result = """curl -X POST 'http://address/path' --data-binary 'content'""" - assert flow_export.curl_command(flow) == result + assert export.curl_command(flow) == result def test_patch(self): flow = tutils.tflow(req=req_patch()) result = """curl -H 'header:qvalue' -H 'content-length:7' -X PATCH 'http://address/path?query=param' --data-binary 'content'""" - assert flow_export.curl_command(flow) == result + assert export.curl_command(flow) == result class TestExportPythonCode(): def test_get(self): flow = tutils.tflow(req=req_get()) - python_equals("test_flow_export/python_get.py", flow_export.python_code(flow)) + python_equals("data/test_flow_export/python_get.py", export.python_code(flow)) def test_post(self): flow = tutils.tflow(req=req_post()) - python_equals("test_flow_export/python_post.py", flow_export.python_code(flow)) + python_equals("data/test_flow_export/python_post.py", export.python_code(flow)) def test_post_json(self): p = req_post() p.content = '{"name": "example", "email": "example@example.com"}' p.headers = Headers(content_type="application/json") flow = tutils.tflow(req=p) - python_equals("test_flow_export/python_post_json.py", flow_export.python_code(flow)) + python_equals("data/test_flow_export/python_post_json.py", export.python_code(flow)) def test_patch(self): flow = tutils.tflow(req=req_patch()) - python_equals("test_flow_export/python_patch.py", flow_export.python_code(flow)) + python_equals("data/test_flow_export/python_patch.py", export.python_code(flow)) class TestRawRequest(): @@ -76,7 +80,7 @@ class TestRawRequest(): host: address:22\r \r """).strip(" ").lstrip() - assert flow_export.raw_request(flow) == result + assert export.raw_request(flow) == result def test_post(self): flow = tutils.tflow(req=req_post()) @@ -86,7 +90,7 @@ class TestRawRequest(): \r content """).strip() - assert flow_export.raw_request(flow) == result + assert export.raw_request(flow) == result def test_patch(self): flow = tutils.tflow(req=req_patch()) @@ -98,54 +102,54 @@ class TestRawRequest(): \r content """).strip() - assert flow_export.raw_request(flow) == result + assert export.raw_request(flow) == result class TestExportLocustCode(): def test_get(self): flow = tutils.tflow(req=req_get()) - python_equals("test_flow_export/locust_get.py", flow_export.locust_code(flow)) + python_equals("data/test_flow_export/locust_get.py", export.locust_code(flow)) def test_post(self): p = req_post() p.content = '''content''' p.headers = '' flow = tutils.tflow(req=p) - python_equals("test_flow_export/locust_post.py", flow_export.locust_code(flow)) + python_equals("data/test_flow_export/locust_post.py", export.locust_code(flow)) def test_patch(self): flow = tutils.tflow(req=req_patch()) - python_equals("test_flow_export/locust_patch.py", flow_export.locust_code(flow)) + python_equals("data/test_flow_export/locust_patch.py", export.locust_code(flow)) class TestExportLocustTask(): def test_get(self): flow = tutils.tflow(req=req_get()) - python_equals("test_flow_export/locust_task_get.py", flow_export.locust_task(flow)) + python_equals("data/test_flow_export/locust_task_get.py", export.locust_task(flow)) def test_post(self): flow = tutils.tflow(req=req_post()) - python_equals("test_flow_export/locust_task_post.py", flow_export.locust_task(flow)) + python_equals("data/test_flow_export/locust_task_post.py", export.locust_task(flow)) def test_patch(self): flow = tutils.tflow(req=req_patch()) - python_equals("test_flow_export/locust_task_patch.py", flow_export.locust_task(flow)) + python_equals("data/test_flow_export/locust_task_patch.py", export.locust_task(flow)) class TestIsJson(): def test_empty(self): - assert flow_export.is_json(None, None) is False + assert export.is_json(None, None) is False def test_json_type(self): headers = Headers(content_type="application/json") - assert flow_export.is_json(headers, "foobar") is False + assert export.is_json(headers, "foobar") is False def test_valid(self): headers = Headers(content_type="application/foobar") - j = flow_export.is_json(headers, '{"name": "example", "email": "example@example.com"}') + j = export.is_json(headers, '{"name": "example", "email": "example@example.com"}') assert j is False - def test_valid(self): + def test_valid2(self): headers = Headers(content_type="application/json") - j = flow_export.is_json(headers, '{"name": "example", "email": "example@example.com"}') + j = export.is_json(headers, '{"name": "example", "email": "example@example.com"}') assert isinstance(j, dict) diff --git a/test/mitmproxy/test_flow_format_compat.py b/test/mitmproxy/test_flow_format_compat.py index 2c477cc2..b2cef88d 100644 --- a/test/mitmproxy/test_flow_format_compat.py +++ b/test/mitmproxy/test_flow_format_compat.py @@ -1,4 +1,5 @@ -from mitmproxy.flow import FlowReader, FlowReadException +from mitmproxy.flow import FlowReader +from mitmproxy.exceptions import FlowReadException from . import tutils diff --git a/test/mitmproxy/test_protocol_http2.py b/test/mitmproxy/test_protocol_http2.py index c3950975..23072260 100644 --- a/test/mitmproxy/test_protocol_http2.py +++ b/test/mitmproxy/test_protocol_http2.py @@ -2,15 +2,21 @@ from __future__ import (absolute_import, print_function, division) -import OpenSSL import pytest import traceback import os import tempfile +import h2 from mitmproxy.proxy.config import ProxyConfig from mitmproxy.cmdline import APP_HOST, APP_PORT +import netlib +from ..netlib import tservers as netlib_tservers +from netlib.http.http2 import framereader + +from . import tservers + import logging logging.getLogger("hyper.packages.hpack.hpack").setLevel(logging.WARNING) logging.getLogger("requests.packages.urllib3.connectionpool").setLevel(logging.WARNING) @@ -19,13 +25,6 @@ logging.getLogger("passlib.registry").setLevel(logging.WARNING) logging.getLogger("PIL.Image").setLevel(logging.WARNING) logging.getLogger("PIL.PngImagePlugin").setLevel(logging.WARNING) -import netlib -from ..netlib import tservers as netlib_tservers -from netlib.utils import http2_read_raw_frame - -import h2 - -from . import tservers requires_alpn = pytest.mark.skipif( not netlib.tcp.HAS_ALPN, @@ -49,7 +48,7 @@ class _Http2ServerBase(netlib_tservers.ServerTestBase): done = False while not done: try: - raw = b''.join(http2_read_raw_frame(self.rfile)) + raw = b''.join(framereader.http2_read_raw_frame(self.rfile)) events = h2_conn.receive_data(raw) except: break @@ -165,12 +164,21 @@ class TestSimple(_Http2TestBase, _Http2ServerBase): assert ('client-foo', 'client-bar-1') in event.headers assert ('client-foo', 'client-bar-2') in event.headers - h2_conn.send_headers(event.stream_id, [ - (':status', '200'), - ('server-foo', 'server-bar'), - ('föo', 'bär'), - ('X-Stream-ID', str(event.stream_id)), - ]) + import warnings + with warnings.catch_warnings(): + # Ignore UnicodeWarning: + # h2/utilities.py:64: UnicodeWarning: Unicode equal comparison + # failed to convert both arguments to Unicode - interpreting + # them as being unequal. + # elif header[0] in (b'cookie', u'cookie') and len(header[1]) < 20: + + warnings.simplefilter("ignore") + h2_conn.send_headers(event.stream_id, [ + (':status', '200'), + ('server-foo', 'server-bar'), + ('föo', 'bär'), + ('X-Stream-ID', str(event.stream_id)), + ]) h2_conn.send_data(event.stream_id, b'foobar') h2_conn.end_stream(event.stream_id) wfile.write(h2_conn.data_to_send()) @@ -192,7 +200,7 @@ class TestSimple(_Http2TestBase, _Http2ServerBase): done = False while not done: try: - events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile))) + events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) @@ -262,7 +270,7 @@ class TestWithBodies(_Http2TestBase, _Http2ServerBase): done = False while not done: try: - events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile))) + events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) @@ -354,7 +362,7 @@ class TestPushPromise(_Http2TestBase, _Http2ServerBase): responses = 0 while not done: try: - raw = b''.join(http2_read_raw_frame(client.rfile)) + raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except: break @@ -404,7 +412,7 @@ class TestPushPromise(_Http2TestBase, _Http2ServerBase): responses = 0 while not done: try: - events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile))) + events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) @@ -435,6 +443,7 @@ class TestPushPromise(_Http2TestBase, _Http2ServerBase): assert b'regular_stream' in bodies # the other two bodies might not be transmitted before the reset + @requires_alpn class TestConnectionLost(_Http2TestBase, _Http2ServerBase): @@ -468,17 +477,17 @@ class TestConnectionLost(_Http2TestBase, _Http2ServerBase): ]) done = False - ended_streams = 0 - pushed_streams = 0 - responses = 0 while not done: try: - raw = b''.join(http2_read_raw_frame(client.rfile)) - events = h2_conn.receive_data(raw) + raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) + h2_conn.receive_data(raw) + except: + break + try: + client.wfile.write(h2_conn.data_to_send()) + client.wfile.flush() except: break - client.wfile.write(h2_conn.data_to_send()) - client.wfile.flush() if len(self.master.state.flows) == 1: assert self.master.state.flows[0].response is None diff --git a/test/mitmproxy/test_proxy.py b/test/mitmproxy/test_proxy.py index e0897135..49c9c909 100644 --- a/test/mitmproxy/test_proxy.py +++ b/test/mitmproxy/test_proxy.py @@ -113,11 +113,10 @@ class TestProcessProxyOptions: "nonexistent") def test_certs(self): - with tutils.tmpdir() as cadir: - self.assert_noerr( - "--cert", - tutils.test_data.path("data/testkey.pem")) - self.assert_err("does not exist", "--cert", "nonexistent") + self.assert_noerr( + "--cert", + tutils.test_data.path("data/testkey.pem")) + self.assert_err("does not exist", "--cert", "nonexistent") def test_auth(self): p = self.assert_noerr("--nonanonymous") diff --git a/test/mitmproxy/test_script.py b/test/mitmproxy/test_script.py index f321d15c..81994780 100644 --- a/test/mitmproxy/test_script.py +++ b/test/mitmproxy/test_script.py @@ -5,9 +5,9 @@ from . import tutils def test_duplicate_flow(): s = flow.State() fm = flow.FlowMaster(None, s) - fm.load_script(tutils.test_data.path("scripts/duplicate_flow.py")) + fm.load_script(tutils.test_data.path("data/scripts/duplicate_flow.py")) f = tutils.tflow() - fm.handle_request(f) + fm.request(f) assert fm.state.flow_count() == 2 assert not fm.state.view[0].request.is_replay assert fm.state.view[1].request.is_replay diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py index 0701d52b..b58c4f44 100644 --- a/test/mitmproxy/test_server.py +++ b/test/mitmproxy/test_server.py @@ -12,6 +12,7 @@ from netlib.http import authentication, http1 from netlib.tutils import raises from pathod import pathoc, pathod +from mitmproxy import controller from mitmproxy.proxy.config import HostMatcher from mitmproxy.exceptions import Kill from mitmproxy.models import Error, HTTPResponse, HTTPFlow @@ -190,8 +191,8 @@ class TcpMixin: assert i_cert == i2_cert == n_cert # Make sure that TCP messages are in the event log. - assert any("305" in m for m in self.master.log) - assert any("306" in m for m in self.master.log) + assert any("305" in m for m in self.master.tlog) + assert any("306" in m for m in self.master.tlog) class AppMixin: @@ -260,7 +261,7 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin, AppMixin): p = self.pathoc() assert p.request(req % self.server.urlbase) assert p.request(req % self.server2.urlbase) - assert switched(self.proxy.log) + assert switched(self.proxy.tlog) def test_blank_leading_line(self): p = self.pathoc() @@ -285,7 +286,7 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin, AppMixin): self.master.set_stream_large_bodies(None) def test_stream_modify(self): - self.master.load_script(tutils.test_data.path("scripts/stream_modify.py")) + self.master.load_script(tutils.test_data.path("data/scripts/stream_modify.py")) d = self.pathod('200:b"foo"') assert d.content == "bar" self.master.unload_scripts() @@ -499,7 +500,7 @@ class TestHttps2Http(tservers.ReverseProxyTest): def test_sni(self): p = self.pathoc(ssl=True, sni="example.com") assert p.request("get:'/p/200'").status_code == 200 - assert all("Error in handle_sni" not in msg for msg in self.proxy.log) + assert all("Error in handle_sni" not in msg for msg in self.proxy.tlog) def test_http(self): p = self.pathoc(ssl=False) @@ -510,7 +511,7 @@ class TestTransparent(tservers.TransparentProxyTest, CommonMixin, TcpMixin): ssl = False def test_tcp_stream_modify(self): - self.master.load_script(tutils.test_data.path("scripts/tcp_stream_modify.py")) + self.master.load_script(tutils.test_data.path("data/scripts/tcp_stream_modify.py")) self._tcpproxy_on() d = self.pathod('200:b"foo"') @@ -623,7 +624,8 @@ class TestProxySSL(tservers.HTTPProxyTest): class MasterRedirectRequest(tservers.TestMaster): redirect_port = None # Set by TestRedirectRequest - def handle_request(self, f): + @controller.handler + def request(self, f): if f.request.path == "/p/201": # This part should have no impact, but it should also not cause any exceptions. @@ -634,12 +636,13 @@ class MasterRedirectRequest(tservers.TestMaster): # This is the actual redirection. f.request.port = self.redirect_port - super(MasterRedirectRequest, self).handle_request(f) + super(MasterRedirectRequest, self).request(f) - def handle_response(self, f): + @controller.handler + def response(self, f): f.response.content = str(f.client_conn.address.port) f.response.headers["server-conn-id"] = str(f.server_conn.source_address.port) - super(MasterRedirectRequest, self).handle_response(f) + super(MasterRedirectRequest, self).response(f) class TestRedirectRequest(tservers.HTTPProxyTest): @@ -689,10 +692,9 @@ class MasterStreamRequest(tservers.TestMaster): """ Enables the stream flag on the flow for all requests """ - - def handle_responseheaders(self, f): + @controller.handler + def responseheaders(self, f): f.response.stream = True - f.reply() class TestStreamRequest(tservers.HTTPProxyTest): @@ -739,8 +741,8 @@ class TestStreamRequest(tservers.HTTPProxyTest): class MasterFakeResponse(tservers.TestMaster): - - def handle_request(self, f): + @controller.handler + def request(self, f): resp = HTTPResponse.wrap(netlib.tutils.tresp()) f.reply(resp) @@ -761,13 +763,14 @@ class TestServerConnect(tservers.HTTPProxyTest): def test_unnecessary_serverconnect(self): """A replayed/fake response with no_upstream_cert should not connect to an upstream server""" assert self.pathod("200").status_code == 200 - for msg in self.proxy.tmaster.log: + for msg in self.proxy.tmaster.tlog: assert "serverconnect" not in msg class MasterKillRequest(tservers.TestMaster): - def handle_request(self, f): + @controller.handler + def request(self, f): f.reply(Kill) @@ -783,7 +786,8 @@ class TestKillRequest(tservers.HTTPProxyTest): class MasterKillResponse(tservers.TestMaster): - def handle_response(self, f): + @controller.handler + def response(self, f): f.reply(Kill) @@ -812,7 +816,8 @@ class TestTransparentResolveError(tservers.TransparentProxyTest): class MasterIncomplete(tservers.TestMaster): - def handle_request(self, f): + @controller.handler + def request(self, f): resp = HTTPResponse.wrap(netlib.tutils.tresp()) resp.content = None f.reply(resp) @@ -930,7 +935,9 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest): k = [0] # variable scope workaround: put into array _func = getattr(master, attr) - def handler(f): + @controller.handler + def handler(*args): + f = args[-1] k[0] += 1 if not (k[0] in exclude): f.client_conn.finish() @@ -940,13 +947,16 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest): setattr(master, attr, handler) - kill_requests(self.chain[1].tmaster, "handle_request", - exclude=[ - # fail first request - 2, # allow second request - ]) + kill_requests( + self.chain[1].tmaster, + "request", + exclude = [ + # fail first request + 2, # allow second request + ] + ) - kill_requests(self.chain[0].tmaster, "handle_request", + kill_requests(self.chain[0].tmaster, "request", exclude=[ 1, # CONNECT # fail first request @@ -1004,10 +1014,10 @@ class AddUpstreamCertsToClientChainMixin: ssl = True servercert = tutils.test_data.path("data/trusted-server.crt") ssloptions = pathod.SSLOptions( - cn="trusted-cert", - certs=[ - ("trusted-cert", servercert) - ] + cn="trusted-cert", + certs=[ + ("trusted-cert", servercert) + ] ) def test_add_upstream_certs_to_client_chain(self): diff --git a/test/mitmproxy/test_utils.py b/test/mitmproxy/test_utils.py index db7dec4a..c01b5f2a 100644 --- a/test/mitmproxy/test_utils.py +++ b/test/mitmproxy/test_utils.py @@ -13,25 +13,6 @@ def test_format_timestamp_with_milli(): assert utils.format_timestamp_with_milli(utils.timestamp()) -def test_isBin(): - assert not utils.isBin("testing\n\r") - assert utils.isBin("testing\x01") - assert utils.isBin("testing\x0e") - assert utils.isBin("testing\x7f") - - -def test_isXml(): - assert not utils.isXML("foo") - assert utils.isXML("<foo") - assert utils.isXML(" \n<foo") - - -def test_clean_hanging_newline(): - s = "foo\n" - assert utils.clean_hanging_newline(s) == "foo" - assert utils.clean_hanging_newline("foo") == "foo" - - def test_pkg_data(): assert utils.pkg_data.path("console") tutils.raises("does not exist", utils.pkg_data.path, "nonexistent") @@ -43,21 +24,6 @@ def test_pretty_json(): assert not utils.pretty_json("moo") -def test_pretty_duration(): - assert utils.pretty_duration(0.00001) == "0ms" - assert utils.pretty_duration(0.0001) == "0ms" - assert utils.pretty_duration(0.001) == "1ms" - assert utils.pretty_duration(0.01) == "10ms" - assert utils.pretty_duration(0.1) == "100ms" - assert utils.pretty_duration(1) == "1.00s" - assert utils.pretty_duration(10) == "10.0s" - assert utils.pretty_duration(100) == "100s" - assert utils.pretty_duration(1000) == "1000s" - assert utils.pretty_duration(10000) == "10000s" - assert utils.pretty_duration(1.123) == "1.12s" - assert utils.pretty_duration(0.123) == "123ms" - - def test_LRUCache(): cache = utils.LRUCache(2) @@ -89,13 +55,3 @@ def test_LRUCache(): assert len(cache.cacheList) == 2 assert len(cache.cache) == 2 - - -def test_parse_size(): - assert not utils.parse_size("") - assert utils.parse_size("1") == 1 - assert utils.parse_size("1k") == 1024 - assert utils.parse_size("1m") == 1024**2 - assert utils.parse_size("1g") == 1024**3 - tutils.raises(ValueError, utils.parse_size, "1f") - tutils.raises(ValueError, utils.parse_size, "ak") diff --git a/test/mitmproxy/tools/memoryleak.py b/test/mitmproxy/tools/memoryleak.py index 259309a6..c03230da 100644 --- a/test/mitmproxy/tools/memoryleak.py +++ b/test/mitmproxy/tools/memoryleak.py @@ -3,8 +3,8 @@ import threading from pympler import muppy, refbrowser from OpenSSL import SSL # import os -#os.environ["TK_LIBRARY"] = r"C:\Python27\tcl\tcl8.5" -#os.environ["TCL_LIBRARY"] = r"C:\Python27\tcl\tcl8.5" +# os.environ["TK_LIBRARY"] = r"C:\Python27\tcl\tcl8.5" +# os.environ["TCL_LIBRARY"] = r"C:\Python27\tcl\tcl8.5" # Also noteworthy: guppy, objgraph diff --git a/test/mitmproxy/tservers.py b/test/mitmproxy/tservers.py index c9d68cfd..24ebb476 100644 --- a/test/mitmproxy/tservers.py +++ b/test/mitmproxy/tservers.py @@ -39,19 +39,11 @@ class TestMaster(flow.FlowMaster): self.apps.add(errapp, "errapp", 80) self.clear_log() - def handle_request(self, f): - flow.FlowMaster.handle_request(self, f) - f.reply() - - def handle_response(self, f): - flow.FlowMaster.handle_response(self, f) - f.reply() - def clear_log(self): - self.log = [] + self.tlog = [] def add_event(self, message, level=None): - self.log.append(message) + self.tlog.append(message) class ProxyThread(threading.Thread): @@ -68,8 +60,8 @@ class ProxyThread(threading.Thread): return self.tmaster.server.address.port @property - def log(self): - return self.tmaster.log + def tlog(self): + return self.tmaster.tlog def run(self): self.tmaster.run() diff --git a/test/mitmproxy/tutils.py b/test/mitmproxy/tutils.py index 118f849c..d0a09035 100644 --- a/test/mitmproxy/tutils.py +++ b/test/mitmproxy/tutils.py @@ -12,7 +12,7 @@ from unittest.case import SkipTest import netlib.utils import netlib.tutils -from mitmproxy import utils, controller +from mitmproxy import controller from mitmproxy.models import ( ClientConnection, ServerConnection, Error, HTTPRequest, HTTPResponse, HTTPFlow, TCPFlow ) @@ -156,6 +156,7 @@ def chdir(dir): yield os.chdir(orig_dir) + @contextmanager def tmpdir(*args, **kwargs): temp_workdir = tempfile.mkdtemp(*args, **kwargs) diff --git a/test/netlib/data/verificationcerts/generate.py b/test/netlib/data/verificationcerts/generate.py index 9203abbb..6d4d8550 100644 --- a/test/netlib/data/verificationcerts/generate.py +++ b/test/netlib/data/verificationcerts/generate.py @@ -64,5 +64,3 @@ do("openssl req -x509 -new -nodes -batch " "-days 1024 " "-out self-signed.crt".format(SUBJECT) ) - - diff --git a/test/netlib/http/http1/test_assemble.py b/test/netlib/http/http1/test_assemble.py index 8dcbae8e..50d29384 100644 --- a/test/netlib/http/http1/test_assemble.py +++ b/test/netlib/http/http1/test_assemble.py @@ -10,11 +10,11 @@ from netlib.tutils import treq, raises, tresp def test_assemble_request(): - c = assemble_request(treq()) == ( + assert assemble_request(treq()) == ( b"GET /path HTTP/1.1\r\n" b"header: qvalue\r\n" - b"Host: address:22\r\n" - b"Content-Length: 7\r\n" + b"content-length: 7\r\n" + b"host: address:22\r\n" b"\r\n" b"content" ) @@ -32,10 +32,10 @@ def test_assemble_request_head(): def test_assemble_response(): - c = assemble_response(tresp()) == ( + assert assemble_response(tresp()) == ( b"HTTP/1.1 200 OK\r\n" b"header-response: svalue\r\n" - b"Content-Length: 7\r\n" + b"content-length: 7\r\n" b"\r\n" b"message" ) diff --git a/test/netlib/http/http1/test_read.py b/test/netlib/http/http1/test_read.py index d8106904..5285ac1d 100644 --- a/test/netlib/http/http1/test_read.py +++ b/test/netlib/http/http1/test_read.py @@ -1,6 +1,5 @@ from __future__ import absolute_import, print_function, division from io import BytesIO -import textwrap from mock import Mock from netlib.exceptions import HttpException, HttpSyntaxException, HttpReadDisconnect, TcpDisconnect from netlib.http import Headers @@ -8,11 +7,22 @@ from netlib.http.http1.read import ( read_request, read_response, read_request_head, read_response_head, read_body, connection_close, expected_http_body_size, _get_first_line, _read_request_line, _parse_authority_form, _read_response_line, _check_http_version, - _read_headers, _read_chunked + _read_headers, _read_chunked, get_header_tokens ) from netlib.tutils import treq, tresp, raises +def test_get_header_tokens(): + headers = Headers() + assert get_header_tokens(headers, "foo") == [] + headers["foo"] = "bar" + assert get_header_tokens(headers, "foo") == ["bar"] + headers["foo"] = "bar, voing" + assert get_header_tokens(headers, "foo") == ["bar", "voing"] + headers.set_all("foo", ["bar, voing", "oink"]) + assert get_header_tokens(headers, "foo") == ["bar", "voing", "oink"] + + def test_read_request(): rfile = BytesIO(b"GET / HTTP/1.1\r\n\r\nskip") r = read_request(rfile) @@ -106,6 +116,7 @@ class TestReadBody(object): rfile = BytesIO(b"123456") assert list(read_body(rfile, -1, max_chunk_size=1)) == [b"1", b"2", b"3", b"4", b"5", b"6"] + def test_connection_close(): headers = Headers() assert connection_close(b"HTTP/1.0", headers) @@ -121,6 +132,7 @@ def test_connection_close(): assert connection_close(b"HTTP/1.0", headers) assert not connection_close(b"HTTP/1.1", headers) + def test_expected_http_body_size(): # Expect: 100-continue assert expected_http_body_size( @@ -203,6 +215,7 @@ def test_read_request_line(): with raises(HttpReadDisconnect): t(b"") + def test_parse_authority_form(): assert _parse_authority_form(b"foo:42") == (b"foo", 42) with raises(HttpSyntaxException): @@ -302,6 +315,7 @@ class TestReadHeaders(object): headers = self._read(data) assert headers.fields == ((b"bar", b""),) + def test_read_chunked(): req = treq(content=None) req.headers["Transfer-Encoding"] = "chunked" diff --git a/test/netlib/http/http2/test_connections.py b/test/netlib/http/http2/test_connections.py index 7d240c0e..27cc30ba 100644 --- a/test/netlib/http/http2/test_connections.py +++ b/test/netlib/http/http2/test_connections.py @@ -1,16 +1,16 @@ -import OpenSSL import mock import codecs -from hyperframe.frame import * - -from netlib import tcp, http, utils +import hyperframe +from netlib import tcp, http from netlib.tutils import raises from netlib.exceptions import TcpDisconnect from netlib.http.http2.connections import HTTP2Protocol, TCPHandler +from netlib.http.http2 import framereader from ... import tservers + class TestTCPHandlerWrapper: def test_wrapped(self): h = TCPHandler(rfile='foo', wfile='bar') @@ -111,11 +111,11 @@ class TestPerformServerConnectionPreface(tservers.ServerTestBase): self.wfile.flush() # check empty settings frame - raw = utils.http2_read_raw_frame(self.rfile) + raw = framereader.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('00000c040000000000000200000000000300000001', 'hex_codec') # check settings acknowledgement - raw = utils.http2_read_raw_frame(self.rfile) + raw = framereader.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('000000040100000000', 'hex_codec') # send settings acknowledgement @@ -214,19 +214,19 @@ class TestApplySettings(tservers.ServerTestBase): protocol = HTTP2Protocol(c) protocol._apply_settings({ - SettingsFrame.ENABLE_PUSH: 'foo', - SettingsFrame.MAX_CONCURRENT_STREAMS: 'bar', - SettingsFrame.INITIAL_WINDOW_SIZE: 'deadbeef', + hyperframe.frame.SettingsFrame.ENABLE_PUSH: 'foo', + hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 'bar', + hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE: 'deadbeef', }) assert c.rfile.safe_read(2) == b"OK" assert protocol.http2_settings[ - SettingsFrame.ENABLE_PUSH] == 'foo' + hyperframe.frame.SettingsFrame.ENABLE_PUSH] == 'foo' assert protocol.http2_settings[ - SettingsFrame.MAX_CONCURRENT_STREAMS] == 'bar' + hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS] == 'bar' assert protocol.http2_settings[ - SettingsFrame.INITIAL_WINDOW_SIZE] == 'deadbeef' + hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE] == 'deadbeef' class TestCreateHeaders(object): @@ -258,7 +258,7 @@ class TestCreateHeaders(object): (b'server', b'version')]) protocol = HTTP2Protocol(self.c) - protocol.http2_settings[SettingsFrame.MAX_FRAME_SIZE] = 8 + protocol.http2_settings[hyperframe.frame.SettingsFrame.MAX_FRAME_SIZE] = 8 bytes = protocol._create_headers(headers, 1, end_stream=True) assert len(bytes) == 3 assert bytes[0] == codecs.decode('000008010100000001828487408294e783', 'hex_codec') @@ -281,7 +281,7 @@ class TestCreateBody(object): def test_create_body_multiple_frames(self): protocol = HTTP2Protocol(self.c) - protocol.http2_settings[SettingsFrame.MAX_FRAME_SIZE] = 5 + protocol.http2_settings[hyperframe.frame.SettingsFrame.MAX_FRAME_SIZE] = 5 bytes = protocol._create_body(b'foobarmehm42', 1) assert len(bytes) == 3 assert bytes[0] == codecs.decode('000005000000000001666f6f6261', 'hex_codec') @@ -312,7 +312,10 @@ class TestReadRequest(tservers.ServerTestBase): req = protocol.read_request(NotImplemented) assert req.stream_id - assert req.headers.fields == ((b':method', b'GET'), (b':path', b'/'), (b':scheme', b'https')) + assert req.headers.fields == () + assert req.method == "GET" + assert req.path == "/" + assert req.scheme == "https" assert req.content == b'foobar' @@ -461,7 +464,7 @@ class TestAssembleRequest(object): b'', b'/', b"HTTP/2.0", - None, + (), None, )) assert len(bytes) == 1 @@ -476,7 +479,7 @@ class TestAssembleRequest(object): b'', b'/', b"HTTP/2.0", - None, + (), None, ) req.stream_id = 0x42 diff --git a/test/netlib/http/test_authentication.py b/test/netlib/http/test_authentication.py index 1df7cd9c..95d72447 100644 --- a/test/netlib/http/test_authentication.py +++ b/test/netlib/http/test_authentication.py @@ -78,7 +78,7 @@ class TestBasicProxyAuth: assert ba.authenticate(headers) ba.clean(headers) - assert not ba.AUTH_HEADER in headers + assert ba.AUTH_HEADER not in headers headers[ba.AUTH_HEADER] = "" assert not ba.authenticate(headers) diff --git a/test/netlib/http/test_cookies.py b/test/netlib/http/test_cookies.py index 6f84c4ce..83b85656 100644 --- a/test/netlib/http/test_cookies.py +++ b/test/netlib/http/test_cookies.py @@ -184,7 +184,7 @@ def test_parse_set_cookie_pairs(): assert ret == lst s2 = cookies._format_set_cookie_pairs(ret) ret2 = cookies._parse_set_cookie_pairs(s2) - assert ret2 == lst + assert ret2 == lst def test_parse_set_cookie_header(): diff --git a/test/netlib/http/test_headers.py b/test/netlib/http/test_headers.py index cd2ca9d1..51819b86 100644 --- a/test/netlib/http/test_headers.py +++ b/test/netlib/http/test_headers.py @@ -1,4 +1,4 @@ -from netlib.http import Headers +from netlib.http import Headers, parse_content_type from netlib.tutils import raises @@ -72,3 +72,12 @@ class TestHeaders(object): replacements = headers.replace(r"Host: ", "X-Host ") assert replacements == 0 assert headers["Host"] == "example.com" + + +def test_parse_content_type(): + p = parse_content_type + assert p("text/html") == ("text", "html", {}) + assert p("text") is None + + v = p("text/html; charset=UTF-8") + assert v == ('text', 'html', {'charset': 'UTF-8'}) diff --git a/test/netlib/http/test_message.py b/test/netlib/http/test_message.py index 64592921..f5bf7f0c 100644 --- a/test/netlib/http/test_message.py +++ b/test/netlib/http/test_message.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, division -from netlib.http import decoded, Headers -from netlib.tutils import tresp, raises +from netlib.http import decoded +from netlib.tutils import tresp def _test_passthrough_attr(message, attr): diff --git a/test/netlib/http/test_multipart.py b/test/netlib/http/test_multipart.py new file mode 100644 index 00000000..1d7e0062 --- /dev/null +++ b/test/netlib/http/test_multipart.py @@ -0,0 +1,24 @@ +from netlib.http import Headers +from netlib.http import multipart + + +def test_decode(): + boundary = 'somefancyboundary' + headers = Headers( + content_type='multipart/form-data; boundary=' + boundary + ) + content = ( + "--{0}\n" + "Content-Disposition: form-data; name=\"field1\"\n\n" + "value1\n" + "--{0}\n" + "Content-Disposition: form-data; name=\"field2\"\n\n" + "value2\n" + "--{0}--".format(boundary).encode() + ) + + form = multipart.decode(headers, content) + + assert len(form) == 2 + assert form[0] == (b"field1", b"value1") + assert form[1] == (b"field2", b"value2") diff --git a/test/netlib/http/test_request.py b/test/netlib/http/test_request.py index fae7aefe..c03db339 100644 --- a/test/netlib/http/test_request.py +++ b/test/netlib/http/test_request.py @@ -13,7 +13,7 @@ class TestRequestData(object): with raises(ValueError): treq(headers="foobar") - assert isinstance(treq(headers=None).headers, Headers) + assert isinstance(treq(headers=()).headers, Headers) class TestRequestCore(object): diff --git a/test/netlib/http/test_response.py b/test/netlib/http/test_response.py index cfd093d4..b3c2f736 100644 --- a/test/netlib/http/test_response.py +++ b/test/netlib/http/test_response.py @@ -2,12 +2,10 @@ from __future__ import absolute_import, print_function, division import email -import six import time from netlib.http import Headers from netlib.http.cookies import CookieAttrs -from netlib.odict import ODict, ODictCaseless from netlib.tutils import raises, tresp from .test_message import _test_passthrough_attr, _test_decoded_attr @@ -17,7 +15,7 @@ class TestResponseData(object): with raises(ValueError): tresp(headers="foobar") - assert isinstance(tresp(headers=None).headers, Headers) + assert isinstance(tresp(headers=()).headers, Headers) class TestResponseCore(object): @@ -26,7 +24,7 @@ class TestResponseCore(object): """ def test_repr(self): response = tresp() - assert repr(response) == "Response(200 OK, unknown content type, 7B)" + assert repr(response) == "Response(200 OK, unknown content type, 7b)" response.content = None assert repr(response) == "Response(200 OK, no content)" @@ -61,7 +59,8 @@ class TestResponseUtils(object): def test_get_cookies_with_parameters(self): resp = tresp() - resp.headers = Headers(set_cookie="cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly") + cookie = "cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly" + resp.headers = Headers(set_cookie=cookie) result = resp.cookies assert len(result) == 1 assert "cookiename" in result diff --git a/test/netlib/http/test_url.py b/test/netlib/http/test_url.py new file mode 100644 index 00000000..26b37230 --- /dev/null +++ b/test/netlib/http/test_url.py @@ -0,0 +1,66 @@ +from netlib import tutils +from netlib.http import url + + +def test_parse(): + with tutils.raises(ValueError): + url.parse("") + + s, h, po, pa = url.parse(b"http://foo.com:8888/test") + assert s == b"http" + assert h == b"foo.com" + assert po == 8888 + assert pa == b"/test" + + s, h, po, pa = url.parse("http://foo/bar") + assert s == b"http" + assert h == b"foo" + assert po == 80 + assert pa == b"/bar" + + s, h, po, pa = url.parse(b"http://user:pass@foo/bar") + assert s == b"http" + assert h == b"foo" + assert po == 80 + assert pa == b"/bar" + + s, h, po, pa = url.parse(b"http://foo") + assert pa == b"/" + + s, h, po, pa = url.parse(b"https://foo") + assert po == 443 + + with tutils.raises(ValueError): + url.parse(b"https://foo:bar") + + # Invalid IDNA + with tutils.raises(ValueError): + url.parse("http://\xfafoo") + # Invalid PATH + with tutils.raises(ValueError): + url.parse("http:/\xc6/localhost:56121") + # Null byte in host + with tutils.raises(ValueError): + url.parse("http://foo\0") + # Port out of range + _, _, port, _ = url.parse("http://foo:999999") + assert port == 80 + # Invalid IPv6 URL - see http://www.ietf.org/rfc/rfc2732.txt + with tutils.raises(ValueError): + url.parse('http://lo[calhost') + + +def test_unparse(): + assert url.unparse("http", "foo.com", 99, "") == "http://foo.com:99" + assert url.unparse("http", "foo.com", 80, "/bar") == "http://foo.com/bar" + assert url.unparse("https", "foo.com", 80, "") == "https://foo.com:80" + assert url.unparse("https", "foo.com", 443, "") == "https://foo.com" + + +def test_urlencode(): + assert url.encode([('foo', 'bar')]) + + +def test_urldecode(): + s = "one=two&three=four" + assert len(url.decode(s)) == 2 diff --git a/test/netlib/test_basetypes.py b/test/netlib/test_basetypes.py new file mode 100644 index 00000000..aa415784 --- /dev/null +++ b/test/netlib/test_basetypes.py @@ -0,0 +1,28 @@ +from netlib import basetypes + + +class SerializableDummy(basetypes.Serializable): + def __init__(self, i): + self.i = i + + def get_state(self): + return self.i + + def set_state(self, i): + self.i = i + + def from_state(self, state): + return type(self)(state) + + +class TestSerializable: + + def test_copy(self): + a = SerializableDummy(42) + assert a.i == 42 + b = a.copy() + assert b.i == 42 + + a.set_state(1) + assert a.i == 1 + assert b.i == 42 diff --git a/test/netlib/test_human.py b/test/netlib/test_human.py new file mode 100644 index 00000000..2a5c2a85 --- /dev/null +++ b/test/netlib/test_human.py @@ -0,0 +1,36 @@ +from netlib import human, tutils + + +def test_parse_size(): + assert human.parse_size("0") == 0 + assert human.parse_size("0b") == 0 + assert human.parse_size("1") == 1 + assert human.parse_size("1k") == 1024 + assert human.parse_size("1m") == 1024**2 + assert human.parse_size("1g") == 1024**3 + tutils.raises(ValueError, human.parse_size, "1f") + tutils.raises(ValueError, human.parse_size, "ak") + + +def test_pretty_size(): + assert human.pretty_size(0) == "0b" + assert human.pretty_size(100) == "100b" + assert human.pretty_size(1024) == "1k" + assert human.pretty_size(1024 + (1024 / 2.0)) == "1.5k" + assert human.pretty_size(1024 * 1024) == "1m" + assert human.pretty_size(10 * 1024 * 1024) == "10m" + + +def test_pretty_duration(): + assert human.pretty_duration(0.00001) == "0ms" + assert human.pretty_duration(0.0001) == "0ms" + assert human.pretty_duration(0.001) == "1ms" + assert human.pretty_duration(0.01) == "10ms" + assert human.pretty_duration(0.1) == "100ms" + assert human.pretty_duration(1) == "1.00s" + assert human.pretty_duration(10) == "10.0s" + assert human.pretty_duration(100) == "100s" + assert human.pretty_duration(1000) == "1000s" + assert human.pretty_duration(10000) == "10000s" + assert human.pretty_duration(1.123) == "1.12s" + assert human.pretty_duration(0.123) == "123ms" diff --git a/test/netlib/test_multidict.py b/test/netlib/test_multidict.py index 5bb65e3f..7319f1c5 100644 --- a/test/netlib/test_multidict.py +++ b/test/netlib/test_multidict.py @@ -49,7 +49,7 @@ class TestMultiDict(object): assert md["foo"] == "bar" with tutils.raises(KeyError): - _ = md["bar"] + md["bar"] md_multi = TMultiDict( [("foo", "a"), ("foo", "b")] diff --git a/test/netlib/test_socks.py b/test/netlib/test_socks.py index 486b975b..17e08054 100644 --- a/test/netlib/test_socks.py +++ b/test/netlib/test_socks.py @@ -1,6 +1,5 @@ import ipaddress from io import BytesIO -import socket from netlib import socks, tcp, tutils diff --git a/test/netlib/test_strutils.py b/test/netlib/test_strutils.py new file mode 100644 index 00000000..734265c4 --- /dev/null +++ b/test/netlib/test_strutils.py @@ -0,0 +1,63 @@ +# coding=utf-8 + +from netlib import strutils + + +def test_clean_bin(): + assert strutils.clean_bin(b"one") == b"one" + assert strutils.clean_bin(b"\00ne") == b".ne" + assert strutils.clean_bin(b"\nne") == b"\nne" + assert strutils.clean_bin(b"\nne", False) == b".ne" + assert strutils.clean_bin(u"\u2605".encode("utf8")) == b"..." + + assert strutils.clean_bin(u"one") == u"one" + assert strutils.clean_bin(u"\00ne") == u".ne" + assert strutils.clean_bin(u"\nne") == u"\nne" + assert strutils.clean_bin(u"\nne", False) == u".ne" + assert strutils.clean_bin(u"\u2605") == u"\u2605" + + +def test_safe_subn(): + assert strutils.safe_subn("foo", u"bar", "\xc2foo") + + +def test_bytes_to_escaped_str(): + assert strutils.bytes_to_escaped_str(b"foo") == "foo" + assert strutils.bytes_to_escaped_str(b"\b") == r"\x08" + assert strutils.bytes_to_escaped_str(br"&!?=\)") == r"&!?=\\)" + assert strutils.bytes_to_escaped_str(b'\xc3\xbc') == r"\xc3\xbc" + assert strutils.bytes_to_escaped_str(b"'") == r"\'" + assert strutils.bytes_to_escaped_str(b'"') == r'"' + + +def test_escaped_str_to_bytes(): + assert strutils.escaped_str_to_bytes("foo") == b"foo" + assert strutils.escaped_str_to_bytes("\x08") == b"\b" + assert strutils.escaped_str_to_bytes("&!?=\\\\)") == br"&!?=\)" + assert strutils.escaped_str_to_bytes("ü") == b'\xc3\xbc' + assert strutils.escaped_str_to_bytes(u"\\x08") == b"\b" + assert strutils.escaped_str_to_bytes(u"&!?=\\\\)") == br"&!?=\)" + assert strutils.escaped_str_to_bytes(u"ü") == b'\xc3\xbc' + + +def test_isBin(): + assert not strutils.isBin("testing\n\r") + assert strutils.isBin("testing\x01") + assert strutils.isBin("testing\x0e") + assert strutils.isBin("testing\x7f") + + +def test_isXml(): + assert not strutils.isXML("foo") + assert strutils.isXML("<foo") + assert strutils.isXML(" \n<foo") + + +def test_clean_hanging_newline(): + s = "foo\n" + assert strutils.clean_hanging_newline(s) == "foo" + assert strutils.clean_hanging_newline("foo") == "foo" + + +def test_hexdump(): + assert list(strutils.hexdump(b"one\0" * 10)) diff --git a/test/netlib/test_tcp.py b/test/netlib/test_tcp.py index 4b4bbb92..083360b4 100644 --- a/test/netlib/test_tcp.py +++ b/test/netlib/test_tcp.py @@ -8,7 +8,6 @@ import threading import mock from OpenSSL import SSL -import OpenSSL from netlib import tcp, certutils, tutils from netlib.exceptions import InvalidCertificateException, TcpReadIncomplete, TlsException, \ @@ -16,6 +15,7 @@ from netlib.exceptions import InvalidCertificateException, TcpReadIncomplete, Tl from . import tservers + class EchoHandler(tcp.BaseHandler): sni = None diff --git a/test/netlib/test_utils.py b/test/netlib/test_utils.py index 1d8f7b0f..eaa66f13 100644 --- a/test/netlib/test_utils.py +++ b/test/netlib/test_utils.py @@ -1,6 +1,7 @@ # coding=utf-8 + from netlib import utils, tutils -from netlib.http import Headers + def test_bidi(): b = utils.BiDi(a=1, b=2) @@ -9,179 +10,3 @@ def test_bidi(): assert b.get_name(5) is None tutils.raises(AttributeError, getattr, b, "c") tutils.raises(ValueError, utils.BiDi, one=1, two=1) - - -def test_hexdump(): - assert list(utils.hexdump(b"one\0" * 10)) - - -def test_clean_bin(): - assert utils.clean_bin(b"one") == b"one" - assert utils.clean_bin(b"\00ne") == b".ne" - assert utils.clean_bin(b"\nne") == b"\nne" - assert utils.clean_bin(b"\nne", False) == b".ne" - assert utils.clean_bin(u"\u2605".encode("utf8")) == b"..." - - assert utils.clean_bin(u"one") == u"one" - assert utils.clean_bin(u"\00ne") == u".ne" - assert utils.clean_bin(u"\nne") == u"\nne" - assert utils.clean_bin(u"\nne", False) == u".ne" - assert utils.clean_bin(u"\u2605") == u"\u2605" - - -def test_pretty_size(): - assert utils.pretty_size(100) == "100B" - assert utils.pretty_size(1024) == "1kB" - assert utils.pretty_size(1024 + (1024 / 2.0)) == "1.5kB" - assert utils.pretty_size(1024 * 1024) == "1MB" - - -def test_parse_url(): - with tutils.raises(ValueError): - utils.parse_url("") - - s, h, po, pa = utils.parse_url(b"http://foo.com:8888/test") - assert s == b"http" - assert h == b"foo.com" - assert po == 8888 - assert pa == b"/test" - - s, h, po, pa = utils.parse_url("http://foo/bar") - assert s == b"http" - assert h == b"foo" - assert po == 80 - assert pa == b"/bar" - - s, h, po, pa = utils.parse_url(b"http://user:pass@foo/bar") - assert s == b"http" - assert h == b"foo" - assert po == 80 - assert pa == b"/bar" - - s, h, po, pa = utils.parse_url(b"http://foo") - assert pa == b"/" - - s, h, po, pa = utils.parse_url(b"https://foo") - assert po == 443 - - with tutils.raises(ValueError): - utils.parse_url(b"https://foo:bar") - - # Invalid IDNA - with tutils.raises(ValueError): - utils.parse_url("http://\xfafoo") - # Invalid PATH - with tutils.raises(ValueError): - utils.parse_url("http:/\xc6/localhost:56121") - # Null byte in host - with tutils.raises(ValueError): - utils.parse_url("http://foo\0") - # Port out of range - _, _, port, _ = utils.parse_url("http://foo:999999") - assert port == 80 - # Invalid IPv6 URL - see http://www.ietf.org/rfc/rfc2732.txt - with tutils.raises(ValueError): - utils.parse_url('http://lo[calhost') - - -def test_unparse_url(): - assert utils.unparse_url("http", "foo.com", 99, "") == "http://foo.com:99" - assert utils.unparse_url("http", "foo.com", 80, "/bar") == "http://foo.com/bar" - assert utils.unparse_url("https", "foo.com", 80, "") == "https://foo.com:80" - assert utils.unparse_url("https", "foo.com", 443, "") == "https://foo.com" - - -def test_urlencode(): - assert utils.urlencode([('foo', 'bar')]) - - -def test_urldecode(): - s = "one=two&three=four" - assert len(utils.urldecode(s)) == 2 - - -def test_get_header_tokens(): - headers = Headers() - assert utils.get_header_tokens(headers, "foo") == [] - headers["foo"] = "bar" - assert utils.get_header_tokens(headers, "foo") == ["bar"] - headers["foo"] = "bar, voing" - assert utils.get_header_tokens(headers, "foo") == ["bar", "voing"] - headers.set_all("foo", ["bar, voing", "oink"]) - assert utils.get_header_tokens(headers, "foo") == ["bar", "voing", "oink"] - - -def test_multipartdecode(): - boundary = 'somefancyboundary' - headers = Headers( - content_type='multipart/form-data; boundary=' + boundary - ) - content = ( - "--{0}\n" - "Content-Disposition: form-data; name=\"field1\"\n\n" - "value1\n" - "--{0}\n" - "Content-Disposition: form-data; name=\"field2\"\n\n" - "value2\n" - "--{0}--".format(boundary).encode() - ) - - form = utils.multipartdecode(headers, content) - - assert len(form) == 2 - assert form[0] == (b"field1", b"value1") - assert form[1] == (b"field2", b"value2") - - -def test_parse_content_type(): - p = utils.parse_content_type - assert p("text/html") == ("text", "html", {}) - assert p("text") is None - - v = p("text/html; charset=UTF-8") - assert v == ('text', 'html', {'charset': 'UTF-8'}) - - -class SerializableDummy(utils.Serializable): - def __init__(self, i): - self.i = i - - def get_state(self): - return self.i - - def set_state(self, i): - self.i = i - - def from_state(self, state): - return type(self)(state) - - -class TestSerializable: - - def test_copy(self): - a = SerializableDummy(42) - assert a.i == 42 - b = a.copy() - assert b.i == 42 - - a.set_state(1) - assert a.i == 1 - assert b.i == 42 - - -def test_safe_subn(): - assert utils.safe_subn("foo", u"bar", "\xc2foo") - - -def test_bytes_to_escaped_str(): - assert utils.bytes_to_escaped_str(b"foo") == "foo" - assert utils.bytes_to_escaped_str(b"\b") == r"\x08" - assert utils.bytes_to_escaped_str(br"&!?=\)") == r"&!?=\\)" - assert utils.bytes_to_escaped_str(b'\xc3\xbc') == r"\xc3\xbc" - - -def test_escaped_str_to_bytes(): - assert utils.escaped_str_to_bytes("foo") == b"foo" - assert utils.escaped_str_to_bytes(r"\x08") == b"\b" - assert utils.escaped_str_to_bytes(r"&!?=\\)") == br"&!?=\)" - assert utils.escaped_str_to_bytes(r"ü") == b'\xc3\xbc' diff --git a/test/netlib/test_version_check.py b/test/netlib/test_version_check.py index 680f80e0..fa6b19e5 100644 --- a/test/netlib/test_version_check.py +++ b/test/netlib/test_version_check.py @@ -1,6 +1,6 @@ from io import StringIO import mock -from netlib import version_check, version +from netlib import version_check @mock.patch("sys.exit") diff --git a/test/netlib/test_wsgi.py b/test/netlib/test_wsgi.py index 8c782b27..5c61f81c 100644 --- a/test/netlib/test_wsgi.py +++ b/test/netlib/test_wsgi.py @@ -11,7 +11,7 @@ def tflow(): class ExampleApp: - + def __init__(self): self.called = False diff --git a/test/netlib/websockets/test_websockets.py b/test/netlib/websockets/test_websockets.py index a7d782a4..50fa26e6 100644 --- a/test/netlib/websockets/test_websockets.py +++ b/test/netlib/websockets/test_websockets.py @@ -2,13 +2,16 @@ import os from netlib.http.http1 import read_response, read_request -from netlib import tcp, websockets, http, tutils +from netlib import tcp +from netlib import tutils +from netlib import websockets from netlib.http import status_codes from netlib.tutils import treq -from netlib.exceptions import * +from netlib import exceptions from .. import tservers + class WebSocketsEchoHandler(tcp.BaseHandler): def __init__(self, connection, address, server): @@ -117,8 +120,8 @@ class TestWebSockets(tservers.ServerTestBase): default builder should always generate valid frames """ msg = self.random_bytes() - client_frame = websockets.Frame.default(msg, from_client=True) - server_frame = websockets.Frame.default(msg, from_client=False) + assert websockets.Frame.default(msg, from_client=True) + assert websockets.Frame.default(msg, from_client=False) def test_serialization_bijection(self): """ @@ -174,7 +177,7 @@ class TestBadHandshake(tservers.ServerTestBase): handler = BadHandshakeHandler def test(self): - with tutils.raises(TcpDisconnect): + with tutils.raises(exceptions.TcpDisconnect): client = WebSocketsClient(("127.0.0.1", self.port)) client.connect() client.send_message(b"hello") diff --git a/test/pathod/test_app.py b/test/pathod/test_app.py index ac89c44c..fbaa773c 100644 --- a/test/pathod/test_app.py +++ b/test/pathod/test_app.py @@ -11,11 +11,11 @@ class TestApp(tutils.DaemonTests): def test_about(self): r = self.getpath("/about") - assert r.ok + assert r.status_code == 200 def test_download(self): r = self.getpath("/download") - assert r.ok + assert r.status_code == 200 def test_docs(self): assert self.getpath("/docs/pathod").status_code == 200 @@ -27,7 +27,7 @@ class TestApp(tutils.DaemonTests): def test_log(self): assert self.getpath("/log").status_code == 200 assert self.get("200:da").status_code == 200 - id = self.d.log()[0]["id"] + id = self.d.expect_log(1)[0]["id"] assert self.getpath("/log").status_code == 200 assert self.getpath("/log/%s" % id).status_code == 200 assert self.getpath("/log/9999999").status_code == 404 diff --git a/test/pathod/test_language_actions.py b/test/pathod/test_language_actions.py index c2e15189..81d2155d 100644 --- a/test/pathod/test_language_actions.py +++ b/test/pathod/test_language_actions.py @@ -68,9 +68,9 @@ class TestInject: def test_spec(self): e = actions.InjectAt.expr() v = e.parseString("i0,'foo'")[0] - assert v.spec() == 'i0,"foo"' + assert v.spec() == "i0,'foo'" - def test_spec(self): + def test_spec2(self): e = actions.InjectAt.expr() v = e.parseString("i0,@100")[0] v2 = v.freeze({}) diff --git a/test/pathod/test_language_base.py b/test/pathod/test_language_base.py index 64d4af1f..47e51bb0 100644 --- a/test/pathod/test_language_base.py +++ b/test/pathod/test_language_base.py @@ -41,11 +41,11 @@ class TestTokValueLiteral: def test_espr(self): v = base.TokValueLiteral("foo") assert v.expr() - assert v.val == "foo" + assert v.val == b"foo" v = base.TokValueLiteral("foo\n") assert v.expr() - assert v.val == "foo\n" + assert v.val == b"foo\n" assert repr(v) def test_spec(self): @@ -67,7 +67,7 @@ class TestTokValueLiteral: def test_roundtrip(self): self.roundtrip("'") - self.roundtrip('\'') + self.roundtrip(r"\'") self.roundtrip("a") self.roundtrip("\"") # self.roundtrip("\\") @@ -171,19 +171,19 @@ class TestMisc: def test_generators(self): v = base.TokValue.parseString("'val'")[0] g = v.get_generator({}) - assert g[:] == "val" + assert g[:] == b"val" def test_value(self): - assert base.TokValue.parseString("'val'")[0].val == "val" - assert base.TokValue.parseString('"val"')[0].val == "val" - assert base.TokValue.parseString('"\'val\'"')[0].val == "'val'" + assert base.TokValue.parseString("'val'")[0].val == b"val" + assert base.TokValue.parseString('"val"')[0].val == b"val" + assert base.TokValue.parseString('"\'val\'"')[0].val == b"'val'" - def test_value(self): + def test_value2(self): class TT(base.Value): preamble = "m" e = TT.expr() v = e.parseString("m'msg'")[0] - assert v.value.val == "msg" + assert v.value.val == b"msg" s = v.spec() assert s == e.parseString(s)[0].spec() @@ -235,8 +235,8 @@ class TestKeyValue: def test_simple(self): e = TKeyValue.expr() v = e.parseString("h'foo'='bar'")[0] - assert v.key.val == "foo" - assert v.value.val == "bar" + assert v.key.val == b"foo" + assert v.value.val == b"bar" v2 = e.parseString(v.spec())[0] assert v2.key.val == v.key.val @@ -289,9 +289,9 @@ def test_options_or_value(): "three" ] e = TT.expr() - assert e.parseString("one")[0].value.val == "one" - assert e.parseString("'foo'")[0].value.val == "foo" - assert e.parseString("'get'")[0].value.val == "get" + assert e.parseString("one")[0].value.val == b"one" + assert e.parseString("'foo'")[0].value.val == b"foo" + assert e.parseString("'get'")[0].value.val == b"get" assert e.parseString("one")[0].spec() == "one" assert e.parseString("'foo'")[0].spec() == "'foo'" diff --git a/test/pathod/test_language_generators.py b/test/pathod/test_language_generators.py index 0fceae85..51f55991 100644 --- a/test/pathod/test_language_generators.py +++ b/test/pathod/test_language_generators.py @@ -7,24 +7,27 @@ import tutils def test_randomgenerator(): g = generators.RandomGenerator("bytes", 100) assert repr(g) + assert g[0] + assert len(g[0]) == 1 assert len(g[:10]) == 10 assert len(g[1:10]) == 9 assert len(g[:1000]) == 100 assert len(g[1000:1001]) == 0 - assert g[0] def test_filegenerator(): with tutils.tmpdir() as t: path = os.path.join(t, "foo") f = open(path, "wb") - f.write("x" * 10000) + f.write(b"x" * 10000) f.close() g = generators.FileGenerator(path) assert len(g) == 10000 - assert g[0] == "x" - assert g[-1] == "x" - assert g[0:5] == "xxxxx" + assert g[0] == b"x" + assert g[-1] == b"x" + assert g[0:5] == b"xxxxx" + assert len(g[1:10]) == 9 + assert len(g[10000:10001]) == 0 assert repr(g) # remove all references to FileGenerator instance to close the file # handle. diff --git a/test/pathod/test_language_http2.py b/test/pathod/test_language_http2.py index abfe4606..de256626 100644 --- a/test/pathod/test_language_http2.py +++ b/test/pathod/test_language_http2.py @@ -5,7 +5,7 @@ from netlib import tcp from netlib.http import user_agents from pathod import language -from pathod.language import http2, base +from pathod.language import http2 import tutils @@ -141,7 +141,6 @@ class TestRequest: assert isinstance(r.tokens[2], http2.NestedResponse) assert r.values(default_settings()) - def test_render_with_body(self): s = StringIO() r = parse_request("GET:'/foo':bfoobar") diff --git a/test/pathod/test_log.py b/test/pathod/test_log.py index d91b8bb1..29801eb3 100644 --- a/test/pathod/test_log.py +++ b/test/pathod/test_log.py @@ -1,10 +1,10 @@ -import StringIO from pathod import log from netlib.exceptions import TcpDisconnect -import netlib.tcp +import six -class DummyIO(StringIO.StringIO): + +class DummyIO(six.StringIO): def start_log(self, *args, **kwargs): pass diff --git a/test/pathod/test_pathoc.py b/test/pathod/test_pathoc.py index 4e8c89c5..6e36c4bf 100644 --- a/test/pathod/test_pathoc.py +++ b/test/pathod/test_pathoc.py @@ -1,12 +1,12 @@ import json from six.moves import cStringIO as StringIO import re -import OpenSSL import pytest from mock import Mock -from netlib import tcp, http, socks -from netlib.exceptions import HttpException, TcpException, NetlibException +from netlib import http +from netlib import tcp +from netlib.exceptions import NetlibException from netlib.http import http1, http2 from pathod import pathoc, test, version, pathod, language @@ -147,7 +147,7 @@ class TestDaemon(_TestDaemon): tutils.raises("ssl handshake", c.connect) def test_showssl(self): - assert not "certificate chain" in self.tval( + assert "certificate chain" not in self.tval( ["get:/p/200"], showssl=True) @@ -170,7 +170,7 @@ class TestDaemon(_TestDaemon): showresp=True, timeout=1 ) - assert not "HTTP" in self.tval( + assert "HTTP" not in self.tval( ["get:'/p/200:p3,100'"], showresp=True, timeout=1, diff --git a/test/pathod/test_pathoc_cmdline.py b/test/pathod/test_pathoc_cmdline.py index f527e861..35909325 100644 --- a/test/pathod/test_pathoc_cmdline.py +++ b/test/pathod/test_pathoc_cmdline.py @@ -29,13 +29,13 @@ def test_pathoc(perror): assert a.connect_to == ["foo", 10] a = cmdline.args_pathoc(["pathoc", "foo.com", "get:/", "--http2"]) - assert a.use_http2 == True - assert a.ssl == True + assert a.use_http2 is True + assert a.ssl is True a = cmdline.args_pathoc(["pathoc", "foo.com", "get:/", "--http2-skip-connection-preface"]) - assert a.use_http2 == True - assert a.ssl == True - assert a.http2_skip_connection_preface == True + assert a.use_http2 is True + assert a.ssl is True + assert a.http2_skip_connection_preface is True a = cmdline.args_pathoc(["pathoc", "-c", "foo", "foo.com:8888", "get:/"]) assert perror.called diff --git a/test/pathod/test_pathod.py b/test/pathod/test_pathod.py index 05a3962e..ec9c169f 100644 --- a/test/pathod/test_pathod.py +++ b/test/pathod/test_pathod.py @@ -1,8 +1,7 @@ from six.moves import cStringIO as StringIO -import pytest -from pathod import pathod, version -from netlib import tcp, http +from pathod import pathod +from netlib import tcp from netlib.exceptions import HttpException, TlsException import tutils @@ -51,7 +50,7 @@ class TestNoApi(tutils.DaemonTests): assert self.getpath("/log").status_code == 404 r = self.getpath("/") assert r.status_code == 200 - assert not "Log" in r.content + assert "Log" not in r.content class TestNotAfterConnect(tutils.DaemonTests): @@ -110,7 +109,7 @@ class TestHexdump(tutils.DaemonTests): hexdump = True def test_hexdump(self): - r = self.get(r"200:b'\xf0'") + assert self.get(r"200:b'\xf0'") class TestNocraft(tutils.DaemonTests): @@ -125,11 +124,10 @@ class TestNocraft(tutils.DaemonTests): class CommonTests(tutils.DaemonTests): def test_binarydata(self): - r = self.get(r"200:b'\xf0'") - l = self.d.last_log() + assert self.get(r"200:b'\xf0'") + assert self.d.last_log() # FIXME: Other binary data elements - @pytest.mark.skip(reason="race condition") def test_sizelimit(self): r = self.get("200:b@1g") assert r.status_code == 800 @@ -140,21 +138,15 @@ class CommonTests(tutils.DaemonTests): r, _ = self.pathoc([r"get:'/p/200':i0,'\r\n'"]) assert r[0].status_code == 200 - def test_info(self): - assert tuple(self.d.info()["version"]) == version.IVERSION - - @pytest.mark.skip(reason="race condition") def test_logs(self): - assert self.d.clear_log() - assert not self.d.last_log() - rsp = self.get("202:da") - assert len(self.d.log()) == 1 - assert self.d.clear_log() + self.d.clear_log() + assert self.get("202:da") + assert self.d.expect_log(1) + self.d.clear_log() assert len(self.d.log()) == 0 def test_disconnect(self): - rsp = self.get("202:b@100k:d200") - assert len(rsp.content) < 200 + tutils.raises("unexpected eof", self.get, "202:b@100k:d200") def test_parserr(self): rsp = self.get("400:msg,b:") @@ -166,7 +158,7 @@ class CommonTests(tutils.DaemonTests): assert rsp.content.strip() == "testfile" def test_anchor(self): - rsp = self.getpath("anchor/foo") + rsp = self.getpath("/anchor/foo") assert rsp.status_code == 202 def test_invalid_first_line(self): @@ -223,7 +215,6 @@ class CommonTests(tutils.DaemonTests): ) assert r[1].payload == "test" - @pytest.mark.skip(reason="race condition") def test_websocket_frame_reflect_error(self): r, _ = self.pathoc( ["ws:/p/", "wf:-mask:knone:f'wf:b@10':i13,'a'"], @@ -233,7 +224,6 @@ class CommonTests(tutils.DaemonTests): # FIXME: Race Condition? assert "Parse error" in self.d.text_log() - @pytest.mark.skip(reason="race condition") def test_websocket_frame_disconnect_error(self): self.pathoc(["ws:/p/", "wf:b@10:d3"], ws_read_limit=0) assert self.d.last_log() diff --git a/test/pathod/test_test.py b/test/pathod/test_test.py index cee286a4..6399894e 100644 --- a/test/pathod/test_test.py +++ b/test/pathod/test_test.py @@ -2,6 +2,10 @@ import logging import requests from pathod import test import tutils + +import requests.packages.urllib3 + +requests.packages.urllib3.disable_warnings() logging.disable(logging.CRITICAL) diff --git a/test/pathod/test_utils.py b/test/pathod/test_utils.py index 4dcedf6e..a46a523a 100644 --- a/test/pathod/test_utils.py +++ b/test/pathod/test_utils.py @@ -11,13 +11,6 @@ def test_membool(): assert m.v == 2 -def test_parse_size(): - assert utils.parse_size("100") == 100 - assert utils.parse_size("100k") == 100 * 1024 - tutils.raises("invalid size spec", utils.parse_size, "foo") - tutils.raises("invalid size spec", utils.parse_size, "100kk") - - def test_parse_anchor_spec(): assert utils.parse_anchor_spec("foo=200") == ("foo", "200") assert utils.parse_anchor_spec("foo") is None @@ -25,15 +18,3 @@ def test_parse_anchor_spec(): def test_data_path(): tutils.raises(ValueError, utils.data.path, "nonexistent") - - -def test_inner_repr(): - assert utils.inner_repr("\x66") == "\x66" - assert utils.inner_repr(u"foo") == "foo" - - -def test_escape_unprintables(): - s = "".join([chr(i) for i in range(255)]) - e = utils.escape_unprintables(s) - assert e.encode('ascii') - assert not "PATHOD_MARKER" in e diff --git a/test/pathod/tutils.py b/test/pathod/tutils.py index f6ed3efb..b9f38d86 100644 --- a/test/pathod/tutils.py +++ b/test/pathod/tutils.py @@ -1,12 +1,19 @@ import tempfile import re import shutil +import requests from six.moves import cStringIO as StringIO +import urllib -import netlib -from pathod import utils, test, pathoc, pathod, language from netlib import tcp -import requests +from netlib import utils +from netlib import tutils + +from pathod import language +from pathod import pathoc +from pathod import pathod +from pathod import test + def treader(bytes): """ @@ -57,10 +64,11 @@ class DaemonTests(object): shutil.rmtree(cls.confdir) def teardown(self): + self.d.wait_for_silence() if not (self.noweb or self.noapi): self.d.clear_log() - def getpath(self, path, params=None): + def _getpath(self, path, params=None): scheme = "https" if self.ssl else "http" resp = requests.get( "%s://localhost:%s/%s" % ( @@ -73,9 +81,29 @@ class DaemonTests(object): ) return resp + def getpath(self, path, params=None): + logfp = StringIO() + c = pathoc.Pathoc( + ("localhost", self.d.port), + ssl=self.ssl, + fp=logfp, + ) + with c.connect(): + if params: + path = path + "?" + urllib.urlencode(params) + resp = c.request("get:%s" % path) + return resp + def get(self, spec): - resp = requests.get(self.d.p(spec), verify=False) - return resp + logfp = StringIO() + c = pathoc.Pathoc( + ("localhost", self.d.port), + ssl=self.ssl, + fp=logfp, + ) + with c.connect(): + resp = c.request("get:/p/%s" % urllib.quote(spec).encode("string_escape")) + return resp def pathoc( self, @@ -100,23 +128,23 @@ class DaemonTests(object): fp=logfp, use_http2=use_http2, ) - c.connect(connect_to) - ret = [] - for i in specs: - resp = c.request(i) - if resp: - ret.append(resp) - for frm in c.wait(): - ret.append(frm) - c.stop() - return ret, logfp.getvalue() + with c.connect(connect_to): + ret = [] + for i in specs: + resp = c.request(i) + if resp: + ret.append(resp) + for frm in c.wait(): + ret.append(frm) + c.stop() + return ret, logfp.getvalue() -tmpdir = netlib.tutils.tmpdir +tmpdir = tutils.tmpdir -raises = netlib.tutils.raises +raises = tutils.raises -test_data = netlib.utils.Data(__name__) +test_data = utils.Data(__name__) def render(r, settings=language.Settings()): |