Canlı bir backend ile test et

Özet

  • Bir canlı backend testi, aday component'i (veya model artifact'ini veya grafik değişikliğini) üretimin kullandığı aynı runtime üzerinde, etrafına sarılı bir I/O harness ile çalıştırır. Aday, üretim container ortamında, üretim tipli stream'ler üzerinde, sahte taşıma olmadan ve ayrı bir test SDK'sı olmadan çalışır.
  • Kanonik döngü manifest güdümlüdür: ppl lease run --test=<manifest> --runtime=<id> bir lease basar, çalışma dizininden bir prerelease yayınlar, yerel fixture'ları yükler, bir live-test olay akışı açar ve sonunda lease'i rollback yapar. ready'de 0, failed'de 1 ile çık.
  • Harness şekli, kenarlarda input_<format>_http / output_<format>_http component'leri olan girdi ⇒ CUT ⇒ çıktı'dır. Girdiler HTTP POST'tur; çıktılar WebSocket çerçeveleridir (serileştirilebilir tipler için JSON, medya için önce-metadata-sonra-ikili).
  • Bir lease temizleme kontratıdır: test backend'i, prerelease, geçici fixture'lar ve deployment'ın hepsi lease içinde yaşar ve lease kapandığında birlikte kaldırılır. TTL, test koşucusu erken çıksa bile yıkmayı garanti eder.
  • El yapımı yol (backend create / add-vertex / connect / change-parameter / deploy), manifest dilbilgisinin ifade edemediği durumları kapsar — tek seferlik grafikler, önceden var olan harness kombinasyonları, standart dışı test koşucuları.

Canlı backend testi nedir

Bir canlı backend testi, aday component'i üretimde çalışacağı runtime üzerinde, gerçek bir backend grafiği içinde, fixture'ların içeri akabilmesi ve sonuçların dışarı akabilmesi için etrafına sarılı bir I/O harness ile çalıştırır. Aday, üretimde gördüğü aynı container'lanmış ortamı, aynı tipli stream'leri ve aynı serving-service bağımlılıklarını görür. Harness component'leri (input_<format>_http, output_<format>_http) kendileri release edilmiş component'lerdir, dolayısıyla test yolu ve üretim yolu aynı yoldur.

Bu, hızlı geri bildirim ile gerçekçi bir ortam arasındaki olağan ödünleşmeden kaçınır. Sahte bir model, gerçek model hakkında hiçbir şey kanıtlamayan hızlı bir test verir; bir notebook'ta elle çalıştırılan bir model gerçekçidir ama hiçbir izolasyon, yeniden üretilebilirlik veya CI hikâyesi sunmaz; ayrı bir "test modu" SDK'sı zamanla üretimden uzaklaşır. Bir canlı backend testi, bunların hiçbiri olmadan gerçekçi ortamı korur.

lease, bunu bir CI deseni olarak pratik kılan şeydir. Test başına ayağa kaldırılan gerçek bir backend aksi takdirde sızıntı yapardı — backend, deployment ve geçici fixture'ların hepsi kalıcı olurdu ve her CI çalıştırması arkasında yetim bırakırdı. Bir lease içinde, tüm aparat birlikte kaldırılan tek bir sahipli kapsamdır, dolayısıyla test hem gerçekçi hem de temizdir.

Bunun arkasındaki sahiplik modeli için Lease'ler ve lease yaşam döngüsü'ne bak.

Harness şekli

fixture
   │
   ▼
input_<fmt>_http ──► CUT (component under test) ──► output_<fmt>_http
   (POST or WS)      (the candidate)                 (WS frames)

Harness, aday component'e gerçek bir girdi kaynağı ve gerçek bir çıktı sink'i verir, böylece test, üretimin yaptığı gibi tipli stream'leri çalıştırır. Input component'i bir HTTP isteği alır ve CUT'un girdi portuna tipli bir stream yayar. Output component'i CUT'un çıktı stream'ini tüketir ve onu testin okuyabileceği bir WebSocket çerçevesi olarak yayar.

