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 diff --git a/setup.py b/setup.py index 08434d1a..ec622e22 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", "tests"]), include_package_data=True, entry_points={ "jupyterhub.proxies": [ 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..5d249171 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" @@ -54,6 +55,17 @@ 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" @@ -166,7 +178,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, ) @@ -182,7 +194,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, @@ -223,13 +235,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, ), @@ -363,7 +375,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, ) @@ -374,7 +386,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, @@ -473,7 +485,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}, ) @@ -549,16 +561,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}", @@ -574,11 +586,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..38bd6992 100644 --- a/tests/dummy_http_server.py +++ b/tests/dummy_http_server.py @@ -12,6 +12,8 @@ import websockets +from .conftest import Config + async def process_request(path, request_headers, port): if path.endswith("/ws"): @@ -31,7 +33,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 3cb6ea46..9301b539 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 +from .conftest import Config + # Mark all tests in this file as slow pytestmark = [pytest.mark.slow] @@ -47,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("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 @@ -116,7 +120,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..34813128 100644 --- a/tests/test_traefik_utils.py +++ b/tests/test_traefik_utils.py @@ -5,6 +5,8 @@ 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 +14,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": {