123 lines
2.2 KiB
Go
123 lines
2.2 KiB
Go
|
package state
|
||
|
|
||
|
import (
|
||
|
"strconv"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
type kv struct {
|
||
|
k uint64
|
||
|
v []byte
|
||
|
}
|
||
|
|
||
|
type bscase struct {
|
||
|
data []kv
|
||
|
// these are the tests to try out
|
||
|
top kv
|
||
|
bottom kv
|
||
|
gets []kv // for each item check the query matches
|
||
|
lte []kv // value for lte queires...
|
||
|
gte []kv // value for gte
|
||
|
}
|
||
|
|
||
|
func TestBasicSpan(t *testing.T) {
|
||
|
|
||
|
a, b, c := []byte{0xaa}, []byte{0xbb}, []byte{0xcc}
|
||
|
|
||
|
lots := make([]kv, 1000)
|
||
|
for i := range lots {
|
||
|
lots[i] = kv{uint64(3 * i), []byte{byte(i / 100), byte(i % 100)}}
|
||
|
}
|
||
|
|
||
|
cases := []bscase{
|
||
|
// simplest queries
|
||
|
{
|
||
|
[]kv{{1, a}, {3, b}, {5, c}},
|
||
|
kv{5, c},
|
||
|
kv{1, a},
|
||
|
[]kv{{1, a}, {3, b}, {5, c}},
|
||
|
[]kv{{2, a}, {77, c}, {3, b}, {0, nil}}, // lte
|
||
|
[]kv{{6, nil}, {2, b}, {1, a}}, // gte
|
||
|
},
|
||
|
// add out of order
|
||
|
{
|
||
|
[]kv{{7, a}, {2, b}, {6, c}},
|
||
|
kv{7, a},
|
||
|
kv{2, b},
|
||
|
[]kv{{2, b}, {6, c}, {7, a}},
|
||
|
[]kv{{4, b}, {7, a}, {1, nil}}, // lte
|
||
|
[]kv{{4, c}, {7, a}, {1, b}}, // gte
|
||
|
},
|
||
|
// add out of order and with duplicates
|
||
|
{
|
||
|
[]kv{{7, a}, {2, b}, {6, c}, {7, c}, {6, b}, {2, a}},
|
||
|
kv{7, c},
|
||
|
kv{2, a},
|
||
|
[]kv{{2, a}, {6, b}, {7, c}},
|
||
|
[]kv{{5, a}, {6, b}, {123, c}}, // lte
|
||
|
[]kv{{0, a}, {3, b}, {7, c}, {8, nil}}, // gte
|
||
|
},
|
||
|
// try lots...
|
||
|
{
|
||
|
lots,
|
||
|
lots[len(lots)-1],
|
||
|
lots[0],
|
||
|
lots,
|
||
|
nil,
|
||
|
nil,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for i, tc := range cases {
|
||
|
store := NewMemKVStore()
|
||
|
|
||
|
// initialize a queue and add items
|
||
|
s := NewSpan(store)
|
||
|
for _, x := range tc.data {
|
||
|
s.Set(x.k, x.v)
|
||
|
}
|
||
|
|
||
|
testSpan(t, i, s, tc)
|
||
|
// reload and try the queries again
|
||
|
s2 := NewSpan(store)
|
||
|
testSpan(t, i+10, s2, tc)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testSpan(t *testing.T, idx int, s *Span, tc bscase) {
|
||
|
assert := assert.New(t)
|
||
|
i := strconv.Itoa(idx)
|
||
|
|
||
|
v, k := s.Top()
|
||
|
assert.Equal(tc.top.k, k, i)
|
||
|
assert.Equal(tc.top.v, v, i)
|
||
|
|
||
|
v, k = s.Bottom()
|
||
|
assert.Equal(tc.bottom.k, k, i)
|
||
|
assert.Equal(tc.bottom.v, v, i)
|
||
|
|
||
|
for _, g := range tc.gets {
|
||
|
v = s.Get(g.k)
|
||
|
assert.Equal(g.v, v, i)
|
||
|
}
|
||
|
|
||
|
for _, l := range tc.lte {
|
||
|
v, k = s.LTE(l.k)
|
||
|
assert.Equal(l.v, v, i)
|
||
|
if l.v != nil {
|
||
|
assert.True(k <= l.k, i)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, t := range tc.gte {
|
||
|
v, k = s.GTE(t.k)
|
||
|
assert.Equal(t.v, v, i)
|
||
|
if t.v != nil {
|
||
|
assert.True(k >= t.k, i)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|