Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/platform/inference/client_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 |
| Branch | master |
| Path or archive member | internal/platform/inference/client_test.go |
| Original SHA-256 | 5fddb36769a4d1f969fe2237bcb0c67c0ad0be4081d7a1562dbf1355e9cdb7f5 |
| Git blob SHA | ad2f423c3c3e702070839fc9315780ec8febcc42 |
| Reading-copy SHA-256 | 5fddb36769a4d1f969fe2237bcb0c67c0ad0be4081d7a1562dbf1355e9cdb7f5 |
Every recorded occurrence
These 23 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/platform/inference/client_test.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/platform/inference/client_test.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓127 lines · 5.0 KB
package inference
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
"time"
"github.com/missionworkforce/missionmatch/internal/platform/scrub"
)
func newTestClient(t *testing.T, h http.Handler) *Client {
t.Helper()
srv := httptest.NewServer(h)
t.Cleanup(srv.Close)
c, err := New(Config{BaseURL: srv.URL, EmbedModel: "all-minilm", Dimension: 384, Timeout: 2 * time.Second})
if err != nil {
t.Fatalf("New: %v", err)
}
return c
}
func TestEmbedReturnsVectorsAndChecksDimension(t *testing.T) {
c := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req EmbedRequest
_ = json.NewDecoder(r.Body).Decode(&req)
out := EmbedResponse{Model: req.Model, Dimension: 384, Embeddings: make([][]float32, len(req.Inputs))}
for i := range out.Embeddings {
out.Embeddings[i] = make([]float32, 384)
}
_ = json.NewEncoder(w).Encode(out)
}))
res, err := c.Embed(context.Background(), []string{"a", "b"})
if err != nil {
t.Fatalf("Embed: %v", err)
}
if len(res.Embeddings) != 2 || len(res.Embeddings[0]) != 384 {
t.Fatalf("expected 2 vectors of width 384, got %d x %d", len(res.Embeddings), len(res.Embeddings[0]))
}
}
func TestEmbedRejectsWrongDimension(t *testing.T) {
c := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
// A plane that returns 768 wide vectors would silently corrupt the vector(384) column.
_ = json.NewEncoder(w).Encode(EmbedResponse{Dimension: 768, Embeddings: [][]float32{make([]float32, 768)}})
}))
if _, err := c.Embed(context.Background(), []string{"x"}); err == nil {
t.Fatal("Embed must hard fail when the plane returns the wrong embedding width")
}
}
func TestRetriesOn5xxThenSucceeds(t *testing.T) {
var calls int32
c := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
if atomic.AddInt32(&calls, 1) < 3 {
w.WriteHeader(http.StatusBadGateway)
return
}
_ = json.NewEncoder(w).Encode(GenerateResponse{Text: "ok"})
}))
c.cfg.MaxRetries = 3
res, err := c.Generate(context.Background(), GenerateRequest{Prompt: "hi"})
if err != nil {
t.Fatalf("Generate should succeed after transient 5xx retries: %v", err)
}
if res.Text != "ok" || atomic.LoadInt32(&calls) != 3 {
t.Fatalf("expected success on the 3rd attempt, got %q after %d calls", res.Text, calls)
}
}
func TestNon5xxErrorIsNotRetried(t *testing.T) {
var calls int32
c := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
atomic.AddInt32(&calls, 1)
w.WriteHeader(http.StatusBadRequest)
}))
c.cfg.MaxRetries = 3
if _, err := c.Generate(context.Background(), GenerateRequest{Prompt: "hi"}); err == nil {
t.Fatal("a 400 must not be retried and must surface as an error")
}
if atomic.LoadInt32(&calls) != 1 {
t.Fatalf("a 4xx must be tried exactly once, got %d calls", calls)
}
}
func TestBreakerOpensAfterRepeatedFailures(t *testing.T) {
c := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusServiceUnavailable)
}))
c.cfg.MaxRetries = 0
c.cb = newBreaker(3, time.Minute)
for i := 0; i < 3; i++ {
_, _ = c.Generate(context.Background(), GenerateRequest{Prompt: "x"})
}
if _, err := c.Generate(context.Background(), GenerateRequest{Prompt: "x"}); err != ErrCircuitOpen {
t.Fatalf("after repeated failures the breaker should fail fast with ErrCircuitOpen, got %v", err)
}
}
func TestTeachEnforcesScrubBoundaryAndRespectsPosture(t *testing.T) {
var transmitted int32
c := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
atomic.AddInt32(&transmitted, 1)
w.WriteHeader(http.StatusAccepted)
}))
// A signal carrying a client fact (a UUID in model_version) must be refused before any transmit.
leak := scrub.TeachingSignal{Pattern: "adjacent_skill_substitution_outcome", Band: scrub.BandHigh, Outcome: scrub.OutcomeApproved, Observations: 1, Successes: 1, ModelVersion: "11111111-1111-1111-1111-111111111111"}
if err := c.Teach(context.Background(), leak); err == nil {
t.Fatal("Teach must refuse a signal carrying a client fact")
}
// Register the model version this test signals on, the same way the producer registers engine.ModelVersion
// at init, so the scrub boundary accepts it. The seam refuses any version nobody registered (the tripwire
// for a drifted scoring contract), so a test that speaks a version must register it.
scrub.RegisterModelVersion("v1.0.0")
// A clean signal with teaching disabled (default posture) validates but does NOT transmit.
clean := scrub.TeachingSignal{Pattern: "adjacent_skill_substitution_outcome", Band: scrub.BandHigh, Outcome: scrub.OutcomeApproved, Observations: 10, Successes: 7, ModelVersion: "v1.0.0"}
if err := c.Teach(context.Background(), clean); err != nil {
t.Fatalf("a clean signal should pass the boundary: %v", err)
}
if atomic.LoadInt32(&transmitted) != 0 {
t.Fatal("with teaching disabled the signal must not be transmitted (federated loop is scaffolded, not active)")
}
}