mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
637558f5aa
Signed-off-by: DL6ER <dl6er@dl6er.de>
304 lines
11 KiB
Bash
304 lines
11 KiB
Bash
#!./test/libs/bats/bin/bats
|
|
|
|
@test "Starting tests without prior history" {
|
|
run bash -c 'grep -c "Total DNS queries: 0" /var/log/pihole-FTL.log'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "1" ]]
|
|
}
|
|
|
|
@test "Initial blocking status is enabled" {
|
|
run bash -c 'grep -c "Blocking status is enabled" /var/log/pihole-FTL.log'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "1" ]]
|
|
}
|
|
|
|
@test "Number of compiled regex filters as expected" {
|
|
run bash -c 'grep -c "Compiled 2 whitelist and 1 blacklist regex filters" /var/log/pihole-FTL.log'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "1" ]]
|
|
}
|
|
|
|
@test "Blacklisted domain is blocked" {
|
|
run bash -c "dig blacklist-blocked.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0.0.0.0" ]]
|
|
[[ ${lines[1]} == "" ]]
|
|
}
|
|
|
|
@test "Gravity domain is blocked" {
|
|
run bash -c "dig gravity-blocked.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0.0.0.0" ]]
|
|
[[ ${lines[1]} == "" ]]
|
|
}
|
|
|
|
@test "Gravity domain is blocked (TCP)" {
|
|
run bash -c "dig gravity-blocked.test.pi-hole.net @127.0.0.1 +tcp +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0.0.0.0" ]]
|
|
[[ ${lines[1]} == "" ]]
|
|
}
|
|
|
|
@test "Gravity domain + whitelist exact match is not blocked" {
|
|
run bash -c "dig whitelisted.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Gravity domain + whitelist regex match is not blocked" {
|
|
run bash -c "dig discourse.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Regex blacklist match is blocked" {
|
|
run bash -c "dig regex5.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0.0.0.0" ]]
|
|
[[ ${lines[1]} == "" ]]
|
|
}
|
|
|
|
@test "Regex blacklist mismatch is not blocked" {
|
|
run bash -c "dig regexA.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Regex blacklist match + whitelist exact match is not blocked" {
|
|
run bash -c "dig regex1.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Regex blacklist match + whitelist regex match is not blocked" {
|
|
run bash -c "dig regex2.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Client 2: Gravity match matching unassociated whitelist is blocked" {
|
|
run bash -c "dig whitelisted.test.pi-hole.net -b 127.0.0.2 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Client 2: Regex blacklist match matching unassociated whitelist is blocked" {
|
|
run bash -c "dig regex1.test.pi-hole.net -b 127.0.0.2 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Same domain is not blocked for client 1 ..." {
|
|
run bash -c "dig regex1.test.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "... or client 3" {
|
|
run bash -c "dig regex1.test.pi-hole.net -b 127.0.0.3 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Client 2: Unassociated blacklist match is not blocked" {
|
|
run bash -c "dig blacklist-blocked.test.pi-hole.net -b 127.0.0.2 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Client 3: Exact blacklist domain is not blocked" {
|
|
run bash -c "dig blacklist-blocked.test.pi-hole.net -b 127.0.0.3 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Client 3: Regex blacklist domain is not blocked" {
|
|
run bash -c "dig regex1.test.pi-hole.net -b 127.0.0.3 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Client 3: Gravity domain is not blocked" {
|
|
run bash -c "dig discourse.pi-hole.net -b 127.0.0.3 @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Google.com (A) is not blocked" {
|
|
run bash -c "dig A google.com @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "0.0.0.0" ]]
|
|
}
|
|
|
|
@test "Google.com (AAAA) is not blocked (TCP query)" {
|
|
run bash -c "dig AAAA google.com @127.0.0.1 +short +tcp"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} != "::" ]]
|
|
[[ ${lines[1]} == "" ]]
|
|
}
|
|
|
|
@test "Known host is resolved as expected" {
|
|
run bash -c "dig ftl.pi-hole.net @127.0.0.1 +short"
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "139.59.170.52" ]]
|
|
[[ ${lines[1]} == "" ]]
|
|
}
|
|
|
|
@test "pihole-FTL.db schema as expected" {
|
|
run bash -c 'sqlite3 /etc/pihole/pihole-FTL.db .dump'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ "${lines[@]}" == *"CREATE TABLE queries ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER NOT NULL, type INTEGER NOT NULL, status INTEGER NOT NULL, domain TEXT NOT NULL, client TEXT NOT NULL, forward TEXT );"* ]]
|
|
[[ "${lines[@]}" == *"CREATE TABLE ftl ( id INTEGER PRIMARY KEY NOT NULL, value BLOB NOT NULL );"* ]]
|
|
[[ "${lines[@]}" == *"CREATE TABLE counters ( id INTEGER PRIMARY KEY NOT NULL, value INTEGER NOT NULL );"* ]]
|
|
[[ "${lines[@]}" == *"CREATE TABLE IF NOT EXISTS \"network\" ( id INTEGER PRIMARY KEY NOT NULL, hwaddr TEXT UNIQUE NOT NULL, interface TEXT NOT NULL, name TEXT, firstSeen INTEGER NOT NULL, lastQuery INTEGER NOT NULL, numQueries INTEGER NOT NULL, macVendor TEXT);"* ]]
|
|
[[ "${lines[@]}" == *"CREATE TABLE network_addresses ( network_id INTEGER NOT NULL, ip TEXT NOT NULL, lastSeen INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)), UNIQUE(network_id,ip), FOREIGN KEY(network_id) REFERENCES network(id));"* ]]
|
|
[[ "${lines[@]}" == *"CREATE INDEX idx_queries_timestamps ON queries (timestamp);"* ]]
|
|
}
|
|
|
|
@test "Fail on invalid argument" {
|
|
run bash -c '/home/pihole/pihole-FTL abc'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "pihole-FTL: invalid option -- 'abc'" ]]
|
|
[[ ${lines[1]} == "Try '/home/pihole/pihole-FTL --help' for more information" ]]
|
|
}
|
|
|
|
@test "Help argument return help text" {
|
|
run bash -c '/home/pihole/pihole-FTL help'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "pihole-FTL - The Pi-hole FTL engine" ]]
|
|
[[ ${lines[3]} == "Available arguments:" ]]
|
|
}
|
|
|
|
@test "No WARNING messages in pihole-FTL.log (besides known capability issues)" {
|
|
run bash -c 'grep "WARNING:" /var/log/pihole-FTL.log | grep -c -v -E "CAP_NET_ADMIN|CAP_NET_RAW"'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0" ]]
|
|
}
|
|
|
|
@test "No ERROR messages in pihole-FTL.log (besides known index.html error)" {
|
|
run bash -c 'grep "ERROR:" /var/log/pihole-FTL.log | grep -c -v -E "index\.html"'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0" ]]
|
|
}
|
|
|
|
@test "No FATAL messages in pihole-FTL.log" {
|
|
run bash -c 'grep -c "FATAL:" /var/log/pihole-FTL.log'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0" ]]
|
|
}
|
|
|
|
# x86_64-musl is built on busybox which has a slightly different
|
|
# variant of ls displaying three, instead of one, spaces between the
|
|
# user and group names.
|
|
|
|
@test "Ownership and permissions of pihole-FTL.db correct" {
|
|
run bash -c 'ls -l /etc/pihole/pihole-FTL.db'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == *"pihole pihole"* || ${lines[0]} == *"pihole pihole"* ]]
|
|
[[ ${lines[0]} == "-rw-r--r--"* ]]
|
|
}
|
|
|
|
# "ldd" prints library dependencies and the used interpreter for a given program
|
|
#
|
|
# Dependencies on shared libraries are displayed like
|
|
# libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa7d28be000)
|
|
#
|
|
# In this test, we use ldd and check for the dependency arrow "=>" to check if
|
|
# our generated binary depends on shared libraries in the way we expect it to
|
|
|
|
@test "Dependence on shared libraries" {
|
|
run bash -c 'ldd ./pihole-FTL'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ "${STATIC}" != "true" && "${lines[@]}" == *"=>"* ]] || \
|
|
[[ "${STATIC}" == "true" && "${lines[@]}" != *"=>"* ]]
|
|
}
|
|
|
|
# "file" determines the file type of our generated binary
|
|
#
|
|
# We use its ability to test whether a specific interpreter is
|
|
# required by the given executable. What the interpreter is, is not
|
|
# really well documented in "man elf(5)", however, one can say that
|
|
# the interpreter is a program that finds and loads the shared
|
|
# libraries needed by a program, prepares the program to run, and then
|
|
# runs it.
|
|
#
|
|
# In this test, we use "file" to confirm the absence of the dependence
|
|
# on an interpreter for the static binary.
|
|
|
|
@test "Dependence on specific interpreter" {
|
|
run bash -c 'file ./pihole-FTL'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ "${STATIC}" != "true" && "${lines[@]}" == *"interpreter"* ]] || \
|
|
[[ "${STATIC}" == "true" && "${lines[@]}" != *"interpreter"* ]]
|
|
}
|
|
|
|
@test "Architecture is correctly reported on startup" {
|
|
run bash -c 'grep "Compiled for" /var/log/pihole-FTL.log'
|
|
printf "Output: %s\n\$CIRCLE_JOB: %s\nuname -m: %s\n" "${lines[@]:-not set}" "${CIRCLE_JOB:-not set}" "$(uname -m)"
|
|
[[ ${lines[0]} == *"Compiled for ${CIRCLE_JOB:-$(uname -m)}"* ]]
|
|
}
|
|
|
|
@test "Building machine (CI) is reported on startup" {
|
|
[[ ${CIRCLE_JOB} != "" ]] && compiled_str="on CI" || compiled_str="locally" && export compiled_str
|
|
run bash -c 'grep "Compiled for" /var/log/pihole-FTL.log'
|
|
printf "Output: %s\n\$CIRCLE_JOB: %s\n" "${lines[@]:-not set}" "${CIRCLE_JOB:-not set}"
|
|
[[ ${lines[0]} == *"(compiled ${compiled_str})"* ]]
|
|
}
|
|
|
|
@test "Compiler version is correctly reported on startup" {
|
|
compiler_version="$(${CC} --version | head -n1)" && export compiler_version
|
|
run bash -c 'grep "Compiled for" /var/log/pihole-FTL.log'
|
|
printf "Output: %s\n\$CC: %s\nVersion: %s\n" "${lines[@]:-not set}" "${CC:-not set}" "${compiler_version:-not set}"
|
|
[[ ${lines[0]} == *"using ${compiler_version}"* ]]
|
|
}
|
|
|
|
@test "No errors on setting busy handlers for the databases" {
|
|
run bash -c 'grep -c "Cannot set busy handler" /var/log/pihole-FTL.log'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "0" ]]
|
|
}
|
|
|
|
@test "Blocking status is correctly logged in pihole.log" {
|
|
run bash -c 'grep -c "gravity blocked gravity-blocked.test.pi-hole.net is 0.0.0.0" /var/log/pihole.log'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "2" ]]
|
|
}
|
|
|
|
@test "HTTP server responds correctly to ping" {
|
|
run bash -c 'curl -s 127.0.0.1:8080/ping'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "pong" ]]
|
|
}
|
|
|
|
@test "HTTP server responds with JSON error 404 to unknown API path" {
|
|
run bash -c 'curl -s 127.0.0.1:8080/admin/api/undefined'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "{\"error\":{\"key\":\"not_found\",\"message\":\"Not found\",\"data\":{\"path\":\"/admin/api/undefined\"}}}" ]]
|
|
}
|
|
|
|
@test "HTTP server responds with normal error 404 to path outside /admin" {
|
|
run bash -c 'curl -s 127.0.0.1:8080/undefined'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "Error 404: Not Found" ]]
|
|
}
|
|
|
|
# This test does not work without actually hosting the web interface
|
|
#@test "HTTP server responds without error to undefined path inside /admin (rerouted to index.html)" {
|
|
# run bash -c 'curl -I -s 127.0.0.1:8080/admin/undefined'
|
|
# printf "%s\n" "${lines[@]}"
|
|
# [[ ${lines[0]} == "HTTP/1.1 200 OK"* ]]
|
|
#}
|
|
|
|
@test "API authorization: Unauthorized for request without password" {
|
|
run bash -c 'curl -I -s 127.0.0.1:8080/admin/api/auth'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "HTTP/1.1 401 Unauthorized"* ]]
|
|
}
|
|
|
|
# This test is assuming the user password is empty
|
|
@test "API authorization: Success for request with correct password" {
|
|
run bash -c 'curl -s -H "X-Pi-hole-Authenticate: cd372fb85148700fa88095e3492d3f9f5beb43e555e5ff26d95f5a6adc36f8e6" 127.0.0.1:8080/admin/api/auth'
|
|
printf "%s\n" "${lines[@]}"
|
|
[[ ${lines[0]} == "{\"status\":\"success\"}" ]]
|
|
}
|