Skip to content

Commit

Permalink
adds testing.docker module to test docker tutorials
Browse files Browse the repository at this point in the history
  • Loading branch information
edublancas committed Jan 3, 2022
1 parent 102f722 commit c1f4384
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/pkgmt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def execute(path, output):
"""Execute rst files
"""
from pkgmt.testing import rst
code = rst.parse_from_path(path)
code = rst.to_script_from_path(path)

if output:
click.echo(f'Writing script to {output}')
Expand Down
73 changes: 73 additions & 0 deletions src/pkgmt/testing/docker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
Testing rst files that call "docker run"
"""
from pathlib import Path

from pkgmt.testing import rst

_template = """\
# exit on error and print each command
set -e
set -x
ROOT=$(pwd)
{code}\
"""


# NOTE: should I modify the command to have the --rm flag?
def _find_docker_run_idx(snippets):
for i, snippet in enumerate(snippets):
if 'docker run' in snippet:
return i

raise ValueError('Did not find "docker run" command')


def _patch_docker_run(snippet):
lines = snippet.splitlines()
idx = None

for i, line in enumerate(lines):
if line.startswith('docker run'):
idx = i

if idx is None:
raise ValueError('Failed to find a line starting with '
f'"docker run", got lines: {lines}')

docker_run_line = lines[idx]

if '-t' not in docker_run_line:
raise ValueError('Expected -t flag to be in the "docker run"'
f' command, got: {docker_run_line!r}')

# cd to $ROOT because the script may have some "cd" commands, and
# we're saving run-in-docker.sh in the initial working directory
lines[idx] = ('cd $ROOT && cat run-in-docker.sh | ' +
docker_run_line.replace('-t ', ''))

return '\n'.join(lines)


def to_script(text):
snippets = rst.to_snippets(text)

idx = _find_docker_run_idx(snippets)

pre, post = snippets[:idx + 1], snippets[idx + 1:]

return pre, post


def to_testing_files(text):
pre, post = to_script(text)
pre[-1] = _patch_docker_run(pre[-1])

Path('test.sh').write_text(_template.format(code='\n\n'.join(pre)))
Path('run-in-docker.sh').write_text(
_template.format(code='\n\n'.join(post)))


def to_testing_files_from_path(path):
to_testing_files(Path(path).read_text())
18 changes: 12 additions & 6 deletions src/pkgmt/testing/rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@
"""


def parse_from_path(path):
return parse(Path(path).read_text())
def to_script_from_path(path):
return to_script(Path(path).read_text())


def parse(content):
def to_snippets(text):
# maybe use sphinx's parser - it should be configured with the custom
# directives
doc = new_document('doc.rst')
doc.settings.pep_references = None
doc.settings.rfc_references = None
# doc.settings.tab_width = None

_parser.parse(content, doc)
_parser.parse(text, doc)

elements = doc.traverse()

Expand All @@ -70,12 +70,18 @@ def previous_not_comment(idx, elements):
return prev.astext() == 'skip-next'

snippets = [
s for i, s in enumerate(selected)
s.astext() for i, s in enumerate(selected)
if not previous_not_comment(i, selected)
and not isinstance(s, nodes.comment)
]

code_user = '\n\n'.join(s.astext() for s in snippets)
return snippets


def to_script(text):
snippets = to_snippets(text)

code_user = '\n\n'.join(snippets)
code_script = _template.format(code=code_user)

return code_script
108 changes: 108 additions & 0 deletions tests/testing/test_docker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from pathlib import Path

import pytest

from pkgmt.testing import docker

simple_in = """\
Some text
.. code-block:: bash
git clone some-repository
cd some-repository
.. code-block:: bash
docker run -i -t some-image /bin/bash
.. code-block:: sh
echo 'hello from docker'
"""

simple_test = """\
# exit on error and print each command
set -e
set -x
ROOT=$(pwd)
git clone some-repository
cd some-repository
cd $ROOT && cat run-in-docker.sh | docker run -i some-image /bin/bash\
"""

simple_run_in_docker = """\
# exit on error and print each command
set -e
set -x
ROOT=$(pwd)
echo 'hello from docker'\
"""

multicommand_in = """\
.. code-block:: bash
git clone some-repository
cd some-repository
.. code-block:: bash
echo hello
docker run -i -t some-image /bin/bash
.. code-block:: sh
echo 'hello from docker'
"""

multicommand_test = """\
# exit on error and print each command
set -e
set -x
ROOT=$(pwd)
git clone some-repository
cd some-repository
echo hello
cd $ROOT && cat run-in-docker.sh | docker run -i some-image /bin/bash\
"""

multicommand_run_in_docker = """\
# exit on error and print each command
set -e
set -x
ROOT=$(pwd)
echo 'hello from docker'\
"""


def test_to_script():
pre, post = docker.to_script(simple_in)
assert pre == [
'git clone some-repository\ncd some-repository',
'docker run -i -t some-image /bin/bash',
]
assert post == ["echo 'hello from docker'"]


@pytest.mark.parametrize('in_, test, run_in_docker', [
[simple_in, simple_test, simple_run_in_docker],
[multicommand_in, multicommand_test, multicommand_run_in_docker],
])
def test_to_testing_files(tmp_empty, in_, test, run_in_docker):
docker.to_testing_files(in_)

test_out = Path('test.sh').read_text()
run_in_docker_out = Path('run-in-docker.sh').read_text()

assert test_out == test
assert run_in_docker_out == run_in_docker
4 changes: 2 additions & 2 deletions tests/testing/test_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@
[simple_in, simple_out],
[skip_in, skip_out],
])
def test_parse(in_, out):
assert rst.parse(in_) == out
def test_to_script(in_, out):
assert rst.to_script(in_) == out

0 comments on commit c1f4384

Please sign in to comment.