feat: full feature parity for all 42 SDKs + comprehensive tests

All SDKs now implement 58+ functions matching C reference (un.h):
- Execution (8): execute, execute_async, wait_job, get_job, cancel_job, list_jobs, get_languages, detect_language
- Sessions (9): list, get, create, destroy, freeze, unfreeze, boost, unboost, execute
- Services (17): list, get, create, destroy, freeze, unfreeze, lock, unlock, set_unfreeze_on_demand, redeploy, logs, execute, env_get/set/delete/export, resize
- Snapshots (9): list, get, session, service, restore, delete, lock, unlock, clone
- Images (13): list, get, publish, delete, lock, unlock, set_visibility, grant/revoke_access, list_trusted, transfer, spawn, clone
- PaaS Logs (2): fetch, stream
- Utilities (5): validate_keys, hmac_sign, health_check, version, last_error

Test suites created for all SDKs with unit, integration, and functional tests.

Languages: AWK, Bash, C++, C#, Clojure, COBOL, Crystal, D, Dart, .NET, Elixir, Erlang, F#, Forth, Fortran, Go, Groovy, Haskell, Java, JavaScript, Julia, Kotlin, Lisp, Lua, Nim, Objective-C, OCaml, Perl, PHP, PowerShell, Prolog, Python, R, Raku, Ruby, Rust, Scheme, Swift, Tcl, TypeScript, V, Zig
This commit is contained in:
russell@unturf.com 2026-02-05 16:45:02 -05:00
parent a5155aed4f
commit 6e746ace44
90 changed files with 28955 additions and 3028 deletions

View file

