Release URBM 2026.06.15.r010

This commit is contained in:
Mikei386
2026-06-15 07:24:15 +02:00
parent 772358578e
commit 1e9487e6f2
9 changed files with 71 additions and 9 deletions
+11
View File
@@ -202,6 +202,17 @@ func (r *Runner) Stats(ctx context.Context, repo model.Repository, mode string)
if mode != "" {
args = append(args, "--mode", mode)
}
stats, err := r.stats(ctx, repo, args)
if err == nil || !isRepositoryLocked(err) {
return stats, err
}
if unlockErr := r.Unlock(ctx, repo); unlockErr != nil {
return Stats{}, fmt.Errorf("repository statistics locked; remove stale lock: %w", unlockErr)
}
return r.stats(ctx, repo, args)
}
func (r *Runner) stats(ctx context.Context, repo model.Repository, args []string) (Stats, error) {
var output []byte
if err := r.run(ctx, repo, args, nil, &output); err != nil {
return Stats{}, err
+43
View File
@@ -130,6 +130,49 @@ func TestStatsUsesRequestedRepositoryCountingMode(t *testing.T) {
}
}
func TestStatsUnlocksStaleRepositoryLockAndRetries(t *testing.T) {
dir := t.TempDir()
logPath := filepath.Join(dir, "commands")
countPath := filepath.Join(dir, "stats-count")
script := filepath.Join(dir, "restic")
body := fmt.Sprintf(`#!/bin/sh
printf '%%s\n' "$*" >> '%s'
case " $* " in
*" stats "*)
count=0
[ -f '%s' ] && count=$(cat '%s')
count=$((count + 1))
printf '%%s' "$count" > '%s'
if [ "$count" -eq 1 ]; then
printf 'Fatal: unable to create lock in backend: repository is already locked\n' >&2
exit 11
fi
printf '%%s\n' '{"total_size":4096,"total_file_count":12}'
;;
esac
`, logPath, countPath, countPath, countPath)
if err := os.WriteFile(script, []byte(body), 0700); err != nil {
t.Fatal(err)
}
runner := &Runner{Binary: script, RuntimeDir: dir, Secrets: fakeSecrets{"password": "secret"}}
repo := model.Repository{Type: model.RepositoryLocal, Location: "/repo", PasswordRef: "password"}
stats, err := runner.Stats(context.Background(), repo, "raw-data")
if err != nil {
t.Fatal(err)
}
if stats.TotalSize != 4096 {
t.Fatalf("unexpected stats: %+v", stats)
}
commands, err := os.ReadFile(logPath)
if err != nil {
t.Fatal(err)
}
lines := strings.Split(strings.TrimSpace(string(commands)), "\n")
if len(lines) != 3 || !strings.Contains(lines[0], "stats") || !strings.Contains(lines[1], "unlock") || !strings.Contains(lines[2], "stats") {
t.Fatalf("expected stats, unlock, stats; got %q", lines)
}
}
func TestForgetUsesAgeAndCalendarRetention(t *testing.T) {
dir := t.TempDir()
argsPath := filepath.Join(dir, "args")