F6 deeper half: poll agent /disks/format/status on the 15s client timeout (slow USB mkfs runs detached) — agentapi.FormatStatus + awaitAgentFormat; then mount+register. Found on the live leg.
This commit is contained in:
@@ -40,6 +40,9 @@ type mockAgent struct {
|
||||
assignCalls []assignCall
|
||||
disksCalls int
|
||||
formatCalls []formatCall
|
||||
formatStatus agentapi.FormatStatusResult
|
||||
formatStatusErr error
|
||||
formatStatusCalls int
|
||||
guestAttachCalls []string
|
||||
decommissionCalls []string
|
||||
guestRebootCalls int
|
||||
@@ -65,6 +68,10 @@ func (m *mockAgent) FormatDisk(_ context.Context, device, fstype string, confirm
|
||||
m.formatCalls = append(m.formatCalls, formatCall{device, fstype, durableID, confirmed})
|
||||
return m.formatRes, m.formatErr
|
||||
}
|
||||
func (m *mockAgent) FormatStatus(context.Context) (agentapi.FormatStatusResult, error) {
|
||||
m.formatStatusCalls++
|
||||
return m.formatStatus, m.formatStatusErr
|
||||
}
|
||||
func (m *mockAgent) AssignDisk(ctx context.Context, uuid, where, fstype, _ string) error {
|
||||
// Respect cancellation — a mount over a dead client/request context fails (this is the F6 bug's
|
||||
// mechanism: a disconnect after format aborts the mount+register leg). Background ctx never
|
||||
@@ -274,6 +281,50 @@ func TestStorageInit_DetachedSurvivesClientDisconnect(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// F6 deeper half — a slow mkfs outruns the agent-client's 15 s timeout; the agent runs it detached,
|
||||
// so the controller must POLL GET /disks/format/status and continue to mount+register on `done`
|
||||
// (rather than reporting the timeout as a failure). Observed live on a 64 GB USB.
|
||||
func TestStorageInit_PollsAgentFormatStatusOnTimeout(t *testing.T) {
|
||||
t.Run("timeout_then_done_registers", func(t *testing.T) {
|
||||
s := testServer(t)
|
||||
agent := &mockAgent{
|
||||
formatErr: context.DeadlineExceeded, // the 15 s client timeout — mkfs continues detached
|
||||
formatStatus: agentapi.FormatStatusResult{Phase: "done", Device: "/dev/sdb1"},
|
||||
disks: agentapi.DisksResponse{Disks: []agentapi.DiskInfo{
|
||||
{Name: "felhom-usb", BackingDevice: "/dev/sdb1", DurableID: "uuid:NEW-9999"},
|
||||
}},
|
||||
}
|
||||
res, err := s.runStorageInit(context.Background(), agent, "/dev/sdb1", "ext4", "/mnt/hdd1", "HDD", true, false, "", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expected success via the format-status poll, got %v", err)
|
||||
}
|
||||
if !res.Registered {
|
||||
t.Fatal("expected registered after the format-status poll (F6)")
|
||||
}
|
||||
if agent.formatStatusCalls == 0 {
|
||||
t.Fatal("the agent format-status was never polled")
|
||||
}
|
||||
if len(agent.assignCalls) != 1 {
|
||||
t.Fatalf("expected exactly one mount after poll-done: %+v", agent.assignCalls)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("timeout_then_failed_surfaces_error", func(t *testing.T) {
|
||||
s := testServer(t)
|
||||
agent := &mockAgent{
|
||||
formatErr: context.DeadlineExceeded,
|
||||
formatStatus: agentapi.FormatStatusResult{Phase: "failed", Device: "/dev/sdb1", Error: "mkfs exploded"},
|
||||
}
|
||||
_, err := s.runStorageInit(context.Background(), agent, "/dev/sdb1", "ext4", "/mnt/hdd1", "HDD", true, false, "", nil)
|
||||
if err == nil {
|
||||
t.Fatal("a failed detached format must surface an error, not register")
|
||||
}
|
||||
if len(s.settings.GetStoragePaths()) != 0 {
|
||||
t.Fatalf("a failed format must NOT register: %+v", s.settings.GetStoragePaths())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// F7 (VALIDATION-n100) — the "Vissza" (Back) anchor on the init/attach wizards must route to
|
||||
// /storage, not /settings. One assertion per template.
|
||||
func TestStorageWizardBackAnchors_PointToStorage(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user