Skip to content

Commit

Permalink
Merge pull request #10 from scikit-build/fix-docker-addon
Browse files Browse the repository at this point in the history
Fix docker addon
  • Loading branch information
jcfr committed Oct 29, 2016
2 parents 54b9b99 + 209669a commit 9536e05
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 7 deletions.
11 changes: 11 additions & 0 deletions _tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,14 @@ def captured_lines(cap):
out, err = cap.readouterr()
return (out.replace(os.linesep, "\n").split("\n"),
err.replace(os.linesep, "\n").split("\n"))


def format_args_for_display(args):
"""Format a list of arguments appropriately for display. When formatting
a command and its arguments, the user should be able to execute the
command by copying and pasting the output directly into a shell.
Currently, the only formatting is naively surrounding each argument with
quotation marks.
"""
return ' '.join("\"{}\"".format(arg) for arg in args)
108 changes: 107 additions & 1 deletion _tests/test_scikit_ci_addons.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

import anyci.docker
import ci_addons
import os
import pytest
import subprocess

from . import captured_lines
from . import captured_lines, format_args_for_display


def test_home():
Expand Down Expand Up @@ -65,3 +66,108 @@ def test_cli():
stderr=subprocess.STDOUT,
cwd=str(root)
)


@pytest.mark.parametrize("filename, expected", [
("library/hello-world:latest", "library-hello-world-latest")
])
def test_addon_anyci_docker_get_valid_filename(filename, expected):
assert anyci.docker.get_valid_filename(filename) == expected


def has_docker():
"""Return True if docker executable is found."""
try:
subprocess.check_output(["docker", "--version"])
return True
except (OSError, subprocess.CalledProcessError):
return False


def test_addon_anyci_docker(tmpdir):

test_image = "hello-world"
test_image_filename = test_image + ".tar"

is_circleci = "CIRCLECI" in os.environ
if is_circleci:
assert has_docker(), "docker is expected when running tests on CircleCI"

if not has_docker():
pytest.skip("docker executable not found")

root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
environment = dict(os.environ)
environment['PYTHONPATH'] = root
environment['HOME'] = str(tmpdir)

def _display_cmd(cmd):
print("\nExecuting: {}".format(format_args_for_display(cmd)))

#
# Delete image if any (useful when testing locally)
#
try:
cmd = ["docker", "rmi", test_image]
_display_cmd(cmd)
subprocess.check_output(cmd)
except subprocess.CalledProcessError:
pass

#
# Check load-pull-save works with default cache directory
#
cmd = ["python", "-m",
"ci_addons", "anyci/docker", "--", "load-pull-save", test_image]
_display_cmd(cmd)
output = subprocess.check_output(
cmd,
env=environment,
stderr=subprocess.STDOUT,
cwd=str(root)
)
assert "Status: Downloaded newer image for %s:latest" % test_image in output
assert tmpdir.join("docker", test_image_filename).exists()

#
# Check load-pull-save works with custom cache directory
#
cache_dir = tmpdir.ensure("cache", dir=True)
cmd_with_cache = cmd + ["--cache-dir", str(cache_dir)]
_display_cmd(cmd_with_cache)
output = subprocess.check_output(
cmd_with_cache,
env=environment,
stderr=subprocess.STDOUT,
cwd=str(root)
)
assert "Status: Image is up to date for %s:latest" % test_image in output
assert tmpdir.join("cache", test_image_filename).exists()

#
# Delete the image
#

cmd = ["docker", "rmi", "-f", test_image]
_display_cmd(cmd)
if not is_circleci:
output = subprocess.check_output(cmd)
assert "Untagged: %s@sha256" % test_image in output
assert "Deleted: sha256:" in output
else:
print(" -> Skipping: "
"Not supported on CircleCI because containers can NOT be "
"removed in unprivileged LXC container")

#
# Check load-pull-save restores cached image
#
_display_cmd(cmd_with_cache)
output = subprocess.check_output(
cmd_with_cache,
env=environment,
stderr=subprocess.STDOUT,
cwd=str(root)
)
assert "Status: Image is up to date for %s:latest" % test_image in output
assert tmpdir.join("cache", test_image_filename).exists()
15 changes: 9 additions & 6 deletions anyci/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,22 @@ def _log(*args):
sys.stdout.flush()


def _get_valid_filename(s):
def get_valid_filename(s):
"""
Returns the given string converted to a string that can be used for a clean
filename. Specifically, leading and trailing spaces are removed; other
spaces are converted to underscores; and anything that is not a unicode
alphanumeric, dash, underscore, or dot, is removed.
spaces are converted to underscores; slashes and colons are converted to
dashes; and anything that is not a unicode alphanumeric, dash, underscore,
or dot, is removed.
>>> get_valid_filename("john's portrait in 2004.jpg")
'johns_portrait_in_2004.jpg'
>>> get_valid_filename("library/hello-world:latest")
'library-hello-world-latest'
Copied from https://github.com/django/django/blob/20be1918e77414837178d6bf1657068c8306d50c/django/utils/encoding.py
Distributed under BSD-3 License
""" # noqa: E501
s = s.strip().replace(' ', '_')
s = s.strip().replace(' ', '_').replace('/', '-').replace(':', '-')
return re.sub(r'(?u)[^-\w.]', '', s)


Expand Down Expand Up @@ -79,7 +82,7 @@ def main():

# Convert image to valid filename
image_filename = os.path.join(
cache_dir, _get_valid_filename(args.image) + '.tar')
cache_dir, get_valid_filename(args.image) + '.tar')
_log("Cached image filename:", image_filename)

# If it exists, load cache image
Expand All @@ -97,7 +100,7 @@ def main():

# Cache image
_log("Caching image into:", cache_dir)
cmd = ["docker", "save", args.image, "-o", image_filename]
cmd = ["docker", "save", "-o", image_filename, args.image]
subprocess.check_call(cmd)

if __name__ == '__main__':
Expand Down
2 changes: 2 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
machine:
python:
version: 2.7.11
services:
- docker
environment:
# Used for testing
EXPECTED_PYTHON_VERSION: 2.7.11
Expand Down

0 comments on commit 9536e05

Please sign in to comment.