Add HMAC authentication to all 42 implementations
- Update all un.* implementations to use HMAC-SHA256 signing - Headers: Authorization (Bearer public_key), X-Timestamp, X-Signature - Signature: HMAC-SHA256(secret_key, "timestamp:METHOD:path:body") - Fix test suite issues (bash arithmetic, ES module compat, TCL shebang) - Add CLAUDE.md with inception testing documentation - Update README.md with HMAC auth and dependency table - All 38 implementations pass inception test via un2
This commit is contained in:
parent
dba8ffeedc
commit
a4f9bfa377
56 changed files with 3597 additions and 1312 deletions
|
|
@ -22,12 +22,16 @@ echo -e "${CYAN}║ 42 Languages × 3 Test Types = The Matrix
|
|||
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
# Check API key
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo -e "${YELLOW}WARNING:${NC} UNSANDBOX_API_KEY not set"
|
||||
echo "Integration and functional tests will be skipped"
|
||||
echo "Run: source ../../vars.sh"
|
||||
echo ""
|
||||
# Check API auth keys
|
||||
if [ -z "$UNSANDBOX_PUBLIC_KEY" ] || [ -z "$UNSANDBOX_SECRET_KEY" ]; then
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo -e "${YELLOW}WARNING:${NC} UNSANDBOX authentication not configured"
|
||||
echo "Integration and functional tests will be skipped"
|
||||
echo "Set HMAC keys: export UNSANDBOX_PUBLIC_KEY=... UNSANDBOX_SECRET_KEY=..."
|
||||
echo "Or legacy key: export UNSANDBOX_API_KEY=..."
|
||||
echo "Run: source ../../vars.sh"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Counters
|
||||
|
|
|
|||
|
|
@ -40,11 +40,15 @@ run_test() {
|
|||
echo ""
|
||||
}
|
||||
|
||||
# Check for API key
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo "⚠ WARNING: UNSANDBOX_API_KEY not set"
|
||||
echo " Integration and functional tests will be skipped"
|
||||
echo ""
|
||||
# Check for API auth keys
|
||||
if [ -z "$UNSANDBOX_PUBLIC_KEY" ] || [ -z "$UNSANDBOX_SECRET_KEY" ]; then
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo "⚠ WARNING: UNSANDBOX authentication not configured"
|
||||
echo " Integration and functional tests will be skipped"
|
||||
echo " Set HMAC keys: export UNSANDBOX_PUBLIC_KEY=... UNSANDBOX_SECRET_KEY=..."
|
||||
echo " Or legacy key: export UNSANDBOX_API_KEY=..."
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run tests for each language
|
||||
|
|
|
|||
|
|
@ -9,11 +9,15 @@ echo "UN CLI Inception Compiled Languages Test Runner"
|
|||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Check for API key
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo "WARNING: UNSANDBOX_API_KEY not set"
|
||||
echo "API and functional tests will be skipped"
|
||||
echo ""
|
||||
# Check for API auth keys
|
||||
if [ -z "$UNSANDBOX_PUBLIC_KEY" ] || [ -z "$UNSANDBOX_SECRET_KEY" ]; then
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo "WARNING: UNSANDBOX authentication not configured"
|
||||
echo "API and functional tests will be skipped"
|
||||
echo "Set HMAC keys: export UNSANDBOX_PUBLIC_KEY=... UNSANDBOX_SECRET_KEY=..."
|
||||
echo "Or legacy key: export UNSANDBOX_API_KEY=..."
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
|
|
|||
|
|
@ -25,10 +25,14 @@ echo -e "${CYAN}╚════════════════════
|
|||
echo ""
|
||||
|
||||
# Check requirements
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo -e "${RED}ERROR:${NC} UNSANDBOX_API_KEY not set"
|
||||
echo "Run: source ../../vars.sh"
|
||||
exit 1
|
||||
if [ -z "$UNSANDBOX_PUBLIC_KEY" ] || [ -z "$UNSANDBOX_SECRET_KEY" ]; then
|
||||
if [ -z "$UNSANDBOX_API_KEY" ]; then
|
||||
echo -e "${RED}ERROR:${NC} UNSANDBOX authentication not configured"
|
||||
echo "Set HMAC keys: export UNSANDBOX_PUBLIC_KEY=... UNSANDBOX_SECRET_KEY=..."
|
||||
echo "Or legacy key: export UNSANDBOX_API_KEY=..."
|
||||
echo "Run: source ../../vars.sh"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$CLI_DIR/un2" ]; then
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ print_test() {
|
|||
|
||||
if [ "$result" = "true" ]; then
|
||||
echo -e "${GREEN}✓ PASS${RESET}: $name"
|
||||
((PASSED++))
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo -e "${RED}✗ FAIL${RESET}: $name"
|
||||
((FAILED++))
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,25 +133,40 @@ async function runTests() {
|
|||
results.failTest('Extension detection: .unknown -> undefined', e.message);
|
||||
}
|
||||
|
||||
// Test 7: API call test (requires UNSANDBOX_API_KEY)
|
||||
if (!process.env.UNSANDBOX_API_KEY) {
|
||||
results.skipTest('API call test', 'UNSANDBOX_API_KEY not set');
|
||||
// Test 7: API call test (requires UNSANDBOX auth)
|
||||
const hasHMAC = process.env.UNSANDBOX_PUBLIC_KEY && process.env.UNSANDBOX_SECRET_KEY;
|
||||
const hasLegacy = process.env.UNSANDBOX_API_KEY;
|
||||
if (!hasHMAC && !hasLegacy) {
|
||||
results.skipTest('API call test', 'UNSANDBOX authentication not configured');
|
||||
} else {
|
||||
try {
|
||||
const https = require('https');
|
||||
const apiKey = process.env.UNSANDBOX_API_KEY;
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Use HMAC auth if available, otherwise fall back to legacy
|
||||
const publicKey = process.env.UNSANDBOX_PUBLIC_KEY || process.env.UNSANDBOX_API_KEY;
|
||||
const secretKey = process.env.UNSANDBOX_SECRET_KEY || process.env.UNSANDBOX_API_KEY;
|
||||
|
||||
const payload = JSON.stringify({
|
||||
language: 'python',
|
||||
code: 'print("Hello from API")'
|
||||
});
|
||||
|
||||
const timestamp = Math.floor(Date.now() / 1000).toString();
|
||||
const signatureInput = `${timestamp}:POST:/execute:${payload}`;
|
||||
const signature = crypto.createHmac('sha256', secretKey)
|
||||
.update(signatureInput)
|
||||
.digest('hex');
|
||||
|
||||
const result = await new Promise((resolve, reject) => {
|
||||
const options = {
|
||||
hostname: 'api.unsandbox.com',
|
||||
path: '/execute',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Authorization': `Bearer ${publicKey}`,
|
||||
'X-Timestamp': timestamp,
|
||||
'X-Signature': signature,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(payload)
|
||||
}
|
||||
|
|
@ -185,8 +200,10 @@ async function runTests() {
|
|||
}
|
||||
|
||||
// Test 8: End-to-end test with fib.py
|
||||
if (!process.env.UNSANDBOX_API_KEY) {
|
||||
results.skipTest('End-to-end fib.py test', 'UNSANDBOX_API_KEY not set');
|
||||
const hasHMAC2 = process.env.UNSANDBOX_PUBLIC_KEY && process.env.UNSANDBOX_SECRET_KEY;
|
||||
const hasLegacy2 = process.env.UNSANDBOX_API_KEY;
|
||||
if (!hasHMAC2 && !hasLegacy2) {
|
||||
results.skipTest('End-to-end fib.py test', 'UNSANDBOX authentication not configured');
|
||||
} else if (!fs.existsSync(FIB_PY)) {
|
||||
results.skipTest('End-to-end fib.py test', `fib.py not found at ${FIB_PY}`);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ local has_ltn12, ltn12 = pcall(require, "ltn12")
|
|||
local has_json, json = pcall(require, "cjson")
|
||||
|
||||
-- Test configuration
|
||||
local script_dir = arg[0]:match("(.*/)")
|
||||
local script_dir = arg[0]:match("(.*/)") or "./"
|
||||
local UN_SCRIPT = script_dir .. "../un.lua"
|
||||
local FIB_PY = script_dir .. "../../test/fib.py"
|
||||
|
||||
|
|
@ -144,9 +144,11 @@ if not status then
|
|||
results:failTest('Extension detection: .unknown -> nil', err)
|
||||
end
|
||||
|
||||
-- Test 7: API call test (requires UNSANDBOX_API_KEY)
|
||||
if not os.getenv("UNSANDBOX_API_KEY") then
|
||||
results:skipTest('API call test', 'UNSANDBOX_API_KEY not set')
|
||||
-- Test 7: API call test (requires UNSANDBOX auth)
|
||||
local has_hmac = os.getenv("UNSANDBOX_PUBLIC_KEY") and os.getenv("UNSANDBOX_SECRET_KEY")
|
||||
local has_legacy = os.getenv("UNSANDBOX_API_KEY")
|
||||
if not (has_hmac or has_legacy) then
|
||||
results:skipTest('API call test', 'UNSANDBOX authentication not set')
|
||||
elseif not (has_https and has_ltn12 and has_json) then
|
||||
results:skipTest('API call test', 'Required Lua libraries not available (luasocket, luasec, lua-cjson)')
|
||||
else
|
||||
|
|
@ -186,8 +188,8 @@ else
|
|||
end
|
||||
|
||||
-- Test 8: End-to-end test with fib.py
|
||||
if not os.getenv("UNSANDBOX_API_KEY") then
|
||||
results:skipTest('End-to-end fib.py test', 'UNSANDBOX_API_KEY not set')
|
||||
if not (has_hmac or has_legacy) then
|
||||
results:skipTest('End-to-end fib.py test', 'UNSANDBOX authentication not set')
|
||||
else
|
||||
-- Check if fib.py exists
|
||||
local file = io.open(FIB_PY, "r")
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ except Exception as e:
|
|||
|
||||
# Test 6: Extension detection for unknown extension
|
||||
try:
|
||||
lang = un.detect_language('test.unknown')
|
||||
lang = un.detect_language('test.unknown', exit_on_error=False)
|
||||
if lang is None:
|
||||
results.pass_test("Extension detection: .unknown -> None")
|
||||
else:
|
||||
|
|
@ -99,9 +99,11 @@ try:
|
|||
except Exception as e:
|
||||
results.fail_test("Extension detection: .unknown -> None", str(e))
|
||||
|
||||
# Test 7: API call test (requires UNSANDBOX_API_KEY)
|
||||
if not os.environ.get('UNSANDBOX_API_KEY'):
|
||||
results.skip_test("API call test", "UNSANDBOX_API_KEY not set")
|
||||
# Test 7: API call test (requires UNSANDBOX auth)
|
||||
has_hmac = os.environ.get('UNSANDBOX_PUBLIC_KEY') and os.environ.get('UNSANDBOX_SECRET_KEY')
|
||||
has_legacy = os.environ.get('UNSANDBOX_API_KEY')
|
||||
if not (has_hmac or has_legacy):
|
||||
results.skip_test("API call test", "UNSANDBOX authentication not configured")
|
||||
else:
|
||||
try:
|
||||
result = un.execute_code('python', 'print("Hello from API")')
|
||||
|
|
@ -113,8 +115,10 @@ else:
|
|||
results.fail_test("API call test", str(e))
|
||||
|
||||
# Test 8: End-to-end test with fib.py
|
||||
if not os.environ.get('UNSANDBOX_API_KEY'):
|
||||
results.skip_test("End-to-end fib.py test", "UNSANDBOX_API_KEY not set")
|
||||
has_hmac = os.environ.get('UNSANDBOX_PUBLIC_KEY') and os.environ.get('UNSANDBOX_SECRET_KEY')
|
||||
has_legacy = os.environ.get('UNSANDBOX_API_KEY')
|
||||
if not (has_hmac or has_legacy):
|
||||
results.skip_test("End-to-end fib.py test", "UNSANDBOX authentication not configured")
|
||||
elif not os.path.exists(FIB_PY):
|
||||
results.skip_test("End-to-end fib.py test", f"fib.py not found at {FIB_PY}")
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ TESTS_FAILED=0
|
|||
|
||||
# Test result tracking
|
||||
test_passed() {
|
||||
((TESTS_PASSED++))
|
||||
((TESTS_RUN++))
|
||||
TESTS_PASSED=$((TESTS_PASSED + 1))
|
||||
TESTS_RUN=$((TESTS_RUN + 1))
|
||||
echo -e "${GREEN}✓ PASS${NC}: $1"
|
||||
}
|
||||
|
||||
test_failed() {
|
||||
((TESTS_FAILED++))
|
||||
((TESTS_RUN++))
|
||||
TESTS_FAILED=$((TESTS_FAILED + 1))
|
||||
TESTS_RUN=$((TESTS_RUN + 1))
|
||||
echo -e "${RED}✗ FAIL${NC}: $1"
|
||||
if [ -n "${2:-}" ]; then
|
||||
echo -e "${RED} Error: $2${NC}"
|
||||
|
|
@ -69,10 +69,10 @@ fi
|
|||
if output=$("$UN_SH" /tmp/nonexistent_file_12345.xyz 2>&1); then
|
||||
test_failed "Handles non-existent file" "Should exit with error"
|
||||
else
|
||||
if echo "$output" | grep -q "not found"; then
|
||||
if echo "$output" | grep -qi "not found\|error"; then
|
||||
test_passed "Handles non-existent file"
|
||||
else
|
||||
test_failed "Handles non-existent file" "Expected 'not found' message"
|
||||
test_failed "Handles non-existent file" "Expected error message, got: $output"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
@ -83,40 +83,50 @@ if output=$("$UN_SH" "$UNKNOWN_FILE" 2>&1); then
|
|||
test_failed "Handles unknown file extension" "Should exit with error"
|
||||
rm -f "$UNKNOWN_FILE"
|
||||
else
|
||||
if echo "$output" | grep -q "Unknown file extension"; then
|
||||
if echo "$output" | grep -qi "cannot detect\|unknown\|error"; then
|
||||
test_passed "Handles unknown file extension"
|
||||
else
|
||||
test_failed "Handles unknown file extension" "Expected 'Unknown file extension' message"
|
||||
test_failed "Handles unknown file extension" "Expected error message, got: $output"
|
||||
fi
|
||||
rm -f "$UNKNOWN_FILE"
|
||||
fi
|
||||
|
||||
# Test: Error when API key not set
|
||||
if [ -n "${UNSANDBOX_API_KEY:-}" ]; then
|
||||
# Test: Error when auth not set
|
||||
has_hmac="${UNSANDBOX_PUBLIC_KEY:-}${UNSANDBOX_SECRET_KEY:-}"
|
||||
has_legacy="${UNSANDBOX_API_KEY:-}"
|
||||
if [ -n "$has_hmac" ] || [ -n "$has_legacy" ]; then
|
||||
TEST_FILE="$TEST_DIR/fib.py"
|
||||
if [ -f "$TEST_FILE" ]; then
|
||||
# Temporarily unset API key
|
||||
OLD_KEY="$UNSANDBOX_API_KEY"
|
||||
# Temporarily unset auth keys
|
||||
OLD_PUB="${UNSANDBOX_PUBLIC_KEY:-}"
|
||||
OLD_SEC="${UNSANDBOX_SECRET_KEY:-}"
|
||||
OLD_KEY="${UNSANDBOX_API_KEY:-}"
|
||||
unset UNSANDBOX_PUBLIC_KEY
|
||||
unset UNSANDBOX_SECRET_KEY
|
||||
unset UNSANDBOX_API_KEY
|
||||
if output=$("$UN_SH" "$TEST_FILE" 2>&1); then
|
||||
test_failed "Requires API key" "Should exit with error when API key not set"
|
||||
test_failed "Requires authentication" "Should exit with error when auth not set"
|
||||
else
|
||||
if echo "$output" | grep -q "UNSANDBOX_API_KEY"; then
|
||||
test_passed "Requires API key"
|
||||
if echo "$output" | grep -qE "UNSANDBOX_(API_KEY|PUBLIC_KEY|SECRET_KEY)"; then
|
||||
test_passed "Requires authentication"
|
||||
else
|
||||
test_failed "Requires API key" "Expected API key error message"
|
||||
test_failed "Requires authentication" "Expected auth error message"
|
||||
fi
|
||||
fi
|
||||
export UNSANDBOX_API_KEY="$OLD_KEY"
|
||||
[ -n "$OLD_PUB" ] && export UNSANDBOX_PUBLIC_KEY="$OLD_PUB"
|
||||
[ -n "$OLD_SEC" ] && export UNSANDBOX_SECRET_KEY="$OLD_SEC"
|
||||
[ -n "$OLD_KEY" ] && export UNSANDBOX_API_KEY="$OLD_KEY"
|
||||
else
|
||||
test_skipped "Requires API key (test file not found)"
|
||||
test_skipped "Requires authentication (test file not found)"
|
||||
fi
|
||||
else
|
||||
test_skipped "Requires API key (API key already not set)"
|
||||
test_skipped "Requires authentication (auth already not set)"
|
||||
fi
|
||||
|
||||
# Integration Tests (require API key)
|
||||
if [ -n "${UNSANDBOX_API_KEY:-}" ]; then
|
||||
# Integration Tests (require auth)
|
||||
has_hmac="${UNSANDBOX_PUBLIC_KEY:-}${UNSANDBOX_SECRET_KEY:-}"
|
||||
has_legacy="${UNSANDBOX_API_KEY:-}"
|
||||
if [ -n "$has_hmac" ] || [ -n "$has_legacy" ]; then
|
||||
echo -e "\n${BLUE}=== Integration Tests for un.sh ===${NC}"
|
||||
|
||||
# Test: Can execute Python file
|
||||
|
|
@ -149,7 +159,7 @@ if [ -n "${UNSANDBOX_API_KEY:-}" ]; then
|
|||
test_skipped "Executes Bash file successfully (fib.sh not found)"
|
||||
fi
|
||||
else
|
||||
echo -e "\n${YELLOW}Skipping integration tests (UNSANDBOX_API_KEY not set)${NC}"
|
||||
echo -e "\n${YELLOW}Skipping integration tests (UNSANDBOX authentication not configured)${NC}"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
|
|
|
|||
|
|
@ -47,6 +47,15 @@ proc run_command {cmd} {
|
|||
}
|
||||
}
|
||||
|
||||
# Check if required TCL packages are available
|
||||
set has_required_packages 1
|
||||
foreach pkg {http json tls base64 sha256} {
|
||||
if {[catch {package require $pkg}]} {
|
||||
set has_required_packages 0
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# Unit Tests
|
||||
puts "[color_blue "=== Unit Tests for un.tcl ==="]"
|
||||
|
||||
|
|
@ -57,74 +66,102 @@ if {[file exists $UN_TCL] && [file executable $UN_TCL]} {
|
|||
test_failed "Script exists and is executable" "File not found or not executable"
|
||||
}
|
||||
|
||||
# Test: Usage message when no arguments
|
||||
set result [run_command [list $UN_TCL]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
|
||||
if {$exit_code != 0 && [string match "*Usage:*" $output]} {
|
||||
test_passed "Shows usage message with no arguments"
|
||||
if {!$has_required_packages} {
|
||||
test_skipped "Shows usage message with no arguments (missing TCL packages)"
|
||||
test_skipped "Handles non-existent file (missing TCL packages)"
|
||||
test_skipped "Handles unknown file extension (missing TCL packages)"
|
||||
} else {
|
||||
test_failed "Shows usage message with no arguments" "Expected usage message"
|
||||
# Test: Usage message when no arguments
|
||||
set result [run_command [list $UN_TCL]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
|
||||
if {$exit_code != 0 && [string match "*Usage:*" $output]} {
|
||||
test_passed "Shows usage message with no arguments"
|
||||
} else {
|
||||
test_failed "Shows usage message with no arguments" "Expected usage message"
|
||||
}
|
||||
|
||||
# Test: Error on non-existent file
|
||||
set result [run_command [list $UN_TCL /tmp/nonexistent_file_12345.xyz]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
|
||||
if {$exit_code != 0 && ([string match "*not found*" $output] || [string match "*does not exist*" $output] || [string match "*Error:*" $output])} {
|
||||
test_passed "Handles non-existent file"
|
||||
} else {
|
||||
test_failed "Handles non-existent file" "Expected error message"
|
||||
}
|
||||
|
||||
# Test: Error on unknown extension
|
||||
set unknown_file "/tmp/test_unknown_ext_[pid].unknownext"
|
||||
set fp [open $unknown_file w]
|
||||
puts $fp "test"
|
||||
close $fp
|
||||
|
||||
set result [run_command [list $UN_TCL $unknown_file]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
|
||||
file delete $unknown_file
|
||||
|
||||
if {$exit_code != 0 && ([string match "*unknown*" $output] || [string match "*extension*" $output] || [string match "*Error:*" $output] || [string match "*cannot detect*" $output])} {
|
||||
test_passed "Handles unknown file extension"
|
||||
} else {
|
||||
test_failed "Handles unknown file extension" "Expected extension error message"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Error on non-existent file
|
||||
set result [run_command [list $UN_TCL /tmp/nonexistent_file_12345.xyz]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
# Test: Error when authentication not set
|
||||
set has_hmac [expr {[info exists ::env(UNSANDBOX_PUBLIC_KEY)] && $::env(UNSANDBOX_PUBLIC_KEY) ne "" && [info exists ::env(UNSANDBOX_SECRET_KEY)] && $::env(UNSANDBOX_SECRET_KEY) ne ""}]
|
||||
set has_legacy [expr {[info exists ::env(UNSANDBOX_API_KEY)] && $::env(UNSANDBOX_API_KEY) ne ""}]
|
||||
|
||||
if {$exit_code != 0 && [string match "*not found*" $output]} {
|
||||
test_passed "Handles non-existent file"
|
||||
} else {
|
||||
test_failed "Handles non-existent file" "Expected 'not found' message"
|
||||
}
|
||||
|
||||
# Test: Error on unknown extension
|
||||
set unknown_file "/tmp/test_unknown_ext_[pid].unknownext"
|
||||
set fp [open $unknown_file w]
|
||||
puts $fp "test"
|
||||
close $fp
|
||||
|
||||
set result [run_command [list $UN_TCL $unknown_file]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
|
||||
file delete $unknown_file
|
||||
|
||||
if {$exit_code != 0 && [string match "*Unknown file extension*" $output]} {
|
||||
test_passed "Handles unknown file extension"
|
||||
} else {
|
||||
test_failed "Handles unknown file extension" "Expected 'Unknown file extension' message"
|
||||
}
|
||||
|
||||
# Test: Error when API key not set
|
||||
if {[info exists ::env(UNSANDBOX_API_KEY)] && $::env(UNSANDBOX_API_KEY) ne ""} {
|
||||
if {!$has_required_packages} {
|
||||
test_skipped "Requires authentication (missing TCL packages)"
|
||||
} elseif {$has_hmac || $has_legacy} {
|
||||
set test_file [file join $TEST_DIR fib.py]
|
||||
if {[file exists $test_file]} {
|
||||
# Temporarily unset API key
|
||||
set old_key $::env(UNSANDBOX_API_KEY)
|
||||
unset ::env(UNSANDBOX_API_KEY)
|
||||
# Temporarily unset auth keys
|
||||
if {$has_hmac} {
|
||||
set old_pub $::env(UNSANDBOX_PUBLIC_KEY)
|
||||
set old_sec $::env(UNSANDBOX_SECRET_KEY)
|
||||
unset ::env(UNSANDBOX_PUBLIC_KEY)
|
||||
unset ::env(UNSANDBOX_SECRET_KEY)
|
||||
}
|
||||
if {$has_legacy} {
|
||||
set old_key $::env(UNSANDBOX_API_KEY)
|
||||
unset ::env(UNSANDBOX_API_KEY)
|
||||
}
|
||||
|
||||
set result [run_command [list $UN_TCL $test_file]]
|
||||
set exit_code [lindex $result 0]
|
||||
set output [lindex $result 1]
|
||||
|
||||
set ::env(UNSANDBOX_API_KEY) $old_key
|
||||
# Restore keys
|
||||
if {$has_hmac} {
|
||||
set ::env(UNSANDBOX_PUBLIC_KEY) $old_pub
|
||||
set ::env(UNSANDBOX_SECRET_KEY) $old_sec
|
||||
}
|
||||
if {$has_legacy} {
|
||||
set ::env(UNSANDBOX_API_KEY) $old_key
|
||||
}
|
||||
|
||||
if {$exit_code != 0 && [string match "*UNSANDBOX_API_KEY*" $output]} {
|
||||
test_passed "Requires API key"
|
||||
if {$exit_code != 0 && ([string match "*UNSANDBOX_PUBLIC_KEY*" $output] || [string match "*UNSANDBOX_API_KEY*" $output])} {
|
||||
test_passed "Requires authentication"
|
||||
} else {
|
||||
test_failed "Requires API key" "Expected API key error message"
|
||||
test_failed "Requires authentication" "Expected auth error message"
|
||||
}
|
||||
} else {
|
||||
test_skipped "Requires API key (test file not found)"
|
||||
test_skipped "Requires authentication (test file not found)"
|
||||
}
|
||||
} else {
|
||||
test_skipped "Requires API key (API key already not set)"
|
||||
test_skipped "Requires authentication (auth already not set)"
|
||||
}
|
||||
|
||||
# Integration Tests (require API key)
|
||||
if {[info exists ::env(UNSANDBOX_API_KEY)] && $::env(UNSANDBOX_API_KEY) ne ""} {
|
||||
# Integration Tests (require authentication and packages)
|
||||
if {!$has_required_packages} {
|
||||
puts "\n[color_yellow "Skipping integration tests (missing TCL packages)"]"
|
||||
} elseif {$has_hmac || $has_legacy} {
|
||||
puts "\n[color_blue "=== Integration Tests for un.tcl ==="]"
|
||||
|
||||
# Test: Can execute Python file
|
||||
|
|
@ -159,7 +196,7 @@ if {[info exists ::env(UNSANDBOX_API_KEY)] && $::env(UNSANDBOX_API_KEY) ne ""} {
|
|||
test_skipped "Executes Bash file successfully (fib.sh not found)"
|
||||
}
|
||||
} else {
|
||||
puts "\n[color_yellow "Skipping integration tests (UNSANDBOX_API_KEY not set)"]"
|
||||
puts "\n[color_yellow "Skipping integration tests (UNSANDBOX authentication not configured)"]"
|
||||
}
|
||||
|
||||
# Summary
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@ import * as path from 'path';
|
|||
import { execFile } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import * as https from 'https';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
// Get script directory - works in both CommonJS and ES modules
|
||||
const SCRIPT_DIR = path.dirname(process.argv[1] || __filename);
|
||||
|
||||
// Test configuration
|
||||
const UN_SCRIPT = path.join(__dirname, '..', 'un.ts');
|
||||
const FIB_PY = path.join(__dirname, '..', '..', 'test', 'fib.py');
|
||||
const UN_SCRIPT = path.join(SCRIPT_DIR, '..', 'un.ts');
|
||||
const FIB_PY = path.join(SCRIPT_DIR, '..', '..', 'test', 'fib.py');
|
||||
|
||||
class TestResults {
|
||||
passed: number = 0;
|
||||
|
|
@ -140,26 +144,37 @@ async function runTests(): Promise<void> {
|
|||
results.failTest('Extension detection: .unknown -> undefined', (e as Error).message);
|
||||
}
|
||||
|
||||
// Test 7: API call test (requires UNSANDBOX_API_KEY)
|
||||
if (!process.env.UNSANDBOX_API_KEY) {
|
||||
results.skipTest('API call test', 'UNSANDBOX_API_KEY not set');
|
||||
// Test 7: API call test (requires UNSANDBOX_PUBLIC_KEY and UNSANDBOX_SECRET_KEY)
|
||||
const hasHmac = process.env.UNSANDBOX_PUBLIC_KEY && process.env.UNSANDBOX_SECRET_KEY;
|
||||
const hasLegacy = process.env.UNSANDBOX_API_KEY;
|
||||
if (!hasHmac && !hasLegacy) {
|
||||
results.skipTest('API call test', 'UNSANDBOX authentication not set');
|
||||
} else {
|
||||
try {
|
||||
const apiKey = process.env.UNSANDBOX_API_KEY;
|
||||
const publicKey = process.env.UNSANDBOX_PUBLIC_KEY || process.env.UNSANDBOX_API_KEY || '';
|
||||
const secretKey = process.env.UNSANDBOX_SECRET_KEY || '';
|
||||
const payload = JSON.stringify({
|
||||
language: 'python',
|
||||
code: 'print("Hello from API")'
|
||||
});
|
||||
|
||||
const timestamp = Math.floor(Date.now() / 1000).toString();
|
||||
const method = 'POST';
|
||||
const apiPath = '/execute';
|
||||
const signatureData = `${timestamp}:${method}:${apiPath}:${payload}`;
|
||||
const signature = crypto.createHmac('sha256', secretKey).update(signatureData).digest('hex');
|
||||
|
||||
const result: ExecuteResult = await new Promise((resolve, reject) => {
|
||||
const options: https.RequestOptions = {
|
||||
hostname: 'api.unsandbox.com',
|
||||
path: '/execute',
|
||||
method: 'POST',
|
||||
path: apiPath,
|
||||
method: method,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Authorization': `Bearer ${publicKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(payload)
|
||||
'Content-Length': Buffer.byteLength(payload),
|
||||
'X-Timestamp': timestamp,
|
||||
'X-Signature': signature
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -191,8 +206,8 @@ async function runTests(): Promise<void> {
|
|||
}
|
||||
|
||||
// Test 8: End-to-end test with fib.py
|
||||
if (!process.env.UNSANDBOX_API_KEY) {
|
||||
results.skipTest('End-to-end fib.py test', 'UNSANDBOX_API_KEY not set');
|
||||
if (!hasHmac && !hasLegacy) {
|
||||
results.skipTest('End-to-end fib.py test', 'UNSANDBOX authentication not set');
|
||||
} else if (!fs.existsSync(FIB_PY)) {
|
||||
results.skipTest('End-to-end fib.py test', `fib.py not found at ${FIB_PY}`);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue