From fd2aa1a5f0fd3eb1f8102cfaa043147f04e1f99c Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 2 Sep 2025 13:49:39 +1200 Subject: [PATCH] test: Update 2 files --- sos | 53 +++++++++++++++-- test.sh | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+), 6 deletions(-) diff --git a/sos b/sos index affad82..fb4d461 100755 --- a/sos +++ b/sos @@ -51,13 +51,18 @@ function show_help() { sos is a script to upload files to a simple object storage server. Usage: - sos upload [label:tag ...] + sos upload [label:tag ...] [--metadata "key=value"] ... Example: sos upload getbin.xyz ./file.txt file:latest + sos upload getbin.xyz ./file.txt file:latest --metadata "templateXXHash64=abc123" --metadata "author=john" This will upload the file to the server, and return the download URL. +Options: + --metadata "key=value" Add custom metadata to the upload. Can be used multiple times. + Example: --metadata "templateXXHash64=\$XXHASH" + Environment variables: SOS_WRITE_TOKEN: The write token to use for the upload. If not set, the script will look in $HOME/.config/sos/write_token.txt. @@ -73,7 +78,7 @@ function datetime() { function upload() { if [ "$#" -lt 3 ]; then - echo "Usage: sos upload [label:tag ...]" + echo "Usage: sos upload [label:tag ...] [--metadata \"key=value\"] ..." exit 1 fi @@ -84,9 +89,33 @@ function upload() { [[ "$first_label" =~ : ]] || die "Label $first_label does not contain a tag!" shift 3 - for label in "$@"; do - [[ "$label" =~ : ]] || die "Label $label does not contain a tag!" - LABELTAGS+=("$label") + + # Arrays to store custom metadata + declare -A CUSTOM_METADATA + + # Parse remaining arguments for labels and metadata + while [ "$#" -gt 0 ]; do + if [ "$1" == "--metadata" ]; then + shift + if [ "$#" -eq 0 ]; then + die "--metadata flag requires a \"key=value\" argument" + fi + # Parse key=value + if [[ "$1" =~ ^([^=]+)=(.*)$ ]]; then + KEY="${BASH_REMATCH[1]}" + VALUE="${BASH_REMATCH[2]}" + CUSTOM_METADATA["$KEY"]="$VALUE" + else + die "Metadata must be in \"key=value\" format, got: $1" + fi + shift + else + # It's a label:tag + label="$1" + [[ "$label" =~ : ]] || die "Label $label does not contain a tag!" + LABELTAGS+=("$label") + shift + fi done # check if file contains : @@ -138,11 +167,23 @@ function upload() { echo "Local hash: $LOCALHASH" + # Build custom metadata JSON entries + CUSTOM_METADATA_JSON="" + for KEY in "${!CUSTOM_METADATA[@]}"; do + # Escape the value for JSON + VALUE="${CUSTOM_METADATA[$KEY]}" + # Basic JSON escaping - escape quotes and backslashes + VALUE="${VALUE//\\/\\\\}" + VALUE="${VALUE//\"/\\\"}" + CUSTOM_METADATA_JSON+=", + \"$KEY\": \"$VALUE\"" + done + METADATA_JSON=$(cat < "${TEST_DIR}/test_files/meta_single.txt" + local output=$(run_sos_upload "${TEST_DIR}/test_files/meta_single.txt" "meta:single" --metadata "customField=testValue" 2>&1) + + # Check if upload succeeded + if ! echo "$output" | grep -q "Download URL:"; then + log_error "Upload with metadata failed" + echo "$output" | head -5 + return 1 + fi + + # Verify metadata was included + local host="${SOS_TEST_HOST:-localhost:${TEST_PORT}}" + local hash=$(curl -s "http://${host}/hash/meta:single" | jq -r '.hash') + local meta=$(curl -s "http://${host}/meta/${hash}" | jq -r '.metadata.customField') + + if [[ "$meta" == "testValue" ]]; then + log_info "Single metadata field working" + return 0 + else + log_error "Metadata not found or incorrect (got: $meta)" + return 1 + fi +} + +test_metadata_multiple() { + log_info "Testing multiple metadata fields..." + + echo "metadata test multiple" > "${TEST_DIR}/test_files/meta_multiple.txt" + local output=$(run_sos_upload "${TEST_DIR}/test_files/meta_multiple.txt" "meta:multiple" \ + --metadata "field1=value1" \ + --metadata "field2=value2" \ + --metadata "templateXXHash64=abc123def456" 2>&1) + + # Check if upload succeeded + if ! echo "$output" | grep -q "Download URL:"; then + log_error "Upload with multiple metadata failed" + echo "$output" | head -5 + return 1 + fi + + # Verify all metadata fields were included + local host="${SOS_TEST_HOST:-localhost:${TEST_PORT}}" + local hash=$(curl -s "http://${host}/hash/meta:multiple" | jq -r '.hash') + local metadata=$(curl -s "http://${host}/meta/${hash}") + + local field1=$(echo "$metadata" | jq -r '.metadata.field1') + local field2=$(echo "$metadata" | jq -r '.metadata.field2') + local xxhash=$(echo "$metadata" | jq -r '.metadata.templateXXHash64') + + if [[ "$field1" == "value1" && "$field2" == "value2" && "$xxhash" == "abc123def456" ]]; then + log_info "Multiple metadata fields working" + return 0 + else + log_error "Metadata fields incorrect" + echo "field1=$field1, field2=$field2, templateXXHash64=$xxhash" + return 1 + fi +} + +test_metadata_special_chars() { + log_info "Testing metadata with special characters..." + + echo "metadata test special" > "${TEST_DIR}/test_files/meta_special.txt" + local output=$(run_sos_upload "${TEST_DIR}/test_files/meta_special.txt" "meta:special" \ + --metadata "description=This is a test with spaces" \ + --metadata "formula=a=b+c" \ + --metadata "path=/usr/local/bin" \ + --metadata "quote=He said \"hello\"" 2>&1) + + # Check if upload succeeded + if ! echo "$output" | grep -q "Download URL:"; then + log_error "Upload with special chars metadata failed" + echo "$output" | head -5 + return 1 + fi + + # Verify metadata with special characters + local host="${SOS_TEST_HOST:-localhost:${TEST_PORT}}" + local hash=$(curl -s "http://${host}/hash/meta:special" | jq -r '.hash') + local metadata=$(curl -s "http://${host}/meta/${hash}") + + local desc=$(echo "$metadata" | jq -r '.metadata.description') + local formula=$(echo "$metadata" | jq -r '.metadata.formula') + local path=$(echo "$metadata" | jq -r '.metadata.path') + local quote=$(echo "$metadata" | jq -r '.metadata.quote') + + if [[ "$desc" == "This is a test with spaces" && \ + "$formula" == "a=b+c" && \ + "$path" == "/usr/local/bin" && \ + "$quote" == 'He said "hello"' ]]; then + log_info "Metadata with special characters working" + return 0 + else + log_error "Special character metadata incorrect" + echo "description='$desc'" + echo "formula='$formula'" + echo "path='$path'" + echo "quote='$quote'" + return 1 + fi +} + +test_metadata_mixed_labels() { + log_info "Testing metadata mixed with multiple labels..." + + echo "metadata test mixed" > "${TEST_DIR}/test_files/meta_mixed.txt" + local output=$(run_sos_upload "${TEST_DIR}/test_files/meta_mixed.txt" \ + "meta:mixed1" \ + --metadata "author=test-user" \ + "meta:mixed2" \ + --metadata "version=1.2.3" \ + "meta:mixed3" 2>&1) + + # Check if upload succeeded + if ! echo "$output" | grep -q "Download URL:"; then + log_error "Upload with mixed labels and metadata failed" + echo "$output" | head -5 + return 1 + fi + + # Verify metadata and labels + local host="${SOS_TEST_HOST:-localhost:${TEST_PORT}}" + local hash=$(curl -s "http://${host}/hash/meta:mixed1" | jq -r '.hash') + local metadata=$(curl -s "http://${host}/meta/${hash}") + + local author=$(echo "$metadata" | jq -r '.metadata.author') + local version=$(echo "$metadata" | jq -r '.metadata.version') + local labels=$(echo "$metadata" | jq -r '.metadata.labeltags | length') + + # Check all three labels exist + local has_mixed1=$(echo "$metadata" | jq -r '.metadata.labeltags | map(select(. == "meta:mixed1")) | length') + local has_mixed2=$(echo "$metadata" | jq -r '.metadata.labeltags | map(select(. == "meta:mixed2")) | length') + local has_mixed3=$(echo "$metadata" | jq -r '.metadata.labeltags | map(select(. == "meta:mixed3")) | length') + + if [[ "$author" == "test-user" && "$version" == "1.2.3" && \ + "$has_mixed1" == "1" && "$has_mixed2" == "1" && "$has_mixed3" == "1" ]]; then + log_info "Mixed labels and metadata working" + return 0 + else + log_error "Mixed metadata/labels incorrect" + echo "author=$author, version=$version" + echo "Labels: mixed1=$has_mixed1, mixed2=$has_mixed2, mixed3=$has_mixed3" + return 1 + fi +} + +test_metadata_empty_value() { + log_info "Testing metadata with empty value..." + + echo "metadata test empty" > "${TEST_DIR}/test_files/meta_empty.txt" + local output=$(run_sos_upload "${TEST_DIR}/test_files/meta_empty.txt" "meta:empty" \ + --metadata "emptyField=" \ + --metadata "normalField=hasValue" 2>&1) + + # Check if upload succeeded + if ! echo "$output" | grep -q "Download URL:"; then + log_error "Upload with empty metadata value failed" + echo "$output" | head -5 + return 1 + fi + + # Verify metadata + local host="${SOS_TEST_HOST:-localhost:${TEST_PORT}}" + local hash=$(curl -s "http://${host}/hash/meta:empty" | jq -r '.hash') + local metadata=$(curl -s "http://${host}/meta/${hash}") + + local empty=$(echo "$metadata" | jq -r '.metadata.emptyField') + local normal=$(echo "$metadata" | jq -r '.metadata.normalField') + + if [[ "$empty" == "" && "$normal" == "hasValue" ]]; then + log_info "Empty metadata value handled correctly" + return 0 + else + log_error "Empty metadata value not handled correctly" + echo "emptyField='$empty', normalField='$normal'" + return 1 + fi +} + # Run all tests run_tests() { local tests=(