unpin the requirements and update all to latest available - needs more work still. see notes in def host()

Signed-off-by: Adam Warner <me@adamwarner.co.uk>
This commit is contained in:
Adam Warner 2021-11-11 22:48:01 +00:00
parent cedd1a2591
commit 579cb8e2ad
No known key found for this signature in database
GPG key ID: 872950F3ECF2B173
3 changed files with 257 additions and 247 deletions

View file

@ -1,10 +1,9 @@
import pytest
import testinfra
import subprocess
from testinfra.backend import base
from textwrap import dedent
check_output = testinfra.get_backend(
"local://"
).get_module("Command").check_output
SETUPVARS = {
'PIHOLE_INTERFACE': 'eth99',
@ -12,85 +11,33 @@ SETUPVARS = {
'PIHOLE_DNS_2': '4.2.2.2'
}
IMAGE = 'pytest_pihole:test_container'
tick_box = "[\x1b[1;32m\u2713\x1b[0m]"
cross_box = "[\x1b[1;31m\u2717\x1b[0m]"
info_box = "[i]"
@pytest.fixture
def Pihole(Docker):
'''
used to contain some script stubbing, now pretty much an alias.
Also provides bash as the default run function shell
'''
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
def host():
funcType = type(Docker.run)
Docker.run = funcType(run_bash, Docker)
return Docker
# run a container
docker_id = subprocess.check_output(
['docker', 'run', '-t', '-d', '--cap-add=ALL', IMAGE]).decode().strip()
# return a testinfra connection to the container
docker_host = testinfra.get_host("docker://" + docker_id)
@pytest.fixture
def Docker(request, args, image, cmd):
'''
combine our fixtures into a docker run command and setup finalizer to
cleanup
'''
assert 'docker' in check_output('id'), "Are you in the docker group?"
docker_run = "docker run {} {} {}".format(args, image, cmd)
docker_id = check_output(docker_run)
# Can we override the host.run function here to use /bin/bash instead of /bin/sh?
# So far this works if I run "pytest -vv -n auto test/test_automated_install.py" locally
# but with the caveat that I manually changed "\home\adam\.local\lib\python3.8\site-packages\testinfra\backend\docker.py"
# to use /bin/bash instead of /bin/sh
# this is not ideal!
def teardown():
check_output("docker rm -f %s", docker_id)
request.addfinalizer(teardown)
yield docker_host
# at the end of the test suite, destroy the container
subprocess.check_call(['docker', 'rm', '-f', docker_id])
docker_container = testinfra.get_backend("docker://" + docker_id)
docker_container.id = docker_id
return docker_container
@pytest.fixture
def args(request):
'''
-t became required when tput began being used
'''
return '-t -d --cap-add=ALL'
@pytest.fixture(params=[
'test_container'
])
def tag(request):
'''
consumed by image to make the test matrix
'''
return request.param
@pytest.fixture()
def image(request, tag):
'''
built by test_000_build_containers.py
'''
return 'pytest_pihole:{}'.format(tag)
@pytest.fixture()
def cmd(request):
'''
default to doing nothing by tailing null, but don't exit
'''
return 'tail -f /dev/null'
# Helper functions
@ -129,7 +76,69 @@ def mock_command_passthrough(script, args, container):
Example use-case: mocking `git pull` but still allowing `git clone` to work as intended
'''
orig_script_path = check_output('which {}'.format(script))
orig_script_path = container.check_output('which {}'.format(script))
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
#!/bin/bash -e
echo "\$0 \$@" >> /var/log/{script}
case "\$1" in'''.format(script=script))
for k, v in args.items():
case = dedent('''
{arg})
echo {res}
exit {retcode}
;;'''.format(arg=k, res=v[0], retcode=v[1]))
mock_script += case
mock_script += dedent(r'''
*)
{orig_script_path} "\$@"
;;'''.format(orig_script_path=orig_script_path))
mock_script += dedent('''
esac''')
container.run('''
cat <<EOF> {script}\n{content}\nEOF
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
content=mock_script,
scriptlog=script))
def mock_command_run(script, args, container):
'''
Allows for setup of commands we don't really want to have to run for real
in unit tests
'''
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
#!/bin/bash -e
echo "\$0 \$@" >> /var/log/{script}
case "\$1 \$2" in'''.format(script=script))
for k, v in args.items():
case = dedent('''
\"{arg}\")
echo {res}
exit {retcode}
;;'''.format(arg=k, res=v[0], retcode=v[1]))
mock_script += case
mock_script += dedent('''
esac''')
container.run('''
cat <<EOF> {script}\n{content}\nEOF
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
content=mock_script,
scriptlog=script))
def mock_command_passthrough(script, args, container):
'''
Per other mock_command* functions, allows intercepting of commands we don't want to run for real
in unit tests, however also allows only specific arguments to be mocked. Anything not defined will
be passed through to the actual command.
Example use-case: mocking `git pull` but still allowing `git clone` to work as intended
'''
orig_script_path = container.check_output('which {}'.format(script))
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
#!/bin/bash -e

View file

@ -1,6 +1,6 @@
docker-compose==1.23.2
pytest==4.3.0
pytest-xdist==1.26.1
pytest-cov==2.6.1
testinfra==1.19.0
tox==3.7.0
docker-compose
pytest
pytest-xdist
pytest-cov
testinfra
tox

View file

@ -14,14 +14,14 @@ from .conftest import (
)
def test_supported_package_manager(Pihole):
def test_supported_package_manager(host):
'''
confirm installer exits when no supported package manager found
'''
# break supported package managers
Pihole.run('rm -rf /usr/bin/apt-get')
Pihole.run('rm -rf /usr/bin/rpm')
package_manager_detect = Pihole.run('''
host.run('rm -rf /usr/bin/apt-get')
host.run('rm -rf /usr/bin/rpm')
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
''')
@ -30,7 +30,7 @@ def test_supported_package_manager(Pihole):
# assert package_manager_detect.rc == 1
def test_setupVars_are_sourced_to_global_scope(Pihole):
def test_setupVars_are_sourced_to_global_scope(host):
'''
currently update_dialogs sources setupVars with a dot,
then various other functions use the variables.
@ -40,7 +40,7 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
for k, v in SETUPVARS.items():
setup_var_file += "{}={}\n".format(k, v)
setup_var_file += "EOF\n"
Pihole.run(setup_var_file)
host.run(setup_var_file)
script = dedent('''\
set -e
@ -58,13 +58,13 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
printSetupVars
''')
output = run_script(Pihole, script).stdout
output = run_script(host, script).stdout
for k, v in SETUPVARS.items():
assert "{}={}".format(k, v) in output
def test_setupVars_saved_to_file(Pihole):
def test_setupVars_saved_to_file(host):
'''
confirm saved settings are written to a file for future updates to re-use
'''
@ -72,7 +72,7 @@ def test_setupVars_saved_to_file(Pihole):
set_setup_vars = '\n'
for k, v in SETUPVARS.items():
set_setup_vars += " {}={}\n".format(k, v)
Pihole.run(set_setup_vars).stdout
host.run(set_setup_vars).stdout
script = dedent('''\
set -e
@ -87,17 +87,17 @@ def test_setupVars_saved_to_file(Pihole):
cat /etc/pihole/setupVars.conf
'''.format(set_setup_vars))
output = run_script(Pihole, script).stdout
output = run_script(host, script).stdout
for k, v in SETUPVARS.items():
assert "{}={}".format(k, v) in output
def test_selinux_not_detected(Pihole):
def test_selinux_not_detected(host):
'''
confirms installer continues when SELinux configuration file does not exist
'''
check_selinux = Pihole.run('''
check_selinux = host.run('''
rm -f /etc/selinux/config
source /opt/pihole/basic-install.sh
checkSelinux
@ -107,11 +107,11 @@ def test_selinux_not_detected(Pihole):
assert check_selinux.rc == 0
def test_installPiholeWeb_fresh_install_no_errors(Pihole):
def test_installPiholeWeb_fresh_install_no_errors(host):
'''
confirms all web page assets from Core repo are installed on a fresh build
'''
installWeb = Pihole.run('''
installWeb = host.run('''
umask 0027
source /opt/pihole/basic-install.sh
installPiholeWeb
@ -128,19 +128,19 @@ def test_installPiholeWeb_fresh_install_no_errors(Pihole):
assert expected_stdout in installWeb.stdout
expected_stdout = tick_box + ' Installing sudoer file'
assert expected_stdout in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
web_directory = host.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'blockingpage.css' in web_directory
def get_directories_recursive(Pihole, directory):
def get_directories_recursive(host, directory):
if directory is None:
return directory
ls = Pihole.run('ls -d {}'.format(directory + '/*/'))
ls = host.run('ls -d {}'.format(directory + '/*/'))
directories = list(filter(bool, ls.stdout.splitlines()))
dirs = directories
for dirval in directories:
dir_rec = get_directories_recursive(Pihole, dirval)
dir_rec = get_directories_recursive(host, dirval)
if isinstance(dir_rec, str):
dirs.extend([dir_rec])
else:
@ -148,14 +148,14 @@ def get_directories_recursive(Pihole, directory):
return dirs
def test_installPihole_fresh_install_readableFiles(Pihole):
def test_installPihole_fresh_install_readableFiles(host):
'''
confirms all neccessary files are readable by pihole user
'''
# Whiptail dialog returns Cancel for user prompt
mock_command('whiptail', {'*': ('', '0')}, Pihole)
mock_command('whiptail', {'*': ('', '0')}, host)
# mock git pull
mock_command_passthrough('git', {'pull': ('', '0')}, Pihole)
mock_command_passthrough('git', {'pull': ('', '0')}, host)
# mock systemctl to not start lighttpd and FTL
mock_command_2(
'systemctl',
@ -189,12 +189,12 @@ def test_installPihole_fresh_install_readableFiles(Pihole):
'0'
),
},
Pihole
host
)
# try to install man
Pihole.run('command -v apt-get > /dev/null && apt-get install -qq man')
Pihole.run('command -v dnf > /dev/null && dnf install -y man')
Pihole.run('command -v yum > /dev/null && yum install -y man')
host.run('command -v apt-get > /dev/null && apt-get install -qq man')
host.run('command -v dnf > /dev/null && dnf install -y man')
host.run('command -v yum > /dev/null && yum install -y man')
# create configuration file
setup_var_file = 'cat <<EOF> /etc/pihole/setupVars.conf\n'
for k, v in SETUPVARS.items():
@ -202,8 +202,8 @@ def test_installPihole_fresh_install_readableFiles(Pihole):
setup_var_file += "INSTALL_WEB_SERVER=true\n"
setup_var_file += "INSTALL_WEB_INTERFACE=true\n"
setup_var_file += "EOF\n"
Pihole.run(setup_var_file)
install = Pihole.run('''
host.run(setup_var_file)
install = host.run('''
export TERM=xterm
export DEBIAN_FRONTEND=noninteractive
umask 0027
@ -223,172 +223,172 @@ def test_installPihole_fresh_install_readableFiles(Pihole):
test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}'
# check files in /etc/pihole for read, write and execute permission
check_etc = test_cmd.format('r', '/etc/pihole', piholeuser)
actual_rc = Pihole.run(check_etc).rc
actual_rc = host.run(check_etc).rc
assert exit_status_success == actual_rc
check_etc = test_cmd.format('x', '/etc/pihole', piholeuser)
actual_rc = Pihole.run(check_etc).rc
actual_rc = host.run(check_etc).rc
assert exit_status_success == actual_rc
# readable and writable dhcp.leases
check_leases = test_cmd.format('r', '/etc/pihole/dhcp.leases', piholeuser)
actual_rc = Pihole.run(check_leases).rc
actual_rc = host.run(check_leases).rc
assert exit_status_success == actual_rc
check_leases = test_cmd.format('w', '/etc/pihole/dhcp.leases', piholeuser)
actual_rc = Pihole.run(check_leases).rc
actual_rc = host.run(check_leases).rc
# readable dns-servers.conf
assert exit_status_success == actual_rc
check_servers = test_cmd.format(
'r', '/etc/pihole/dns-servers.conf', piholeuser)
actual_rc = Pihole.run(check_servers).rc
actual_rc = host.run(check_servers).rc
assert exit_status_success == actual_rc
# readable GitHubVersions
check_version = test_cmd.format(
'r', '/etc/pihole/GitHubVersions', piholeuser)
actual_rc = Pihole.run(check_version).rc
actual_rc = host.run(check_version).rc
assert exit_status_success == actual_rc
# readable install.log
check_install = test_cmd.format(
'r', '/etc/pihole/install.log', piholeuser)
actual_rc = Pihole.run(check_install).rc
actual_rc = host.run(check_install).rc
assert exit_status_success == actual_rc
# readable localbranches
check_localbranch = test_cmd.format(
'r', '/etc/pihole/localbranches', piholeuser)
actual_rc = Pihole.run(check_localbranch).rc
actual_rc = host.run(check_localbranch).rc
assert exit_status_success == actual_rc
# readable localversions
check_localversion = test_cmd.format(
'r', '/etc/pihole/localversions', piholeuser)
actual_rc = Pihole.run(check_localversion).rc
actual_rc = host.run(check_localversion).rc
assert exit_status_success == actual_rc
# readable logrotate
check_logrotate = test_cmd.format(
'r', '/etc/pihole/logrotate', piholeuser)
actual_rc = Pihole.run(check_logrotate).rc
actual_rc = host.run(check_logrotate).rc
assert exit_status_success == actual_rc
# readable macvendor.db
check_macvendor = test_cmd.format(
'r', '/etc/pihole/macvendor.db', piholeuser)
actual_rc = Pihole.run(check_macvendor).rc
actual_rc = host.run(check_macvendor).rc
assert exit_status_success == actual_rc
# readable and writeable pihole-FTL.conf
check_FTLconf = test_cmd.format(
'r', '/etc/pihole/pihole-FTL.conf', piholeuser)
actual_rc = Pihole.run(check_FTLconf).rc
actual_rc = host.run(check_FTLconf).rc
assert exit_status_success == actual_rc
check_FTLconf = test_cmd.format(
'w', '/etc/pihole/pihole-FTL.conf', piholeuser)
actual_rc = Pihole.run(check_FTLconf).rc
actual_rc = host.run(check_FTLconf).rc
assert exit_status_success == actual_rc
# readable setupVars.conf
check_setup = test_cmd.format(
'r', '/etc/pihole/setupVars.conf', piholeuser)
actual_rc = Pihole.run(check_setup).rc
actual_rc = host.run(check_setup).rc
assert exit_status_success == actual_rc
# check dnsmasq files
# readable /etc/dnsmasq.conf
check_dnsmasqconf = test_cmd.format(
'r', '/etc/dnsmasq.conf', piholeuser)
actual_rc = Pihole.run(check_dnsmasqconf).rc
actual_rc = host.run(check_dnsmasqconf).rc
assert exit_status_success == actual_rc
# readable /etc/dnsmasq.d/01-pihole.conf
check_dnsmasqconf = test_cmd.format(
'r', '/etc/dnsmasq.d', piholeuser)
actual_rc = Pihole.run(check_dnsmasqconf).rc
actual_rc = host.run(check_dnsmasqconf).rc
assert exit_status_success == actual_rc
check_dnsmasqconf = test_cmd.format(
'x', '/etc/dnsmasq.d', piholeuser)
actual_rc = Pihole.run(check_dnsmasqconf).rc
actual_rc = host.run(check_dnsmasqconf).rc
assert exit_status_success == actual_rc
check_dnsmasqconf = test_cmd.format(
'r', '/etc/dnsmasq.d/01-pihole.conf', piholeuser)
actual_rc = Pihole.run(check_dnsmasqconf).rc
actual_rc = host.run(check_dnsmasqconf).rc
assert exit_status_success == actual_rc
# check readable and executable /etc/init.d/pihole-FTL
check_init = test_cmd.format(
'x', '/etc/init.d/pihole-FTL', piholeuser)
actual_rc = Pihole.run(check_init).rc
actual_rc = host.run(check_init).rc
assert exit_status_success == actual_rc
check_init = test_cmd.format(
'r', '/etc/init.d/pihole-FTL', piholeuser)
actual_rc = Pihole.run(check_init).rc
actual_rc = host.run(check_init).rc
assert exit_status_success == actual_rc
# check readable /etc/lighttpd/lighttpd.conf
check_lighttpd = test_cmd.format(
'r', '/etc/lighttpd/lighttpd.conf', piholeuser)
actual_rc = Pihole.run(check_lighttpd).rc
actual_rc = host.run(check_lighttpd).rc
assert exit_status_success == actual_rc
# check readable and executable manpages
if maninstalled is True:
check_man = test_cmd.format(
'x', '/usr/local/share/man', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'r', '/usr/local/share/man', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'x', '/usr/local/share/man/man8', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'r', '/usr/local/share/man/man8', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'x', '/usr/local/share/man/man5', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'r', '/usr/local/share/man/man5', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'r', '/usr/local/share/man/man8/pihole.8', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'r', '/usr/local/share/man/man8/pihole-FTL.8', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
check_man = test_cmd.format(
'r', '/usr/local/share/man/man5/pihole-FTL.conf.5', piholeuser)
actual_rc = Pihole.run(check_man).rc
actual_rc = host.run(check_man).rc
assert exit_status_success == actual_rc
# check not readable sudoers file
check_sudo = test_cmd.format(
'r', '/etc/sudoers.d/pihole', piholeuser)
actual_rc = Pihole.run(check_sudo).rc
actual_rc = host.run(check_sudo).rc
assert exit_status_success != actual_rc
# check not readable cron file
check_sudo = test_cmd.format(
'x', '/etc/cron.d/', piholeuser)
actual_rc = Pihole.run(check_sudo).rc
actual_rc = host.run(check_sudo).rc
assert exit_status_success == actual_rc
check_sudo = test_cmd.format(
'r', '/etc/cron.d/', piholeuser)
actual_rc = Pihole.run(check_sudo).rc
actual_rc = host.run(check_sudo).rc
assert exit_status_success == actual_rc
check_sudo = test_cmd.format(
'r', '/etc/cron.d/pihole', piholeuser)
actual_rc = Pihole.run(check_sudo).rc
actual_rc = host.run(check_sudo).rc
assert exit_status_success == actual_rc
directories = get_directories_recursive(Pihole, '/etc/.pihole/')
directories = get_directories_recursive(host, '/etc/.pihole/')
for directory in directories:
check_pihole = test_cmd.format('r', directory, piholeuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
check_pihole = test_cmd.format('x', directory, piholeuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
findfiles = 'find "{}" -maxdepth 1 -type f -exec echo {{}} \\;;'
filelist = Pihole.run(findfiles.format(directory))
filelist = host.run(findfiles.format(directory))
files = list(filter(bool, filelist.stdout.splitlines()))
for file in files:
check_pihole = test_cmd.format('r', file, piholeuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
@pytest.mark.parametrize("test_webpage", [True])
def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
'''
confirms all web page assets from Core repo are readable
by $LIGHTTPD_USER on a fresh build
@ -398,9 +398,10 @@ def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
# "pi.hole"
]
# Whiptail dialog returns Cancel for user prompt
mock_command('whiptail', {'*': ('', '0')}, Pihole)
mock_command('whiptail', {'*': ('', '0')}, host)
# mock git pull
mock_command_passthrough('git', {'pull': ('', '0')}, Pihole)
mock_command_passthrough('git', {'pull': ('', '0')}, host)
# mock systemctl to start lighttpd and FTL
ligthttpdcommand = dedent(r'''\"\"
echo 'starting lighttpd with {}'
@ -478,7 +479,7 @@ def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
'0'
),
},
Pihole
host
)
# create configuration file
setup_var_file = 'cat <<EOF> /etc/pihole/setupVars.conf\n'
@ -488,8 +489,8 @@ def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
setup_var_file += "INSTALL_WEB_INTERFACE=true\n"
setup_var_file += "IPV4_ADDRESS=127.0.0.1\n"
setup_var_file += "EOF\n"
Pihole.run(setup_var_file)
installWeb = Pihole.run('''
host.run(setup_var_file)
installWeb = host.run('''
export TERM=xterm
export DEBIAN_FRONTEND=noninteractive
umask 0027
@ -542,55 +543,55 @@ def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
# readable and writeable pihole-FTL.db
check_FTLconf = test_cmd.format(
'r', '/etc/pihole/pihole-FTL.db', piholeuser)
actual_rc = Pihole.run(check_FTLconf).rc
actual_rc = host.run(check_FTLconf).rc
assert exit_status_success == actual_rc
check_FTLconf = test_cmd.format(
'w', '/etc/pihole/pihole-FTL.db', piholeuser)
actual_rc = Pihole.run(check_FTLconf).rc
actual_rc = host.run(check_FTLconf).rc
assert exit_status_success == actual_rc
# check directories above $webroot for read and execute permission
check_var = test_cmd.format('r', '/var', webuser)
actual_rc = Pihole.run(check_var).rc
actual_rc = host.run(check_var).rc
assert exit_status_success == actual_rc
check_var = test_cmd.format('x', '/var', webuser)
actual_rc = Pihole.run(check_var).rc
actual_rc = host.run(check_var).rc
assert exit_status_success == actual_rc
check_www = test_cmd.format('r', '/var/www', webuser)
actual_rc = Pihole.run(check_www).rc
actual_rc = host.run(check_www).rc
assert exit_status_success == actual_rc
check_www = test_cmd.format('x', '/var/www', webuser)
actual_rc = Pihole.run(check_www).rc
actual_rc = host.run(check_www).rc
assert exit_status_success == actual_rc
check_html = test_cmd.format('r', '/var/www/html', webuser)
actual_rc = Pihole.run(check_html).rc
actual_rc = host.run(check_html).rc
assert exit_status_success == actual_rc
check_html = test_cmd.format('x', '/var/www/html', webuser)
actual_rc = Pihole.run(check_html).rc
actual_rc = host.run(check_html).rc
assert exit_status_success == actual_rc
# check directories below $webroot for read and execute permission
check_admin = test_cmd.format('r', webroot + '/admin', webuser)
actual_rc = Pihole.run(check_admin).rc
actual_rc = host.run(check_admin).rc
assert exit_status_success == actual_rc
check_admin = test_cmd.format('x', webroot + '/admin', webuser)
actual_rc = Pihole.run(check_admin).rc
actual_rc = host.run(check_admin).rc
assert exit_status_success == actual_rc
directories = get_directories_recursive(Pihole, webroot + '/admin/*/')
directories = get_directories_recursive(host, webroot + '/admin/*/')
for directory in directories:
check_pihole = test_cmd.format('r', directory, webuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
check_pihole = test_cmd.format('x', directory, webuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
findfiles = 'find "{}" -maxdepth 1 -type f -exec echo {{}} \\;;'
filelist = Pihole.run(findfiles.format(directory))
filelist = host.run(findfiles.format(directory))
files = list(filter(bool, filelist.stdout.splitlines()))
for file in files:
check_pihole = test_cmd.format('r', file, webuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
# check web interface files
# change nameserver to pi-hole
# setting nameserver in /etc/resolv.conf to pi-hole does
# not work here because of the way docker uses this file
ns = Pihole.run(
ns = host.run(
r"sed -i 's/nameserver.*/nameserver 127.0.0.1/' /etc/resolv.conf")
pihole_is_ns = ns.rc == 0
@ -599,19 +600,19 @@ def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
return bool(m)
if installWebInterface is True:
check_pihole = test_cmd.format('r', webroot + '/pihole', webuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
assert exit_status_success == actual_rc
check_pihole = test_cmd.format('x', webroot + '/pihole', webuser)
actual_rc = Pihole.run(check_pihole).rc
actual_rc = host.run(check_pihole).rc
assert exit_status_success == actual_rc
# check most important files in $webroot for read permission
check_index = test_cmd.format(
'r', webroot + '/pihole/index.php', webuser)
actual_rc = Pihole.run(check_index).rc
actual_rc = host.run(check_index).rc
assert exit_status_success == actual_rc
check_blockpage = test_cmd.format(
'r', webroot + '/pihole/blockingpage.css', webuser)
actual_rc = Pihole.run(check_blockpage).rc
actual_rc = host.run(check_blockpage).rc
assert exit_status_success == actual_rc
if test_webpage is True:
# check webpage for unreadable files
@ -631,23 +632,23 @@ def test_installPihole_fresh_install_readableBlockpage(Pihole, test_webpage):
testpage = "http://" + page + "/admin/"
resolvesuccess = True
if is_ip(page) is False:
dig = Pihole.run(digcommand.format(page))
dig = host.run(digcommand.format(page))
testpage = "http://" + dig.stdout.strip() + "/admin/"
resolvesuccess = dig.rc == 0
if resolvesuccess or pihole_is_ns:
# check HTTP status of blockpage
actual_rc = Pihole.run(status.format(testpage))
actual_rc = host.run(status.format(testpage))
assert exit_status_success == actual_rc.rc
# check for PHP error
actual_output = Pihole.run(pagecontent.format(testpage))
actual_output = host.run(pagecontent.format(testpage))
assert noPHPfopen.match(actual_output.stdout) is None
def test_update_package_cache_success_no_errors(Pihole):
def test_update_package_cache_success_no_errors(host):
'''
confirms package cache was updated without any errors
'''
updateCache = Pihole.run('''
updateCache = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
update_package_cache
@ -657,12 +658,12 @@ def test_update_package_cache_success_no_errors(Pihole):
assert 'error' not in updateCache.stdout.lower()
def test_update_package_cache_failure_no_errors(Pihole):
def test_update_package_cache_failure_no_errors(host):
'''
confirms package cache was not updated
'''
mock_command('apt-get', {'update': ('', '1')}, Pihole)
updateCache = Pihole.run('''
mock_command('apt-get', {'update': ('', '1')}, host)
updateCache = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
update_package_cache
@ -672,12 +673,12 @@ def test_update_package_cache_failure_no_errors(Pihole):
assert 'Error: Unable to update package cache.' in updateCache.stdout
def test_FTL_detect_aarch64_no_errors(Pihole):
def test_FTL_detect_aarch64_no_errors(host):
'''
confirms only aarch64 package is downloaded for FTL engine
'''
# mock uname to return aarch64 platform
mock_command('uname', {'-m': ('aarch64', '0')}, Pihole)
mock_command('uname', {'-m': ('aarch64', '0')}, host)
# mock ldd to respond with aarch64 shared library
mock_command(
'ldd',
@ -687,9 +688,9 @@ def test_FTL_detect_aarch64_no_errors(Pihole):
'0'
)
},
Pihole
host
)
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -705,15 +706,15 @@ def test_FTL_detect_aarch64_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv4t_no_errors(Pihole):
def test_FTL_detect_armv4t_no_errors(host):
'''
confirms only armv4t package is downloaded for FTL engine
'''
# mock uname to return armv4t platform
mock_command('uname', {'-m': ('armv4t', '0')}, Pihole)
mock_command('uname', {'-m': ('armv4t', '0')}, host)
# mock ldd to respond with ld-linux shared library
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux.so.3', '0')}, Pihole)
detectPlatform = Pihole.run('''
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux.so.3', '0')}, host)
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -729,15 +730,15 @@ def test_FTL_detect_armv4t_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv5te_no_errors(Pihole):
def test_FTL_detect_armv5te_no_errors(host):
'''
confirms only armv5te package is downloaded for FTL engine
'''
# mock uname to return armv5te platform
mock_command('uname', {'-m': ('armv5te', '0')}, Pihole)
mock_command('uname', {'-m': ('armv5te', '0')}, host)
# mock ldd to respond with ld-linux shared library
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux.so.3', '0')}, Pihole)
detectPlatform = Pihole.run('''
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux.so.3', '0')}, host)
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -753,15 +754,15 @@ def test_FTL_detect_armv5te_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv6l_no_errors(Pihole):
def test_FTL_detect_armv6l_no_errors(host):
'''
confirms only armv6l package is downloaded for FTL engine
'''
# mock uname to return armv6l platform
mock_command('uname', {'-m': ('armv6l', '0')}, Pihole)
mock_command('uname', {'-m': ('armv6l', '0')}, host)
# mock ldd to respond with ld-linux-armhf shared library
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, Pihole)
detectPlatform = Pihole.run('''
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, host)
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -778,15 +779,15 @@ def test_FTL_detect_armv6l_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv7l_no_errors(Pihole):
def test_FTL_detect_armv7l_no_errors(host):
'''
confirms only armv7l package is downloaded for FTL engine
'''
# mock uname to return armv7l platform
mock_command('uname', {'-m': ('armv7l', '0')}, Pihole)
mock_command('uname', {'-m': ('armv7l', '0')}, host)
# mock ldd to respond with ld-linux-armhf shared library
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, Pihole)
detectPlatform = Pihole.run('''
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, host)
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -803,15 +804,15 @@ def test_FTL_detect_armv7l_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv8a_no_errors(Pihole):
def test_FTL_detect_armv8a_no_errors(host):
'''
confirms only armv8a package is downloaded for FTL engine
'''
# mock uname to return armv8a platform
mock_command('uname', {'-m': ('armv8a', '0')}, Pihole)
mock_command('uname', {'-m': ('armv8a', '0')}, host)
# mock ldd to respond with ld-linux-armhf shared library
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, Pihole)
detectPlatform = Pihole.run('''
mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, host)
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -827,11 +828,11 @@ def test_FTL_detect_armv8a_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_x86_64_no_errors(Pihole):
def test_FTL_detect_x86_64_no_errors(host):
'''
confirms only x86_64 package is downloaded for FTL engine
'''
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -847,11 +848,11 @@ def test_FTL_detect_x86_64_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_unknown_no_errors(Pihole):
def test_FTL_detect_unknown_no_errors(host):
''' confirms only generic package is downloaded for FTL engine '''
# mock uname to return generic platform
mock_command('uname', {'-m': ('mips', '0')}, Pihole)
detectPlatform = Pihole.run('''
mock_command('uname', {'-m': ('mips', '0')}, host)
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -863,18 +864,18 @@ def test_FTL_detect_unknown_no_errors(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_FTL_download_aarch64_no_errors(Pihole):
def test_FTL_download_aarch64_no_errors(host):
'''
confirms only aarch64 package is downloaded for FTL engine
'''
# mock whiptail answers and ensure installer dependencies
mock_command('whiptail', {'*': ('', '0')}, Pihole)
Pihole.run('''
mock_command('whiptail', {'*': ('', '0')}, host)
host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
install_dependent_packages ${INSTALLER_DEPS[@]}
''')
download_binary = Pihole.run('''
download_binary = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
FTLinstall "pihole-FTL-aarch64-linux-gnu"
@ -884,11 +885,11 @@ def test_FTL_download_aarch64_no_errors(Pihole):
assert 'error' not in download_binary.stdout.lower()
def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
def test_FTL_binary_installed_and_responsive_no_errors(host):
'''
confirms FTL binary is copied and functional in installed location
'''
installed_binary = Pihole.run('''
installed_binary = host.run('''
source /opt/pihole/basic-install.sh
create_pihole_user
funcOutput=$(get_binary_name)
@ -901,11 +902,11 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
assert expected_stdout in installed_binary.stdout
# def test_FTL_support_files_installed(Pihole):
# def test_FTL_support_files_installed(host):
# '''
# confirms FTL support files are installed
# '''
# support_files = Pihole.run('''
# support_files = host.run('''
# source /opt/pihole/basic-install.sh
# FTLdetect
# stat -c '%a %n' /var/log/pihole-FTL.log
@ -918,7 +919,7 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
# assert '644 /var/log/pihole-FTL.log' in support_files.stdout
def test_IPv6_only_link_local(Pihole):
def test_IPv6_only_link_local(host):
'''
confirms IPv6 blocking is disabled for Link-local address
'''
@ -931,9 +932,9 @@ def test_IPv6_only_link_local(Pihole):
'0'
)
},
Pihole
host
)
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
find_IPv6_information
''')
@ -941,7 +942,7 @@ def test_IPv6_only_link_local(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_IPv6_only_ULA(Pihole):
def test_IPv6_only_ULA(host):
'''
confirms IPv6 blocking is enabled for ULA addresses
'''
@ -954,9 +955,9 @@ def test_IPv6_only_ULA(Pihole):
'0'
)
},
Pihole
host
)
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
find_IPv6_information
''')
@ -964,7 +965,7 @@ def test_IPv6_only_ULA(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_IPv6_only_GUA(Pihole):
def test_IPv6_only_GUA(host):
'''
confirms IPv6 blocking is enabled for GUA addresses
'''
@ -977,9 +978,9 @@ def test_IPv6_only_GUA(Pihole):
'0'
)
},
Pihole
host
)
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
find_IPv6_information
''')
@ -987,7 +988,7 @@ def test_IPv6_only_GUA(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_IPv6_GUA_ULA_test(Pihole):
def test_IPv6_GUA_ULA_test(host):
'''
confirms IPv6 blocking is enabled for GUA and ULA addresses
'''
@ -1001,9 +1002,9 @@ def test_IPv6_GUA_ULA_test(Pihole):
'0'
)
},
Pihole
host
)
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
find_IPv6_information
''')
@ -1011,7 +1012,7 @@ def test_IPv6_GUA_ULA_test(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_IPv6_ULA_GUA_test(Pihole):
def test_IPv6_ULA_GUA_test(host):
'''
confirms IPv6 blocking is enabled for GUA and ULA addresses
'''
@ -1025,9 +1026,9 @@ def test_IPv6_ULA_GUA_test(Pihole):
'0'
)
},
Pihole
host
)
detectPlatform = Pihole.run('''
detectPlatform = host.run('''
source /opt/pihole/basic-install.sh
find_IPv6_information
''')
@ -1035,13 +1036,13 @@ def test_IPv6_ULA_GUA_test(Pihole):
assert expected_stdout in detectPlatform.stdout
def test_validate_ip(Pihole):
def test_validate_ip(host):
'''
Tests valid_ip for various IP addresses
'''
def test_address(addr, success=True):
output = Pihole.run('''
output = host.run('''
source /opt/pihole/basic-install.sh
valid_ip "{addr}"
'''.format(addr=addr))
@ -1076,9 +1077,9 @@ def test_validate_ip(Pihole):
test_address('0.0.0.0#00001', False)
def test_os_check_fails(Pihole):
def test_os_check_fails(host):
''' Confirms install fails on unsupported OS '''
Pihole.run('''
host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
install_dependent_packages ${OS_CHECK_DEPS[@]}
@ -1088,7 +1089,7 @@ def test_os_check_fails(Pihole):
VERSION_ID="2"
EOT
''')
detectOS = Pihole.run('''t
detectOS = host.run('''t
source /opt/pihole/basic-install.sh
os_check
''')
@ -1096,15 +1097,15 @@ def test_os_check_fails(Pihole):
assert expected_stdout in detectOS.stdout
def test_os_check_passes(Pihole):
def test_os_check_passes(host):
''' Confirms OS meets the requirements '''
Pihole.run('''
host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
install_dependent_packages ${OS_CHECK_DEPS[@]}
install_dependent_packages ${INSTALLER_DEPS[@]}
''')
detectOS = Pihole.run('''
detectOS = host.run('''
source /opt/pihole/basic-install.sh
os_check
''')
@ -1112,10 +1113,10 @@ def test_os_check_passes(Pihole):
assert expected_stdout in detectOS.stdout
def test_package_manager_has_installer_deps(Pihole):
def test_package_manager_has_installer_deps(host):
''' Confirms OS is able to install the required packages for the installer'''
mock_command('whiptail', {'*': ('', '0')}, Pihole)
output = Pihole.run('''
mock_command('whiptail', {'*': ('', '0')}, host)
output = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
install_dependent_packages ${INSTALLER_DEPS[@]}
@ -1125,10 +1126,10 @@ def test_package_manager_has_installer_deps(Pihole):
assert output.rc == 0
def test_package_manager_has_pihole_deps(Pihole):
def test_package_manager_has_pihole_deps(host):
''' Confirms OS is able to install the required packages for Pi-hole '''
mock_command('whiptail', {'*': ('', '0')}, Pihole)
output = Pihole.run('''
mock_command('whiptail', {'*': ('', '0')}, host)
output = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
@ -1139,10 +1140,10 @@ def test_package_manager_has_pihole_deps(Pihole):
assert output.rc == 0
def test_package_manager_has_web_deps(Pihole):
def test_package_manager_has_web_deps(host):
''' Confirms OS is able to install the required packages for web '''
mock_command('whiptail', {'*': ('', '0')}, Pihole)
output = Pihole.run('''
mock_command('whiptail', {'*': ('', '0')}, host)
output = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php