diff --git a/checker/checker.go b/checker/checker.go index e6ab23dfb..2c9536f14 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -60,7 +60,7 @@ func (e ErrDuplicatePacks) Error() string { } // LoadIndex loads all index files. -func (c *Checker) LoadIndex() error { +func (c *Checker) LoadIndex() (hints []error, errs []error) { debug.Log("LoadIndex", "Start") type indexRes struct { Index *repository.Index @@ -107,13 +107,19 @@ func (c *Checker) LoadIndex() error { done := make(chan struct{}) defer close(done) + if perr != nil { + errs = append(errs, perr) + return hints, errs + } + packToIndex := make(map[backend.ID]backend.IDSet) for res := range indexCh { debug.Log("LoadIndex", "process index %v", res.ID) idxID, err := backend.ParseID(res.ID) if err != nil { - return err + errs = append(errs, fmt.Errorf("unable to parse as index ID: %v", res.ID)) + continue } c.indexes[idxID] = res.Index @@ -142,16 +148,16 @@ func (c *Checker) LoadIndex() error { for packID := range c.packs { debug.Log("LoadIndex", " check pack %v: contained in %d indexes", packID.Str(), len(packToIndex[packID])) if len(packToIndex[packID]) > 1 { - return ErrDuplicatePacks{ + hints = append(hints, ErrDuplicatePacks{ PackID: packID, Indexes: packToIndex[packID], - } + }) } } c.repo.SetIndex(c.masterIndex) - return perr + return hints, errs } // PackError describes an error with a specific pack. diff --git a/checker/checker_test.go b/checker/checker_test.go index 24ac88ec5..37d7f7a7b 100644 --- a/checker/checker_test.go +++ b/checker/checker_test.go @@ -59,7 +59,15 @@ func TestCheckRepo(t *testing.T) { repo := OpenLocalRepo(t, repodir) chkr := checker.New(repo) - OK(t, chkr.LoadIndex()) + hints, errs := chkr.LoadIndex() + if len(errs) > 0 { + t.Fatalf("expected no errors, got %v: %v", len(errs), errs) + } + + if len(hints) > 0 { + t.Errorf("expected no hints, got %v: %v", len(hints), hints) + } + OKs(t, checkPacks(chkr)) OKs(t, checkStruct(chkr)) }) @@ -73,8 +81,16 @@ func TestMissingPack(t *testing.T) { OK(t, repo.Backend().Remove(backend.Data, packID)) chkr := checker.New(repo) - OK(t, chkr.LoadIndex()) - errs := checkPacks(chkr) + hints, errs := chkr.LoadIndex() + if len(errs) > 0 { + t.Fatalf("expected no errors, got %v: %v", len(errs), errs) + } + + if len(hints) > 0 { + t.Errorf("expected no hints, got %v: %v", len(hints), hints) + } + + errs = checkPacks(chkr) Assert(t, len(errs) == 1, "expected exactly one error, got %v", len(errs)) @@ -97,8 +113,16 @@ func TestUnreferencedPack(t *testing.T) { OK(t, repo.Backend().Remove(backend.Index, indexID)) chkr := checker.New(repo) - OK(t, chkr.LoadIndex()) - errs := checkPacks(chkr) + hints, errs := chkr.LoadIndex() + if len(errs) > 0 { + t.Fatalf("expected no errors, got %v: %v", len(errs), errs) + } + + if len(hints) > 0 { + t.Errorf("expected no hints, got %v: %v", len(hints), hints) + } + + errs = checkPacks(chkr) Assert(t, len(errs) == 1, "expected exactly one error, got %v", len(errs)) @@ -130,7 +154,15 @@ func TestUnreferencedBlobs(t *testing.T) { sort.Sort(unusedBlobsBySnapshot) chkr := checker.New(repo) - OK(t, chkr.LoadIndex()) + hints, errs := chkr.LoadIndex() + if len(errs) > 0 { + t.Fatalf("expected no errors, got %v: %v", len(errs), errs) + } + + if len(hints) > 0 { + t.Errorf("expected no hints, got %v: %v", len(hints), hints) + } + OKs(t, checkPacks(chkr)) OKs(t, checkStruct(chkr)) @@ -148,13 +180,27 @@ func TestDuplicatePacksInIndex(t *testing.T) { repo := OpenLocalRepo(t, repodir) chkr := checker.New(repo) - err := chkr.LoadIndex() - if err == nil { - t.Fatalf("did not get expected checker error for duplicate packs in indexes") + hints, errs := chkr.LoadIndex() + if len(hints) == 0 { + t.Fatalf("did not get expected checker hints for duplicate packs in indexes") } - if _, ok := err.(checker.ErrDuplicatePacks); !ok { - t.Fatalf("did not get ErrDuplicatePacks, got %v instead", err) + found := false + for _, hint := range hints { + if _, ok := hint.(checker.ErrDuplicatePacks); ok { + found = true + } else { + t.Errorf("got unexpected hint: %v", hint) + } } + + if !found { + t.Fatalf("did not find hint ErrDuplicatePacks") + } + + if len(errs) > 0 { + t.Errorf("expected no errors, got %v: %v", len(errs), errs) + } + }) } diff --git a/cmd/restic/cmd_check.go b/cmd/restic/cmd_check.go index 0d5993845..a7439be4e 100644 --- a/cmd/restic/cmd_check.go +++ b/cmd/restic/cmd_check.go @@ -50,8 +50,17 @@ func (cmd CmdCheck) Execute(args []string) error { chkr := checker.New(repo) cmd.global.Verbosef("Load indexes\n") - if err = chkr.LoadIndex(); err != nil { - return err + hints, errs := chkr.LoadIndex() + + for _, hint := range hints { + cmd.global.Printf("%v\n", hint) + } + + if len(errs) > 0 { + for _, err := range errs { + cmd.global.Warnf("error: %v\n", err) + } + return fmt.Errorf("LoadIndex returned errors") } done := make(chan struct{})