Release URBM 2026.06.15.r010
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user