package wal import ( "fmt" "sync" "testing" "github.com/dailz/go-kv/config" ) func newTestWalWriter(t *testing.T) *WalWriter { t.Helper() cfg := config.Defaults() ww, err := NewWalWriter(&cfg, t.TempDir(), 0, 0) if err != nil { t.Fatalf("NewWalWriter: %v", err) } t.Cleanup(func() { if err := ww.Close(); err != nil { t.Fatalf("Close: %v", err) } }) return ww } func TestWalWriterSinglePut(t *testing.T) { ww := newTestWalWriter(t) if err := ww.Put([]byte("k1"), []byte("v1")); err != nil { t.Fatalf("Put: %v", err) } got := ww.Get([]byte("k1")) if !got.Found { t.Fatal("Get(k1) not found") } if string(got.Value) != "v1" { t.Fatalf("Get(k1) value = %q, want %q", got.Value, "v1") } } func TestWalWriterMultiplePuts(t *testing.T) { ww := newTestWalWriter(t) for i := range 10 { key := fmt.Appendf(nil, "k%d", i) value := fmt.Appendf(nil, "v%d", i) if err := ww.Put(key, value); err != nil { t.Fatalf("Put(%q): %v", key, err) } } for i := range 10 { key := fmt.Appendf(nil, "k%d", i) want := fmt.Sprintf("v%d", i) got := ww.Get(key) if !got.Found { t.Fatalf("Get(%q) not found", key) } if string(got.Value) != want { t.Fatalf("Get(%q) value = %q, want %q", key, got.Value, want) } } } func TestWalWriterGroupCommit(t *testing.T) { ww := newTestWalWriter(t) const writers = 5 var wg sync.WaitGroup errCh := make(chan error, writers) for i := range writers { wg.Go(func() { key := fmt.Appendf(nil, "group-k%d", i) value := fmt.Appendf(nil, "group-v%d", i) if err := ww.Put(key, value); err != nil { errCh <- fmt.Errorf("put %d: %w", i, err) } }) } wg.Wait() close(errCh) for err := range errCh { if err != nil { t.Fatal(err) } } for i := range writers { key := fmt.Appendf(nil, "group-k%d", i) want := fmt.Sprintf("group-v%d", i) got := ww.Get(key) if !got.Found { t.Fatalf("Get(%q) not found", key) } if string(got.Value) != want { t.Fatalf("Get(%q) value = %q, want %q", key, got.Value, want) } } } func TestWalWriterDelete(t *testing.T) { ww := newTestWalWriter(t) if err := ww.Put([]byte("k"), []byte("v")); err != nil { t.Fatalf("Put: %v", err) } if err := ww.Delete([]byte("k")); err != nil { t.Fatalf("Delete: %v", err) } got := ww.Get([]byte("k")) if got.Found { t.Fatalf("Get(k) found deleted key with value %q", got.Value) } }