blob: e01cb35aabfeafc60f1c246e530fd7e6550b8807 [file]
// Copyright 2019 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package buffer
import (
"container/heap"
"math/rand"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
func TestBatchHeap(t *testing.T) {
Convey(`batchHeap`, t, func() {
h := batchHeap{}
Convey(`ordering`, func() {
checkSorted := func() {
for i := 1; i < h.Len(); i++ {
So(h.Less(i-1, i), ShouldBeTrue)
So(h.Less(i, i-1), ShouldBeFalse)
}
}
Convey(`id`, func() {
h.data = append(h.data,
&Batch{id: 0},
&Batch{id: 1})
checkSorted()
})
Convey(`nextSend`, func() {
now := time.Now()
h.data = append(h.data,
&Batch{nextSend: now},
&Batch{nextSend: now.Add(time.Second)})
checkSorted()
})
Convey(`(nextSend, id)`, func() {
now := time.Now().UTC()
h.data = append(h.data,
&Batch{nextSend: now, id: 0},
&Batch{nextSend: now.Add(time.Second), id: 0},
&Batch{nextSend: now.Add(time.Second), id: 1},
&Batch{nextSend: now.Add(2 * time.Second), id: 0},
)
checkSorted()
})
Convey(`test push-pop yields sorted`, func() {
now := time.Now().UTC()
for i := uint64(0); i < 20; i++ {
h.data = append(h.data, &Batch{nextSend: now, id: i})
}
shuffled := batchHeap{data: make([]*Batch, h.Len())}
copy(shuffled.data, h.data)
rand.Shuffle(shuffled.Len(), shuffled.Swap)
So(shuffled, ShouldNotResemble, h)
heap.Init(&shuffled)
sorted := make([]*Batch, 0, shuffled.Len())
for shuffled.Len() > 0 {
sorted = append(sorted, heap.Pop(&shuffled).(*Batch))
}
So(sorted, ShouldResemble, h.data)
})
Convey(`batch dropping`, func() {
h.PushBatch(&Batch{id: 10})
h.PushBatch(&Batch{id: 20})
Convey(`drops an old batch`, func() {
oldest, idx := h.Oldest()
So(oldest.id, ShouldEqual, 10)
So(idx, ShouldEqual, 0)
h.RemoveAt(idx)
So(h.PopBatch(), ShouldResemble, &Batch{id: 20})
So(h.data, ShouldBeEmpty)
})
})
})
})
}