#!/usr/bin/env nu # Integration tests for AWS API client with mocked responses def test-result [ name: string result: bool ] { if $result { print $"✓ ($name)" } else { print $"✗ ($name)" } $result } def load-mock-responses [] { open ($env.PROVISIONING)/extensions/providers/aws/tests/mocks/mock_api_responses.json } # Test: Describe instances returns list def test-describe-instances-returns-list [] { let mocks = (load-mock-responses) let response = $mocks.describe_instances_list let test1 = (test-result "API: describe-instances returns list" ($response | get -o Reservations | is-not-empty)) let test2 = (test-result "API: Reservations array present" (($response | get -o Reservations | length) > 0)) $test1 and $test2 } # Test: Single instance response structure def test-single-instance-response [] { let mocks = (load-mock-responses) let response = $mocks.describe_instances_single let instance = ($response.Reservations | get -o 0 | get -o Instances | get -o 0) let test1 = (test-result "API: Instance has InstanceId" ($instance | get -o InstanceId | is-not-empty)) let test2 = (test-result "API: Instance has InstanceType" ($instance | get -o InstanceType | is-not-empty)) let test3 = (test-result "API: Instance has State" ($instance | get -o State | is-not-empty)) let test4 = (test-result "API: Instance has PrivateIpAddress" ($instance | get -o PrivateIpAddress | is-not-empty)) $test1 and $test2 and $test3 and $test4 } # Test: Volumes list response def test-describe-volumes-list [] { let mocks = (load-mock-responses) let response = $mocks.describe_volumes_list let test1 = (test-result "API: describe-volumes returns list" ($response | get -o Volumes | is-not-empty)) let test2 = (test-result "API: Volumes array has entries" (($response | get -o Volumes | length) > 0)) $test1 and $test2 } # Test: Volume response structure def test-volume-response-structure [] { let mocks = (load-mock-responses) let response = $mocks.describe_volumes_single let volume = ($response.Volumes | get -o 0) let test1 = (test-result "API: Volume has VolumeId" ($volume | get -o VolumeId | is-not-empty)) let test2 = (test-result "API: Volume has Size" ($volume | get -o Size | is-not-empty)) let test3 = (test-result "API: Volume has State" ($volume | get -o State | is-not-empty)) let test4 = (test-result "API: Volume has AvailabilityZone" ($volume | get -o AvailabilityZone | is-not-empty)) $test1 and $test2 and $test3 and $test4 } # Test: Create instance response def test-create-instance-response [] { let mocks = (load-mock-responses) let response = $mocks.create_instance_response let instance = ($response.Instances | get -o 0) let test1 = (test-result "API: Created instance has InstanceId" ($instance | get -o InstanceId | is-not-empty)) let test2 = (test-result "API: Created instance in pending state" (($instance | get -o State | get -o Name) == "pending")) $test1 and $test2 } # Test: Instance type information def test-describe-instance-types [] { let mocks = (load-mock-responses) let response = $mocks.describe_instance_types let test1 = (test-result "API: Instance types list present" ($response | get -o InstanceTypes | is-not-empty)) let test2 = (test-result "API: t3.micro has vCPU info" (($response.InstanceTypes | where {|it| $it.InstanceType == "t3.micro"} | length) > 0)) $test1 and $test2 } # Test: Error 401 Unauthorized def test-error-401-unauthorized [] { let mocks = (load-mock-responses) let response = $mocks.error_401 let test1 = (test-result "API: Error 401 has Code field" ($response | get -o Error | get -o Code | is-not-empty)) let test2 = (test-result "API: Error 401 code is UnauthorizedOperation" (($response.Error | get -o Code) == "UnauthorizedOperation")) $test1 and $test2 } # Test: Error 404 Not Found def test-error-404-not-found [] { let mocks = (load-mock-responses) let response = $mocks.error_404 let test1 = (test-result "API: Error 404 has Code field" ($response | get -o Error | get -o Code | is-not-empty)) let test2 = (test-result "API: Error 404 references InvalidInstanceID" (($response.Error | get -o Code) == "InvalidInstanceID.NotFound")) $test1 and $test2 } # Test: Error 429 Rate Limit def test-error-429-rate-limit [] { let mocks = (load-mock-responses) let response = $mocks.error_429 let test1 = (test-result "API: Error 429 has Code field" ($response | get -o Error | get -o Code | is-not-empty)) let test2 = (test-result "API: Error 429 is RequestLimitExceeded" (($response.Error | get -o Code) == "RequestLimitExceeded")) $test1 and $test2 } # Test: Instance state validation def test-instance-state-validation [] { let mocks = (load-mock-responses) let instances = ($mocks.describe_instances_list.Reservations | each {|r| $r.Instances} | flatten) let running_count = ($instances | where {|i| ($i.State | get -o Name) == "running"} | length) let stopped_count = ($instances | where {|i| ($i.State | get -o Name) == "stopped"} | length) let test1 = (test-result "API: Response contains running instance" ($running_count > 0)) let test2 = (test-result "API: Response contains stopped instance" ($stopped_count > 0)) $test1 and $test2 } # Test: Key pair information def test-describe-key-pairs [] { let mocks = (load-mock-responses) let response = $mocks.describe_key_pairs let test1 = (test-result "API: Key pairs list present" ($response | get -o KeyPairs | is-not-empty)) let test2 = (test-result "API: Key pair has KeyName" (($response.KeyPairs | get -o 0 | get -o KeyName) == "aws-default")) $test1 and $test2 } # Test: Pricing data structure def test-pricing-data-structure [] { let mocks = (load-mock-responses) let pricing = ($mocks.pricing_data | get -o 0) let test1 = (test-result "API: Pricing has InstanceType" ($pricing | get -o InstanceType | is-not-empty)) let test2 = (test-result "API: Pricing has OnDemand rate" ($pricing | get -o Pricing | get -o OnDemand | is-not-empty)) let test3 = (test-result "API: Pricing has vCPU info" ($pricing | get -o VCpu | is-not-empty)) $test1 and $test2 and $test3 } # Test: Attachment information def test-volume-attachment-info [] { let mocks = (load-mock-responses) let volume = ($mocks.describe_volumes_single.Volumes | get -o 0) let attachment = ($volume.Attachments | get -o 0) let test1 = (test-result "API: Attachment has InstanceId" ($attachment | get -o InstanceId | is-not-empty)) let test2 = (test-result "API: Attachment has Device path" ($attachment | get -o Device | is-not-empty)) $test1 and $test2 } # Main test execution def main [] { print "=== AWS API Client Integration Tests ===" print "" let results = [ (test-describe-instances-returns-list), (test-single-instance-response), (test-describe-volumes-list), (test-volume-response-structure), (test-create-instance-response), (test-describe-instance-types), (test-error-401-unauthorized), (test-error-404-not-found), (test-error-429-rate-limit), (test-instance-state-validation), (test-describe-key-pairs), (test-pricing-data-structure), (test-volume-attachment-info) ] let passed = ($results | where {|it| $it == true} | length) let failed = ($results | where {|it| $it == false} | length) print "" print $"Test Results: ($passed) passed, ($failed) failed" { passed: $passed, failed: $failed, total: ($passed + $failed) } } main