bbecf0592e
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
52 lines
1.9 KiB
Go
52 lines
1.9 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
|
)
|
|
|
|
// Part D over the wire: the report ACK WITHHOLDS the controller floor for a box whose agent is below
|
|
// the golden's MinAgent, and serves it once the agent qualifies. Companion red-proof: revert the
|
|
// report handler to the ungated EffectiveMinControllerVersion → the held case leaks the floor.
|
|
func TestReportACK_ManagedFloorHold(t *testing.T) {
|
|
h, st, _ := newTestHandler(t)
|
|
st.SetDefaultMinControllerVersion("0.113.0") // controller floor
|
|
_ = st.SetArtifactManifest(store.ArtifactManifest{GoldenVersion: "0.113.0", MinAgent: "0.81.0"}) // coupled golden
|
|
if err := st.SaveCustomerConfig(&store.CustomerConfig{CustomerID: "c", RetrievalPassword: "pw", APIKey: "k", ConfigJSON: "{}"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := st.UpsertHost(&store.Host{HostID: "hc", CustomerID: "c", APIKey: "hc-key"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ackFloor := func() (interface{}, bool) {
|
|
rr := do(h, http.MethodPost, "/report", globalKey, `{"customer_id":"c"}`)
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("report status = %d", rr.Code)
|
|
}
|
|
var ack map[string]interface{}
|
|
_ = json.Unmarshal(rr.Body.Bytes(), &ack)
|
|
v, ok := ack["min_controller_version"]
|
|
return v, ok
|
|
}
|
|
|
|
// Agent below MinAgent → the floor is HELD (ACK omits it).
|
|
if err := st.SaveHostReport("hc", "c", []byte(`{}`), store.HostReportDenorm{AgentVersion: "0.79.0"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v, ok := ackFloor(); ok {
|
|
t.Errorf("held box: ACK must OMIT the floor, got %v", v)
|
|
}
|
|
|
|
// Agent updates to ≥ MinAgent → the floor is now served.
|
|
if err := st.SaveHostReport("hc", "c", []byte(`{}`), store.HostReportDenorm{AgentVersion: "0.82.0"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v, ok := ackFloor(); !ok || v != "0.113.0" {
|
|
t.Errorf("qualified box: ACK must serve the floor 0.113.0, got %v (present=%v)", v, ok)
|
|
}
|
|
}
|