Unit test dengan mock sering kali memberikan rasa aman palsu. Test suite berstatus hijau (passing) padahal implementasi dependensi upstream telah mengubah struktur response payload, tipe data, atau status code. Masalah integrasi ini baru terungkap ketika kode masuk ke production runtime dan memicu runtime error masif.
Pendekatan efektif untuk memitigasi risiko ini adalah synthetic canary deployment. Pola ini membatasi rilis baru ke sebagian kecil infrastruktur, mengeksekusi uji verifikasi sintetis terhadap endpoint live, memantau metrik kegagalan secara real-time, lalu mengeksekusi automated rollback sebelum memengaruhi seluruh pengguna.
Anatomi Masalah: Mengapa Mock Menipu Pipeline CI
Mock menggantikan dependency eksternal dengan asumsi statis. Ketika downstream service mengasumsikan upstream mengembalikan integer ID 101, tetapi pembaruan upstream mengubah field tersebut menjadi string UUID "usr_abc123", unit test bermock downstream tetap valid. Test runner memvalidasi mock against mock logic, bukan API contract sesungguhnya.
Ketika kode dideploy langsung ke seluruh instans, error parsing JSON atau null pointer reference terjadi seketika di level user-facing. Canary release membatasi radius ledakan (blast radius) hingga di bawah 10% dari total traffic.
Arsitektur Synthetic Canary Deployment
Arsitektur implementasi membutuhkan tiga komponen utama:
- Traffic Ingress/Routing: Memisahkan traffic antara baseline (versi lama yang stabil) dan canary (versi baru) menggunakan weight-based routing.
- Synthetic Verification Runner: Task CI/CD atau standalone runner yang mengirimkan controlled synthetic request khusus bertanda HTTP header unik ke canary target.
- Prometheus/Metric Collector & Rollback Controller: Mengukur failure rate (HTTP 4xx non-auth dan 5xx) serta memicu deployment abort jika threshold terlampaui.
Implementasi Skrip Synthetic Verification
Skrip berikut dijalankan segera setelah pod canary ready. Skrip memverifikasi payload response nyata terhadap skema minimum yang diharapkan tanpa mengotori database operasional.
#!/usr/bin/env python3
import sys
import json
import urllib.request
import urllib.error
CANARY_URL = "https://canary-internal.service.local/api/v1/orders/health-probe"
EXPECTED_SCHEMA_KEYS = {"id", "status", "items", "total_amount"}
def run_synthetic_probe():
req = urllib.request.Request(
CANARY_URL,
headers={
"User-Agent": "SyntheticProbe/1.0",
"X-Canary-Probe": "true",
"Accept": "application/json"
}
)
try:
with urllib.request.urlopen(req, timeout=5) as response:
if response.status != 200:
print(f"FAIL: HTTP status code is {response.status}")
sys.exit(1)
payload = json.loads(response.read().decode("utf-8"))
# Validasi contract payload
missing_keys = EXPECTED_SCHEMA_KEYS - payload.keys()
if missing_keys:
print(f"FAIL: Contract mismatch. Missing keys: {missing_keys}")
sys.exit(1)
if not isinstance(payload["items"], list):
print(f"FAIL: 'items' expected list, got {type(payload['items']).__name__}")
sys.exit(1)
print("SUCCESS: Canary synthetic verification passed.")
sys.exit(0)
except urllib.error.HTTPError as e:
print(f"FAIL: Synthetic probe returned HTTP {e.code}: {e.reason}")
sys.exit(1)
except Exception as e:
print(f"FAIL: Network error or malformed JSON: {e}")
sys.exit(1)
if __name__ == "__main__":
run_synthetic_probe()
Konfigurasi Automated Rollback dengan Argo Rollouts
Konfigurasi Kubernetes Rollout di bawah membatasi alokasi canary hingga 10%, memanggil Webhook sintetis, dan menganalisis error rate via Prometheus. Jika error HTTP 5xx melebihi 1%, proses otomatis dibatalkan.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: order-service
spec:
replicas: 10
strategy:
canary:
analysis:
templates:
- templateName: canary-error-rate-check
args:
- name: service-name
value: order-service-canary
steps:
- setWeight: 10
- pause: { duration: 3m }
- setWeight: 50
- pause: { duration: 5m }
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: canary-error-rate-check
spec:
metrics:
- name: error-rate
interval: 30s
failureLimit: 2
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="order-service-canary",status=~"5.*"}[1m]))
/
sum(rate(http_requests_total{service="order-service-canary"}[1m])) * 100
successCondition: result[0] < 1.0
Observabilitas: Metrik yang Wajib Dipantau
Saat canary berlangsung, fokus monitoring diarahkan ke dua indikator utama:
- Unexpected HTTP 4xx: Peningkatan drastis HTTP 400 Bad Request atau 422 Unprocessable Entity mengindikasikan contract parsing issue antara payload baru dan validasi client.
- HTTP 5xx Rate: Mengindikasikan unhandled exception akibat perubahan contract yang tidak dikenali runtime code.
- Synthetic Run Metric: Metrik dedicated (counter kegagalan probe) untuk mendeteksi mismatch sebelum user traffic normal masuk ke canary pod.
Mitigasi Jangka Panjang: Contract Testing
Meskipun canary deployment mengamankan runtime, pencegahan tetap harus bergeser ke kiri (shift-left). Terapkan Consumer-Driven Contract Testing menggunakan kakas berikut:
- Pact: Consumer mendefinisikan ekspektasi request/response, menghasilkan kontrak JSON, yang kemudian diverifikasi otomatis terhadap API provider di CI pipeline provider.
- Schemathesis: Menggunakan spesifikasi OpenAPI/Swagger untuk menghasilkan property-based testing otomatis guna menemukan edge-case respons yang tidak sesuai schema.
Catatan Operasional: Pastikan synthetic probe request diberi bypass atau mock token pada layer database transaksi agar tidak memproduksi data sampah (ghost records) di tabel accounting atau analitik produksi.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!