You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.4 KiB

package capacity
import (
"errors"
"os"
"path/filepath"
"sync"
"testing"
)
func testPolicy() Policy {
policy := Policy{FormatVersion: 1, Layout: "tera-userdata-v1", Enforcement: EnforcementV1}
policy.CapsBytes.UpdateStaging = 1000
policy.CapsBytes.UpdatePackageMax = 800
policy.CapsBytes.GlobalFreeFloor = 200
return policy
}
func TestGovernorEnforcesClassCapAndGlobalFloor(t *testing.T) {
root := t.TempDir()
if err := os.WriteFile(filepath.Join(root, "existing"), make([]byte, 300), 0o600); err != nil {
t.Fatal(err)
}
governor, err := New(root, testPolicy())
if err != nil {
t.Fatal(err)
}
governor.free = func(string) (int64, error) { return 900, nil }
reservation, snapshot, err := governor.Reserve(600)
if err != nil {
t.Fatalf("reserve: %v", err)
}
if snapshot.UpdateReserved != 600 || snapshot.Pressure != "warning" {
t.Fatalf("unexpected snapshot: %+v", snapshot)
}
if _, _, err := governor.Reserve(101); !errors.Is(err, ErrInsufficientSpace) {
t.Fatalf("second reservation error = %v, want insufficient space", err)
}
reservation.Release()
if snapshot, err := governor.Snapshot(); err != nil || snapshot.UpdateReserved != 0 {
t.Fatalf("released snapshot = %+v, %v", snapshot, err)
}
}
func TestGovernorConcurrentReservationsAreBounded(t *testing.T) {
root := t.TempDir()
governor, err := New(root, testPolicy())
if err != nil {
t.Fatal(err)
}
governor.free = func(string) (int64, error) { return 1000, nil }
var wait sync.WaitGroup
start := make(chan struct{})
results := make(chan error, 2)
for range 2 {
wait.Add(1)
go func() {
defer wait.Done()
<-start
_, _, err := governor.Reserve(500)
results <- err
}()
}
close(start)
wait.Wait()
close(results)
succeeded := 0
for err := range results {
if err == nil {
succeeded++
} else if !errors.Is(err, ErrInsufficientSpace) {
t.Fatalf("unexpected reservation error: %v", err)
}
}
if succeeded != 1 {
t.Fatalf("successful reservations = %d, want 1", succeeded)
}
}
func TestDirectoryUsageRejectsSymlink(t *testing.T) {
root := t.TempDir()
target := filepath.Join(root, "target")
if err := os.WriteFile(target, []byte("x"), 0o600); err != nil {
t.Fatal(err)
}
if err := os.Symlink(target, filepath.Join(root, "link")); err != nil {
t.Skipf("symlink unavailable: %v", err)
}
if _, err := directoryUsage(root); err == nil {
t.Fatal("directoryUsage accepted symlink")
}
}