2016-07-16 23:00:20 +02:00
|
|
|
import pytest
|
|
|
|
import testinfra
|
|
|
|
|
2016-08-28 07:43:21 +02:00
|
|
|
check_output = testinfra.get_backend(
|
|
|
|
"local://"
|
|
|
|
).get_module("Command").check_output
|
|
|
|
|
2018-08-06 00:58:41 +02:00
|
|
|
def DockerGeneric(request, args, image, cmd, entrypoint=''):
|
2016-08-28 07:43:21 +02:00
|
|
|
assert 'docker' in check_output('id'), "Are you in the docker group?"
|
2018-08-04 20:31:58 +02:00
|
|
|
if 'pihole' in image:
|
2017-12-08 03:27:06 +01:00
|
|
|
args += " --dns 127.0.0.1 -v /dev/null:/etc/pihole/adlists.default -e PYTEST=\"True\""
|
2018-08-06 01:20:55 +02:00
|
|
|
docker_run = "docker run -d {args} {entry} {image} {cmd}".format(args=args, entry=entrypoint, image=image, cmd=cmd)
|
2017-05-14 00:03:24 +02:00
|
|
|
print docker_run
|
2016-08-28 07:43:21 +02:00
|
|
|
docker_id = check_output(docker_run)
|
|
|
|
|
|
|
|
def teardown():
|
2017-05-05 05:37:26 +02:00
|
|
|
check_output("docker logs {}".format(docker_id))
|
|
|
|
check_output("docker rm -f {}".format(docker_id))
|
2016-08-28 07:43:21 +02:00
|
|
|
request.addfinalizer(teardown)
|
|
|
|
|
2016-09-08 06:07:38 +02:00
|
|
|
docker_container = testinfra.get_backend("docker://" + docker_id)
|
|
|
|
docker_container.id = docker_id
|
2017-01-18 05:48:59 +01:00
|
|
|
|
|
|
|
def run_bash(self, command, *args, **kwargs):
|
|
|
|
cmd = self.get_command(command, *args)
|
|
|
|
if self.user is not None:
|
|
|
|
out = self.run_local(
|
|
|
|
"docker exec -u %s %s /bin/bash -c %s",
|
|
|
|
self.user, self.name, cmd)
|
|
|
|
else:
|
|
|
|
out = self.run_local(
|
|
|
|
"docker exec %s /bin/bash -c %s", self.name, cmd)
|
|
|
|
out.command = self.encode(cmd)
|
|
|
|
return out
|
|
|
|
|
|
|
|
funcType = type(docker_container.run)
|
|
|
|
docker_container.run = funcType(run_bash, docker_container, testinfra.backend.docker.DockerBackend)
|
2016-09-08 06:07:38 +02:00
|
|
|
return docker_container
|
2016-08-28 07:43:21 +02:00
|
|
|
|
2018-08-06 00:58:41 +02:00
|
|
|
|
2016-08-28 07:43:21 +02:00
|
|
|
@pytest.fixture
|
2018-08-06 00:58:41 +02:00
|
|
|
def Docker(request, args, image, cmd, entrypoint):
|
2016-08-28 07:43:21 +02:00
|
|
|
''' One-off Docker container run '''
|
2018-08-06 00:58:41 +02:00
|
|
|
return DockerGeneric(request, args, image, cmd, entrypoint)
|
2016-08-28 07:43:21 +02:00
|
|
|
|
2017-05-14 00:03:24 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2016-09-08 06:07:38 +02:00
|
|
|
def DockerPersist(request, persist_args, persist_image, persist_cmd, Dig):
|
2018-08-04 20:31:58 +02:00
|
|
|
''' Persistent Docker container for multiple tests, instead of stopping container after one test '''
|
|
|
|
''' Uses DUP'd module scoped fixtures because smaller scoped fixtures won't mix with module scope '''
|
2016-09-08 06:07:38 +02:00
|
|
|
persistent_container = DockerGeneric(request, persist_args, persist_image, persist_cmd)
|
|
|
|
''' attach a dig conatiner for lookups '''
|
|
|
|
persistent_container.dig = Dig(persistent_container.id)
|
|
|
|
return persistent_container
|
2016-08-28 07:43:21 +02:00
|
|
|
|
2018-08-06 00:58:41 +02:00
|
|
|
@pytest.fixture
|
|
|
|
def entrypoint():
|
|
|
|
return ''
|
|
|
|
|
2016-08-03 05:29:52 +02:00
|
|
|
@pytest.fixture()
|
2016-08-28 07:43:21 +02:00
|
|
|
def args(request):
|
2017-05-14 00:03:24 +02:00
|
|
|
return '-e ServerIP="127.0.0.1" -e ServerIPv6="::1"'
|
2016-07-16 23:00:20 +02:00
|
|
|
|
2018-07-17 06:43:55 +02:00
|
|
|
@pytest.fixture(params=['amd64', 'armel', 'armhf', 'aarch64'])
|
2017-10-05 18:59:19 +02:00
|
|
|
def arch(request):
|
2016-08-03 05:29:52 +02:00
|
|
|
return request.param
|
2016-07-16 23:00:20 +02:00
|
|
|
|
2018-08-04 20:31:58 +02:00
|
|
|
@pytest.fixture()
|
|
|
|
def version(request):
|
|
|
|
''' TODO: include from external .py that can be shared with Dockerfile.py / Tests / deploy scripts '''
|
|
|
|
return 'v4.0'
|
2017-10-05 18:59:19 +02:00
|
|
|
|
|
|
|
@pytest.fixture()
|
2018-08-04 20:31:58 +02:00
|
|
|
def tag(request, version, arch):
|
|
|
|
return '{}_{}'.format(version, arch)
|
2017-10-05 18:59:19 +02:00
|
|
|
|
2016-08-28 07:43:21 +02:00
|
|
|
@pytest.fixture
|
|
|
|
def webserver(request, tag):
|
2018-08-04 20:31:58 +02:00
|
|
|
''' TODO: this is obvious without alpine+nginx as the alternative, remove fixture, hard code lighttpd in tests? '''
|
|
|
|
return 'lighttpd'
|
2016-08-28 07:43:21 +02:00
|
|
|
|
2016-08-03 05:29:52 +02:00
|
|
|
@pytest.fixture()
|
2016-08-28 07:43:21 +02:00
|
|
|
def image(request, tag):
|
2018-08-04 20:31:58 +02:00
|
|
|
image = 'pihole'
|
2017-10-17 06:45:39 +02:00
|
|
|
return '{}:{}'.format(image, tag)
|
2016-08-03 05:29:52 +02:00
|
|
|
|
|
|
|
@pytest.fixture()
|
2016-08-28 07:43:21 +02:00
|
|
|
def cmd(request):
|
2017-05-14 00:03:24 +02:00
|
|
|
return 'tail -f /dev/null'
|
2016-08-03 05:29:52 +02:00
|
|
|
|
2017-11-06 04:30:07 +01:00
|
|
|
@pytest.fixture(scope='module', params=['amd64'])
|
2017-10-19 05:02:23 +02:00
|
|
|
def persist_arch(request):
|
2018-07-03 07:19:01 +02:00
|
|
|
'''amd64 only, dnsmasq/pihole-FTL(?untested?) will not start under qemu-user-static :('''
|
2017-10-19 05:02:23 +02:00
|
|
|
return request.param
|
|
|
|
|
2018-08-04 20:31:58 +02:00
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def persist_version(request):
|
|
|
|
''' TODO: include from external .py that can be shared with Dockerfile.py / Tests / deploy scripts '''
|
|
|
|
return 'v4.0'
|
2017-10-19 05:02:23 +02:00
|
|
|
|
2017-05-14 00:03:24 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2016-08-28 07:43:21 +02:00
|
|
|
def persist_args(request):
|
2017-05-14 00:03:24 +02:00
|
|
|
return '-e ServerIP="127.0.0.1" -e ServerIPv6="::1"'
|
2016-07-16 23:00:20 +02:00
|
|
|
|
2017-10-19 05:02:23 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2018-08-04 20:31:58 +02:00
|
|
|
def persist_tag(request, persist_version, persist_arch):
|
|
|
|
return '{}_{}'.format(persist_version, persist_arch)
|
2016-07-16 23:00:20 +02:00
|
|
|
|
2017-05-14 00:03:24 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2016-08-28 07:43:21 +02:00
|
|
|
def persist_webserver(request, persist_tag):
|
2018-08-04 20:31:58 +02:00
|
|
|
''' TODO: this is obvious without alpine+nginx as the alternative, remove fixture, hard code lighttpd in tests? '''
|
|
|
|
return 'lighttpd'
|
2016-07-16 23:00:20 +02:00
|
|
|
|
2017-05-14 00:03:24 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2016-08-28 07:43:21 +02:00
|
|
|
def persist_image(request, persist_tag):
|
2018-08-04 20:31:58 +02:00
|
|
|
image = 'pihole'
|
2017-10-19 05:24:22 +02:00
|
|
|
return '{}:{}'.format(image, persist_tag)
|
2016-08-28 07:43:21 +02:00
|
|
|
|
2017-05-14 00:03:24 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2016-08-28 07:43:21 +02:00
|
|
|
def persist_cmd(request):
|
2017-05-14 00:03:24 +02:00
|
|
|
return 'tail -f /dev/null'
|
2016-07-16 23:00:20 +02:00
|
|
|
|
2016-08-03 05:29:52 +02:00
|
|
|
@pytest.fixture
|
|
|
|
def Slow():
|
|
|
|
"""
|
|
|
|
Run a slow check, check if the state is correct for `timeout` seconds.
|
|
|
|
"""
|
|
|
|
import time
|
2017-05-14 00:03:24 +02:00
|
|
|
def slow(check, timeout=20):
|
2016-08-03 05:29:52 +02:00
|
|
|
timeout_at = time.time() + timeout
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
assert check()
|
|
|
|
except AssertionError, e:
|
2016-08-28 07:43:21 +02:00
|
|
|
if time.time() < timeout_at:
|
2016-08-03 05:29:52 +02:00
|
|
|
time.sleep(1)
|
|
|
|
else:
|
|
|
|
raise e
|
|
|
|
else:
|
|
|
|
return
|
|
|
|
return slow
|
2016-09-08 06:07:38 +02:00
|
|
|
|
2017-05-14 00:03:24 +02:00
|
|
|
@pytest.fixture(scope='module')
|
2016-09-08 06:07:38 +02:00
|
|
|
def Dig(request):
|
|
|
|
''' separate container to link to pi-hole and perform lookups '''
|
|
|
|
''' a docker pull is faster than running an install of dnsutils '''
|
|
|
|
def dig(docker_id):
|
2016-10-21 05:36:55 +02:00
|
|
|
args = '--link {}:test_pihole'.format(docker_id)
|
2016-09-08 06:07:38 +02:00
|
|
|
image = 'azukiapp/dig'
|
|
|
|
cmd = 'tail -f /dev/null'
|
|
|
|
dig_container = DockerGeneric(request, args, image, cmd)
|
|
|
|
return dig_container
|
|
|
|
return dig
|
|
|
|
|
2016-11-06 20:40:24 +01:00
|
|
|
'''
|
|
|
|
Persistent Docker container for testing service post start.sh
|
|
|
|
'''
|
|
|
|
@pytest.fixture
|
|
|
|
def RunningPiHole(DockerPersist, Slow, persist_webserver):
|
|
|
|
''' Persist a fully started docker-pi-hole to help speed up subsequent tests '''
|
2018-07-03 07:19:01 +02:00
|
|
|
Slow(lambda: DockerPersist.run('pgrep pihole-FTL').rc == 0)
|
2017-01-12 03:12:56 +01:00
|
|
|
Slow(lambda: DockerPersist.run('pgrep {}'.format(persist_webserver) ).rc == 0)
|
2016-11-06 20:40:24 +01:00
|
|
|
return DockerPersist
|