forked from TrueCloudLab/restic
Let the checker return a list of hints along with errors
This commit is contained in:
parent
91e1929b52
commit
96ecc26507
3 changed files with 79 additions and 18 deletions
|
@ -60,7 +60,7 @@ func (e ErrDuplicatePacks) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadIndex loads all index files.
|
// LoadIndex loads all index files.
|
||||||
func (c *Checker) LoadIndex() error {
|
func (c *Checker) LoadIndex() (hints []error, errs []error) {
|
||||||
debug.Log("LoadIndex", "Start")
|
debug.Log("LoadIndex", "Start")
|
||||||
type indexRes struct {
|
type indexRes struct {
|
||||||
Index *repository.Index
|
Index *repository.Index
|
||||||
|
@ -107,13 +107,19 @@ func (c *Checker) LoadIndex() error {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
|
if perr != nil {
|
||||||
|
errs = append(errs, perr)
|
||||||
|
return hints, errs
|
||||||
|
}
|
||||||
|
|
||||||
packToIndex := make(map[backend.ID]backend.IDSet)
|
packToIndex := make(map[backend.ID]backend.IDSet)
|
||||||
|
|
||||||
for res := range indexCh {
|
for res := range indexCh {
|
||||||
debug.Log("LoadIndex", "process index %v", res.ID)
|
debug.Log("LoadIndex", "process index %v", res.ID)
|
||||||
idxID, err := backend.ParseID(res.ID)
|
idxID, err := backend.ParseID(res.ID)
|
||||||
if err != nil {
|
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
|
c.indexes[idxID] = res.Index
|
||||||
|
@ -142,16 +148,16 @@ func (c *Checker) LoadIndex() error {
|
||||||
for packID := range c.packs {
|
for packID := range c.packs {
|
||||||
debug.Log("LoadIndex", " check pack %v: contained in %d indexes", packID.Str(), len(packToIndex[packID]))
|
debug.Log("LoadIndex", " check pack %v: contained in %d indexes", packID.Str(), len(packToIndex[packID]))
|
||||||
if len(packToIndex[packID]) > 1 {
|
if len(packToIndex[packID]) > 1 {
|
||||||
return ErrDuplicatePacks{
|
hints = append(hints, ErrDuplicatePacks{
|
||||||
PackID: packID,
|
PackID: packID,
|
||||||
Indexes: packToIndex[packID],
|
Indexes: packToIndex[packID],
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.repo.SetIndex(c.masterIndex)
|
c.repo.SetIndex(c.masterIndex)
|
||||||
|
|
||||||
return perr
|
return hints, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackError describes an error with a specific pack.
|
// PackError describes an error with a specific pack.
|
||||||
|
|
|
@ -59,7 +59,15 @@ func TestCheckRepo(t *testing.T) {
|
||||||
repo := OpenLocalRepo(t, repodir)
|
repo := OpenLocalRepo(t, repodir)
|
||||||
|
|
||||||
chkr := checker.New(repo)
|
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, checkPacks(chkr))
|
||||||
OKs(t, checkStruct(chkr))
|
OKs(t, checkStruct(chkr))
|
||||||
})
|
})
|
||||||
|
@ -73,8 +81,16 @@ func TestMissingPack(t *testing.T) {
|
||||||
OK(t, repo.Backend().Remove(backend.Data, packID))
|
OK(t, repo.Backend().Remove(backend.Data, packID))
|
||||||
|
|
||||||
chkr := checker.New(repo)
|
chkr := checker.New(repo)
|
||||||
OK(t, chkr.LoadIndex())
|
hints, errs := chkr.LoadIndex()
|
||||||
errs := checkPacks(chkr)
|
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,
|
Assert(t, len(errs) == 1,
|
||||||
"expected exactly one error, got %v", len(errs))
|
"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))
|
OK(t, repo.Backend().Remove(backend.Index, indexID))
|
||||||
|
|
||||||
chkr := checker.New(repo)
|
chkr := checker.New(repo)
|
||||||
OK(t, chkr.LoadIndex())
|
hints, errs := chkr.LoadIndex()
|
||||||
errs := checkPacks(chkr)
|
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,
|
Assert(t, len(errs) == 1,
|
||||||
"expected exactly one error, got %v", len(errs))
|
"expected exactly one error, got %v", len(errs))
|
||||||
|
@ -130,7 +154,15 @@ func TestUnreferencedBlobs(t *testing.T) {
|
||||||
sort.Sort(unusedBlobsBySnapshot)
|
sort.Sort(unusedBlobsBySnapshot)
|
||||||
|
|
||||||
chkr := checker.New(repo)
|
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, checkPacks(chkr))
|
||||||
OKs(t, checkStruct(chkr))
|
OKs(t, checkStruct(chkr))
|
||||||
|
|
||||||
|
@ -148,13 +180,27 @@ func TestDuplicatePacksInIndex(t *testing.T) {
|
||||||
repo := OpenLocalRepo(t, repodir)
|
repo := OpenLocalRepo(t, repodir)
|
||||||
|
|
||||||
chkr := checker.New(repo)
|
chkr := checker.New(repo)
|
||||||
err := chkr.LoadIndex()
|
hints, errs := chkr.LoadIndex()
|
||||||
if err == nil {
|
if len(hints) == 0 {
|
||||||
t.Fatalf("did not get expected checker error for duplicate packs in indexes")
|
t.Fatalf("did not get expected checker hints for duplicate packs in indexes")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := err.(checker.ErrDuplicatePacks); !ok {
|
found := false
|
||||||
t.Fatalf("did not get ErrDuplicatePacks, got %v instead", err)
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,17 @@ func (cmd CmdCheck) Execute(args []string) error {
|
||||||
chkr := checker.New(repo)
|
chkr := checker.New(repo)
|
||||||
|
|
||||||
cmd.global.Verbosef("Load indexes\n")
|
cmd.global.Verbosef("Load indexes\n")
|
||||||
if err = chkr.LoadIndex(); err != nil {
|
hints, errs := chkr.LoadIndex()
|
||||||
return err
|
|
||||||
|
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{})
|
done := make(chan struct{})
|
||||||
|
|
Loading…
Reference in a new issue