#!/bin/bash # Don't use set -e because we want to continue even if tests fail set -uo pipefail PROJECT="getpkg" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" GETPKG="${SCRIPT_DIR}/output/${PROJECT}" TEST_DIR="${SCRIPT_DIR}/test_temp" TEST_TOOL_NAME="test-tool-$RANDOM" TEST_ARCH=$(uname -m | sed 's/x86_64/x86_64/;s/arm64/aarch64/;s/aarch64/aarch64/') # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Test counters TESTS_PASSED=0 TESTS_FAILED=0 # Function to print test results print_test_result() { local test_name="$1" local result="$2" if [ "$result" -eq 0 ]; then echo -e "${GREEN}✓${NC} $test_name" ((TESTS_PASSED++)) else echo -e "${RED}✗${NC} $test_name" ((TESTS_FAILED++)) fi } # Function to cleanup test artifacts CLEANED=0 cleanup() { if [ "$CLEANED" -eq 1 ]; then return fi CLEANED=1 echo -e "\n${YELLOW}Cleaning up test artifacts...${NC}" # Remove local test directories rm -rf "$TEST_DIR" rm -rf ~/.config/getpkg/"${TEST_TOOL_NAME}.json" 2>/dev/null || true rm -rf ~/.config/getpkg/"${TEST_TOOL_NAME}-noarch.json" 2>/dev/null || true rm -rf ~/.getpkg/"${TEST_TOOL_NAME}" 2>/dev/null || true rm -rf ~/.getpkg/"${TEST_TOOL_NAME}-noarch" 2>/dev/null || true rm -rf ~/.local/bin/getpkg/"${TEST_TOOL_NAME}" 2>/dev/null || true rm -rf ~/.local/bin/getpkg/"${TEST_TOOL_NAME}-noarch" 2>/dev/null || true # Remove test tool from bashrc_getpkg if it exists # if [ -f ~/.bashrc_getpkg ]; then # sed -i "/${TEST_TOOL_NAME}/d" ~/.bashrc_getpkg 2>/dev/null || true # fi $GETPKG uninstall "$TEST_TOOL_NAME" 2>/dev/null || true $GETPKG uninstall "${TEST_TOOL_NAME}-noarch" 2>/dev/null || true # Clean up from getpkg.xyz if we have write access if [ -n "${SOS_WRITE_TOKEN:-}" ]; then echo "Attempting to clean up test objects from getpkg.xyz..." # Clean up main architecture variant $GETPKG unpublish "${TEST_TOOL_NAME}:${TEST_ARCH}" 2>/dev/null || true # Clean up noarch variant $GETPKG unpublish "${TEST_TOOL_NAME}-noarch:universal" 2>/dev/null || true # Clean up any remaining test packages that start with "test-" echo "Cleaning up any remaining test packages..." DIR_RESPONSE=$(curl -s "https://getpkg.xyz/dir" 2>/dev/null || echo "") if [ -n "$DIR_RESPONSE" ]; then # Extract test package labeltags from JSON response if command -v jq >/dev/null 2>&1; then TEST_PACKAGES=$(echo "$DIR_RESPONSE" | jq -r '.entries[]?.labeltags[]? // empty' 2>/dev/null | grep "^test-" | sort -u || echo "") else # Fallback: extract labeltags using grep and sed TEST_PACKAGES=$(echo "$DIR_RESPONSE" | grep -o '"test-[^"]*"' | sed 's/"//g' | sort -u || echo "") fi if [ -n "$TEST_PACKAGES" ]; then echo "$TEST_PACKAGES" | while read -r package; do if [ -n "$package" ]; then echo " Cleaning up orphaned test package: $package" $GETPKG unpublish "$package" 2>/dev/null || true fi done fi fi echo "Cleaned up test tools from getpkg.xyz" else echo "Note: SOS_WRITE_TOKEN not set, cannot clean up remote test objects" fi } # Set up trap to ensure cleanup runs trap cleanup EXIT # Create test directory mkdir -p "$TEST_DIR" echo -e "${YELLOW}Running getpkg tests...${NC}\n" # Check if getpkg binary exists if [ ! -f "$GETPKG" ]; then echo -e "${RED}Error: getpkg binary not found at $GETPKG${NC}" echo "Please run ./build.sh first to build getpkg" exit 1 fi if [ ! -x "$GETPKG" ]; then echo -e "${RED}Error: getpkg binary is not executable${NC}" exit 1 fi echo "Using getpkg binary: $GETPKG" # Test 1: Version command echo "Test 1: Version command" VERSION=$(timeout 3 "$GETPKG" version 2>&1) || VERSION="" if [[ "$VERSION" =~ ^[0-9]{4}\.[0-9]{4}\.[0-9]{4}$ ]]; then print_test_result "Version format (YYYY.MMDD.HHMM)" 0 else print_test_result "Version format (YYYY.MMDD.HHMM)" 1 fi # Test 2: Help command echo -e "\nTest 2: Help command" HELP_OUTPUT=$(timeout 3 "$GETPKG" help 2>&1) || HELP_OUTPUT="" if [[ "$HELP_OUTPUT" =~ getpkg\ -\ Package\ manager\ for\ dropshell\ tools ]] || [[ "$HELP_OUTPUT" =~ USAGE: ]]; then print_test_result "Help command output" 0 else print_test_result "Help command output" 1 fi # Test 3: Autocomplete command echo -e "\nTest 3: Autocomplete command" AUTOCOMPLETE_OUTPUT=$(timeout 3 "$GETPKG" autocomplete 2>&1) || AUTOCOMPLETE_OUTPUT="" if [[ "$AUTOCOMPLETE_OUTPUT" =~ install ]] && [[ "$AUTOCOMPLETE_OUTPUT" =~ publish ]]; then print_test_result "Autocomplete command output" 0 else print_test_result "Autocomplete command output" 1 fi # Test 4: Hash command echo -e "\nTest 4: Hash command" # Test 4a: Hash command with missing argument echo "Test 4a: Hash command error handling" HASH_ERROR_OUTPUT=$("$GETPKG" hash 2>&1) || true if [[ "$HASH_ERROR_OUTPUT" =~ "Usage: getpkg hash" ]]; then print_test_result "Hash command error handling (missing argument)" 0 else print_test_result "Hash command error handling (missing argument)" 1 fi # Test 4b: Hash command with nonexistent file echo "Test 4b: Hash command with nonexistent file" HASH_NONEXISTENT_OUTPUT=$("$GETPKG" hash nonexistent_file.txt 2>&1) || true if [[ "$HASH_NONEXISTENT_OUTPUT" =~ "Error: Path does not exist" ]]; then print_test_result "Hash command error handling (nonexistent file)" 0 else print_test_result "Hash command error handling (nonexistent file)" 1 fi # Test 4c: Hash command with test file echo "Test 4c: Hash command with test file" TEST_FILE="${TEST_DIR}/test_hash_file.txt" echo "test content for hashing" > "$TEST_FILE" HASH_FILE_OUTPUT=$("$GETPKG" hash "$TEST_FILE" 2>&1) || HASH_FILE_OUTPUT="" if [[ "$HASH_FILE_OUTPUT" =~ ^[0-9]+$ ]]; then print_test_result "Hash command with file (numeric output)" 0 # Test that the hash is consistent HASH_FILE_OUTPUT2=$("$GETPKG" hash "$TEST_FILE" 2>&1) || HASH_FILE_OUTPUT2="" if [ "$HASH_FILE_OUTPUT" = "$HASH_FILE_OUTPUT2" ]; then print_test_result "Hash command consistency (same file, same hash)" 0 else print_test_result "Hash command consistency (same file, same hash)" 1 fi else print_test_result "Hash command with file (numeric output)" 1 print_test_result "Hash command consistency (same file, same hash)" 1 fi # Test 4d: Hash command with directory echo "Test 4d: Hash command with directory" TEST_HASH_DIR="${TEST_DIR}/test_hash_dir" mkdir -p "$TEST_HASH_DIR" echo "dir content 1" > "$TEST_HASH_DIR/file1.txt" echo "dir content 2" > "$TEST_HASH_DIR/file2.txt" HASH_DIR_OUTPUT=$("$GETPKG" hash "$TEST_HASH_DIR" 2>&1) || HASH_DIR_OUTPUT="" if [[ "$HASH_DIR_OUTPUT" =~ ^[0-9]+$ ]]; then print_test_result "Hash command with directory (numeric output)" 0 # Test that directory hash is different from file hash if [ "$HASH_DIR_OUTPUT" != "$HASH_FILE_OUTPUT" ]; then print_test_result "Hash command different for file vs directory" 0 else print_test_result "Hash command different for file vs directory" 1 fi else print_test_result "Hash command with directory (numeric output)" 1 print_test_result "Hash command different for file vs directory" 1 fi # Test 4e: Hash command compatibility with tr (sos script format) echo "Test 4e: Hash command compatibility with tr command" LOCALHASH=$("$GETPKG" hash "$TEST_FILE" | tr -d '[:space:]') || LOCALHASH="" if [[ "$LOCALHASH" =~ ^[0-9]+$ ]] && [ ${#LOCALHASH} -gt 0 ]; then print_test_result "Hash command compatible with tr -d '[:space:]'" 0 else print_test_result "Hash command compatible with tr -d '[:space:]'" 1 fi # Test 4f: Hash command appears in autocomplete echo "Test 4f: Hash command in autocomplete" if [[ "$AUTOCOMPLETE_OUTPUT" =~ hash ]]; then print_test_result "Hash command appears in autocomplete" 0 else print_test_result "Hash command appears in autocomplete" 1 fi # Test 4g: Hash command appears in help echo "Test 4g: Hash command in help" if [[ "$HELP_OUTPUT" =~ hash.*file_or_directory ]] && [[ "$HELP_OUTPUT" =~ "Outputs raw hash value to stdout" ]]; then print_test_result "Hash command appears in help" 0 else print_test_result "Hash command appears in help" 1 fi # Test 5: Create command echo -e "\nTest 5: Create command" CREATE_DIR="${TEST_DIR}/${TEST_TOOL_NAME}" timeout 3 "$GETPKG" create "$TEST_TOOL_NAME" "$CREATE_DIR" >/dev/null 2>&1 || true if [ -d "$CREATE_DIR" ] && [ -f "$CREATE_DIR/setup_script.sh" ]; then print_test_result "Create tool directory" 0 else print_test_result "Create tool directory" 1 fi # Test 6: Create test tool binary echo -e "\nTest 6: Create test tool" cat > "$CREATE_DIR/${TEST_TOOL_NAME}" << 'EOF' #!/bin/bash case "$1" in version) echo "1.0.0" ;; autocomplete) echo "subcommand1" echo "subcommand2" ;; *) echo "Test tool - $1" ;; esac EOF chmod +x "$CREATE_DIR/${TEST_TOOL_NAME}" if [ -x "$CREATE_DIR/${TEST_TOOL_NAME}" ]; then print_test_result "Create test tool binary" 0 else print_test_result "Create test tool binary" 1 fi # Test 6b: Test basic publish functionality echo -e "\nTest 6b: Testing basic publish command" # Test with a dummy token to see error message DUMMY_OUTPUT=$(timeout 3 "$GETPKG" publish "dummy:x86_64" "$CREATE_DIR" 2>&1 <<< "") || true echo "Dummy publish output: $DUMMY_OUTPUT" # Test 7: Publish command (requires SOS_WRITE_TOKEN) if [ -n "${SOS_WRITE_TOKEN:-}" ]; then echo -e "\nTest 7: Publish command with ARCH" echo "SOS_WRITE_TOKEN is set: ${#SOS_WRITE_TOKEN} characters" echo "Publishing ${TEST_TOOL_NAME}:${TEST_ARCH} from $CREATE_DIR" echo "Directory contents:" ls -la "$CREATE_DIR" echo "Running: $GETPKG publish ${TEST_TOOL_NAME}:${TEST_ARCH} $CREATE_DIR" # Make sure the token is exported for the subprocess export SOS_WRITE_TOKEN # Run publish command and capture both stdout and stderr PUBLISH_OUTPUT=$(timeout 3 "$GETPKG" publish "${TEST_TOOL_NAME}:${TEST_ARCH}" "$CREATE_DIR" 2>&1) PUBLISH_EXIT_CODE=$? echo "Publish exit code: $PUBLISH_EXIT_CODE" echo "Publish output: $PUBLISH_OUTPUT" # Check if the output indicates a crash or missing dependencies if [ -z "$PUBLISH_OUTPUT" ] && [ $PUBLISH_EXIT_CODE -ne 0 ]; then echo "Publish command failed with no output. Checking for missing dependencies..." ldd "$GETPKG" 2>&1 | grep "not found" || echo "All dependencies found" fi if [[ "$PUBLISH_OUTPUT" =~ Published! ]] && [[ "$PUBLISH_OUTPUT" =~ URL: ]] && [[ "$PUBLISH_OUTPUT" =~ Hash: ]]; then print_test_result "Publish tool with ARCH to getpkg.xyz" 0 # Extract hash for later cleanup PUBLISHED_HASH=$(echo "$PUBLISH_OUTPUT" | grep "Hash:" | cut -d' ' -f2) echo "Published hash: $PUBLISHED_HASH" # Test 8: Check if published tool exists echo -e "\nTest 8: Check published tool exists" EXISTS_CHECK=$(curl -s "https://getpkg.xyz/exists/${TEST_TOOL_NAME}:${TEST_ARCH}" 2>/dev/null || echo "error") if [[ "$EXISTS_CHECK" != "error" ]] && [[ "$EXISTS_CHECK" != "false" ]]; then print_test_result "Published tool exists on server" 0 else print_test_result "Published tool exists on server" 1 fi # Test 9: Install command echo -e "\nTest 9: Install command" INSTALL_OUTPUT=$(timeout 3 "$GETPKG" install "$TEST_TOOL_NAME" 2>&1) || INSTALL_OUTPUT="" if [[ "$INSTALL_OUTPUT" =~ Installed\ ${TEST_TOOL_NAME}\ successfully ]] || [[ "$INSTALL_OUTPUT" =~ ${TEST_TOOL_NAME}\ is\ already\ up\ to\ date ]]; then print_test_result "Install tool from getpkg.xyz" 0 # Test 10: Check installed files echo -e "\nTest 10: Check installed files" if [ -f ~/.config/getpkg/"${TEST_TOOL_NAME}.json" ] && [ -d ~/.getpkg/"${TEST_TOOL_NAME}" ] && [ -L ~/.local/bin/getpkg/"${TEST_TOOL_NAME}" ]; then print_test_result "Tool files installed correctly" 0 else print_test_result "Tool files installed correctly" 1 fi # Test 11: Check bashrc_getpkg modifications echo -e "\nTest 11: Check bashrc modifications" if [ -f ~/.bashrc_getpkg ] && grep -q "${TEST_TOOL_NAME}" ~/.bashrc_getpkg; then print_test_result "Bashrc modifications for PATH and autocomplete" 0 else print_test_result "Bashrc modifications for PATH and autocomplete" 1 fi # Test 12: Reinstall after manual removal echo -e "\nTest 12: Reinstall after manual removal" # First remove the tool rm -rf ~/.getpkg/"${TEST_TOOL_NAME}" rm -rf ~/.local/bin/getpkg/"${TEST_TOOL_NAME}" rm -f ~/.config/getpkg/"${TEST_TOOL_NAME}.json" REINSTALL_OUTPUT=$(timeout 3 "$GETPKG" install "$TEST_TOOL_NAME" 2>&1) || REINSTALL_OUTPUT="" if [[ "$REINSTALL_OUTPUT" =~ Installed\ ${TEST_TOOL_NAME}\ successfully ]] || [[ "$REINSTALL_OUTPUT" =~ ${TEST_TOOL_NAME}\ is\ already\ up\ to\ date ]]; then print_test_result "Reinstall after manual removal" 0 else print_test_result "Reinstall after manual removal" 1 fi # Test 13: Update already installed tool (should say up to date) echo -e "\nTest 13: Update check for installed tool" UPDATE_OUTPUT=$(timeout 3 "$GETPKG" install "$TEST_TOOL_NAME" 2>&1) || UPDATE_OUTPUT="" if [[ "$UPDATE_OUTPUT" =~ ${TEST_TOOL_NAME}\ is\ already\ up\ to\ date ]]; then print_test_result "Update check recognizes up-to-date tool" 0 else print_test_result "Update check recognizes up-to-date tool" 1 fi else print_test_result "Install tool from getpkg.xyz" 1 # Skip dependent tests print_test_result "Tool files installed correctly" 1 print_test_result "Bashrc modifications for PATH and autocomplete" 1 print_test_result "Reinstall after manual removal" 1 print_test_result "Update check recognizes up-to-date tool" 1 fi else print_test_result "Publish tool with ARCH to getpkg.xyz" 1 # Skip dependent tests print_test_result "Published tool exists on server" 1 print_test_result "Install tool from getpkg.xyz" 1 print_test_result "Tool files installed correctly" 1 print_test_result "Bashrc modifications for PATH and autocomplete" 1 print_test_result "Reinstall after manual removal" 1 print_test_result "Update check recognizes up-to-date tool" 1 fi # Test 13b: Publish without ARCH (for cross-platform tools) echo -e "\nTest 13b: Publish without ARCH" TEST_TOOL_NOARCH="${TEST_TOOL_NAME}-noarch" mkdir -p "${TEST_DIR}/${TEST_TOOL_NOARCH}" cat > "${TEST_DIR}/${TEST_TOOL_NOARCH}/${TEST_TOOL_NOARCH}" << 'EOF' #!/bin/bash case "$1" in version) echo "1.0.0" ;; *) echo "Cross-platform test tool" ;; esac EOF chmod +x "${TEST_DIR}/${TEST_TOOL_NOARCH}/${TEST_TOOL_NOARCH}" PUBLISH_NOARCH_OUTPUT=$(timeout 3 "$GETPKG" publish "${TEST_TOOL_NOARCH}" "${TEST_DIR}/${TEST_TOOL_NOARCH}" 2>&1) || PUBLISH_NOARCH_OUTPUT="" if [[ "$PUBLISH_NOARCH_OUTPUT" =~ Published! ]] && [[ "$PUBLISH_NOARCH_OUTPUT" =~ URL: ]] && [[ "$PUBLISH_NOARCH_OUTPUT" =~ Hash: ]]; then print_test_result "Publish tool without ARCH" 0 else print_test_result "Publish tool without ARCH" 1 fi # Test 13c: Install universal tool (arch fallback) echo -e "\nTest 13c: Install universal tool (arch fallback)" rm -rf ~/.config/getpkg/"${TEST_TOOL_NOARCH}.json" ~/.getpkg/"${TEST_TOOL_NOARCH}" ~/.local/bin/getpkg/"${TEST_TOOL_NOARCH}" 2>/dev/null || true FALLBACK_INSTALL_OUTPUT=$(timeout 3 "$GETPKG" install "${TEST_TOOL_NOARCH}" 2>&1) || FALLBACK_INSTALL_OUTPUT="" # Check if tool was installed successfully and has universal architecture if [[ "$FALLBACK_INSTALL_OUTPUT" =~ Installed\ ${TEST_TOOL_NOARCH}\ successfully ]] && [ -f ~/.config/getpkg/"${TEST_TOOL_NOARCH}.json" ]; then # Verify the architecture is "universal" in the config file INSTALLED_ARCH=$(grep -o '"arch"[[:space:]]*:[[:space:]]*"[^"]*"' ~/.config/getpkg/"${TEST_TOOL_NOARCH}.json" | sed 's/.*"\([^"]*\)".*/\1/') if [ "$INSTALLED_ARCH" = "universal" ]; then print_test_result "Install universal tool with arch fallback" 0 # Test update check for universal tool UPDATE_UNIVERSAL_OUTPUT=$(timeout 3 "$GETPKG" install "${TEST_TOOL_NOARCH}" 2>&1) || UPDATE_UNIVERSAL_OUTPUT="" if [[ "$UPDATE_UNIVERSAL_OUTPUT" =~ ${TEST_TOOL_NOARCH}\ is\ already\ up\ to\ date ]]; then print_test_result "Update check for universal tool" 0 else print_test_result "Update check for universal tool" 1 fi else print_test_result "Install universal tool with arch fallback" 1 print_test_result "Update check for universal tool" 1 fi else print_test_result "Install universal tool with arch fallback" 1 print_test_result "Update check for universal tool" 1 fi # Clean up the noarch tool from server NOARCH_HASH=$(curl -s "https://getpkg.xyz/hash/${TEST_TOOL_NOARCH}" 2>/dev/null || echo "") if [ -n "$NOARCH_HASH" ] && [ "$NOARCH_HASH" != "null" ] && [ "$NOARCH_HASH" != "Not found" ]; then curl -s -H "Authorization: Bearer ${SOS_WRITE_TOKEN}" \ "https://getpkg.xyz/deleteobject?hash=${NOARCH_HASH}" >/dev/null 2>&1 || true fi else echo -e "\n${YELLOW}Skipping publish/install tests (SOS_WRITE_TOKEN not set)${NC}" echo "To run full tests, set SOS_WRITE_TOKEN environment variable" fi # Test 13d: Comprehensive uninstall test if [ -n "${SOS_WRITE_TOKEN:-}" ]; then echo -e "\nTest 13d: Comprehensive uninstall test" TEST_UNINSTALL_TOOL="test-uninstall-$RANDOM" UNINSTALL_DIR="${TEST_DIR}/${TEST_UNINSTALL_TOOL}" mkdir -p "$UNINSTALL_DIR" # Create test tool with multiple executables cat > "$UNINSTALL_DIR/${TEST_UNINSTALL_TOOL}" << 'EOF' #!/bin/bash case "$1" in version) echo "1.0.0" ;; autocomplete) echo "help version" ;; *) echo "Test uninstall tool" ;; esac EOF chmod +x "$UNINSTALL_DIR/${TEST_UNINSTALL_TOOL}" # Create a second executable in the tool cat > "$UNINSTALL_DIR/${TEST_UNINSTALL_TOOL}-helper" << 'EOF' #!/bin/bash echo "Helper tool" EOF chmod +x "$UNINSTALL_DIR/${TEST_UNINSTALL_TOOL}-helper" # Publish and install the tool PUBLISH_OUTPUT=$(timeout 3 "$GETPKG" publish "${TEST_UNINSTALL_TOOL}:${TEST_ARCH}" "$UNINSTALL_DIR" 2>&1) if [[ "$PUBLISH_OUTPUT" =~ Published! ]]; then INSTALL_OUTPUT=$(timeout 3 "$GETPKG" install "$TEST_UNINSTALL_TOOL" 2>&1) if [[ "$INSTALL_OUTPUT" =~ Installed\ ${TEST_UNINSTALL_TOOL}\ successfully ]]; then # Count bashrc entries before uninstall BASHRC_ENTRIES_BEFORE=$(grep -c "$TEST_UNINSTALL_TOOL" ~/.bashrc_getpkg 2>/dev/null || true) BASHRC_ENTRIES_BEFORE=${BASHRC_ENTRIES_BEFORE:-0} # Verify all components exist CONFIG_EXISTS=false TOOL_DIR_EXISTS=false SYMLINK_EXISTS=false # HELPER_SYMLINK_EXISTS=false [ -f ~/.config/getpkg/"${TEST_UNINSTALL_TOOL}.json" ] && CONFIG_EXISTS=true [ -d ~/.getpkg/"$TEST_UNINSTALL_TOOL" ] && TOOL_DIR_EXISTS=true [ -L ~/.local/bin/getpkg/"$TEST_UNINSTALL_TOOL" ] && SYMLINK_EXISTS=true # Check if helper symlink exists (not currently used in validation) # [ -L ~/.local/bin/getpkg/"${TEST_UNINSTALL_TOOL}-helper" ] && HELPER_SYMLINK_EXISTS=true if $CONFIG_EXISTS && $TOOL_DIR_EXISTS && $SYMLINK_EXISTS; then # Now uninstall UNINSTALL_OUTPUT=$(timeout 3 "$GETPKG" uninstall "$TEST_UNINSTALL_TOOL" 2>&1) if [[ "$UNINSTALL_OUTPUT" =~ Uninstalled\ ${TEST_UNINSTALL_TOOL}\ successfully ]]; then # Check all components are removed ALL_REMOVED=true # Check config file removed if [ -f ~/.config/getpkg/"${TEST_UNINSTALL_TOOL}.json" ]; then echo "ERROR: Config file still exists after uninstall" ALL_REMOVED=false fi # Check tool directory removed if [ -d ~/.getpkg/"$TEST_UNINSTALL_TOOL" ]; then echo "ERROR: Tool directory still exists after uninstall" ALL_REMOVED=false fi # Check symlinks removed if [ -L ~/.local/bin/getpkg/"$TEST_UNINSTALL_TOOL" ]; then echo "ERROR: Main symlink still exists after uninstall" ALL_REMOVED=false fi if [ -L ~/.local/bin/getpkg/"${TEST_UNINSTALL_TOOL}-helper" ]; then echo "ERROR: Helper symlink still exists after uninstall" ALL_REMOVED=false fi # Check bashrc entries removed BASHRC_ENTRIES_AFTER=$(grep -c "$TEST_UNINSTALL_TOOL" ~/.bashrc_getpkg 2>/dev/null || true) BASHRC_ENTRIES_AFTER=${BASHRC_ENTRIES_AFTER:-0} if [ "$BASHRC_ENTRIES_AFTER" -ne 0 ]; then echo "ERROR: Bashrc entries still exist after uninstall (found $BASHRC_ENTRIES_AFTER entries)" ALL_REMOVED=false fi if $ALL_REMOVED; then print_test_result "Complete uninstall removes all components" 0 else print_test_result "Complete uninstall removes all components" 1 fi else print_test_result "Complete uninstall removes all components" 1 fi else echo "ERROR: Not all components were created during install" print_test_result "Complete uninstall removes all components" 1 fi # Cleanup from server $GETPKG unpublish "${TEST_UNINSTALL_TOOL}:${TEST_ARCH}" 2>/dev/null || true else print_test_result "Complete uninstall removes all components" 1 fi else print_test_result "Complete uninstall removes all components" 1 fi # Always cleanup test uninstall tool from server, even if test failed if [[ "$PUBLISH_OUTPUT" =~ Published! ]]; then $GETPKG unpublish "${TEST_UNINSTALL_TOOL}:${TEST_ARCH}" 2>/dev/null || true fi fi # Test 13.5: Comprehensive unpublish functionality echo -e "\nTest 13.5: Comprehensive unpublish functionality" # Only run unpublish tests if SOS_WRITE_TOKEN is available if [ -n "${SOS_WRITE_TOKEN:-}" ]; then # Create unique test names for unpublish tests UNPUBLISH_TOOL_BASE="test-unpublish-$RANDOM" UNPUBLISH_TOOL_MULTI="${UNPUBLISH_TOOL_BASE}-multi" UNPUBLISH_TOOL_CUSTOM="${UNPUBLISH_TOOL_BASE}-custom" UNPUBLISH_TEST_DIR="${TEST_DIR}/unpublish_tests" # Create test directory structure mkdir -p "$UNPUBLISH_TEST_DIR" # Test 13.5a: Create and publish tool with multiple architectures echo "Test 13.5a: Unpublish tool with multiple architectures" echo '#!/bin/bash echo "Multi-arch unpublish test"' > "$UNPUBLISH_TEST_DIR/$UNPUBLISH_TOOL_MULTI" chmod +x "$UNPUBLISH_TEST_DIR/$UNPUBLISH_TOOL_MULTI" # Publish to multiple architectures PUBLISH_x86_64_OUTPUT=$("$GETPKG" publish "${UNPUBLISH_TOOL_MULTI}:x86_64" "$UNPUBLISH_TEST_DIR" 2>&1) PUBLISH_aarch64_OUTPUT=$("$GETPKG" publish "${UNPUBLISH_TOOL_MULTI}:aarch64" "$UNPUBLISH_TEST_DIR" 2>&1) PUBLISH_universal_OUTPUT=$("$GETPKG" publish "${UNPUBLISH_TOOL_MULTI}:universal" "$UNPUBLISH_TEST_DIR" 2>&1) if [[ "$PUBLISH_x86_64_OUTPUT" =~ Published! ]] && [[ "$PUBLISH_aarch64_OUTPUT" =~ Published! ]] && [[ "$PUBLISH_universal_OUTPUT" =~ Published! ]]; then # Test robust unpublish - should remove ALL architectures sleep 1 # Give server time to process all publishes UNPUBLISH_OUTPUT=$("$GETPKG" unpublish "$UNPUBLISH_TOOL_MULTI" 2>&1) UNPUBLISH_EXIT_CODE=$? # Check that unpublish found and removed packages if [ $UNPUBLISH_EXIT_CODE -eq 0 ] && [[ "$UNPUBLISH_OUTPUT" =~ "Found" ]] && [[ "$UNPUBLISH_OUTPUT" =~ "Successfully unpublished" ]]; then print_test_result "Unpublish removes all architectures" 0 else print_test_result "Unpublish removes all architectures" 1 echo " Unpublish failed: $UNPUBLISH_OUTPUT" fi else print_test_result "Unpublish removes all architectures" 1 echo " Failed to publish test tool to multiple architectures" echo " x86_64: $PUBLISH_x86_64_OUTPUT" echo " aarch64: $PUBLISH_aarch64_OUTPUT" echo " universal: $PUBLISH_universal_OUTPUT" fi # Test 13.5b: Unpublish tool with universal architecture echo "Test 13.5b: Unpublish tool with universal architecture" echo '#!/bin/bash echo "Universal arch unpublish test"' > "$UNPUBLISH_TEST_DIR/$UNPUBLISH_TOOL_CUSTOM" chmod +x "$UNPUBLISH_TEST_DIR/$UNPUBLISH_TOOL_CUSTOM" # Publish with universal architecture PUBLISH_CUSTOM_OUTPUT=$("$GETPKG" publish "${UNPUBLISH_TOOL_CUSTOM}:universal" "$UNPUBLISH_TEST_DIR" 2>&1) if [[ "$PUBLISH_CUSTOM_OUTPUT" =~ Published! ]]; then # Test that unpublish can find and remove custom tags UNPUBLISH_CUSTOM_OUTPUT=$("$GETPKG" unpublish "$UNPUBLISH_TOOL_CUSTOM" 2>&1) UNPUBLISH_CUSTOM_EXIT_CODE=$? if [ $UNPUBLISH_CUSTOM_EXIT_CODE -eq 0 ] && [[ "$UNPUBLISH_CUSTOM_OUTPUT" =~ Found\ ${UNPUBLISH_TOOL_CUSTOM}:universal ]]; then print_test_result "Unpublish finds universal architecture" 0 else print_test_result "Unpublish finds universal architecture" 1 echo " Failed to find or unpublish custom tag: $UNPUBLISH_CUSTOM_OUTPUT" fi else print_test_result "Unpublish finds universal architecture" 1 echo " Failed to publish tool with custom tag: $PUBLISH_CUSTOM_OUTPUT" fi # Test 13.5c: Unpublish non-existent tool echo "Test 13.5c: Unpublish non-existent tool" NON_EXISTENT_TOOL="non-existent-tool-$RANDOM" UNPUBLISH_MISSING_OUTPUT=$("$GETPKG" unpublish "$NON_EXISTENT_TOOL" 2>&1) UNPUBLISH_MISSING_EXIT_CODE=$? if [ $UNPUBLISH_MISSING_EXIT_CODE -ne 0 ] && [[ "$UNPUBLISH_MISSING_OUTPUT" =~ "No packages found" ]]; then print_test_result "Unpublish handles missing tools gracefully" 0 else print_test_result "Unpublish handles missing tools gracefully" 1 echo " Expected failure for non-existent tool, got: $UNPUBLISH_MISSING_OUTPUT" fi # Test 13.5d: Unpublish by hash echo "Test 13.5d: Unpublish by hash" UNPUBLISH_TOOL_HASH="${UNPUBLISH_TOOL_BASE}-hash" echo '#!/bin/bash echo "Hash unpublish test"' > "$UNPUBLISH_TEST_DIR/$UNPUBLISH_TOOL_HASH" chmod +x "$UNPUBLISH_TEST_DIR/$UNPUBLISH_TOOL_HASH" PUBLISH_HASH_OUTPUT=$("$GETPKG" publish "${UNPUBLISH_TOOL_HASH}:x86_64" "$UNPUBLISH_TEST_DIR" 2>&1) if [[ "$PUBLISH_HASH_OUTPUT" =~ Hash:\ ([0-9]+) ]]; then EXTRACTED_HASH="${BASH_REMATCH[1]}" # Test unpublish by hash UNPUBLISH_HASH_OUTPUT=$("$GETPKG" unpublish "$EXTRACTED_HASH" 2>&1) UNPUBLISH_HASH_EXIT_CODE=$? if [ $UNPUBLISH_HASH_EXIT_CODE -eq 0 ] && [[ "$UNPUBLISH_HASH_OUTPUT" =~ "Successfully unpublished hash" ]]; then print_test_result "Unpublish by hash works" 0 else print_test_result "Unpublish by hash works" 1 echo " Failed to unpublish by hash: $UNPUBLISH_HASH_OUTPUT" fi else print_test_result "Unpublish by hash works" 1 echo " Could not extract hash from publish output" fi # Cleanup unpublish test directory rm -rf "$UNPUBLISH_TEST_DIR" else echo " Skipping unpublish tests (SOS_WRITE_TOKEN not set)" print_test_result "Unpublish removes all architectures" 0 # Pass as skipped print_test_result "Unpublish finds universal architecture" 0 print_test_result "Unpublish handles missing tools gracefully" 0 print_test_result "Unpublish by hash works" 0 fi # Test 14: Invalid tool name validation echo -e "\nTest 14: Invalid tool name validation" INVALID_OUTPUT=$(timeout 3 "$GETPKG" install "../evil-tool" 2>&1) INVALID_EXIT_CODE=$? echo "Invalid tool output: $INVALID_OUTPUT" echo "Invalid tool exit code: $INVALID_EXIT_CODE" if [[ "$INVALID_OUTPUT" =~ Invalid\ tool\ name ]]; then print_test_result "Invalid tool name rejection" 0 else print_test_result "Invalid tool name rejection" 1 fi # Test 15: Update command (if we have tools installed) if [ -d ~/.config/getpkg ] && [ "$(find ~/.config/getpkg -name "*.json" -type f 2>/dev/null | wc -l)" -gt 0 ]; then echo -e "\nTest 15: Update command" UPDATE_ALL_OUTPUT=$(timeout 30 "$GETPKG" update 2>&1) || UPDATE_ALL_OUTPUT="" if [[ "$UPDATE_ALL_OUTPUT" =~ Update\ Summary ]]; then print_test_result "Update all tools command" 0 else print_test_result "Update all tools command" 1 fi else echo -e "\n${YELLOW}Skipping update all test (no tools installed)${NC}" fi cleanup # Print summary echo -e "\n${YELLOW}Test Summary:${NC}" echo -e "Tests passed: ${GREEN}${TESTS_PASSED}${NC}" echo -e "Tests failed: ${RED}${TESTS_FAILED}${NC}" if [ "$TESTS_FAILED" -eq 0 ]; then echo -e "\n${GREEN}All tests passed!${NC}" exit 0 else echo -e "\n${RED}Some tests failed!${NC}" exit 1 fi