mirror of
https://github.com/rancher/steve.git
synced 2025-04-28 11:14:43 +00:00
Some tests which relied on timeouts were a bit flaky in CI. This PR refactors a few of them to work on a more reliable method of receiving from a channel and raises the timeout of another test.
112 lines
3.4 KiB
Go
112 lines
3.4 KiB
Go
package counts
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rancher/apiserver/pkg/types"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_countsBuffer(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
numInputEvents int
|
|
overrideInput map[int]int // events whose count we should override. Don't include an event >= numInputEvents
|
|
}{
|
|
{
|
|
name: "test basic input",
|
|
numInputEvents: 1,
|
|
},
|
|
{
|
|
name: "test basic multiple input",
|
|
numInputEvents: 3,
|
|
},
|
|
{
|
|
name: "test basic input which is overriden by later events",
|
|
numInputEvents: 3,
|
|
overrideInput: map[int]int{
|
|
1: 17,
|
|
},
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
debounceDuration = 10 * time.Millisecond
|
|
countsChannel := make(chan Count, 100)
|
|
outputChannel := countsBuffer(countsChannel)
|
|
|
|
countsChannel <- Count{
|
|
ID: "count",
|
|
Counts: map[string]ItemCount{"test": createItemCount(1)},
|
|
}
|
|
|
|
// first event is not buffered, so we expect to receive it quicker than the debounce
|
|
_, err := receiveWithTimeout(outputChannel, time.Second*1)
|
|
assert.NoError(t, err, "Expected first event to be received quickly")
|
|
|
|
// stream our standard count events
|
|
for i := 0; i < test.numInputEvents; i++ {
|
|
countsChannel <- Count{
|
|
ID: "count",
|
|
Counts: map[string]ItemCount{strconv.Itoa(i): createItemCount(1)},
|
|
}
|
|
}
|
|
|
|
// stream any overrides, if applicable
|
|
for key, value := range test.overrideInput {
|
|
countsChannel <- Count{
|
|
ID: "count",
|
|
Counts: map[string]ItemCount{strconv.Itoa(key): createItemCount(value)},
|
|
}
|
|
}
|
|
|
|
// due to complexities of cycle calculation, give a slight delay for the event to actually stream
|
|
output, err := receiveWithTimeout(outputChannel, debounceDuration+time.Millisecond*10)
|
|
assert.NoError(t, err, "did not expect an error when receiving value from channel")
|
|
outputCount := output.Object.Object.(Count)
|
|
assert.Len(t, outputCount.Counts, test.numInputEvents)
|
|
for outputID, outputItem := range outputCount.Counts {
|
|
outputIdx, err := strconv.Atoi(outputID)
|
|
assert.NoError(t, err, "couldn't convert output idx")
|
|
nsTotal := 0
|
|
for _, nsSummary := range outputItem.Namespaces {
|
|
nsTotal += nsSummary.Count
|
|
}
|
|
if outputOverride, ok := test.overrideInput[outputIdx]; ok {
|
|
assert.Equal(t, outputOverride, outputItem.Summary.Count, "expected overridden output count to be most recent value")
|
|
assert.Equal(t, outputOverride, nsTotal, "expected overridden output namespace count to be most recent value")
|
|
} else {
|
|
assert.Equal(t, 1, outputItem.Summary.Count, "expected non-overridden output count to be 1")
|
|
assert.Equal(t, 1, nsTotal, "expected non-overridden output namespace count to be 1")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// receiveWithTimeout tries to get a value from input within duration. Returns an error if no input was received during that period
|
|
func receiveWithTimeout(input chan types.APIEvent, duration time.Duration) (*types.APIEvent, error) {
|
|
select {
|
|
case value := <-input:
|
|
return &value, nil
|
|
case <-time.After(duration):
|
|
return nil, fmt.Errorf("timeout error, no value received after %f seconds", duration.Seconds())
|
|
}
|
|
}
|
|
|
|
func createItemCount(countTotal int) ItemCount {
|
|
return ItemCount{
|
|
Summary: Summary{
|
|
Count: countTotal,
|
|
},
|
|
Namespaces: map[string]Summary{
|
|
"test": {
|
|
Count: countTotal,
|
|
},
|
|
},
|
|
}
|
|
}
|