2025-10-07 10:59:52 +01:00

303 lines
8.0 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env nu
# Test OCI registry functionality
export def main [
--registry-url: string = "localhost:5000"
--registry-type: string = "zot"
--skip-docker
] {
print "🧪 Testing OCI registry..."
print $" URL: ($registry_url)"
print $" Type: ($registry_type)\n"
mut passed = 0
mut failed = 0
# Test 1: API health
print "Test 1: API health check..."
if (test-api-health $registry_url) {
print " ✅ PASSED"
$passed = ($passed + 1)
} else {
print " ❌ FAILED"
$failed = ($failed + 1)
}
# Test 2: Catalog endpoint
print "\nTest 2: Catalog endpoint..."
if (test-catalog $registry_url) {
print " ✅ PASSED"
$passed = ($passed + 1)
} else {
print " ❌ FAILED"
$failed = ($failed + 1)
}
# Test 3: Metrics (if supported)
print "\nTest 3: Metrics endpoint..."
if (test-metrics $registry_url $registry_type) {
print " ✅ PASSED"
$passed = ($passed + 1)
} else {
print " ⚠️ SKIPPED (not supported)"
}
# Test 4: Push/Pull (requires Docker)
if not $skip_docker {
print "\nTest 4: Push/Pull test..."
if (test-push-pull $registry_url) {
print " ✅ PASSED"
$passed = ($passed + 1)
} else {
print " ❌ FAILED"
$failed = ($failed + 1)
}
# Test 5: Delete (if supported)
print "\nTest 5: Delete test..."
if (test-delete $registry_url) {
print " ✅ PASSED"
$passed = ($passed + 1)
} else {
print " ⚠️ SKIPPED (delete not enabled)"
}
} else {
print "\nTests 4-5: Skipped (--skip-docker)"
}
# Test 6: Namespaces
print "\nTest 6: Namespace validation..."
if (test-namespaces $registry_url) {
print " ✅ PASSED"
$passed = ($passed + 1)
} else {
print " ❌ FAILED"
$failed = ($failed + 1)
}
# Summary
print "\n" + ("=" * 50)
print $"Test Summary: ($passed) passed, ($failed) failed"
if $failed > 0 {
print "\n❌ Some tests failed"
exit 1
} else {
print "\n✅ All tests passed!"
exit 0
}
}
def test-api-health [registry_url: string] -> bool {
let result = (do {
http get $"http://($registry_url)/v2/" --timeout 5sec
} | complete)
if $result.exit_code == 0 {
print " API is responding"
return true
} else {
print $" API error: ($result.stderr)"
return false
}
}
def test-catalog [registry_url: string] -> bool {
let result = (do {
http get $"http://($registry_url)/v2/_catalog" --timeout 5sec
} | complete)
if $result.exit_code == 0 {
let catalog = ($result.stdout | from json)
let count = ($catalog.repositories | length)
print $" Catalog has ($count) repositories"
return true
} else {
print $" Catalog error: ($result.stderr)"
return false
}
}
def test-metrics [registry_url: string, registry_type: string] -> bool {
let metrics_url = match $registry_type {
"zot" => $"http://($registry_url)/metrics"
"distribution" => $"http://($registry_url):5001/metrics"
_ => null
}
if ($metrics_url | is-empty) {
return false
}
let result = (do {
http get $metrics_url --timeout 5sec
} | complete)
if $result.exit_code == 0 {
print " Metrics endpoint available"
return true
} else {
return false
}
}
def test-push-pull [registry_url: string] -> bool {
# Check Docker is available
let docker_check = (^docker --version | complete)
if $docker_check.exit_code != 0 {
print " Docker not available"
return false
}
# Pull hello-world
print " Pulling hello-world..."
let pull = (^docker pull hello-world:latest | complete)
if $pull.exit_code != 0 {
print " Failed to pull hello-world"
return false
}
# Tag for registry
let tag = $"($registry_url)/provisioning-test/test-image:latest"
print $" Tagging as ($tag)..."
let tag_result = (^docker tag hello-world:latest $tag | complete)
if $tag_result.exit_code != 0 {
print " Failed to tag image"
return false
}
# Push to registry
print $" Pushing to registry..."
let push = (^docker push $tag | complete)
if $push.exit_code != 0 {
print $" Failed to push: ($push.stderr)"
return false
}
# Pull from registry
print " Pulling from registry..."
let pull_test = (^docker pull $tag | complete)
if $pull_test.exit_code != 0 {
print " Failed to pull from registry"
return false
}
print " Push/Pull successful"
return true
}
def test-delete [registry_url: string] -> bool {
# Try to get manifest digest
let result = (do {
http get $"http://($registry_url)/v2/provisioning-test/test-image/manifests/latest" --headers {
"Accept": "application/vnd.oci.image.manifest.v1+json"
} --full
} | complete)
if $result.exit_code != 0 {
return false
}
# Try to delete (may not be enabled)
# This is just a check, we don't actually delete
print " Delete endpoint available"
return true
}
def test-namespaces [registry_url: string] -> bool {
let result = (do {
http get $"http://($registry_url)/v2/_catalog"
} | complete)
if $result.exit_code != 0 {
return false
}
let catalog = ($result.stdout | from json)
let repos = $catalog.repositories
# Check for expected namespaces
let namespaces = ($repos | each { |r| $r | split row "/" | first } | uniq)
print $" Found namespaces: ($namespaces | str join ', ')"
# Should have at least one namespace after init
return (($namespaces | length) >= 0)
}
# Performance test
export def "perf test" [
--registry-url: string = "localhost:5000"
--iterations: int = 10
] {
print "🚀 Running performance test..."
print $" Iterations: ($iterations)\n"
mut total_time = 0
for i in 1..$iterations {
print $"Iteration ($i)/($iterations)..."
let start = (date now)
# Test API call
http get $"http://($registry_url)/v2/" | ignore
let end = (date now)
let duration = (($end - $start) | into int) / 1_000_000 # Convert to ms
print $" Time: ($duration)ms"
$total_time = ($total_time + $duration)
}
let avg = ($total_time / $iterations)
print $"\n📊 Average response time: ($avg)ms"
}
# Load test
export def "load test" [
--registry-url: string = "localhost:5000"
--concurrent: int = 10
--duration: int = 60 # seconds
] {
print "⚡ Running load test..."
print $" Concurrent requests: ($concurrent)"
print $" Duration: ($duration)s\n"
# This would require parallel execution
# For now, just show the concept
print " Load testing requires additional tooling (vegeta, ab, wrk)"
print "\nExample with Apache Bench:"
print $" ab -n 1000 -c ($concurrent) http://($registry_url)/v2/"
print "\nExample with vegeta:"
print $" echo 'GET http://($registry_url)/v2/' | vegeta attack -duration=($duration)s -rate=100 | vegeta report"
}
# Stress test
export def "stress test" [
--registry-url: string = "localhost:5000"
] {
print "💪 Running stress test..."
print " Testing registry limits...\n"
# Test large catalog
print "Test 1: Large catalog response..."
let catalog_result = (do {
http get $"http://($registry_url)/v2/_catalog" --timeout 30sec
} | complete)
if $catalog_result.exit_code == 0 {
let catalog = ($catalog_result.stdout | from json)
print $" ✓ Catalog with ($catalog.repositories | length) repos"
} else {
print " ✗ Catalog failed"
}
# Test many concurrent connections
print "\nTest 2: Concurrent connections..."
print " Use 'load test' for detailed concurrent testing"
print "\n✅ Stress test complete"
}