Files
docker-stacks/tests/base-notebook/test_start_container.py
Yuvi Panda bceaead5d2 Migrate start-notebook & start-singleuser to python (#2006)
* Migrate start-notebook.sh to bash

Based on

> Stop using bash, haha 👍

from https://github.com/jupyter/docker-stacks/issues/1532.

If there's more apetite for this, I'll try to migrate
`start.sh` and `start-singleuser.sh` as well - I think they should
all be merged together. We can remove the `.sh` suffixes for
accuracy, and keep symlinks in so old config still works. Since
the shebang is what is used to launch the correct interpreter,
the `.sh` doesn't matter.

Will help fix https://github.com/jupyter/docker-stacks/issues/1532,
as I believe all those things are going to be easier to do from
python than bash

* Rename start-notebook.sh to start-notebook

* Cleanup start-notebook a little

* Fix typo

* Migrate start-singleuser as well

* Remove unused import

* Run symlink commands as root

* Combine repetitive RUN commands

* Remove multiple args to env

-u can not be set by shebang, we must set the env var
instead

* Fix conditional inversion

Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>

* Fix how start-singleuser is exec'd

* Actually call jupyterhub-singleuser in start-singleuser

* Pass through any additional args we get

* Put .py suffix on the start-* scripts

* Add .sh shims for the start-* scripts

* Document start-notebook.sh and start-singleuser.sh

* Partially test start-notebook.sh

* Reflow warning docs

Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>

---------

Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2023-10-17 14:46:43 +02:00

89 lines
3.2 KiB
Python

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import logging
import time
from typing import Optional
import pytest # type: ignore
import requests
from tests.conftest import TrackedContainer, find_free_port
LOGGER = logging.getLogger(__name__)
@pytest.mark.parametrize(
"env,expected_command,expected_start,expected_warnings",
[
(None, "jupyter lab", True, []),
(["DOCKER_STACKS_JUPYTER_CMD=lab"], "jupyter lab", True, []),
(["RESTARTABLE=yes"], "run-one-constantly jupyter lab", True, []),
(["DOCKER_STACKS_JUPYTER_CMD=notebook"], "jupyter notebook", True, []),
(["DOCKER_STACKS_JUPYTER_CMD=server"], "jupyter server", True, []),
(["DOCKER_STACKS_JUPYTER_CMD=nbclassic"], "jupyter nbclassic", True, []),
(
["JUPYTERHUB_API_TOKEN=my_token"],
"jupyterhub-singleuser",
False,
["WARNING: using start-singleuser.py"],
),
],
)
def test_start_notebook(
container: TrackedContainer,
http_client: requests.Session,
env: Optional[list[str]],
expected_command: str,
expected_start: bool,
expected_warnings: list[str],
) -> None:
"""Test the notebook start-notebook.py script"""
LOGGER.info(
f"Test that the start-notebook.py launches the {expected_command} server from the env {env} ..."
)
host_port = find_free_port()
running_container = container.run_detached(
tty=True,
environment=env,
ports={"8888/tcp": host_port},
)
# sleeping some time to let the server start
time.sleep(1)
logs = running_container.logs().decode("utf-8")
LOGGER.debug(logs)
# checking that the expected command is launched
assert (
f"Executing the command: {expected_command}" in logs
), f"Not the expected command ({expected_command}) was launched"
# checking errors and warnings in logs
assert "ERROR" not in logs, "ERROR(s) found in logs"
for exp_warning in expected_warnings:
assert exp_warning in logs, f"Expected warning {exp_warning} not found in logs"
warnings = TrackedContainer.get_warnings(logs)
assert len(expected_warnings) == len(warnings)
# checking if the server is listening
if expected_start:
resp = http_client.get(f"http://localhost:{host_port}")
assert resp.status_code == 200, "Server is not listening"
def test_tini_entrypoint(
container: TrackedContainer, pid: int = 1, command: str = "tini"
) -> None:
"""Check that tini is launched as PID 1
Credits to the following answer for the ps options used in the test:
https://superuser.com/questions/632979/if-i-know-the-pid-number-of-a-process-how-can-i-get-its-name
"""
LOGGER.info(f"Test that {command} is launched as PID {pid} ...")
running_container = container.run_detached(
tty=True,
command=["start.sh"],
)
# Select the PID 1 and get the corresponding command
cmd = running_container.exec_run(f"ps -p {pid} -o comm=")
output = cmd.output.decode("utf-8").strip("\n")
assert "ERROR" not in output
assert "WARNING" not in output
assert output == command, f"{command} shall be launched as pid {pid}, got {output}"