diff --git a/test/conftest.py b/test/conftest.py index fb7e1eea..e395ec27 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -6,12 +6,12 @@ from textwrap import dedent SETUPVARS = { - 'PIHOLE_INTERFACE': 'eth99', - 'PIHOLE_DNS_1': '4.2.2.1', - 'PIHOLE_DNS_2': '4.2.2.2' + "PIHOLE_INTERFACE": "eth99", + "PIHOLE_DNS_1": "4.2.2.1", + "PIHOLE_DNS_2": "4.2.2.2", } -IMAGE = 'pytest_pihole:test_container' +IMAGE = "pytest_pihole:test_container" tick_box = "[\x1b[1;32m\u2713\x1b[0m]" cross_box = "[\x1b[1;31m\u2717\x1b[0m]" @@ -38,132 +38,187 @@ testinfra.backend.docker.DockerBackend.run = run_bash @pytest.fixture def host(): # run a container - docker_id = subprocess.check_output( - ['docker', 'run', '-t', '-d', '--cap-add=ALL', IMAGE]).decode().strip() + 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) yield docker_host # at the end of the test suite, destroy the container - subprocess.check_call(['docker', 'rm', '-f', docker_id]) + subprocess.check_call(["docker", "rm", "-f", docker_id]) # Helper functions def mock_command(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'''\ + """ + 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)) + case "\$1" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ {arg}) echo {res} exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(''' - esac''') - container.run(''' + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=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('command -v {}'.format(script)) - full_script_path = '/usr/local/bin/{}'.format(script) - mock_script = dedent(r'''\ + """ + orig_script_path = container.check_output("command -v {}".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)) + case "\$1" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ {arg}) echo {res} exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(r''' + mock_script += dedent( + r""" *) {orig_script_path} "\$@" - ;;'''.format(orig_script_path=orig_script_path)) - mock_script += dedent(''' - esac''') - container.run(''' + ;;""".format( + orig_script_path=orig_script_path + ) + ) + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=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'''\ + """ + 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)) + case "\$1 \$2" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ \"{arg}\") echo {res} exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(''' - esac''') - container.run(''' + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) + rm -f /var/log/{scriptlog}""".format( + script=full_script_path, content=mock_script, scriptlog=script + ) + ) def mock_command_2(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'''\ + """ + 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)) + case "\$1 \$2" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ \"{arg}\") echo \"{res}\" exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(''' - esac''') - container.run(''' + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) + rm -f /var/log/{scriptlog}""".format( + script=full_script_path, content=mock_script, scriptlog=script + ) + ) def run_script(Pihole, script): diff --git a/test/setup.py b/test/setup.py index 9f3b4b48..cdde20d3 100644 --- a/test/setup.py +++ b/test/setup.py @@ -2,6 +2,6 @@ from setuptools import setup setup( py_modules=[], - setup_requires=['pytest-runner'], - tests_require=['pytest'], + setup_requires=["pytest-runner"], + tests_require=["pytest"], ) diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index 70300243..895db6dc 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -10,39 +10,42 @@ from .conftest import ( mock_command_run, mock_command_2, mock_command_passthrough, - run_script + run_script, ) def test_supported_package_manager(host): - ''' + """ confirm installer exits when no supported package manager found - ''' + """ # break supported package managers - host.run('rm -rf /usr/bin/apt-get') - host.run('rm -rf /usr/bin/rpm') - package_manager_detect = host.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 - ''') - expected_stdout = cross_box + ' No supported package manager found' + """ + ) + expected_stdout = cross_box + " No supported package manager found" assert expected_stdout in package_manager_detect.stdout # assert package_manager_detect.rc == 1 def test_setupVars_are_sourced_to_global_scope(host): - ''' + """ currently update_dialogs sources setupVars with a dot, then various other functions use the variables. This confirms the sourced variables are in scope between functions - ''' - setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' + """ + setup_var_file = "cat < /etc/pihole/setupVars.conf\n" for k, v in SETUPVARS.items(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "EOF\n" host.run(setup_var_file) - script = dedent('''\ + script = dedent( + """\ set -e printSetupVars() { # Currently debug test function only @@ -56,7 +59,8 @@ def test_setupVars_are_sourced_to_global_scope(host): } update_dialogs printSetupVars - ''') + """ + ) output = run_script(host, script).stdout @@ -65,16 +69,17 @@ def test_setupVars_are_sourced_to_global_scope(host): def test_setupVars_saved_to_file(host): - ''' + """ confirm saved settings are written to a file for future updates to re-use - ''' + """ # dedent works better with this and padding matching script below - set_setup_vars = '\n' + set_setup_vars = "\n" for k, v in SETUPVARS.items(): set_setup_vars += " {}={}\n".format(k, v) host.run(set_setup_vars) - script = dedent('''\ + script = dedent( + """\ set -e echo start TERM=xterm @@ -85,7 +90,10 @@ def test_setupVars_saved_to_file(host): echo "" > /etc/pihole/pihole-FTL.conf finalExports cat /etc/pihole/setupVars.conf - '''.format(set_setup_vars)) + """.format( + set_setup_vars + ) + ) output = run_script(host, script).stdout @@ -94,48 +102,52 @@ def test_setupVars_saved_to_file(host): def test_selinux_not_detected(host): - ''' + """ confirms installer continues when SELinux configuration file does not exist - ''' - check_selinux = host.run(''' + """ + check_selinux = host.run( + """ rm -f /etc/selinux/config source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = info_box + ' SELinux not detected' + """ + ) + expected_stdout = info_box + " SELinux not detected" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_installPiholeWeb_fresh_install_no_errors(host): - ''' + """ confirms all web page assets from Core repo are installed on a fresh build - ''' - installWeb = host.run(''' + """ + installWeb = host.run( + """ umask 0027 source /opt/pihole/basic-install.sh installPiholeWeb - ''') - expected_stdout = info_box + ' Installing 404 page...' + """ + ) + expected_stdout = info_box + " Installing 404 page..." assert expected_stdout in installWeb.stdout - expected_stdout = tick_box + (' Creating directory for 404 page, ' - 'and copying files') + expected_stdout = tick_box + ( + " Creating directory for 404 page, " "and copying files" + ) assert expected_stdout in installWeb.stdout - expected_stdout = info_box + ' Backing up index.lighttpd.html' + expected_stdout = info_box + " Backing up index.lighttpd.html" assert expected_stdout in installWeb.stdout - expected_stdout = ('No default index.lighttpd.html file found... ' - 'not backing up') + expected_stdout = "No default index.lighttpd.html file found... " "not backing up" assert expected_stdout in installWeb.stdout - expected_stdout = tick_box + ' Installing sudoer file' + expected_stdout = tick_box + " Installing sudoer file" assert expected_stdout in installWeb.stdout - web_directory = host.run('ls -r /var/www/html/pihole').stdout - assert 'index.php' in web_directory + web_directory = host.run("ls -r /var/www/html/pihole").stdout + assert "index.php" in web_directory def get_directories_recursive(host, directory): if directory is None: return directory - ls = host.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: @@ -148,61 +160,41 @@ def get_directories_recursive(host, directory): def test_installPihole_fresh_install_readableFiles(host): - ''' + """ confirms all necessary files are readable by pihole user - ''' + """ # dialog returns Cancel for user prompt - mock_command('dialog', {'*': ('', '0')}, host) + mock_command("dialog", {"*": ("", "0")}, host) # mock git pull - mock_command_passthrough('git', {'pull': ('', '0')}, host) + mock_command_passthrough("git", {"pull": ("", "0")}, host) # mock systemctl to not start lighttpd and FTL mock_command_2( - 'systemctl', + "systemctl", { - 'enable lighttpd': ( - '', - '0' - ), - 'restart lighttpd': ( - '', - '0' - ), - 'start lighttpd': ( - '', - '0' - ), - 'enable pihole-FTL': ( - '', - '0' - ), - 'restart pihole-FTL': ( - '', - '0' - ), - 'start pihole-FTL': ( - '', - '0' - ), - '*': ( - 'echo "systemctl call with $@"', - '0' - ), + "enable lighttpd": ("", "0"), + "restart lighttpd": ("", "0"), + "start lighttpd": ("", "0"), + "enable pihole-FTL": ("", "0"), + "restart pihole-FTL": ("", "0"), + "start pihole-FTL": ("", "0"), + "*": ('echo "systemctl call with $@"', "0"), }, - host + host, ) # try to install 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') + 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 < /etc/pihole/setupVars.conf\n' + setup_var_file = "cat < /etc/pihole/setupVars.conf\n" for k, v in SETUPVARS.items(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "INSTALL_WEB_SERVER=true\n" setup_var_file += "INSTALL_WEB_INTERFACE=true\n" setup_var_file += "EOF\n" host.run(setup_var_file) - install = host.run(''' + install = host.run( + """ export TERM=xterm export DEBIAN_FRONTEND=noninteractive umask 0027 @@ -212,183 +204,164 @@ def test_installPihole_fresh_install_readableFiles(host): runUnattended=true useUpdateVars=true main - ''') + """ + ) assert 0 == install.rc maninstalled = True - if (info_box + ' man not installed') in install.stdout: + if (info_box + " man not installed") in install.stdout: maninstalled = False - piholeuser = 'pihole' + piholeuser = "pihole" exit_status_success = 0 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) + check_etc = test_cmd.format("r", "/etc/pihole", piholeuser) actual_rc = host.run(check_etc).rc assert exit_status_success == actual_rc - check_etc = test_cmd.format('x', '/etc/pihole', piholeuser) + check_etc = test_cmd.format("x", "/etc/pihole", piholeuser) 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) + check_leases = test_cmd.format("r", "/etc/pihole/dhcp.leases", piholeuser) actual_rc = host.run(check_leases).rc assert exit_status_success == actual_rc - check_leases = test_cmd.format('w', '/etc/pihole/dhcp.leases', piholeuser) + check_leases = test_cmd.format("w", "/etc/pihole/dhcp.leases", piholeuser) 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) + check_servers = test_cmd.format("r", "/etc/pihole/dns-servers.conf", piholeuser) actual_rc = host.run(check_servers).rc assert exit_status_success == actual_rc # readable install.log - check_install = test_cmd.format( - 'r', '/etc/pihole/install.log', piholeuser) + check_install = test_cmd.format("r", "/etc/pihole/install.log", piholeuser) actual_rc = host.run(check_install).rc assert exit_status_success == actual_rc # readable versions - check_localversion = test_cmd.format( - 'r', '/etc/pihole/versions', piholeuser) + check_localversion = test_cmd.format("r", "/etc/pihole/versions", piholeuser) 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) + check_logrotate = test_cmd.format("r", "/etc/pihole/logrotate", piholeuser) 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) + check_macvendor = test_cmd.format("r", "/etc/pihole/macvendor.db", piholeuser) 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) + check_FTLconf = test_cmd.format("r", "/etc/pihole/pihole-FTL.conf", piholeuser) 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) + check_FTLconf = test_cmd.format("w", "/etc/pihole/pihole-FTL.conf", piholeuser) 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) + check_setup = test_cmd.format("r", "/etc/pihole/setupVars.conf", piholeuser) 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) + check_dnsmasqconf = test_cmd.format("r", "/etc/dnsmasq.conf", piholeuser) 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) + check_dnsmasqconf = test_cmd.format("r", "/etc/dnsmasq.d", piholeuser) + 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 = host.run(check_dnsmasqconf).rc assert exit_status_success == actual_rc check_dnsmasqconf = test_cmd.format( - 'x', '/etc/dnsmasq.d', piholeuser) - 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) + "r", "/etc/dnsmasq.d/01-pihole.conf", piholeuser + ) 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) + check_init = test_cmd.format("x", "/etc/init.d/pihole-FTL", piholeuser) 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) + check_init = test_cmd.format("r", "/etc/init.d/pihole-FTL", piholeuser) 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) + check_lighttpd = test_cmd.format("r", "/etc/lighttpd/lighttpd.conf", piholeuser) 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) + check_man = test_cmd.format("x", "/usr/local/share/man", piholeuser) + 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 = 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 = 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 = 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 = 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 = host.run(check_man).rc assert exit_status_success == actual_rc check_man = test_cmd.format( - 'r', '/usr/local/share/man', piholeuser) + "r", "/usr/local/share/man/man8/pihole.8", piholeuser + ) 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 = 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 = 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 = 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 = 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 = 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) + "r", "/usr/local/share/man/man8/pihole-FTL.8", piholeuser + ) 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) + check_sudo = test_cmd.format("r", "/etc/sudoers.d/pihole", piholeuser) 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) + check_sudo = test_cmd.format("x", "/etc/cron.d/", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success == actual_rc - check_sudo = test_cmd.format( - 'r', '/etc/cron.d/', piholeuser) + check_sudo = test_cmd.format("r", "/etc/cron.d/", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success == actual_rc - check_sudo = test_cmd.format( - 'r', '/etc/cron.d/pihole', piholeuser) + check_sudo = test_cmd.format("r", "/etc/cron.d/pihole", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success == actual_rc - directories = get_directories_recursive(host, '/etc/.pihole/') + directories = get_directories_recursive(host, "/etc/.pihole/") for directory in directories: - check_pihole = test_cmd.format('r', directory, piholeuser) + check_pihole = test_cmd.format("r", directory, piholeuser) actual_rc = host.run(check_pihole).rc - check_pihole = test_cmd.format('x', directory, piholeuser) + check_pihole = test_cmd.format("x", directory, piholeuser) actual_rc = host.run(check_pihole).rc findfiles = 'find "{}" -maxdepth 1 -type f -exec echo {{}} \\;;' 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) + check_pihole = test_cmd.format("r", file, piholeuser) actual_rc = host.run(check_pihole).rc @pytest.mark.parametrize("test_webpage", [True]) 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 - ''' + """ piholeWebpage = [ "127.0.0.1", # "pi.hole" ] # dialog returns Cancel for user prompt - mock_command('dialog', {'*': ('', '0')}, host) + mock_command("dialog", {"*": ("", "0")}, host) # mock git pull - mock_command_passthrough('git', {'pull': ('', '0')}, host) + mock_command_passthrough("git", {"pull": ("", "0")}, host) # mock systemctl to start lighttpd and FTL - ligthttpdcommand = dedent(r'''\"\" + ligthttpdcommand = dedent( + r'''\"\" echo 'starting lighttpd with {}' if [ command -v "apt-get" >/dev/null 2>&1 ]; then LIGHTTPD_USER="www-data" @@ -418,63 +391,45 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): /usr/sbin/lighttpd -tt -f '{config}' /usr/sbin/lighttpd -f '{config}' echo \"\"'''.format( - '{}', - usergroup='${{LIGHTTPD_USER}}:${{LIGHTTPD_GROUP}}', - chmodarg='{{}}', - config='/etc/lighttpd/lighttpd.conf', - run='/var/run/lighttpd', - cache='/var/cache/lighttpd', - uploads='/var/cache/lighttpd/uploads', - compress='/var/cache/lighttpd/compress' + "{}", + usergroup="${{LIGHTTPD_USER}}:${{LIGHTTPD_GROUP}}", + chmodarg="{{}}", + config="/etc/lighttpd/lighttpd.conf", + run="/var/run/lighttpd", + cache="/var/cache/lighttpd", + uploads="/var/cache/lighttpd/uploads", + compress="/var/cache/lighttpd/compress", ) ) - FTLcommand = dedent('''\"\" + FTLcommand = dedent( + '''\"\" set -x /etc/init.d/pihole-FTL restart - echo \"\"''') + echo \"\"''' + ) mock_command_run( - 'systemctl', + "systemctl", { - 'enable lighttpd': ( - '', - '0' - ), - 'restart lighttpd': ( - ligthttpdcommand.format('restart'), - '0' - ), - 'start lighttpd': ( - ligthttpdcommand.format('start'), - '0' - ), - 'enable pihole-FTL': ( - '', - '0' - ), - 'restart pihole-FTL': ( - FTLcommand, - '0' - ), - 'start pihole-FTL': ( - FTLcommand, - '0' - ), - '*': ( - 'echo "systemctl call with $@"', - '0' - ), + "enable lighttpd": ("", "0"), + "restart lighttpd": (ligthttpdcommand.format("restart"), "0"), + "start lighttpd": (ligthttpdcommand.format("start"), "0"), + "enable pihole-FTL": ("", "0"), + "restart pihole-FTL": (FTLcommand, "0"), + "start pihole-FTL": (FTLcommand, "0"), + "*": ('echo "systemctl call with $@"', "0"), }, - host + host, ) # create configuration file - setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' + setup_var_file = "cat < /etc/pihole/setupVars.conf\n" for k, v in SETUPVARS.items(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "INSTALL_WEB_SERVER=true\n" setup_var_file += "INSTALL_WEB_INTERFACE=true\n" setup_var_file += "EOF\n" host.run(setup_var_file) - installWeb = host.run(''' + installWeb = host.run( + """ export TERM=xterm export DEBIAN_FRONTEND=noninteractive umask 0027 @@ -488,33 +443,32 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): echo "webroot=${webroot}" echo "INSTALL_WEB_INTERFACE=${INSTALL_WEB_INTERFACE}" echo "INSTALL_WEB_SERVER=${INSTALL_WEB_SERVER}" - ''') + """ + ) assert 0 == installWeb.rc - piholeuser = 'pihole' - webuser = '' - user = re.findall( - r"^\s*LIGHTTPD_USER=.*$", installWeb.stdout, re.MULTILINE) + piholeuser = "pihole" + webuser = "" + user = re.findall(r"^\s*LIGHTTPD_USER=.*$", installWeb.stdout, re.MULTILINE) for match in user: - webuser = match.replace('LIGHTTPD_USER=', '').strip() - webroot = '' - user = re.findall( - r"^\s*webroot=.*$", installWeb.stdout, re.MULTILINE) + webuser = match.replace("LIGHTTPD_USER=", "").strip() + webroot = "" + user = re.findall(r"^\s*webroot=.*$", installWeb.stdout, re.MULTILINE) for match in user: - webroot = match.replace('webroot=', '').strip() + webroot = match.replace("webroot=", "").strip() if not webroot.strip(): - webroot = '/var/www/html' + webroot = "/var/www/html" installWebInterface = True interface = re.findall( - r"^\s*INSTALL_WEB_INTERFACE=.*$", installWeb.stdout, re.MULTILINE) + r"^\s*INSTALL_WEB_INTERFACE=.*$", installWeb.stdout, re.MULTILINE + ) for match in interface: - testvalue = match.replace('INSTALL_WEB_INTERFACE=', '').strip().lower() + testvalue = match.replace("INSTALL_WEB_INTERFACE=", "").strip().lower() if not testvalue.strip(): installWebInterface = testvalue == "true" installWebServer = True - server = re.findall( - r"^\s*INSTALL_WEB_SERVER=.*$", installWeb.stdout, re.MULTILINE) + server = re.findall(r"^\s*INSTALL_WEB_SERVER=.*$", installWeb.stdout, re.MULTILINE) for match in server: - testvalue = match.replace('INSTALL_WEB_SERVER=', '').strip().lower() + testvalue = match.replace("INSTALL_WEB_SERVER=", "").strip().lower() if not testvalue.strip(): installWebServer = testvalue == "true" # if webserver install was not requested @@ -525,87 +479,88 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}' # check files that need a running FTL to be created # readable and writeable pihole-FTL.db - check_FTLconf = test_cmd.format( - 'r', '/etc/pihole/pihole-FTL.db', piholeuser) + check_FTLconf = test_cmd.format("r", "/etc/pihole/pihole-FTL.db", piholeuser) 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) + check_FTLconf = test_cmd.format("w", "/etc/pihole/pihole-FTL.db", piholeuser) 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) + check_var = test_cmd.format("r", "/var", webuser) actual_rc = host.run(check_var).rc assert exit_status_success == actual_rc - check_var = test_cmd.format('x', '/var', webuser) + check_var = test_cmd.format("x", "/var", webuser) actual_rc = host.run(check_var).rc assert exit_status_success == actual_rc - check_www = test_cmd.format('r', '/var/www', webuser) + check_www = test_cmd.format("r", "/var/www", webuser) actual_rc = host.run(check_www).rc assert exit_status_success == actual_rc - check_www = test_cmd.format('x', '/var/www', webuser) + check_www = test_cmd.format("x", "/var/www", webuser) actual_rc = host.run(check_www).rc assert exit_status_success == actual_rc - check_html = test_cmd.format('r', '/var/www/html', webuser) + check_html = test_cmd.format("r", "/var/www/html", webuser) actual_rc = host.run(check_html).rc assert exit_status_success == actual_rc - check_html = test_cmd.format('x', '/var/www/html', webuser) + check_html = test_cmd.format("x", "/var/www/html", webuser) 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) + check_admin = test_cmd.format("r", webroot + "/admin", webuser) actual_rc = host.run(check_admin).rc assert exit_status_success == actual_rc - check_admin = test_cmd.format('x', webroot + '/admin', webuser) + check_admin = test_cmd.format("x", webroot + "/admin", webuser) actual_rc = host.run(check_admin).rc assert exit_status_success == actual_rc - directories = get_directories_recursive(host, webroot + '/admin/*/') + directories = get_directories_recursive(host, webroot + "/admin/*/") for directory in directories: - check_pihole = test_cmd.format('r', directory, webuser) + check_pihole = test_cmd.format("r", directory, webuser) actual_rc = host.run(check_pihole).rc - check_pihole = test_cmd.format('x', directory, webuser) + check_pihole = test_cmd.format("x", directory, webuser) actual_rc = host.run(check_pihole).rc findfiles = 'find "{}" -maxdepth 1 -type f -exec echo {{}} \\;;' 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) + check_pihole = test_cmd.format("r", file, webuser) 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 = host.run( - r"sed -i 's/nameserver.*/nameserver 127.0.0.1/' /etc/resolv.conf") + ns = host.run(r"sed -i 's/nameserver.*/nameserver 127.0.0.1/' /etc/resolv.conf") pihole_is_ns = ns.rc == 0 def is_ip(address): m = re.match(r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})", address) return bool(m) + if installWebInterface is True: - check_pihole = test_cmd.format('r', webroot + '/pihole', webuser) + check_pihole = test_cmd.format("r", webroot + "/pihole", webuser) actual_rc = host.run(check_pihole).rc assert exit_status_success == actual_rc - check_pihole = test_cmd.format('x', webroot + '/pihole', webuser) + check_pihole = test_cmd.format("x", webroot + "/pihole", webuser) 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) + check_index = test_cmd.format("r", webroot + "/pihole/index.php", webuser) actual_rc = host.run(check_index).rc assert exit_status_success == actual_rc if test_webpage is True: # check webpage for unreadable files noPHPfopen = re.compile( - (r"PHP Error(%d+):\s+fopen([^)]+):\s+" + - r"failed to open stream: " + - r"Permission denied in"), - re.I) + ( + r"PHP Error(%d+):\s+fopen([^)]+):\s+" + + r"failed to open stream: " + + r"Permission denied in" + ), + re.I, + ) # using cURL option --dns-servers is not possible status = ( - 'curl -s --head "{}" | ' + - 'head -n 1 | ' + - 'grep "HTTP/1.[01] [23].." > /dev/null') + 'curl -s --head "{}" | ' + + "head -n 1 | " + + 'grep "HTTP/1.[01] [23].." > /dev/null' + ) digcommand = r"dig A +short {} @127.0.0.1 | head -n 1" pagecontent = 'curl --verbose -L "{}"' for page in piholeWebpage: @@ -625,258 +580,285 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): def test_update_package_cache_success_no_errors(host): - ''' + """ confirms package cache was updated without any errors - ''' - updateCache = host.run(''' + """ + updateCache = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect update_package_cache - ''') - expected_stdout = tick_box + ' Update local cache of available packages' + """ + ) + expected_stdout = tick_box + " Update local cache of available packages" assert expected_stdout in updateCache.stdout - assert 'error' not in updateCache.stdout.lower() + assert "error" not in updateCache.stdout.lower() def test_update_package_cache_failure_no_errors(host): - ''' + """ confirms package cache was not updated - ''' - mock_command('apt-get', {'update': ('', '1')}, host) - updateCache = host.run(''' + """ + mock_command("apt-get", {"update": ("", "1")}, host) + updateCache = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect update_package_cache - ''') - expected_stdout = cross_box + ' Update local cache of available packages' + """ + ) + expected_stdout = cross_box + " Update local cache of available packages" assert expected_stdout in updateCache.stdout - assert 'Error: Unable to update package cache.' in updateCache.stdout + assert "Error: Unable to update package cache." in updateCache.stdout 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')}, host) + mock_command("uname", {"-m": ("aarch64", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with aarch64 shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-aarch64.so.1', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected AArch64 (64 Bit ARM) processor' + expected_stdout = tick_box + " Detected AArch64 (64 Bit ARM) processor" assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout 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')}, host) + mock_command("uname", {"-m": ("armv4t", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with armv4t shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv4 processor') + expected_stdout = tick_box + (" Detected ARMv4 processor") assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout 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')}, host) + mock_command("uname", {"-m": ("armv5te", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with ld-linux shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv5 (or newer) processor') + expected_stdout = tick_box + (" Detected ARMv5 (or newer) processor") assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout 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')}, host) + mock_command("uname", {"-m": ("armv6l", "0")}, host) # mock ldd to respond with ld-linux-armhf shared library # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-armhf.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv6 processor ' - '(with hard-float support)') + expected_stdout = tick_box + ( + " Detected ARMv6 processor " "(with hard-float support)" + ) assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout 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')}, host) + mock_command("uname", {"-m": ("armv7l", "0")}, host) # mock ldd to respond with ld-linux-armhf shared library # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-armhf.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv7 processor ' - '(with hard-float support)') + expected_stdout = tick_box + ( + " Detected ARMv7 processor " "(with hard-float support)" + ) assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout 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')}, host) + mock_command("uname", {"-m": ("armv8a", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with ld-linux-armhf shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-armhf.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected ARMv8 (or newer) processor' + expected_stdout = tick_box + " Detected ARMv8 (or newer) processor" assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_x86_64_no_errors(host): - ''' + """ confirms only x86_64 package is downloaded for FTL engine - ''' + """ # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected x86_64 processor' + expected_stdout = tick_box + " Detected x86_64 processor" assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_unknown_no_errors(host): - ''' confirms only generic package is downloaded for FTL engine ''' + """confirms only generic package is downloaded for FTL engine""" # mock uname to return generic platform - mock_command('uname', {'-m': ('mips', '0')}, host) + mock_command("uname", {"-m": ("mips", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = 'Not able to detect processor (unknown: mips)' + """ + ) + expected_stdout = "Not able to detect processor (unknown: mips)" assert expected_stdout in detectPlatform.stdout def test_FTL_download_aarch64_no_errors(host): - ''' + """ confirms only aarch64 package is downloaded for FTL engine - ''' + """ # mock dialog answers and ensure installer dependencies - mock_command('dialog', {'*': ('', '0')}, host) - host.run(''' + mock_command("dialog", {"*": ("", "0")}, host) + host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${INSTALLER_DEPS[@]} - ''') - download_binary = host.run(''' + """ + ) + download_binary = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user FTLinstall "pihole-FTL-aarch64-linux-gnu" - ''') - expected_stdout = tick_box + ' Downloading and Installing FTL' + """ + ) + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in download_binary.stdout - assert 'error' not in download_binary.stdout.lower() + assert "error" not in download_binary.stdout.lower() def test_FTL_binary_installed_and_responsive_no_errors(host): - ''' + """ confirms FTL binary is copied and functional in installed location - ''' - installed_binary = host.run(''' + """ + installed_binary = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) @@ -884,176 +866,189 @@ def test_FTL_binary_installed_and_responsive_no_errors(host): binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - version_check = host.run(''' + """ + ) + version_check = host.run( + """ VERSION=$(pihole-FTL version) echo ${VERSION:0:1} - ''') - expected_stdout = 'v' + """ + ) + expected_stdout = "v" assert expected_stdout in version_check.stdout def test_IPv6_only_link_local(host): - ''' + """ confirms IPv6 blocking is disabled for Link-local address - ''' + """ # mock ip -6 address to return Link-local address mock_command_2( - 'ip', - { - '-6 address': ( - 'inet6 fe80::d210:52fa:fe00:7ad7/64 scope link', - '0' - ) - }, - host + "ip", + {"-6 address": ("inet6 fe80::d210:52fa:fe00:7ad7/64 scope link", "0")}, + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = ('Unable to find IPv6 ULA/GUA address') + """ + ) + expected_stdout = "Unable to find IPv6 ULA/GUA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_only_ULA(host): - ''' + """ confirms IPv6 blocking is enabled for ULA addresses - ''' + """ # mock ip -6 address to return ULA address mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 ULA address' + """ + ) + expected_stdout = "Found IPv6 ULA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_only_GUA(host): - ''' + """ confirms IPv6 blocking is enabled for GUA addresses - ''' + """ # mock ip -6 address to return GUA address mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 GUA address' + """ + ) + expected_stdout = "Found IPv6 GUA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_GUA_ULA_test(host): - ''' + """ confirms IPv6 blocking is enabled for GUA and ULA addresses - ''' + """ # mock ip -6 address to return GUA and ULA addresses mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\n' - 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\n" + "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 ULA address' + """ + ) + expected_stdout = "Found IPv6 ULA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_ULA_GUA_test(host): - ''' + """ confirms IPv6 blocking is enabled for GUA and ULA addresses - ''' + """ # mock ip -6 address to return ULA and GUA addresses mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\n' - 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\n" + "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 ULA address' + """ + ) + expected_stdout = "Found IPv6 ULA address" assert expected_stdout in detectPlatform.stdout def test_validate_ip(host): - ''' + """ Tests valid_ip for various IP addresses - ''' + """ def test_address(addr, success=True): - output = host.run(''' + output = host.run( + """ source /opt/pihole/basic-install.sh valid_ip "{addr}" - '''.format(addr=addr)) + """.format( + addr=addr + ) + ) assert output.rc == 0 if success else 1 - test_address('192.168.1.1') - test_address('127.0.0.1') - test_address('255.255.255.255') - test_address('255.255.255.256', False) - test_address('255.255.256.255', False) - test_address('255.256.255.255', False) - test_address('256.255.255.255', False) - test_address('1092.168.1.1', False) - test_address('not an IP', False) - test_address('8.8.8.8#', False) - test_address('8.8.8.8#0') - test_address('8.8.8.8#1') - test_address('8.8.8.8#42') - test_address('8.8.8.8#888') - test_address('8.8.8.8#1337') - test_address('8.8.8.8#65535') - test_address('8.8.8.8#65536', False) - test_address('8.8.8.8#-1', False) - test_address('00.0.0.0', False) - test_address('010.0.0.0', False) - test_address('001.0.0.0', False) - test_address('0.0.0.0#00', False) - test_address('0.0.0.0#01', False) - test_address('0.0.0.0#001', False) - test_address('0.0.0.0#0001', False) - test_address('0.0.0.0#00001', False) + test_address("192.168.1.1") + test_address("127.0.0.1") + test_address("255.255.255.255") + test_address("255.255.255.256", False) + test_address("255.255.256.255", False) + test_address("255.256.255.255", False) + test_address("256.255.255.255", False) + test_address("1092.168.1.1", False) + test_address("not an IP", False) + test_address("8.8.8.8#", False) + test_address("8.8.8.8#0") + test_address("8.8.8.8#1") + test_address("8.8.8.8#42") + test_address("8.8.8.8#888") + test_address("8.8.8.8#1337") + test_address("8.8.8.8#65535") + test_address("8.8.8.8#65536", False) + test_address("8.8.8.8#-1", False) + test_address("00.0.0.0", False) + test_address("010.0.0.0", False) + test_address("001.0.0.0", False) + test_address("0.0.0.0#00", False) + test_address("0.0.0.0#01", False) + test_address("0.0.0.0#001", False) + test_address("0.0.0.0#0001", False) + test_address("0.0.0.0#00001", False) def test_os_check_fails(host): - ''' Confirms install fails on unsupported OS ''' - host.run(''' + """Confirms install fails on unsupported OS""" + host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${OS_CHECK_DEPS[@]} @@ -1062,65 +1057,78 @@ def test_os_check_fails(host): ID=UnsupportedOS VERSION_ID="2" EOT - ''') - detectOS = host.run('''t + """ + ) + detectOS = host.run( + """t source /opt/pihole/basic-install.sh os_check - ''') - expected_stdout = 'Unsupported OS detected: UnsupportedOS' + """ + ) + expected_stdout = "Unsupported OS detected: UnsupportedOS" assert expected_stdout in detectOS.stdout def test_os_check_passes(host): - ''' Confirms OS meets the requirements ''' - host.run(''' + """Confirms OS meets the requirements""" + host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${OS_CHECK_DEPS[@]} install_dependent_packages ${INSTALLER_DEPS[@]} - ''') - detectOS = host.run(''' + """ + ) + detectOS = host.run( + """ source /opt/pihole/basic-install.sh os_check - ''') - expected_stdout = 'Supported OS detected' + """ + ) + expected_stdout = "Supported OS detected" assert expected_stdout in detectOS.stdout def test_package_manager_has_installer_deps(host): - ''' Confirms OS is able to install the required packages for the installer''' - mock_command('dialog', {'*': ('', '0')}, host) - output = host.run(''' + """Confirms OS is able to install the required packages for the installer""" + mock_command("dialog", {"*": ("", "0")}, host) + output = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${INSTALLER_DEPS[@]} - ''') + """ + ) - assert 'No package' not in output.stdout + assert "No package" not in output.stdout assert output.rc == 0 def test_package_manager_has_pihole_deps(host): - ''' Confirms OS is able to install the required packages for Pi-hole ''' - mock_command('dialog', {'*': ('', '0')}, host) - output = host.run(''' + """Confirms OS is able to install the required packages for Pi-hole""" + mock_command("dialog", {"*": ("", "0")}, host) + output = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${PIHOLE_DEPS[@]} - ''') + """ + ) - assert 'No package' not in output.stdout + assert "No package" not in output.stdout assert output.rc == 0 def test_package_manager_has_web_deps(host): - ''' Confirms OS is able to install the required packages for web ''' - mock_command('dialog', {'*': ('', '0')}, host) - output = host.run(''' + """Confirms OS is able to install the required packages for web""" + mock_command("dialog", {"*": ("", "0")}, host) + output = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${PIHOLE_WEB_DEPS[@]} - ''') + """ + ) - assert 'No package' not in output.stdout + assert "No package" not in output.stdout assert output.rc == 0 diff --git a/test/test_any_utils.py b/test/test_any_utils.py index 5126f263..a2604dc2 100644 --- a/test/test_any_utils.py +++ b/test/test_any_utils.py @@ -1,22 +1,27 @@ def test_key_val_replacement_works(host): - ''' Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file ''' - host.run(''' + """Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file""" + host.run( + """ source /opt/pihole/utils.sh addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1" addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2" addOrEditKeyValPair "./testoutput" "KEY_ONE" "value3" addOrEditKeyValPair "./testoutput" "KEY_FOUR" "value4" - ''') - output = host.run(''' + """ + ) + output = host.run( + """ cat ./testoutput - ''') - expected_stdout = 'KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n' + """ + ) + expected_stdout = "KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n" assert expected_stdout == output.stdout def test_key_addition_works(host): - ''' Confirms addKey adds a key (no value) to a file without duplicating it ''' - host.run(''' + """Confirms addKey adds a key (no value) to a file without duplicating it""" + host.run( + """ source /opt/pihole/utils.sh addKey "./testoutput" "KEY_ONE" addKey "./testoutput" "KEY_ONE" @@ -24,17 +29,21 @@ def test_key_addition_works(host): addKey "./testoutput" "KEY_TWO" addKey "./testoutput" "KEY_THREE" addKey "./testoutput" "KEY_THREE" - ''') - output = host.run(''' + """ + ) + output = host.run( + """ cat ./testoutput - ''') - expected_stdout = 'KEY_ONE\nKEY_TWO\nKEY_THREE\n' + """ + ) + expected_stdout = "KEY_ONE\nKEY_TWO\nKEY_THREE\n" assert expected_stdout == output.stdout def test_key_removal_works(host): - ''' Confirms removeKey removes a key or key/value pair ''' - host.run(''' + """Confirms removeKey removes a key or key/value pair""" + host.run( + """ source /opt/pihole/utils.sh addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1" addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2" @@ -42,81 +51,100 @@ def test_key_removal_works(host): addKey "./testoutput" "KEY_FOUR" removeKey "./testoutput" "KEY_TWO" removeKey "./testoutput" "KEY_FOUR" - ''') - output = host.run(''' + """ + ) + output = host.run( + """ cat ./testoutput - ''') - expected_stdout = 'KEY_ONE=value1\nKEY_THREE=value3\n' + """ + ) + expected_stdout = "KEY_ONE=value1\nKEY_THREE=value3\n" assert expected_stdout == output.stdout def test_getFTLAPIPortFile_default(host): - ''' Confirms getFTLAPIPortFile returns the default API port file path ''' - output = host.run(''' + """Confirms getFTLAPIPortFile returns the default API port file path""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLAPIPortFile - ''') - expected_stdout = '/run/pihole-FTL.port\n' + """ + ) + expected_stdout = "/run/pihole-FTL.port\n" assert expected_stdout == output.stdout def test_getFTLAPIPort_default(host): - ''' Confirms getFTLAPIPort returns the default API port ''' - output = host.run(''' + """Confirms getFTLAPIPort returns the default API port""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLAPIPort "/run/pihole-FTL.port" - ''') - expected_stdout = '4711\n' + """ + ) + expected_stdout = "4711\n" assert expected_stdout == output.stdout def test_getFTLAPIPortFile_and_getFTLAPIPort_custom(host): - ''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location ''' - host.run(''' + """Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location""" + host.run( + """ tmpfile=$(mktemp) echo "PORTFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf echo "1234" > ${tmpfile} - ''') - output = host.run(''' + """ + ) + output = host.run( + """ source /opt/pihole/utils.sh FTL_API_PORT_FILE=$(getFTLAPIPortFile) getFTLAPIPort "${FTL_API_PORT_FILE}" - ''') - expected_stdout = '1234\n' + """ + ) + expected_stdout = "1234\n" assert expected_stdout == output.stdout def test_getFTLPIDFile_default(host): - ''' Confirms getFTLPIDFile returns the default PID file path ''' - output = host.run(''' + """Confirms getFTLPIDFile returns the default PID file path""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLPIDFile - ''') - expected_stdout = '/run/pihole-FTL.pid\n' + """ + ) + expected_stdout = "/run/pihole-FTL.pid\n" assert expected_stdout == output.stdout def test_getFTLPID_default(host): - ''' Confirms getFTLPID returns the default value if FTL is not running ''' - output = host.run(''' + """Confirms getFTLPID returns the default value if FTL is not running""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLPID - ''') - expected_stdout = '-1\n' + """ + ) + expected_stdout = "-1\n" assert expected_stdout == output.stdout def test_getFTLPIDFile_and_getFTLPID_custom(host): - ''' Confirms getFTLPIDFile returns a custom PID file path ''' - host.run(''' + """Confirms getFTLPIDFile returns a custom PID file path""" + host.run( + """ tmpfile=$(mktemp) echo "PIDFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf echo "1234" > ${tmpfile} - ''') - output = host.run(''' + """ + ) + output = host.run( + """ source /opt/pihole/utils.sh FTL_PID_FILE=$(getFTLPIDFile) getFTLPID "${FTL_PID_FILE}" - ''') - expected_stdout = '1234\n' + """ + ) + expected_stdout = "1234\n" assert expected_stdout == output.stdout diff --git a/test/test_centos_common_support.py b/test/test_centos_common_support.py index 3497267a..871fee29 100644 --- a/test/test_centos_common_support.py +++ b/test/test_centos_common_support.py @@ -8,17 +8,20 @@ from .conftest import ( def test_enable_epel_repository_centos(host): - ''' + """ confirms the EPEL package repository is enabled when installed on CentOS - ''' - package_manager_detect = host.run(''' + """ + package_manager_detect = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect - ''') - expected_stdout = info_box + (' Enabling EPEL package repository ' - '(https://fedoraproject.org/wiki/EPEL)') + """ + ) + expected_stdout = info_box + ( + " Enabling EPEL package repository " "(https://fedoraproject.org/wiki/EPEL)" + ) assert expected_stdout in package_manager_detect.stdout - expected_stdout = tick_box + ' Installed' + expected_stdout = tick_box + " Installed" assert expected_stdout in package_manager_detect.stdout - epel_package = host.package('epel-release') + epel_package = host.package("epel-release") assert epel_package.is_installed diff --git a/test/test_centos_fedora_common_support.py b/test/test_centos_fedora_common_support.py index df806771..7e0bae4e 100644 --- a/test/test_centos_fedora_common_support.py +++ b/test/test_centos_fedora_common_support.py @@ -6,60 +6,70 @@ from .conftest import ( def mock_selinux_config(state, host): - ''' + """ Creates a mock SELinux config file with expected content - ''' + """ # validate state string - valid_states = ['enforcing', 'permissive', 'disabled'] + valid_states = ["enforcing", "permissive", "disabled"] assert state in valid_states # getenforce returns the running state of SELinux - mock_command('getenforce', {'*': (state.capitalize(), '0')}, host) + mock_command("getenforce", {"*": (state.capitalize(), "0")}, host) # create mock configuration with desired content - host.run(''' + host.run( + """ mkdir /etc/selinux echo "SELINUX={state}" > /etc/selinux/config - '''.format(state=state.lower())) + """.format( + state=state.lower() + ) + ) def test_selinux_enforcing_exit(host): - ''' + """ confirms installer prompts to exit when SELinux is Enforcing by default - ''' + """ mock_selinux_config("enforcing", host) - check_selinux = host.run(''' + check_selinux = host.run( + """ source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = cross_box + ' Current SELinux: enforcing' + """ + ) + expected_stdout = cross_box + " Current SELinux: enforcing" assert expected_stdout in check_selinux.stdout - expected_stdout = 'SELinux Enforcing detected, exiting installer' + expected_stdout = "SELinux Enforcing detected, exiting installer" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 1 def test_selinux_permissive(host): - ''' + """ confirms installer continues when SELinux is Permissive - ''' + """ mock_selinux_config("permissive", host) - check_selinux = host.run(''' + check_selinux = host.run( + """ source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = tick_box + ' Current SELinux: permissive' + """ + ) + expected_stdout = tick_box + " Current SELinux: permissive" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_selinux_disabled(host): - ''' + """ confirms installer continues when SELinux is Disabled - ''' + """ mock_selinux_config("disabled", host) - check_selinux = host.run(''' + check_selinux = host.run( + """ source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = tick_box + ' Current SELinux: disabled' + """ + ) + expected_stdout = tick_box + " Current SELinux: disabled" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 diff --git a/test/test_fedora_support.py b/test/test_fedora_support.py index 57a6c5c4..e7d31a5d 100644 --- a/test/test_fedora_support.py +++ b/test/test_fedora_support.py @@ -1,13 +1,15 @@ def test_epel_and_remi_not_installed_fedora(host): - ''' + """ confirms installer does not attempt to install EPEL/REMI repositories on Fedora - ''' - package_manager_detect = host.run(''' + """ + package_manager_detect = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect - ''') - assert package_manager_detect.stdout == '' + """ + ) + assert package_manager_detect.stdout == "" - epel_package = host.package('epel-release') + epel_package = host.package("epel-release") assert not epel_package.is_installed