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) } }