package cluster import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" ) // TestTokenTransportPOST verifies a token serializes over HTTP POST to the // peer endpoint and receives 2xx. func TestTokenTransportPOST(t *testing.T) { var got Token srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/manager/cluster/token" { http.NotFound(w, r) return } if err := json.NewDecoder(r.Body).Decode(&got); err != nil { http.Error(w, "bad token", http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) })) defer srv.Close() tr := &TokenTransport{User: "u", Pass: "p"} host := srv.Listener.Addr().String() send := tr.SendTo(func(nodeID string) string { return host }) err := send(context.Background(), "peer1", &Token{Cycle: 3}) if err != nil { t.Fatalf("send: %v", err) } if got.Cycle != 3 { t.Fatalf("got token = %+v", got) } } // TestTokenTransportHeartbeat verifies a nil-token ping (leader heartbeat). func TestTokenTransportHeartbeat(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/manager/cluster/token" { http.NotFound(w, r) return } w.WriteHeader(http.StatusOK) })) defer srv.Close() tr := &TokenTransport{User: "u", Pass: "p"} if err := tr.HeartbeatPing(context.Background(), srv.Listener.Addr().String()); err != nil { t.Fatalf("heartbeat: %v", err) } } // TestTokenTransportError verifies non-2xx -> error (dead peer detection). func TestTokenTransportError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "gone", http.StatusServiceUnavailable) })) defer srv.Close() tr := &TokenTransport{User: "u", Pass: "p"} if err := tr.HeartbeatPing(context.Background(), srv.Listener.Addr().String()); err == nil { t.Fatal("expected error on 503") } }