From 40e883202842622c9da48afb5c10bcc4a3a1cece Mon Sep 17 00:00:00 2001 From: Carl Smedstad Date: Tue, 27 Aug 2024 08:04:06 +0200 Subject: [PATCH 1/4] Don't add CWD to sys.path for testing - redundant A package in CWD will take precedence over system-installed packages without sys.path modifications, at least in non-archaic Python versions. --- tests/server_test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/server_test.py b/tests/server_test.py index 16a2501..29ec09e 100644 --- a/tests/server_test.py +++ b/tests/server_test.py @@ -1,6 +1,3 @@ -# Import RangeHTTPServer from this project, not the global install. -import sys -sys.path = ['.'] + sys.path from RangeHTTPServer import RangeRequestHandler import pytest From 2627d62f5431046956d82e4400f6e9883837cbba Mon Sep 17 00:00:00 2001 From: Carl Smedstad Date: Tue, 27 Aug 2024 08:06:06 +0200 Subject: [PATCH 2/4] Remove Python 2 support from tests --- tests/server_test.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/server_test.py b/tests/server_test.py index 29ec09e..70fa879 100644 --- a/tests/server_test.py +++ b/tests/server_test.py @@ -2,13 +2,7 @@ import pytest -try: - # Python 3 - from http.server import HTTPServer - -except ImportError: - # Python2 - from BaseHTTPServer import HTTPServer +from http.server import HTTPServer import requests import threading From 17ee85d5aa1dfb06d148312e2cc3b71a09a0d50d Mon Sep 17 00:00:00 2001 From: Carl Smedstad Date: Tue, 27 Aug 2024 08:08:01 +0200 Subject: [PATCH 3/4] Sort and organize imports in tests/server_test.py --- tests/server_test.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/server_test.py b/tests/server_test.py index 70fa879..5327071 100644 --- a/tests/server_test.py +++ b/tests/server_test.py @@ -1,13 +1,12 @@ -from RangeHTTPServer import RangeRequestHandler - -import pytest - from http.server import HTTPServer - -import requests import threading import time +import pytest +import requests + +from RangeHTTPServer import RangeRequestHandler + httpd = None server_thread = None From 6498c2d305c31072ed14919eb72eed5155f8c7ee Mon Sep 17 00:00:00 2001 From: Carl Smedstad Date: Tue, 27 Aug 2024 08:09:11 +0200 Subject: [PATCH 4/4] Fix tests by properly implementing server pytest fixture Implement and use the pytest fixture 'http_server'. Also, solve the TODO of selecting the first available free port instead of a hardcoded one. Resolves #38 --- tests/server_test.py | 55 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/tests/server_test.py b/tests/server_test.py index 5327071..6f3f961 100644 --- a/tests/server_test.py +++ b/tests/server_test.py @@ -1,4 +1,5 @@ from http.server import HTTPServer +import socket import threading import time @@ -8,23 +9,27 @@ from RangeHTTPServer import RangeRequestHandler -httpd = None -server_thread = None -def setup(): +def get_free_port() -> int: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(('', 0)) + return s.getsockname()[1] + + +@pytest.fixture(scope="module") +def http_server(): + port = get_free_port() def start_server(): global httpd RangeRequestHandler.protocol_version = 'HTTP/1.0' - # TODO(danvk): pick a random, available port - httpd = HTTPServer(('', 8712), RangeRequestHandler) + httpd = HTTPServer(('', port), RangeRequestHandler) httpd.serve_forever() - global server_thread server_thread = threading.Thread(target=start_server) server_thread.start() time.sleep(1.0) + yield f'http://localhost:{port}' -def teardown(): httpd.shutdown() server_thread.join() @@ -38,15 +43,15 @@ def headers_of_note(response): 'Content-Length']} -def test_simple_request(): - r = requests.get('http://localhost:8712/tests/data.txt') +def test_simple_request(http_server): + r = requests.get(f'{http_server}/tests/data.txt') assert 200 == r.status_code assert '0123456789abcdef\n' == r.text assert 'text/plain' == r.headers['content-type'] -def test_range_request(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_range_request(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=0-9'}) assert 206 == r.status_code assert '0123456789' == r.text @@ -58,8 +63,8 @@ def test_range_request(): } == headers_of_note(r) -def test_open_range_request(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_open_range_request(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=10-'}) assert 206 == r.status_code assert 'abcdef\n' == r.text @@ -71,8 +76,8 @@ def test_open_range_request(): } == headers_of_note(r) -def test_mid_file_range_request(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_mid_file_range_request(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=6-10'}) assert 206 == r.status_code assert '6789a' == r.text @@ -84,20 +89,20 @@ def test_mid_file_range_request(): } == headers_of_note(r) -def test_404(): - r = requests.get('http://localhost:8712/tests/nonexistent.txt', +def test_404(http_server): + r = requests.get(f'{http_server}/tests/nonexistent.txt', headers={'Range': 'bytes=6-10'}) assert 404 == r.status_code -def test_bad_range(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_bad_range(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=abc'}) assert 400 == r.status_code -def test_range_past_eof(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_range_past_eof(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=10-100'}) assert 206 == r.status_code assert 'abcdef\n' == r.text @@ -109,8 +114,8 @@ def test_range_past_eof(): } == headers_of_note(r) -def test_range_at_eof(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_range_at_eof(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=16-'}) assert 206 == r.status_code assert '\n' == r.text @@ -122,7 +127,7 @@ def test_range_at_eof(): } == headers_of_note(r) -def test_range_starting_past_eof(): - r = requests.get('http://localhost:8712/tests/data.txt', +def test_range_starting_past_eof(http_server): + r = requests.get(f'{http_server}/tests/data.txt', headers={'Range': 'bytes=17-'}) assert 416 == r.status_code # "Requested Range Not Satisfiable"