303 lines
8.0 KiB
Plaintext
Raw Normal View History

2025-10-07 10:59:52 +01:00
#!/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"
}