Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cgi response code as error check point #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
gabrielfernandes-codes marked this conversation as resolved.
Show resolved Hide resolved
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