mirror of
https://github.com/jupyter/docker-stacks.git
synced 2025-10-09 11:02:57 +00:00
Add a way to easily test units
This commit is contained in:
@@ -7,6 +7,7 @@ import pytest
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@@ -16,7 +17,7 @@ LOGGER = logging.getLogger(__name__)
|
|||||||
)
|
)
|
||||||
def test_nbconvert(container, test_file):
|
def test_nbconvert(container, test_file):
|
||||||
"""Check if Spark notebooks can be executed"""
|
"""Check if Spark notebooks can be executed"""
|
||||||
host_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data")
|
host_data_dir = os.path.join(THIS_DIR, "data")
|
||||||
cont_data_dir = "/home/jovyan/data"
|
cont_data_dir = "/home/jovyan/data"
|
||||||
output_dir = "/tmp"
|
output_dir = "/tmp"
|
||||||
timeout_ms = 600
|
timeout_ms = 600
|
||||||
|
@@ -8,22 +8,23 @@ LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"package_manager, cmd",
|
"package_manager, version_arg",
|
||||||
[
|
[
|
||||||
("apt", "--version"),
|
("apt", "--version"),
|
||||||
("conda", "--version"),
|
("conda", "--version"),
|
||||||
("mamba", "--version"),
|
("mamba", "--version"),
|
||||||
("npm", "--version"),
|
("npm", "--version"),
|
||||||
("pip", "--version"),
|
("pip", "--version")
|
||||||
],
|
]
|
||||||
)
|
)
|
||||||
def test_package_manager(container, package_manager, cmd):
|
def test_package_manager(container, package_manager, version_arg):
|
||||||
"""Test the notebook start-notebook script"""
|
"""Test the notebook start-notebook script"""
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
f"Test that the package manager {package_manager} is working properly ..."
|
f"Test that the package manager {package_manager} is working properly ..."
|
||||||
)
|
)
|
||||||
c = container.run(
|
c = container.run(
|
||||||
tty=True, command=["start.sh", "bash", "-c", f"{package_manager} {cmd}"]
|
tty=True,
|
||||||
|
command=["start.sh", "bash", "-c", f"{package_manager} {version_arg}"]
|
||||||
)
|
)
|
||||||
rv = c.wait(timeout=5)
|
rv = c.wait(timeout=5)
|
||||||
logs = c.logs(stdout=True).decode("utf-8")
|
logs = c.logs(stdout=True).decode("utf-8")
|
||||||
|
@@ -9,7 +9,8 @@ LOGGER = logging.getLogger(__name__)
|
|||||||
def test_pandoc(container):
|
def test_pandoc(container):
|
||||||
"""Pandoc shall be able to convert MD to HTML."""
|
"""Pandoc shall be able to convert MD to HTML."""
|
||||||
c = container.run(
|
c = container.run(
|
||||||
tty=True, command=["start.sh", "bash", "-c", 'echo "**BOLD**" | pandoc']
|
tty=True,
|
||||||
|
command=["start.sh", "bash", "-c", 'echo "**BOLD**" | pandoc']
|
||||||
)
|
)
|
||||||
c.wait(timeout=10)
|
c.wait(timeout=10)
|
||||||
logs = c.logs(stdout=True).decode("utf-8")
|
logs = c.logs(stdout=True).decode("utf-8")
|
||||||
|
@@ -8,7 +8,11 @@ LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"env,expected_server", [(["JUPYTER_ENABLE_LAB=yes"], "lab"), (None, "notebook"), ],
|
"env,expected_server",
|
||||||
|
[
|
||||||
|
(["JUPYTER_ENABLE_LAB=yes"], "lab"),
|
||||||
|
(None, "notebook")
|
||||||
|
]
|
||||||
)
|
)
|
||||||
def test_start_notebook(container, http_client, env, expected_server):
|
def test_start_notebook(container, http_client, env, expected_server):
|
||||||
"""Test the notebook start-notebook script"""
|
"""Test the notebook start-notebook script"""
|
||||||
|
@@ -9,7 +9,8 @@ def test_julia(container):
|
|||||||
"""Basic julia test"""
|
"""Basic julia test"""
|
||||||
LOGGER.info("Test that julia is correctly installed ...")
|
LOGGER.info("Test that julia is correctly installed ...")
|
||||||
running_container = container.run(
|
running_container = container.run(
|
||||||
tty=True, command=["start.sh", "bash", "-c", "sleep infinity"]
|
tty=True,
|
||||||
|
command=["start.sh", "bash", "-c", "sleep infinity"]
|
||||||
)
|
)
|
||||||
command = "julia --version"
|
command = "julia --version"
|
||||||
cmd = running_container.exec_run(command)
|
cmd = running_container.exec_run(command)
|
||||||
|
@@ -7,15 +7,21 @@ import pytest
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_file, output_format,", [
|
@pytest.mark.parametrize(
|
||||||
("notebook_math", "pdf"), ("notebook_math", "html"),
|
"test_file, output_format",
|
||||||
("notebook_svg", "pdf"), ("notebook_svg", "html"),
|
[
|
||||||
])
|
("notebook_math", "pdf"),
|
||||||
|
("notebook_math", "html"),
|
||||||
|
("notebook_svg", "pdf"),
|
||||||
|
("notebook_svg", "html")
|
||||||
|
]
|
||||||
|
)
|
||||||
def test_nbconvert(container, test_file, output_format):
|
def test_nbconvert(container, test_file, output_format):
|
||||||
"""Check if nbconvert is able to convert a notebook file"""
|
"""Check if nbconvert is able to convert a notebook file"""
|
||||||
host_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data")
|
host_data_dir = os.path.join(THIS_DIR, "data")
|
||||||
cont_data_dir = "/home/jovyan/data"
|
cont_data_dir = "/home/jovyan/data"
|
||||||
output_dir = "/tmp"
|
output_dir = "/tmp"
|
||||||
LOGGER.info(f"Test that the example notebook {test_file} can be converted to {output_format.upper()} ...")
|
LOGGER.info(f"Test that the example notebook {test_file} can be converted to {output_format.upper()} ...")
|
||||||
|
@@ -16,15 +16,3 @@ def test_spark_shell(container):
|
|||||||
logs = c.logs(stdout=True).decode('utf-8')
|
logs = c.logs(stdout=True).decode('utf-8')
|
||||||
LOGGER.debug(logs)
|
LOGGER.debug(logs)
|
||||||
assert 'res0: Int = 2' in logs, "spark-shell does not work"
|
assert 'res0: Int = 2' in logs, "spark-shell does not work"
|
||||||
|
|
||||||
|
|
||||||
def test_pyspark(container):
|
|
||||||
"""PySpark should be in the Python path"""
|
|
||||||
c = container.run(
|
|
||||||
tty=True,
|
|
||||||
command=['start.sh', 'python', '-c', 'import pyspark']
|
|
||||||
)
|
|
||||||
rv = c.wait(timeout=30)
|
|
||||||
assert rv == 0 or rv["StatusCode"] == 0, "pyspark not in PYTHONPATH"
|
|
||||||
logs = c.logs(stdout=True).decode('utf-8')
|
|
||||||
LOGGER.debug(logs)
|
|
||||||
|
4
pyspark-notebook/test/units/unit_spark.py
Normal file
4
pyspark-notebook/test/units/unit_spark.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Copyright (c) Jupyter Development Team.
|
||||||
|
# Distributed under the terms of the Modified BSD License.
|
||||||
|
|
||||||
|
import pyspark # noqa: F401
|
@@ -1,5 +1,6 @@
|
|||||||
docker
|
docker
|
||||||
myst-parser
|
myst-parser
|
||||||
|
packaging
|
||||||
plumbum
|
plumbum
|
||||||
pre-commit
|
pre-commit
|
||||||
pytest
|
pytest
|
||||||
|
@@ -7,23 +7,23 @@ import pytest
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_file,expected_file,description",
|
@pytest.mark.parametrize(
|
||||||
[
|
"test_file,expected_file,description",
|
||||||
("matplotlib_1.py", "test.png",
|
[
|
||||||
"Test that matplotlib is able to plot a graph and write it as an image ..."),
|
("matplotlib_1.py", "test.png", "Test that matplotlib is able to plot a graph and write it as an image ..."),
|
||||||
("matplotlib_fonts_1.py", "test_fonts.png",
|
("matplotlib_fonts_1.py", "test_fonts.png", "Test cm-super latex labels in matplotlib ...")
|
||||||
"Test cm-super latex labels in matplotlib ...")
|
]
|
||||||
])
|
)
|
||||||
def test_matplotlib(container, test_file, expected_file, description):
|
def test_matplotlib(container, test_file, expected_file, description):
|
||||||
"""Various tests performed on matplotlib
|
"""Various tests performed on matplotlib
|
||||||
|
|
||||||
- Test that matplotlib is able to plot a graph and write it as an image
|
- Test that matplotlib is able to plot a graph and write it as an image
|
||||||
- Test matplotlib latex fonts, which depend on the cm-super package
|
- Test matplotlib latex fonts, which depend on the cm-super package
|
||||||
"""
|
"""
|
||||||
host_data_dir = os.path.join(os.path.dirname(
|
host_data_dir = os.path.join(THIS_DIR, "data")
|
||||||
os.path.realpath(__file__)), "data")
|
|
||||||
cont_data_dir = "/home/jovyan/data"
|
cont_data_dir = "/home/jovyan/data"
|
||||||
output_dir = "/tmp"
|
output_dir = "/tmp"
|
||||||
LOGGER.info(description)
|
LOGGER.info(description)
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
# Copyright (c) Jupyter Development Team.
|
|
||||||
# Distributed under the terms of the Modified BSD License.
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"name,command_list",
|
|
||||||
[
|
|
||||||
(
|
|
||||||
"Sum series",
|
|
||||||
[
|
|
||||||
"import pandas as pd",
|
|
||||||
"import numpy as np",
|
|
||||||
"np.random.seed(0)",
|
|
||||||
"print(pd.Series(np.random.randint(0, 7, size=10)).sum())"
|
|
||||||
]
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_pandas(container, name, command_list):
|
|
||||||
"""Basic pandas tests"""
|
|
||||||
LOGGER.info(f"Testing pandas: {name} ...")
|
|
||||||
command = ';'.join(command_list)
|
|
||||||
c = container.run(tty=True, command=["start.sh", "python", "-c", command])
|
|
||||||
rv = c.wait(timeout=30)
|
|
||||||
assert rv == 0 or rv["StatusCode"] == 0, f"Command {command} failed"
|
|
||||||
logs = c.logs(stdout=True).decode("utf-8")
|
|
||||||
LOGGER.debug(logs)
|
|
9
scipy-notebook/test/units/unit_pandas.py
Normal file
9
scipy-notebook/test/units/unit_pandas.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) Jupyter Development Team.
|
||||||
|
# Distributed under the terms of the Modified BSD License.
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
|
||||||
|
np.random.seed(0)
|
||||||
|
print(pd.Series(np.random.randint(0, 7, size=10)).sum())
|
@@ -1,30 +0,0 @@
|
|||||||
# Copyright (c) Jupyter Development Team.
|
|
||||||
# Distributed under the terms of the Modified BSD License.
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"name,command",
|
|
||||||
[
|
|
||||||
(
|
|
||||||
"Hello world",
|
|
||||||
"import tensorflow as tf;print(tf.constant('Hello, TensorFlow'))",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"Sum",
|
|
||||||
"import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_tensorflow(container, name, command):
|
|
||||||
"""Basic tensorflow tests"""
|
|
||||||
LOGGER.info(f"Testing tensorflow: {name} ...")
|
|
||||||
c = container.run(tty=True, command=["start.sh", "python", "-c", command])
|
|
||||||
rv = c.wait(timeout=30)
|
|
||||||
assert rv == 0 or rv["StatusCode"] == 0, f"Command {command} failed"
|
|
||||||
logs = c.logs(stdout=True).decode("utf-8")
|
|
||||||
LOGGER.debug(logs)
|
|
7
tensorflow-notebook/test/units/unit_tensorflow.py
Normal file
7
tensorflow-notebook/test/units/unit_tensorflow.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Copyright (c) Jupyter Development Team.
|
||||||
|
# Distributed under the terms of the Modified BSD License.
|
||||||
|
import tensorflow as tf
|
||||||
|
|
||||||
|
|
||||||
|
print(tf.constant('Hello, TensorFlow'))
|
||||||
|
print(tf.reduce_sum(tf.random.normal([1000, 1000])))
|
@@ -50,7 +50,8 @@ class CondaPackageHelper:
|
|||||||
"""Start the TrackedContainer and return an instance of a running container"""
|
"""Start the TrackedContainer and return an instance of a running container"""
|
||||||
LOGGER.info(f"Starting container {container.image_name} ...")
|
LOGGER.info(f"Starting container {container.image_name} ...")
|
||||||
return container.run(
|
return container.run(
|
||||||
tty=True, command=["start.sh", "bash", "-c", "sleep infinity"]
|
tty=True,
|
||||||
|
command=["start.sh", "bash", "-c", "sleep infinity"]
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
33
test/test_units.py
Normal file
33
test/test_units.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Copyright (c) Jupyter Development Team.
|
||||||
|
# Distributed under the terms of the Modified BSD License.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
def test_units(container):
|
||||||
|
"""Various units tests
|
||||||
|
Add a py file in the {image}/test/units dir and it will be automatically tested
|
||||||
|
"""
|
||||||
|
host_data_dir = os.path.join(THIS_DIR, "../", container.image_name(), "test/units")
|
||||||
|
cont_data_dir = "/home/jovyan/data"
|
||||||
|
|
||||||
|
if not os.path.exists(host_data_dir):
|
||||||
|
LOGGER.info(f"Not found unit tests for image: {container.image_name()}")
|
||||||
|
return
|
||||||
|
|
||||||
|
command = "sleep infinity"
|
||||||
|
running_container = container.run(
|
||||||
|
volumes={host_data_dir: {"bind": cont_data_dir, "mode": "ro"}},
|
||||||
|
tty=True,
|
||||||
|
command=["start.sh", "bash", "-c", command],
|
||||||
|
)
|
||||||
|
for test_file in os.listdir(host_data_dir):
|
||||||
|
LOGGER.info("Running unit test: {test_file}")
|
||||||
|
command = f"python {cont_data_dir}/{test_file}"
|
||||||
|
cmd = running_container.exec_run(command)
|
||||||
|
assert cmd.exit_code == 0, f"Command {command} failed"
|
||||||
|
LOGGER.debug(cmd.output.decode("utf-8"))
|
Reference in New Issue
Block a user