ctl federation add/list/remove/sync keeps peers in the store (migration 0029); their /v1/models are offered here as external models named PEER/MODEL and kept in step, a model still named by a fallback kept withdrawn. Peers are checked at /ready, timed, and taken out of routing while down. Requests to a peer carry x-llmgw-hop and are refused (508) when they come back to a cluster they passed through; residency and no_store keep requests off peers; X-Request-Id and, with --send-tags, attribution tags go along. ctl model fallbacks sets overflow to a peer. Console view, metrics, admin API routes and docs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
51 lines
1.5 KiB
Go
51 lines
1.5 KiB
Go
package store
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestAFederationPeerIsKeptWithWhatItLastOffered(t *testing.T) {
|
|
s, err := OpenSQLite(t.Context(), filepath.Join(t.TempDir(), "s.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { _ = s.Close() })
|
|
ctx := t.Context()
|
|
|
|
if err := s.PutFederationPeer(ctx, FederationPeer{Name: "east", URL: "https://east", KeyFile: "/k",
|
|
SendTags: true, CreatedBy: "ops"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
peers, err := s.FederationPeers(ctx)
|
|
if err != nil || len(peers) != 1 {
|
|
t.Fatalf("%v %+v", err, peers)
|
|
}
|
|
if p := peers[0]; !p.SendTags || string(p.Models) != "[]" || !p.SyncedAt.IsZero() || p.CreatedBy != "ops" {
|
|
t.Errorf("as kept: %+v", p)
|
|
}
|
|
|
|
at := time.Now()
|
|
if err := s.SetFederationPeerModels(ctx, "east", "c1", json.RawMessage(`[{"id":"m"}]`), at); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
p, err := s.FederationPeer(ctx, "east")
|
|
if err != nil || p.Cluster != "c1" || string(p.Models) != `[{"id":"m"}]` || p.SyncedAt.UnixMilli() != at.UnixMilli() {
|
|
t.Errorf("after a sync: %v %+v", err, p)
|
|
}
|
|
|
|
// A sync finishing after the peer was removed does not bring it back.
|
|
if err := s.DeleteFederationPeer(ctx, "east"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := s.SetFederationPeerModels(ctx, "east", "c1", json.RawMessage(`[]`), at); !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("syncing a removed peer: %v", err)
|
|
}
|
|
if err := s.DeleteFederationPeer(ctx, "east"); !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("removing it twice: %v", err)
|
|
}
|
|
}
|