95 lines
1.7 KiB
Go
95 lines
1.7 KiB
Go
package pfile
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
type FileState struct {
|
|
SeqNum uint64
|
|
Data map[[2]uint64][]byte
|
|
}
|
|
|
|
func (pf *File) Assert(t *testing.T, state pFileState) {
|
|
t.Helper()
|
|
|
|
pf.lock.RLock()
|
|
defer pf.lock.RUnlock()
|
|
|
|
idx, err := NewIndex(pf)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
data := map[[2]uint64][]byte{}
|
|
err = IterateAllocated(pf, idx, func(cID, iID uint64, fileData []byte) error {
|
|
data[[2]uint64{cID, iID}] = bytes.Clone(fileData)
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(data) != len(state.Data) {
|
|
t.Fatalf("Expected %d items but got %d.", len(state.Data), len(data))
|
|
}
|
|
|
|
for key, expected := range state.Data {
|
|
val, ok := data[key]
|
|
if !ok {
|
|
t.Fatalf("No data found for key %v.", key)
|
|
}
|
|
if !bytes.Equal(val, expected) {
|
|
t.Fatalf("Incorrect data for key %v.", key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFileStateUpdateRandom(t *testing.T) {
|
|
t.Parallel()
|
|
tmpDir := t.TempDir()
|
|
walDir := filepath.Join(tmpDir, "wal")
|
|
pageFilePath := filepath.Join(tmpDir, "pagefile")
|
|
|
|
if err := os.MkdirAll(walDir, 0700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pf, err := Open(pageFilePath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
idx, err := NewIndex(pf)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
state := pFileState{
|
|
Data: map[[2]uint64][]byte{},
|
|
}
|
|
|
|
for i := uint64(1); i < 256; i++ {
|
|
changes := randomChangeList()
|
|
idx.StageChanges(changes)
|
|
|
|
if err := pf.ApplyChanges(changes); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
idx.ApplyChanges(changes)
|
|
|
|
for _, ch := range changes {
|
|
if !ch.Store {
|
|
delete(state.Data, [2]uint64{ch.CollectionID, ch.ItemID})
|
|
} else {
|
|
state.Data[[2]uint64{ch.CollectionID, ch.ItemID}] = ch.Data
|
|
}
|
|
}
|
|
|
|
pf.Assert(t, state)
|
|
}
|
|
}
|