@ -0,0 +1,211 @@
// Tests for the Rust unsandbox SDK
// Run with: cargo test
use un::*;
use std::env;
// ============================================================================
// Unit Tests - Test exported library functions
// ============================================================================
#[test]
fn test_detect_language() {
assert_eq!(detect_language("script.py"), Some("python"));
assert_eq!(detect_language("script.js"), Some("javascript"));
assert_eq!(detect_language("script.ts"), Some("typescript"));
assert_eq!(detect_language("script.rb"), Some("ruby"));
assert_eq!(detect_language("script.go"), Some("go"));
assert_eq!(detect_language("script.rs"), Some("rust"));
assert_eq!(detect_language("script.c"), Some("c"));
assert_eq!(detect_language("script.cpp"), Some("cpp"));
assert_eq!(detect_language("script.d"), Some("d"));
assert_eq!(detect_language("script.zig"), Some("zig"));
assert_eq!(detect_language("script.sh"), Some("bash"));
assert_eq!(detect_language("script.lua"), Some("lua"));
assert_eq!(detect_language("script.php"), Some("php"));
assert_eq!(detect_language("script.unknown"), None);
assert_eq!(detect_language("script"), None);
}
#[test]
fn test_hmac_sign() {
let secret_key = "test-secret";
let message = "test-message";
let result = hmac_sign(secret_key, message);
// Should return a 64-character hex string
assert_eq!(result.len(), 64, "HMAC signature should be 64 characters");
// Should be deterministic
let result2 = hmac_sign(secret_key, message);
assert_eq!(result, result2, "HMAC sign is not deterministic");
// Different inputs should produce different outputs
let result3 = hmac_sign(secret_key, "different-message");
assert_ne!(result, result3, "Different inputs should produce different signatures");
}
#[test]
fn test_version() {
let v = version();
assert!(!v.is_empty(), "Version should not be empty");
// Should be in semver format (at least "0.0.0")
assert!(v.len() >= 5, "Version should be in semver format");
}
#[test]
fn test_last_error() {
// Set an error
set_last_error("test error message");
// Retrieve it
let err = last_error();
assert_eq!(err, "test error message");
// Clear it
set_last_error("");
let err = last_error();
assert!(err.is_empty(), "Error should be cleared");
}
#[test]
fn test_credentials_new() {
let pk = "unsb-pk-test-test-test-test";
let sk = "unsb-sk-test1-test2-test3-test4";
let creds = Credentials::new(pk, sk);
assert_eq!(creds.public_key, pk);
assert_eq!(creds.secret_key, sk);
}
// ============================================================================
// Integration Tests - Test SDK internal consistency
// ============================================================================
#[test]
fn test_resolve_credentials_from_env() {
// Save original env vars
let orig_pk = env::var("UNSANDBOX_PUBLIC_KEY").ok();
let orig_sk = env::var("UNSANDBOX_SECRET_KEY").ok();
// Set test env vars
let test_pk = "unsb-pk-test-test-test-test";
let test_sk = "unsb-sk-test1-test2-test3-test4";
env::set_var("UNSANDBOX_PUBLIC_KEY", test_pk);
env::set_var("UNSANDBOX_SECRET_KEY", test_sk);
// Test
let creds = resolve_credentials(None, None).expect("Should resolve from env");
assert_eq!(creds.public_key, test_pk);
assert_eq!(creds.secret_key, test_sk);
// Restore original env vars
match orig_pk {
Some(v) => env::set_var("UNSANDBOX_PUBLIC_KEY", v),
None => env::remove_var("UNSANDBOX_PUBLIC_KEY"),
}
match orig_sk {
Some(v) => env::set_var("UNSANDBOX_SECRET_KEY", v),
None => env::remove_var("UNSANDBOX_SECRET_KEY"),
}
}
#[test]
fn test_resolve_credentials_from_args() {
let test_pk = "unsb-pk-arg1-arg2-arg3-arg4";
let test_sk = "unsb-sk-arg11-arg22-arg33-arg44";
let creds = resolve_credentials(Some(test_pk), Some(test_sk))
.expect("Should resolve from args");
assert_eq!(creds.public_key, test_pk);
assert_eq!(creds.secret_key, test_sk);
}
// ============================================================================
// Functional Tests - Test against real API (requires credentials)
// ============================================================================
fn get_test_credentials() -> Option<Credentials> {
resolve_credentials(None, None).ok()
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_health_check() {
let healthy = health_check();
if !healthy {
eprintln!("API health check returned unhealthy (API may be unreachable)");
}
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_get_languages() {
let creds = get_test_credentials().expect("No credentials for functional test");
let languages = get_languages(&creds).expect("GetLanguages failed");
assert!(!languages.is_empty(), "Languages list should not be empty");
// Should include common languages
assert!(
languages.contains(&"python".to_string()),
"Languages should include python"
);
assert!(
languages.contains(&"javascript".to_string()),
"Languages should include javascript"
);
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_validate_keys() {
let creds = get_test_credentials().expect("No credentials for functional test");
let result = validate_keys(&creds).expect("ValidateKeys failed");
assert!(result.valid, "Keys should be valid");
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_execute_code() {
let creds = get_test_credentials().expect("No credentials for functional test");
let result = execute_code("python", "print('hello from rust test')", &creds)
.expect("ExecuteCode failed");
assert!(!result.output.is_empty(), "Output should not be empty");
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_list_sessions() {
let creds = get_test_credentials().expect("No credentials for functional test");
let _sessions = list_sessions(&creds).expect("ListSessions failed");
// Should return a list (possibly empty)
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_list_services() {
let creds = get_test_credentials().expect("No credentials for functional test");
let _services = list_services(&creds).expect("ListServices failed");
// Should return a list (possibly empty)
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_list_snapshots() {
let creds = get_test_credentials().expect("No credentials for functional test");
let _snapshots = list_snapshots(&creds).expect("ListSnapshots failed");
// Should return a list (possibly empty)
}
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn test_list_images() {
let creds = get_test_credentials().expect("No credentials for functional test");
let _images = list_images(None, &creds).expect("ListImages failed");
// Should return a list (possibly empty)
}