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
260 lines
8 KiB
D
260 lines
8 KiB
D
// Tests for the D unsandbox SDK
|
|
// Compile: dmd -unittest -main test_un.d ../src/un.d -of=test_un
|
|
// Run: ./test_un
|
|
|
|
import std.stdio;
|
|
import std.process : environment;
|
|
import std.algorithm : canFind;
|
|
|
|
// Note: In D, unittest blocks are automatically discovered and run
|
|
// when compiling with -unittest flag
|
|
|
|
// ============================================================================
|
|
// Unit Tests - Test exported library functions
|
|
// ============================================================================
|
|
|
|
unittest {
|
|
writeln("Testing detectLanguage...");
|
|
assert(detectLanguage("script.py") == "python");
|
|
assert(detectLanguage("script.js") == "javascript");
|
|
assert(detectLanguage("script.ts") == "typescript");
|
|
assert(detectLanguage("script.go") == "go");
|
|
assert(detectLanguage("script.rs") == "rust");
|
|
assert(detectLanguage("script.c") == "c");
|
|
assert(detectLanguage("script.cpp") == "cpp");
|
|
assert(detectLanguage("script.d") == "d");
|
|
assert(detectLanguage("script.zig") == "zig");
|
|
assert(detectLanguage("script.sh") == "bash");
|
|
assert(detectLanguage("script.rb") == "ruby");
|
|
assert(detectLanguage("script.php") == "php");
|
|
assert(detectLanguage("script.unknown") == "");
|
|
assert(detectLanguage("script") == "");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing hmacSign...");
|
|
string secretKey = "test-secret";
|
|
string message = "test-message";
|
|
|
|
string result = hmacSign(secretKey, message);
|
|
|
|
// Should return a 64-character hex string
|
|
assert(result.length == 64, "HMAC signature should be 64 characters");
|
|
|
|
// Should be deterministic
|
|
string result2 = hmacSign(secretKey, message);
|
|
assert(result == result2, "HMAC sign should be deterministic");
|
|
|
|
// Different inputs should produce different outputs
|
|
string result3 = hmacSign(secretKey, "different-message");
|
|
assert(result != result3, "Different inputs should produce different signatures");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing sdkVersion...");
|
|
string v = sdkVersion();
|
|
assert(v.length > 0, "Version should not be empty");
|
|
// Should be in semver format (at least "0.0.0")
|
|
assert(v.length >= 5, "Version should be in semver format");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing lastError...");
|
|
// Set an error
|
|
setLastError("test error message");
|
|
|
|
// Retrieve it
|
|
string err = lastError();
|
|
assert(err == "test error message");
|
|
|
|
// Clear it
|
|
setLastError("");
|
|
err = lastError();
|
|
assert(err == "", "Error should be cleared");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing escapeJson...");
|
|
assert(escapeJson("hello") == "hello");
|
|
assert(escapeJson("hello\"world") == "hello\\\"world");
|
|
assert(escapeJson("line1\nline2") == "line1\\nline2");
|
|
assert(escapeJson("tab\there") == "tab\\there");
|
|
assert(escapeJson("back\\slash") == "back\\\\slash");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Integration Tests - Test SDK internal consistency
|
|
// ============================================================================
|
|
|
|
unittest {
|
|
writeln("Testing computeHmac...");
|
|
string key = "test-key";
|
|
string msg = "test-message";
|
|
|
|
string sig1 = computeHmac(key, msg);
|
|
string sig2 = computeHmac(key, msg);
|
|
|
|
// Should be deterministic
|
|
assert(sig1 == sig2, "HMAC should be deterministic");
|
|
|
|
// Should produce different results for different inputs
|
|
string sig3 = computeHmac(key, "different");
|
|
assert(sig1 != sig3, "Different inputs should produce different signatures");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing buildAuthHeaders...");
|
|
string pk = "unsb-pk-test-test-test-test";
|
|
string sk = "unsb-sk-test1-test2-test3-test4";
|
|
|
|
string headers = buildAuthHeaders("POST", "/execute", "{}", pk, sk);
|
|
|
|
// Should contain auth header
|
|
assert(headers.canFind("Authorization: Bearer " ~ pk));
|
|
// Should contain timestamp header
|
|
assert(headers.canFind("X-Timestamp:"));
|
|
// Should contain signature header
|
|
assert(headers.canFind("X-Signature:"));
|
|
writeln(" PASS");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Functional Tests - Test against real API (requires credentials)
|
|
// ============================================================================
|
|
|
|
bool hasCredentials() {
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
return pk.length > 0 && sk.length > 0;
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing healthCheck (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
bool healthy = healthCheck();
|
|
writeln(" Health check result: ", healthy ? "healthy" : "unhealthy");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing getLanguages (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = getLanguages(pk, sk);
|
|
assert(result.length > 0, "Languages result should not be empty");
|
|
// Should contain python
|
|
assert(result.canFind("python"), "Languages should include python");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing validateKeysFn (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = validateKeysFn(pk, sk);
|
|
assert(result.length > 0, "Validate keys result should not be empty");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing execute (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = execute("python", "print('hello from d test')", pk, sk);
|
|
assert(result.length > 0, "Execute result should not be empty");
|
|
// Should contain output
|
|
assert(result.canFind("stdout") || result.canFind("output"), "Result should contain output");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing sessionList (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = sessionList(pk, sk);
|
|
assert(result.length > 0, "Session list result should not be empty");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing serviceListFn (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = serviceListFn(pk, sk);
|
|
assert(result.length > 0, "Service list result should not be empty");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing snapshotList (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = snapshotList(pk, sk);
|
|
assert(result.length > 0, "Snapshot list result should not be empty");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
unittest {
|
|
writeln("Testing imageList (functional)...");
|
|
if (!hasCredentials()) {
|
|
writeln(" SKIP (no credentials)");
|
|
return;
|
|
}
|
|
|
|
string pk = environment.get("UNSANDBOX_PUBLIC_KEY", "");
|
|
string sk = environment.get("UNSANDBOX_SECRET_KEY", "");
|
|
|
|
string result = imageList("", pk, sk);
|
|
assert(result.length > 0, "Image list result should not be empty");
|
|
writeln(" PASS");
|
|
}
|
|
|
|
void main() {
|
|
writeln("===== D SDK Tests Complete =====");
|
|
}
|