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

Enhancement: Run end-to-end tests asserting an HTTP response status code #900

Merged
merged 1 commit into from
Jan 23, 2024
Merged
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
10 changes: 8 additions & 2 deletions .github/workflows/integrate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
extensions: "none, json, mbstring, tokenizer"
extensions: "none, curl, json, mbstring, tokenizer"
php-version: "${{ matrix.php-version }}"

- name: "Set up problem matchers for PHP"
Expand Down Expand Up @@ -64,6 +64,9 @@ jobs:
php-version:
- "8.2"

env:
HTTP_HOST: "localhost:8080"

steps:
- name: "Checkout"
uses: "actions/checkout@v4"
Expand All @@ -72,11 +75,14 @@ jobs:
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
extensions: "none"
extensions: "none, curl"
php-version: "${{ matrix.php-version }}"

- name: "Set up problem matchers for PHP"
run: "echo \"::add-matcher::${{ runner.tool_cache }}/php.json\""

- name: "Start built-in web server for PHP"
run: "php -S ${{ env.HTTP_HOST }} .router.php &"

- name: "Run tests"
run: "php tests/run-tests.php -j3 -q --show-diff"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ backend/mirror.gif
backend/mirror.png
backend/mirror.jpg
backend/GeoIP.dat
tests/server.log
tests/server.pid
.php-cs-fixer.cache
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.EXPORT_ALL_VARIABLES:

HTTP_HOST:=localhost:8080

.PHONY: help
help: ## Displays this list of targets with descriptions
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}'
Expand All @@ -7,8 +11,8 @@ coding-standards: vendor ## Fixes code style issues with friendsofphp/php-cs-fix
vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose

.PHONY: tests
tests: ## Runs tests
php tests/run-tests.php -j3 -q
tests: vendor ## Runs tests
tests/server start; php tests/run-tests.php -j3 -q; tests/server stop

vendor: composer.json composer.lock
composer validate --strict
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"php": "~8.2.0"
},
"require-dev": {
"ext-curl": "*",
"friendsofphp/php-cs-fixer": "^3.40.2"
},
"autoload": {
Expand Down
6 changes: 4 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
--TEST--
paths return HTTP response status code 200, 301, or 302
--FILE--
<?php

declare(strict_types=1);

$httpHost = getenv('HTTP_HOST');

if (!is_string($httpHost)) {
throw new \RuntimeException('Environment variable "HTTP_HOST" is not set.');
}

$pathToRoot = realpath(__DIR__ . '/../..');

$pathsToFiles = [
...glob($pathToRoot . '/*.php'),
...glob($pathToRoot . '/archive/*.php'),
...glob($pathToRoot . '/conferences/*.php'),
...glob($pathToRoot . '/license/*.php'),
...glob($pathToRoot . '/manual/*.php'),
...glob($pathToRoot . '/manual/en/*.php'),
...glob($pathToRoot . '/releases/*.php'),
...glob($pathToRoot . '/releases/*/*.php'),
...glob($pathToRoot . '/releases/*/*/*.php'),
];

$paths = str_replace($pathToRoot, '', $pathsToFiles);

$baseUrl = sprintf(
'http://%s',
$httpHost,
);

$pathsToStatusCodes = array_combine(
$paths,
array_map(static function (string $url) use ($baseUrl): int {
$handle = curl_init();

$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => sprintf(
'%s%s',
$baseUrl,
$url,
),
];

curl_setopt_array($handle, $options);

curl_exec($handle);

return curl_getinfo($handle, CURLINFO_HTTP_CODE);
}, $paths),
);

$pathsWithUnexpectedStatusCodes = array_filter($pathsToStatusCodes, static function (int $statusCode): bool {
return !in_array($statusCode, [200, 301, 302], true);
});

var_dump($pathsWithUnexpectedStatusCodes);
?>
--EXPECT--
array(0) {
}
3 changes: 3 additions & 0 deletions tests/php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[PHP]

display_errors = Off
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

171 changes: 171 additions & 0 deletions tests/server
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#!/bin/bash

