MCPcopy Index your code
hub / github.com/codehamr/codehamr / TestApplyRestoresBinaryWhenPromoteFails

Function TestApplyRestoresBinaryWhenPromoteFails

internal/update/update_test.go:114–147  ·  view source on GitHub ↗

TestApplyRestoresBinaryWhenPromoteFails covers the most dangerous failure: the running binary is moved aside to execPath+".old", then the promote rename fails. Without the restore the user is left with NO executable at execPath. Driven through the promoteRename seam (the one step we can't make fail

(t *testing.T)

Source from the content-addressed store, hash-verified

112// fail deterministically and root-safely via the filesystem); the restore
113// uses real os.Rename, so this asserts recovery actually happens.
114func TestApplyRestoresBinaryWhenPromoteFails(t *testing.T) {
115 asset := platformAsset(t)
116 body := []byte("verified new binary\n")
117 r := newFakeRelease(t, asset, body, hashOf(body))
118 withReleaseURLs(t, r.srv.URL)
119
120 orig := promoteRename
121 promoteRename = func(string, string) error { return fmt.Errorf("simulated promote failure") }
122 t.Cleanup(func() { promoteRename = orig })
123
124 tmpDir := t.TempDir()
125 exec := filepath.Join(tmpDir, "codehamr")
126 const originalBytes = "the original running binary\n"
127 if err := os.WriteFile(exec, []byte(originalBytes), 0o755); err != nil {
128 t.Fatal(err)
129 }
130
131 err := Apply(context.Background(), exec)
132 if err == nil {
133 t.Fatal("Apply must surface the promote failure")
134 }
135 // The original binary must be restored from .old, not left missing.
136 got, readErr := os.ReadFile(exec)
137 if readErr != nil {
138 t.Fatalf("execPath is gone after a failed promote - user left with no binary: %v", readErr)
139 }
140 if string(got) != originalBytes {
141 t.Fatalf("execPath not restored to the original binary: got %q", got)
142 }
143 // No half-written temp file should leak.
144 if matches, _ := filepath.Glob(filepath.Join(tmpDir, ".codehamr-update-*")); len(matches) != 0 {
145 t.Fatalf("temp file leaked after failed promote: %+v", matches)
146 }
147}
148
149// TestApplyReportsRestoreFailure covers the doubly-bad path: the promote
150// rename fails AND the restore of the moved-aside binary also fails. Apply

Callers

nothing calls this directly

Calls 5

platformAssetFunction · 0.85
newFakeReleaseFunction · 0.85
hashOfFunction · 0.85
withReleaseURLsFunction · 0.85
ApplyFunction · 0.85

Tested by

no test coverage detected