88 lines
3.3 KiB
Go
88 lines
3.3 KiB
Go
package dispatcher
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.ipao.vip/rogee/go-sip/internal/configread"
|
|
)
|
|
|
|
func newCurrentFollowerFixture(t *testing.T, revision int64) (*CurrentDiscoveryFollower, func() bool) {
|
|
t.Helper()
|
|
executor, _, _, s := newCurrentExecuteFixture(t)
|
|
approved := currentPolicySnapshot(t).SIP
|
|
sipBody, err := json.Marshal(approved)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
terminalSeen := false
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
var body []byte
|
|
switch r.URL.Path {
|
|
case "/internal/v1/dispatcher/tasks":
|
|
switch r.URL.Query().Get("after") {
|
|
case "initial":
|
|
body = []byte(fmt.Sprintf(`{"dispatcher_id":%q,"cursor":"middle","tasks":[{"task_id":"task-asr","tenant_id":1001,"status":"running","task_revision":%d}]}`, executor.DispatcherID, revision))
|
|
case "middle":
|
|
terminalSeen = true
|
|
body = []byte(fmt.Sprintf(`{"dispatcher_id":%q,"cursor":"opaque-tail","tasks":[]}`, executor.DispatcherID))
|
|
default:
|
|
t.Errorf("unexpected discovery cursor: %s", r.URL.RawQuery)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
case "/internal/v1/dispatcher/sip":
|
|
body = sipBody
|
|
case "/internal/v1/dispatcher/ai-providers":
|
|
body = currentConfigExample(t, "config-read-providers")
|
|
case "/internal/v1/dispatcher/task/task-asr":
|
|
body = currentConfigExample(t, "config-read-task-asr")
|
|
case "/internal/v1/dispatcher/tenant/1001/quota":
|
|
body = currentConfigExample(t, "config-read-quota")
|
|
default:
|
|
t.Errorf("unexpected config path: %s", r.URL.Path)
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
_, _ = w.Write(body)
|
|
}))
|
|
t.Cleanup(server.Close)
|
|
client, err := configread.NewClient(server.URL, executor.DispatcherID, "test-secret", server.Client())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
follower := &CurrentDiscoveryFollower{DispatcherID: executor.DispatcherID, Client: client, Store: s, ApprovedSIP: approved, VerifySIP: func(context.Context, configread.CurrentSIP) error { return nil }, Cursor: "initial"}
|
|
return follower, func() bool { return terminalSeen }
|
|
}
|
|
|
|
func TestCurrentDiscoveryFollowerPersistsPageBeforeAdvancingToTerminalEmpty(t *testing.T) {
|
|
follower, terminal := newCurrentFollowerFixture(t, 1)
|
|
if err := follower.Poll(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if follower.Cursor != "opaque-tail" || !terminal() {
|
|
t.Fatalf("cursor did not advance through terminal empty page: %q %v", follower.Cursor, terminal())
|
|
}
|
|
if admitted, err := follower.Store.CanAdmit(follower.DispatcherID, 1001, "task-asr"); err != nil || !admitted {
|
|
t.Fatalf("valid discovery closed admission: %v %v", admitted, err)
|
|
}
|
|
}
|
|
|
|
func TestCurrentDiscoveryFollowerFailedPageKeepsCursorAndClosesAdmission(t *testing.T) {
|
|
follower, terminal := newCurrentFollowerFixture(t, 2)
|
|
if err := follower.Poll(context.Background()); err == nil {
|
|
t.Fatal("task revision mismatch was accepted")
|
|
}
|
|
if follower.Cursor != "initial" || terminal() {
|
|
t.Fatalf("failed page advanced cursor: %q %v", follower.Cursor, terminal())
|
|
}
|
|
if admitted, err := follower.Store.CanAdmit(follower.DispatcherID, 1001, "task-asr"); err != nil || admitted {
|
|
t.Fatalf("failed page left task admission open: %v %v", admitted, err)
|
|
}
|
|
}
|