feat: complete daemon operations and recovery tooling
This commit is contained in:
@@ -22,7 +22,7 @@ import (
|
||||
func TestServerAcceptsBackendUpdateThroughUnixSocket(t *testing.T) {
|
||||
socketPath := shortSocketPath(t)
|
||||
updater := &fakeUpdater{record: transaction.Transaction{ID: "transaction-01", State: transaction.StateCommitted}}
|
||||
server, err := New(socketPath, updater, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
server, err := New(socketPath, updater, &fakeDiagnoser{}, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func TestServerAcceptsBackendUpdateThroughUnixSocket(t *testing.T) {
|
||||
func TestServerAcceptsDirectNativeJARThroughUnixSocket(t *testing.T) {
|
||||
socketPath := shortSocketPath(t)
|
||||
updater := &fakeUpdater{record: transaction.Transaction{ID: "transaction-direct-01", State: transaction.StateCommitted}}
|
||||
server, err := New(socketPath, updater, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
server, err := New(socketPath, updater, &fakeDiagnoser{}, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
@@ -93,7 +93,7 @@ func TestServerAcceptsDirectNativeJARThroughUnixSocket(t *testing.T) {
|
||||
func TestServerAcceptsContainerImageThroughUnixSocket(t *testing.T) {
|
||||
socketPath := shortSocketPath(t)
|
||||
updater := &fakeUpdater{record: transaction.Transaction{ID: "transaction-container-01", State: transaction.StateCommitted}}
|
||||
server, err := New(socketPath, updater, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
server, err := New(socketPath, updater, &fakeDiagnoser{}, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
@@ -121,7 +121,7 @@ func TestServerReturnsTransactionFailure(t *testing.T) {
|
||||
record: transaction.Transaction{ID: "transaction-02", State: transaction.StateRolledBack},
|
||||
err: errors.New("health check failed"),
|
||||
}
|
||||
server, err := New(socketPath, updater, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
server, err := New(socketPath, updater, &fakeDiagnoser{}, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func TestServerReturnsTransactionFailure(t *testing.T) {
|
||||
func TestServerAcceptsBackendRestartThroughUnixSocket(t *testing.T) {
|
||||
socketPath := shortSocketPath(t)
|
||||
updater := &fakeUpdater{record: transaction.Transaction{ID: "transaction-restart-01", State: transaction.StateCommitted}}
|
||||
server, err := New(socketPath, updater, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
server, err := New(socketPath, updater, &fakeDiagnoser{}, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
@@ -168,6 +168,55 @@ func TestServerAcceptsBackendRestartThroughUnixSocket(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestServerReturnsStatusThroughUnixSocket 验证服务端能通过 Unix Socket 处理 status 请求,
|
||||
// 并把诊断结果返回给客户端。
|
||||
func TestServerReturnsStatusThroughUnixSocket(t *testing.T) {
|
||||
socketPath := shortSocketPath(t)
|
||||
updater := &fakeUpdater{}
|
||||
diagnosis := daemonapi.Diagnosis{Service: "backend", Type: "container", Healthy: true, Items: []daemonapi.DiagnosisItem{{Level: daemonapi.DiagnosisLevelOK, Code: "ok", Message: "ok"}}}
|
||||
diagnoser := &fakeDiagnoser{diagnosis: diagnosis}
|
||||
server, err := New(socketPath, updater, diagnoser, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
serveResult := make(chan error, 1)
|
||||
go func() { serveResult <- server.Serve(ctx) }()
|
||||
waitForSocket(t, socketPath, serveResult)
|
||||
|
||||
result, err := daemonclient.Status(context.Background(), socketPath, "backend")
|
||||
if err != nil {
|
||||
t.Fatalf("submit status: %v", err)
|
||||
}
|
||||
if result.Service != "backend" || !result.Healthy {
|
||||
t.Fatalf("unexpected status result: %+v", result)
|
||||
}
|
||||
}
|
||||
|
||||
// TestServerReconcileForwardsApply 验证 reconcile --apply 会把 apply 标志正确传递给诊断器。
|
||||
func TestServerReconcileForwardsApply(t *testing.T) {
|
||||
socketPath := shortSocketPath(t)
|
||||
updater := &fakeUpdater{}
|
||||
diagnoser := &fakeDiagnoser{diagnosis: daemonapi.Diagnosis{Service: "backend", Type: "container", Healthy: true}}
|
||||
server, err := New(socketPath, updater, diagnoser, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
if err != nil {
|
||||
t.Fatalf("create daemon server: %v", err)
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
serveResult := make(chan error, 1)
|
||||
go func() { serveResult <- server.Serve(ctx) }()
|
||||
waitForSocket(t, socketPath, serveResult)
|
||||
|
||||
if _, err := daemonclient.Reconcile(context.Background(), socketPath, "backend", true); err != nil {
|
||||
t.Fatalf("submit reconcile apply: %v", err)
|
||||
}
|
||||
if !diagnoser.applied {
|
||||
t.Fatal("reconcile --apply was not forwarded to diagnoser")
|
||||
}
|
||||
}
|
||||
|
||||
// shortSocketPath 创建一个短目录并返回其下的 daemon.sock 路径,用于规避 Unix Socket 路径长度上限。
|
||||
// 目录会在测试结束时自动清理。
|
||||
func shortSocketPath(t *testing.T) string {
|
||||
@@ -259,3 +308,21 @@ func (u *fakeUpdater) Restart(_ context.Context, report backendupdate.ProgressRe
|
||||
}
|
||||
return u.record, u.err
|
||||
}
|
||||
|
||||
// fakeDiagnoser backendDiagnoser 接口的测试替身,返回预设的空诊断结果。
|
||||
type fakeDiagnoser struct {
|
||||
diagnosis daemonapi.Diagnosis
|
||||
err error
|
||||
applied bool
|
||||
}
|
||||
|
||||
// Diagnose 返回预设的诊断结果。
|
||||
func (d *fakeDiagnoser) Diagnose(context.Context) (daemonapi.Diagnosis, error) {
|
||||
return d.diagnosis, d.err
|
||||
}
|
||||
|
||||
// Reconcile 返回预设的诊断结果,并记录 apply 标志。
|
||||
func (d *fakeDiagnoser) Reconcile(_ context.Context, apply bool) (daemonapi.Diagnosis, error) {
|
||||
d.applied = apply
|
||||
return d.diagnosis, d.err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user