Files
the-littlest-jupyterhub/integration-tests/test_bootstrap.py

152 lines
4.7 KiB
Python
Raw Normal View History

"""
This test file tests bootstrap.py ability to
- error verbosely for old ubuntu
- error verbosely for no systemd
- start and provide a progress page web server
"""
2020-08-18 23:56:37 +03:00
import concurrent.futures
2020-08-21 18:03:57 +03:00
import os
import subprocess
2020-08-18 23:56:37 +03:00
import time
GIT_REPO_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
BASE_IMAGE = os.getenv("BASE_IMAGE", "ubuntu:20.04")
2020-08-21 18:03:57 +03:00
def _stop_container():
"""
Stops a container if its already running.
"""
subprocess.run(
["docker", "rm", "--force", "test-bootstrap"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
2020-08-18 23:56:37 +03:00
)
2020-08-21 18:03:57 +03:00
def _run_bootstrap_in_container(image, complete_setup=True):
"""
1. (Re-)starts a container named test-bootstrap based on image, mounting
local git repo and exposing port 8080 to the containers port 80.
2. Installs python3, systemd, git, and curl in container
3. Runs bootstrap/bootstrap.py in container to install the mounted git
repo's tljh package in --editable mode.
"""
_stop_container()
2020-08-21 18:03:57 +03:00
2020-08-24 13:01:54 +03:00
# Start a detached container
subprocess.check_output(
2020-08-24 13:01:54 +03:00
[
"docker",
"run",
"--env=DEBIAN_FRONTEND=noninteractive",
"--env=TLJH_BOOTSTRAP_DEV=yes",
"--env=TLJH_BOOTSTRAP_PIP_SPEC=/srv/src",
f"--volume={GIT_REPO_PATH}:/srv/src",
"--publish=8080:80",
2020-08-24 13:01:54 +03:00
"--detach",
"--name=test-bootstrap",
2020-08-24 13:01:54 +03:00
image,
"bash",
2020-08-24 13:01:54 +03:00
"-c",
"sleep 300s",
2020-08-24 13:01:54 +03:00
]
)
run = ["docker", "exec", "-i", "test-bootstrap"]
subprocess.check_output(run + ["apt-get", "update"])
subprocess.check_output(run + ["apt-get", "install", "--yes", "python3"])
if complete_setup:
subprocess.check_output(
run + ["apt-get", "install", "--yes", "systemd", "git", "curl"]
)
2020-08-21 18:03:57 +03:00
run_bootstrap = run + [
"python3",
"/srv/src/bootstrap/bootstrap.py",
"--show-progress-page",
]
# Run bootstrap script inside detached container, return the output
2020-08-21 18:03:57 +03:00
return subprocess.run(
run_bootstrap,
text=True,
capture_output=True,
2020-08-21 18:03:57 +03:00
)
def test_ubuntu_too_old():
"""
Error with a useful message when running in older Ubuntu
"""
output = _run_bootstrap_in_container("ubuntu:18.04", False)
_stop_container()
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 20.04 or higher\n"
assert output.returncode == 1
def test_no_systemd():
output = _run_bootstrap_in_container("ubuntu:22.04", False)
assert "Systemd is required to run TLJH" in output.stdout
assert output.returncode == 1
2020-08-18 23:56:37 +03:00
def _wait_for_progress_page_response(expected_status_code, timeout):
2020-08-19 02:33:17 +03:00
start = time.time()
while time.time() - start < timeout:
2020-08-18 23:56:37 +03:00
try:
2020-08-24 13:01:54 +03:00
resp = subprocess.check_output(
[
"curl",
"--include",
"http://localhost:8080/index.html",
],
text=True,
stderr=subprocess.DEVNULL,
2020-08-24 13:01:54 +03:00
)
if "HTTP/1.0 200 OK" in resp:
return True
except Exception:
pass
time.sleep(1)
return False
2020-08-18 23:56:37 +03:00
def test_show_progress_page():
with concurrent.futures.ThreadPoolExecutor() as executor:
run_bootstrap_job = executor.submit(_run_bootstrap_in_container, BASE_IMAGE)
2020-08-19 02:33:17 +03:00
# Check that the bootstrap script started the web server reporting
# progress successfully responded.
success = _wait_for_progress_page_response(
expected_status_code=200, timeout=180
)
if success:
# Let's terminate the test here and save a minute or so in test
# executation time, because we can know that the will be stopped
# successfully in other tests as otherwise traefik won't be able to
# start and use the same port for example.
return
# Now await an expected failure to startup JupyterHub by tljh.installer,
# which should have taken over the work started by the bootstrap script.
#
# This failure is expected to occur in
# tljh.installer.ensure_jupyterhub_service calling systemd.reload_daemon
# like this:
#
# > System has not been booted with systemd as init system (PID 1).
# > Can't operate.
#
output = run_bootstrap_job.result()
print(output.stdout)
print(output.stderr)
# At this point we should be able to see that tljh.installer
# intentionally stopped the web server reporting progress as the port
# were about to become needed by Traefik.
2020-08-21 18:03:57 +03:00
assert "Progress page server stopped successfully." in output.stdout
assert success