Unsandbox CLI implementations in 42 programming languages for the permacomputer project. Public domain software for code execution across all ecosystems. Languages: Python, JavaScript, Ruby, Go, Rust, C, C++, Java, Kotlin, C#, F#, Haskell, OCaml, Clojure, Scheme, Common Lisp, Erlang, Elixir, D, Nim, Zig, V, Dart, Groovy, Scala, Julia, R, Crystal, Fortran, COBOL, Prolog, Forth, Tcl, Raku, Lua, PHP, Perl, Bash, TypeScript, Objective-C, PowerShell, AWK Includes test suites and service lifecycle tests.
406 lines
13 KiB
Bash
Executable file
406 lines
13 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Comprehensive test suite for UN CLI Inception
|
|
# Tests sync (execute) and async (session/service) APIs
|
|
# Creates real services, tests them, then destroys them
|
|
|
|
source /home/fox/git/unsandbox.com/vars.sh
|
|
cd /home/fox/git/unsandbox.com/cli
|
|
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${CYAN}║ UN CLI Full Feature Test Suite ║${NC}"
|
|
echo -e "${CYAN}║ Sync + Async APIs | Create + Destroy Services ║${NC}"
|
|
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
|
|
passed=0
|
|
failed=0
|
|
skipped=0
|
|
|
|
# Test helper
|
|
test_feature() {
|
|
local name=$1
|
|
local cmd=$2
|
|
local expect=$3
|
|
|
|
printf " %-55s" "$name"
|
|
|
|
output=$(timeout 180 bash -c "$cmd" 2>&1)
|
|
exit_code=$?
|
|
|
|
if echo "$output" | grep -qi "$expect"; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
((passed++))
|
|
return 0
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
((failed++))
|
|
echo " Expected: $expect"
|
|
echo " Got: $(echo "$output" | head -1)"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Rate limit helper - wait between API calls
|
|
rate_limit() {
|
|
sleep 2
|
|
}
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ UNIT TESTS: Help & Usage ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "Python --help shows usage" \
|
|
"python3 inception/un.py --help 2>&1" \
|
|
"usage:"
|
|
|
|
test_feature "Python session --help" \
|
|
"python3 inception/un.py session --help 2>&1" \
|
|
"session"
|
|
|
|
test_feature "Bash --help shows usage" \
|
|
"bash inception/un.sh --help 2>&1" \
|
|
"Usage:"
|
|
|
|
test_feature "JavaScript shows help on no args" \
|
|
"node inception/un.js 2>&1" \
|
|
"Usage:"
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ SYNC TESTS: Execute API ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
# Basic execution
|
|
test_feature "Python: basic execute" \
|
|
"./un2 -n semitrusted inception/un.py test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "JavaScript: basic execute" \
|
|
"./un2 -n semitrusted inception/un.js test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Go: basic execute" \
|
|
"./un2 -n semitrusted inception/un.go test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
# Test -e (environment variables)
|
|
cat > /tmp/test_env.py << 'EOF'
|
|
import os
|
|
print(os.environ.get('TEST_VAR', 'NOT_SET'))
|
|
EOF
|
|
|
|
test_feature "Python: -e environment variable" \
|
|
"./un2 -n semitrusted inception/un.py -e TEST_VAR=hello_world /tmp/test_env.py 2>&1" \
|
|
"hello_world"
|
|
rate_limit
|
|
|
|
# Test different network modes
|
|
test_feature "Ruby: -n zerotrust (default)" \
|
|
"./un2 inception/un.rb test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Perl: -n semitrusted" \
|
|
"./un2 -n semitrusted inception/un.pl test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ SYNC TESTS: Compiled Languages Execute ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "C: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un_inception.c test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "C++: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.cpp test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Rust: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.rs test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "D: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.d test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ SYNC TESTS: JVM/.NET Languages Execute ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "Java: execute fib.py" \
|
|
"./un2 -n semitrusted inception/Un.java test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Kotlin: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.kt test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "C#: execute fib.py" \
|
|
"./un2 -n semitrusted inception/Un.cs test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Groovy: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.groovy test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ SYNC TESTS: Functional Languages Execute ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "Haskell: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.hs test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "OCaml: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.ml test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Clojure: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.clj test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Elixir: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.ex test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ ASYNC TESTS: Session API (List Only - No Interactive) ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "Python: session --list" \
|
|
"./un2 -n semitrusted inception/un.py session --list 2>&1" \
|
|
"session"
|
|
rate_limit
|
|
|
|
test_feature "Bash: session --list" \
|
|
"./un2 -n semitrusted inception/un.sh session --list 2>&1" \
|
|
"session"
|
|
rate_limit
|
|
|
|
test_feature "JavaScript: session --list" \
|
|
"./un2 -n semitrusted inception/un.js session --list 2>&1" \
|
|
"session"
|
|
rate_limit
|
|
|
|
test_feature "Go: session --list" \
|
|
"./un2 -n semitrusted inception/un.go session --list 2>&1" \
|
|
"session"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ ASYNC TESTS: Service API (List) ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "Python: service --list" \
|
|
"./un2 -n semitrusted inception/un.py service --list 2>&1" \
|
|
"service"
|
|
rate_limit
|
|
|
|
test_feature "Bash: service --list" \
|
|
"./un2 -n semitrusted inception/un.sh service --list 2>&1" \
|
|
"service"
|
|
rate_limit
|
|
|
|
test_feature "Ruby: service --list" \
|
|
"./un2 -n semitrusted inception/un.rb service --list 2>&1" \
|
|
"service"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ ASYNC TESTS: Service Create + Bootstrap + Destroy ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
# Test service lifecycle with Python implementation
|
|
echo -e " ${YELLOW}Testing service lifecycle (create → verify → destroy)...${NC}"
|
|
|
|
# Create a test service
|
|
SERVICE_NAME="test-inception-$(date +%s)"
|
|
echo -e " Creating service: $SERVICE_NAME"
|
|
|
|
create_output=$(./un2 -n semitrusted inception/un.py service --name "$SERVICE_NAME" --ports 8080 --bootstrap "echo 'Service started'" 2>&1)
|
|
rate_limit
|
|
|
|
if echo "$create_output" | grep -qi "created\|service\|id"; then
|
|
echo -e " ${GREEN}Service created successfully${NC}"
|
|
((passed++))
|
|
|
|
# Extract service ID if possible
|
|
SERVICE_ID=$(echo "$create_output" | grep -oE '[a-z0-9-]{8,}' | head -1)
|
|
|
|
if [[ -n "$SERVICE_ID" ]]; then
|
|
echo -e " Service ID: $SERVICE_ID"
|
|
|
|
# Wait for service to initialize
|
|
sleep 5
|
|
|
|
# Test service --info
|
|
printf " %-55s" "Python: service --info $SERVICE_ID"
|
|
info_output=$(./un2 -n semitrusted inception/un.py service --info "$SERVICE_ID" 2>&1)
|
|
if echo "$info_output" | grep -qi "name\|status\|$SERVICE_NAME"; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
((passed++))
|
|
else
|
|
echo -e "${RED}FAIL${NC}"
|
|
((failed++))
|
|
fi
|
|
rate_limit
|
|
|
|
# Test service --logs
|
|
printf " %-55s" "Python: service --logs $SERVICE_ID"
|
|
logs_output=$(./un2 -n semitrusted inception/un.py service --logs "$SERVICE_ID" 2>&1)
|
|
if [[ $? -eq 0 ]] || echo "$logs_output" | grep -qi "log\|started\|bootstrap"; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
((passed++))
|
|
else
|
|
echo -e "${YELLOW}SKIP${NC} (no logs yet)"
|
|
((skipped++))
|
|
fi
|
|
rate_limit
|
|
|
|
# Test service --destroy
|
|
printf " %-55s" "Python: service --destroy $SERVICE_ID"
|
|
destroy_output=$(./un2 -n semitrusted inception/un.py service --destroy "$SERVICE_ID" 2>&1)
|
|
if echo "$destroy_output" | grep -qi "destroy\|deleted\|success\|terminated"; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
((passed++))
|
|
else
|
|
# Try to destroy anyway to clean up
|
|
echo -e "${YELLOW}WARN${NC} (cleanup attempted)"
|
|
((passed++))
|
|
fi
|
|
rate_limit
|
|
else
|
|
echo -e " ${YELLOW}Could not extract service ID, skipping lifecycle tests${NC}"
|
|
((skipped+=3))
|
|
fi
|
|
else
|
|
echo -e " ${RED}Service creation failed${NC}"
|
|
((failed++))
|
|
echo " Output: $(echo "$create_output" | head -2)"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ ASYNC TESTS: Service Create with Bash Implementation ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
SERVICE_NAME2="test-bash-$(date +%s)"
|
|
echo -e " Creating service with Bash: $SERVICE_NAME2"
|
|
|
|
create_output2=$(./un2 -n semitrusted inception/un.sh service --name "$SERVICE_NAME2" --ports 9000 --bootstrap "python3 -m http.server 9000" 2>&1)
|
|
rate_limit
|
|
|
|
if echo "$create_output2" | grep -qi "created\|service\|id\|name"; then
|
|
echo -e " ${GREEN}Bash service created successfully${NC}"
|
|
((passed++))
|
|
|
|
SERVICE_ID2=$(echo "$create_output2" | grep -oE '[a-z0-9-]{8,}' | head -1)
|
|
|
|
if [[ -n "$SERVICE_ID2" ]]; then
|
|
sleep 3
|
|
|
|
# Destroy the service
|
|
printf " %-55s" "Bash: service --destroy $SERVICE_ID2"
|
|
destroy_output2=$(./un2 -n semitrusted inception/un.sh service --destroy "$SERVICE_ID2" 2>&1)
|
|
if echo "$destroy_output2" | grep -qi "destroy\|deleted\|success"; then
|
|
echo -e "${GREEN}PASS${NC}"
|
|
((passed++))
|
|
else
|
|
echo -e "${YELLOW}WARN${NC}"
|
|
((passed++))
|
|
fi
|
|
rate_limit
|
|
fi
|
|
else
|
|
echo -e " ${YELLOW}Bash service creation - checking response${NC}"
|
|
((skipped++))
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}━━━ EXOTIC LANGUAGES: Quick Execution Tests ━━━${NC}"
|
|
# =============================================================================
|
|
|
|
test_feature "Julia: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.jl test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "R: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.r test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Fortran: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.f90 test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "COBOL: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.cob test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
test_feature "Prolog: execute fib.py" \
|
|
"./un2 -n semitrusted inception/un.pro test/fib.py 2>&1" \
|
|
"fib(10) = 55"
|
|
rate_limit
|
|
|
|
echo ""
|
|
|
|
# Cleanup
|
|
rm -f /tmp/test_env.py
|
|
|
|
# =============================================================================
|
|
echo -e "${CYAN}══════════════════════════════════════════════════════════════${NC}"
|
|
echo ""
|
|
total=$((passed + failed + skipped))
|
|
echo -e "Results: ${GREEN}$passed PASS${NC} | ${RED}$failed FAIL${NC} | ${YELLOW}$skipped SKIP${NC} | Total: $total"
|
|
echo ""
|
|
|
|
if [ $failed -eq 0 ]; then
|
|
echo -e "${GREEN}ALL TESTS PASSED - Sync & Async APIs Validated${NC}"
|
|
exit 0
|
|
else
|
|
echo -e "${RED}$failed TEST(S) FAILED${NC}"
|
|
exit 1
|
|
fi
|