-
Notifications
You must be signed in to change notification settings - Fork 339
/
test_bootstrap.py
148 lines (123 loc) · 4.63 KB
/
test_bootstrap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""
Test running bootstrap script in different circumstances
"""
import concurrent.futures
import os
import subprocess
from textwrap import dedent
import time
def install_pkgs(container_name, show_progress_page):
# Install python3 inside the ubuntu container
# There is no trusted Ubuntu+Python3 container we can use
pkgs = ["python3"]
if show_progress_page:
pkgs += ["systemd", "git", "curl"]
# Create the sudoers dir, so that the installer succesfully gets to the
# point of starting jupyterhub and stopping the progress page server.
subprocess.check_output(
["docker", "exec", container_name, "mkdir", "-p", "etc/sudoers.d"]
)
subprocess.check_output(["docker", "exec", container_name, "apt-get", "update"])
subprocess.check_output(
["docker", "exec", container_name, "apt-get", "install", "--yes"] + pkgs
)
def get_bootstrap_script_location(container_name, show_progress_page):
# Copy only the bootstrap script to container when progress page not enabled, to be faster
source_path = "bootstrap/"
bootstrap_script = "/srv/src/bootstrap.py"
if show_progress_page:
source_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), os.pardir)
)
bootstrap_script = "/srv/src/bootstrap/bootstrap.py"
subprocess.check_call(["docker", "cp", source_path, f"{container_name}:/srv/src"])
return bootstrap_script
def run_bootstrap(container_name, image, show_progress_page=False):
# stop container if it is already running
subprocess.run(["docker", "rm", "-f", container_name])
# Start a detached container
subprocess.check_call(
[
"docker",
"run",
"--detach",
"--name",
container_name,
image,
"/bin/bash",
"-c",
"sleep 1000s",
]
)
install_pkgs(container_name, show_progress_page)
bootstrap_script = get_bootstrap_script_location(container_name, show_progress_page)
exec_flags = ["-i", container_name, "python3", bootstrap_script]
if show_progress_page:
exec_flags = (
["-e", "TLJH_BOOTSTRAP_DEV=yes", "-e", "TLJH_BOOTSTRAP_PIP_SPEC=/srv/src"]
+ exec_flags
+ ["--show-progress-page"]
)
# Run bootstrap script, return the output
return subprocess.run(
["docker", "exec"] + exec_flags,
check=False,
stdout=subprocess.PIPE,
encoding="utf-8",
)
def test_ubuntu_too_old():
"""
Error with a useful message when running in older Ubuntu
"""
output = run_bootstrap("old-distro-test", "ubuntu:16.04")
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 18.04 or higher\n"
assert output.returncode == 1
def test_inside_no_systemd_docker():
output = run_bootstrap("plain-docker-test", "ubuntu:18.04")
assert (
output.stdout.strip()
== dedent(
"""
Systemd is required to run TLJH
Running inside a docker container without systemd isn't supported
We recommend against running a production TLJH instance inside a docker container
For local development, see http://tljh.jupyter.org/en/latest/contributing/dev-setup.html
"""
).strip()
)
assert output.returncode == 1
def verify_progress_page(expected_status_code, timeout):
progress_page_status = False
start = time.time()
while not progress_page_status and (time.time() - start < timeout):
try:
resp = subprocess.check_output(
[
"docker",
"exec",
"progress-page",
"curl",
"-i",
"http://localhost/index.html",
]
)
if b"HTTP/1.0 200 OK" in resp:
progress_page_status = True
break
except Exception as e:
time.sleep(2)
continue
return progress_page_status
def test_progress_page():
with concurrent.futures.ThreadPoolExecutor() as executor:
installer = executor.submit(
run_bootstrap, "progress-page", "ubuntu:18.04", True
)
# Check if progress page started
started = verify_progress_page(expected_status_code=200, timeout=120)
assert started
# This will fail start tljh but should successfully get to the point
# Where it stops the progress page server.
output = installer.result()
# Check if progress page stopped
assert "Progress page server stopped successfully." in output.stdout