testing
parent
8a3b234fe5
commit
d7f9e92fc4
|
@ -119,64 +119,89 @@ func TestFullBTreeIndex(t *testing.T) {
|
|||
|
||||
func TestPartialBTreeIndex(t *testing.T) {
|
||||
|
||||
// Test against the name index.
|
||||
// Test against the extID btree index.
|
||||
run := func(name string, inner func(t *testing.T, db *DB) []*User) {
|
||||
testWithDB(t, name, func(t *testing.T, db *DB) {
|
||||
expected := inner(t, db)
|
||||
|
||||
if err := db.Users.nameBTree.EqualsList(expected); err != nil {
|
||||
if err := db.Users.extIDBTree.EqualsList(expected); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
db.Close()
|
||||
db = OpenDB(db.root, true)
|
||||
|
||||
if err := db.Users.nameBTree.EqualsList(expected); err != nil {
|
||||
if err := db.Users.extIDBTree.EqualsList(expected); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
run("empty", func(t *testing.T, db *DB) []*User {
|
||||
run("insert out", func(t *testing.T, db *DB) []*User {
|
||||
users := []*User{
|
||||
{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "xxx"},
|
||||
{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ggg"},
|
||||
{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "aaa"},
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
if _, err := db.Users.c.Insert(*u); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
return []*User{}
|
||||
})
|
||||
|
||||
run("insert", func(t *testing.T, db *DB) (users []*User) {
|
||||
users = append(users,
|
||||
&User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "xxx"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ggg"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "aaa"})
|
||||
run("insert in", func(t *testing.T, db *DB) []*User {
|
||||
users := []*User{
|
||||
{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "xxx"},
|
||||
{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ggg", ExtID: "x"},
|
||||
{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "aaa"},
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
if _, err := db.Users.c.Insert(*u); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
users[0], users[2] = users[2], users[0]
|
||||
|
||||
return users
|
||||
return []*User{users[1]}
|
||||
})
|
||||
|
||||
run("insert duplicates", func(t *testing.T, db *DB) (users []*User) {
|
||||
users = append(users,
|
||||
&User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "xxx"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ggg"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "xxx"})
|
||||
run("update out to out", func(t *testing.T, db *DB) []*User {
|
||||
users := []*User{
|
||||
{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "aaa"},
|
||||
{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ccc", ExtID: "A"},
|
||||
{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "eee"},
|
||||
{ID: db.Users.c.NextID(), Email: "g@h.com", Name: "ggg", ExtID: "B"},
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
if _, err := db.Users.c.Insert(*u); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
users = []*User{users[1], users[0], users[2]}
|
||||
return users
|
||||
|
||||
err := db.Users.c.Update(users[0].ID, func(u User) (User, error) {
|
||||
u.Name = "axa"
|
||||
users[0].Name = "axa"
|
||||
return u, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return []*User{users[1], users[3]}
|
||||
})
|
||||
|
||||
run("update", func(t *testing.T, db *DB) (users []*User) {
|
||||
users = append(users,
|
||||
&User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "ccc"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "aaa"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "bbb"})
|
||||
run("update in to in", func(t *testing.T, db *DB) []*User {
|
||||
users := []*User{
|
||||
{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "aaa"},
|
||||
{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ccc", ExtID: "A"},
|
||||
{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "eee"},
|
||||
{ID: db.Users.c.NextID(), Email: "g@h.com", Name: "ggg", ExtID: "B"},
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
if _, err := db.Users.c.Insert(*u); err != nil {
|
||||
|
@ -185,23 +210,24 @@ func TestPartialBTreeIndex(t *testing.T) {
|
|||
}
|
||||
|
||||
err := db.Users.c.Update(users[1].ID, func(u User) (User, error) {
|
||||
u.Name = "ccc"
|
||||
u.ExtID = "C"
|
||||
users[1].ExtID = "C"
|
||||
return u, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
users[1].Name = "ccc"
|
||||
|
||||
users = []*User{users[2], users[0], users[1]}
|
||||
return users
|
||||
return []*User{users[3], users[1]}
|
||||
})
|
||||
|
||||
run("update", func(t *testing.T, db *DB) (users []*User) {
|
||||
users = append(users,
|
||||
&User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "bbb"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "aaa"},
|
||||
&User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "bbb"})
|
||||
run("update out to in", func(t *testing.T, db *DB) []*User {
|
||||
users := []*User{
|
||||
{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "aaa"},
|
||||
{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ccc", ExtID: "A"},
|
||||
{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "eee"},
|
||||
{ID: db.Users.c.NextID(), Email: "g@h.com", Name: "ggg", ExtID: "B"},
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
if _, err := db.Users.c.Insert(*u); err != nil {
|
||||
|
@ -209,9 +235,42 @@ func TestPartialBTreeIndex(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
db.Users.c.Delete(users[1].ID)
|
||||
users = []*User{users[0], users[2]}
|
||||
return users
|
||||
err := db.Users.c.Update(users[2].ID, func(u User) (User, error) {
|
||||
u.ExtID = "C"
|
||||
users[2].ExtID = "C"
|
||||
return u, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return []*User{users[1], users[3], users[2]}
|
||||
})
|
||||
|
||||
run("update in to out", func(t *testing.T, db *DB) []*User {
|
||||
users := []*User{
|
||||
{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "aaa"},
|
||||
{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ccc", ExtID: "A"},
|
||||
{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "eee"},
|
||||
{ID: db.Users.c.NextID(), Email: "g@h.com", Name: "ggg", ExtID: "B"},
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
if _, err := db.Users.c.Insert(*u); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
err := db.Users.c.Update(users[1].ID, func(u User) (User, error) {
|
||||
u.ExtID = ""
|
||||
users[1].ExtID = ""
|
||||
return u, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return []*User{users[3]}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,416 +1,83 @@
|
|||
package mdb
|
||||
|
||||
/*
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCollection(t *testing.T) {
|
||||
type Item struct {
|
||||
ID uint64
|
||||
Name string // Full map.
|
||||
ExtID string // Partial map.
|
||||
}
|
||||
|
||||
sanitize := func(item *Item) {
|
||||
item.Name = strings.TrimSpace(item.Name)
|
||||
item.ExtID = strings.TrimSpace(item.ExtID)
|
||||
}
|
||||
|
||||
ErrInvalidExtID := errors.New("InvalidExtID")
|
||||
|
||||
validate := func(item *Item) error {
|
||||
if len(item.ExtID) != 0 && !strings.HasPrefix(item.ExtID, "x") {
|
||||
return ErrInvalidExtID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
run := func(name string, inner func(t *testing.T, c *Collection[Item])) {
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
root := filepath.Join(os.TempDir(), randString())
|
||||
//defer os.RemoveAll(root)
|
||||
|
||||
db := NewPrimary(root)
|
||||
defer db.Close()
|
||||
|
||||
c := NewCollection(db, randString(), func(i *Item) uint64 { return i.ID })
|
||||
c.SetSanitize(sanitize)
|
||||
c.SetValidate(validate)
|
||||
|
||||
NewMapIndex(c,
|
||||
"Name",
|
||||
func(i *Item) string { return i.Name },
|
||||
nil)
|
||||
|
||||
NewMapIndex(c,
|
||||
"ExtID",
|
||||
func(i *Item) string { return i.ExtID },
|
||||
func(i *Item) bool { return i.ExtID != "" })
|
||||
|
||||
inner(t, c)
|
||||
})
|
||||
}
|
||||
|
||||
verifyCollectionOnce := func(c *Collection[Item], expected ...Item) error {
|
||||
if len(c.items.m) != len(expected) {
|
||||
return fmt.Errorf("Expected %d items, but got %d.", len(expected), len(c.items.m))
|
||||
}
|
||||
|
||||
for _, item := range expected {
|
||||
i, ok := c.Get(item.ID)
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing expected item: %v", item)
|
||||
}
|
||||
if !reflect.DeepEqual(i, item) {
|
||||
return fmt.Errorf("Items aren't equal: %v != %v", i, item)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
verifyCollection := func(c *Collection[Item], expected ...Item) error {
|
||||
if err := verifyCollectionOnce(c, expected...); err != nil {
|
||||
return fmt.Errorf("%w: original", err)
|
||||
}
|
||||
|
||||
// Reload the collection and verify again.
|
||||
c.db.Close()
|
||||
|
||||
db := NewSecondary(c.db.root)
|
||||
c2 := NewCollection(db, c.name, func(i *Item) uint64 { return i.ID })
|
||||
db.Start()
|
||||
defer db.Close()
|
||||
return verifyCollectionOnce(c2, expected...)
|
||||
}
|
||||
|
||||
run("empty", func(t *testing.T, c *Collection[Item]) {
|
||||
err := verifyCollection(c)
|
||||
if err != nil {
|
||||
testWithDB(t, "insert on secondary", func(t *testing.T, db *DB) {
|
||||
c := db.Users.c
|
||||
c.primary = false
|
||||
if _, err := c.Insert(User{}); !errors.Is(err, ErrReadOnly) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("check NextID", func(t *testing.T, c *Collection[Item]) {
|
||||
id := c.NextID()
|
||||
for i := 0; i < 100; i++ {
|
||||
next := c.NextID()
|
||||
if next <= id {
|
||||
t.Fatal(next, id)
|
||||
}
|
||||
id = next
|
||||
}
|
||||
})
|
||||
|
||||
run("insert", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{1, "Name", "xid"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = verifyCollection(c, item)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("insert concurrent differnt items", func(t *testing.T, c *Collection[Item]) {
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
c.Insert(Item{
|
||||
ID: c.NextID(),
|
||||
Name: fmt.Sprintf("Name.%03d", i),
|
||||
ExtID: fmt.Sprintf("x.%03d", i),
|
||||
})
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
})
|
||||
|
||||
run("insert concurrent same item", func(t *testing.T, c *Collection[Item]) {
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
c.Insert(Item{
|
||||
ID: 1,
|
||||
Name: "My name",
|
||||
})
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if err := verifyCollection(c, Item{1, "My name", ""}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("insert invalid", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{
|
||||
testWithDB(t, "insert validation error", func(t *testing.T, db *DB) {
|
||||
c := db.Users.c
|
||||
user := User{
|
||||
ID: c.NextID(),
|
||||
Name: "Hello",
|
||||
ExtID: "123"})
|
||||
if !errors.Is(err, ErrInvalidExtID) {
|
||||
t.Fatal(item, err)
|
||||
Email: "a@b.com",
|
||||
}
|
||||
})
|
||||
|
||||
run("insert duplicate ID", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{
|
||||
ID: c.NextID(),
|
||||
Name: "Hello",
|
||||
})
|
||||
if err != nil {
|
||||
if _, err := c.Insert(user); !errors.Is(err, ErrInvalidName) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
item2, err := c.Insert(Item{ID: item.ID, Name: "Item"})
|
||||
if !errors.Is(err, ErrDuplicate) {
|
||||
t.Fatal(err, item2)
|
||||
}
|
||||
})
|
||||
|
||||
run("insert duplicate name", func(t *testing.T, c *Collection[Item]) {
|
||||
_, err := c.Insert(Item{
|
||||
ID: c.NextID(),
|
||||
Name: "Hello",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
item2, err := c.Insert(Item{ID: c.NextID(), Name: "Hello"})
|
||||
if !errors.Is(err, ErrDuplicate) {
|
||||
t.Fatal(err, item2)
|
||||
}
|
||||
})
|
||||
|
||||
run("insert duplicate ext ID", func(t *testing.T, c *Collection[Item]) {
|
||||
_, err := c.Insert(Item{
|
||||
testWithDB(t, "insert duplicate", func(t *testing.T, db *DB) {
|
||||
c := db.Users.c
|
||||
user := User{
|
||||
ID: c.NextID(),
|
||||
Name: "Hello",
|
||||
ExtID: "x1",
|
||||
Name: "adsf",
|
||||
Email: "a@b.com",
|
||||
}
|
||||
if _, err := c.Insert(user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := c.Insert(user); !errors.Is(err, ErrDuplicate) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
testWithDB(t, "update on secondary", func(t *testing.T, db *DB) {
|
||||
c := db.Users.c
|
||||
user := User{ID: c.NextID(), Name: "adsf", Email: "a@b.com"}
|
||||
if _, err := c.Insert(user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.primary = false
|
||||
|
||||
err := c.Update(user.ID, func(u User) (User, error) {
|
||||
u.Name = "xxx"
|
||||
return u, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
item2, err := c.Insert(Item{ID: c.NextID(), Name: "name", ExtID: "x1"})
|
||||
if !errors.Is(err, ErrDuplicate) {
|
||||
t.Fatal(err, item2)
|
||||
}
|
||||
})
|
||||
|
||||
run("get not found", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{
|
||||
ID: c.NextID(),
|
||||
Name: "Hello",
|
||||
ExtID: "x1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if i, ok := c.Get(item.ID + 1); ok {
|
||||
t.Fatal(i)
|
||||
}
|
||||
})
|
||||
|
||||
run("update", func(t *testing.T, c *Collection[Item]) {
|
||||
item1, err := c.Insert(Item{
|
||||
ID: c.NextID(),
|
||||
Name: "Hello",
|
||||
ExtID: "x1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = c.Update(item1.ID, func(item Item) (Item, error) {
|
||||
item.Name = "name"
|
||||
item.ExtID = "x88"
|
||||
return item, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = verifyCollection(c, Item{ID: item1.ID, Name: "name", ExtID: "x88"})
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrReadOnly) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("update concurrent different items", func(t *testing.T, c *Collection[Item]) {
|
||||
items := make([]Item, 10)
|
||||
for i := range items {
|
||||
item, err := c.Insert(Item{ID: c.NextID(), Name: randString()})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
items[i] = item
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(10)
|
||||
for i := range items {
|
||||
item := items[i]
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for x := 0; x < 100; x++ {
|
||||
err := c.Update(item.ID, func(i Item) (Item, error) {
|
||||
i.Name = randString()
|
||||
return i, nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
})
|
||||
|
||||
run("update concurrent same item", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{ID: c.NextID(), Name: randString()})
|
||||
if err != nil {
|
||||
testWithDB(t, "update not found", func(t *testing.T, db *DB) {
|
||||
c := db.Users.c
|
||||
user := User{ID: c.NextID(), Name: "adsf", Email: "a@b.com"}
|
||||
if _, err := c.Insert(user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for x := 0; x < 100; x++ {
|
||||
err := c.Update(item.ID, func(i Item) (Item, error) {
|
||||
i.Name = randString()
|
||||
return i, nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
})
|
||||
|
||||
run("update not found", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{ID: c.NextID(), Name: randString()})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = c.Update(item.ID+1, func(i Item) (Item, error) {
|
||||
i.Name = randString()
|
||||
return i, nil
|
||||
err := c.Update(user.ID+1, func(u User) (User, error) {
|
||||
u.Name = "xxx"
|
||||
return u, nil
|
||||
})
|
||||
if !errors.Is(err, ErrNotFound) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("update mismatched IDs", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{ID: c.NextID(), Name: randString()})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Update w/ failed valiation
|
||||
|
||||
err = c.Update(item.ID, func(i Item) (Item, error) {
|
||||
i.ID++
|
||||
return i, nil
|
||||
})
|
||||
|
||||
if !errors.Is(err, ErrMismatchedIDs) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("update invalid", func(t *testing.T, c *Collection[Item]) {
|
||||
item, err := c.Insert(Item{ID: c.NextID(), Name: randString()})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = c.Update(item.ID, func(i Item) (Item, error) {
|
||||
i.ExtID = "a"
|
||||
return i, nil
|
||||
})
|
||||
if !errors.Is(err, ErrInvalidExtID) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("delete", func(t *testing.T, c *Collection[Item]) {
|
||||
item1, err := c.Insert(Item{c.NextID(), "name1", "x1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
item2, err := c.Insert(Item{c.NextID(), "name2", "x2"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
item3, err := c.Insert(Item{c.NextID(), "name3", "x3"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.Delete(item2.ID)
|
||||
if err := verifyCollection(c, item1, item3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
run("delete not found", func(t *testing.T, c *Collection[Item]) {
|
||||
item1, err := c.Insert(Item{c.NextID(), "name1", "x1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
item2, err := c.Insert(Item{c.NextID(), "name2", "x2"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
item3, err := c.Insert(Item{c.NextID(), "name3", "x3"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c.Delete(c.NextID())
|
||||
if err := verifyCollection(c, item1, item2, item3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
// Delete on secondary
|
||||
// Delete not found
|
||||
// Get found
|
||||
// Get not found
|
||||
}
|
||||
|
||||
func BenchmarkLoad(b *testing.B) {
|
||||
type Item struct {
|
||||
ID uint64
|
||||
Name string
|
||||
}
|
||||
|
||||
root := filepath.Join("test-files", randString())
|
||||
db := NewPrimary(root)
|
||||
getID := func(item *Item) uint64 { return item.ID }
|
||||
|
||||
c := NewCollection(db, "items", getID)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
item := Item{ID: c.NextID(), Name: fmt.Sprintf("Name %04d", i)}
|
||||
c.Insert(item)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
c2 := NewCollection(db, "items", getID)
|
||||
log.Print(len(c2.items.m))
|
||||
if len(c2.items.m) != b.N {
|
||||
panic("What?")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
Reference in New Issue