package pfile import ( "bytes" crand "crypto/rand" "math/rand" "testing" "git.crumpington.com/public/jldb/lib/errs" ) func randomPage(t *testing.T) dataPage { p := newDataPage() h := p.Header() x := rand.Float32() if x > 0.66 { h.PageType = pageTypeFree h.DataSize = 0 } else if x < 0.33 { h.PageType = pageTypeHead h.DataSize = rand.Uint64() } else { h.PageType = pageTypeData h.DataSize = rand.Uint64() } h.CollectionID = rand.Uint64() h.ItemID = rand.Uint64() dataSize := h.DataSize if h.DataSize > pageDataSize { dataSize = pageDataSize } if _, err := crand.Read(p.Data()[:dataSize]); err != nil { t.Fatal(err) } h.CRC = p.ComputeCRC() return p } // ---------------------------------------------------------------------------- func TestPageValidate(t *testing.T) { for i := 0; i < 100; i++ { p := randomPage(t) // Should be valid initially. if err := p.Validate(); err != nil { t.Fatal(err) } for i := 0; i < pageSize; i++ { p[i]++ if err := p.Validate(); !errs.Corrupt.Is(err) { t.Fatal(err) } p[i]-- } // Should be valid initially. if err := p.Validate(); err != nil { t.Fatal(err) } } } func TestPageEmptyIsValid(t *testing.T) { if err := emptyPage.Validate(); err != nil { t.Fatal(err) } } func TestPageWrite(t *testing.T) { for i := 0; i < 100; i++ { page := newDataPage() h := page.Header() h.PageType = pageTypeData h.CollectionID = rand.Uint64() h.ItemID = rand.Uint64() h.DataSize = uint64(1 + rand.Int63n(2*pageDataSize)) data := make([]byte, h.DataSize) crand.Read(data) n := page.Write(data) h.CRC = page.ComputeCRC() if n > pageDataSize || n < 1 { t.Fatal(n) } if !bytes.Equal(data[:n], page.Data()[:n]) { t.Fatal(data[:n], page.Data()[:n]) } if err := page.Validate(); err != nil { t.Fatal(err) } } }