From 3b74e8d3e3ad1e51ba598f87611d74e4d9449b1b Mon Sep 17 00:00:00 2001 From: diginc Date: Sun, 28 Aug 2016 00:43:21 -0500 Subject: [PATCH] Tests working again, along with persistent tests with an actual running pi-hole container --- .gitmodules | 2 +- .travis.yml | 2 +- AdminLTE | 2 +- AdminLTE_version.txt | 2 +- alpine.docker | 2 +- alpine/gravity.sh | 6 ++-- alpine/nginx.conf | 2 +- alpine/start.sh | 6 ++-- autotest | 2 +- debian.docker | 3 +- debian/start.sh | 6 ++-- test/conftest.py | 73 +++++++++++++++++++++++++++++++++----------- test/test_start.py | 42 +++++++++++++++++++------ 13 files changed, 107 insertions(+), 43 deletions(-) diff --git a/.gitmodules b/.gitmodules index a808b3a..4ac310c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/pi-hole/pi-hole.git [submodule "AdminLTE"] path = AdminLTE - url = https://github.com/diginc/AdminLTE.git + url = https://github.com/pi-hole/AdminLTE.git diff --git a/.travis.yml b/.travis.yml index bcfe610..655f84e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ python: install: - pip install -r requirements.txt -script: py.test +script: py.test -v diff --git a/AdminLTE b/AdminLTE index 2e02fc4..fa5f2fc 160000 --- a/AdminLTE +++ b/AdminLTE @@ -1 +1 @@ -Subproject commit 2e02fc412ab95a55b835aa5777283ad59a4e3458 +Subproject commit fa5f2fcaf000a9343985dffc9e7382ae1c99b85b diff --git a/AdminLTE_version.txt b/AdminLTE_version.txt index b056e35..b1f7421 100644 --- a/AdminLTE_version.txt +++ b/AdminLTE_version.txt @@ -1 +1 @@ -vDev +v1.4 diff --git a/alpine.docker b/alpine.docker index b39248c..065fab1 100644 --- a/alpine.docker +++ b/alpine.docker @@ -20,7 +20,7 @@ COPY ./pi-hole/advanced/Scripts/* /usr/local/bin/ RUN mkdir -p /opt/ && ln -s /usr/local/bin /opt/pihole COPY ./pi-hole/advanced/dnsmasq.conf.original /etc/dnsmasq.conf COPY ./pi-hole/advanced/01-pihole.conf /etc/dnsmasq.d/ -COPY ./pi-hole/advanced/index.html /var/www/html/pihole/index.html +COPY ./pi-hole/advanced/index* /var/www/html/pihole/ COPY ./pi-hole/advanced/pihole.sudo /etc/sudoers.d/pihole COPY ./AdminLTE /var/www/html/admin COPY ./AdminLTE_version.txt /etc/ diff --git a/alpine/gravity.sh b/alpine/gravity.sh index 3221939..483bd1a 100755 --- a/alpine/gravity.sh +++ b/alpine/gravity.sh @@ -19,7 +19,7 @@ else echo "::: sudo will be used." # Check if it is actually installed # If it isn't, exit because the install cannot complete - if [[ $(dpkg-query -s sudo) ]];then + if [ -x "$(command -v sudo)" ];then export SUDO="sudo" else echo "::: Please install sudo or run this script as root." @@ -152,7 +152,7 @@ function gravity_transport() { fi # Silently curl url - curl -s $cmd_ext $heisenbergCompensator -A "$agent" $url > $patternBuffer + curl -s -L $cmd_ext $heisenbergCompensator -A "$agent" $url > $patternBuffer # Check for list updates gravity_patternCheck "$patternBuffer" # Cleanup @@ -181,7 +181,7 @@ function gravity_spinup() { # to complete properly and reset the user agent when required case "$domain" in "adblock.mahakala.is") - agent='Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' + agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36' cmd_ext="-e http://forum.xda-developers.com/" ;; diff --git a/alpine/nginx.conf b/alpine/nginx.conf index a80b8ca..70c0183 100644 --- a/alpine/nginx.conf +++ b/alpine/nginx.conf @@ -14,7 +14,7 @@ http { server { listen 80; listen [::]:80; - root /var/www/html; + root /var/www/html/pihole; index index.php index.html index.nginx-debian.html; error_page 404 /pihole/index.html; diff --git a/alpine/start.sh b/alpine/start.sh index ea83d51..703d11a 100755 --- a/alpine/start.sh +++ b/alpine/start.sh @@ -13,7 +13,7 @@ echo "env[ServerIP] = ${ServerIP}" >> $PHP_ENV_CONFIG; if [ -n "$VIRTUAL_HOST" ] ; then echo "env[VIRTUAL_HOST] = ${VIRTUAL_HOST}" >> $PHP_ENV_CONFIG; -else +else echo "env[VIRTUAL_HOST] = ${ServerIP}" >> $PHP_ENV_CONFIG; fi; @@ -23,7 +23,7 @@ cat $PHP_ENV_CONFIG dnsType='default' DNS1=${DNS1:-'8.8.8.8'} DNS2=${DNS2:-'8.8.4.4'} -if [ "$DNS1" != '8.8.8.8' ] || [ "$DNS2" != '8.8.4.4' ] ; then +if [ "$DNS1" != '8.8.8.8' ] || [ "$DNS2" != '8.8.4.4' ] ; then dnsType='custom' fi; @@ -34,7 +34,9 @@ sed -i "s/@DNS2@/$DNS2/" /etc/dnsmasq.d/01-pihole.conf && \ dnsmasq --test -7 /etc/dnsmasq.d || exit 1 php-fpm -t || exit 1 nginx -t || exit 1 +echo " :: All config checks passed, starting ..." +if [ -n "$PYTEST" ] ; then sed -i 's/^gravity_spinup/#donotcurl/g' `which gravity.sh`; fi; gravity.sh dnsmasq -7 /etc/dnsmasq.d php-fpm diff --git a/autotest b/autotest index 6ce3ed5..3747cc0 100755 --- a/autotest +++ b/autotest @@ -1 +1 @@ -py.test -f test/ +py.test -v -f test/ diff --git a/debian.docker b/debian.docker index 5fae7c2..71fd761 100644 --- a/debian.docker +++ b/debian.docker @@ -26,7 +26,8 @@ RUN mkdir -p /opt/ && ln -s /usr/local/bin /opt/pihole COPY ./pi-hole/advanced/lighttpd.conf.debian /etc/lighttpd/lighttpd.conf COPY ./pi-hole/advanced/dnsmasq.conf.original /etc/dnsmasq.conf COPY ./pi-hole/advanced/01-pihole.conf /etc/dnsmasq.d/ -COPY ./pi-hole/advanced/index.html /var/www/html/pihole/index.html +COPY ./pi-hole/advanced/index* /var/www/html/pihole/ +RUN rm /var/www/html/index.lighttpd.html COPY ./pi-hole/advanced/pihole.sudo /etc/sudoers.d/pihole COPY ./AdminLTE /var/www/html/admin COPY ./AdminLTE_version.txt /etc/ diff --git a/debian/start.sh b/debian/start.sh index 9e1d517..02797cb 100755 --- a/debian/start.sh +++ b/debian/start.sh @@ -11,7 +11,7 @@ sed -i "/bin-environment/ a\\\t\t\t\"PHP_ERROR_LOG\" => \"${PHP_ERROR_LOG}\"," $ if [ -n "$VIRTUAL_HOST" ] ; then sed -i "/bin-environment/ a\\\t\t\t\"VIRTUAL_HOST\" => \"${VIRTUAL_HOST}\"," $PHP_ENV_CONFIG -else +else sed -i "/bin-environment/ a\\\t\t\t\"VIRTUAL_HOST\" => \"${ServerIP}\"," $PHP_ENV_CONFIG fi; @@ -21,7 +21,7 @@ grep -E '(VIRTUAL_HOST|ServerIP)' $PHP_ENV_CONFIG dnsType='default' DNS1=${DNS1:-'8.8.8.8'} DNS2=${DNS2:-'8.8.4.4'} -if [ "$DNS1" != '8.8.8.8' ] || [ "$DNS2" != '8.8.4.4' ] ; then +if [ "$DNS1" != '8.8.8.8' ] || [ "$DNS2" != '8.8.4.4' ] ; then dnsType='custom' fi; @@ -31,7 +31,9 @@ sed -i "s/@DNS2@/$DNS2/" /etc/dnsmasq.d/01-pihole.conf && \ dnsmasq --test -7 /etc/dnsmasq.d || exit 1 lighttpd -t -f /etc/lighttpd/lighttpd.conf || exit 1 +echo " :: All config checks passed, starting ..." +if [ -n "$PYTEST" ] ; then sed -i 's/^gravity_spinup/#donotcurl/g' `which gravity.sh`; fi; gravity.sh # dnsmasq start included service lighttpd start diff --git a/test/conftest.py b/test/conftest.py index d49a236..01c3330 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -1,38 +1,75 @@ import pytest import testinfra +DEBUG = [] + +check_output = testinfra.get_backend( + "local://" +).get_module("Command").check_output + +def DockerGeneric(request, args, image, cmd): + assert 'docker' in check_output('id'), "Are you in the docker group?" + docker_run = "docker run -d -e PYTEST=\"True\" {} {} {}".format(args, image, cmd) + docker_id = check_output(docker_run) + + def teardown(): + check_output("docker stop %s", docker_id) + check_output("docker rm %s", docker_id) + request.addfinalizer(teardown) + + return testinfra.get_backend("docker://" + docker_id) + +@pytest.fixture +def Docker(request, args, image, cmd): + ''' One-off Docker container run ''' + return DockerGeneric(request, args, image, cmd) + +@pytest.fixture(scope='session') +def DockerPersist(request, persist_args, persist_image, persist_cmd): + ''' Persistent Docker container for multiple tests ''' + return DockerGeneric(request, persist_args, persist_image, persist_cmd) + @pytest.fixture() -def args(request): +def args(request): return '-e ServerIP="192.168.100.2"' @pytest.fixture(params=['alpine', 'debian']) def tag(request): return request.param +@pytest.fixture +@pytest.mark.parametrize('tag,webserver', [ ( 'alpine', 'nginx' ), ( 'debian', 'lighttpd' ) ]) +def webserver(request, tag): + return webserver + @pytest.fixture() -def image(request, tag): +def image(request, tag): return 'diginc/pi-hole:{}'.format(tag) @pytest.fixture() -def cmd(request): +def cmd(request): return '/start.sh' -DEBUG = [] +@pytest.fixture(scope='session') +def persist_args(request): + return '-e ServerIP="192.168.100.2"' -@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) +@pytest.fixture(scope='session', params=['alpine', 'debian']) +def persist_tag(request): + return request.param - def teardown(): - LocalCommand.check_output("docker rm -f %s", docker_id) - request.addfinalizer(teardown) +@pytest.fixture(scope='session') +def persist_webserver(request, persist_tag): + web_dict = { 'alpine': 'nginx', 'debian': 'lighttpd' } + return web_dict[persist_tag] - return testinfra.get_backend("docker://" + docker_id) +@pytest.fixture(scope='session') +def persist_image(request, persist_tag): + return 'diginc/pi-hole:{}'.format(persist_tag) + +@pytest.fixture(scope='session') +def persist_cmd(request): + return '/start.sh' @pytest.fixture def Slow(): @@ -40,13 +77,13 @@ def Slow(): Run a slow check, check if the state is correct for `timeout` seconds. """ import time - def slow(check, timeout=30): + def slow(check, timeout=15): timeout_at = time.time() + timeout while True: try: assert check() except AssertionError, e: - if timeout_at < time.time(): + if time.time() < timeout_at: time.sleep(1) else: raise e diff --git a/test/test_start.py b/test/test_start.py index 3c9ce8d..b3798d1 100644 --- a/test/test_start.py +++ b/test/test_start.py @@ -1,6 +1,7 @@ import pytest +import time ''' conftest.py provides the defaults through fixtures ''' -''' Note, testinfra builtins don't seem fully compatible with +''' Note, testinfra builtins don't seem fully compatible with docker containers (esp. alpine) stripped down nature ''' def test_pihole_default_run_command(Docker): @@ -21,12 +22,33 @@ def test_ServerIP_missing_triggers_start_error(Docker): assert start.rc == 1 assert error_msg in start.stdout -@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) +@pytest.fixture +def RunningPiHole(DockerPersist, Slow, persist_webserver): + ''' Persist a docker and provide some parameterized data for re-use ''' + Slow(lambda: DockerPersist.run( 'pgrep {}'.format(persist_webserver) ).rc == 0) + return DockerPersist + +def test_indecies_are_present(RunningPiHole): + File = RunningPiHole.get_module('File') + File('/var/www/html/pihole/index.html').exists + File('/var/www/html/pihole/index.js').exists + +@pytest.mark.parametrize('url', [ '/' ] ) +#@pytest.mark.parametrize('url', [ '/', '/index.html', 'any.html' ] ) +def test_html_index_requests_load_as_expected(RunningPiHole, url): + command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://127.0.0.1{}'.format(url) + print command + http_rc = RunningPiHole.run(command) + print RunningPiHole.run('ls -lat /tmp/curled_file').stdout + print RunningPiHole.run('cat /tmp/curled_file').stdout + assert RunningPiHole.run('md5sum /tmp/curled_file /var/www/html/pihole/index.html').rc == 0 + assert int(http_rc.stdout) == 200 + +@pytest.mark.parametrize('url', [ '/index.js' ] ) +#@pytest.mark.parametrize('url', [ '/index.js', '/any.js'] ) +def test_javascript_requests_load_as_expected(RunningPiHole, url): + command = 'curl -s -o /tmp/curled_file -w "%{{http_code}}" http://127.0.0.1{}'.format(url) + print command + http_rc = RunningPiHole.run(command) + assert RunningPiHole.run('md5sum /tmp/curled_file /var/www/html/pihole/index.js').rc == 0 + assert int(http_rc.stdout) == 200