From 9d3d33b6a276a7c94159b4f20429956615362093 Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 26 Jun 2018 00:09:30 -0600 Subject: [PATCH 01/21] add tests for selinux checking Signed-off-by: bcambl --- .gitignore | 1 + test/test_automated_install.py | 50 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/.gitignore b/.gitignore index 73f14ae3..91bb6aff 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.swp __pycache__ .cache +.pytest_cache # Created by https://www.gitignore.io/api/jetbrains+iml diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 2c65c660..684b7004 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -173,6 +173,56 @@ def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' in firewall_calls assert 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' in firewall_calls +def test_selinux_enforcing_default_exit(Pihole): + ''' confirms installer prompts to exit when SELinux is Enforcing by default ''' + # getenforce returns the running state of SELinux + mock_command('getenforce', {'*':('Enforcing', '0')}, Pihole) + # Whiptail dialog returns Cancel for user prompt + mock_command('whiptail', {'*':('', '1')}, Pihole) + check_selinux = Pihole.run(''' + source /opt/pihole/basic-install.sh + checkSelinux + ''') + assert info_box + ' SELinux mode detected: Enforcing' in check_selinux.stdout + assert 'SELinux Enforcing detected, exiting installer' in check_selinux.stdout + assert check_selinux.rc == 1 + +def test_selinux_enforcing_continue(Pihole): + ''' confirms installer prompts to continue with custom policy warning ''' + # getenforce returns the running state of SELinux + mock_command('getenforce', {'*':('Enforcing', '0')}, Pihole) + # Whiptail dialog returns Cancel for user prompt + mock_command('whiptail', {'*':('', '0')}, Pihole) + check_selinux = Pihole.run(''' + source /opt/pihole/basic-install.sh + checkSelinux + ''') + assert info_box + ' SELinux mode detected: Enforcing' in check_selinux.stdout + assert info_box + ' Continuing installation with SELinux Enforcing' in check_selinux.stdout + assert info_box + ' Please refer to official SELinux documentation to create a custom policy' in check_selinux.stdout + assert check_selinux.rc == 0 + +def test_selinux_permissive(Pihole): + ''' confirms installer continues when SELinux is Permissive ''' + # getenforce returns the running state of SELinux + mock_command('getenforce', {'*':('Permissive', '0')}, Pihole) + check_selinux = Pihole.run(''' + source /opt/pihole/basic-install.sh + checkSelinux + ''') + assert info_box + ' SELinux mode detected: Permissive' in check_selinux.stdout + assert check_selinux.rc == 0 + +def test_selinux_disabled(Pihole): + ''' confirms installer continues when SELinux is Disabled ''' + mock_command('getenforce', {'*':('Disabled', '0')}, Pihole) + check_selinux = Pihole.run(''' + source /opt/pihole/basic-install.sh + checkSelinux + ''') + assert info_box + ' SELinux mode detected: Disabled' in check_selinux.stdout + assert check_selinux.rc == 0 + def test_installPiholeWeb_fresh_install_no_errors(Pihole): ''' confirms all web page assets from Core repo are installed on a fresh build ''' installWeb = Pihole.run(''' From 4468d81472cf43cb4d83909d3ca642499b6660a2 Mon Sep 17 00:00:00 2001 From: bcambl Date: Mon, 2 Jul 2018 14:54:19 -0600 Subject: [PATCH 02/21] python linting: 2 lines prior to defs (E302) Signed-off-by: bcambl --- test/conftest.py | 6 ++++++ test/test_000_build_containers.py | 1 + test/test_automated_install.py | 33 +++++++++++++++++++++++++++++++ test/test_shellcheck.py | 1 + 4 files changed, 41 insertions(+) diff --git a/test/conftest.py b/test/conftest.py index 5960cc24..44e0a4a4 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -5,6 +5,7 @@ check_output = testinfra.get_backend( "local://" ).get_module("Command").check_output + @pytest.fixture def Pihole(Docker): ''' used to contain some script stubbing, now pretty much an alias. @@ -25,6 +26,7 @@ def Pihole(Docker): Docker.run = funcType(run_bash, Docker, testinfra.backend.docker.DockerBackend) return Docker + @pytest.fixture def Docker(request, args, image, cmd): ''' combine our fixtures into a docker run command and setup finalizer to cleanup ''' @@ -40,21 +42,25 @@ def Docker(request, args, image, cmd): docker_container.id = docker_id return docker_container + @pytest.fixture def args(request): ''' -t became required when tput began being used ''' return '-t -d' + @pytest.fixture(params=['debian', 'centos']) 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 ''' diff --git a/test/test_000_build_containers.py b/test/test_000_build_containers.py index c617f3ae..725136d8 100644 --- a/test/test_000_build_containers.py +++ b/test/test_000_build_containers.py @@ -6,6 +6,7 @@ run_local = testinfra.get_backend( "local://" ).get_module("Command").run + @pytest.mark.parametrize("image,tag", [ ( 'test/debian.Dockerfile', 'pytest_pihole:debian' ), ( 'test/centos.Dockerfile', 'pytest_pihole:centos' ), diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 684b7004..f7b8702d 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -13,6 +13,7 @@ tick_box="[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8") cross_box="[\x1b[1;31m\xe2\x9c\x97\x1b[0m]".decode("utf-8") info_box="[i]".decode("utf-8") + def test_setupVars_are_sourced_to_global_scope(Pihole): ''' currently update_dialogs sources setupVars with a dot, then various other functions use the variables. @@ -46,6 +47,7 @@ def test_setupVars_are_sourced_to_global_scope(Pihole): for k,v in SETUPVARS.iteritems(): assert "{}={}".format(k, v) in output + def test_setupVars_saved_to_file(Pihole): ''' confirm saved settings are written to a file for future updates to re-use ''' set_setup_vars = '\n' # dedent works better with this and padding matching script below @@ -70,6 +72,7 @@ def test_setupVars_saved_to_file(Pihole): for k,v in SETUPVARS.iteritems(): assert "{}={}".format(k, v) in output + def test_configureFirewall_firewalld_running_no_errors(Pihole): ''' confirms firewalld rules are applied when firewallD is running ''' # firewallD returns 'running' as status @@ -87,6 +90,7 @@ def test_configureFirewall_firewalld_running_no_errors(Pihole): assert 'firewall-cmd --permanent --add-service=http --add-service=dns' in firewall_calls assert 'firewall-cmd --reload' in firewall_calls + def test_configureFirewall_firewalld_disabled_no_errors(Pihole): ''' confirms firewalld rules are not applied when firewallD is not running ''' # firewallD returns non-running status @@ -98,6 +102,7 @@ def test_configureFirewall_firewalld_disabled_no_errors(Pihole): expected_stdout = 'No active firewall detected.. skipping firewall configuration' assert expected_stdout in configureFirewall.stdout + def test_configureFirewall_firewalld_enabled_declined_no_errors(Pihole): ''' confirms firewalld rules are not applied when firewallD is running, user declines ruleset ''' # firewallD returns running status @@ -111,6 +116,7 @@ def test_configureFirewall_firewalld_enabled_declined_no_errors(Pihole): expected_stdout = 'Not installing firewall rulesets.' assert expected_stdout in configureFirewall.stdout + def test_configureFirewall_no_firewall(Pihole): ''' confirms firewall skipped no daemon is running ''' configureFirewall = Pihole.run(''' @@ -120,6 +126,7 @@ def test_configureFirewall_no_firewall(Pihole): expected_stdout = 'No active firewall detected' assert expected_stdout in configureFirewall.stdout + def test_configureFirewall_IPTables_enabled_declined_no_errors(Pihole): ''' confirms IPTables rules are not applied when IPTables is running, user declines ruleset ''' # iptables command exists @@ -135,6 +142,7 @@ def test_configureFirewall_IPTables_enabled_declined_no_errors(Pihole): expected_stdout = 'Not installing firewall rulesets.' assert expected_stdout in configureFirewall.stdout + def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): ''' confirms IPTables rules are not applied when IPTables is running and rules exist ''' # iptables command exists and returns 0 on calls (should return 0 on iptables -C) @@ -154,6 +162,7 @@ def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' not in firewall_calls assert 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' not in firewall_calls + def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): ''' confirms IPTables rules are applied when IPTables is running and rules do not exist ''' # iptables command and returns 0 on calls (should return 1 on iptables -C) @@ -173,6 +182,7 @@ def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' in firewall_calls assert 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' in firewall_calls + def test_selinux_enforcing_default_exit(Pihole): ''' confirms installer prompts to exit when SELinux is Enforcing by default ''' # getenforce returns the running state of SELinux @@ -187,6 +197,7 @@ def test_selinux_enforcing_default_exit(Pihole): assert 'SELinux Enforcing detected, exiting installer' in check_selinux.stdout assert check_selinux.rc == 1 + def test_selinux_enforcing_continue(Pihole): ''' confirms installer prompts to continue with custom policy warning ''' # getenforce returns the running state of SELinux @@ -202,6 +213,7 @@ def test_selinux_enforcing_continue(Pihole): assert info_box + ' Please refer to official SELinux documentation to create a custom policy' in check_selinux.stdout assert check_selinux.rc == 0 + def test_selinux_permissive(Pihole): ''' confirms installer continues when SELinux is Permissive ''' # getenforce returns the running state of SELinux @@ -213,6 +225,7 @@ def test_selinux_permissive(Pihole): assert info_box + ' SELinux mode detected: Permissive' in check_selinux.stdout assert check_selinux.rc == 0 + def test_selinux_disabled(Pihole): ''' confirms installer continues when SELinux is Disabled ''' mock_command('getenforce', {'*':('Disabled', '0')}, Pihole) @@ -223,6 +236,7 @@ def test_selinux_disabled(Pihole): assert info_box + ' SELinux mode detected: Disabled' in check_selinux.stdout assert check_selinux.rc == 0 + def test_installPiholeWeb_fresh_install_no_errors(Pihole): ''' confirms all web page assets from Core repo are installed on a fresh build ''' installWeb = Pihole.run(''' @@ -238,6 +252,7 @@ def test_installPiholeWeb_fresh_install_no_errors(Pihole): assert 'index.php' in web_directory assert 'blockingpage.css' in web_directory + def test_update_package_cache_success_no_errors(Pihole): ''' confirms package cache was updated without any errors''' updateCache = Pihole.run(''' @@ -248,6 +263,7 @@ def test_update_package_cache_success_no_errors(Pihole): assert tick_box + ' Update local cache of available packages' in updateCache.stdout assert 'Error: Unable to update package cache.' not in updateCache.stdout + def test_update_package_cache_failure_no_errors(Pihole): ''' confirms package cache was not updated''' mock_command('apt-get', {'update':('', '1')}, Pihole) @@ -259,6 +275,7 @@ def test_update_package_cache_failure_no_errors(Pihole): assert cross_box + ' Update local cache of available packages' in updateCache.stdout assert 'Error: Unable to update package cache.' in updateCache.stdout + def test_FTL_detect_aarch64_no_errors(Pihole): ''' confirms only aarch64 package is downloaded for FTL engine ''' # mock uname to return aarch64 platform @@ -276,6 +293,7 @@ def test_FTL_detect_aarch64_no_errors(Pihole): expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in detectPlatform.stdout + def test_FTL_detect_armv6l_no_errors(Pihole): ''' confirms only armv6l package is downloaded for FTL engine ''' # mock uname to return armv6l platform @@ -293,6 +311,7 @@ def test_FTL_detect_armv6l_no_errors(Pihole): expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in detectPlatform.stdout + def test_FTL_detect_armv7l_no_errors(Pihole): ''' confirms only armv7l package is downloaded for FTL engine ''' # mock uname to return armv7l platform @@ -310,6 +329,7 @@ def test_FTL_detect_armv7l_no_errors(Pihole): expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in detectPlatform.stdout + def test_FTL_detect_x86_64_no_errors(Pihole): ''' confirms only x86_64 package is downloaded for FTL engine ''' detectPlatform = Pihole.run(''' @@ -323,6 +343,7 @@ def test_FTL_detect_x86_64_no_errors(Pihole): expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in detectPlatform.stdout + def test_FTL_detect_unknown_no_errors(Pihole): ''' confirms only generic package is downloaded for FTL engine ''' # mock uname to return generic platform @@ -334,6 +355,7 @@ def test_FTL_detect_unknown_no_errors(Pihole): expected_stdout = 'Not able to detect architecture (unknown: mips)' assert expected_stdout in detectPlatform.stdout + def test_FTL_download_aarch64_no_errors(Pihole): ''' confirms only aarch64 package is downloaded for FTL engine ''' # mock uname to return generic platform @@ -348,6 +370,7 @@ def test_FTL_download_aarch64_no_errors(Pihole): error = 'Error: URL not found' assert error not in download_binary.stdout + def test_FTL_download_unknown_fails_no_errors(Pihole): ''' confirms unknown binary is not downloaded for FTL engine ''' # mock uname to return generic platform @@ -360,6 +383,7 @@ def test_FTL_download_unknown_fails_no_errors(Pihole): error = 'Error: URL not found' assert error in download_binary.stdout + def test_FTL_binary_installed_and_responsive_no_errors(Pihole): ''' confirms FTL binary is copied and functional in installed location ''' installed_binary = Pihole.run(''' @@ -370,6 +394,7 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole): expected_stdout = 'v' assert expected_stdout in installed_binary.stdout + # def test_FTL_support_files_installed(Pihole): # ''' confirms FTL support files are installed ''' # support_files = Pihole.run(''' @@ -384,6 +409,7 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole): # assert '644 /run/pihole-FTL.pid' in support_files.stdout # assert '644 /var/log/pihole-FTL.log' in support_files.stdout + def test_IPv6_only_link_local(Pihole): ''' confirms IPv6 blocking is disabled for Link-local address ''' # mock ip -6 address to return Link-local address @@ -395,6 +421,7 @@ def test_IPv6_only_link_local(Pihole): expected_stdout = 'Unable to find IPv6 ULA/GUA address, IPv6 adblocking will not be enabled' assert expected_stdout in detectPlatform.stdout + def test_IPv6_only_ULA(Pihole): ''' confirms IPv6 blocking is enabled for ULA addresses ''' # mock ip -6 address to return ULA address @@ -406,6 +433,7 @@ def test_IPv6_only_ULA(Pihole): expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads' assert expected_stdout in detectPlatform.stdout + def test_IPv6_only_GUA(Pihole): ''' confirms IPv6 blocking is enabled for GUA addresses ''' # mock ip -6 address to return GUA address @@ -417,6 +445,7 @@ def test_IPv6_only_GUA(Pihole): expected_stdout = 'Found IPv6 GUA address, using it for blocking IPv6 ads' assert expected_stdout in detectPlatform.stdout + def test_IPv6_GUA_ULA_test(Pihole): ''' confirms IPv6 blocking is enabled for GUA and ULA addresses ''' # mock ip -6 address to return GUA and ULA addresses @@ -428,6 +457,7 @@ def test_IPv6_GUA_ULA_test(Pihole): expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads' assert expected_stdout in detectPlatform.stdout + def test_IPv6_ULA_GUA_test(Pihole): ''' confirms IPv6 blocking is enabled for GUA and ULA addresses ''' # mock ip -6 address to return ULA and GUA addresses @@ -439,6 +469,7 @@ def test_IPv6_ULA_GUA_test(Pihole): expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads' assert expected_stdout in detectPlatform.stdout + # 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 ''' @@ -461,6 +492,7 @@ def mock_command(script, args, container): chmod +x {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) @@ -482,6 +514,7 @@ def mock_command_2(script, args, container): chmod +x {script} rm -f /var/log/{scriptlog}'''.format(script=full_script_path, content=mock_script, scriptlog=script)) + def run_script(Pihole, script): result = Pihole.run(script) assert result.rc == 0 diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py index 5b1a8961..0bd03f36 100644 --- a/test/test_shellcheck.py +++ b/test/test_shellcheck.py @@ -5,6 +5,7 @@ run_local = testinfra.get_backend( "local://" ).get_module("Command").run + def test_scripts_pass_shellcheck(): ''' Make sure shellcheck does not find anything wrong with our shell scripts ''' shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck -x \"$file\" -e SC1090,SC1091; done;" From da3dfd0998c1cd86afdf3ecf6cec7bc95b77ac57 Mon Sep 17 00:00:00 2001 From: bcambl Date: Mon, 2 Jul 2018 15:25:51 -0600 Subject: [PATCH 03/21] python linting: missing whitespace after ':' (E231) Signed-off-by: bcambl --- test/test_automated_install.py | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index f7b8702d..55709af9 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -76,9 +76,9 @@ def test_setupVars_saved_to_file(Pihole): def test_configureFirewall_firewalld_running_no_errors(Pihole): ''' confirms firewalld rules are applied when firewallD is running ''' # firewallD returns 'running' as status - mock_command('firewall-cmd', {'*':('running', 0)}, Pihole) + mock_command('firewall-cmd', {'*': ('running', 0)}, Pihole) # Whiptail dialog returns Ok for user prompt - mock_command('whiptail', {'*':('', 0)}, Pihole) + mock_command('whiptail', {'*': ('', 0)}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall @@ -94,7 +94,7 @@ def test_configureFirewall_firewalld_running_no_errors(Pihole): def test_configureFirewall_firewalld_disabled_no_errors(Pihole): ''' confirms firewalld rules are not applied when firewallD is not running ''' # firewallD returns non-running status - mock_command('firewall-cmd', {'*':('not running', '1')}, Pihole) + mock_command('firewall-cmd', {'*': ('not running', '1')}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall @@ -106,9 +106,9 @@ def test_configureFirewall_firewalld_disabled_no_errors(Pihole): def test_configureFirewall_firewalld_enabled_declined_no_errors(Pihole): ''' confirms firewalld rules are not applied when firewallD is running, user declines ruleset ''' # firewallD returns running status - mock_command('firewall-cmd', {'*':('running', 0)}, Pihole) + mock_command('firewall-cmd', {'*': ('running', 0)}, Pihole) # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*':('', 1)}, Pihole) + mock_command('whiptail', {'*': ('', 1)}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall @@ -130,11 +130,11 @@ def test_configureFirewall_no_firewall(Pihole): def test_configureFirewall_IPTables_enabled_declined_no_errors(Pihole): ''' confirms IPTables rules are not applied when IPTables is running, user declines ruleset ''' # iptables command exists - mock_command('iptables', {'*':('', '0')}, Pihole) + mock_command('iptables', {'*': ('', '0')}, Pihole) # modinfo returns always true (ip_tables module check) - mock_command('modinfo', {'*':('', '0')}, Pihole) + mock_command('modinfo', {'*': ('', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*':('', '1')}, Pihole) + mock_command('whiptail', {'*': ('', '1')}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall @@ -146,11 +146,11 @@ def test_configureFirewall_IPTables_enabled_declined_no_errors(Pihole): def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): ''' confirms IPTables rules are not applied when IPTables is running and rules exist ''' # iptables command exists and returns 0 on calls (should return 0 on iptables -C) - mock_command('iptables', {'-S':('-P INPUT DENY', '0')}, Pihole) + mock_command('iptables', {'-S': ('-P INPUT DENY', '0')}, Pihole) # modinfo returns always true (ip_tables module check) - mock_command('modinfo', {'*':('', '0')}, Pihole) + mock_command('modinfo', {'*': ('', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*':('', '0')}, Pihole) + mock_command('whiptail', {'*': ('', '0')}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall @@ -166,11 +166,11 @@ def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): ''' confirms IPTables rules are applied when IPTables is running and rules do not exist ''' # iptables command and returns 0 on calls (should return 1 on iptables -C) - mock_command('iptables', {'-S':('-P INPUT DENY', '0'), '-C':('', 1), '-I':('', 0)}, Pihole) + mock_command('iptables', {'-S': ('-P INPUT DENY', '0'), '-C': ('', 1), '-I': ('', 0)}, Pihole) # modinfo returns always true (ip_tables module check) - mock_command('modinfo', {'*':('', '0')}, Pihole) + mock_command('modinfo', {'*': ('', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*':('', '0')}, Pihole) + mock_command('whiptail', {'*': ('', '0')}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall @@ -186,9 +186,9 @@ def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): def test_selinux_enforcing_default_exit(Pihole): ''' confirms installer prompts to exit when SELinux is Enforcing by default ''' # getenforce returns the running state of SELinux - mock_command('getenforce', {'*':('Enforcing', '0')}, Pihole) + mock_command('getenforce', {'*': ('Enforcing', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*':('', '1')}, Pihole) + mock_command('whiptail', {'*': ('', '1')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh checkSelinux @@ -201,9 +201,9 @@ def test_selinux_enforcing_default_exit(Pihole): def test_selinux_enforcing_continue(Pihole): ''' confirms installer prompts to continue with custom policy warning ''' # getenforce returns the running state of SELinux - mock_command('getenforce', {'*':('Enforcing', '0')}, Pihole) + mock_command('getenforce', {'*': ('Enforcing', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt - mock_command('whiptail', {'*':('', '0')}, Pihole) + mock_command('whiptail', {'*': ('', '0')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh checkSelinux @@ -217,7 +217,7 @@ def test_selinux_enforcing_continue(Pihole): def test_selinux_permissive(Pihole): ''' confirms installer continues when SELinux is Permissive ''' # getenforce returns the running state of SELinux - mock_command('getenforce', {'*':('Permissive', '0')}, Pihole) + mock_command('getenforce', {'*': ('Permissive', '0')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh checkSelinux @@ -228,7 +228,7 @@ def test_selinux_permissive(Pihole): def test_selinux_disabled(Pihole): ''' confirms installer continues when SELinux is Disabled ''' - mock_command('getenforce', {'*':('Disabled', '0')}, Pihole) + mock_command('getenforce', {'*': ('Disabled', '0')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh checkSelinux @@ -266,7 +266,7 @@ def test_update_package_cache_success_no_errors(Pihole): def test_update_package_cache_failure_no_errors(Pihole): ''' confirms package cache was not updated''' - mock_command('apt-get', {'update':('', '1')}, Pihole) + mock_command('apt-get', {'update': ('', '1')}, Pihole) updateCache = Pihole.run(''' source /opt/pihole/basic-install.sh distro_check @@ -279,9 +279,9 @@ def test_update_package_cache_failure_no_errors(Pihole): def test_FTL_detect_aarch64_no_errors(Pihole): ''' 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')}, Pihole) # mock ldd to respond with aarch64 shared library - mock_command('ldd', {'/bin/ls':('/lib/ld-linux-aarch64.so.1', '0')}, Pihole) + mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-aarch64.so.1', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -297,9 +297,9 @@ def test_FTL_detect_aarch64_no_errors(Pihole): def test_FTL_detect_armv6l_no_errors(Pihole): ''' 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')}, Pihole) # mock ldd to respond with aarch64 shared library - mock_command('ldd', {'/bin/ls':('/lib/ld-linux-armhf.so.3', '0')}, Pihole) + mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -315,9 +315,9 @@ def test_FTL_detect_armv6l_no_errors(Pihole): def test_FTL_detect_armv7l_no_errors(Pihole): ''' 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')}, Pihole) # mock ldd to respond with aarch64 shared library - mock_command('ldd', {'/bin/ls':('/lib/ld-linux-armhf.so.3', '0')}, Pihole) + mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-armhf.so.3', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -347,7 +347,7 @@ def test_FTL_detect_x86_64_no_errors(Pihole): def test_FTL_detect_unknown_no_errors(Pihole): ''' confirms only generic package is downloaded for FTL engine ''' # mock uname to return generic platform - mock_command('uname', {'-m':('mips', '0')}, Pihole) + mock_command('uname', {'-m': ('mips', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -413,7 +413,7 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole): def test_IPv6_only_link_local(Pihole): ''' 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')}, Pihole) + mock_command_2('ip', {'-6 address': ('inet6 fe80::d210:52fa:fe00:7ad7/64 scope link', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -425,7 +425,7 @@ def test_IPv6_only_link_local(Pihole): def test_IPv6_only_ULA(Pihole): ''' confirms IPv6 blocking is enabled for ULA addresses ''' # mock ip -6 address to return ULA address - mock_command_2('ip', {'-6 address':('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2('ip', {'-6 address': ('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -437,7 +437,7 @@ def test_IPv6_only_ULA(Pihole): def test_IPv6_only_GUA(Pihole): ''' confirms IPv6 blocking is enabled for GUA addresses ''' # mock ip -6 address to return GUA address - mock_command_2('ip', {'-6 address':('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2('ip', {'-6 address': ('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -449,7 +449,7 @@ def test_IPv6_only_GUA(Pihole): def test_IPv6_GUA_ULA_test(Pihole): ''' confirms IPv6 blocking is enabled for GUA and ULA addresses ''' # mock ip -6 address to return GUA and ULA addresses - mock_command_2('ip', {'-6 address':('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\ninet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2('ip', {'-6 address': ('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\ninet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -461,7 +461,7 @@ def test_IPv6_GUA_ULA_test(Pihole): def test_IPv6_ULA_GUA_test(Pihole): ''' confirms IPv6 blocking is enabled for GUA and ULA addresses ''' # mock ip -6 address to return ULA and GUA addresses - mock_command_2('ip', {'-6 address':('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\ninet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2('ip', {'-6 address': ('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\ninet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog From c3d443aaffcf75bd2993358eb2e25a1bb33040d5 Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 3 Jul 2018 00:05:24 -0600 Subject: [PATCH 04/21] python linting: lines > 79 characters (E501) Signed-off-by: bcambl --- test/conftest.py | 31 +++- test/test_automated_install.py | 307 ++++++++++++++++++++++++++------- test/test_shellcheck.py | 9 +- 3 files changed, 271 insertions(+), 76 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 44e0a4a4..80fea82b 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -8,8 +8,10 @@ check_output = testinfra.get_backend( @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 ''' + ''' + 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: @@ -23,13 +25,18 @@ def Pihole(Docker): return out funcType = type(Docker.run) - Docker.run = funcType(run_bash, Docker, testinfra.backend.docker.DockerBackend) + Docker.run = funcType(run_bash, + Docker, + testinfra.backend.docker.DockerBackend) return Docker @pytest.fixture def Docker(request, args, image, cmd): - ''' combine our fixtures into a docker run command and setup finalizer to cleanup ''' + ''' + 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) @@ -45,23 +52,31 @@ def Docker(request, args, image, cmd): @pytest.fixture def args(request): - ''' -t became required when tput began being used ''' + ''' + -t became required when tput began being used + ''' return '-t -d' @pytest.fixture(params=['debian', 'centos']) def tag(request): - ''' consumed by image to make the test matrix ''' + ''' + consumed by image to make the test matrix + ''' return request.param @pytest.fixture() def image(request, tag): - ''' built by test_000_build_containers.py ''' + ''' + 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 ''' + ''' + default to doing nothing by tailing null, but don't exit + ''' return 'tail -f /dev/null' diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 55709af9..a604e197 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -15,9 +15,11 @@ info_box="[i]".decode("utf-8") def test_setupVars_are_sourced_to_global_scope(Pihole): - ''' currently update_dialogs sources setupVars with a dot, + ''' + 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 ''' + This confirms the sourced variables are in scope between functions + ''' setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' for k,v in SETUPVARS.iteritems(): setup_var_file += "{}={}\n".format(k, v) @@ -49,8 +51,11 @@ def test_setupVars_are_sourced_to_global_scope(Pihole): def test_setupVars_saved_to_file(Pihole): - ''' confirm saved settings are written to a file for future updates to re-use ''' - set_setup_vars = '\n' # dedent works better with this and padding matching script below + ''' + 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' for k,v in SETUPVARS.iteritems(): set_setup_vars += " {}={}\n".format(k, v) Pihole.run(set_setup_vars).stdout @@ -74,7 +79,9 @@ def test_setupVars_saved_to_file(Pihole): def test_configureFirewall_firewalld_running_no_errors(Pihole): - ''' confirms firewalld rules are applied when firewallD is running ''' + ''' + confirms firewalld rules are applied when firewallD is running + ''' # firewallD returns 'running' as status mock_command('firewall-cmd', {'*': ('running', 0)}, Pihole) # Whiptail dialog returns Ok for user prompt @@ -87,24 +94,33 @@ def test_configureFirewall_firewalld_running_no_errors(Pihole): assert expected_stdout in configureFirewall.stdout firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout assert 'firewall-cmd --state' in firewall_calls - assert 'firewall-cmd --permanent --add-service=http --add-service=dns' in firewall_calls + assert ('firewall-cmd ' + '--permanent ' + '--add-service=http ' + '--add-service=dns') in firewall_calls assert 'firewall-cmd --reload' in firewall_calls def test_configureFirewall_firewalld_disabled_no_errors(Pihole): - ''' confirms firewalld rules are not applied when firewallD is not running ''' + ''' + confirms firewalld rules are not applied when firewallD is not running + ''' # firewallD returns non-running status mock_command('firewall-cmd', {'*': ('not running', '1')}, Pihole) configureFirewall = Pihole.run(''' source /opt/pihole/basic-install.sh configureFirewall ''') - expected_stdout = 'No active firewall detected.. skipping firewall configuration' + expected_stdout = ('No active firewall detected.. ' + 'skipping firewall configuration') assert expected_stdout in configureFirewall.stdout def test_configureFirewall_firewalld_enabled_declined_no_errors(Pihole): - ''' confirms firewalld rules are not applied when firewallD is running, user declines ruleset ''' + ''' + confirms firewalld rules are not applied when firewallD is running, user + declines ruleset + ''' # firewallD returns running status mock_command('firewall-cmd', {'*': ('running', 0)}, Pihole) # Whiptail dialog returns Cancel for user prompt @@ -128,7 +144,10 @@ def test_configureFirewall_no_firewall(Pihole): def test_configureFirewall_IPTables_enabled_declined_no_errors(Pihole): - ''' confirms IPTables rules are not applied when IPTables is running, user declines ruleset ''' + ''' + confirms IPTables rules are not applied when IPTables is running, user + declines ruleset + ''' # iptables command exists mock_command('iptables', {'*': ('', '0')}, Pihole) # modinfo returns always true (ip_tables module check) @@ -144,8 +163,12 @@ def test_configureFirewall_IPTables_enabled_declined_no_errors(Pihole): def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): - ''' confirms IPTables rules are not applied when IPTables is running and rules exist ''' - # iptables command exists and returns 0 on calls (should return 0 on iptables -C) + ''' + confirms IPTables rules are not applied when IPTables is running and rules + exist + ''' + # iptables command exists and returns 0 on calls + # (should return 0 on iptables -C) mock_command('iptables', {'-S': ('-P INPUT DENY', '0')}, Pihole) # modinfo returns always true (ip_tables module check) mock_command('modinfo', {'*': ('', '0')}, Pihole) @@ -158,15 +181,38 @@ def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): expected_stdout = 'Installing new IPTables firewall rulesets' assert expected_stdout in configureFirewall.stdout firewall_calls = Pihole.run('cat /var/log/iptables').stdout - assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT' not in firewall_calls - assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' not in firewall_calls - assert 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' not in firewall_calls + iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT' + assert iptables_line not in firewall_calls + iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' + assert iptables_line not in firewall_calls + iptables_line = 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' + assert iptables_line not in firewall_calls def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): - ''' confirms IPTables rules are applied when IPTables is running and rules do not exist ''' + ''' + confirms IPTables rules are applied when IPTables is running and rules do + not exist + ''' # iptables command and returns 0 on calls (should return 1 on iptables -C) - mock_command('iptables', {'-S': ('-P INPUT DENY', '0'), '-C': ('', 1), '-I': ('', 0)}, Pihole) + mock_command( + 'iptables', + { + '-S': ( + '-P INPUT DENY', + '0' + ), + '-C': ( + '', + 1 + ), + '-I': ( + '', + 0 + ) + }, + Pihole + ) # modinfo returns always true (ip_tables module check) mock_command('modinfo', {'*': ('', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt @@ -178,13 +224,18 @@ def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): expected_stdout = 'Installing new IPTables firewall rulesets' assert expected_stdout in configureFirewall.stdout firewall_calls = Pihole.run('cat /var/log/iptables').stdout - assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT' in firewall_calls - assert 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' in firewall_calls - assert 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' in firewall_calls + iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT' + assert iptables_line in firewall_calls + iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' + assert iptables_line in firewall_calls + iptables_line = 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' + assert iptables_line in firewall_calls def test_selinux_enforcing_default_exit(Pihole): - ''' confirms installer prompts to exit when SELinux is Enforcing by default ''' + ''' + confirms installer prompts to exit when SELinux is Enforcing by default + ''' # getenforce returns the running state of SELinux mock_command('getenforce', {'*': ('Enforcing', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt @@ -193,13 +244,17 @@ def test_selinux_enforcing_default_exit(Pihole): source /opt/pihole/basic-install.sh checkSelinux ''') - assert info_box + ' SELinux mode detected: Enforcing' in check_selinux.stdout - assert 'SELinux Enforcing detected, exiting installer' in check_selinux.stdout + expected_stdout = info_box + ' SELinux mode detected: Enforcing' + assert expected_stdout in check_selinux.stdout + expected_stdout = 'SELinux Enforcing detected, exiting installer' + assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 1 def test_selinux_enforcing_continue(Pihole): - ''' confirms installer prompts to continue with custom policy warning ''' + ''' + confirms installer prompts to continue with custom policy warning + ''' # getenforce returns the running state of SELinux mock_command('getenforce', {'*': ('Enforcing', '0')}, Pihole) # Whiptail dialog returns Cancel for user prompt @@ -208,80 +263,117 @@ def test_selinux_enforcing_continue(Pihole): source /opt/pihole/basic-install.sh checkSelinux ''') - assert info_box + ' SELinux mode detected: Enforcing' in check_selinux.stdout - assert info_box + ' Continuing installation with SELinux Enforcing' in check_selinux.stdout - assert info_box + ' Please refer to official SELinux documentation to create a custom policy' in check_selinux.stdout + expected_stdout = info_box + ' SELinux mode detected: Enforcing' + assert expected_stdout in check_selinux.stdout + expected_stdout = info_box + (' Continuing installation with SELinux ' + 'Enforcing') + assert expected_stdout in check_selinux.stdout + expected_stdout = info_box + (' Please refer to official SELinux ' + 'documentation to create a custom policy') + assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_selinux_permissive(Pihole): - ''' confirms installer continues when SELinux is Permissive ''' + ''' + confirms installer continues when SELinux is Permissive + ''' # getenforce returns the running state of SELinux mock_command('getenforce', {'*': ('Permissive', '0')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh checkSelinux ''') - assert info_box + ' SELinux mode detected: Permissive' in check_selinux.stdout + expected_stdout = info_box + ' SELinux mode detected: Permissive' + assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_selinux_disabled(Pihole): - ''' confirms installer continues when SELinux is Disabled ''' + ''' + confirms installer continues when SELinux is Disabled + ''' mock_command('getenforce', {'*': ('Disabled', '0')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh checkSelinux ''') - assert info_box + ' SELinux mode detected: Disabled' in check_selinux.stdout + expected_stdout = info_box + ' SELinux mode detected: Disabled' + assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_installPiholeWeb_fresh_install_no_errors(Pihole): - ''' confirms all web page assets from Core repo are installed on a fresh build ''' + ''' + confirms all web page assets from Core repo are installed on a fresh build + ''' installWeb = Pihole.run(''' source /opt/pihole/basic-install.sh installPiholeWeb ''') - assert info_box + ' Installing blocking page...' in installWeb.stdout - assert tick_box + ' Creating directory for blocking page, and copying files' in installWeb.stdout - assert cross_box + ' Backing up index.lighttpd.html' in installWeb.stdout - assert 'No default index.lighttpd.html file found... not backing up' in installWeb.stdout - assert tick_box + ' Installing sudoer file' in installWeb.stdout + expected_stdout = info_box + ' Installing blocking page...' + assert expected_stdout in installWeb.stdout + expected_stdout = tick_box + (' Creating directory for blocking page, ' + 'and copying files') + assert expected_stdout in installWeb.stdout + expected_stdout = cross_box + ' Backing up index.lighttpd.html' + assert expected_stdout in installWeb.stdout + 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' + assert expected_stdout in installWeb.stdout web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout assert 'index.php' in web_directory assert 'blockingpage.css' in web_directory def test_update_package_cache_success_no_errors(Pihole): - ''' confirms package cache was updated without any errors''' + ''' + confirms package cache was updated without any errors + ''' updateCache = Pihole.run(''' source /opt/pihole/basic-install.sh distro_check update_package_cache ''') - assert tick_box + ' Update local cache of available packages' in updateCache.stdout + expected_stdout = tick_box + ' Update local cache of available packages' + assert expected_stdout in updateCache.stdout assert 'Error: Unable to update package cache.' not in updateCache.stdout def test_update_package_cache_failure_no_errors(Pihole): - ''' confirms package cache was not updated''' + ''' + confirms package cache was not updated + ''' mock_command('apt-get', {'update': ('', '1')}, Pihole) updateCache = Pihole.run(''' source /opt/pihole/basic-install.sh distro_check update_package_cache ''') - assert cross_box + ' Update local cache of available packages' in updateCache.stdout + 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 def test_FTL_detect_aarch64_no_errors(Pihole): - ''' confirms only aarch64 package is downloaded for FTL engine ''' + ''' + confirms only aarch64 package is downloaded for FTL engine + ''' # mock uname to return aarch64 platform mock_command('uname', {'-m': ('aarch64', '0')}, Pihole) # mock ldd to respond with aarch64 shared library - mock_command('ldd', {'/bin/ls': ('/lib/ld-linux-aarch64.so.1', '0')}, Pihole) + mock_command( + 'ldd', + { + '/bin/ls': ( + '/lib/ld-linux-aarch64.so.1', + '0' + ) + }, + Pihole + ) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -295,7 +387,9 @@ def test_FTL_detect_aarch64_no_errors(Pihole): def test_FTL_detect_armv6l_no_errors(Pihole): - ''' confirms only armv6l package is downloaded for FTL engine ''' + ''' + confirms only armv6l package is downloaded for FTL engine + ''' # mock uname to return armv6l platform mock_command('uname', {'-m': ('armv6l', '0')}, Pihole) # mock ldd to respond with aarch64 shared library @@ -306,14 +400,17 @@ def test_FTL_detect_armv6l_no_errors(Pihole): ''') expected_stdout = info_box + ' FTL Checks...' assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected ARM-hf architecture (armv6 or lower)' + expected_stdout = tick_box + (' Detected ARM-hf architecture ' + '(armv6 or lower)') assert expected_stdout in detectPlatform.stdout expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in detectPlatform.stdout def test_FTL_detect_armv7l_no_errors(Pihole): - ''' confirms only armv7l package is downloaded for FTL engine ''' + ''' + confirms only armv7l package is downloaded for FTL engine + ''' # mock uname to return armv7l platform mock_command('uname', {'-m': ('armv7l', '0')}, Pihole) # mock ldd to respond with aarch64 shared library @@ -331,7 +428,9 @@ def test_FTL_detect_armv7l_no_errors(Pihole): def test_FTL_detect_x86_64_no_errors(Pihole): - ''' confirms only x86_64 package is downloaded for FTL engine ''' + ''' + confirms only x86_64 package is downloaded for FTL engine + ''' detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -357,7 +456,9 @@ def test_FTL_detect_unknown_no_errors(Pihole): def test_FTL_download_aarch64_no_errors(Pihole): - ''' confirms only aarch64 package is downloaded for FTL engine ''' + ''' + confirms only aarch64 package is downloaded for FTL engine + ''' # mock uname to return generic platform download_binary = Pihole.run(''' source /opt/pihole/basic-install.sh @@ -372,7 +473,9 @@ def test_FTL_download_aarch64_no_errors(Pihole): def test_FTL_download_unknown_fails_no_errors(Pihole): - ''' confirms unknown binary is not downloaded for FTL engine ''' + ''' + confirms unknown binary is not downloaded for FTL engine + ''' # mock uname to return generic platform download_binary = Pihole.run(''' source /opt/pihole/basic-install.sh @@ -385,7 +488,9 @@ def test_FTL_download_unknown_fails_no_errors(Pihole): def test_FTL_binary_installed_and_responsive_no_errors(Pihole): - ''' confirms FTL binary is copied and functional in installed location ''' + ''' + confirms FTL binary is copied and functional in installed location + ''' installed_binary = Pihole.run(''' source /opt/pihole/basic-install.sh FTLdetect @@ -396,7 +501,9 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole): # def test_FTL_support_files_installed(Pihole): -# ''' confirms FTL support files are installed ''' +# ''' +# confirms FTL support files are installed +# ''' # support_files = Pihole.run(''' # source /opt/pihole/basic-install.sh # FTLdetect @@ -411,21 +518,44 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole): def test_IPv6_only_link_local(Pihole): - ''' confirms IPv6 blocking is disabled for Link-local address ''' + ''' + 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')}, Pihole) + mock_command_2( + 'ip', + { + '-6 address': ( + 'inet6 fe80::d210:52fa:fe00:7ad7/64 scope link', + '0' + ) + }, + Pihole + ) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog ''') - expected_stdout = 'Unable to find IPv6 ULA/GUA address, IPv6 adblocking will not be enabled' + expected_stdout = ('Unable to find IPv6 ULA/GUA address, ' + 'IPv6 adblocking will not be enabled') assert expected_stdout in detectPlatform.stdout def test_IPv6_only_ULA(Pihole): - ''' confirms IPv6 blocking is enabled for ULA addresses ''' + ''' + confirms IPv6 blocking is enabled for ULA addresses + ''' # mock ip -6 address to return ULA address - mock_command_2('ip', {'-6 address': ('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2( + 'ip', + { + '-6 address': ( + 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', + '0' + ) + }, + Pihole + ) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -435,9 +565,20 @@ def test_IPv6_only_ULA(Pihole): def test_IPv6_only_GUA(Pihole): - ''' confirms IPv6 blocking is enabled for GUA addresses ''' + ''' + confirms IPv6 blocking is enabled for GUA addresses + ''' # mock ip -6 address to return GUA address - mock_command_2('ip', {'-6 address': ('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2( + 'ip', + { + '-6 address': ( + 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', + '0' + ) + }, + Pihole + ) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -447,9 +588,21 @@ def test_IPv6_only_GUA(Pihole): def test_IPv6_GUA_ULA_test(Pihole): - ''' confirms IPv6 blocking is enabled for GUA and ULA addresses ''' + ''' + confirms IPv6 blocking is enabled for GUA and ULA addresses + ''' # mock ip -6 address to return GUA and ULA addresses - mock_command_2('ip', {'-6 address': ('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\ninet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2( + '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' + ) + }, + Pihole + ) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -459,9 +612,21 @@ def test_IPv6_GUA_ULA_test(Pihole): def test_IPv6_ULA_GUA_test(Pihole): - ''' confirms IPv6 blocking is enabled for GUA and ULA addresses ''' + ''' + confirms IPv6 blocking is enabled for GUA and ULA addresses + ''' # mock ip -6 address to return ULA and GUA addresses - mock_command_2('ip', {'-6 address': ('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\ninet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole) + mock_command_2( + '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' + ) + }, + Pihole + ) detectPlatform = Pihole.run(''' source /opt/pihole/basic-install.sh useIPv6dialog @@ -472,7 +637,10 @@ def test_IPv6_ULA_GUA_test(Pihole): # 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 ''' + ''' + 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('''\ #!/bin/bash -e @@ -490,11 +658,16 @@ def mock_command(script, args, container): 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 ''' + ''' + 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('''\ #!/bin/bash -e @@ -512,7 +685,9 @@ def mock_command_2(script, args, container): 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/test_shellcheck.py b/test/test_shellcheck.py index 0bd03f36..b9b1cea5 100644 --- a/test/test_shellcheck.py +++ b/test/test_shellcheck.py @@ -7,8 +7,13 @@ run_local = testinfra.get_backend( def test_scripts_pass_shellcheck(): - ''' Make sure shellcheck does not find anything wrong with our shell scripts ''' - shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck -x \"$file\" -e SC1090,SC1091; done;" + ''' + Make sure shellcheck does not find anything wrong with our shell scripts + ''' + shellcheck = ("find . -type f -name 'update.sh' " + "| while read file; do " + "shellcheck -x \"$file\" -e SC1090,SC1091; " + "done;") results = run_local(shellcheck) print results.stdout assert '' == results.stdout From 9bd4986781fbfc610bc8cb174f3b53152491ac9d Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 3 Jul 2018 00:21:57 -0600 Subject: [PATCH 05/21] python linting: whitespace before ':' (E203) Signed-off-by: bcambl --- test/test_automated_install.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index a604e197..1bbdefa1 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -2,11 +2,11 @@ import pytest from textwrap import dedent SETUPVARS = { - 'PIHOLE_INTERFACE' : 'eth99', - 'IPV4_ADDRESS' : '1.1.1.1', - 'IPV6_ADDRESS' : 'FE80::240:D0FF:FE48:4672', - 'PIHOLE_DNS_1' : '4.2.2.1', - 'PIHOLE_DNS_2' : '4.2.2.2' + 'PIHOLE_INTERFACE': 'eth99', + 'IPV4_ADDRESS': '1.1.1.1', + 'IPV6_ADDRESS': 'FE80::240:D0FF:FE48:4672', + 'PIHOLE_DNS_1': '4.2.2.1', + 'PIHOLE_DNS_2': '4.2.2.2' } tick_box="[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8") From 79232d02c935e88b9df211e66cddcda85144b109 Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 3 Jul 2018 00:30:00 -0600 Subject: [PATCH 06/21] python linting: 'pytest' imported but unused (F401) Signed-off-by: bcambl --- test/test_automated_install.py | 1 - test/test_shellcheck.py | 1 - 2 files changed, 2 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 1bbdefa1..027e5365 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -1,4 +1,3 @@ -import pytest from textwrap import dedent SETUPVARS = { diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py index b9b1cea5..43e8ad6f 100644 --- a/test/test_shellcheck.py +++ b/test/test_shellcheck.py @@ -1,4 +1,3 @@ -import pytest import testinfra run_local = testinfra.get_backend( From 1d3445bc0f019f2a01d36552c0e8a84fa5e67467 Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 3 Jul 2018 00:33:30 -0600 Subject: [PATCH 07/21] python linting: whitespace after '(' and before ')' (E201 & E202) Signed-off-by: bcambl --- test/test_000_build_containers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_000_build_containers.py b/test/test_000_build_containers.py index 725136d8..dc365026 100644 --- a/test/test_000_build_containers.py +++ b/test/test_000_build_containers.py @@ -8,8 +8,8 @@ run_local = testinfra.get_backend( @pytest.mark.parametrize("image,tag", [ - ( 'test/debian.Dockerfile', 'pytest_pihole:debian' ), - ( 'test/centos.Dockerfile', 'pytest_pihole:centos' ), + ('test/debian.Dockerfile', 'pytest_pihole:debian'), + ('test/centos.Dockerfile', 'pytest_pihole:centos'), ]) def test_build_pihole_image(image, tag): build_cmd = run_local('docker build -f {} -t {} .'.format(image, tag)) From 064a75b21b73948a11b2af2518a3e9dc2cc01192 Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 3 Jul 2018 00:35:16 -0600 Subject: [PATCH 08/21] python linting: missing whitespace around operator (E225) Signed-off-by: bcambl --- test/test_automated_install.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 027e5365..14c2b77a 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -8,9 +8,9 @@ SETUPVARS = { 'PIHOLE_DNS_2': '4.2.2.2' } -tick_box="[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8") -cross_box="[\x1b[1;31m\xe2\x9c\x97\x1b[0m]".decode("utf-8") -info_box="[i]".decode("utf-8") +tick_box = "[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8") +cross_box = "[\x1b[1;31m\xe2\x9c\x97\x1b[0m]".decode("utf-8") +info_box = "[i]".decode("utf-8") def test_setupVars_are_sourced_to_global_scope(Pihole): From 40537e1522b2eb9d18d07254b4b8f155d749061e Mon Sep 17 00:00:00 2001 From: bcambl Date: Tue, 3 Jul 2018 00:36:47 -0600 Subject: [PATCH 09/21] python linting: missing whitespace after ',' (E231) Signed-off-by: bcambl --- test/test_automated_install.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 14c2b77a..400a94f4 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -20,7 +20,7 @@ def test_setupVars_are_sourced_to_global_scope(Pihole): This confirms the sourced variables are in scope between functions ''' setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' - for k,v in SETUPVARS.iteritems(): + for k, v in SETUPVARS.iteritems(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "EOF\n" Pihole.run(setup_var_file) @@ -45,7 +45,7 @@ def test_setupVars_are_sourced_to_global_scope(Pihole): output = run_script(Pihole, script).stdout - for k,v in SETUPVARS.iteritems(): + for k, v in SETUPVARS.iteritems(): assert "{}={}".format(k, v) in output @@ -55,7 +55,7 @@ def test_setupVars_saved_to_file(Pihole): ''' # dedent works better with this and padding matching script below set_setup_vars = '\n' - for k,v in SETUPVARS.iteritems(): + for k, v in SETUPVARS.iteritems(): set_setup_vars += " {}={}\n".format(k, v) Pihole.run(set_setup_vars).stdout @@ -73,7 +73,7 @@ def test_setupVars_saved_to_file(Pihole): output = run_script(Pihole, script).stdout - for k,v in SETUPVARS.iteritems(): + for k, v in SETUPVARS.iteritems(): assert "{}={}".format(k, v) in output From 5ca2ad6148b83ab2d072477dda95ab0c3b97332f Mon Sep 17 00:00:00 2001 From: bcambl Date: Thu, 5 Jul 2018 18:10:43 -0600 Subject: [PATCH 10/21] move test globals & mock commands to conftest Signed-off-by: bcambl --- test/conftest.py | 74 ++++++++++++++++++++++++++++++ test/test_automated_install.py | 82 ++++------------------------------ 2 files changed, 83 insertions(+), 73 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 80fea82b..7ec3832e 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -1,10 +1,23 @@ import pytest import testinfra +from textwrap import dedent check_output = testinfra.get_backend( "local://" ).get_module("Command").check_output +SETUPVARS = { + 'PIHOLE_INTERFACE': 'eth99', + 'IPV4_ADDRESS': '1.1.1.1', + 'IPV6_ADDRESS': 'FE80::240:D0FF:FE48:4672', + 'PIHOLE_DNS_1': '4.2.2.1', + 'PIHOLE_DNS_2': '4.2.2.2' +} + +tick_box = "[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8") +cross_box = "[\x1b[1;31m\xe2\x9c\x97\x1b[0m]".decode("utf-8") +info_box = "[i]".decode("utf-8") + @pytest.fixture def Pihole(Docker): @@ -80,3 +93,64 @@ def cmd(request): default to doing nothing by tailing null, but don't exit ''' return 'tail -f /dev/null' + + +# 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('''\ + #!/bin/bash -e + echo "\$0 \$@" >> /var/log/{script} + case "\$1" in'''.format(script=script)) + for k, v in args.iteritems(): + 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 < {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_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('''\ + #!/bin/bash -e + echo "\$0 \$@" >> /var/log/{script} + case "\$1 \$2" in'''.format(script=script)) + for k, v in args.iteritems(): + 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 < {script}\n{content}\nEOF + chmod +x {script} + rm -f /var/log/{scriptlog}'''.format(script=full_script_path, + content=mock_script, + scriptlog=script)) + + +def run_script(Pihole, script): + result = Pihole.run(script) + assert result.rc == 0 + return result diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 400a94f4..3718282f 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -1,16 +1,13 @@ from textwrap import dedent - -SETUPVARS = { - 'PIHOLE_INTERFACE': 'eth99', - 'IPV4_ADDRESS': '1.1.1.1', - 'IPV6_ADDRESS': 'FE80::240:D0FF:FE48:4672', - 'PIHOLE_DNS_1': '4.2.2.1', - 'PIHOLE_DNS_2': '4.2.2.2' -} - -tick_box = "[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8") -cross_box = "[\x1b[1;31m\xe2\x9c\x97\x1b[0m]".decode("utf-8") -info_box = "[i]".decode("utf-8") +from conftest import ( + SETUPVARS, + tick_box, + info_box, + cross_box, + mock_command, + mock_command_2, + run_script +) def test_setupVars_are_sourced_to_global_scope(Pihole): @@ -632,64 +629,3 @@ def test_IPv6_ULA_GUA_test(Pihole): ''') expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads' assert expected_stdout in detectPlatform.stdout - - -# 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('''\ - #!/bin/bash -e - echo "\$0 \$@" >> /var/log/{script} - case "\$1" in'''.format(script=script)) - for k, v in args.iteritems(): - 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 < {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_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('''\ - #!/bin/bash -e - echo "\$0 \$@" >> /var/log/{script} - case "\$1 \$2" in'''.format(script=script)) - for k, v in args.iteritems(): - 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 < {script}\n{content}\nEOF - chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) - - -def run_script(Pihole, script): - result = Pihole.run(script) - assert result.rc == 0 - return result From 553aad6ed2d489bd508d7f956261d5e4b69de6a4 Mon Sep 17 00:00:00 2001 From: bcambl Date: Thu, 5 Jul 2018 18:12:39 -0600 Subject: [PATCH 11/21] add Fedora container to test matrix Signed-off-by: bcambl --- test/conftest.py | 2 +- test/fedora.Dockerfile | 16 ++++++++++++++++ test/test_000_build_containers.py | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/fedora.Dockerfile diff --git a/test/conftest.py b/test/conftest.py index 7ec3832e..58530d38 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -71,7 +71,7 @@ def args(request): return '-t -d' -@pytest.fixture(params=['debian', 'centos']) +@pytest.fixture(params=['debian', 'centos', 'fedora']) def tag(request): ''' consumed by image to make the test matrix diff --git a/test/fedora.Dockerfile b/test/fedora.Dockerfile new file mode 100644 index 00000000..c4834388 --- /dev/null +++ b/test/fedora.Dockerfile @@ -0,0 +1,16 @@ +FROM fedora:latest + +ENV GITDIR /etc/.pihole +ENV SCRIPTDIR /opt/pihole + +RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole +ADD . $GITDIR +RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR + +RUN true && \ + chmod +x $SCRIPTDIR/* + +ENV PH_TEST true + +#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \ diff --git a/test/test_000_build_containers.py b/test/test_000_build_containers.py index dc365026..ad243754 100644 --- a/test/test_000_build_containers.py +++ b/test/test_000_build_containers.py @@ -10,6 +10,7 @@ run_local = testinfra.get_backend( @pytest.mark.parametrize("image,tag", [ ('test/debian.Dockerfile', 'pytest_pihole:debian'), ('test/centos.Dockerfile', 'pytest_pihole:centos'), + ('test/fedora.Dockerfile', 'pytest_pihole:fedora'), ]) def test_build_pihole_image(image, tag): build_cmd = run_local('docker build -f {} -t {} .'.format(image, tag)) From 09d40679c0d26aa139df1eff0b7a6cf1727ecb40 Mon Sep 17 00:00:00 2001 From: bcambl Date: Fri, 6 Jul 2018 10:07:43 -0600 Subject: [PATCH 12/21] add test for unsupported distro checking Signed-off-by: bcambl --- test/test_automated_install.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 3718282f..683c688c 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -10,6 +10,22 @@ from conftest import ( ) +def test_supported_operating_system(Pihole): + ''' + confirm installer exists on unsupported distribution + ''' + # break supported package managers to emulate an unsupported distribution + Pihole.run('rm -rf /usr/bin/apt-get') + Pihole.run('rm -rf /usr/bin/rpm') + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = cross_box + ' OS distribution not supported' + assert expected_stdout in distro_check.stdout + # assert distro_check.rc == 1 + + def test_setupVars_are_sourced_to_global_scope(Pihole): ''' currently update_dialogs sources setupVars with a dot, From d4addd53ad34597608ed0ca0116c844e1f017a02 Mon Sep 17 00:00:00 2001 From: bcambl Date: Sat, 7 Jul 2018 17:44:05 -0600 Subject: [PATCH 13/21] Add tests for Fedora/CentOS distro_check - test to ensure installer behavior with unsupported CentOS releases - test to ensure repository enablement - test to ensure PHP upgrade opt-in/opt-out behavior Signed-off-by: bcambl --- test/test_centos_fedora_support.py | 215 +++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 test/test_centos_fedora_support.py diff --git a/test/test_centos_fedora_support.py b/test/test_centos_fedora_support.py new file mode 100644 index 00000000..3447edfa --- /dev/null +++ b/test/test_centos_fedora_support.py @@ -0,0 +1,215 @@ +import pytest +from conftest import ( + tick_box, + info_box, + cross_box, + mock_command, + mock_command_2, +) + + +@pytest.mark.parametrize("tag", [('fedora'), ]) +def test_epel_and_remi_not_installed_fedora(Pihole): + ''' + confirms installer does not attempt to install EPEL repository on Fedora + ''' + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' Enabling EPEL package repository ' + '(https://fedoraproject.org/wiki/EPEL)') + assert expected_stdout not in distro_check.stdout + expected_stdout = tick_box + ' Installed epel-release' + assert expected_stdout not in distro_check.stdout + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout not in distro_check.stdout + epel_package = Pihole.package('epel-release') + assert not epel_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_release_supported_version_check_centos(Pihole): + ''' + confirms installer exits on unsupported releases of CentOS + ''' + # mock CentOS release < 7 (unsupported) + mock_command_2( + 'rpm', + {"-q --queryformat '%{VERSION}' centos-release'": ( + '5', + '0' + )}, + Pihole + ) + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = cross_box + (' CentOS is not suported.') + assert expected_stdout in distro_check.stdout + expected_stdout = 'Please update to CentOS release 7 or later' + assert expected_stdout in distro_check.stdout + # assert distro_check.rc == 1 # currently only exits.. should exit 1? + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_enable_epel_repository_centos(Pihole): + ''' + confirms the EPEL package repository is enabled when installed on CentOS + ''' + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' Enabling EPEL package repository ' + '(https://fedoraproject.org/wiki/EPEL)') + assert expected_stdout in distro_check.stdout + expected_stdout = tick_box + ' Installed epel-release' + assert expected_stdout in distro_check.stdout + epel_package = Pihole.package('epel-release') + assert epel_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_php_upgrade_default_optout_centos(Pihole): + ''' + confirms the default behavior to opt-out of installing PHP7 from REMI + ''' + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout in distro_check.stdout + remi_package = Pihole.package('remi-release') + assert not remi_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_php_upgrade_user_optout_centos(Pihole): + ''' + confirms installer behavior when user opt-out of installing PHP7 from REMI + (php not currently installed) + ''' + # Whiptail dialog returns Cancel for user prompt + mock_command('whiptail', {'*': ('', '1')}, Pihole) + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout in distro_check.stdout + remi_package = Pihole.package('remi-release') + assert not remi_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_php_upgrade_user_optin_centos(Pihole): + ''' + confirms installer behavior when user opt-in to installing PHP7 from REMI + (php not currently installed) + ''' + # Whiptail dialog returns Cancel for user prompt + mock_command('whiptail', {'*': ('', '0')}, Pihole) + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout not in distro_check.stdout + expected_stdout = info_box + (' Enabling Remi\'s RPM repository ' + '(https://rpms.remirepo.net)') + assert expected_stdout in distro_check.stdout + expected_stdout = tick_box + (' Remi\'s RPM repository has ' + 'been enabled for PHP7') + assert expected_stdout in distro_check.stdout + remi_package = Pihole.package('remi-release') + assert remi_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_php_version_lt_7_detected_upgrade_default_optout_centos(Pihole): + ''' + confirms the default behavior to opt-out of upgrading to PHP7 from REMI + ''' + # first we will install the default php version to test installer behavior + php_install = Pihole.run('yum install -y php') + assert php_install.rc == 0 + php_package = Pihole.package('php') + default_centos_php_version = php_package.version.split('.')[0] + if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended + pytest.skip("Test deprecated . Detected default PHP version >= 7") + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout in distro_check.stdout + remi_package = Pihole.package('remi-release') + assert not remi_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_php_version_lt_7_detected_upgrade_user_optout_centos(Pihole): + ''' + confirms installer behavior when user opt-out to upgrade to PHP7 via REMI + ''' + # first we will install the default php version to test installer behavior + php_install = Pihole.run('yum install -y php') + assert php_install.rc == 0 + php_package = Pihole.package('php') + default_centos_php_version = php_package.version.split('.')[0] + if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended + pytest.skip("Test deprecated . Detected default PHP version >= 7") + # Whiptail dialog returns Cancel for user prompt + mock_command('whiptail', {'*': ('', '1')}, Pihole) + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + ''') + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout in distro_check.stdout + remi_package = Pihole.package('remi-release') + assert not remi_package.is_installed + + +@pytest.mark.parametrize("tag", [('centos'), ]) +def test_php_version_lt_7_detected_upgrade_user_optin_centos(Pihole): + ''' + confirms installer behavior when user opt-in to upgrade to PHP7 via REMI + ''' + # first we will install the default php version to test installer behavior + php_install = Pihole.run('yum install -y php') + assert php_install.rc == 0 + php_package = Pihole.package('php') + default_centos_php_version = php_package.version.split('.')[0] + if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended + pytest.skip("Test deprecated . Detected default PHP version >= 7") + # Whiptail dialog returns Cancel for user prompt + mock_command('whiptail', {'*': ('', '0')}, Pihole) + distro_check = Pihole.run(''' + source /opt/pihole/basic-install.sh + distro_check + install_dependent_packages PIHOLE_WEB_DEPS[@] + ''') + expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' + 'Deprecated PHP may be in use.') + assert expected_stdout not in distro_check.stdout + expected_stdout = info_box + (' Enabling Remi\'s RPM repository ' + '(https://rpms.remirepo.net)') + assert expected_stdout in distro_check.stdout + expected_stdout = tick_box + (' Remi\'s RPM repository has ' + 'been enabled for PHP7') + assert expected_stdout in distro_check.stdout + remi_package = Pihole.package('remi-release') + assert remi_package.is_installed + updated_php_package = Pihole.package('php') + updated_php_version = updated_php_package.version.split('.')[0] + assert int(updated_php_version) == 7 From e4a6dcd35c65ec62eb7df677dbe03291538be110 Mon Sep 17 00:00:00 2001 From: bcambl Date: Sat, 7 Jul 2018 17:51:36 -0600 Subject: [PATCH 14/21] update travis.yml to run tests in parallel Signed-off-by: bcambl --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2ca3b2d2..e8c6ce10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ python: install: - pip install -r requirements.txt -script: py.test -vv +script: py.test -vv -n auto From 4c23964964d2d6bc86a36a29f7d44721ad3ec2eb Mon Sep 17 00:00:00 2001 From: bcambl Date: Sat, 7 Jul 2018 18:42:10 -0600 Subject: [PATCH 15/21] ensure images are build prior to running tests Signed-off-by: bcambl --- .travis.yml | 6 +++++- test/test_000_build_containers.py | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e8c6ce10..563ec131 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,8 @@ python: install: - pip install -r requirements.txt -script: py.test -vv -n auto +script: + # run tasks marked as 'build_stage' first (ensure docker images are built) + - py.test -vv -n auto -m "build_stage" + # run the remaining tasks in the test suite + - py.test -vv -n auto -m "not build_stage" diff --git a/test/test_000_build_containers.py b/test/test_000_build_containers.py index ad243754..e9e9e7db 100644 --- a/test/test_000_build_containers.py +++ b/test/test_000_build_containers.py @@ -12,6 +12,9 @@ run_local = testinfra.get_backend( ('test/centos.Dockerfile', 'pytest_pihole:centos'), ('test/fedora.Dockerfile', 'pytest_pihole:fedora'), ]) +# mark as 'build_stage' so we can ensure images are build first when tests +# are executed in parallel. (not required when tests are executed serially) +@pytest.mark.build_stage def test_build_pihole_image(image, tag): build_cmd = run_local('docker build -f {} -t {} .'.format(image, tag)) if build_cmd.rc != 0: From fff31558a0aa2a2b05a04231822ffa6bf903bfbd Mon Sep 17 00:00:00 2001 From: bcambl Date: Sun, 8 Jul 2018 13:58:23 -0600 Subject: [PATCH 16/21] assert REMI repository is not installed for Fedora - fix whiptail mock comments to clarify continue vs cancel Signed-off-by: bcambl --- test/test_automated_install.py | 2 +- test/test_centos_fedora_support.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 683c688c..8b9ed39e 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -269,7 +269,7 @@ def test_selinux_enforcing_continue(Pihole): ''' # getenforce returns the running state of SELinux mock_command('getenforce', {'*': ('Enforcing', '0')}, Pihole) - # Whiptail dialog returns Cancel for user prompt + # Whiptail dialog returns Continue for user prompt mock_command('whiptail', {'*': ('', '0')}, Pihole) check_selinux = Pihole.run(''' source /opt/pihole/basic-install.sh diff --git a/test/test_centos_fedora_support.py b/test/test_centos_fedora_support.py index 3447edfa..033d6752 100644 --- a/test/test_centos_fedora_support.py +++ b/test/test_centos_fedora_support.py @@ -11,7 +11,8 @@ from conftest import ( @pytest.mark.parametrize("tag", [('fedora'), ]) def test_epel_and_remi_not_installed_fedora(Pihole): ''' - confirms installer does not attempt to install EPEL repository on Fedora + confirms installer does not attempt to install EPEL/REMI repositories + on Fedora ''' distro_check = Pihole.run(''' source /opt/pihole/basic-install.sh @@ -27,6 +28,8 @@ def test_epel_and_remi_not_installed_fedora(Pihole): assert expected_stdout not in distro_check.stdout epel_package = Pihole.package('epel-release') assert not epel_package.is_installed + remi_package = Pihole.package('remi-release') + assert not remi_package.is_installed @pytest.mark.parametrize("tag", [('centos'), ]) @@ -51,7 +54,6 @@ def test_release_supported_version_check_centos(Pihole): assert expected_stdout in distro_check.stdout expected_stdout = 'Please update to CentOS release 7 or later' assert expected_stdout in distro_check.stdout - # assert distro_check.rc == 1 # currently only exits.. should exit 1? @pytest.mark.parametrize("tag", [('centos'), ]) @@ -113,7 +115,7 @@ def test_php_upgrade_user_optin_centos(Pihole): confirms installer behavior when user opt-in to installing PHP7 from REMI (php not currently installed) ''' - # Whiptail dialog returns Cancel for user prompt + # Whiptail dialog returns Continue for user prompt mock_command('whiptail', {'*': ('', '0')}, Pihole) distro_check = Pihole.run(''' source /opt/pihole/basic-install.sh @@ -192,7 +194,7 @@ def test_php_version_lt_7_detected_upgrade_user_optin_centos(Pihole): default_centos_php_version = php_package.version.split('.')[0] if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended pytest.skip("Test deprecated . Detected default PHP version >= 7") - # Whiptail dialog returns Cancel for user prompt + # Whiptail dialog returns Continue for user prompt mock_command('whiptail', {'*': ('', '0')}, Pihole) distro_check = Pihole.run(''' source /opt/pihole/basic-install.sh From 88e4b6390c77f641cf15fceea77c1d453aa0e0d7 Mon Sep 17 00:00:00 2001 From: Adam Hill Date: Wed, 11 Jul 2018 23:23:32 -0500 Subject: [PATCH 17/21] Tox! Signed-off-by: Adam Hill --- .gitignore | 4 ++++ .travis.yml | 3 +-- requirements.txt | 1 + setup.py | 6 ++++++ test/README.md | 13 +++++++++++++ tox.ini | 10 ++++++++++ 6 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 setup.py create mode 100644 test/README.md create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 91bb6aff..1e80dfb8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ __pycache__ .cache .pytest_cache +.tox +.eggs +*.egg-info + # Created by https://www.gitignore.io/api/jetbrains+iml diff --git a/.travis.yml b/.travis.yml index 563ec131..eaaff197 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,5 @@ install: script: # run tasks marked as 'build_stage' first (ensure docker images are built) - - py.test -vv -n auto -m "build_stage" # run the remaining tasks in the test suite - - py.test -vv -n auto -m "not build_stage" + - tox diff --git a/requirements.txt b/requirements.txt index 53737ca5..f2c61e42 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ pytest pytest-xdist pytest-cov testinfra +tox diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..0e393bc1 --- /dev/null +++ b/setup.py @@ -0,0 +1,6 @@ +from setuptools import setup + +setup( + setup_requires=['pytest-runner'], + tests_require=['pytest'], +) diff --git a/test/README.md b/test/README.md new file mode 100644 index 00000000..07f6c539 --- /dev/null +++ b/test/README.md @@ -0,0 +1,13 @@ +# How do I test? + +Make sure you have Docker and Python w/pip package manager. + +From command line all you need to do is: + +- `pip install tox` +- `tox` + +# How do I debug python? + +Highly recommended: Setup PyCharm on a **Docker enabled** machine. Having a python debugger like PyCharm changes your life if you've never used it :) + diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..e7916e04 --- /dev/null +++ b/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py27 + +[testenv] +whitelist_externals = docker +deps = -rrequirements.txt +commands = docker build -f test/debian.Dockerfile -t pytest_pihole:debian . + docker build -f test/centos.Dockerfile -t pytest_pihole:centos . + docker build -f test/fedora.Dockerfile -t pytest_pihole:fedora . + pytest {posargs:-vv -n auto} -m "not build_stage" ./test/ From 449b7bf6e414ae8cea4c4ae30bb70eb986593912 Mon Sep 17 00:00:00 2001 From: Adam Hill Date: Wed, 11 Jul 2018 23:25:08 -0500 Subject: [PATCH 18/21] reduce the amount of strict `not in` checks Signed-off-by: Adam Hill --- test/README.md | 1 - test/test_centos_fedora_support.py | 15 ++++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/test/README.md b/test/README.md index 07f6c539..5029becf 100644 --- a/test/README.md +++ b/test/README.md @@ -10,4 +10,3 @@ From command line all you need to do is: # How do I debug python? Highly recommended: Setup PyCharm on a **Docker enabled** machine. Having a python debugger like PyCharm changes your life if you've never used it :) - diff --git a/test/test_centos_fedora_support.py b/test/test_centos_fedora_support.py index 033d6752..1afde246 100644 --- a/test/test_centos_fedora_support.py +++ b/test/test_centos_fedora_support.py @@ -1,4 +1,5 @@ import pytest +import re from conftest import ( tick_box, info_box, @@ -18,14 +19,8 @@ def test_epel_and_remi_not_installed_fedora(Pihole): source /opt/pihole/basic-install.sh distro_check ''') - expected_stdout = info_box + (' Enabling EPEL package repository ' - '(https://fedoraproject.org/wiki/EPEL)') - assert expected_stdout not in distro_check.stdout - expected_stdout = tick_box + ' Installed epel-release' - assert expected_stdout not in distro_check.stdout - expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' - 'Deprecated PHP may be in use.') - assert expected_stdout not in distro_check.stdout + assert distro_check.stdout == '' + epel_package = Pihole.package('epel-release') assert not epel_package.is_installed remi_package = Pihole.package('remi-release') @@ -121,9 +116,7 @@ def test_php_upgrade_user_optin_centos(Pihole): source /opt/pihole/basic-install.sh distro_check ''') - expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. ' - 'Deprecated PHP may be in use.') - assert expected_stdout not in distro_check.stdout + assert 'opt-out' not in distro_check.stdout expected_stdout = info_box + (' Enabling Remi\'s RPM repository ' '(https://rpms.remirepo.net)') assert expected_stdout in distro_check.stdout From 8ca4c66e3c0811cc6ff482ef5d683705f05be2e6 Mon Sep 17 00:00:00 2001 From: Adam Hill Date: Thu, 12 Jul 2018 00:03:10 -0500 Subject: [PATCH 19/21] make smarter assertions rathe than `largestring not in string` Signed-off-by: Adam Hill --- test/test_automated_install.py | 40 +++++++++++++++++------------- test/test_centos_fedora_support.py | 1 - 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/test/test_automated_install.py b/test/test_automated_install.py index 8b9ed39e..876b06eb 100644 --- a/test/test_automated_install.py +++ b/test/test_automated_install.py @@ -1,4 +1,5 @@ from textwrap import dedent +import re from conftest import ( SETUPVARS, tick_box, @@ -193,12 +194,16 @@ def test_configureFirewall_IPTables_enabled_rules_exist_no_errors(Pihole): expected_stdout = 'Installing new IPTables firewall rulesets' assert expected_stdout in configureFirewall.stdout firewall_calls = Pihole.run('cat /var/log/iptables').stdout - iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT' - assert iptables_line not in firewall_calls - iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' - assert iptables_line not in firewall_calls - iptables_line = 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' - assert iptables_line not in firewall_calls + # General call type occurances + assert len(re.findall(r'iptables -S', firewall_calls)) == 1 + assert len(re.findall(r'iptables -C', firewall_calls)) == 4 + assert len(re.findall(r'iptables -I', firewall_calls)) == 0 + + # Specific port call occurances + assert len(re.findall(r'tcp --dport 80', firewall_calls)) == 1 + assert len(re.findall(r'tcp --dport 53', firewall_calls)) == 1 + assert len(re.findall(r'udp --dport 53', firewall_calls)) == 1 + assert len(re.findall(r'tcp --dport 4711:4720', firewall_calls)) == 1 def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): @@ -236,12 +241,16 @@ def test_configureFirewall_IPTables_enabled_not_exist_no_errors(Pihole): expected_stdout = 'Installing new IPTables firewall rulesets' assert expected_stdout in configureFirewall.stdout firewall_calls = Pihole.run('cat /var/log/iptables').stdout - iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT' - assert iptables_line in firewall_calls - iptables_line = 'iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT' - assert iptables_line in firewall_calls - iptables_line = 'iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT' - assert iptables_line in firewall_calls + # General call type occurances + assert len(re.findall(r'iptables -S', firewall_calls)) == 1 + assert len(re.findall(r'iptables -C', firewall_calls)) == 4 + assert len(re.findall(r'iptables -I', firewall_calls)) == 4 + + # Specific port call occurances + assert len(re.findall(r'tcp --dport 80', firewall_calls)) == 2 + assert len(re.findall(r'tcp --dport 53', firewall_calls)) == 2 + assert len(re.findall(r'udp --dport 53', firewall_calls)) == 2 + assert len(re.findall(r'tcp --dport 4711:4720', firewall_calls)) == 2 def test_selinux_enforcing_default_exit(Pihole): @@ -351,7 +360,7 @@ def test_update_package_cache_success_no_errors(Pihole): ''') expected_stdout = tick_box + ' Update local cache of available packages' assert expected_stdout in updateCache.stdout - assert 'Error: Unable to update package cache.' not in updateCache.stdout + assert 'error' not in updateCache.stdout.lower() def test_update_package_cache_failure_no_errors(Pihole): @@ -478,10 +487,7 @@ def test_FTL_download_aarch64_no_errors(Pihole): ''') expected_stdout = tick_box + ' Downloading and Installing FTL' assert expected_stdout in download_binary.stdout - error = 'Error: Download of binary from Github failed' - assert error not in download_binary.stdout - error = 'Error: URL not found' - assert error not in download_binary.stdout + assert 'error' not in download_binary.stdout.lower() def test_FTL_download_unknown_fails_no_errors(Pihole): diff --git a/test/test_centos_fedora_support.py b/test/test_centos_fedora_support.py index 1afde246..8318e44a 100644 --- a/test/test_centos_fedora_support.py +++ b/test/test_centos_fedora_support.py @@ -1,5 +1,4 @@ import pytest -import re from conftest import ( tick_box, info_box, From b04195041ab8b94eac4be6722a3c132eb6001645 Mon Sep 17 00:00:00 2001 From: Adam Hill Date: Thu, 12 Jul 2018 10:22:50 -0500 Subject: [PATCH 20/21] Update README.md --- test/README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/README.md b/test/README.md index 5029becf..f5a9b5e8 100644 --- a/test/README.md +++ b/test/README.md @@ -1,4 +1,4 @@ -# How do I test? +# Recommended way to run tests Make sure you have Docker and Python w/pip package manager. @@ -7,6 +7,19 @@ From command line all you need to do is: - `pip install tox` - `tox` +Tox handles setting up a virtual environment for python dependancies, installing dependancies, building the docker images used by tests, and finally running tests. It's an easy way to have travis-ci like build behavior locally. + +## Alternative py.test method of running tests + +You're responsible for setting up your virtual env and dependancies in this situation. + +``` +py.test -vv -n auto -m "build_stage" +py.test -vv -n auto -m "not build_stage" +``` + +The build_stage tests have to run first to create the docker images, followed by the actual tests which utilize said images. Unless you're changing your dockerfiles you shouldn't have to run the build_stage every time - but it's a good idea to rebuild at least once a day in case the base Docker images or packages change. + # How do I debug python? Highly recommended: Setup PyCharm on a **Docker enabled** machine. Having a python debugger like PyCharm changes your life if you've never used it :) From 6b17620389c3c407f74670e613d5b50485390886 Mon Sep 17 00:00:00 2001 From: Adam Hill Date: Thu, 12 Jul 2018 10:24:01 -0500 Subject: [PATCH 21/21] Update .travis.yml --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index eaaff197..fa525e01 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,5 @@ install: - pip install -r requirements.txt script: - # run tasks marked as 'build_stage' first (ensure docker images are built) - # run the remaining tasks in the test suite + # tox.ini handles setup, ordering of docker build first, and then run tests - tox