feat(remote-speakers): enhance remote speaker management and API integration
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
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.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user