init --patroni user@host ... installs PostgreSQL, Patroni and etcd on the given machines over ssh, with this one as the third etcd vote, makes the role and database, and moves the store in use into the cluster. Each step checks first, so it changes nothing on a cluster that is up. For a store of several hosts the control plane publishes each member's role, state and lag from Patroni, a stopped member as missing, prints it in ctl status, and alerts on it. Making an administrator on PostgreSQL sent a bool to an integer column; it sends an integer now. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
54 lines
1.6 KiB
Go
54 lines
1.6 KiB
Go
package cli
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/control/adminapi"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func TestAQueuedChangeIsNotReportedAsAnError(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusAccepted)
|
|
_, _ = w.Write([]byte(`{"queued":["r1"]}`))
|
|
}))
|
|
defer srv.Close()
|
|
var out struct {
|
|
Queued []string `json:"queued"`
|
|
}
|
|
if err := newCtlClient(srv.URL).post(t.Context(), "/api/v1/restart", []byte(`{}`), &out); err != nil {
|
|
t.Fatalf("202 read as a failure: %v", err)
|
|
}
|
|
if len(out.Queued) != 1 {
|
|
t.Errorf("the body of a 202 was not read: %+v", out)
|
|
}
|
|
}
|
|
|
|
func TestStatusSaysWhoLeadsTheStoreAndWhetherTheRestKeepUp(t *testing.T) {
|
|
render := func(s adminapi.Summary) string {
|
|
cmd := &cobra.Command{}
|
|
var b bytes.Buffer
|
|
cmd.SetOut(&b)
|
|
printSummary(cmd, s)
|
|
return b.String()
|
|
}
|
|
out := render(adminapi.Summary{Store: []adminapi.StoreMember{
|
|
{Name: "llmgw-ctl02", Role: "replica", State: "streaming", Lag: 2048},
|
|
{Name: "llmgw-pg01", Role: "leader", State: "running"},
|
|
}})
|
|
if !strings.Contains(out, "STORE llmgw-ctl02 streaming (2 KB behind), llmgw-pg01 leads") {
|
|
t.Errorf("status:\n%s", out)
|
|
}
|
|
out = render(adminapi.Summary{Store: []adminapi.StoreMember{{Name: "llmgw-pg01", Role: "replica", State: "stopped"}}})
|
|
if !strings.Contains(out, "NO LEADER") {
|
|
t.Errorf("a store with no leader was not called out:\n%s", out)
|
|
}
|
|
if out := render(adminapi.Summary{}); strings.Contains(out, "STORE") {
|
|
t.Error("a single database got a store line")
|
|
}
|
|
}
|