From 060155cf24e7044d028c2dba26a701c2aa3821fb Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Wed, 17 May 2023 21:36:31 -0500 Subject: [PATCH 01/10] ensure requirements.txt is included in the sdist --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index f794f78f..72449366 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ include versioneer.py include jupyterhub_traefik_proxy/_version.py +include requirements.txt From 63851f29efa416a69f6961bad05b6b9d5ecce9f4 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 18 May 2023 08:21:27 -0500 Subject: [PATCH 02/10] exclude the performance package --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 08434d1a..5132eeaa 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ "Programming Language :: Python", "Programming Language :: Python :: 3", ], - packages=find_packages(), + packages=find_packages(exclude=["performance"]), include_package_data=True, entry_points={ "jupyterhub.proxies": [ From 987aab13d742dbd9e574de7f9afd12681a6b7a6d Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 18 May 2023 08:25:55 -0500 Subject: [PATCH 03/10] also exclude tests --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5132eeaa..ec622e22 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ "Programming Language :: Python", "Programming Language :: Python :: 3", ], - packages=find_packages(exclude=["performance"]), + packages=find_packages(exclude=["performance", "tests"]), include_package_data=True, entry_points={ "jupyterhub.proxies": [ From 7e82fc5687b9f4f8d358e5134c9ac1608115f930 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 18 May 2023 08:29:53 -0500 Subject: [PATCH 04/10] make tests an importable (but not installed) module, use relative imports --- tests/__init__.py | 0 tests/conftest.py | 3 ++- tests/test_proxy.py | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/conftest.py b/tests/conftest.py index 9d62cb0f..e35c0daf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,6 @@ from urllib.parse import urlparse import pytest -import utils from certipy import Certipy from consul.aio import Consul from jupyterhub.utils import exponential_backoff @@ -24,6 +23,8 @@ from jupyterhub_traefik_proxy.fileprovider import TraefikFileProviderProxy from jupyterhub_traefik_proxy.traefik_utils import deep_merge +from . import utils + HERE = Path(__file__).parent.resolve() config_files = HERE / "config_files" diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 3cb6ea46..0ce9864e 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -14,7 +14,6 @@ from urllib.parse import quote, urlparse import pytest -import utils import websockets from jupyterhub.objects import Hub, Server from jupyterhub.user import User @@ -23,6 +22,9 @@ from jupyterhub_traefik_proxy.proxy import TraefikProxy +from . import utils + + # Mark all tests in this file as slow pytestmark = [pytest.mark.slow] From db3e6d885922a276e31583d01dcfeed58812572d Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Tue, 23 May 2023 09:25:12 -0500 Subject: [PATCH 05/10] add localhost env var --- tests/conftest.py | 50 +++++++++++++++++++++++-------------- tests/dummy_http_server.py | 3 ++- tests/test_proxy.py | 6 ++--- tests/test_traefik_utils.py | 5 +++- 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index e35c0daf..fa6b0f0f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ """General pytest fixtures""" +import os import asyncio import logging import os @@ -55,9 +56,20 @@ class Config: traefik_api_user = "api_admin" traefik_api_pass = "admin" + # a single location for overloading the domain part of test URLs, e.g. + # to force ipv4 + # + # JHTP_TEST_LOCALHOST="127.0.0.1" python -m pytest tests ... + # + # or ipv6 + # + # JHTP_TEST_LOCALHOST="::1" python -m pytest tests ... + # + localhost = os.environ.get("JHTP_TEST_LOCALHOST", "localhost") + # The URL that should be proxied to jupyterhub # Putting here, can easily change between http and https - public_url = "https://127.0.0.1:8000" + public_url = f"http://{localhost}:8000" # Define a "slow" test marker so that we can run the slow tests at the end @@ -100,7 +112,7 @@ def certipy(): with TemporaryDirectory() as td: certipy = Certipy(store_dir=td) certipy.create_ca("ca") - local_names = ["DNS:localhost", "IP:127.0.0.1"] + local_names = ["DNS:localhost", f"IP:{Config.localhost}"] # etcd certs from certipy don't work for some reason? # I don't understand why, but the originals do # certipy.create_signed_pair("etcd", "ca", alt_names=local_names) @@ -167,7 +179,7 @@ async def no_auth_consul_proxy(launch_consul, proxy_args): Consul acl disabled. """ proxy = TraefikConsulProxy( - consul_url=f"http://127.0.0.1:{Config.consul_port}", + consul_url=f"http://{Config.localhost}:{Config.consul_port}", should_start=True, **proxy_args, ) @@ -183,7 +195,7 @@ async def auth_consul_proxy(launch_consul_auth, proxy_args): Consul acl enabled. """ proxy = TraefikConsulProxy( - consul_url=f"http://127.0.0.1:{Config.consul_auth_port}", + consul_url=f"http://{Config.localhost}:{Config.consul_auth_port}", consul_password=Config.consul_token, should_start=True, **proxy_args, @@ -224,13 +236,13 @@ def _make_etcd_proxy(*, auth=False, client_ca=None, **extra_kwargs): client_ca = str(client_ca) kwargs.update( dict( - etcd_url="https://localhost:2379", + etcd_url=f"https://{Config.localhost}:2379", etcd_username=Config.etcd_user, etcd_password=Config.etcd_password, etcd_client_kwargs=dict( grpc_options=[ - ("grpc.ssl_target_name_override", "localhost"), - ("grpc.default_authority", "localhost"), + ("grpc.ssl_target_name_override", Config.localhost), + ("grpc.default_authority", Config.localhost), ], ca_cert=client_ca, ), @@ -364,7 +376,7 @@ async def external_file_proxy_toml(launch_traefik_file, dynamic_config_dir, prox @pytest.fixture async def external_consul_proxy(launch_traefik_consul, proxy_args): proxy = TraefikConsulProxy( - consul_url=f"http://127.0.0.1:{Config.consul_port}", + consul_url=f"http://{Config.localhost}:{Config.consul_port}", should_start=False, **proxy_args, ) @@ -375,7 +387,7 @@ async def external_consul_proxy(launch_traefik_consul, proxy_args): @pytest.fixture async def auth_external_consul_proxy(launch_traefik_consul_auth, proxy_args): proxy = TraefikConsulProxy( - consul_url=f"http://127.0.0.1:{Config.consul_auth_port}", + consul_url=f"http://{Config.localhost}:{Config.consul_auth_port}", consul_password=Config.consul_token, should_start=False, **proxy_args, @@ -474,7 +486,7 @@ def launch_traefik_consul(launch_traefik, launch_consul): @pytest.fixture def launch_traefik_consul_auth(launch_traefik, launch_consul_auth): return launch_traefik( - f"--providers.consul.endpoints=http://127.0.0.1:{Config.consul_auth_port}", + f"--providers.consul.endpoints=http://{Config.localhost}:{Config.consul_auth_port}", env={"CONSUL_HTTP_TOKEN": Config.consul_token}, ) @@ -550,16 +562,16 @@ async def launch_etcd_auth(etcd_ssl_key_cert, etcd_client_ca): f"--peer-trusted-ca-file={etcd_client_ca}", f"--cert-file={cert}", f"--key-file={key}", - "--initial-cluster=default=https://localhost:2380", - "--initial-advertise-peer-urls=https://localhost:2380", - "--listen-peer-urls=https://localhost:2380", - "--listen-client-urls=https://localhost:2379", - "--advertise-client-urls=https://localhost:2379", + f"--initial-cluster=default=https://{Config.localhost}:2380", + f"--initial-advertise-peer-urls=https://{Config.localhost}:2380", + f"--listen-peer-urls=https://{Config.localhost}:2380", + f"--listen-client-urls=https://{Config.localhost}:2379", + f"--advertise-client-urls=https://{Config.localhost}:2379", "--log-level=debug", ], ) etcdctl_args = [ - "--endpoints=localhost:2379", + f"--endpoints={Config.localhost}:2379", "--user", f"{Config.etcd_user}:{Config.etcd_password}", f"--cacert={etcd_client_ca}", @@ -575,11 +587,11 @@ async def launch_etcd_auth(etcd_ssl_key_cert, etcd_client_ca): c = etcd3.client( user=Config.etcd_user, password=Config.etcd_password, - host="localhost", + host=Config.localhost, port=2379, grpc_options=[ - ("grpc.ssl_target_name_override", "localhost"), - ("grpc.default_authority", "localhost"), + ("grpc.ssl_target_name_override", Config.localhost), + ("grpc.default_authority", Config.localhost), ], ca_cert=etcd_client_ca, ) diff --git a/tests/dummy_http_server.py b/tests/dummy_http_server.py index 2293ce22..88ccdbf4 100644 --- a/tests/dummy_http_server.py +++ b/tests/dummy_http_server.py @@ -12,6 +12,7 @@ import websockets +from .conftest import Config async def process_request(path, request_headers, port): if path.endswith("/ws"): @@ -31,7 +32,7 @@ async def send_port(websocket, path): async def main(port): async with websockets.serve( send_port, - host="127.0.0.1", + host=Config.localhost, port=port, process_request=partial(process_request, port=port), ): diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 0ce9864e..a60589a9 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -23,7 +23,7 @@ from jupyterhub_traefik_proxy.proxy import TraefikProxy from . import utils - +from .conftest import Config # Mark all tests in this file as slow pytestmark = [pytest.mark.slow] @@ -49,7 +49,7 @@ def __init__(self, name="", *, user, **kwargs): self.proxy_spec = url_path_join(self.user.proxy_spec, name, "/") def start(self): - self.server = Server.from_url("http://127.0.0.1:%i" % randint(1025, 65535)) + self.server = Server.from_url(f"http://{Config.localhost}:{randint(1025, 65535)}") def stop(self): self.server = None @@ -118,7 +118,7 @@ async def _launch_backends(n=1): already_available = len(running_backends) for i in range(already_available, n): port = base_port + i - url = f"http://127.0.0.1:{port}" + url = f"http://{Config.localhost}:{port}" print(f"Launching backend on {url}") backend = subprocess.Popen([sys.executable, dummy_server_path, str(port)]) running_backends.append(backend) diff --git a/tests/test_traefik_utils.py b/tests/test_traefik_utils.py index 8f67f102..66c072bf 100644 --- a/tests/test_traefik_utils.py +++ b/tests/test_traefik_utils.py @@ -5,6 +5,7 @@ from jupyterhub_traefik_proxy import traefik_utils +from .conftest import Config # Mark all tests in this file as asyncio def test_roundtrip_routes(): @@ -12,7 +13,9 @@ def test_roundtrip_routes(): routes = { "backends": { "backend1": { - "servers": {"server1": {"url": "http://127.0.0.1:9009", "weight": 1}} + "servers": { + "server1": {"url": f"http://{Config.localhost}:9009", "weight": 1} + } } }, "frontends": { From c3edc3c73099f4780e3d7984d1ea4b68915288db Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 14:27:37 +0000 Subject: [PATCH 06/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/conftest.py | 1 - tests/dummy_http_server.py | 1 + tests/test_proxy.py | 4 +++- tests/test_traefik_utils.py | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index fa6b0f0f..2563acb7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,5 @@ """General pytest fixtures""" -import os import asyncio import logging import os diff --git a/tests/dummy_http_server.py b/tests/dummy_http_server.py index 88ccdbf4..38bd6992 100644 --- a/tests/dummy_http_server.py +++ b/tests/dummy_http_server.py @@ -14,6 +14,7 @@ from .conftest import Config + async def process_request(path, request_headers, port): if path.endswith("/ws"): return None diff --git a/tests/test_proxy.py b/tests/test_proxy.py index a60589a9..9301b539 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -49,7 +49,9 @@ def __init__(self, name="", *, user, **kwargs): self.proxy_spec = url_path_join(self.user.proxy_spec, name, "/") def start(self): - self.server = Server.from_url(f"http://{Config.localhost}:{randint(1025, 65535)}") + self.server = Server.from_url( + f"http://{Config.localhost}:{randint(1025, 65535)}" + ) def stop(self): self.server = None diff --git a/tests/test_traefik_utils.py b/tests/test_traefik_utils.py index 66c072bf..34813128 100644 --- a/tests/test_traefik_utils.py +++ b/tests/test_traefik_utils.py @@ -7,6 +7,7 @@ from .conftest import Config + # Mark all tests in this file as asyncio def test_roundtrip_routes(): pytest.mark.asyncio From d1ba01f1b76ab7b85081cd5a84a2385af9031c25 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Tue, 23 May 2023 09:46:21 -0500 Subject: [PATCH 07/10] restore 127.0.0.1 for IP-specific value --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 2563acb7..4b2b1672 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -111,7 +111,7 @@ def certipy(): with TemporaryDirectory() as td: certipy = Certipy(store_dir=td) certipy.create_ca("ca") - local_names = ["DNS:localhost", f"IP:{Config.localhost}"] + local_names = ["DNS:localhost", "IP:127.0.0.1"] # etcd certs from certipy don't work for some reason? # I don't understand why, but the originals do # certipy.create_signed_pair("etcd", "ca", alt_names=local_names) From d621cd2f9eb51e99b5f9c9c6ac2469a5048a7abb Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Tue, 23 May 2023 09:46:50 -0500 Subject: [PATCH 08/10] restore https --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 4b2b1672..8456afe6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -68,7 +68,7 @@ class Config: # The URL that should be proxied to jupyterhub # Putting here, can easily change between http and https - public_url = f"http://{localhost}:8000" + public_url = f"https://{localhost}:8000" # Define a "slow" test marker so that we can run the slow tests at the end From ee1062e37c6a119d0a5d2e5fcd0d26915cea5b45 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Wed, 24 May 2023 07:12:11 -0500 Subject: [PATCH 09/10] always use 127.0.0.1 for public_url --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8456afe6..e581a6e0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -68,7 +68,7 @@ class Config: # The URL that should be proxied to jupyterhub # Putting here, can easily change between http and https - public_url = f"https://{localhost}:8000" + public_url = f"https://127.0.0.1:8000" # Define a "slow" test marker so that we can run the slow tests at the end From f6f6f338b3c2a5d052fb518e1f7db45c30bd1d2d Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Wed, 24 May 2023 07:12:51 -0500 Subject: [PATCH 10/10] remove unused f string --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index e581a6e0..5d249171 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -68,7 +68,7 @@ class Config: # The URL that should be proxied to jupyterhub # Putting here, can easily change between http and https - public_url = f"https://127.0.0.1:8000" + public_url = "https://127.0.0.1:8000" # Define a "slow" test marker so that we can run the slow tests at the end