mirror of
https://github.com/jupyter/docker-stacks.git
synced 2025-10-10 19:42:58 +00:00
Matplotlib tests + helpers methods
* Maplotlib is an important package. It has now its own test checking that a plot can be generated and exported has an image. * Some helpers methods added to the `Makefile` mainly permitting to clean containers and images * Improved assertion messages of some tests
This commit is contained in:
36
Makefile
36
Makefile
@@ -52,6 +52,16 @@ build-test-all: $(foreach I,$(ALL_IMAGES),arch_patch/$(I) build/$(I) test/$(I) )
|
||||
check-outdated/%: ## check the outdated conda packages in a stack and produce a report (experimental)
|
||||
@TEST_IMAGE="$(OWNER)/$(notdir $@)" pytest test/test_outdated.py
|
||||
|
||||
cont-clean-all: cont-stop-all cont-rm-all ## clean all containers (stop + rm)
|
||||
|
||||
cont-stop-all: ## stop all containers
|
||||
@echo "Stopping all containers ..."
|
||||
-docker stop -t0 $(shell docker ps -a -q) 2> /dev/null
|
||||
|
||||
cont-rm-all: ## remove all containers
|
||||
@echo "Removing all containers ..."
|
||||
-docker rm --force $(shell docker ps -a -q) 2> /dev/null
|
||||
|
||||
dev/%: ARGS?=
|
||||
dev/%: DARGS?=
|
||||
dev/%: PORT?=8888
|
||||
@@ -61,6 +71,20 @@ dev/%: ## run a foreground container for a stack
|
||||
dev-env: ## install libraries required to build docs and run tests
|
||||
pip install -r requirements-dev.txt
|
||||
|
||||
img-clean: img-rm-dang img-rm ## clean dangling and jupyter images
|
||||
|
||||
img-list: ## list jupyter images
|
||||
@echo "Listing $(OWNER) images ..."
|
||||
docker images "$(OWNER)/*"
|
||||
|
||||
img-rm: ## remove jupyter images
|
||||
@echo "Removing $(OWNER) images ..."
|
||||
-docker rmi --force $(shell docker images --quiet "$(OWNER)/*") 2> /dev/null
|
||||
|
||||
img-rm-dang: ## remove dangling images (tagged None)
|
||||
@echo "Removing dangling images ..."
|
||||
-docker rmi --force $(shell docker images -f "dangling=true" -q) 2> /dev/null
|
||||
|
||||
docs: ## build HTML documentation
|
||||
make -C docs html
|
||||
|
||||
@@ -71,11 +95,17 @@ n-docs-diff: ## number of docs/ files changed since branch from master
|
||||
n-other-diff: ## number of files outside docs/ changed since branch from master
|
||||
@git diff --name-only $(DIFF_RANGE) -- ':!docs/' | wc -l | awk '{print $$1}'
|
||||
|
||||
run/%: ## run a bash in interactive mode in a stack
|
||||
docker run -it --rm $(OWNER)/$(notdir $@) $(SHELL)
|
||||
pull/%: DARGS?=
|
||||
pull/%: ## pull a jupyter image
|
||||
docker pull $(DARGS) $(OWNER)/$(notdir $@)
|
||||
|
||||
run/%: DARGS?=
|
||||
run/%: ## run a bash in interactive mode in a stack
|
||||
docker run -it --rm $(DARGS) $(OWNER)/$(notdir $@) $(SHELL)
|
||||
|
||||
run-sudo/%: DARGS?=
|
||||
run-sudo/%: ## run a bash in interactive mode as root in a stack
|
||||
docker run -it --rm -u root $(OWNER)/$(notdir $@) $(SHELL)
|
||||
docker run -it --rm -u root $(DARGS) $(OWNER)/$(notdir $@) $(SHELL)
|
||||
|
||||
tx-en: ## rebuild en locale strings and push to master (req: GH_TOKEN)
|
||||
@git config --global user.email "travis@travis-ci.org"
|
||||
|
@@ -16,7 +16,7 @@ def test_nbconvert(container, format):
|
||||
cont_data_dir = "/home/jovyan/data"
|
||||
test_file = "notebook1"
|
||||
output_dir = "/tmp"
|
||||
LOGGER.info(f"Converting example notebook to {format.upper()} ...")
|
||||
LOGGER.info(f"Test that an example notebook can be converted to {format.upper()} ...")
|
||||
command = f"jupyter nbconvert {cont_data_dir}/{test_file}.ipynb --output-dir {output_dir} --to {format}"
|
||||
c = container.run(
|
||||
volumes={host_data_dir: {"bind": cont_data_dir, "mode": "ro"}},
|
||||
@@ -24,8 +24,8 @@ def test_nbconvert(container, format):
|
||||
command=["start.sh", "bash", "-c", command],
|
||||
)
|
||||
rv = c.wait(timeout=30)
|
||||
assert rv == 0 or rv["StatusCode"] == 0
|
||||
assert rv == 0 or rv["StatusCode"] == 0, f"Command {command} failed"
|
||||
logs = c.logs(stdout=True).decode("utf-8")
|
||||
LOGGER.debug(logs)
|
||||
assert f"{output_dir}/{test_file}.{format}" in logs
|
||||
|
||||
expected_file = f"{output_dir}/{test_file}.{format}"
|
||||
assert expected_file in logs, f"Expected file {expected_file} not generated"
|
||||
|
24
scipy-notebook/test/data/matplotlib_1.py
Normal file
24
scipy-notebook/test/data/matplotlib_1.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Matplotlit: Create a simple plot example.
|
||||
# Refs: https://matplotlib.org/3.1.1/gallery/lines_bars_and_markers/simple_plot.html
|
||||
|
||||
# Optional test with [Matplotlib Jupyter Integration](https://github.com/matplotlib/ipympl)
|
||||
# %matplotlib widget
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
# Data for plotting
|
||||
t = np.arange(0.0, 2.0, 0.01)
|
||||
s = 1 + np.sin(2 * np.pi * t)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(t, s)
|
||||
|
||||
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
|
||||
title='About as simple as it gets, folks')
|
||||
ax.grid()
|
||||
# Note that the test can be run headless by checking if an image is produced
|
||||
file_path = os.path.join("/tmp", "test.png")
|
||||
fig.savefig(file_path)
|
||||
print(f"File {file_path} saved")
|
35
scipy-notebook/test/test_matplotlib.py
Normal file
35
scipy-notebook/test/test_matplotlib.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
import os
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def test_matplotlib(container):
|
||||
"""Test that matplotlib is able to plot a graph and write it as an image"""
|
||||
host_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data")
|
||||
cont_data_dir = "/home/jovyan/data"
|
||||
test_file = "matplotlib_1.py"
|
||||
output_dir = "/tmp"
|
||||
LOGGER.info(f"Test that matplotlib is able to plot a graph and write it as an image ...")
|
||||
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],
|
||||
)
|
||||
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"))
|
||||
# Checking if the file is generated
|
||||
# https://stackoverflow.com/a/15895594/4413446
|
||||
expected_file = f"{output_dir}/test.png"
|
||||
command = f"test -s {expected_file}"
|
||||
cmd = running_container.exec_run(command)
|
||||
assert cmd.exit_code == 0, f"Command {command} failed"
|
||||
LOGGER.debug(cmd.output.decode("utf-8"))
|
@@ -21,6 +21,6 @@ def test_pandas(container, name, command):
|
||||
LOGGER.info(f"Testing pandas: {name} ...")
|
||||
c = container.run(tty=True, command=["start.sh", "python", "-c", command])
|
||||
rv = c.wait(timeout=30)
|
||||
assert rv == 0 or rv["StatusCode"] == 0
|
||||
assert rv == 0 or rv["StatusCode"] == 0, f"Command {command} failed"
|
||||
logs = c.logs(stdout=True).decode("utf-8")
|
||||
LOGGER.debug(logs)
|
||||
|
@@ -25,6 +25,6 @@ def test_tensorflow(container, name, command):
|
||||
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
|
||||
assert rv == 0 or rv["StatusCode"] == 0, f"Command {command} failed"
|
||||
logs = c.logs(stdout=True).decode("utf-8")
|
||||
LOGGER.debug(logs)
|
||||
|
@@ -1,9 +1,10 @@
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
def test_secured_server(container, http_client):
|
||||
"""Notebook server should eventually request user login."""
|
||||
container.run()
|
||||
resp = http_client.get('http://localhost:8888')
|
||||
resp = http_client.get("http://localhost:8888")
|
||||
resp.raise_for_status()
|
||||
assert 'login_submit' in resp.text
|
||||
assert "login_submit" in resp.text, "User login not requested"
|
||||
|
Reference in New Issue
Block a user