- PATCH /agents/{id} switches the mode and reconnects the agent
- POST /revisions/{n}/deploy creates pending push deployments, sends
ApplyRevisionCommand with the deployment ID, re-sends open pushes on
connect and announces them in GetDesiredState; reports with the ID
complete the deployment
- POST /revisions/{n}/rollback re-renders the stored generator input
with the next revision number
- GET /revisions/{n}/diff and GET /config/pending with unified diffs
- GET /events streams agent, deployment, revision and pending events
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
2.3 KiB
Go
94 lines
2.3 KiB
Go
// SPDX-License-Identifier: LicenseRef-DDI-Proprietary
|
|
|
|
package agenthub
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.beugsiud.de/beug.k/DDI/internal/agentpki"
|
|
)
|
|
|
|
func TestHub(t *testing.T) {
|
|
h := New()
|
|
a := h.Attach("a", "dns", ModeAutoPull)
|
|
b := h.Attach("b", "dhcp", ModeManual)
|
|
if !h.Connected("a") || !h.Connected("b") || h.Connected("c") {
|
|
t.Fatal("connected state")
|
|
}
|
|
if c := h.Count(); c["dns"] != 1 || c["dhcp"] != 1 {
|
|
t.Errorf("count %v", c)
|
|
}
|
|
|
|
if n := h.NotifyRevision(7); n != 1 {
|
|
t.Errorf("notified %d", n)
|
|
}
|
|
cmd := <-a.Commands()
|
|
if cmd.GetApplyRevision().GetRevision() != 7 || !agentpki.ValidAgentID(cmd.GetCommandId()) ||
|
|
!agentpki.ValidAgentID(cmd.GetApplyRevision().GetDeploymentId()) {
|
|
t.Errorf("command %v", cmd)
|
|
}
|
|
select {
|
|
case <-b.Commands():
|
|
t.Error("manual agent notified")
|
|
default:
|
|
}
|
|
|
|
// A full queue drops commands instead of blocking.
|
|
for range queueSize + 3 {
|
|
h.NotifyRevision(8)
|
|
}
|
|
if len(a.cmds) != queueSize {
|
|
t.Errorf("queue length %d", len(a.cmds))
|
|
}
|
|
|
|
// A newer stream replaces the old one.
|
|
a2 := h.Attach("a", "dns", ModeAutoPull)
|
|
if a.Reason() == "" {
|
|
t.Error("old stream not closed")
|
|
}
|
|
h.Detach(a) // stale detach must not remove the new stream
|
|
if !h.Connected("a") {
|
|
t.Error("stale detach removed the new stream")
|
|
}
|
|
|
|
h.Disconnect("a", "revoked")
|
|
if a2.Reason() != "revoked" || h.Connected("a") {
|
|
t.Errorf("disconnect: %q", a2.Reason())
|
|
}
|
|
h.Detach(b)
|
|
if h.Connected("b") || len(h.Count()) != 0 {
|
|
t.Error("detach")
|
|
}
|
|
h.Disconnect("unknown", "x") // no-op
|
|
}
|
|
|
|
func TestSend(t *testing.T) {
|
|
h := New()
|
|
if h.Send("m", ApplyCommand(3, "12")) {
|
|
t.Error("sent to an agent without stream")
|
|
}
|
|
m := h.Attach("m", "dns", ModeManual)
|
|
if !h.Send("m", ApplyCommand(3, "12")) {
|
|
t.Fatal("not sent")
|
|
}
|
|
cmd := <-m.Commands()
|
|
if cmd.GetApplyRevision().GetRevision() != 3 || cmd.GetApplyRevision().GetDeploymentId() != "12" ||
|
|
!agentpki.ValidAgentID(cmd.GetCommandId()) {
|
|
t.Errorf("command %v", cmd)
|
|
}
|
|
for range queueSize {
|
|
h.Send("m", ApplyCommand(4, "13"))
|
|
}
|
|
if h.Send("m", ApplyCommand(5, "14")) {
|
|
t.Error("sent to a full queue")
|
|
}
|
|
|
|
// Only streams in auto_pull mode get new revisions.
|
|
x := h.Attach("x", "dhcp", ModeAutoPull)
|
|
h.SetMode("x", ModeManual)
|
|
h.SetMode("unknown", ModeManual) // no-op
|
|
if n := h.NotifyRevision(9); n != 0 || len(x.Commands()) != 0 {
|
|
t.Errorf("manual stream notified: %d", n)
|
|
}
|
|
}
|