diff --git a/.circleci/config.yml b/.circleci/config.yml index 98fde0c..6736b3e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -58,8 +58,10 @@ commands: .circleci/integration-test.py run-test \ --bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \ - basic-tests test_hub.py test_install.py test_extensions.py \ + basic-tests test_hub.py test_proxy.py \ + test_install.py test_extensions.py \ << parameters.upgrade >> + admin_tests: parameters: upgrade: diff --git a/integration-tests/test_proxy.py b/integration-tests/test_proxy.py index 1ee236f..9b37f40 100644 --- a/integration-tests/test_proxy.py +++ b/integration-tests/test_proxy.py @@ -5,7 +5,9 @@ import ssl from subprocess import check_call import time -import requests +import toml +from tornado.httpclient import HTTPClient, HTTPRequest, HTTPClientError +import pytest from tljh.config import reload_component, set_config_value, CONFIG_FILE @@ -53,14 +55,64 @@ def test_manual_https(preserve_config): # verify that our certificate was loaded by traefik assert server_cert == file_cert - for i in range(5): + for i in range(10): time.sleep(i) # verify that we can still connect to the hub - r = requests.get("https://127.0.0.1/hub/api", verify=False) - if r.status_code == 200: - break; - - r.raise_for_status() + try: + req = HTTPRequest( + "https://127.0.0.1/hub/api", method="GET", validate_cert=False + ) + resp = HTTPClient().fetch(req) + break + except Exception as e: + pass + assert resp.code == 200 # cleanup shutil.rmtree(ssl_dir) + + +def test_extra_traefik_config(): + extra_config_dir = os.path.join(CONFIG_DIR, "traefik_config.d") + os.makedirs(extra_config_dir, exist_ok=True) + + extra_config = { + "entryPoints": {"no_auth_api": {"address": "127.0.0.1:9999"}}, + "api": {"dashboard": True, "entrypoint": "no_auth_api"}, + } + + success = False + for i in range(5): + time.sleep(i) + try: + with pytest.raises(HTTPClientError, match="HTTP 401: Unauthorized"): + # The default dashboard entrypoint requires authentication, so it should fail + req = HTTPRequest("http://127.0.0.1:8099/dashboard/", method="GET") + HTTPClient().fetch(req) + success = True + break + except Exception as e: + pass + + assert success == True + + # Load the extra config + with open(os.path.join(extra_config_dir, "extra.toml"), "w+") as extra_config_file: + toml.dump(extra_config, extra_config_file) + reload_component("proxy") + + for i in range(5): + time.sleep(i) + try: + # The new dashboard entrypoint shouldn't require authentication anymore + req = HTTPRequest("http://127.0.0.1:9999/dashboard/", method="GET") + resp = HTTPClient().fetch(req) + break + except ConnectionRefusedError: + pass + # If the request didn't get through after 5 tries, this should fail + assert resp.code == 200 + + # cleanup + os.remove(os.path.join(extra_config_dir, "extra.toml")) + reload_component("proxy")