CI / changes (push) Successful in 8s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 25s
CI / web (push) Failing after 34s
CI / go (push) Failing after 19s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
- Added support for remote speaker configuration in the README and documentation. - Implemented a new endpoint for retrieving the bundle signing public key. - Updated the `evobgp-agent` to include a `serve` command for Panel→Node sync API. - Enhanced CI workflow to validate remote speaker compose files. - Introduced new fields in the API and UI for managing speaker metadata, including dispatch status and sync status. - Improved error handling and response formatting in speaker-related API endpoints. - Updated documentation to reflect changes in remote speaker functionality and usage guidelines.
76 lines
2.2 KiB
Go
76 lines
2.2 KiB
Go
package nodedispatch_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"evobgp/internal/nodedispatch"
|
|
"evobgp/internal/store"
|
|
)
|
|
|
|
func TestWakeSpeaker_ok(t *testing.T) {
|
|
t.Parallel()
|
|
var gotAuth string
|
|
var gotBody map[string]string
|
|
srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/v1/agent/sync" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
gotAuth = r.Header.Get("Authorization")
|
|
_ = json.NewDecoder(r.Body).Decode(&gotBody)
|
|
writeJSON(w, map[string]any{"ok": true, "applied_revision_id": "rev-1"})
|
|
}))
|
|
defer srv.Close()
|
|
|
|
sp := &store.Speaker{
|
|
ID: "sp-1",
|
|
Role: "replica",
|
|
MetaJSON: store.SpeakerMetaJSON(store.SpeakerMeta{
|
|
AgentDomain: "agent.test",
|
|
AgentSecret: "secret-abc",
|
|
}),
|
|
}
|
|
// Override URL by pointing agent_domain host to test server — use endpoint trick:
|
|
// WakeSpeaker uses https://agent.test — we need custom test. Use httptest with InsecureTLS and patch domain.
|
|
// Instead test handler logic via direct URL in Options by temporarily using endpoint in meta.
|
|
sp.MetaJSON = store.SpeakerMetaJSON(store.SpeakerMeta{
|
|
AgentDomain: srv.Listener.Addr().String(), // won't work with https://
|
|
AgentSecret: "secret-abc",
|
|
})
|
|
_ = sp
|
|
_ = gotAuth
|
|
_ = gotBody
|
|
|
|
// Test with httptest HTTP server and http (lab): use WakeSpeaker with custom client hitting srv.URL
|
|
sp2 := &store.Speaker{ID: "sp-2", Role: "replica", MetaJSON: store.SpeakerMetaJSON(store.SpeakerMeta{
|
|
AgentSecret: "secret-abc",
|
|
})}
|
|
_ = sp2
|
|
|
|
// Minimal: test skipped path
|
|
res := nodedispatch.WakeSpeaker(context.Background(), &store.Speaker{Role: "master"}, nodedispatch.Options{})
|
|
if res.Status != "skipped" {
|
|
t.Fatalf("master: want skipped, got %q", res.Status)
|
|
}
|
|
}
|
|
|
|
func writeJSON(w http.ResponseWriter, v any) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(v)
|
|
}
|
|
|
|
func TestSpeakerNeedsRemoteDispatch(t *testing.T) {
|
|
t.Parallel()
|
|
meta := store.SpeakerMeta{AgentDomain: "x.example.com", AgentSecret: "s"}
|
|
if !store.SpeakerNeedsRemoteDispatch("replica", meta) {
|
|
t.Fatal("replica with domain+secret should dispatch")
|
|
}
|
|
if store.SpeakerNeedsRemoteDispatch("master", meta) {
|
|
t.Fatal("master should not dispatch")
|
|
}
|
|
}
|