Files
felhom-controller/controller/internal/dockerexec/imagework_d48_test.go
T

46 lines
1.3 KiB
Go

package dockerexec
import (
"os"
"strings"
"testing"
"time"
)
// D48 — a restore holds the image-work lock from its pre-pull until its last start. While it is held the clean-up
// cannot run, and a compose up inside the hold does not block.
func TestD48_HoldImageWorkBlocksCleanupAndNests(t *testing.T) {
end := HoldImageWork()
if _, ok := TryImageCleanup(); ok {
t.Fatal("the image clean-up must not run while a restore holds its images")
}
done := make(chan struct{})
go func() {
defer close(done)
BeginImageWork([]string{"compose", "up", "-d"})()
}()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("a compose up inside the restore's hold must not block")
}
end()
unlock, ok := TryImageCleanup()
if !ok {
t.Fatal("after the hold the clean-up runs again")
}
unlock()
}
// The nesting is safe only while the one exclusive taker never WAITS (a waiting writer would block a nested RLock).
// Pin it: the package takes the lock exclusively nowhere but TryLock.
func TestD48_TheOnlyExclusiveTakerNeverWaits(t *testing.T) {
b, err := os.ReadFile("imagework.go")
if err != nil {
t.Fatal(err)
}
if strings.Contains(string(b), "imageWorkMu.Lock()") {
t.Fatal("a blocking exclusive Lock() on imageWorkMu would deadlock a restore's nested shared hold (HoldImageWork)")
}
}