provisioning-catalog/providers/hetzner/tests/integration/test_pricing_cache.nu

237 lines
6.9 KiB
Text
Raw Normal View History

#!/usr/bin/env nu
# Hetzner provider pricing and cache integration tests (with mocks)
# Load mock responses
def load-mock-responses []: nothing -> record {
let mocks = (open ../../tests/mocks/mock_api_responses.json)
$mocks
}
# Mock: get pricing data
def mock-get-pricing []: nothing -> record {
let mocks = (load-mock-responses)
{server_types: $mocks.server_types_list.server_types}
}
# Mock: cache operations
def mock-create-cache-entry [server: string]: nothing -> record {
{
server: $server
timestamp: (now)
cached_at: (date now | date to-record)
}
}
def mock-read-cache-entry [server: string]: nothing -> record {
{
server: $server
timestamp: (now)
cached_at: (date now | date to-record)
}
}
# Test framework
def test-result [name: string, passed: bool]: nothing -> record {
if $passed {
print $"✓ ($name)"
} else {
print $"✗ ($name)"
}
{name: $name, passed: $passed}
}
# Test: Get pricing data
def test_get_pricing_data []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
($pricing | has server_types)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "get_pricing: returns pricing data" $passed
}
# Test: Server type pricing structure
def test_server_type_pricing_structure []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
let st = ($pricing.server_types | first)
{
has_name: ($st | has name)
has_cores: ($st | has cores)
has_prices: ($st | has prices)
}
} | complete)
let passed = ($result.exit_code == 0 and
$result.stdout.has_name and
$result.stdout.has_cores and
$result.stdout.has_prices)
test-result "pricing: server type structure" $passed
}
# Test: Pricing hourly rate exists
def test_pricing_hourly_rate []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
let st = ($pricing.server_types | first)
let price = ($st.prices | first)
($price | has price_hourly)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "pricing: hourly rate field" $passed
}
# Test: Pricing monthly rate exists
def test_pricing_monthly_rate []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
let st = ($pricing.server_types | first)
let price = ($st.prices | first)
($price | has price_monthly)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "pricing: monthly rate field" $passed
}
# Test: Create cache entry
def test_create_cache_entry []: nothing -> record {
let result = (do {
let cache = (mock-create-cache-entry "test-server")
{
has_server: ($cache | has server)
has_timestamp: ($cache | has timestamp)
}
} | complete)
let passed = ($result.exit_code == 0 and
$result.stdout.has_server and
$result.stdout.has_timestamp)
test-result "cache: create entry structure" $passed
}
# Test: Read cache entry
def test_read_cache_entry []: nothing -> record {
let result = (do {
let cache = (mock-read-cache-entry "test-server")
$cache.server
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout == "test-server")
test-result "cache: read entry" $passed
}
# Test: Cache timestamp is valid
def test_cache_timestamp_valid []: nothing -> record {
let result = (do {
let cache = (mock-create-cache-entry "test-server")
($cache.timestamp | describe) =~ "int"
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "cache: timestamp is integer" $passed
}
# Test: Price with net and gross
def test_price_net_and_gross []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
let st = ($pricing.server_types | first)
let price = ($st.prices | first)
let hourly = $price.price_hourly
{
has_net: ($hourly | has net)
has_gross: ($hourly | has gross)
}
} | complete)
let passed = ($result.exit_code == 0 and
$result.stdout.has_net and
$result.stdout.has_gross)
test-result "pricing: net and gross prices" $passed
}
# Test: Multiple server types pricing
def test_multiple_server_types []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
($pricing.server_types | length)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout > 1)
test-result "pricing: multiple server types" $passed
}
# Test: Cache entry contains server name
def test_cache_server_name []: nothing -> record {
let result = (do {
let cache = (mock-create-cache-entry "my-production-server")
$cache.server == "my-production-server"
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "cache: preserves server name" $passed
}
# Test: Calculate pricing per GB
def test_pricing_per_gb []: nothing -> record {
let result = (do {
# Volume pricing: 0.085 EUR per GB per month
let volume_gb = 100
let volume_price = $volume_gb * 0.085
$volume_price > 0
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "pricing: volume per GB calculation" $passed
}
# Test: Server type names available
def test_server_type_names []: nothing -> record {
let result = (do {
let pricing = (mock-get-pricing)
let names = ($pricing.server_types | map {|st| $st.name})
("cx11" in $names) and ("cx21" in $names)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "pricing: standard server types available" $passed
}
# Main test runner
def main []: nothing -> record {
print "=== Hetzner Pricing & Cache Integration Tests (Mock Mode) ==="
print ""
let results = [
(test_get_pricing_data)
(test_server_type_pricing_structure)
(test_pricing_hourly_rate)
(test_pricing_monthly_rate)
(test_create_cache_entry)
(test_read_cache_entry)
(test_cache_timestamp_valid)
(test_price_net_and_gross)
(test_multiple_server_types)
(test_cache_server_name)
(test_pricing_per_gb)
(test_server_type_names)
]
print ""
print "Test Summary:"
print "============="
let passed = ($results | where {|r| $r.passed} | length)
let failed = ($results | where {|r| not $r.passed} | length)
let total = ($results | length)
print $"Passed: ($passed)/$total"
print $"Failed: ($failed)/$total"
{passed: $passed, failed: $failed, total: $total}
}