#!/usr/bin/env nu # Test provisioning plugins are installed and working # # This script verifies that the three critical provisioning plugins # are properly installed, registered, and functional. # # Usage: # nu test-plugins.nu # Run all tests # nu test-plugins.nu --quick # Quick registration check only # nu test-plugins.nu --verbose # Detailed output # nu test-plugins.nu --json # Output as JSON const PROVISIONING_PLUGINS = [ { name: "nu_plugin_auth" test_command: "auth verify --local" expected_fields: ["valid"] description: "JWT authentication with system keyring" } { name: "nu_plugin_kms" test_command: "kms status" expected_fields: ["backend", "available"] description: "Multi-backend KMS encryption" } { name: "nu_plugin_orchestrator" test_command: "orch status" expected_fields: ["running", "tasks_pending"] description: "Local orchestrator operations" } ] # Check if plugin is registered def check-registration [plugin_name: string]: nothing -> record { let registered_plugins = (plugin list | get name?) if ($registered_plugins == null) { return { name: $plugin_name registered: false message: "Could not query plugin list" } } let is_registered = $plugin_name in $registered_plugins { name: $plugin_name registered: $is_registered message: (if $is_registered { "Registered" } else { "Not registered" }) } } # Test plugin functionality def test-plugin-function [ plugin_name: string test_command: string expected_fields: list ]: nothing -> record { let start_time = (date now) try { # Execute the test command let result = (nu -c $test_command | from json) let duration = ((date now) - $start_time) | into int | $in / 1_000_000 # Check if expected fields exist let missing_fields = ($expected_fields | where { |field| not ($field in ($result | columns)) }) if ($missing_fields | length) > 0 { return { name: $plugin_name functional: false message: $"Missing fields: ($missing_fields | str join ', ')" duration_ms: $duration } } { name: $plugin_name functional: true message: "Commands working" duration_ms: $duration result: $result } } catch { |err| let duration = ((date now) - $start_time) | into int | $in / 1_000_000 # Some commands might return errors but still work (e.g., no token) # This is expected behavior, not a failure if ($err.msg | str contains "not logged in") or ($err.msg | str contains "token not found") or ($err.msg | str contains "No sessions") { return { name: $plugin_name functional: true message: "Commands working (expected auth state)" duration_ms: $duration } } { name: $plugin_name functional: false message: $"Error: ($err.msg)" duration_ms: $duration } } } # Run all tests def run-tests [ --quick: bool = false --verbose: bool = false ]: nothing -> list { mut results = [] for plugin in $PROVISIONING_PLUGINS { # Registration check let reg_result = (check-registration $plugin.name) $results = ($results | append { plugin: $plugin.name test: "registration" passed: $reg_result.registered message: $reg_result.message duration_ms: 0 }) if $verbose { let status = if $reg_result.registered { "[PASS]" } else { "[FAIL]" } print $"($status) ($plugin.name) - Registration: ($reg_result.message)" } # Skip functional tests if quick mode or not registered if $quick or (not $reg_result.registered) { continue } # Functional test let func_result = (test-plugin-function $plugin.name $plugin.test_command $plugin.expected_fields) $results = ($results | append { plugin: $plugin.name test: "functional" passed: $func_result.functional message: $func_result.message duration_ms: $func_result.duration_ms }) if $verbose { let status = if $func_result.functional { "[PASS]" } else { "[FAIL]" } print $"($status) ($plugin.name) - Functional: ($func_result.message) \(($func_result.duration_ms)ms\)" } } $results } # Main entry point def main [ --quick (-q) # Quick registration check only --verbose (-v) # Detailed output --json (-j) # Output as JSON ]: nothing -> nothing { if not $json { print "" print "======================================================" print " Provisioning Plugins Test Suite" print "======================================================" print "" } let results = (run-tests --quick=$quick --verbose=$verbose) # Calculate summary let total_tests = ($results | length) let passed_tests = ($results | where passed == true | length) let failed_tests = ($results | where passed == false | length) # Registration summary let reg_results = ($results | where test == "registration") let reg_passed = ($reg_results | where passed == true | length) let reg_total = ($reg_results | length) # Functional summary let func_results = ($results | where test == "functional") let func_passed = ($func_results | where passed == true | length) let func_total = ($func_results | length) if $json { # JSON output { total: $total_tests passed: $passed_tests failed: $failed_tests registration: { total: $reg_total passed: $reg_passed } functional: { total: $func_total passed: $func_passed } results: $results all_passed: ($failed_tests == 0) } | to json } else { # Human-readable output if not $verbose { # Print results table print "Test Results:" print "" for result in $results { let status = if $result.passed { "[OK] " } else { "[FAIL]" } let test_type = if $result.test == "registration" { "reg" } else { "func" } let duration = if $result.duration_ms > 0 { $" \(($result.duration_ms)ms\)" } else { "" } print $" ($status) ($result.plugin | fill -w 25) ($test_type | fill -w 5) ($result.message)($duration)" } } print "" print "------------------------------------------------------" print "Summary:" print $" Registration: ($reg_passed)/($reg_total) passed" if not $quick { print $" Functional: ($func_passed)/($func_total) passed" } print $" Total: ($passed_tests)/($total_tests) passed" print "------------------------------------------------------" print "" if $failed_tests == 0 { print "All tests passed! Plugins are ready to use." } else { print $"($failed_tests) test\(s\) failed. Some plugins may need attention." print "" print "Troubleshooting:" print " 1. Build plugins: nu install-plugins.nu" print " 2. Register only: nu install-plugins.nu --skip-build" print " 3. Check plugin list: plugin list" } print "" } # Exit with error code if tests failed if $failed_tests > 0 { exit 1 } } # Export for module usage export def "provisioning-plugins test" [--quick (-q), --verbose (-v), --json (-j)] { main --quick=$quick --verbose=$verbose --json=$json }