Skip to content

Commit 1e7a2f0

Browse files
tests: add test_url_opener.py
Signed-off-by: John Mulligan <[email protected]>
1 parent fb13460 commit 1e7a2f0

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

tests/test_url_opener.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#
2+
# sambacc: a samba container configuration tool
3+
# Copyright (C) 2023 John Mulligan
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>
17+
#
18+
19+
import errno
20+
import http
21+
import http.server
22+
import os
23+
import sys
24+
import threading
25+
import urllib.request
26+
27+
import pytest
28+
29+
import sambacc.url_opener
30+
31+
32+
class _Server:
33+
def __init__(self, port=8111):
34+
port = int(os.environ.get("SAMBACC_TEST_HTTP_PORT", port))
35+
self._port = port
36+
self._server = http.server.HTTPServer(("127.0.0.1", port), _Handler)
37+
38+
@property
39+
def port(self):
40+
return self._port
41+
42+
def start(self):
43+
self._t = threading.Thread(target=self._server.serve_forever)
44+
self._t.start()
45+
46+
def stop(self):
47+
sys.stdout.flush()
48+
self._server.shutdown()
49+
self._t.join()
50+
51+
52+
class _Handler(http.server.BaseHTTPRequestHandler):
53+
def do_GET(self):
54+
word = self.path.split("/")[-1]
55+
method = f"get_{word}"
56+
return getattr(self, method)()
57+
58+
def get_a(self):
59+
return self._ok("Wilbur was Right")
60+
61+
def get_b(self):
62+
return self._ok("This is a test")
63+
64+
def get_err404(self):
65+
self._err(http.HTTPStatus.NOT_FOUND, "Not Found")
66+
67+
def get_err401(self):
68+
self._err(http.HTTPStatus.UNAUTHORIZED, "Unauthorized")
69+
70+
def get_err403(self):
71+
self._err(http.HTTPStatus.FORBIDDEN, "Forbidden")
72+
73+
def _ok(self, value):
74+
self.send_response(http.HTTPStatus.OK)
75+
self.send_header("Content-Type", "text/plain")
76+
self.send_header("Content-Length", str(len(value)))
77+
self.end_headers()
78+
self.wfile.write(value.encode("utf8"))
79+
80+
def _err(self, err_value, err_msg):
81+
self.send_response(err_value)
82+
self.send_header("Content-Type", "text/plain")
83+
self.send_header("Content-Length", str(len(err_msg)))
84+
self.end_headers()
85+
self.wfile.write(err_msg.encode("utf8"))
86+
87+
88+
@pytest.fixture(scope="module")
89+
def http_server():
90+
srv = _Server()
91+
srv.start()
92+
try:
93+
yield srv
94+
finally:
95+
srv.stop()
96+
97+
98+
def test_success_1(http_server):
99+
url = f"http://localhost:{http_server.port}/a"
100+
opener = sambacc.url_opener.URLOpener()
101+
res = opener.open(url)
102+
assert res.read() == b"Wilbur was Right"
103+
104+
105+
def test_success_2(http_server):
106+
url = f"http://localhost:{http_server.port}/b"
107+
opener = sambacc.url_opener.URLOpener()
108+
res = opener.open(url)
109+
assert res.read() == b"This is a test"
110+
111+
112+
def test_error_404(http_server):
113+
url = f"http://localhost:{http_server.port}/err404"
114+
opener = sambacc.url_opener.URLOpener()
115+
with pytest.raises(OSError) as err:
116+
opener.open(url)
117+
assert err.value.status == 404
118+
assert err.value.errno == errno.ENOENT
119+
120+
121+
def test_error_401(http_server):
122+
url = f"http://localhost:{http_server.port}/err401"
123+
opener = sambacc.url_opener.URLOpener()
124+
with pytest.raises(OSError) as err:
125+
opener.open(url)
126+
assert err.value.status == 401
127+
assert err.value.errno == errno.EPERM
128+
129+
130+
def test_error_403(http_server):
131+
url = f"http://localhost:{http_server.port}/err403"
132+
opener = sambacc.url_opener.URLOpener()
133+
with pytest.raises(OSError) as err:
134+
opener.open(url)
135+
assert err.value.status == 403
136+
# No errno mapped for this one
137+
138+
139+
def test_map_errno(http_server):
140+
url = f"http://localhost:{http_server.port}/err401"
141+
opener = sambacc.url_opener.URLOpener()
142+
with pytest.raises(OSError) as err:
143+
opener.open(url)
144+
# do not replace an existing errno
145+
err.value.errno = errno.EIO
146+
sambacc.url_opener._map_errno(err.value)
147+
assert err.value.errno == errno.EIO
148+
149+
150+
def test_unknown_url():
151+
opener = sambacc.url_opener.URLOpener()
152+
with pytest.raises(sambacc.url_opener.SchemeNotSupported):
153+
opener.open("bloop://foo/bar/baz")
154+
155+
156+
def test_unknown_url_type():
157+
opener = sambacc.url_opener.URLOpener()
158+
with pytest.raises(sambacc.url_opener.SchemeNotSupported):
159+
opener.open("bonk-bonk-bonk")
160+
161+
162+
def test_value_error_during_handling():
163+
class H(urllib.request.BaseHandler):
164+
def bonk_open(self, req):
165+
raise ValueError("fiddlesticks")
166+
167+
class UO(sambacc.url_opener.URLOpener):
168+
_handlers = sambacc.url_opener.URLOpener._handlers + [H]
169+
170+
opener = UO()
171+
with pytest.raises(ValueError) as err:
172+
opener.open("bonk:bonk")
173+
assert str(err.value) == "fiddlesticks"

0 commit comments

Comments
 (0)