Add integration testing infrastructure with Podman Compose
- Add docker/podman-compose.yml for Immich server (no ML) - Add test-data/sample-photos/ with 3 public domain images - Add scripts/start-immich.sh for container startup + admin/API key creation - Add scripts/seed-data.sh for uploading test photos and creating albums - Add scripts/stop-immich.sh for cleanup with volume destruction - Add scripts/run-example.sh wrapper (fixed env var export) - Update examples to use IMMICH_URL and IMMICH_API_KEY env vars - Add .github/workflows/integration-test.yml for CI - Update assets.list() to use /search/metadata endpoint - Update AGENTS.md with example running instructions - Add 5 new examples: search_metadata, album_management, timeline_browsing, delete_assets, server_info
This commit is contained in:
42
scripts/run-example.sh
Executable file
42
scripts/run-example.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
EXAMPLE=$1
|
||||
|
||||
if [ -z "$EXAMPLE" ]; then
|
||||
echo "Usage: $0 <example_name>"
|
||||
echo "Available examples:"
|
||||
ls examples/*.rs | sed 's/examples\///' | sed 's/\.rs$//' | sed 's/^/ - /'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if example exists
|
||||
if [ ! -f "examples/${EXAMPLE}.rs" ]; then
|
||||
echo "Error: Example 'examples/${EXAMPLE}.rs' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Start immich if not running
|
||||
if ! curl -s http://localhost:2283/api/server/ping > /dev/null 2>&1; then
|
||||
echo "Immich is not running. Starting..."
|
||||
./scripts/start-immich.sh
|
||||
fi
|
||||
|
||||
# Seed data if not already done
|
||||
if [ ! -f .seeded ]; then
|
||||
echo "Seeding test data..."
|
||||
./scripts/seed-data.sh
|
||||
touch .seeded
|
||||
fi
|
||||
|
||||
# Load environment variables
|
||||
# set -a exports all variables defined from here on
|
||||
set -a
|
||||
source .env.test
|
||||
set +a
|
||||
|
||||
# Run the example
|
||||
echo "Running example: $EXAMPLE"
|
||||
cargo run --example "$EXAMPLE"
|
||||
175
scripts/seed-data.sh
Executable file
175
scripts/seed-data.sh
Executable file
@@ -0,0 +1,175 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Seed data script for Immich SDK testing
|
||||
# Uploads sample photos to an Immich test instance
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Change to script directory
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Load environment variables from .env.test if it exists
|
||||
if [ -f ".env.test" ]; then
|
||||
echo "Loading environment from .env.test"
|
||||
source .env.test
|
||||
fi
|
||||
|
||||
# Check required environment variables
|
||||
if [ -z "$IMMICH_URL" ]; then
|
||||
echo "Error: IMMICH_URL environment variable is not set"
|
||||
echo "Please set it or create a .env.test file with:"
|
||||
echo " IMMICH_URL=http://localhost:2283"
|
||||
echo " IMMICH_API_KEY=your-api-key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$IMMICH_API_KEY" ]; then
|
||||
echo "Error: IMMICH_API_KEY environment variable is not set"
|
||||
echo "Please set it or create a .env.test file with:"
|
||||
echo " IMMICH_URL=http://localhost:2283"
|
||||
echo " IMMICH_API_KEY=your-api-key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PHOTO_DIR="test-data/sample-photos"
|
||||
|
||||
# Check if photo directory exists
|
||||
if [ ! -d "$PHOTO_DIR" ]; then
|
||||
echo "Warning: Photo directory $PHOTO_DIR does not exist"
|
||||
echo "Creating directory..."
|
||||
mkdir -p "$PHOTO_DIR"
|
||||
echo "Please add sample .jpg files to $PHOTO_DIR and run again"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Count jpg files
|
||||
jpg_count=$(find "$PHOTO_DIR" -name "*.jpg" -type f 2>/dev/null | wc -l)
|
||||
|
||||
if [ "$jpg_count" -eq 0 ]; then
|
||||
echo "Warning: No .jpg files found in $PHOTO_DIR"
|
||||
echo "Please add sample .jpg files and run again"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "======================================"
|
||||
echo "Immich Seed Data Script"
|
||||
echo "======================================"
|
||||
echo "Target: $IMMICH_URL"
|
||||
echo "Photos to upload: $jpg_count"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
# Array to store uploaded asset IDs
|
||||
declare -a asset_ids
|
||||
|
||||
# Upload photos
|
||||
for photo in "$PHOTO_DIR"/*.jpg; do
|
||||
[ -f "$photo" ] || continue
|
||||
|
||||
filename=$(basename "$photo")
|
||||
device_asset_id=$(basename "$photo" .jpg)
|
||||
|
||||
echo -n "Uploading $filename... "
|
||||
|
||||
# Upload with asset data and capture response
|
||||
response=$(curl -s -X POST "$IMMICH_URL/api/assets" \
|
||||
-H "x-api-key: $IMMICH_API_KEY" \
|
||||
-F "assetData=@$photo" \
|
||||
-F "deviceAssetId=$device_asset_id" \
|
||||
-F "deviceId=test-device" \
|
||||
-F "fileCreatedAt=2024-01-15T10:00:00.000Z" \
|
||||
-F "fileModifiedAt=2024-01-15T10:00:00.000Z" \
|
||||
-H "Accept: application/json" 2>/dev/null || true)
|
||||
|
||||
# Extract asset ID from response if possible
|
||||
asset_id=$(echo "$response" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4 || true)
|
||||
|
||||
if [ -n "$asset_id" ]; then
|
||||
asset_ids+=("$asset_id")
|
||||
echo "OK (ID: ${asset_id:0:8}...)"
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "======================================"
|
||||
echo "Upload Summary"
|
||||
echo "======================================"
|
||||
echo "Photos uploaded: $jpg_count"
|
||||
|
||||
# Create album and add assets if we have asset IDs
|
||||
if [ ${#asset_ids[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Creating album..."
|
||||
|
||||
# Create album
|
||||
album_response=$(curl -s -X POST "$IMMICH_URL/api/albums" \
|
||||
-H "x-api-key: $IMMICH_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"albumName":"SDK Test Album"}' 2>/dev/null || true)
|
||||
|
||||
album_id=$(echo "$album_response" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4 || true)
|
||||
|
||||
if [ -n "$album_id" ]; then
|
||||
echo "Album created: SDK Test Album (ID: ${album_id:0:8}...)"
|
||||
|
||||
# Add assets to album
|
||||
echo "Adding photos to album..."
|
||||
|
||||
# Build JSON array of asset IDs
|
||||
asset_json="["
|
||||
first=true
|
||||
for id in "${asset_ids[@]}"; do
|
||||
if [ "$first" = true ]; then
|
||||
first=false
|
||||
else
|
||||
asset_json+=","
|
||||
fi
|
||||
asset_json+="\"$id\""
|
||||
done
|
||||
asset_json+="]"
|
||||
|
||||
add_response=$(curl -s -X PUT "$IMMICH_URL/api/albums/$album_id/assets" \
|
||||
-H "x-api-key: $IMMICH_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"ids\":$asset_json}" 2>/dev/null || true)
|
||||
|
||||
echo "Added ${#asset_ids[@]} photos to album"
|
||||
|
||||
# Mark first photo as favorite
|
||||
if [ ${#asset_ids[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Marking first photo as favorite..."
|
||||
|
||||
curl -s -X PUT "$IMMICH_URL/api/assets" \
|
||||
-H "x-api-key: $IMMICH_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"ids\":[\"${asset_ids[0]}\"],\"isFavorite\":true}" \
|
||||
2>/dev/null > /dev/null || true
|
||||
|
||||
echo "Marked as favorite"
|
||||
fi
|
||||
else
|
||||
echo "Warning: Could not create album (album ID not found in response)"
|
||||
fi
|
||||
else
|
||||
echo "Warning: No asset IDs captured - skipping album creation"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "======================================"
|
||||
echo "Seed complete!"
|
||||
echo "======================================"
|
||||
echo "Server: $IMMICH_URL"
|
||||
echo "Photos uploaded: $jpg_count"
|
||||
if [ ${#asset_ids[@]} -gt 0 ]; then
|
||||
echo "Album: SDK Test Album"
|
||||
echo "Favorites: 1"
|
||||
fi
|
||||
echo ""
|
||||
echo "You can now run examples against this server:"
|
||||
echo " cargo run --example list_assets"
|
||||
echo " cargo run --example list_albums"
|
||||
echo "======================================"
|
||||
121
scripts/start-immich.sh
Executable file
121
scripts/start-immich.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Script to start Immich containers, create admin user, and generate API key
|
||||
# This script is used for integration testing
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check dependencies
|
||||
check_dependency() {
|
||||
if ! command -v "$1" &> /dev/null; then
|
||||
echo -e "${RED}Error: $1 is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking dependencies..."
|
||||
check_dependency "podman"
|
||||
check_dependency "curl"
|
||||
check_dependency "jq"
|
||||
|
||||
# Check if podman-compose is available
|
||||
if ! podman compose version &> /dev/null && ! command -v podman-compose &> /dev/null; then
|
||||
echo -e "${RED}Error: podman-compose is not available${NC}"
|
||||
echo "Please install podman-compose or ensure 'podman compose' is available"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start containers
|
||||
echo "Starting Immich containers..."
|
||||
podman compose -f docker/podman-compose.yml up -d
|
||||
|
||||
# Wait for health check (max 120s)
|
||||
echo "Waiting for Immich to be ready..."
|
||||
READY=false
|
||||
for i in {1..60}; do
|
||||
if curl -s http://localhost:2283/api/server/ping > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}Immich is ready!${NC}"
|
||||
READY=true
|
||||
break
|
||||
fi
|
||||
echo "Attempt $i/60 - waiting for Immich..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$READY" = false ]; then
|
||||
echo -e "${RED}Error: Immich failed to become ready within 120 seconds${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Admin credentials
|
||||
ADMIN_EMAIL="admin@example.com"
|
||||
ADMIN_PASSWORD="admin123"
|
||||
ADMIN_NAME="Admin User"
|
||||
|
||||
# Create admin user
|
||||
echo "Creating admin user..."
|
||||
curl -s -X POST http://localhost:2283/api/auth/admin-sign-up \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\",\"name\":\"$ADMIN_NAME\"}" \
|
||||
|| echo -e "${YELLOW}Admin may already exist, continuing...${NC}"
|
||||
|
||||
# Login to get access token
|
||||
echo "Logging in to get access token..."
|
||||
LOGIN_RESPONSE=$(curl -s -X POST http://localhost:2283/api/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}")
|
||||
|
||||
ACCESS_TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.accessToken')
|
||||
|
||||
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
|
||||
echo -e "${RED}Error: Failed to get access token${NC}"
|
||||
echo "Response: $LOGIN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create API key
|
||||
echo "Creating API key..."
|
||||
API_KEY_RESPONSE=$(curl -s -X POST http://localhost:2283/api/api-keys \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-d '{"name":"sdk-test-key","permissions":["all"]}')
|
||||
|
||||
API_KEY=$(echo "$API_KEY_RESPONSE" | jq -r '.secret')
|
||||
|
||||
if [ -z "$API_KEY" ] || [ "$API_KEY" = "null" ]; then
|
||||
echo -e "${RED}Error: Failed to create API key${NC}"
|
||||
echo "Response: $API_KEY_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save to .env.test
|
||||
echo "Saving credentials to .env.test..."
|
||||
cat > .env.test << EOF
|
||||
IMMICH_URL=http://localhost:2283
|
||||
IMMICH_API_KEY=$API_KEY
|
||||
EOF
|
||||
|
||||
# Success message
|
||||
echo -e "${GREEN}=======================================${NC}"
|
||||
echo -e "${GREEN}Immich setup complete!${NC}"
|
||||
echo -e "${GREEN}=======================================${NC}"
|
||||
echo ""
|
||||
echo "Credentials saved to .env.test:"
|
||||
echo " IMMICH_URL: http://localhost:2283"
|
||||
echo " IMMICH_API_KEY: ${API_KEY:0:10}... (truncated)"
|
||||
echo ""
|
||||
echo "Admin user:"
|
||||
echo " Email: $ADMIN_EMAIL"
|
||||
echo " Password: $ADMIN_PASSWORD"
|
||||
echo ""
|
||||
echo "You can now access Immich at: http://localhost:2283"
|
||||
echo ""
|
||||
echo "To stop the containers, run:"
|
||||
echo " podman compose -f docker/podman-compose.yml down"
|
||||
12
scripts/stop-immich.sh
Executable file
12
scripts/stop-immich.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "Stopping Immich containers and destroying volumes..."
|
||||
podman compose -f docker/podman-compose.yml down -v
|
||||
|
||||
# Clean up state files
|
||||
rm -f .env.test .seeded
|
||||
|
||||
echo "Immich stopped and cleaned up."
|
||||
Reference in New Issue
Block a user