Skip to content

Commit

Permalink
Use cgi response code as error check point
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfernandes-codes committed Nov 28, 2020
1 parent 6b560ef commit 2c1bd6c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 29 deletions.
26 changes: 17 additions & 9 deletions php-fpm-healthcheck
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
# Ping mode with data (outputs php-fpm status text): ./php-fpm-healthcheck -v
#
# Exit status codes:
# 2,9,111 - Couldn't connect to PHP fpm, is it running?
# 8 - Couldn't reach PHP fpm status page, have you configured it with `pm.status_path = /status`?
# 1 - A healthcheck condition has failed
# 2 - Couldn't connect to PHP fpm, is it running?
# 3 - Invalid option given
# 4 - One or more required softwares are missing
# 8 - Couldn't reach PHP fpm status page, have you configured it with `pm.status_path = /status`?
# 9 - Couldn't connect to PHP fpm, is it running?
# 10 - Invalid PHP fpm status page response
# 111 - Couldn't connect to PHP fpm, is it running?
#
# Available options:
# -v|--verbose
Expand Down Expand Up @@ -52,16 +55,21 @@ command -v grep 1> /dev/null || { >&2 echo "Make sure grep is installed (i.e. ap
# Get status from fastcgi connection
# $1 - cgi-fcgi connect argument
get_fpm_status() {
if test "$VERBOSE" = 1; then printf "Trying to connect to php-fpm via: %s%s\\n" "$1" "$SCRIPT_NAME"; fi;

# Since I cannot use pipefail I'll just split these in two commands
if test "$VERBOSE" = 1; then printf "Trying to connect to PHP-FPM via: %s%s\\n" "$1" "$SCRIPT_NAME"; fi;

FPM_STATUS=$(env -i REQUEST_METHOD="$REQUEST_METHOD" SCRIPT_NAME="$SCRIPT_NAME" SCRIPT_FILENAME="$SCRIPT_FILENAME" "$FCGI_CMD_PATH" -bind -connect "$1" 2> /dev/null)
FPM_STATUS=$(echo "$FPM_STATUS" | tail +5)
RESPONSE_CODE=$(echo "$FPM_STATUS" | sed -n '/Status:/p' | sed -e 's/[^0-9]//g')

if test "$VERBOSE" = 1; then printf "php-fpm status output:\\n%s\\n" "$FPM_STATUS"; fi;
# If missing status code, assume 200
if ! test "$RESPONSE_CODE" -eq "$RESPONSE_CODE" 2> /dev/null; then
RESPONSE_CODE=200
fi

if test "$FPM_STATUS" = "File not found."; then
>&2 printf "php-fpm status page non reachable\\n";
if test "$RESPONSE_CODE" -ge 200 -a "$RESPONSE_CODE" -lt 400; then
if test "$VERBOSE" = 1; then printf "PHP-FPM status output:\\n%s\\n" "$(echo "$FPM_STATUS" | tail +5)"; fi;
return
else
>&2 printf "PHP-FPM status page non reachable. Error: %s\\n" "$RESPONSE_CODE";
exit 8;
fi;
}
Expand Down
50 changes: 35 additions & 15 deletions test/testinfra/test_fpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ def test_exit_when_no_status_page_is_configured(host, setup_fpm_to_default_fixtu

cmd = host.run("php-fpm-healthcheck -v")
assert cmd.rc == 8
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "status output:" in cmd.stdout
assert "php-fpm status page non reachable" in cmd.stderr
assert "Trying to connect to PHP-FPM via:" in cmd.stdout
assert "PHP-FPM status page non reachable. Error: 404" in cmd.stderr

@pytest.mark.php_fpm
def test_fpm_on_socket(host, setup_fpm_to_default_fixture):
Expand All @@ -34,54 +33,75 @@ def test_fpm_on_socket(host, setup_fpm_to_default_fixture):

cmd = host.run("FCGI_CONNECT=/var/run/php-fpm.sock php-fpm-healthcheck -v")
assert cmd.rc == 0
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "status output:" in cmd.stdout
assert "Trying to connect to PHP-FPM via:" in cmd.stdout
assert "PHP-FPM status output:" in cmd.stdout
assert "pool:" in cmd.stdout

# https://github.com/renatomefi/php-fpm-healthcheck/issues/18
@pytest.mark.php_fpm
def test_fpm_on_socket_with_huge_env(host, setup_fpm_to_default_fixture):
cmd = host.run("HUGE_ENV=\"$(dd if=/dev/zero bs=8192 count=1 | tr '\\000' '\\040')\" php-fpm-healthcheck -v")
assert cmd.rc == 0
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "status output:" in cmd.stdout
assert "Trying to connect to PHP-FPM via:" in cmd.stdout
assert "PHP-FPM status output:" in cmd.stdout
assert "pool:" in cmd.stdout

@pytest.mark.php_fpm
def test_default_status_page_path(host, setup_fpm_to_default_fixture):
cmd = host.run("php-fpm-healthcheck -v")
assert cmd.rc == 0
assert "Trying to connect to php-fpm via: localhost:9000/status" in cmd.stdout
assert "Trying to connect to PHP-FPM via: localhost:9000/status" in cmd.stdout

@pytest.mark.php_fpm
def test_exit_when_fpm_is_invalid_path(host, setup_fpm_to_default_fixture):
cmd = host.run("FCGI_STATUS_PATH=/invalid php-fpm-healthcheck -v")
assert cmd.rc == 8
assert "Trying to connect to php-fpm via: localhost:9000/invalid" in cmd.stdout
assert "File not found." in cmd.stdout
assert "php-fpm status page non reachable" in cmd.stderr
assert "Trying to connect to PHP-FPM via: localhost:9000/invalid" in cmd.stdout
assert "PHP-FPM status page non reachable. Error: 404" in cmd.stderr

# @pytest.mark.php_fpm
# def test_exit_when_fpm_has_500_error_code(host, setup_fpm_to_default_fixture):
# This tests should be included when possible to use custom status page
# host.run("mkdir -p /var/www/html/error")
# host.run("touch /var/www/html/error/index.php")
# host.run("echo \"<?php http_response_code(500);\" > /var/www/html/error/index.php")
# cmd = host.run("FCGI_STATUS_PATH=/var/www/html/error/index.php php-fpm-healthcheck -v")
# assert cmd.rc == 8
# assert "Trying to connect to PHP-FPM via: localhost:9000/var/www/html/error/index.php" in cmd.stdout
# assert "PHP-FPM status page non reachable. Error: 500" in cmd.stderr

# @pytest.mark.php_fpm
# def test_exit_when_fpm_has_400_error_code(host, setup_fpm_to_default_fixture):
# This tests should be included when possible to use custom status page
# host.run("mkdir -p /var/www/html/error")
# host.run("touch /var/www/html/error/index.php")
# host.run("echo \"<?php http_response_code(400);\" > /var/www/html/error/index.php")
# cmd = host.run("FCGI_STATUS_PATH=/var/www/html/error/index.php php-fpm-healthcheck -v")
# assert cmd.rc == 8
# assert "Trying to connect to PHP-FPM via: localhost:9000/var/www/html/error/index.php" in cmd.stdout
# assert "PHP-FPM status page non reachable. Error: 400" in cmd.stderr

@pytest.mark.alpine
def test_exit_when_fpm_is_not_reachable_apk(host, setup_fpm_to_default_fixture):
cmd = host.run("FCGI_CONNECT=localhost:9001 php-fpm-healthcheck -v")
assert cmd.rc in (111, 9)
assert "Trying to connect to php-fpm via: localhost:9001" in cmd.stdout
assert "Trying to connect to PHP-FPM via: localhost:9001" in cmd.stdout

@pytest.mark.alpine
def test_exit_when_fpm_is_invalid_host_apk(host, setup_fpm_to_default_fixture):
cmd = host.run("FCGI_CONNECT=abc php-fpm-healthcheck -v")
assert cmd.rc in (2, 9)
assert "Trying to connect to php-fpm via: abc" in cmd.stdout
assert "Trying to connect to PHP-FPM via: abc" in cmd.stdout

@pytest.mark.stretch
def test_exit_when_fpm_is_not_reachable_apt(host, setup_fpm_to_default_fixture):
cmd = host.run("FCGI_CONNECT=localhost:9001 php-fpm-healthcheck -v")
assert cmd.rc == 111
assert "Trying to connect to php-fpm via: localhost:9001" in cmd.stdout
assert "Trying to connect to PHP-FPM via: localhost:9001" in cmd.stdout

@pytest.mark.stretch
def test_exit_when_fpm_is_invalid_host_apt(host, setup_fpm_to_default_fixture):
cmd = host.run("FCGI_CONNECT=abc php-fpm-healthcheck -v")
assert cmd.rc == 2
assert "Trying to connect to php-fpm via: abc" in cmd.stdout
assert "Trying to connect to PHP-FPM via: abc" in cmd.stdout

6 changes: 3 additions & 3 deletions test/testinfra/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ def test_metric_fail_accepted_conn_with_other_metrics(host):
def test_metric_accepted_conn(host):
cmd = host.run("php-fpm-healthcheck -v")
assert cmd.rc == 0
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "status output:" in cmd.stdout
assert "Trying to connect to PHP-FPM via:" in cmd.stdout
assert "PHP-FPM status output:" in cmd.stdout
assert "pool:" in cmd.stdout

@pytest.mark.php_fpm
def test_listen_queue_len_and_listen_queue_vars_are_parsed_correctly(host):
cmd = host.run("php-fpm-healthcheck --verbose --listen-queue=5 --max-listen-queue=1024")
assert cmd.rc == 0
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "Trying to connect to PHP-FPM via:" in cmd.stdout
assert "'listen queue' value '0' and expected is less than '5" in cmd.stdout
assert "'max listen queue' value '0' and expected is less than '1024'" in cmd.stdout
4 changes: 2 additions & 2 deletions test/testinfra/test_ping.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ def test_ping(host):
def test_ping_verbose(host):
cmd = host.run("php-fpm-healthcheck -v")
assert cmd.rc == 0
assert "Trying to connect to php-fpm via:" in cmd.stdout
assert "status output:" in cmd.stdout
assert "Trying to connect to PHP-FPM via:" in cmd.stdout
assert "PHP-FPM status output:" in cmd.stdout
assert "pool:" in cmd.stdout

0 comments on commit 2c1bd6c

Please sign in to comment.