repositories / bugabinga.net
bugabinga.net
personal infrastructure for bugabinga!
owned by admin
services/luci/internal/podman/storage_test.go
Rawpackage podman
import (
"context"
"fmt"
"io"
"strings"
"testing"
"time"
)
type storageExecutor struct {
calls [][]string
response func([]string) (string, error)
}
func (e *storageExecutor) Run(_ context.Context, args []string, stdout, _ io.Writer) error {
e.calls = append(e.calls, append([]string(nil), args...))
output, err := e.response(args)
_, _ = io.WriteString(stdout, output)
return err
}
func TestStorageInfoUsesEngineGraphroot(t *testing.T) {
executor := &storageExecutor{response: func(args []string) (string, error) {
if strings.Join(args, " ") != "info --format json" {
return "", fmt.Errorf("unexpected %v", args)
}
return `{"store":{"graphRootAllocated":100,"graphRootUsed":40}}`, nil
}}
info, err := StorageInfoFor(context.Background(), executor)
if err != nil || info.Free() != 60 {
t.Fatalf("info=%#v err=%v", info, err)
}
}
func TestPruneLuciBuildCacheOnlyRemovesOldDanglingUnreferencedImages(t *testing.T) {
images := `[{
"Id":"old","Size":70,"Created":1,"Containers":0,"Names":["<none>:<none>"],"Labels":{"io.luci.build":"cache-v1"}
},{
"Id":"active","Size":70,"Created":1,"Containers":1,"Names":["<none>:<none>"],"Labels":{"io.luci.build":"cache-v1"}
},{
"Id":"tagged","Size":70,"Created":1,"Containers":0,"Names":["luci-build-current"],"Labels":{"io.luci.build":"cache-v1"}
},{
"Id":"foreign","Size":70,"Created":1,"Containers":0,"Names":["<none>:<none>"],"Labels":{"other":"value"}
}]`
executor := &storageExecutor{response: func(args []string) (string, error) {
if args[0] == "image" && args[1] == "ls" {
return images, nil
}
if args[0] == "image" && args[1] == "rm" {
if len(args) != 3 || args[2] != "old" || contains(args, "--force") {
return "", fmt.Errorf("unsafe remove %v", args)
}
return "old", nil
}
return "", fmt.Errorf("unexpected %v", args)
}}
report, err := PruneLuciBuildCache(context.Background(), executor, 80, time.Hour, map[string]bool{"active": true}, time.Unix(7200, 0))
if err != nil || len(report.Removed) != 1 || report.Removed[0] != "old" || report.Bytes != 0 {
t.Fatalf("report=%#v err=%v", report, err)
}
for _, call := range executor.calls {
if len(call) > 1 && call[0] == "image" && call[1] == "rm" && call[2] != "old" {
t.Fatalf("removed protected image: %v", call)
}
}
}
func TestPruneFailsClosedWhenSafeCandidatesCannotMeetBudget(t *testing.T) {
executor := &storageExecutor{response: func(args []string) (string, error) {
if args[0] == "image" && args[1] == "ls" {
return `[{"Id":"active","Size":101,"Created":1,"Containers":0,"Names":["<none>:<none>"],"Labels":{"io.luci.build":"cache-v1"}}]`, nil
}
return "", fmt.Errorf("unexpected mutation %v", args)
}}
_, err := PruneLuciBuildCache(context.Background(), executor, 100, time.Hour, map[string]bool{"active": true}, time.Unix(2, 0))
if err == nil || !strings.Contains(err.Error(), "above budget") {
t.Fatalf("err=%v", err)
}
}