102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
package main
|
|
|
|
import "testing"
|
|
|
|
func TestAdaptiveSizerRecoversFromMinimum(t *testing.T) {
|
|
opts := chunkClientOptions{
|
|
startSize: 64,
|
|
minSize: 32,
|
|
maxSize: 1024,
|
|
adaptive: true,
|
|
adaptSuccesses: 2,
|
|
}
|
|
s := newAdaptiveSizer("test", 64, opts)
|
|
_, next := s.Failure(64)
|
|
if next != 32 {
|
|
t.Fatalf("failure should reduce 64 -> 32, got %d", next)
|
|
}
|
|
for i := 0; i < 16; i++ {
|
|
s.Success(32)
|
|
}
|
|
if got := s.Current(); got <= 32 {
|
|
t.Fatalf("adaptive controller remained stuck at minimum: %d", got)
|
|
}
|
|
}
|
|
|
|
func newTestConn(min, max int) *chunkConn {
|
|
return &chunkConn{pipeline: max, minPipeline: min, maxPipeline: max}
|
|
}
|
|
|
|
func TestPinnedBatchNeverAdapts(t *testing.T) {
|
|
c := newTestConn(5, 5)
|
|
if got := c.batchCount(1400); got != 5 {
|
|
t.Fatalf("pinned batch should request 5 records, got %d", got)
|
|
}
|
|
for i := 0; i < 10; i++ {
|
|
if _, _, shrank := c.shrinkPipeline(); shrank {
|
|
t.Fatal("pinned batch shrank on transport failure")
|
|
}
|
|
c.growPipeline()
|
|
}
|
|
if c.pipeline != 5 {
|
|
t.Fatalf("pinned batch drifted to %d", c.pipeline)
|
|
}
|
|
if got := c.batchCount(1400); got != 5 {
|
|
t.Fatalf("pinned batch should still request 5 records, got %d", got)
|
|
}
|
|
}
|
|
|
|
func TestPinnedBatchSurvivesOneMiBCap(t *testing.T) {
|
|
// 8 x 1 MiB records exceed the ~1 MiB useful-data cap. A pinned depth must
|
|
// win anyway, otherwise a path that needs exactly 8 records is broken by
|
|
// an unrelated size heuristic.
|
|
c := newTestConn(8, 8)
|
|
if got := c.batchCount(1024 * 1024); got != 8 {
|
|
t.Fatalf("pinned batch should ignore the 1 MiB cap, got %d", got)
|
|
}
|
|
// An unpinned batch is still capped.
|
|
c = newTestConn(1, 8)
|
|
if got := c.batchCount(1024 * 1024); got != 1 {
|
|
t.Fatalf("unpinned batch should be capped to 1, got %d", got)
|
|
}
|
|
}
|
|
|
|
func TestAdaptiveBatchStopsAtFloor(t *testing.T) {
|
|
c := newTestConn(4, 32)
|
|
seen := map[int]bool{}
|
|
for i := 0; i < 12; i++ {
|
|
_, next, _ := c.shrinkPipeline()
|
|
seen[next] = true
|
|
}
|
|
if c.pipeline != 4 {
|
|
t.Fatalf("batch fell to %d, want the floor 4", c.pipeline)
|
|
}
|
|
if !seen[16] || !seen[8] {
|
|
t.Fatalf("expected halving through 16 and 8, saw %v", seen)
|
|
}
|
|
for i := 0; i < 100; i++ {
|
|
c.growPipeline()
|
|
}
|
|
if c.pipeline != 32 {
|
|
t.Fatalf("batch grew to %d, want the ceiling 32", c.pipeline)
|
|
}
|
|
}
|
|
|
|
func TestSingleBatchIsFixed(t *testing.T) {
|
|
c := newTestConn(1, 1)
|
|
if !c.pinnedBatch() {
|
|
t.Fatal("a 1..1 batch must be treated as pinned")
|
|
}
|
|
c.growPipeline()
|
|
if c.pipeline != 1 {
|
|
t.Fatalf("batch of 1 grew to %d", c.pipeline)
|
|
}
|
|
}
|
|
|
|
func TestReconnectZeroMeansPersistent(t *testing.T) {
|
|
lane := newRequestLane("127.0.0.1:1", 0, 0, 0)
|
|
if lane.reconnectEvery != 0 {
|
|
t.Fatalf("reconnectEvery=%d, want 0", lane.reconnectEvery)
|
|
}
|
|
}
|