Docker HTTPS by default, smoke test improvements

Docker:
- HTTPS enabled by default (generates self-signed cert)
- Added docker-entrypoint.sh for SSL cert generation
- Gunicorn now starts with --certfile/--keyfile when HTTPS enabled
- Install curl/openssl in web container for healthcheck and certs
- Updated docs to reflect HTTPS default

Smoke Test:
- Moved from rpi/ to scripts/ (works for Pi, Docker, and dev)
- Updated header and examples
- Added to .gitignore exceptions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Aaron D. Lee
2026-01-07 23:45:44 -05:00
parent a00a154a1a
commit 455c6dfd01
7 changed files with 95 additions and 14 deletions

View File

@@ -1,328 +0,0 @@
#!/bin/bash
#
# Stegasoo Pi Smoke Test
# Tests all core functionality against a running Pi instance
#
# Usage: ./smoke-test.sh [host] [port] [user] [pass]
#
set -e
# Configuration
HOST="${1:-stegasoo.local}"
PORT="${2:-443}"
USER="${3:-admin}"
PASS="${4:-stegasoo}"
# Build URL (don't include :443 since it's default for https)
if [ "$PORT" = "443" ]; then
BASE_URL="https://$HOST"
else
BASE_URL="https://$HOST:$PORT"
fi
COOKIE_JAR="/tmp/stegasoo_smoke_cookies.txt"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEST_DATA="$SCRIPT_DIR/../test_data"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
PASSED=0
FAILED=0
# -----------------------------------------------------------------------------
# Helper functions
# -----------------------------------------------------------------------------
log_test() {
echo -e "${CYAN}[TEST]${NC} $1"
}
log_pass() {
echo -e "${GREEN}[PASS]${NC} $1"
PASSED=$((PASSED + 1))
}
log_fail() {
echo -e "${RED}[FAIL]${NC} $1"
FAILED=$((FAILED + 1))
}
curl_get() {
curl -sk "$BASE_URL$1" -b "$COOKIE_JAR" -c "$COOKIE_JAR" "${@:2}"
}
curl_post() {
curl -sk -X POST "$BASE_URL$1" -b "$COOKIE_JAR" -c "$COOKIE_JAR" "${@:2}"
}
wait_for_job() {
local endpoint="$1"
local job_id="$2"
local max_polls="${3:-30}"
for i in $(seq 1 $max_polls); do
sleep 1
result=$(curl_get "$endpoint/$job_id")
if echo "$result" | grep -q '"status":\s*"complete"'; then
echo "$result"
return 0
fi
if echo "$result" | grep -q '"status":\s*"error"'; then
echo "$result"
return 1
fi
done
echo '{"status":"timeout"}'
return 1
}
# -----------------------------------------------------------------------------
# Tests
# -----------------------------------------------------------------------------
test_connectivity() {
log_test "Connectivity to $BASE_URL"
if curl -sk --connect-timeout 5 "$BASE_URL" -o /dev/null; then
log_pass "Server reachable"
else
log_fail "Cannot reach server"
exit 1
fi
}
test_setup_or_login() {
log_test "Setup/Login"
# Check if setup needed
response=$(curl_get "/" -L -o /dev/null -w "%{url_effective}")
if echo "$response" | grep -q "/setup"; then
log_test "Completing first-time setup..."
curl_post "/setup" \
-d "username=$USER" \
-d "password=$PASS" \
-d "password_confirm=$PASS" \
-L -o /dev/null
fi
# Login
curl_get "/login" -o /dev/null # Get session
curl_post "/login" \
-d "username=$USER" \
-d "password=$PASS" \
-L -o /dev/null
# Verify logged in
code=$(curl_get "/encode" -o /dev/null -w "%{http_code}")
if [ "$code" = "200" ]; then
log_pass "Authenticated successfully"
else
log_fail "Authentication failed (got $code)"
fi
}
test_pages() {
log_test "Page accessibility"
local pages="encode decode generate tools about"
local all_pass=true
for page in $pages; do
code=$(curl_get "/$page" -o /dev/null -w "%{http_code}")
if [ "$code" = "200" ]; then
echo -e " ${GREEN}${NC} /$page"
else
echo -e " ${RED}${NC} /$page ($code)"
all_pass=false
fi
done
if $all_pass; then
log_pass "All pages accessible"
else
log_fail "Some pages inaccessible"
fi
}
test_encode_decode_dct() {
log_test "DCT Encode/Decode round trip"
local message="DCT smoke test $(date +%s)"
# Encode
response=$(curl_post "/encode" \
-F "reference_photo=@$TEST_DATA/ref.jpg" \
-F "carrier=@$TEST_DATA/carrier.jpg" \
-F "message=$message" \
-F "passphrase=tower booty sunny windy" \
-F "pin=727643678" \
-F "embed_mode=dct" \
-F "channel_key=auto" \
-F "async=true")
job_id=$(echo "$response" | grep -oP '"job_id":\s*"[^"]+"' | cut -d'"' -f4)
if [ -z "$job_id" ]; then
log_fail "DCT encode - no job ID returned"
return
fi
# Wait for encode
result=$(wait_for_job "/encode/status" "$job_id" 15)
if ! echo "$result" | grep -q '"status":\s*"complete"'; then
log_fail "DCT encode timeout or error"
return
fi
file_id=$(echo "$result" | grep -oP '"file_id":\s*"[^"]+"' | cut -d'"' -f4)
curl_get "/encode/download/$file_id" -o /tmp/stego_dct_test.jpg
echo -e " ${GREEN}${NC} Encoded $(ls -lh /tmp/stego_dct_test.jpg | awk '{print $5}')"
# Decode
response=$(curl_post "/decode" \
-F "reference_photo=@$TEST_DATA/ref.jpg" \
-F "stego_image=@/tmp/stego_dct_test.jpg" \
-F "passphrase=tower booty sunny windy" \
-F "pin=727643678" \
-F "embed_mode=auto" \
-F "channel_key=auto" \
-F "async=true")
job_id=$(echo "$response" | grep -oP '"job_id":\s*"[^"]+"' | cut -d'"' -f4)
# Wait for decode (DCT is slower on Pi)
result=$(wait_for_job "/decode/status" "$job_id" 60)
if echo "$result" | grep -q "$message"; then
log_pass "DCT round trip - message verified"
else
log_fail "DCT decode - message mismatch"
echo " Expected: $message"
echo " Got: $result"
fi
}
test_encode_decode_lsb() {
log_test "LSB Encode/Decode round trip"
local message="LSB smoke test $(date +%s)"
# Encode
response=$(curl_post "/encode" \
-F "reference_photo=@$TEST_DATA/ref.jpg" \
-F "carrier=@$TEST_DATA/carrier.jpg" \
-F "message=$message" \
-F "passphrase=tower booty sunny windy" \
-F "pin=727643678" \
-F "embed_mode=lsb" \
-F "channel_key=auto" \
-F "async=true")
job_id=$(echo "$response" | grep -oP '"job_id":\s*"[^"]+"' | cut -d'"' -f4)
if [ -z "$job_id" ]; then
log_fail "LSB encode - no job ID returned"
return
fi
result=$(wait_for_job "/encode/status" "$job_id" 10)
if ! echo "$result" | grep -q '"status":\s*"complete"'; then
log_fail "LSB encode timeout or error"
return
fi
file_id=$(echo "$result" | grep -oP '"file_id":\s*"[^"]+"' | cut -d'"' -f4)
curl_get "/encode/download/$file_id" -o /tmp/stego_lsb_test.png
echo -e " ${GREEN}${NC} Encoded $(ls -lh /tmp/stego_lsb_test.png | awk '{print $5}')"
# Decode
response=$(curl_post "/decode" \
-F "reference_photo=@$TEST_DATA/ref.jpg" \
-F "stego_image=@/tmp/stego_lsb_test.png" \
-F "passphrase=tower booty sunny windy" \
-F "pin=727643678" \
-F "embed_mode=lsb" \
-F "channel_key=auto" \
-F "async=true")
job_id=$(echo "$response" | grep -oP '"job_id":\s*"[^"]+"' | cut -d'"' -f4)
result=$(wait_for_job "/decode/status" "$job_id" 15)
if echo "$result" | grep -q "$message"; then
log_pass "LSB round trip - message verified"
else
log_fail "LSB decode - message mismatch"
fi
}
test_tools() {
log_test "Tools endpoints"
# Capacity check
response=$(curl_post "/api/tools/capacity" \
-F "image=@$TEST_DATA/carrier.jpg" \
-w "%{http_code}" -o /tmp/capacity_result.json)
if [ "$response" = "200" ]; then
echo -e " ${GREEN}${NC} Capacity check"
else
echo -e " ${RED}${NC} Capacity check ($response)"
fi
# EXIF read
response=$(curl_post "/api/tools/exif" \
-F "image=@$TEST_DATA/carrier.jpg" \
-w "%{http_code}" -o /tmp/exif_result.json)
if [ "$response" = "200" ]; then
echo -e " ${GREEN}${NC} EXIF read"
log_pass "Tools API works"
else
echo -e " ${RED}${NC} EXIF read ($response)"
log_fail "Tools API failed"
fi
}
# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------
echo ""
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Stegasoo Pi Smoke Test ║${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "Target: ${YELLOW}$BASE_URL${NC}"
echo -e "User: ${YELLOW}$USER${NC}"
echo ""
# Clean up
rm -f "$COOKIE_JAR" /tmp/stego_*_test.* /tmp/exif_stripped.jpg
# Run tests
test_connectivity
test_setup_or_login
test_pages
test_encode_decode_lsb
test_encode_decode_dct
test_tools
# Summary
echo ""
echo -e "${CYAN}════════════════════════════════════════════════════════════════${NC}"
echo -e "Results: ${GREEN}$PASSED passed${NC}, ${RED}$FAILED failed${NC}"
echo -e "${CYAN}════════════════════════════════════════════════════════════════${NC}"
# Clean up
rm -f "$COOKIE_JAR"
if [ $FAILED -gt 0 ]; then
exit 1
fi