package bolt import ( "fmt" "github.com/stretchr/testify/assert" "go.etcd.io/bbolt" "testing" "time" ) func TestIndex(t *testing.T) { ns := time.Now().Nanosecond() path := fmt.Sprintf("/tmp/stufflog_idx_test_%s_%d.db", time.Now().Format("20060102150405"), ns) db, err := bbolt.Open(path, 0744, nil) if err != nil { t.Fatal("Failed to open db:", err) } idx, err := newIndex(db, "idx", "stuff", "things") idx2, err := newIndex(db, "idx", "stuff2", "things") testId := []byte("Test") test2Id := []byte("Test2") test3Id := []byte("Test3") test4Id := []byte("Test4") t.Run("Insert Initial", func(t *testing.T) { _ = db.Update(func(tx *bbolt.Tx) error { itx := idx.WithTx(tx) itx2 := idx2.WithTx(tx) assert.NoError(t, itx.Set(testId, "A", "B", "C", "D", "E")) assert.NoError(t, itx.Set(test2Id, "B", "C")) assert.NoError(t, itx.Set(test3Id, "A", "C", "D")) assert.NoError(t, itx.Set(test4Id, "A", "C", "D")) assert.NoError(t, itx2.Set(testId, "user_0")) assert.NoError(t, itx2.Set(test2Id, "user_1")) assert.NoError(t, itx2.Set(test3Id, "user_2")) assert.NoError(t, itx.Set(testId, "A", "B", "C")) assert.NoError(t, itx.Set(testId, "A", "C")) assert.NoError(t, itx.Set(test4Id)) return nil }) }) if t.Failed() { return } t.Run("Check Initial", func(t *testing.T) { _ = db.View(func(tx *bbolt.Tx) error { itx := idx.WithTx(tx) itx2 := idx2.WithTx(tx) ids, err := itx.Get("A") assert.NoError(t, err) assert.Equal(t, [][]byte{testId, test3Id}, ids) ids, err = itx.Get("B") assert.NoError(t, err) assert.Equal(t, [][]byte{test2Id}, ids) ids, err = itx.Get("C") assert.NoError(t, err) assert.Equal(t, [][]byte{testId, test2Id, test3Id}, ids) ids, err = itx.Get("D") assert.NoError(t, err) assert.Equal(t, [][]byte{test3Id}, ids) ids, err = itx2.Get("user_0") assert.NoError(t, err) assert.Equal(t, [][]byte{testId}, ids) ids, err = itx2.Get("user_1") assert.NoError(t, err) assert.Equal(t, [][]byte{test2Id}, ids) ids, err = itx2.Get("user_2") assert.NoError(t, err) assert.Equal(t, [][]byte{test3Id}, ids) return nil }) }) if t.Failed() { return } t.Run("Check Initial Reverse", func(t *testing.T) { _ = db.View(func(tx *bbolt.Tx) error { itx := idx.WithTx(tx) itx2 := idx2.WithTx(tx) values, err := itx.Reverse(testId) assert.NoError(t, err) assert.Equal(t, []string{"A", "C"}, values) values, err = itx.Reverse(test2Id) assert.NoError(t, err) assert.Equal(t, []string{"B", "C"}, values) values, err = itx.Reverse(test3Id) assert.NoError(t, err) assert.Equal(t, []string{"A", "C", "D"}, values) values, err = itx.Reverse(test4Id) assert.NoError(t, err) assert.Empty(t, values) values, err = itx2.Reverse(testId) assert.NoError(t, err) assert.Equal(t, []string{"user_0"}, values) values, err = itx2.Reverse(test2Id) assert.NoError(t, err) assert.Equal(t, []string{"user_1"}, values) values, err = itx2.Reverse(test3Id) assert.NoError(t, err) assert.Equal(t, []string{"user_2"}, values) return nil }) }) if t.Failed() { return } t.Run("Nuke 'n Pave", func(t *testing.T) { _ = db.Update(func(tx *bbolt.Tx) error { assert.NoError(t, idx.Reset(tx)) assert.NoError(t, idx2.Reset(tx)) itx := idx.WithTx(tx) itx2 := idx2.WithTx(tx) assert.NoError(t, itx.Set(testId, "pave")) assert.NoError(t, itx.Set(test2Id, "pave")) assert.NoError(t, itx.Set(test3Id, "pave")) assert.NoError(t, itx2.Set(testId, "pave2")) assert.NoError(t, itx2.Set(test3Id, "pave2")) return nil }) }) if t.Failed() { return } t.Run("Check Nuke 'n Pave", func(t *testing.T) { _ = db.View(func(tx *bbolt.Tx) error { itx := idx.WithTx(tx) itx2 := idx2.WithTx(tx) ids, err := itx.Get("A") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx.Get("B") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx.Get("C") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx.Get("D") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx2.Get("user_0") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx2.Get("user_1") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx2.Get("user_2") assert.NoError(t, err) assert.Empty(t, ids) ids, err = itx.Get("pave") assert.NoError(t, err) assert.Equal(t, [][]byte{testId, test2Id, test3Id}, ids) ids, err = itx2.Get("pave2") assert.NoError(t, err) assert.Equal(t, [][]byte{testId, test3Id}, ids) return nil }) }) if t.Failed() { return } t.Run("Check Nuke 'n Pave Reverse", func(t *testing.T) { _ = db.View(func(tx *bbolt.Tx) error { itx := idx.WithTx(tx) itx2 := idx2.WithTx(tx) values, err := itx.Reverse(testId) assert.NoError(t, err) assert.Equal(t, []string{"pave"}, values) values, err = itx.Reverse(test2Id) assert.NoError(t, err) assert.Equal(t, []string{"pave"}, values) values, err = itx.Reverse(test3Id) assert.NoError(t, err) assert.Equal(t, []string{"pave"}, values) values, err = itx2.Reverse(testId) assert.NoError(t, err) assert.Equal(t, []string{"pave2"}, values) values, err = itx2.Reverse(test2Id) assert.NoError(t, err) assert.Empty(t, values) values, err = itx2.Reverse(test3Id) assert.NoError(t, err) assert.Equal(t, []string{"pave2"}, values) return nil }) }) if t.Failed() { return } }