# Solo Mode Integration Tests # Comprehensive tests for solo mode deployment use std log use ../framework/test_helpers.nu * use ../framework/orbstack_helpers.nu * # Main test suite export def main [] { log info "Running Solo Mode Integration Tests" let test_config = (load-test-config) # Setup solo mode environment log info "Setting up solo mode environment..." setup-solo-mode $test_config mut results = [] # Run all solo mode tests $results = ($results | append (test-minimal-services $test_config)) $results = ($results | append (test-single-user-operations $test_config)) $results = ($results | append (test-no-multiuser-services $test_config)) $results = ($results | append (test-workspace-creation $test_config)) $results = ($results | append (test-server-deployment-with-dns $test_config)) $results = ($results | append (test-taskserv-installation $test_config)) $results = ($results | append (test-extension-loading-from-oci $test_config)) $results = ($results | append (test-admin-permissions $test_config)) # Teardown log info "Tearing down solo mode environment..." teardown-solo-mode $test_config # Report results report-test-results $results } # Setup solo mode environment def setup-solo-mode [test_config: record] { # Deploy solo mode services nu provisioning/tests/integration/setup_test_environment.nu --mode solo } # Teardown solo mode environment def teardown-solo-mode [test_config: record] { nu provisioning/tests/integration/teardown_test_environment.nu --force } # Test 1: Verify minimal services running def test-minimal-services [test_config: record] { run-test "solo-mode-minimal-services" { log info "Testing minimal services in solo mode..." # Verify orchestrator is running assert-true (check-service-health "orchestrator") "Orchestrator should be running" # Verify CoreDNS is running assert-true (check-service-health "coredns") "CoreDNS should be running" # Verify OCI registry (Zot) is running let oci_url = $"http://($test_config.services.oci_registry.zot.host):($test_config.services.oci_registry.zot.port)/v2/" let response = (http get $oci_url) assert-http-success $response "OCI registry should be running" # Verify multi-user services are NOT running assert-false (check-service-health "gitea") "Gitea should NOT be running in solo mode" assert-false (check-service-health "postgres") "PostgreSQL should NOT be running in solo mode" log info "✓ Minimal services verified" } } # Test 2: Single user operations def test-single-user-operations [test_config: record] { run-test "solo-mode-single-user" { log info "Testing single user operations..." let orchestrator_url = $"http://($test_config.services.orchestrator.host):($test_config.services.orchestrator.port)" # All operations should work as admin user (no authentication required) let response = (http get $"($orchestrator_url)/tasks") assert-http-success $response "Task list should be accessible" log info "✓ Single user operations work" } } # Test 3: Verify no multi-user services def test-no-multiuser-services [test_config: record] { run-test "solo-mode-no-multiuser-services" { log info "Testing that multi-user services are absent..." # Attempt to connect to Gitea (should fail) let gitea_url = $"http://($test_config.services.gitea.host):($test_config.services.gitea.port)" try { http get $gitea_url error make { msg: "Gitea should not be accessible in solo mode" } } catch { # Expected to fail log info "✓ Gitea is not running (expected)" } # Attempt to connect to PostgreSQL (should fail) try { psql -h $test_config.services.postgres.host -p $test_config.services.postgres.port -U test -d test -c "SELECT 1" | complete error make { msg: "PostgreSQL should not be accessible in solo mode" } } catch { # Expected to fail log info "✓ PostgreSQL is not running (expected)" } log info "✓ Multi-user services are absent" } } # Test 4: Create workspace in solo mode def test-workspace-creation [test_config: record] { run-test "solo-mode-create-workspace" { log info "Testing workspace creation in solo mode..." let workspace = create-test-workspace "solo-test-ws" { provider: "local" environment: "test" } # Verify workspace directory structure assert-true ($"($workspace.path)/config" | path exists) "Config directory should exist" assert-true ($"($workspace.path)/infra" | path exists) "Infra directory should exist" assert-true ($"($workspace.path)/extensions" | path exists) "Extensions directory should exist" assert-true ($"($workspace.path)/runtime" | path exists) "Runtime directory should exist" # Verify workspace config let config = (open $"($workspace.path)/config/provisioning.yaml") assert-eq $config.workspace.name "solo-test-ws" "Workspace name should match" # Cleanup cleanup-test-workspace $workspace log info "✓ Workspace created successfully" } } # Test 5: Deploy server with auto-DNS registration def test-server-deployment-with-dns [test_config: record] { run-test "solo-mode-server-with-dns" { log info "Testing server deployment with DNS registration..." let orchestrator_url = $"http://($test_config.services.orchestrator.host):($test_config.services.orchestrator.port)" # Create server let server_name = "test-server-01" let create_response = (http post $"($orchestrator_url)/workflows/servers/create" { server: { hostname: $server_name provider: "local" cores: 2 memory: 4096 zone: "local" } check: true }) assert-http-success $create_response "Server creation should succeed" let task_id = $create_response.body.task_id # Wait for server creation to complete wait-for-condition --timeout 120 --interval 5 { let status_response = (http get $"($orchestrator_url)/tasks/($task_id)") $status_response.body.status == "completed" } "server creation to complete" # Verify DNS registration let dns_query = (dig @$test_config.services.coredns.host $"($server_name).local" +short) assert-not-empty $dns_query "DNS record should exist for server" log info $"✓ Server created with DNS: ($server_name).local → ($dns_query)" # Cleanup server delete-test-server $task_id } } # Test 6: Install taskserv (kubernetes) def test-taskserv-installation [test_config: record] { run-test "solo-mode-taskserv-installation" { log info "Testing taskserv installation..." let orchestrator_url = $"http://($test_config.services.orchestrator.host):($test_config.services.orchestrator.port)" # First, create a server let server_response = (http post $"($orchestrator_url)/workflows/servers/create" { server: { hostname: "taskserv-test" provider: "local" cores: 4 memory: 8192 } check: true }) let server_task_id = $server_response.body.task_id # Wait for server creation wait-for-condition --timeout 120 { let status = (http get $"($orchestrator_url)/tasks/($server_task_id)") $status.body.status == "completed" } "server creation" # Install kubernetes taskserv let taskserv_response = (http post $"($orchestrator_url)/workflows/taskserv/create" { taskserv: "kubernetes" server: "taskserv-test" check: true }) assert-http-success $taskserv_response "Taskserv installation should succeed" let taskserv_task_id = $taskserv_response.body.task_id # Wait for taskserv installation wait-for-condition --timeout 300 { let status = (http get $"($orchestrator_url)/tasks/($taskserv_task_id)") $status.body.status == "completed" } "taskserv installation" log info "✓ Taskserv installed successfully" # Cleanup delete-test-server $server_task_id } } # Test 7: Extension loading from local OCI def test-extension-loading-from-oci [test_config: record] { run-test "solo-mode-extension-loading-oci" { log info "Testing extension loading from OCI registry..." let oci_url = $"http://($test_config.services.oci_registry.zot.host):($test_config.services.oci_registry.zot.port)" # Push a test extension to OCI # Note: In real implementation, this would use `oras push` # For testing, we'll verify OCI registry is accessible let catalog_response = (http get $"($oci_url)/v2/_catalog") assert-http-success $catalog_response "OCI catalog should be accessible" log info "✓ OCI registry accessible for extension loading" } } # Test 8: Admin permissions (all operations allowed) def test-admin-permissions [test_config: record] { run-test "solo-mode-admin-permissions" { log info "Testing admin permissions in solo mode..." let orchestrator_url = $"http://($test_config.services.orchestrator.host):($test_config.services.orchestrator.port)" # In solo mode, all operations are allowed (single admin user) # Test: List tasks let tasks_response = (http get $"($orchestrator_url)/tasks") assert-http-success $tasks_response "Admin can list tasks" # Test: List servers let servers_response = (http get $"($orchestrator_url)/servers") assert-http-success $servers_response "Admin can list servers" # Test: Create workflow let workflow_response = (http post $"($orchestrator_url)/workflows/servers/create" { server: { hostname: "admin-test" provider: "local" } check: true }) assert-http-success $workflow_response "Admin can create workflows" log info "✓ Admin has full permissions in solo mode" } } # Report test results def report-test-results [results: list] { let total = ($results | length) let passed = ($results | where status == "passed" | length) let failed = ($results | where status == "failed" | length) log info "=========================================" log info "Solo Mode Test Results" log info "=========================================" log info $"Total: ($total)" log info $"Passed: ($passed)" log info $"Failed: ($failed)" log info "=========================================" if $failed > 0 { log error "Some tests failed:" $results | where status == "failed" | each { |test| log error $" - ($test.test_name): ($test.error_message)" } } $results }