aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2021-10-04 09:04:33 +0000
committerOmar Polo <op@omarpolo.com>2021-10-04 09:04:33 +0000
commit176179b2a9e99af595892c396a219c2bc11fb6c9 (patch)
tree31a9683f9014418846896b50011a3216ecb3a8f8
parentc28994868efd1da6259f805984cc93135bd74a3a (diff)
rework the regression suite
The tests are still there, the suite is equivalent to the old one, but this one is better structured. The biggest annoyance I had with the old one was that it wasn't straightforward to test only a specific set of tests. It's still impossible, but it's way easier to do it now. This extract all the tests to their own functions. It's overall better in all possible regards.
-rw-r--r--.gitignore1
-rw-r--r--regress/Makefile1
-rw-r--r--regress/lib.sh185
-rwxr-xr-xregress/runtime415
-rw-r--r--regress/tests.sh305
5 files changed, 525 insertions, 382 deletions
diff --git a/.gitignore b/.gitignore
index 89f482a..e4a5ff4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,4 @@ regress/iri_test
regress/puny-test
regress/*.o
regress/gg
+regress/gmid.pid
diff --git a/regress/Makefile b/regress/Makefile
index 0efddad..5b2d29b 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -71,6 +71,7 @@ clean:
rm -f localhost.cert.pem localhost.key.pem
rm -f testca.* valid.csr valid.key valid.crt invalid.*pem
rm -rf testdata fill-file puny-test gg fcgi-test
+ rm -f gmid.pid
testdata: fill-file
mkdir testdata
diff --git a/regress/lib.sh b/regress/lib.sh
new file mode 100644
index 0000000..afee6f8
--- /dev/null
+++ b/regress/lib.sh
@@ -0,0 +1,185 @@
+failed=
+
+gg="./gg"
+gmid="./../gmid"
+current_test=
+
+run_test() {
+ ggflags=
+ port=10965
+ config_common="
+ipv6 off
+port $port
+"
+ hdr=
+ body=
+ dont_check=no
+
+ current_test=$1
+ rm -f reg.conf
+
+ if ! $1; then
+ echo "$1 failed"
+ failed="$failed $1"
+ else
+ echo "$1 passed"
+ fi
+
+ if [ "$dont_check" != 'no' ]; then
+ return
+ fi
+
+ if ! check; then
+ echo "gmid crashed?"
+ failed="$failed $1"
+ fi
+}
+
+# usage: gen_config <global config> <server config>
+# generates a configuration file reg.conf
+gen_config() {
+ cat <<EOF > reg.conf
+$config_common
+$1
+server "localhost" {
+ cert "$PWD/cert.pem"
+ key "$PWD/key.pem"
+ root "$PWD/testdata"
+ $2
+}
+EOF
+ if ! checkconf; then
+ echo "failed to parse the config" >&2
+ return 1
+ fi
+}
+
+checkconf() {
+ $gmid -n -c reg.conf >/dev/null
+}
+
+# usage: setup_simple_test <global config> <server config>
+# generates a configuration file with `gen_config', validates it and
+# launches the daemon
+setup_simple_test() {
+ gen_config "$1" "$2"
+ run
+}
+
+# usage: get <path>
+# return the body of the request on stdout
+get() {
+ $gg -T30 -b $ggflags "gemini://localhost:10965/$1"
+}
+
+# usage: head <path>
+# return the meta response line on stdout
+head() {
+ $gg -T30 -h $ggflags "gemini://localhost:10965/$1"
+}
+
+# usage: raw <path>
+# return both header and body
+raw() {
+ $gg -T30 $ggflags "gemini://localhost:10965/$1"
+}
+
+# usage: fetch <path>
+# fetches the header and the body. They're returned in $hdr and
+# $body.
+fetch() {
+ if ! hdr="$(head $1)" || ! body="$(get $1)"; then
+ return 1
+ fi
+}
+
+# usage: fetch_hdr <path>
+# fetches the header into $hdr
+fetch_hdr() {
+ hdr="$(head $1)"
+ body=""
+}
+
+# usage: check_reply header body
+# checks that $hdr and $body are equal to the given strings
+check_reply() {
+ if [ "$hdr" != "$1" ]; then
+ echo "Header mismatch" >&2
+ echo "wants : $1" >&2
+ echo "got : $hdr" >&2
+ return 1
+ fi
+
+ if [ "$body" != "$2" ]; then
+ echo "Body mismatch" >&2
+ echo "wants : $1" >&2
+ echo "got : $body" >&2
+ return 1
+ fi
+}
+
+run() {
+ if check; then
+ kill -HUP "$(cat gmid.pid)"
+ sleep 1
+ return
+ fi
+
+ $gmid -P gmid.pid -c reg.conf
+
+ # give gmid time to bind the port, otherwise we end up
+ # executing gg when gmid isn't ready yet.
+ sleep 1
+}
+
+check() {
+ if [ ! -f gmid.pid ]; then
+ return 1
+ fi
+
+ pid="$(cat gmid.pid || true)"
+ if [ "$pid" == "" ]; then
+ return 1
+ fi
+
+ # remember: we're running under ``set -e''
+ if ps $pid >/dev/null; then
+ return 0
+ fi
+
+ return 1
+}
+
+# usage: sha in out
+# writes the sha256 of `in' to `out'
+sha() {
+ if which sha256 >/dev/null 2>&1; then
+ sha256 < "$1" > "$2"
+ return $?
+ fi
+
+ if which sha256sum >/dev/null 2>&1; then
+ sha256sum "$1" | awk '{print $1}' > "$2"
+ return $?
+ fi
+
+ echo "No sha binary found" >&2
+ exit 1
+}
+
+count() {
+ wc -l | xargs
+}
+
+quit() {
+ pid="$(cat gmid.pid || true)"
+ if [ "$pid" != "" ]; then
+ kill $pid || true
+ wait || true
+ fi
+}
+
+onexit() {
+ rm -f bigfile bigfile.sha
+ quit
+}
diff --git a/regress/runtime b/regress/runtime
index 7566a1a..f34ff7d 100755
--- a/regress/runtime
+++ b/regress/runtime
@@ -1,7 +1,5 @@
#!/bin/sh
-set -e
-
if [ "${SKIP_RUNTIME_TESTS:-0}" -eq 1 ]; then
echo
echo "======================"
@@ -11,387 +9,40 @@ if [ "${SKIP_RUNTIME_TESTS:-0}" -eq 1 ]; then
exit 0
fi
-ggflags=
-
-port=10965
-
-config_common="
-ipv6 off
-port $port
-"
-
-# usage: config <global config> <stuff for localhost>
-# generates a configuration file reg.conf
-config() {
- cat <<EOF > reg.conf
-$config_common
-$1
-server "localhost" {
- cert "$PWD/cert.pem"
- key "$PWD/key.pem"
- root "$PWD/testdata"
- $2
-}
-EOF
-}
-
-checkconf() {
- ./../gmid -n -c reg.conf
-}
-
-# usage: get <path>
-# return the body of the request on stdout
-get() {
- ./gg -T30 -b $ggflags "gemini://localhost:10965/$1"
-}
-
-# usage: head <path>
-# return the meta response line on stdout
-head() {
- ./gg -T30 -h $ggflags "gemini://localhost:10965/$1"
-}
-
-# usage: raw <path>
-# return both header and body
-raw() {
- ./gg -T30 $ggflags "gemini://localhost:10965/$1"
-}
-
-run() {
- ./../gmid -f -c reg.conf &
- pid=$!
- # give gmid time to bind the port, otherwise we end up
- # executing gg when gmid isn't ready yet.
- sleep 1
-}
-
-# usage: check [exit-message]
-# check if gmid is still running
-check() {
- if ! ps $pid >/dev/null; then
- echo ${1:-"gmid crashed?"}
- exit 1
- fi
-}
-
-restart() {
- kill -HUP $pid
- sleep 1
-}
-
-# quit gmid
-quit() {
- kill $pid || true
- wait || true
-}
+rm -f gmid.pid
-count() {
- wc -l | xargs
-}
-
-# usage: eq a b errmsg
-# if a and b aren't equal strings, exit with errmsg
-eq() {
- if ! [ "$1" = "$2" ]; then
- echo "$3: \"$1\" not equal \"$2\""
- exit 1
- fi
-}
-
-onexit() {
- rm -f bigfile bigfile.sha
- quit
-}
-
-# configless tests
-
-./../gmid -p $port -H localhost -d . testdata &
-pid=$!
-sleep 1
-
-eq "$(head /)" "20 text/gemini" "Unexpected head for /"
-eq "$(get /)" "# hello world$ln" "Unexpected body for /"
-echo OK GET / in configless mode
-quit
-
-# daemon tests
+. ./lib.sh
+. ./tests.sh
trap 'onexit' INT TERM EXIT
-endl=`printf "\r\n"`
-lf=`echo`
-
-config "" ""
-checkconf
-run
-
-eq "$(head /)" "20 text/gemini" "Unexpected head for /"
-eq "$(get /)" "# hello world$ln" "Unexpected body for /"
-echo OK GET /
-
-eq "$(head /foo)" "51 not found" "Unexpected head /foo"
-eq "$(get /foo)" "" "Unexpected body /foo"
-echo OK GET /foo
-
-# should redirect if asked for a directory but without the trailing /
-eq "$(head /dir)" "30 /dir/" "Unexpected redirect for /dir"
-eq "$(get /dir)" "" "Unexpected body for redirect"
-echo OK GET /dir
-
-# 51 for a directory without index.gmi
-eq "$(head /dir/)" "51 not found" "Unexpected head for /"
-eq "$(get /dir/)" "" "Unexpected body for error"
-echo OK GET /dir/
-
-eq "$(head /dir/foo.gmi)" "20 text/gemini" "Unexpected head for /dir/foo.gmi"
-eq "$(get /dir/foo.gmi)" "# hello world$ln" "Unexpected body for /dir/foo.gmi"
-echo OK GET /dir/foo.gmi
-
-# try a big file
-eq "$(head /bigfile)" "20 application/octet-stream" "Unexpected head for /bigfile"
-get /bigfile > bigfile
-./sha bigfile bigfile.sha
-eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /bigfile"
-echo OK GET /bigfile
-
-# shouldn't be executing cgi scripts
-eq "$(head /hello)" "20 application/octet-stream" "Unexpected head for /hello"
-echo OK GET /hello
-
-check "should be running"
-
-# try with custom mime
-config 'map "text/x-funny-text" to-ext "gmi"' 'default type "application/x-trash"'
-checkconf
-restart
-
-eq "$(head /)" "20 text/x-funny-text" "Unexpected head for /"
-echo OK GET / with custom mime
-
-eq "$(head /hello)" "20 application/x-trash" "Unexpected head for /hello"
-echo OK GET /hello with custom mime
-
-check "should be running"
-
-# try with custom lang
-config '' 'lang "it"'
-checkconf
-restart
-
-eq "$(head /)" "20 text/gemini;lang=it" "Unexpected head for /"
-echo OK GET / with custom lang
-
-check "should be running"
-
-# make sure we can use different lang in different location rules
-config '' 'lang "it" location "/en/*" { lang "en" } location "/de/*" { lang "de" }'
-checkconf
-echo OK parse multiple locations correctly
-restart
-
-# try with CGI scripts
-config '' 'cgi "*"'
-checkconf
-restart
-
-eq "$(head /hello)" "20 text/gemini" "Unexpected head for /hello"
-eq "$(get /hello)" "# hello world$ln" "Unexpected body for /hello"
-echo OK GET /hello with cgi
-
-eq "$(head /slow)" "20 text/gemini" "Unexpected head for /slow"
-eq "$(get /slow)" "# hello world$ln" "Unexpected body for /slow"
-echo OK GET /slow with cgi
-
-eq "$(head /err)" "42 CGI error" "Unexpected head for /err"
-eq "$(get /err)" "" "Unexpected body for /err"
-echo OK GET /err with cgi
-
-#eq "$(raw /invalid | wc -c | xargs)" 2048 "Unexpected body for /invalid"
-#echo OK GET /invalid with cgi
-
-eq "$(raw /max-length-reply | wc -c | xargs)" 1029 "Unexpected header for /max-length-reply"
-echo OK GET /max-length-reply with cgi
-
-# try a big file
-eq "$(head /serve-bigfile)" "20 application/octet-stream" "Unexpected head for /serve-bigfile"
-get /bigfile > bigfile
-./sha bigfile bigfile.sha
-eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /serve-bigfile"
-echo OK GET /serve-bigfile with cgi
-
-# ensure we split the query correctly
-eq "$(get /env | awk /^-/ | count)" 1 "Unexpected number of arguments"
-eq "$(get /env?foo | awk /^-/ | count)" 2 "Unexpected number of arguments"
-eq "$(get /env?foo+bar | awk /^-/ | count)" 3 "Unexpected number of arguments"
-eq "$(get /env?foo+bar=5 | awk /^-/ | count)" 1 "Unexpected number of arguments"
-eq "$(get /env?foo+bar%3d5 | awk /^-/ | count)" 3 "Unexpected number of arguments"
-
-check "should be running"
-
-config '' 'index "foo.gmi"'
-checkconf
-restart
-
-eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /"
-eq "$(get /dir/)" "# hello world$ln" "Unexpected body for error"
-echo OK GET /dir/ with custom index
-
-check "should be running"
-
-config '' 'location "/dir/*" { default type "text/plain" index "hello" }'
-checkconf
-restart
-
-eq "$(head /dir/hello)" "20 text/plain" "Unexpected head for /"
-echo OK GET /dir/hello with location and default type
-
-eq "$(head /dir/)" "20 text/plain" "Unexpected head for /dir/"
-eq "$(get /dir/|tail -1)" 'echo "# hello world"' "Unexpected body for /dir/"
-echo OK GET /dir/ with location and custom index
-
-check "should be running"
-
-config '' 'location "/dir/*" { auto index on }'
-checkconf
-restart
-
-eq "$(head /)" "20 text/gemini" "Unexpected head for /"
-eq "$(get /)" "# hello world$ln" "Unexpected body for /"
-echo OK GET / with auto index
-
-eq "$(head /dir)" "30 /dir/" "Unexpected head for /dir"
-eq "$(head /dir/)" "20 text/gemini" "Unexpected head for /dir/"
-eq "$(get /dir/|wc -l|xargs)" "5" "Unexpected body for /dir/"
-echo OK GET /dir/ with auto index on
-
-check "should be running"
-
-# test block return and strip
-
-config '' 'location "*" { block }'
-checkconf
-restart
-
-eq "$(head /)" "40 temporary failure" "Unexpected head for /"
-eq "$(get /)" "" "Unexpected body for /"
-echo OK GET / with block
-
-eq "$(head /nonexists)" "40 temporary failure" "Unexpected head for /nonexists"
-eq "$(get /nonexists)" "" "Unexpected body for /nonexists"
-echo OK GET /nonexists with block
-
-check "should be running"
-
-config '' '
-location "/dir" {
- strip 1
- block return 40 "%% %p %q %P %N test"
-}
-location "*" {
- strip 99
- block return 40 "%% %p %q %P %N test"
-}'
-checkconf
-restart
-
-eq "$(head /dir/foo.gmi)" "40 % /foo.gmi 10965 localhost test"
-echo OK GET /dir/foo.gmi with strip and block
-
-eq "$(head /bigfile)" "40 % / 10965 localhost test"
-echo OK GET /bigfile with strip and block
-
-check "should be running"
-
-# test the entrypoint
-
-config '' 'entrypoint "/env"'
-checkconf
-restart
-
-eq "$(head /foo/bar)" "20 text/plain; lang=en" "Unknown head for /foo/bar"
-eq "$(get /foo/bar|grep PATH_INFO)" "PATH_INFO=/foo/bar" "Unexpected PATH_INFO"
-echo OK GET /foo/bar with entrypoint
-
-# test with require ca
-
-config '' 'require client ca "'$PWD'/testca.pem"'
-checkconf
-restart
-
-eq "$(head /)" "60 client certificate required" "Unexpected head for /"
-echo OK GET / without client certificate
-
-ggflags="-C valid.crt -K valid.key"
-eq "$(head /)" "20 text/gemini" "Unexpected head for /"
-echo OK GET / with valid client certificate
-
-ggflags="-C invalid.cert.pem -K invalid.key.pem"
-eq "$(head /)" "61 certificate not authorised" "Unexpected head for /"
-echo OK GET / with invalid client certificate
-
-ggflags=''
-
-
-# test with root inside a location
-
-config '' 'location "/foo/*" { root "'$PWD'/testdata" strip 1 }'
-checkconf
-restart
-
-eq "$(head /foo)" "51 not found" "Unexpected head for /foo"
-eq "$(head /foo/)" "20 text/gemini" "Unexpected head for /foo/"
-echo OK /foo and /foo/ with root inside location
-
-# how to match both /foo and /foo/*
-config '' '
- location "/foo" { block return 31 "%p/" }
- location "/foo/*" { root "'$PWD'/testdata" strip 1 }
-'
-checkconf
-restart
-
-eq "$(head /foo)" "31 /foo/" "Unexpected head for /foo"
-eq "$(head /foo/)" "20 text/gemini" "Unexpected head for /foo/"
-echo OK /foo and /foo/ with root inside location
-
-# test with fastcgi
-
-# NB: the fcgi spawn is NOT supported outside of this test suite
-
-config 'prefork 1' 'fastcgi spawn "'$PWD'/fcgi-test"'
-checkconf
-restart
-
-eq "$(head /)" "20 text/gemini" "Unexpected head for /"
-eq "$(get /)" "# Hello, world!" "Unexpected body for /"
-echo OK GET / with fastcgi
-
-# test macro expansion
-
-cat <<EOF > reg.conf
-pwd = "$PWD"
-$config_common
-
-server "localhost" {
- # the quoting of \$ is for sh
- cert \$pwd "/cert.pem"
- key \$pwd "/key.pem"
- root \$pwd "/testdata"
-}
-EOF
-checkconf
-restart
-
-eq "$(head /)" "20 text/gemini" "Unexpected head for /"
-eq "$(get /)" "# hello world$ln" "Unexpected body for /"
-echo OK GET / with macro expansion
-
-
-# 1.7.4 bugfix: check_for_cgi goes out-of-bound processing a string
-# that doesn't contain a '/'
-config '' 'cgi "*"'
-checkconf
-restart
-
-eq "$(head /favicon.txt)" "51 not found" "Unexpected head for /"
-echo OK GET /favicon.txt with cgi
+run_test test_configless_mode
+run_test test_static_files
+run_test test_directory_redirect
+run_test test_serve_big_files
+run_test test_dont_execute_scripts
+run_test test_custom_mime
+run_test test_default_type
+run_test test_custom_lang
+run_test test_parse_custom_lang_per_location
+run_test test_cgi_scripts
+run_test test_cgi_big_replies
+run_test test_cgi_split_query
+run_test test_custom_index
+run_test test_custom_index_default_type_per_location
+run_test test_auto_index
+run_test test_block
+run_test test_block_return_fmt
+run_test test_entrypoint
+run_test test_require_client_ca
+run_test test_root_inside_location
+run_test test_root_inside_location_with_redirect
+run_test test_fastcgi
+run_test test_macro_expansion
+run_test test_174_bugfix
+
+if [ "$failed" != "" ]; then
+ echo
+ echo "failed tests:$failed"
+ exit 1
+fi
diff --git a/regress/tests.sh b/regress/tests.sh
new file mode 100644
index 0000000..c01013e
--- /dev/null
+++ b/regress/tests.sh
@@ -0,0 +1,305 @@
+test_configless_mode() {
+ dont_check=yes
+
+ $gmid -p $port -H localhost -d . testdata &
+ pid=$!
+ sleep 1
+
+ fetch /
+ kill $pid
+ check_reply "20 text/gemini" "# hello world" || return 1
+}
+
+test_static_files() {
+ setup_simple_test
+
+ fetch /
+ check_reply "20 text/gemini" "# hello world" || return 1
+
+ fetch /foo
+ check_reply "51 not found" || return 1
+
+ fetch /dir/foo.gmi
+ check_reply "20 text/gemini" "# hello world" || return 1
+}
+
+test_directory_redirect() {
+ setup_simple_test
+
+ fetch /dir
+ check_reply "30 /dir/" || return 1
+
+ fetch /dir/
+ check_reply "51 not found" || return 1
+}
+
+test_serve_big_files() {
+ setup_simple_test
+
+ hdr="$(head /bigfile)"
+ get /bigfile > bigfile
+ sha bigfile bigfile.sha
+ body="$(cat bigfile.sha)"
+
+ check_reply "20 application/octet-stream" "$(cat testdata/bigfile.sha)"
+}
+
+test_dont_execute_scripts() {
+ setup_simple_test
+
+ fetch_hdr /hello
+ check_reply "20 application/octet-stream" "" || return 1
+}
+
+test_custom_mime() {
+ setup_simple_test 'map "text/x-funny" to-ext "gmi"' ''
+
+ fetch_hdr /
+ check_reply "20 text/x-funny"
+}
+
+test_default_type() {
+ setup_simple_test '' 'default type "application/x-foo"'
+
+ fetch_hdr /hello
+ check_reply "20 application/x-foo"
+}
+
+test_custom_lang() {
+ setup_simple_test '' 'lang it'
+
+ fetch_hdr /
+ check_reply "20 text/gemini;lang=it"
+}
+
+test_parse_custom_lang_per_location() {
+ setup_simple_test '' \
+ 'lang it location "/en/*" {lang en} location "/de/*" {lang de}'
+ # can parse multiple locations
+}
+
+test_cgi_scripts() {
+ setup_simple_test '' 'cgi "*"'
+
+ fetch /hello
+ check_reply "20 text/gemini" "# hello world" || return 1
+
+ fetch /slow
+ check_reply "20 text/gemini" "# hello world" || return 1
+
+ fetch /err
+ check_reply "42 CGI error" || return 1
+
+ fetch /invalid
+ check_reply "42 CGI error" || return 1
+}
+
+test_cgi_big_replies() {
+ setup_simple_test '' 'cgi "*"'
+
+ hdr="$(head /serve-bigfile)"
+ get /bigfile > bigfile
+ sha bigfile bigfile.sha
+ body="$(cat bigfile.sha)"
+ check_reply "20 application/octet-stream" "$(cat testdata/bigfile.sha)"
+}
+
+test_cgi_split_query() {
+ setup_simple_test '' 'cgi "*"'
+
+ for s in "1" "2 ?foo" "3 ?foo+bar" "1 ?foo+bar=5" "3 ?foo+bar%3d5"; do
+ exp="$(echo $s | sed 's/ .*//')"
+ qry="$(echo $s | sed 's/^..//')"
+
+ if [ "$exp" = "$qry" ]; then
+ # the "1" case yields exp == qry
+ qry=''
+ fi
+
+ url="/env$qry"
+
+ n="$(get "$url" | awk /^-/ | count)"
+ if [ $? -ne 0 ]; then
+ echo "failed to get /$url"
+ return 1
+ fi
+
+ if [ "$n" -ne $exp ]; then
+ echo "Unexpected number of args"
+ echo "want : $exp"
+ echo "got : $n"
+ return 1
+ fi
+ done
+}
+
+test_custom_index() {
+ setup_simple_test '' 'index "foo.gmi"'
+
+ fetch /dir/
+ check_reply "20 text/gemini" "# hello world"
+}
+
+test_custom_index_default_type_per_location() {
+ setup_simple_test '' 'location "/dir/*" { default type "text/plain" index "hello" }'
+
+ fetch /dir/
+ check_reply "20 text/plain" "$(cat hello)"
+}
+
+test_auto_index() {
+ setup_simple_test '' 'location "/dir/*" { auto index on }'
+
+ fetch /
+ check_reply "20 text/gemini" "# hello world" || return 1
+
+ fetch_hdr /dir
+ check_reply "30 /dir/" || return 1
+
+ fetch_hdr /dir/
+ check_reply "20 text/gemini"
+
+ # we expect 5 lines from the auto index
+
+ body="$(get /dir/ | count)"
+ if [ $? -ne 0 ]; then
+ echo 'failed to get /dir/'
+ return 1
+ fi
+
+ if [ "$body" -ne 5 ]; then
+ echo "expected five lines from the auto index, got $body"
+ return 1
+ fi
+}
+
+test_block() {
+ setup_simple_test '' 'location "*" { block }'
+
+ fetch /
+ check_reply "40 temporary failure" || return 1
+
+ fetch /nonexists
+ check_reply "40 temporary failure" || return 1
+}
+
+test_block_return_fmt() {
+ setup_simple_test '' '
+location "/dir" {
+ strip 1
+ block return 40 "%% %p %q %P %N test"
+}
+location "*" {
+ strip 99
+ block return 40 "%% %p %q %P %N test"
+}'
+
+ fetch_hdr /dir/foo.gmi
+ check_reply "40 % /foo.gmi 10965 localhost test" || return 1
+
+ fetch_hdr /bigfile
+ check_reply "40 % / 10965 localhost test" || return 1
+}
+
+test_entrypoint() {
+ setup_simple_test '' 'entrypoint "/env"'
+
+ fetch_hdr /foo/bar
+ check_reply "20 text/plain; lang=en" || return 1
+
+ # TODO: test something similar with plain cgi too
+
+ body="$(get /foo/bar|grep PATH_INFO)"
+ if [ $? -ne 0 ]; then
+ echo "failed to get /foo/bar"
+ return 1
+ fi
+
+ if [ "$body" != "PATH_INFO=/foo/bar" ]; then
+ echo "Invalid PATH_INFO generated"
+ echo "want : PATH_INFO=/foo/bar"
+ echo "got : $body"
+ return 1
+ fi
+}
+
+test_require_client_ca() {
+ setup_simple_test '' 'require client ca "'$PWD'/testca.pem"'
+
+ fetch /
+ check_reply "60 client certificate required" || return 1
+
+ ggflags="-C valid.crt -K valid.key"
+ fetch_hdr /
+ check_reply "20 text/gemini" || return 1
+
+ ggflags="-C invalid.cert.pem -K invalid.key.pem"
+ fetch_hdr /
+ check_reply "61 certificate not authorised" || return 1
+}
+
+test_root_inside_location() {
+ setup_simple_test '' 'location "/foo/*" { root "'$PWD'/testdata" strip 1 }'
+
+ fetch /foo
+ check_reply "51 not found" || return 1
+
+ fetch_hdr /foo/
+ check_reply "20 text/gemini"
+}
+
+test_root_inside_location_with_redirect() {
+ setup_simple_test '' '
+location "/foo" { block return 31 "%p/" }
+location "/foo/*" { root "'$PWD'/testdata" strip 1 }'
+
+ fetch /foo
+ check_reply "31 /foo/" || return 1
+
+ fetch_hdr /foo/
+ check_reply "20 text/gemini"
+}
+
+test_fastcgi() {
+ # XXX: prefork 1 for testing
+ setup_simple_test 'prefork 1' 'fastcgi spawn "'$PWD'/fcgi-test"'
+
+ fetch /
+ check_reply "20 text/gemini" "# Hello, world!"
+}
+
+test_macro_expansion() {
+ cat <<EOF > reg.conf
+pwd = "$PWD"
+$config_common
+
+server "localhost" {
+ # the quoting of \$ is for sh
+ cert \$pwd "/cert.pem"
+ key \$pwd "/key.pem"
+ root \$pwd "/testdata"
+}
+EOF
+
+ if ! checkconf; then
+ echo "failed to parse the config"
+ return 1
+ fi
+
+ run
+
+ fetch /
+ check_reply "20 text/gemini" "# hello world"
+}
+
+# 1.7.4 bugfix: check_for_cgi goes out-of-bound processing a string
+# that doesn't contain a '/'
+test_174_bugfix() {
+ setup_simple_test '' 'cgi "*"'
+
+ # thanks cage :)
+ for i in 0 1 2 3 4 5 6 7 8 9; do
+ fetch /favicon.txt
+ check_reply "51 not found" || return 1
+ done
+}