Files
distributor/internal/storage/walk_test.go

108 lines
2.9 KiB
Go

package storage
import (
"context"
"errors"
"testing"
)
func TestWalkEmitterHonorsLimit(t *testing.T) {
emitter := NewWalkEmitter(context.Background(), "test", WalkOptions{Limit: 2}, func(Entry) error {
return nil
})
if err := emitter.Emit(Entry{Path: "one"}); err != nil {
t.Fatalf("first Emit() error = %v", err)
}
if err := emitter.Emit(Entry{Path: "two"}); err != nil {
t.Fatalf("second Emit() error = %v", err)
}
if err := emitter.Emit(Entry{Path: "three"}); !errors.Is(err, ErrStopWalk) {
t.Fatalf("third Emit() error = %v, want ErrStopWalk", err)
}
if !emitter.LimitReached() {
t.Fatal("LimitReached() = false, want true")
}
}
func TestWalkEmitterStopsWithoutError(t *testing.T) {
emitter := NewWalkEmitter(context.Background(), "test", WalkOptions{}, func(Entry) error {
return ErrStopWalk
})
err := emitter.Emit(Entry{Path: "one"})
if !errors.Is(err, ErrStopWalk) {
t.Fatalf("Emit() error = %v, want ErrStopWalk", err)
}
if err := FinishWalk(err); err != nil {
t.Fatalf("FinishWalk() error = %v, want nil", err)
}
}
func TestWalkEmitterWrapsCallbackErrors(t *testing.T) {
callbackErr := errors.New("callback failed")
emitter := NewWalkEmitter(context.Background(), "test", WalkOptions{}, func(Entry) error {
return callbackErr
})
err := emitter.Emit(Entry{Path: "one"})
if !errors.Is(err, callbackErr) {
t.Fatalf("Emit() error = %v, want callback error", err)
}
var storageErr *Error
if !errors.As(err, &storageErr) {
t.Fatalf("Emit() error type = %T, want *Error", err)
}
if storageErr.Op != OpWalk || storageErr.Backend != "test" || storageErr.Path != "one" || storageErr.Kind != ErrUnknown {
t.Fatalf("wrapped error = %#v", storageErr)
}
}
func TestWalkEmitterHonorsContextCancellation(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
called := false
emitter := NewWalkEmitter(ctx, "test", WalkOptions{}, func(Entry) error {
called = true
return nil
})
err := emitter.Emit(Entry{Path: "one"})
if !errors.Is(err, context.Canceled) {
t.Fatalf("Emit() error = %v, want context.Canceled", err)
}
if called {
t.Fatal("callback was called after context cancellation")
}
}
func TestHasAnyUsesNonRecursiveLimitOneWalk(t *testing.T) {
backend := &recordingBackend{}
found, err := HasAny(context.Background(), backend, "bundle")
if err != nil {
t.Fatalf("HasAny() error = %v", err)
}
if !found {
t.Fatal("HasAny() = false, want true")
}
if backend.prefix != "bundle" {
t.Fatalf("walk prefix = %q, want bundle", backend.prefix)
}
if backend.opts != (WalkOptions{Recursive: false, Limit: 1}) {
t.Fatalf("walk options = %#v, want non-recursive limit one", backend.opts)
}
}
type recordingBackend struct {
Backend
prefix string
opts WalkOptions
}
func (b *recordingBackend) Walk(_ context.Context, prefix string, opts WalkOptions, fn WalkFunc) error {
b.prefix = prefix
b.opts = opts
return FinishWalk(fn(Entry{Path: "bundle/file.txt", Type: EntryTypeFile}))
}