Merge pull request #27 from diginc/pytest_params

Refactor testinfra docker to support parametrize
This commit is contained in:
Adam Hill 2016-08-02 23:41:06 -05:00 committed by GitHub
commit 782fb27559
3 changed files with 70 additions and 48 deletions

@ -1 +1 @@
Subproject commit 246599a0ba46f2f63659ba231341b03472ecf9ea
Subproject commit 2e02fc412ab95a55b835aa5777283ad59a4e3458

View File

@ -1,53 +1,55 @@
import pytest
import testinfra
# Use testinfra to get a handy function to run commands locally
check_output = testinfra.get_backend(
"local://"
).get_module("Command").check_output
@pytest.fixture()
def args(request):
return '-e ServerIP="192.168.100.2"'
@pytest.fixture(params=['alpine', 'debian'])
def tag(request):
return request.param
@pytest.fixture
def TestinfraBackend(request):
docker_run = "docker run -d {}".format(request.param)
print docker_run
@pytest.fixture()
def image(request, tag):
return 'diginc/pi-hole:{}'.format(tag)
docker_id = check_output(docker_run)
check_output("docker exec %s sed -i 's/^gravity_spinup/#donotcurl/g' /usr/local/bin/gravity.sh", docker_id)
@pytest.fixture()
def cmd(request):
return '/start.sh'
DEBUG = []
@pytest.fixture()
def Docker(request, LocalCommand, args, image, cmd):
assert 'docker' in LocalCommand.check_output('id'), "Are you in the docker group?"
docker_run = "docker run -d {} {} {}".format(args, image, cmd)
if 'run' in DEBUG:
assert docker_run == 'docker run -d -e ServerIP="192.168.100.2" diginc/pi-hole:alpine /start.sh'
docker_id = LocalCommand.check_output(docker_run)
LocalCommand.check_output("docker exec %s sed -i 's/^gravity_spinup/#donotcurl/g' /usr/local/bin/gravity.sh", docker_id)
def teardown():
check_output("docker rm -f %s", docker_id)
LocalCommand.check_output("docker rm -f %s", docker_id)
request.addfinalizer(teardown)
return testinfra.get_backend("docker://" + docker_id)
def pytest_generate_tests(metafunc):
if "TestinfraBackend" in metafunc.fixturenames:
mark_args = getattr(metafunc.function, "docker_args", None)
docker_args = []
if mark_args is not None:
docker_args = docker_args + list(mark_args.args)
mark_images = getattr(metafunc.function, "docker_images", None)
images = ['diginc/pi-hole:alpine', 'diginc/pi-hole:debian']
if mark_images is not None:
images = mark_images.args
mark_cmd = getattr(metafunc.function, "docker_cmd", None)
command = 'tail -f /dev/null'
if mark_cmd is not None:
command = " ".join(mark_cmd.args)
docker_run_args = []
for img in images:
docker_run_args.append('{} {} {}'.format(" ".join(docker_args),
img, command))
if getattr(metafunc.function, "persistent", None) is not None:
scope = "session"
else:
scope = "function"
metafunc.parametrize(
"TestinfraBackend", docker_run_args, indirect=True, scope=scope)
@pytest.fixture
def Slow():
"""
Run a slow check, check if the state is correct for `timeout` seconds.
"""
import time
def slow(check, timeout=30):
timeout_at = time.time() + timeout
while True:
try:
assert check()
except AssertionError, e:
if timeout_at < time.time():
time.sleep(1)
else:
raise e
else:
return
return slow

View File

@ -1,12 +1,32 @@
import pytest
''' conftest.py provides the defaults through fixtures '''
''' Note, testinfra builtins don't seem fully compatible with
docker containers (esp. alpine) stripped down nature '''
def test_ServerIP_missing_env_triggers_error(Command):
start = Command.run('/start.sh')
def test_pihole_default_run_command(Docker):
expected_proc = '/sbin/tini -- /start.sh'
pgrep = 'pgrep -f "{}" | wc -l || echo 0'.format(expected_proc)
find_proc = Docker.run(pgrep).stdout
if int(find_proc) < 1:
print Docker.run('ps -ef')
print "{} : {}".format(pgrep, find_proc)
assert False, '{}: Couldn\'t find proc {}'.format(tag, expected_proc)
@pytest.mark.parametrize('args', [ '' ])
@pytest.mark.parametrize('cmd', [ 'tail -f /dev/null' ])
def test_ServerIP_missing_triggers_start_error(Docker):
''' When args to docker are empty start.sh exits saying ServerIP is required '''
start = Docker.run('/start.sh')
error_msg = "ERROR: To function correctly you must pass an environment variables of 'ServerIP' into the docker container"
assert start.rc == 1
assert error_msg in start.stdout
@pytest.mark.docker_args('-e ServerIP="192.168.1.2"')
@pytest.mark.docker_cmd('/start.sh')
def test_ServerIP_allows_normal_startup(Command):
assert Command.run('pgrep -f /start.sh | wc') != 0
@pytest.mark.parametrize('tag,webserver', [
( 'alpine', 'nginx' ),
( 'debian', 'lighttpd' )
])
def test_start_launches_dns_and_a_webserver(Docker, webserver, Slow):
''' after we wait for start to finish '''
import time
Socket = Docker.get_module("Socket")
Slow(lambda: Docker.run( 'ps -ef | grep -q "{}"'.format(webserver) ).rc == 0)