144 lines
4.0 KiB
Go
144 lines
4.0 KiB
Go
|
package commands
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/RoaringBitmap/roaring/roaring64"
|
||
|
)
|
||
|
|
||
|
func newMockForwardChunkLocator(chunks [][]byte) ChunkLocator {
|
||
|
return func(block uint64) (ChunkProvider, bool, error) {
|
||
|
for i, v := range chunks {
|
||
|
bm := roaring64.NewBitmap()
|
||
|
if _, err := bm.ReadFrom(bytes.NewReader(v)); err != nil {
|
||
|
return nil, false, err
|
||
|
}
|
||
|
if block > bm.Maximum() {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
return newMockForwardChunkProvider(chunks[i:]), true, nil
|
||
|
}
|
||
|
|
||
|
// Not found; return the last to simulate the behavior of returning
|
||
|
// the 0xffff... chunk
|
||
|
if len(chunks) > 0 {
|
||
|
return newMockForwardChunkProvider(chunks[len(chunks)-1:]), true, nil
|
||
|
}
|
||
|
|
||
|
return nil, true, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func newMockForwardChunkProvider(chunks [][]byte) ChunkProvider {
|
||
|
i := 0
|
||
|
return func() ([]byte, bool, error) {
|
||
|
if i >= len(chunks) {
|
||
|
return nil, false, nil
|
||
|
}
|
||
|
|
||
|
chunk := chunks[i]
|
||
|
i++
|
||
|
return chunk, true, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWith1Chunk(t *testing.T) {
|
||
|
// Mocks 1 chunk
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 0)
|
||
|
|
||
|
checkNext(t, blockProvider, 1000, true)
|
||
|
checkNext(t, blockProvider, 1005, true)
|
||
|
checkNext(t, blockProvider, 1010, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWith1ChunkMiddleBlock(t *testing.T) {
|
||
|
// Mocks 1 chunk
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 1005)
|
||
|
|
||
|
checkNext(t, blockProvider, 1005, true)
|
||
|
checkNext(t, blockProvider, 1010, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWith1ChunkNotExactBlock(t *testing.T) {
|
||
|
// Mocks 1 chunk
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 1007)
|
||
|
|
||
|
checkNext(t, blockProvider, 1010, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWith1ChunkLastBlock(t *testing.T) {
|
||
|
// Mocks 1 chunk
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 1010)
|
||
|
|
||
|
checkNext(t, blockProvider, 1010, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWith1ChunkBlockNotFound(t *testing.T) {
|
||
|
// Mocks 1 chunk
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 1100)
|
||
|
|
||
|
checkNext(t, blockProvider, 0, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWithNoChunks(t *testing.T) {
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 0)
|
||
|
|
||
|
checkNext(t, blockProvider, 0, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWithMultipleChunks(t *testing.T) {
|
||
|
// Mocks 2 chunks
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
chunk2 := createBitmap(t, []uint64{1501, 1600})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 0)
|
||
|
|
||
|
checkNext(t, blockProvider, 1000, true)
|
||
|
checkNext(t, blockProvider, 1005, true)
|
||
|
checkNext(t, blockProvider, 1010, true)
|
||
|
checkNext(t, blockProvider, 1501, true)
|
||
|
checkNext(t, blockProvider, 1600, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) {
|
||
|
// Mocks 2 chunks
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
chunk2 := createBitmap(t, []uint64{1501, 1600})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 1300)
|
||
|
|
||
|
checkNext(t, blockProvider, 1501, true)
|
||
|
checkNext(t, blockProvider, 1600, false)
|
||
|
}
|
||
|
|
||
|
func TestForwardBlockProviderWithMultipleChunksBlockNotFound(t *testing.T) {
|
||
|
// Mocks 2 chunks
|
||
|
chunk1 := createBitmap(t, []uint64{1000, 1005, 1010})
|
||
|
chunk2 := createBitmap(t, []uint64{1501, 1600})
|
||
|
|
||
|
chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2})
|
||
|
blockProvider := NewForwardBlockProvider(chunkLocator, 1700)
|
||
|
|
||
|
checkNext(t, blockProvider, 0, false)
|
||
|
}
|