diff --git a/.gitignore b/.gitignore index 7f4b915..5d32496 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ **/*.rs.bk # Default upload directory -/upload/ +**/upload/ diff --git a/fixtures/.env b/fixtures/.env new file mode 100644 index 0000000..da936d9 --- /dev/null +++ b/fixtures/.env @@ -0,0 +1 @@ +RUST_LOG=error \ No newline at end of file diff --git a/fixtures/README.md b/fixtures/README.md new file mode 100644 index 0000000..023af52 --- /dev/null +++ b/fixtures/README.md @@ -0,0 +1,51 @@ +## Fixtures + +This directory contains the [test fixtures](https://en.wikipedia.org/wiki/Test_fixture) and a simple testing framework for `rustypaste`. + +### Running fixtures + +1. Build the project in debug mode: `cargo build` +2. Execute the runner script in this directory: `./test-fixtures.sh` + +### Adding new fixtures + +Create an appropriately named directory for the test fixture you want to add. e.g. `test-file-upload` + +Each fixture directory should contain the following files: + +``` +test-file-upload/ +├── config.toml +└── test.sh +``` + +- `config.toml`: Contains the `rustypaste` configuration. See [the default configuration](../config.toml). +- `test.sh`: Contains the helper functions for testing. The file format is the following: + +```sh +#!/usr/bin/env bash + +setup() { + # preparation +} + +run_test() { + # assertions +} + +teardown() { + # cleanup +} +``` + +These functions are executed in the order defined above. + +See the [test-file-upload](./test-file-upload/test.sh) fixture for an example. + +### Debugging + +Set the `DEBUG` environment variable to `true` while executing the runner script: + +```sh +$ DEBUG=true ./test-fixtures.sh +``` diff --git a/fixtures/test-duplicate-file-upload/config.toml b/fixtures/test-duplicate-file-upload/config.toml new file mode 100644 index 0000000..a949e05 --- /dev/null +++ b/fixtures/test-duplicate-file-upload/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = true diff --git a/fixtures/test-duplicate-file-upload/test.sh b/fixtures/test-duplicate-file-upload/test.sh new file mode 100755 index 0000000..935e4d1 --- /dev/null +++ b/fixtures/test-duplicate-file-upload/test.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +duplicate_content="test data" + +setup() { + echo "$duplicate_content" > file + date +%s > unique_file1 + sleep 1 + date +%s > unique_file2 +} + +run_test() { + first_file_url=$(curl -s -F "file=@file" localhost:8000) + test "$duplicate_content" = "$(cat upload/file.txt)" + + second_file_url=$(curl -s -F "file=@file" localhost:8000) + test "$first_file_url" = "$second_file_url" + for url in "$first_file_url" "$second_file_url"; do + test "$duplicate_content" = "$(curl -s $url)" + done + + first_file_url=$(curl -s -F "file=@unique_file1" localhost:8000) + second_file_url=$(curl -s -F "file=@unique_file2" localhost:8000) + test "$first_file_url" != "$second_file_url" +} + +teardown() { + rm file unique_file1 unique_file2 + rm -r upload +} diff --git a/fixtures/test-expiring-file-upload/config.toml b/fixtures/test-expiring-file-upload/config.toml new file mode 100644 index 0000000..bef300e --- /dev/null +++ b/fixtures/test-expiring-file-upload/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-expiring-file-upload/test.sh b/fixtures/test-expiring-file-upload/test.sh new file mode 100755 index 0000000..a05eeae --- /dev/null +++ b/fixtures/test-expiring-file-upload/test.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +content="test data" + +setup() { + echo "$content" > file +} + +run_test() { + file_url=$(curl -s -F "file=@file" -H "expire:1s" localhost:8000) + test "$content" = "$(cat upload/file.txt.*)" + sleep 2s + + result="$(curl -s $file_url)" + test "file is not found or expired :(" = "$result" +} + +teardown() { + rm file + rm -r upload +} diff --git a/fixtures/test-file-upload/config.toml b/fixtures/test-file-upload/config.toml new file mode 100644 index 0000000..bef300e --- /dev/null +++ b/fixtures/test-file-upload/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-file-upload/test.sh b/fixtures/test-file-upload/test.sh new file mode 100755 index 0000000..797074e --- /dev/null +++ b/fixtures/test-file-upload/test.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +content="test data" + +setup() { + echo "$content" > file +} + +run_test() { + file_url=$(curl -s -F "file=@file" localhost:8000) + test "$file_url" = "http://localhost:8000/file.txt" + test "$content" = "$(cat upload/file.txt)" + test "$content" = "$(curl -s $file_url)" +} + +teardown() { + rm file + rm -r upload +} diff --git a/fixtures/test-fixtures.sh b/fixtures/test-fixtures.sh new file mode 100755 index 0000000..2cac43a --- /dev/null +++ b/fixtures/test-fixtures.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +FIXTURE_DIR=$(readlink -f "$(dirname "$0")") +PROJECT_DIR="$FIXTURE_DIR/.." +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' + +run_fixture() { + cd "$FIXTURE_DIR/$1" || exit 1 + source "test.sh" + NO_COLOR=1 CONFIG=config.toml "$PROJECT_DIR/target/debug/rustypaste" & + SERVER_PID=$! + trap 'kill -9 "$SERVER_PID" && wait "$SERVER_PID" 2> /dev/null' RETURN + sleep 1 + setup + run_test + result=$? + teardown + return "$result" +} + +main() { + find * -maxdepth 0 -type d -print0 | while IFS= read -r -d '' fixture; do + run_fixture "$fixture" + exit_status=$? + if [ "$exit_status" -eq 0 ]; then + echo -e "[${GREEN}ok${NC}] $fixture" + else + echo -e "[${RED}fail${NC}] $fixture" + exit "$exit_status" + fi + done +} + +[ "$DEBUG" == 'true' ] && set -x && export RUST_LOG=debug +main diff --git a/fixtures/test-oneshot-upload/config.toml b/fixtures/test-oneshot-upload/config.toml new file mode 100644 index 0000000..bef300e --- /dev/null +++ b/fixtures/test-oneshot-upload/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-oneshot-upload/test.sh b/fixtures/test-oneshot-upload/test.sh new file mode 100755 index 0000000..64c9a6a --- /dev/null +++ b/fixtures/test-oneshot-upload/test.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +content="0nesh0t" + +setup() { + echo "$content" > file +} + +run_test() { + file_url=$(curl -s -F "oneshot=@file" localhost:8000) + test "$content" = $(curl -s "$file_url") + test "$content" = "$(cat upload/oneshot/file.txt.*)" + + result="$(curl -s $file_url)" + test "file is not found or expired :(" = "$result" +} + +teardown() { + rm file + rm -r upload +} diff --git a/fixtures/test-path-traversal/config.toml b/fixtures/test-path-traversal/config.toml new file mode 100644 index 0000000..ac51df8 --- /dev/null +++ b/fixtures/test-path-traversal/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10kb" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-path-traversal/test.sh b/fixtures/test-path-traversal/test.sh new file mode 100755 index 0000000..6190b70 --- /dev/null +++ b/fixtures/test-path-traversal/test.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +content="test" + +setup() { + echo "$content" > file +} + +run_test() { + result=$(curl -s --path-as-is localhost:8000/.) + test "file is not found or expired :(" = "$result" + + result=$(curl -s --write-out "%{http_code}" --path-as-is localhost:8000/../test.sh) + test "404" = "$result" + + result=$(curl -s -X POST -F "file=@file;filename=../." localhost:8000) + test "$content" = "$(cat upload/file.txt)" +} + +teardown() { + rm file + rm -r upload +} diff --git a/fixtures/test-remote-file-upload/config.toml b/fixtures/test-remote-file-upload/config.toml new file mode 100644 index 0000000..5841f04 --- /dev/null +++ b/fixtures/test-remote-file-upload/config.toml @@ -0,0 +1,10 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" +timeout="60s" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-remote-file-upload/test.sh b/fixtures/test-remote-file-upload/test.sh new file mode 100755 index 0000000..ed6a3c8 --- /dev/null +++ b/fixtures/test-remote-file-upload/test.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +url="https://raw.githubusercontent.com/orhun/rustypaste/master/img/rustypaste_logo.png" + +setup() { + :; +} + +run_test() { + file_url=$(curl -s -F "remote=$url" localhost:8000) + curl -s "$file_url" -o uploaded_file > /dev/null + curl -s "$url" -o remote_file > /dev/null + test "$(sha256sum uploaded_file | awk '{print $1}')" = "$(sha256sum remote_file | awk '{print $1}')" +} + +teardown() { + rm uploaded_file remote_file + rm -r upload +} diff --git a/fixtures/test-server-auth/config.toml b/fixtures/test-server-auth/config.toml new file mode 100644 index 0000000..8d08f0e --- /dev/null +++ b/fixtures/test-server-auth/config.toml @@ -0,0 +1,10 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" +auth_token="rustypasteisawesome" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-server-auth/test.sh b/fixtures/test-server-auth/test.sh new file mode 100755 index 0000000..154ed26 --- /dev/null +++ b/fixtures/test-server-auth/test.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +auth_token="rustypasteisawesome" +content="topsecret" + +setup() { + echo "$content" > file +} + +run_test() { + result=$(curl -s -F "file=@file" localhost:8000) + test "unauthorized" = "$result" + + result=$(curl -s -F "file=@file" -H "Authorization: $auth_token" localhost:8000) + test "unauthorized" != "$result" + test "$content" = "$(cat upload/file.txt)" + test "$content" = "$(curl -s $result)" +} + +teardown() { + rm file + rm -r upload +} diff --git a/fixtures/test-server-payload-limit/config.toml b/fixtures/test-server-payload-limit/config.toml new file mode 100644 index 0000000..ac51df8 --- /dev/null +++ b/fixtures/test-server-payload-limit/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10kb" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-server-payload-limit/test.sh b/fixtures/test-server-payload-limit/test.sh new file mode 100755 index 0000000..d0670e3 --- /dev/null +++ b/fixtures/test-server-payload-limit/test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +setup() { + touch emptyfile + truncate -s 9KB smallfile + truncate -s 10KB normalfile + truncate -s 11KB bigfile +} + +run_test() { + result=$(curl -s -F "file=@emptyfile" localhost:8000) + test "invalid file size" = "$result" + + result=$(curl -s -F "file=@bigfile" localhost:8000) + test "upload limit exceeded" = "$result" + + result=$(curl -s -F "file=@normalfile" localhost:8000) + test "upload limit exceeded" != "$result" + + result=$(curl -s -F "file=@smallfile" localhost:8000) + test "upload limit exceeded" != "$result" +} + +teardown() { + rm emptyfile smallfile normalfile bigfile + rm -r upload +} diff --git a/fixtures/test-url-upload/config.toml b/fixtures/test-url-upload/config.toml new file mode 100644 index 0000000..bef300e --- /dev/null +++ b/fixtures/test-url-upload/config.toml @@ -0,0 +1,9 @@ +[server] +address="127.0.0.1:8000" +max_content_length="10MB" +upload_path="./upload" + +[paste] +random_url = { enabled = false, type = "petname", words = 2, separator = "-" } +default_extension = "txt" +duplicate_files = false diff --git a/fixtures/test-url-upload/test.sh b/fixtures/test-url-upload/test.sh new file mode 100755 index 0000000..55e73a8 --- /dev/null +++ b/fixtures/test-url-upload/test.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +url="https://orhun.dev/" + +setup() { + :; +} + +run_test() { + curl -s -F "url=$url" localhost:8000 > /dev/null + test "$url" = "$(cat upload/url/url)" + + result=$(curl -s -F "url=invalidurl" localhost:8000) + test "relative URL without a base" = "$result" +} + +teardown() { + rm -r upload +}