aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/helper_tools/dumperview.py4
-rw-r--r--test/mitmproxy/addons/test_core_option_validation.py43
-rw-r--r--test/mitmproxy/addons/test_dumper.py16
-rw-r--r--test/mitmproxy/addons/test_intercept.py8
-rw-r--r--test/mitmproxy/addons/test_proxyauth.py38
-rw-r--r--test/mitmproxy/addons/test_replace.py24
-rw-r--r--test/mitmproxy/addons/test_setheaders.py14
-rw-r--r--test/mitmproxy/addons/test_streambodies.py7
-rw-r--r--test/mitmproxy/addons/test_streamfile.py6
-rw-r--r--test/mitmproxy/addons/test_termlog.py2
-rw-r--r--test/mitmproxy/addons/test_view.py25
-rw-r--r--test/mitmproxy/net/test_server_spec.py32
-rw-r--r--test/mitmproxy/proxy/protocol/test_http2.py5
-rw-r--r--test/mitmproxy/proxy/protocol/test_websocket.py2
-rw-r--r--test/mitmproxy/proxy/test_config.py21
-rw-r--r--test/mitmproxy/proxy/test_server.py20
-rw-r--r--test/mitmproxy/test_flow.py3
-rw-r--r--test/mitmproxy/test_optmanager.py210
-rw-r--r--test/mitmproxy/test_proxy.py70
-rw-r--r--test/mitmproxy/tools/test_cmdline.py25
-rw-r--r--test/mitmproxy/tools/test_dump.py14
-rw-r--r--test/mitmproxy/tservers.py8
-rw-r--r--test/mitmproxy/utils/test_typecheck.py6
23 files changed, 343 insertions, 260 deletions
diff --git a/test/helper_tools/dumperview.py b/test/helper_tools/dumperview.py
index be56fe14..d417d767 100755
--- a/test/helper_tools/dumperview.py
+++ b/test/helper_tools/dumperview.py
@@ -4,12 +4,12 @@ import click
from mitmproxy.addons import dumper
from mitmproxy.test import tflow
from mitmproxy.test import taddons
-from mitmproxy.tools import dump
+from mitmproxy.tools import options
def show(flow_detail, flows):
d = dumper.Dumper()
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=flow_detail)
for f in flows:
ctx.cycle(d, f)
diff --git a/test/mitmproxy/addons/test_core_option_validation.py b/test/mitmproxy/addons/test_core_option_validation.py
new file mode 100644
index 00000000..0bb2bb0d
--- /dev/null
+++ b/test/mitmproxy/addons/test_core_option_validation.py
@@ -0,0 +1,43 @@
+from mitmproxy import exceptions
+from mitmproxy.addons import core_option_validation
+from mitmproxy.test import taddons
+import pytest
+from unittest import mock
+
+
+def test_simple():
+ sa = core_option_validation.CoreOptionValidation()
+ with taddons.context() as tctx:
+ with pytest.raises(exceptions.OptionsError):
+ tctx.configure(sa, body_size_limit = "invalid")
+ tctx.configure(sa, body_size_limit = "1m")
+ assert tctx.options._processed["body_size_limit"]
+
+ with pytest.raises(exceptions.OptionsError, match="mutually exclusive"):
+ tctx.configure(
+ sa,
+ add_upstream_certs_to_client_chain = True,
+ upstream_cert = False
+ )
+ with pytest.raises(exceptions.OptionsError, match="Invalid mode"):
+ tctx.configure(
+ sa,
+ mode = "Flibble"
+ )
+
+
+@mock.patch("mitmproxy.platform.original_addr", None)
+def test_no_transparent():
+ sa = core_option_validation.CoreOptionValidation()
+ with taddons.context() as tctx:
+ with pytest.raises(Exception, match="Transparent mode not supported"):
+ tctx.configure(sa, mode = "transparent")
+
+
+@mock.patch("mitmproxy.platform.original_addr")
+def test_modes(m):
+ sa = core_option_validation.CoreOptionValidation()
+ with taddons.context() as tctx:
+ tctx.configure(sa, mode = "reverse:http://localhost")
+ with pytest.raises(Exception, match="Invalid server specification"):
+ tctx.configure(sa, mode = "reverse:")
diff --git a/test/mitmproxy/addons/test_dumper.py b/test/mitmproxy/addons/test_dumper.py
index 22d2c2c6..47374617 100644
--- a/test/mitmproxy/addons/test_dumper.py
+++ b/test/mitmproxy/addons/test_dumper.py
@@ -9,13 +9,13 @@ from mitmproxy.test import tutils
from mitmproxy.addons import dumper
from mitmproxy import exceptions
-from mitmproxy.tools import dump
from mitmproxy import http
+from mitmproxy import options
def test_configure():
d = dumper.Dumper()
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, filtstr="~b foo")
assert d.filter
@@ -34,7 +34,7 @@ def test_configure():
def test_simple():
sio = io.StringIO()
d = dumper.Dumper(sio)
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=0)
d.response(tflow.tflow(resp=True))
assert not sio.getvalue()
@@ -103,7 +103,7 @@ def test_echo_body():
sio = io.StringIO()
d = dumper.Dumper(sio)
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=3)
d._echo_message(f.response)
t = sio.getvalue()
@@ -113,7 +113,7 @@ def test_echo_body():
def test_echo_request_line():
sio = io.StringIO()
d = dumper.Dumper(sio)
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=3, showhost=True)
f = tflow.tflow(client_conn=None, server_conn=True, resp=True)
f.request.is_replay = True
@@ -148,7 +148,7 @@ class TestContentView:
view_auto.side_effect = exceptions.ContentViewException("")
sio = io.StringIO()
d = dumper.Dumper(sio)
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=4, verbosity=3)
d.response(tflow.tflow())
assert "Content viewer failed" in ctx.master.event_log[0][1]
@@ -157,7 +157,7 @@ class TestContentView:
def test_tcp():
sio = io.StringIO()
d = dumper.Dumper(sio)
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=3, showhost=True)
f = tflow.ttcpflow()
d.tcp_message(f)
@@ -172,7 +172,7 @@ def test_tcp():
def test_websocket():
sio = io.StringIO()
d = dumper.Dumper(sio)
- with taddons.context(options=dump.Options()) as ctx:
+ with taddons.context(options=options.Options()) as ctx:
ctx.configure(d, flow_detail=3, showhost=True)
f = tflow.twebsocketflow()
d.websocket_message(f)
diff --git a/test/mitmproxy/addons/test_intercept.py b/test/mitmproxy/addons/test_intercept.py
index cf5ba6e8..465e6433 100644
--- a/test/mitmproxy/addons/test_intercept.py
+++ b/test/mitmproxy/addons/test_intercept.py
@@ -7,15 +7,9 @@ from mitmproxy.test import taddons
from mitmproxy.test import tflow
-class Options(options.Options):
- def __init__(self, *, intercept=None, **kwargs):
- self.intercept = intercept
- super().__init__(**kwargs)
-
-
def test_simple():
r = intercept.Intercept()
- with taddons.context(options=Options()) as tctx:
+ with taddons.context(options=options.Options()) as tctx:
assert not r.filt
tctx.configure(r, intercept="~q")
assert r.filt
diff --git a/test/mitmproxy/addons/test_proxyauth.py b/test/mitmproxy/addons/test_proxyauth.py
index dd5829ab..14782755 100644
--- a/test/mitmproxy/addons/test_proxyauth.py
+++ b/test/mitmproxy/addons/test_proxyauth.py
@@ -28,40 +28,43 @@ def test_configure():
up = proxyauth.ProxyAuth()
with taddons.context() as ctx:
with pytest.raises(exceptions.OptionsError):
- ctx.configure(up, auth_singleuser="foo")
+ ctx.configure(up, proxyauth="foo")
- ctx.configure(up, auth_singleuser="foo:bar")
+ ctx.configure(up, proxyauth="foo:bar")
assert up.singleuser == ["foo", "bar"]
- ctx.configure(up, auth_singleuser=None)
+ ctx.configure(up, proxyauth=None)
assert up.singleuser is None
- ctx.configure(up, auth_nonanonymous=True)
+ ctx.configure(up, proxyauth="any")
assert up.nonanonymous
- ctx.configure(up, auth_nonanonymous=False)
+ ctx.configure(up, proxyauth=None)
assert not up.nonanonymous
with pytest.raises(exceptions.OptionsError):
- ctx.configure(up, auth_htpasswd=tutils.test_data.path("mitmproxy/net/data/server.crt"))
+ ctx.configure(
+ up,
+ proxyauth= "@" + tutils.test_data.path("mitmproxy/net/data/server.crt")
+ )
with pytest.raises(exceptions.OptionsError):
- ctx.configure(up, auth_htpasswd="nonexistent")
+ ctx.configure(up, proxyauth="@nonexistent")
ctx.configure(
up,
- auth_htpasswd=tutils.test_data.path(
+ proxyauth= "@" + tutils.test_data.path(
"mitmproxy/net/data/htpasswd"
)
)
assert up.htpasswd
assert up.htpasswd.check_password("test", "test")
assert not up.htpasswd.check_password("test", "foo")
- ctx.configure(up, auth_htpasswd=None)
+ ctx.configure(up, proxyauth=None)
assert not up.htpasswd
with pytest.raises(exceptions.OptionsError):
- ctx.configure(up, auth_nonanonymous=True, mode="transparent")
+ ctx.configure(up, proxyauth="any", mode="transparent")
with pytest.raises(exceptions.OptionsError):
- ctx.configure(up, auth_nonanonymous=True, mode="socks5")
+ ctx.configure(up, proxyauth="any", mode="socks5")
ctx.configure(up, mode="regular")
assert up.mode == "regular"
@@ -70,7 +73,7 @@ def test_configure():
def test_check():
up = proxyauth.ProxyAuth()
with taddons.context() as ctx:
- ctx.configure(up, auth_nonanonymous=True, mode="regular")
+ ctx.configure(up, proxyauth="any", mode="regular")
f = tflow.tflow()
assert not up.check(f)
f.request.headers["Proxy-Authorization"] = proxyauth.mkauth(
@@ -86,18 +89,17 @@ def test_check():
)
assert not up.check(f)
- ctx.configure(up, auth_nonanonymous=False, auth_singleuser="test:test")
+ ctx.configure(up, proxyauth="test:test")
f.request.headers["Proxy-Authorization"] = proxyauth.mkauth(
"test", "test"
)
assert up.check(f)
- ctx.configure(up, auth_nonanonymous=False, auth_singleuser="test:foo")
+ ctx.configure(up, proxyauth="test:foo")
assert not up.check(f)
ctx.configure(
up,
- auth_singleuser=None,
- auth_htpasswd=tutils.test_data.path(
+ proxyauth="@" + tutils.test_data.path(
"mitmproxy/net/data/htpasswd"
)
)
@@ -114,7 +116,7 @@ def test_check():
def test_authenticate():
up = proxyauth.ProxyAuth()
with taddons.context() as ctx:
- ctx.configure(up, auth_nonanonymous=True, mode="regular")
+ ctx.configure(up, proxyauth="any", mode="regular")
f = tflow.tflow()
assert not f.response
@@ -147,7 +149,7 @@ def test_authenticate():
def test_handlers():
up = proxyauth.ProxyAuth()
with taddons.context() as ctx:
- ctx.configure(up, auth_nonanonymous=True, mode="regular")
+ ctx.configure(up, proxyauth="any", mode="regular")
f = tflow.tflow()
assert not f.response
diff --git a/test/mitmproxy/addons/test_replace.py b/test/mitmproxy/addons/test_replace.py
index 126c6e3d..8c280c51 100644
--- a/test/mitmproxy/addons/test_replace.py
+++ b/test/mitmproxy/addons/test_replace.py
@@ -22,11 +22,11 @@ class TestReplace:
def test_configure(self):
r = replace.Replace()
with taddons.context() as tctx:
- tctx.configure(r, replacements=[("one", "two", "three")])
+ tctx.configure(r, replacements=["one/two/three"])
with pytest.raises(Exception, match="Invalid filter pattern"):
- tctx.configure(r, replacements=[("~b", "two", "three")])
+ tctx.configure(r, replacements=["/~b/two/three"])
with pytest.raises(Exception, match="Invalid regular expression"):
- tctx.configure(r, replacements=[("foo", "+", "three")])
+ tctx.configure(r, replacements=["/foo/+/three"])
tctx.configure(r, replacements=["/a/b/c/"])
def test_simple(self):
@@ -35,8 +35,8 @@ class TestReplace:
tctx.configure(
r,
replacements = [
- ("~q", "foo", "bar"),
- ("~s", "foo", "bar"),
+ "/~q/foo/bar",
+ "/~s/foo/bar",
]
)
f = tflow.tflow()
@@ -58,10 +58,10 @@ class TestUpstreamProxy(tservers.HTTPUpstreamProxyTest):
self.proxy.tmaster.addons.add(sa)
self.proxy.tmaster.options.replacements = [
- ("~q", "foo", "bar"),
- ("~q", "bar", "baz"),
- ("~q", "foo", "oh noes!"),
- ("~s", "baz", "ORLY")
+ "/~q/foo/bar",
+ "/~q/bar/baz",
+ "/~q/foo/oh noes!",
+ "/~s/baz/ORLY"
]
p = self.pathoc()
with p.connect():
@@ -81,9 +81,9 @@ class TestReplaceFile:
tctx.configure(
r,
replacement_files = [
- ("~q", "foo", rp),
- ("~s", "foo", rp),
- ("~b nonexistent", "nonexistent", "nonexistent"),
+ "/~q/foo/" + rp,
+ "/~s/foo/" + rp,
+ "/~b nonexistent/nonexistent/nonexistent",
]
)
f = tflow.tflow()
diff --git a/test/mitmproxy/addons/test_setheaders.py b/test/mitmproxy/addons/test_setheaders.py
index 6355f2be..3aaee7f4 100644
--- a/test/mitmproxy/addons/test_setheaders.py
+++ b/test/mitmproxy/addons/test_setheaders.py
@@ -21,7 +21,7 @@ class TestSetHeaders:
sh = setheaders.SetHeaders()
with taddons.context() as tctx:
with pytest.raises(Exception, match="Invalid setheader filter pattern"):
- tctx.configure(sh, setheaders = [("~b", "one", "two")])
+ tctx.configure(sh, setheaders = ["/~b/one/two"])
tctx.configure(sh, setheaders = ["/foo/bar/voing"])
def test_setheaders(self):
@@ -30,8 +30,8 @@ class TestSetHeaders:
tctx.configure(
sh,
setheaders = [
- ("~q", "one", "two"),
- ("~s", "one", "three")
+ "/~q/one/two",
+ "/~s/one/three"
]
)
f = tflow.tflow()
@@ -47,8 +47,8 @@ class TestSetHeaders:
tctx.configure(
sh,
setheaders = [
- ("~s", "one", "two"),
- ("~s", "one", "three")
+ "/~s/one/two",
+ "/~s/one/three"
]
)
f = tflow.tflow(resp=True)
@@ -60,8 +60,8 @@ class TestSetHeaders:
tctx.configure(
sh,
setheaders = [
- ("~q", "one", "two"),
- ("~q", "one", "three")
+ "/~q/one/two",
+ "/~q/one/three"
]
)
f = tflow.tflow()
diff --git a/test/mitmproxy/addons/test_streambodies.py b/test/mitmproxy/addons/test_streambodies.py
index b982c66d..c6ce5e81 100644
--- a/test/mitmproxy/addons/test_streambodies.py
+++ b/test/mitmproxy/addons/test_streambodies.py
@@ -1,13 +1,16 @@
+from mitmproxy import exceptions
from mitmproxy.test import tflow
from mitmproxy.test import taddons
-
from mitmproxy.addons import streambodies
+import pytest
def test_simple():
sa = streambodies.StreamBodies()
with taddons.context() as tctx:
- tctx.configure(sa, stream_large_bodies = 10)
+ with pytest.raises(exceptions.OptionsError):
+ tctx.configure(sa, stream_large_bodies = "invalid")
+ tctx.configure(sa, stream_large_bodies = "10")
f = tflow.tflow()
f.request.content = b""
diff --git a/test/mitmproxy/addons/test_streamfile.py b/test/mitmproxy/addons/test_streamfile.py
index 4922fc0b..4105c1fc 100644
--- a/test/mitmproxy/addons/test_streamfile.py
+++ b/test/mitmproxy/addons/test_streamfile.py
@@ -7,13 +7,13 @@ from mitmproxy.test import taddons
from mitmproxy import io
from mitmproxy import exceptions
-from mitmproxy.tools import dump
+from mitmproxy import options
from mitmproxy.addons import streamfile
def test_configure():
sa = streamfile.StreamFile()
- with taddons.context(options=dump.Options()) as tctx:
+ with taddons.context(options=options.Options()) as tctx:
with tutils.tmpdir() as tdir:
p = os.path.join(tdir, "foo")
with pytest.raises(exceptions.OptionsError):
@@ -59,7 +59,7 @@ def test_simple():
tctx.configure(sa, streamfile=None)
assert rd(p)[0].response
- tctx.configure(sa, streamfile=p, streamfile_append=True)
+ tctx.configure(sa, streamfile="+" + p)
f = tflow.tflow()
sa.request(f)
tctx.configure(sa, streamfile=None)
diff --git a/test/mitmproxy/addons/test_termlog.py b/test/mitmproxy/addons/test_termlog.py
index 70c3a7f2..2133b74d 100644
--- a/test/mitmproxy/addons/test_termlog.py
+++ b/test/mitmproxy/addons/test_termlog.py
@@ -3,7 +3,7 @@ import pytest
from mitmproxy.addons import termlog
from mitmproxy import log
-from mitmproxy.tools.dump import Options
+from mitmproxy.options import Options
from mitmproxy.test import taddons
diff --git a/test/mitmproxy/addons/test_view.py b/test/mitmproxy/addons/test_view.py
index a063416f..b7842314 100644
--- a/test/mitmproxy/addons/test_view.py
+++ b/test/mitmproxy/addons/test_view.py
@@ -15,23 +15,6 @@ def tft(*, method="get", start=0):
return f
-class Options(options.Options):
- def __init__(
- self,
- *,
- filter=None,
- console_order=None,
- console_order_reversed=False,
- console_focus_follow=False,
- **kwargs
- ):
- self.filter = filter
- self.console_order = console_order
- self.console_order_reversed = console_order_reversed
- self.console_focus_follow = console_focus_follow
- super().__init__(**kwargs)
-
-
def test_order_refresh():
v = view.View()
sargs = []
@@ -42,7 +25,7 @@ def test_order_refresh():
v.sig_view_refresh.connect(save)
tf = tflow.tflow(resp=True)
- with taddons.context(options=Options()) as tctx:
+ with taddons.context(options=options.Options()) as tctx:
tctx.configure(v, console_order="time")
v.add(tf)
tf.request.timestamp_start = 1
@@ -149,7 +132,7 @@ def test_filter():
def test_order():
v = view.View()
- with taddons.context(options=Options()) as tctx:
+ with taddons.context(options=options.Options()) as tctx:
v.request(tft(method="get", start=1))
v.request(tft(method="put", start=2))
v.request(tft(method="get", start=3))
@@ -280,7 +263,7 @@ def test_signals():
def test_focus_follow():
v = view.View()
- with taddons.context(options=Options()) as tctx:
+ with taddons.context(options=options.Options()) as tctx:
tctx.configure(v, console_focus_follow=True, filter="~m get")
v.add(tft(start=5))
@@ -394,7 +377,7 @@ def test_settings():
def test_configure():
v = view.View()
- with taddons.context(options=Options()) as tctx:
+ with taddons.context(options=options.Options()) as tctx:
tctx.configure(v, filter="~q")
with pytest.raises(Exception, match="Invalid interception filter"):
tctx.configure(v, filter="~~")
diff --git a/test/mitmproxy/net/test_server_spec.py b/test/mitmproxy/net/test_server_spec.py
new file mode 100644
index 00000000..095ad519
--- /dev/null
+++ b/test/mitmproxy/net/test_server_spec.py
@@ -0,0 +1,32 @@
+import pytest
+
+from mitmproxy.net import server_spec
+
+
+def test_parse():
+ assert server_spec.parse("example.com") == ("https", ("example.com", 443))
+ assert server_spec.parse("example.com") == ("https", ("example.com", 443))
+ assert server_spec.parse("http://example.com") == ("http", ("example.com", 80))
+ assert server_spec.parse("http://127.0.0.1") == ("http", ("127.0.0.1", 80))
+ assert server_spec.parse("http://[::1]") == ("http", ("::1", 80))
+ assert server_spec.parse("http://[::1]/") == ("http", ("::1", 80))
+ assert server_spec.parse("https://[::1]/") == ("https", ("::1", 443))
+ assert server_spec.parse("http://[::1]:8080") == ("http", ("::1", 8080))
+
+ with pytest.raises(ValueError, match="Invalid server specification"):
+ server_spec.parse(":")
+
+ with pytest.raises(ValueError, match="Invalid server scheme"):
+ server_spec.parse("ftp://example.com")
+
+ with pytest.raises(ValueError, match="Invalid hostname"):
+ server_spec.parse("$$$")
+
+ with pytest.raises(ValueError, match="Invalid port"):
+ server_spec.parse("example.com:999999")
+
+
+def test_parse_with_mode():
+ assert server_spec.parse_with_mode("m:example.com") == ("m", ("https", ("example.com", 443)))
+ with pytest.raises(ValueError):
+ server_spec.parse_with_mode("moo")
diff --git a/test/mitmproxy/proxy/protocol/test_http2.py b/test/mitmproxy/proxy/protocol/test_http2.py
index 871d02fe..1f695cc5 100644
--- a/test/mitmproxy/proxy/protocol/test_http2.py
+++ b/test/mitmproxy/proxy/protocol/test_http2.py
@@ -100,7 +100,7 @@ class _Http2TestBase:
def get_options(cls):
opts = options.Options(
listen_port=0,
- no_upstream_cert=False,
+ upstream_cert=True,
ssl_insecure=True
)
opts.cadir = os.path.join(tempfile.gettempdir(), "mitmproxy")
@@ -499,7 +499,8 @@ class TestBodySizeLimit(_Http2Test):
return True
def test_body_size_limit(self):
- self.config.options.body_size_limit = 20
+ self.config.options.body_size_limit = "20"
+ self.config.options._processed["body_size_limit"] = 20
client, h2_conn = self._setup_connection()
diff --git a/test/mitmproxy/proxy/protocol/test_websocket.py b/test/mitmproxy/proxy/protocol/test_websocket.py
index bac0e527..486e9d64 100644
--- a/test/mitmproxy/proxy/protocol/test_websocket.py
+++ b/test/mitmproxy/proxy/protocol/test_websocket.py
@@ -64,7 +64,7 @@ class _WebSocketTestBase:
def get_options(cls):
opts = options.Options(
listen_port=0,
- no_upstream_cert=False,
+ upstream_cert=True,
ssl_insecure=True,
websocket=True,
)
diff --git a/test/mitmproxy/proxy/test_config.py b/test/mitmproxy/proxy/test_config.py
index 4272d952..777ab4dd 100644
--- a/test/mitmproxy/proxy/test_config.py
+++ b/test/mitmproxy/proxy/test_config.py
@@ -1,20 +1 @@
-import pytest
-from mitmproxy.proxy import config
-
-
-def test_parse_server_spec():
- with pytest.raises(Exception, match="Invalid server specification"):
- config.parse_server_spec("")
- assert config.parse_server_spec("http://foo.com:88") == (
- "http", ("foo.com", 88)
- )
- assert config.parse_server_spec("http://foo.com") == (
- "http", ("foo.com", 80)
- )
- assert config.parse_server_spec("https://foo.com") == (
- "https", ("foo.com", 443)
- )
- with pytest.raises(Exception, match="Invalid server specification"):
- config.parse_server_spec("foo.com")
- with pytest.raises(Exception, match="Invalid server specification"):
- config.parse_server_spec("http://")
+# TODO: write tests
diff --git a/test/mitmproxy/proxy/test_server.py b/test/mitmproxy/proxy/test_server.py
index 56b09b9a..aa45761a 100644
--- a/test/mitmproxy/proxy/test_server.py
+++ b/test/mitmproxy/proxy/test_server.py
@@ -10,7 +10,7 @@ from mitmproxy import options
from mitmproxy.addons import script
from mitmproxy.addons import proxyauth
from mitmproxy import http
-from mitmproxy.proxy.config import HostMatcher, parse_server_spec
+from mitmproxy.proxy.config import HostMatcher
import mitmproxy.net.http
from mitmproxy.net import tcp
from mitmproxy.net import socks
@@ -302,7 +302,7 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin):
class TestHTTPAuth(tservers.HTTPProxyTest):
def test_auth(self):
self.master.addons.add(proxyauth.ProxyAuth())
- self.master.options.auth_singleuser = "test:test"
+ self.master.options.proxyauth = "test:test"
assert self.pathod("202").status_code == 407
p = self.pathoc()
with p.connect():
@@ -321,7 +321,7 @@ class TestHTTPAuth(tservers.HTTPProxyTest):
class TestHTTPReverseAuth(tservers.ReverseProxyTest):
def test_auth(self):
self.master.addons.add(proxyauth.ProxyAuth())
- self.master.options.auth_singleuser = "test:test"
+ self.master.options.proxyauth = "test:test"
assert self.pathod("202").status_code == 401
p = self.pathoc()
with p.connect():
@@ -342,22 +342,22 @@ class TestHTTPS(tservers.HTTPProxyTest, CommonMixin, TcpMixin):
def test_clientcert_file(self):
try:
- self.config.clientcerts = os.path.join(
+ self.config.client_certs = os.path.join(
tutils.test_data.path("mitmproxy/data/clientcert"), "client.pem")
f = self.pathod("304")
assert f.status_code == 304
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
finally:
- self.config.clientcerts = None
+ self.config.client_certs = None
def test_clientcert_dir(self):
try:
- self.config.clientcerts = tutils.test_data.path("mitmproxy/data/clientcert")
+ self.config.client_certs = tutils.test_data.path("mitmproxy/data/clientcert")
f = self.pathod("304")
assert f.status_code == 304
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
finally:
- self.config.clientcerts = None
+ self.config.client_certs = None
def test_error_post_connect(self):
p = self.pathoc()
@@ -579,8 +579,6 @@ class TestHttps2Http(tservers.ReverseProxyTest):
@classmethod
def get_options(cls):
opts = super().get_options()
- s = parse_server_spec(opts.upstream_server)
- opts.upstream_server = "http://{}:{}".format(s.address[0], s.address[1])
return opts
def pathoc(self, ssl, sni=None):
@@ -870,11 +868,11 @@ class TestServerConnect(tservers.HTTPProxyTest):
@classmethod
def get_options(cls):
opts = tservers.HTTPProxyTest.get_options()
- opts.no_upstream_cert = True
+ opts.upstream_cert = False
return opts
def test_unnecessary_serverconnect(self):
- """A replayed/fake response with no_upstream_cert should not connect to an upstream server"""
+ """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.tlog:
assert "serverconnect" not in msg
diff --git a/test/mitmproxy/test_flow.py b/test/mitmproxy/test_flow.py
index 0ac3bfd6..f4d32cbb 100644
--- a/test/mitmproxy/test_flow.py
+++ b/test/mitmproxy/test_flow.py
@@ -63,8 +63,7 @@ class TestSerialize:
r = self._treader()
s = tservers.TestState()
opts = options.Options(
- mode="reverse",
- upstream_server="https://use-this-domain"
+ mode="reverse:https://use-this-domain"
)
conf = ProxyConfig(opts)
fm = master.Master(opts, DummyServer(conf))
diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py
index 161b0dcf..db33cddd 100644
--- a/test/mitmproxy/test_optmanager.py
+++ b/test/mitmproxy/test_optmanager.py
@@ -1,6 +1,8 @@
import copy
import os
import pytest
+import typing
+import argparse
from mitmproxy import options
from mitmproxy import optmanager
@@ -9,48 +11,51 @@ from mitmproxy.test import tutils
class TO(optmanager.OptManager):
- def __init__(self, one=None, two=None):
- self.one = one
- self.two = two
+ def __init__(self):
super().__init__()
+ self.add_option("one", typing.Optional[int], None, "help")
+ self.add_option("two", typing.Optional[int], 2, "help")
+ self.add_option("bool", bool, False, "help")
class TD(optmanager.OptManager):
- def __init__(self, *, one="done", two="dtwo", three="error"):
- self.one = one
- self.two = two
- self.three = three
+ def __init__(self):
super().__init__()
+ self.add_option("one", str, "done", "help")
+ self.add_option("two", str, "dtwo", "help")
class TD2(TD):
- def __init__(self, *, three="dthree", four="dfour", **kwargs):
- self.three = three
- self.four = four
- super().__init__(three=three, **kwargs)
+ def __init__(self):
+ super().__init__()
+ self.add_option("three", str, "dthree", "help")
+ self.add_option("four", str, "dfour", "help")
class TM(optmanager.OptManager):
- def __init__(self, one="one", two=["foo"], three=None):
- self.one = one
- self.two = two
- self.three = three
+ def __init__(self):
super().__init__()
+ self.add_option("two", typing.Sequence[str], ["foo"], "help")
+ self.add_option("one", typing.Optional[str], None, "help")
-def test_defaults():
- assert TD2.default("one") == "done"
- assert TD2.default("two") == "dtwo"
- assert TD2.default("three") == "dthree"
- assert TD2.default("four") == "dfour"
+def test_add_option():
+ o = TO()
+ with pytest.raises(ValueError, match="already exists"):
+ o.add_option("one", typing.Optional[int], None, "help")
+
+def test_defaults():
o = TD2()
- assert o._defaults == {
+ defaults = {
"one": "done",
"two": "dtwo",
"three": "dthree",
"four": "dfour",
}
+ for k, v in defaults.items():
+ assert o.default(k) == v
+
assert not o.has_changed("one")
newvals = dict(
one="xone",
@@ -64,18 +69,19 @@ def test_defaults():
assert v == getattr(o, k)
o.reset()
assert not o.has_changed("one")
- for k, v in o._defaults.items():
- assert v == getattr(o, k)
+
+ for k in o.keys():
+ assert not o.has_changed(k)
def test_options():
- o = TO(two="three")
- assert o.keys() == set(["one", "two"])
+ o = TO()
+ assert o.keys() == {"bool", "one", "two"}
assert o.one is None
- assert o.two == "three"
- o.one = "one"
- assert o.one == "one"
+ assert o.two == 2
+ o.one = 1
+ assert o.one == 1
with pytest.raises(TypeError):
TO(nonexistent = "value")
@@ -91,34 +97,38 @@ def test_options():
o.changed.connect(sub)
- o.one = "ninety"
+ o.one = 90
assert len(rec) == 1
- assert rec[-1].one == "ninety"
+ assert rec[-1].one == 90
- o.update(one="oink")
+ o.update(one=3)
assert len(rec) == 2
- assert rec[-1].one == "oink"
+ assert rec[-1].one == 3
def test_setter():
- o = TO(two="three")
+ o = TO()
f = o.setter("two")
- f("xxx")
- assert o.two == "xxx"
+ f(99)
+ assert o.two == 99
with pytest.raises(Exception, match="No such option"):
o.setter("nonexistent")
def test_toggler():
- o = TO(two=True)
- f = o.toggler("two")
+ o = TO()
+ f = o.toggler("bool")
+ assert o.bool is False
f()
- assert o.two is False
+ assert o.bool is True
f()
- assert o.two is True
+ assert o.bool is False
with pytest.raises(Exception, match="No such option"):
o.toggler("nonexistent")
+ with pytest.raises(Exception, match="boolean options"):
+ o.toggler("one")
+
class Rec():
def __init__(self):
@@ -132,19 +142,19 @@ def test_subscribe():
o = TO()
r = Rec()
o.subscribe(r, ["two"])
- o.one = "foo"
+ o.one = 2
assert not r.called
- o.two = "foo"
+ o.two = 3
assert r.called
assert len(o.changed.receivers) == 1
del r
- o.two = "bar"
+ o.two = 4
assert len(o.changed.receivers) == 0
def test_rollback():
- o = TO(one="two")
+ o = TO()
rec = []
@@ -157,27 +167,35 @@ def test_rollback():
recerr.append(kwargs)
def err(opts, updated):
- if opts.one == "ten":
+ if opts.one == 10:
+ raise exceptions.OptionsError()
+ if opts.bool is True:
raise exceptions.OptionsError()
o.changed.connect(sub)
o.changed.connect(err)
o.errored.connect(errsub)
- o.one = "ten"
+ assert o.one is None
+ o.one = 10
+ o.bool = True
assert isinstance(recerr[0]["exc"], exceptions.OptionsError)
- assert o.one == "two"
- assert len(rec) == 2
- assert rec[0].one == "ten"
- assert rec[1].one == "two"
+ assert o.one is None
+ assert o.bool is False
+ assert len(rec) == 4
+ assert rec[0].one == 10
+ assert rec[1].one is None
+ assert rec[2].bool is True
+ assert rec[3].bool is False
+
+ with pytest.raises(exceptions.OptionsError):
+ with o.rollback({"one"}, reraise=True):
+ raise exceptions.OptionsError()
-def test_repr():
- assert repr(TO()) == "test.mitmproxy.test_optmanager.TO({'one': None, 'two': None})"
- assert repr(TO(one='x' * 60)) == """test.mitmproxy.test_optmanager.TO({
- 'one': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
- 'two': None
-})"""
+def test_simple():
+ assert repr(TO())
+ assert "one" in TO()
def test_serialize():
@@ -249,3 +267,85 @@ def test_merge():
assert m.one == "two"
m.merge(dict(two=["bar"]))
assert m.two == ["foo", "bar"]
+
+
+def test_option():
+ o = optmanager._Option("test", int, 1, None, None)
+ assert o.current() == 1
+ with pytest.raises(TypeError):
+ o.set("foo")
+ with pytest.raises(TypeError):
+ optmanager._Option("test", str, 1, None, None)
+
+ o2 = optmanager._Option("test", int, 1, None, None)
+ assert o2 == o
+ o2.set(5)
+ assert o2 != o
+
+
+def test_dump():
+ o = options.Options()
+ assert optmanager.dump(o)
+
+
+class TTypes(optmanager.OptManager):
+ def __init__(self):
+ super().__init__()
+ self.add_option("str", str, "str", "help")
+ self.add_option("optstr", typing.Optional[str], "optstr", "help", "help")
+ self.add_option("bool", bool, False, "help")
+ self.add_option("bool_on", bool, True, "help")
+ self.add_option("int", int, 0, "help")
+ self.add_option("optint", typing.Optional[int], 0, "help")
+ self.add_option("seqstr", typing.Sequence[str], [], "help")
+ self.add_option("unknown", float, 0.0, "help")
+
+
+def test_make_parser():
+ parser = argparse.ArgumentParser()
+ opts = TTypes()
+ opts.make_parser(parser, "str", short="a")
+ opts.make_parser(parser, "bool", short="b")
+ opts.make_parser(parser, "int", short="c")
+ opts.make_parser(parser, "seqstr", short="d")
+ opts.make_parser(parser, "bool_on", short="e")
+ with pytest.raises(ValueError):
+ opts.make_parser(parser, "unknown")
+
+
+def test_set():
+ opts = TTypes()
+
+ opts.set("str=foo")
+ assert opts.str == "foo"
+ with pytest.raises(TypeError):
+ opts.set("str")
+
+ opts.set("optstr=foo")
+ assert opts.optstr == "foo"
+ opts.set("optstr")
+ assert opts.optstr is None
+
+ opts.set("bool=false")
+ assert opts.bool is False
+ opts.set("bool")
+ assert opts.bool is True
+ opts.set("bool=true")
+ assert opts.bool is True
+ with pytest.raises(exceptions.OptionsError):
+ opts.set("bool=wobble")
+
+ opts.set("int=1")
+ assert opts.int == 1
+ with pytest.raises(exceptions.OptionsError):
+ opts.set("int=wobble")
+ opts.set("optint")
+ assert opts.optint is None
+
+ assert opts.seqstr == []
+ opts.set("seqstr=foo")
+ assert opts.seqstr == ["foo"]
+ opts.set("seqstr=bar")
+ assert opts.seqstr == ["foo", "bar"]
+ opts.set("seqstr")
+ assert opts.seqstr == []
diff --git a/test/mitmproxy/test_proxy.py b/test/mitmproxy/test_proxy.py
index 37cec57a..7a49c530 100644
--- a/test/mitmproxy/test_proxy.py
+++ b/test/mitmproxy/test_proxy.py
@@ -1,4 +1,3 @@
-import os
import argparse
from unittest import mock
from OpenSSL import SSL
@@ -6,6 +5,7 @@ import pytest
from mitmproxy.tools import cmdline
+from mitmproxy.tools import main
from mitmproxy import options
from mitmproxy.proxy import ProxyConfig
from mitmproxy.proxy.server import DummyServer, ProxyServer, ConnectionHandler
@@ -30,10 +30,10 @@ class TestProcessProxyOptions:
def p(self, *args):
parser = MockParser()
- cmdline.common_options(parser)
- args = parser.parse_args(args=args)
opts = options.Options()
- opts.merge(cmdline.get_common_options(args))
+ cmdline.common_options(parser, opts)
+ args = parser.parse_args(args=args)
+ main.process_options(parser, opts, args)
pconf = config.ProxyConfig(opts)
return parser, pconf
@@ -45,44 +45,6 @@ class TestProcessProxyOptions:
def test_simple(self):
assert self.p()
- def test_cadir(self):
- with tutils.tmpdir() as cadir:
- self.assert_noerr("--cadir", cadir)
-
- @mock.patch("mitmproxy.platform.original_addr", None)
- def test_no_transparent(self):
- with pytest.raises(Exception, match="Transparent mode not supported"):
- self.p("-T")
-
- @mock.patch("mitmproxy.platform.original_addr")
- def test_modes(self, _):
- self.assert_noerr("-R", "http://localhost")
- with pytest.raises(Exception, match="expected one argument"):
- self.p("-R")
- with pytest.raises(Exception, match="Invalid server specification"):
- self.p("-R", "reverse")
-
- self.assert_noerr("-T")
-
- self.assert_noerr("-U", "http://localhost")
- with pytest.raises(Exception, match="Invalid server specification"):
- self.p("-U", "upstream")
-
- self.assert_noerr("--upstream-auth", "test:test")
- with pytest.raises(Exception, match="expected one argument"):
- self.p("--upstream-auth")
- with pytest.raises(Exception, match="mutually exclusive"):
- self.p("-R", "http://localhost", "-T")
-
- def test_client_certs(self):
- with tutils.tmpdir() as cadir:
- self.assert_noerr("--client-certs", cadir)
- self.assert_noerr(
- "--client-certs",
- os.path.join(tutils.test_data.path("mitmproxy/data/clientcert"), "client.pem"))
- with pytest.raises(Exception, match="path does not exist"):
- self.p("--client-certs", "nonexistent")
-
def test_certs(self):
self.assert_noerr(
"--cert",
@@ -91,19 +53,9 @@ class TestProcessProxyOptions:
self.p("--cert", "nonexistent")
def test_insecure(self):
- p = self.assert_noerr("--insecure")
+ p = self.assert_noerr("--ssl-insecure")
assert p.openssl_verification_mode_server == SSL.VERIFY_NONE
- def test_upstream_trusted_cadir(self):
- expected_dir = "/path/to/a/ca/dir"
- p = self.assert_noerr("--upstream-trusted-cadir", expected_dir)
- assert p.options.ssl_verify_upstream_trusted_cadir == expected_dir
-
- def test_upstream_trusted_ca(self):
- expected_file = "/path/to/a/cert/file"
- p = self.assert_noerr("--upstream-trusted-ca", expected_file)
- assert p.options.ssl_verify_upstream_trusted_ca == expected_file
-
class TestProxyServer:
@@ -131,19 +83,19 @@ class TestDummyServer:
class TestConnectionHandler:
def test_fatal_error(self, capsys):
- config = mock.Mock()
- root_layer = mock.Mock()
- root_layer.side_effect = RuntimeError
- config.options.mode.return_value = root_layer
+ opts = options.Options()
+ pconf = config.ProxyConfig(opts)
+
channel = mock.Mock()
def ask(_, x):
- return x
+ raise RuntimeError
+
channel.ask = ask
c = ConnectionHandler(
mock.MagicMock(),
("127.0.0.1", 8080),
- config,
+ pconf,
channel
)
c.handle()
diff --git a/test/mitmproxy/tools/test_cmdline.py b/test/mitmproxy/tools/test_cmdline.py
index 96d5ae31..65cfeb07 100644
--- a/test/mitmproxy/tools/test_cmdline.py
+++ b/test/mitmproxy/tools/test_cmdline.py
@@ -1,31 +1,30 @@
import argparse
from mitmproxy.tools import cmdline
+from mitmproxy.tools import main
+from mitmproxy import options
def test_common():
parser = argparse.ArgumentParser()
- cmdline.common_options(parser)
- opts = parser.parse_args(args=[])
-
- assert cmdline.get_common_options(opts)
-
- opts.stickycookie_filt = "foo"
- opts.stickyauth_filt = "foo"
- v = cmdline.get_common_options(opts)
- assert v["stickycookie"] == "foo"
- assert v["stickyauth"] == "foo"
+ opts = options.Options()
+ cmdline.common_options(parser, opts)
+ args = parser.parse_args(args=[])
+ assert main.process_options(parser, opts, args)
def test_mitmproxy():
- ap = cmdline.mitmproxy()
+ opts = options.Options()
+ ap = cmdline.mitmproxy(opts)
assert ap
def test_mitmdump():
- ap = cmdline.mitmdump()
+ opts = options.Options()
+ ap = cmdline.mitmdump(opts)
assert ap
def test_mitmweb():
- ap = cmdline.mitmweb()
+ opts = options.Options()
+ ap = cmdline.mitmweb(opts)
assert ap
diff --git a/test/mitmproxy/tools/test_dump.py b/test/mitmproxy/tools/test_dump.py
index b4183725..2542ec4b 100644
--- a/test/mitmproxy/tools/test_dump.py
+++ b/test/mitmproxy/tools/test_dump.py
@@ -3,8 +3,10 @@ import pytest
from unittest import mock
from mitmproxy import proxy
+from mitmproxy import exceptions
from mitmproxy import log
from mitmproxy import controller
+from mitmproxy import options
from mitmproxy.tools import dump
from mitmproxy.test import tutils
@@ -12,8 +14,8 @@ from .. import tservers
class TestDumpMaster(tservers.MasterTest):
- def mkmaster(self, flt, **options):
- o = dump.Options(filtstr=flt, verbosity=-1, flow_detail=0, **options)
+ def mkmaster(self, flt, **opts):
+ o = options.Options(filtstr=flt, verbosity=-1, flow_detail=0, **opts)
m = dump.DumpMaster(o, proxy.DummyServer(), with_termlog=False, with_dumper=False)
return m
@@ -25,9 +27,9 @@ class TestDumpMaster(tservers.MasterTest):
self.mkmaster(None, rfile=p),
1, b"",
)
- with pytest.raises(dump.DumpError):
+ with pytest.raises(exceptions.OptionsError):
self.mkmaster(None, rfile="/nonexistent")
- with pytest.raises(dump.DumpError):
+ with pytest.raises(exceptions.OptionsError):
self.mkmaster(None, rfile="test_dump.py")
def test_has_error(self):
@@ -40,13 +42,13 @@ class TestDumpMaster(tservers.MasterTest):
@pytest.mark.parametrize("termlog", [False, True])
def test_addons_termlog(self, termlog):
with mock.patch('sys.stdout'):
- o = dump.Options()
+ o = options.Options()
m = dump.DumpMaster(o, proxy.DummyServer(), with_termlog=termlog)
assert (m.addons.get('termlog') is not None) == termlog
@pytest.mark.parametrize("dumper", [False, True])
def test_addons_dumper(self, dumper):
with mock.patch('sys.stdout'):
- o = dump.Options()
+ o = options.Options()
m = dump.DumpMaster(o, proxy.DummyServer(), with_dumper=dumper)
assert (m.addons.get('dumper') is not None) == dumper
diff --git a/test/mitmproxy/tservers.py b/test/mitmproxy/tservers.py
index 9a289ae5..a8aaa358 100644
--- a/test/mitmproxy/tservers.py
+++ b/test/mitmproxy/tservers.py
@@ -288,7 +288,7 @@ class ReverseProxyTest(ProxyTestBase):
@classmethod
def get_options(cls):
opts = ProxyTestBase.get_options()
- opts.upstream_server = "".join(
+ s = "".join(
[
"https" if cls.ssl else "http",
"://",
@@ -296,7 +296,7 @@ class ReverseProxyTest(ProxyTestBase):
str(cls.server.port)
]
)
- opts.mode = "reverse"
+ opts.mode = "reverse:" + s
return opts
def pathoc(self, sni=None):
@@ -373,9 +373,9 @@ class ChainProxyTest(ProxyTestBase):
def get_options(cls):
opts = super().get_options()
if cls.chain: # First proxy is in normal mode.
+ s = "http://127.0.0.1:%s" % cls.chain[0].port
opts.update(
- mode="upstream",
- upstream_server="http://127.0.0.1:%s" % cls.chain[0].port
+ mode="upstream:" + s,
)
return opts
diff --git a/test/mitmproxy/utils/test_typecheck.py b/test/mitmproxy/utils/test_typecheck.py
index 67981be4..d99a914f 100644
--- a/test/mitmproxy/utils/test_typecheck.py
+++ b/test/mitmproxy/utils/test_typecheck.py
@@ -16,12 +16,6 @@ class T(TBase):
super(T, self).__init__(42)
-def test_get_arg_type_from_constructor_annotation():
- assert typecheck.get_arg_type_from_constructor_annotation(T, "foo") == str
- assert typecheck.get_arg_type_from_constructor_annotation(T, "bar") == int
- assert not typecheck.get_arg_type_from_constructor_annotation(T, "baz")
-
-
def test_check_type():
typecheck.check_type("foo", 42, int)
with pytest.raises(TypeError):