fix: synchronize DWH registry snapshots
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -204,6 +205,83 @@ func TestReadSecretAndCreateSecretUse0600AndExclusiveCreate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLockSharedAllowsReadersAndBlocksExclusiveWriter(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
first, err := OpenDir(root)
|
||||
if err != nil {
|
||||
t.Fatalf("OpenDir(first) error = %v", err)
|
||||
}
|
||||
defer first.Close()
|
||||
second, err := OpenDir(root)
|
||||
if err != nil {
|
||||
t.Fatalf("OpenDir(second) error = %v", err)
|
||||
}
|
||||
defer second.Close()
|
||||
third, err := OpenDir(root)
|
||||
if err != nil {
|
||||
t.Fatalf("OpenDir(third) error = %v", err)
|
||||
}
|
||||
defer third.Close()
|
||||
if first.fd == second.fd || second.fd == third.fd || first.fd == third.fd {
|
||||
t.Fatal("OpenDir() reused a descriptor; want separate lock file descriptions")
|
||||
}
|
||||
|
||||
type sharedLocker interface {
|
||||
LockShared(string) (*Lock, error)
|
||||
}
|
||||
firstLocker, ok := any(first).(sharedLocker)
|
||||
if !ok {
|
||||
t.Fatal("Dir lacks shared advisory locking")
|
||||
}
|
||||
secondLocker, ok := any(second).(sharedLocker)
|
||||
if !ok {
|
||||
t.Fatal("Dir lacks shared advisory locking")
|
||||
}
|
||||
|
||||
firstShared, err := firstLocker.LockShared("registry.lock")
|
||||
if err != nil {
|
||||
t.Fatalf("LockShared(first) error = %v", err)
|
||||
}
|
||||
defer firstShared.Close()
|
||||
secondShared, err := secondLocker.LockShared("registry.lock")
|
||||
if err != nil {
|
||||
t.Fatalf("LockShared(second) error = %v", err)
|
||||
}
|
||||
defer secondShared.Close()
|
||||
|
||||
probe, err := os.OpenFile(filepath.Join(root, "registry.lock"), os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("OpenFile(lock probe) error = %v", err)
|
||||
}
|
||||
if err := syscall.Flock(int(probe.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err == nil {
|
||||
_ = syscall.Flock(int(probe.Fd()), syscall.LOCK_UN)
|
||||
_ = probe.Close()
|
||||
t.Fatal("exclusive lock acquired while separate shared locks were held")
|
||||
} else if !errors.Is(err, syscall.EWOULDBLOCK) && !errors.Is(err, syscall.EAGAIN) {
|
||||
_ = probe.Close()
|
||||
t.Fatalf("nonblocking exclusive lock error = %v, want EWOULDBLOCK", err)
|
||||
}
|
||||
if err := probe.Close(); err != nil {
|
||||
t.Fatalf("Close(lock probe) error = %v", err)
|
||||
}
|
||||
|
||||
if err := secondShared.Close(); err != nil {
|
||||
t.Fatalf("Close(second shared) error = %v", err)
|
||||
}
|
||||
secondShared = nil
|
||||
if err := firstShared.Close(); err != nil {
|
||||
t.Fatalf("Close(first shared) error = %v", err)
|
||||
}
|
||||
firstShared = nil
|
||||
exclusive, err := third.Lock("registry.lock")
|
||||
if err != nil {
|
||||
t.Fatalf("Lock(exclusive after shared release) error = %v", err)
|
||||
}
|
||||
if err := exclusive.Close(); err != nil {
|
||||
t.Fatalf("Close(exclusive) error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func writeFile(t *testing.T, path string, data []byte, mode os.FileMode) {
|
||||
t.Helper()
|
||||
if err := os.WriteFile(path, data, mode); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user