# https://github.com/cubny/php-built-in-server-manager/blob/9a5cbeaad50a108d6058b882b83ba23fbd7722a9/server

# default hostname
HOST=localhost
# default port number
PORT=8080
# script name
NAME=${0##*/}

usage () {
cat <<EOF

$NAME (PHP built-in web server manager) Version 0.2.0
PHP builtin server manager on port $PORT

usage: ./$NAME <command> [<hostname>:<port>]

Available commands:

start Starts PHP built-in web server server on specified hostname:port, default is localhost:$PORT
stop Stops the PHP built-in web server
restart Stops and Starts on previously specified hostname:port
status Status of "$NAME" process
log Show the PHP built-in web server logs. Use the -f option for a live update


report bugs to [email protected]
$NAME homepage: <https://github.com/cubny/php-built-in-server-manager>

EOF
return 0
}

setup_colors() {

if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
BOLD=""
NORMAL=""
fi
}

# if no command specified exit and show usage
if [[ $# < 1 ]]; then
echo $NAME: no command specified
usage
exit 1
fi

# if hostname:port specified override defaults
if [[ $# > 1 ]]; then
IFS=':' read -r -a hostport <<< "$2"
if [[ ! -z "${hostport[0]}" ]]; then
HOST=${hostport[0]}
fi
if [[ ! -z "${hostport[1]}" ]]; then
PORT=${hostport[1]}
fi
fi

# pidfile contents would be hostname:port:pid
PIDFILE=tests/server.pid
LOGFILE=tests/server.log

validate_server () {
which php &> /dev/null
if [[ $? -eq 1 ]]; then
printf "${YELLOW}Error: PHP not found. ${NORMAL}Please install PHP version 5.4 or greater!\n"
return 1
fi

php -h | grep -q -- '-S'
if [[ $? -eq 1 ]]; then
printf "${YELLOW}Error: PHP version must be 5.4 or greater!${NORMAL}\n"
return 1
fi

return 0
}

start_server () {
validate_server

if [[ $? -eq 1 ]]; then
return 1
fi

if [[ -e "$PIDFILE" ]]; then
printf "${YELLOW}Server seems to be running!${NORMAL}\n"
echo
echo if not, there is probably a zombie "$PIDFILE" in this directory.
echo if you are sure no server is running just remove "$PIDFILE" manually and start again
return 1
else
printf "${GREEN}"$NAME" started on $HOST:$PORT${NORMAL}\n"
php -S "$HOST":"$PORT" -c tests/php.ini >> "$LOGFILE" 2>&1 &
echo "$HOST":"$PORT":$! > $PIDFILE
return 0
fi
}

read_pidfile() {
if [[ -e "$PIDFILE" ]]; then
PIDFILECONTENT=`cat "$PIDFILE"`
IFS=: read HOST PORT PID <<< "$PIDFILECONTENT:"
return 0
else
return 1
fi
}

stop_server () {
if read_pidfile; then
kill -9 "$PID"
rm -f "$PIDFILE"
printf "${GREEN}"$NAME" stopped!${NORMAL}\n"
return 0
else
printf "${YELLOW}"$NAME" is not running!${NORMAL}\n"
return 1
fi
}

status_server() {
if read_pidfile && kill -0 "$PID" ; then
printf "${BLUE}"$NAME" is running on ${HOST}:${PORT}${NORMAL}\n"
else
printf "${YELLOW}"$NAME" is not running!${NORMAL}\n"
fi
}


log_server() {
if read_pidfile && kill -0 "$PID" ; then
if [[ "$1" = "-f" ]]; then
TAIL_OPTS="-f"
fi
tail $TAIL_OPTS "$LOGFILE"
else
printf "${YELLOW}"$NAME" is not running!${NORMAL}\n"
fi
}


setup_colors

case $1 in
start) start_server;;
stop) stop_server;;
restart) stop_server; start_server ;;
status) status_server;;
log) log_server $2;;
-h) usage ;;
--help) usage ;;
*) usage;;
esac