Harness, normal bir backend üzerinde vertex'ler olarak eklenen iki normal release edilmiş component'tir — özel altyapı değil. Her uçtaki vertex'i değiştirerek farklı harness component'lerini (ses CUT'u için bir Input Audio HTTP, görüntü yayan bir CUT için bir Output Image HTTP) yer değiştirirsin. Şekil aynı kalır. output_type'sız bir CUT — log-message gibi bir sink — hâlâ canlı test edilebilirdir: harness tarafından okunabilir bir çerçeve üretmez, dolayısıyla bunun yerine container log'larına karşı assertion yaparsın.

Birini çalıştırmanın iki yolu

Aynı canlı teste iki yol vardır. Onu tekrarlayıp tekrarlamayacağına göre seç.

Manifest güdümlüBildirimsel ve tekrarlanabilir, ppl lease run --test ile sürülür. CI, regresyon paketleri, kanıt döngüleri ve sürüm karşılaştırmaları için buna başvur. Aşağıdaki Yol 1'de ayrıntılı.
El yapımı backendHam backend create / add-vertex / connect / deploy primitive'leri. Tek seferlik grafikler ve manifest dilbilgisinin ifade edemediği harness kombinasyonları için buna başvur. Aşağıdaki Yol 2'de ayrıntılı.

Yol 1 — manifest güdümlü (ppl lease run --test=…)

Bu yolu tekrarlamak istediğin her şey için kullan: CI, regresyon paketleri, kanıt döngüleri, sürüm karşılaştırmaları.

Manifest testi bildirimsel olarak tanımlar: adayın ne olduğu, hangi fixture'ları görmesi gerektiği, etrafını hangi grafiğin sardığı ve hangi çıktıların yakalanması gerektiği. CLI manifesti okur, gerekirse adayı yayınlar, yerel fixture'ları yükler, live-test olay akışını açar ve test bir terminal duruma ulaşana kadar sunucu olaylarını NDJSON olarak yayar.

ppl lease run --test=tests/live-test.yml --runtime=<runtime_id>

CLI sırasıyla beş şey yapar, hepsi manifestten türetilmiştir: ayrıştır, opsiyonel olarak CUT prerelease'ini çalışma dizininden yayınla, herhangi bir yerel-path fixture'ını önceden yükle (manifest girdilerini file_id'ye yeniden yazarak), live-test akışını aç ve her sunucu olayını stdout'ta tek bir NDJSON satırı olarak yay. Çıkış kodu ready'de 0 ve failed veya taşıma kapanışında 1'dir; bu, bir CI adımının ihtiyaç duyduğu kontrattır.

--cut-version-id, cwd'den bir tane yayınlamak yerine testi belirli bir prerelease'e yönlendirir. --label lease etiketini ayarlar (sonraki toplu temizlik için kullanılır). --ttl lease'in ömrünü cap'ler (sunucu bir default artı sabit bir cap uygular). Çalıştırma çıktığında lease her zaman rollback yapar; bir deployment'ı inceleme için ayakta tutmak istersen ppl lease test kullan, o da sen rollback yapana dek onu lease üzerinde çalışır bırakır.

Manifest

Manifest, tüm çalıştırmanın bildirimsel bir tanımıdır. vertices bölümü kenarlardaki harness component'lerini adlandırır ve CUT vertex'ini işaretsiz bırakır — harness'sız bir vertex CUT'tur. edges bölümü onları bağlar. Fixture'lar isimle iliştirilir ve path / url / file_id'den tam olarak birine çözümlenir. secret'lar workspace secret'larını vertex parametrelerine bağlar. output files, platformun yıkma sırasında hangi üretilen dosyaları workspace'e kaydetmesi gerektiğini beyan eder.

release:  auto: true                    # CLI publishes a prerelease from cwddeploy:  fixed_duration: 10m           # Pin deployment lifetime (Go duration)  lease_ttl: 30m                # Whole-lease TTL (server caps)fixtures:  - {name: dog, path: ./tests/dog.jpg}secrets:  - {vertex: cut, key: HF_TOKEN, workspace_secret: hf_token}graph:  vertices:    in:  {harness: "Input Image HTTP"}    cut: {params: {model_cfg: {type: String, value: '"fastvit_t8"'}}}    out: {harness: "Output JSON HTTP"}  edges:    - {from: in,  from_output: 0, to: cut, to_input: 0}    - {from: cut, from_output: 0, to: out, to_input: 0}output_files:  - {name: report, vertex: cut, key: report.json}

Olay akışı

Sunucu, test kurulumunun her adımını live-test akışı üzerinden raporlar. Her olay bir type alanı olan bir JSON nesnesidir; CLI onları aynen, satır başına bir tane yazdırır.

typeAnlamı
lease_createdSunucu bu çalıştırma için bir lease bastı.
fixture_fetchedHer URL modu fixture için bir tane.
backend_createdSunucu bir backend id atadı.
vertex_addedHer vertex için bir tane; sunucu tarafından atanan vertex_id'yi taşır.
edge_connectedHer kenar için bir tane.
param_setAyarlanan her vertex parametresi için bir tane.
file_boundHer vertex dosya bağlaması için bir tane.
deploy_starteddeployment id basıldı.
containerAyağa kaldırılan her container için bir tane.
readyTerminal başarı. CLI 0 ile çıkar.
failedTerminal başarısızlık. Payload {stage, error, debug_bundle?}. CLI 1 ile çıkar.

Akış test kurulumunu kapsar; fixture-içeri / sonuç-dışarı alışverişi ready sonrası forward edilen endpoint'lere karşı gerçekleşir. Assertion'larını her vertex_added olayında taşınan sunucu tarafından atanan vertex_id'ye geri eşle.

Yol 2 — el yapımı backend

Bu yolu, manifest dilbilgisi testi tanımlayamadığında kullan: tek seferlik grafikler, şemanın kapsamadığı harness kombinasyonları veya manifest akışının gömmediği bir koşucuda yazılmış sürücüler.

El yapımı yol, platformun dahili olarak kullandığı aynı CLI primitive'lerini kullanır: bir backend oluştur, input / CUT / output vertex'lerini ekle, portlarını bağla, CUT'un ihtiyaç duyduğu parametreleri bağla ve deploy et.

PID=$(ppl backend create --name "live test $(date +%s)" | jq -r .data.backend_id)# component versions returns a bare JSON array (no {count, items} envelope):INPUT_V=$(ppl component versions <input_component_id>  | jq -r '.[] | select(.tags[]? == "latest") | .id')CUT_V=$(ppl component versions <cut_component_id>      | jq -r '.[] | select(.tags[]? == "latest") | .id')OUTPUT_V=$(ppl component versions <output_component_id> | jq -r '.[] | select(.tags[]? == "latest") | .id')# add-vertex has no vertex-id flag — the server assigns it and returns# it in .data.vertex_id. Capture each id for the connect calls.IN=$(ppl  backend add-vertex $PID --version $INPUT_V  --alias in  | jq -r .data.vertex_id)CUT=$(ppl backend add-vertex $PID --version $CUT_V    --alias cut | jq -r .data.vertex_id)OUT=$(ppl backend add-vertex $PID --version $OUTPUT_V --alias out | jq -r .data.vertex_id)ppl backend connect $PID --from-vertex $IN  --from-output 0 --to-vertex $CUT --to-input 0ppl backend connect $PID --from-vertex $CUT --from-output 0 --to-vertex $OUT --to-input 0ppl backend change-parameter $PID --vertex $CUT --name model_cfg \    --type String --value '"fastvit_t8"'ppl backend deploy --runtime <runtime_id> --backend $PID

Bu fiiller bir lease'e iliştirilmez — yalnızca manifest güdümlü lease run yolu backend'i, prerelease'i, fixture'ları ve deployment'ı birlikte rollback yapan tek bir lease-sahipli kapsam olarak damgalar. Dolayısıyla yukarıdaki el yapımı dizi, kaynakları elle attığın (ppl backend undeploy --backend $PID, ardından ppl backend delete $PID) tek seferlik keşif için olan biçimdir. Otomatik temizlemeli tekrarlanabilir bir CI döngüsü için Yol 1'i kullan.

Harness'ı seçme

Her taraftaki harness, CUT'un I/O tipiyle eşleşmek zorundadır:

CUT girdi tipiHarness ingress
ImageInput Image HTTP (çıktı 0 = Image)
AudioFrameInput Audio HTTP
TensorInput NumPy HTTP
serileştirilebilir herhangi bir şeyInput JSON HTTP (çıktı 0 = t)
CUT çıktı tipiHarness egress
ImageOutput Image HTTP
Polygon<Double>Output JSON HTTP
[BoundingBox]Output JSON HTTP
genel herhangi bir şeyOutput JSON HTTP

Output JSON HTTP default egress'tir: herhangi bir backend-tipli mesajı kabul eder ve onu WebSocket üzerinde JSON'a serileştirir; bu, testlerde en kolay assertion yapılan şekildir. CUT bir Image yaydığında ve ham baytları istediğinde Output Image HTTP'yi (önce-metadata-sonra-ikili çerçeve protokolü) kullan.

Harness component'lerini sorguyla keşfet — yalın list sınırı 20 kayıttır ve --query bunun ötesinde arar:

ppl component list --query=Inputppl component list --query=Output

Testi sürme

deploy sonrası, endpoint URL'lerini ppl forward $PID ile al. Her satır endpoint_name'i (harness component'inin http: bloğunda beyan ettiği şey), vertex_id'yi, url'yi ve token'ı taşır. URL'yi ve token'ı bearer kimlik bilgileri olarak ele al; onları loglamak yerine test sürücüne ortam değişkenleri olarak geçir.

Çıktı URL'si HTTP'dir, ama testler ona WebSocket olarak bağlanır (https://wss://). Girdi URL'si düz HTTP POST'tur. Çıktı WebSocket'ini girdiyi göndermeden önce aç — aksi takdirde yanıt, okuyucu hâlâ bağlanırken gelebilir ve test onu kaçırır. Output JSON HTTP için backend mesajı başına bir metin çerçevesi JSON gövdesini taşır; Output Image HTTP için bir metin çerçevesi {"type": "metadata", "metadata": {…}} (anahtarlar metadata_keys üzerinden yapılandırılabilir) ardından görüntü baytlarını taşıyan bir ikili çerçeve gelir.

Zamanlama gerçekleri

Taze bir backend deploy etmek 30 saniyeden 4 dakikaya kadar sürer — runtime'ın yerel registry'sinden image çekme, container başlatma, tip çıkarımı çalıştırma, endpoint kaydı. Soğuk runtime'lar bu aralığın üst ucunda oturur. CUT bir modeli tembel yüklüyorsa (HuggingFace çekme, ONNX başlatma, Triton model yükleme), deploy sonrası ilk istek ek 10–30 saniye sürebilir. Test sürücüleri ilk istek için çerçeve başına okuma timeout'larını ≥30 saniye ayarlamalı ve soğuk başlatma zamanını test başına değil, harness düzeyinde bütçelemeli.

Bu sayılar test tasarımını şekillendirir çünkü her taze backend onları tekrar öder — backend'ler arasında amortize olmazlar. Bunlara saygı duyan bir CI paketi, fixture başına yeni bir backend ayağa kaldırmak yerine bir backend ayağa kaldırır, ona karşı birçok fixture çalıştırır ve onu yıkar. Manifest yolu bunu doğrudan destekler: bir lease tüm çalıştırma için bir deployment tutar.

Test başarısız olduğunda

Başarısızlıklar küçük bir şekiller kümesine düşer:

  • Bir connect kenarında tip uyumsuzluğu — platform grafiği deploy öncesi reddetti. Hata kenarı ve çakışmayı adlandırır; bağlantıyı düzelt (genellikle uyumsuz ama uyumlu tipler arasında eksik bir transformation).
  • endpoint çözümleniyor ama POST 404 döndürüyor — backend hâlâ deploy ediyor. Girdi göndermeden önce container'lar running olana kadar yokla.
  • WebSocket okumaları timeout oluyor — CUT container içinde çöktü. Log'larını oku (ppl deployment logs --container <container_id>).
  • WebSocket bağlanıyor ama çerçeve gelmiyor — CUT çalışıyor ama sessizce başarısız oluyor (istisna yok, emit yok). Bir sonraki adım component düzeyinde loglamadır.
  • Deploy "no nodes available" ile reddediyor — runtime'ın aday için GPU veya RAM boşluğu yok. Farklı bir runtime seç veya bekle.

Daha geniş desenler için Yaygın hatalar'a bak.

Bunun uyduğu yer

Bir canlı backend testi, build ile ship arasındaki kanıt adımıdır. Aday component'in, model artifact'inin veya grafik revizyonunun üretimde çalışacağı runtime üzerinde doğru davranıp davranmadığını yanıtlar. runtime üretimle aynıdır ve lease temizlemeyi garanti eder, dolayısıyla sonuç hem gerçekçi hem de tekrarlanabilirdir — bir promote kararının ihtiyaç duyduğu kanıt.

Manifest yolu bu döngüyü elle sürülen bir dizi yerine bir CI adımına dönüştürür. El yapımı yol, manifest dilbilgisine uymayan testleri kapsar. İkisi de aynı kanıtı üretir; yalnızca testi nasıl tanımladığında farklılaşırlar.

İlgili

  • Davranışı kanıtla — hepsi bu döngünün üzerine kurulan daha geniş kanıt modları (model entegrasyonu, veri pipeline'ları, sürüm karşılaştırması).
  • lease yaşam döngüsü — her live-test çalıştırmasının arkasındaki temizleme kontratı.
  • Lease'ler — geçici kaynaklar için sahiplik modeli.
  • Deploy et ve izle — bu döngünün geçici olmayan karşılığı.
  • Backend'ler — testin sardığı grafik.
  • Yaygın hatalar — belirti → çözüm araması.

Bu sayfa yardımcı oldu mu?