blob: a6ca7d28a5ff2dffa99bc9a43be9035ce2b49dc2 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//go:build !build_with_native_toolchain
// +build !build_with_native_toolchain
package fifo
import (
"fmt"
"math/bits"
"testing"
"entries_gen_test/entries"
)
func TestEntries(t *testing.T) {
var e entries.Entries
var maxDepth uint16
// Use unsigned integer underflow to determine the maximum permitted depth.
maxDepth = 0
maxDepth--
// The maximum permitted depth is half the range of the index type used.
maxDepth >>= 1
for _, depth := range []uint16{2, 50, maxDepth} {
t.Run(fmt.Sprintf("depth=%d", depth), func(t *testing.T) {
capacity := e.Init(depth)
if ones := bits.OnesCount16(capacity); ones != 1 {
t.Fatalf("got len(storage)=%d (binary=%b) want power of two", capacity, capacity)
}
scratch := make([]struct{}, capacity)
for _, delta := range []uint16{depth, 1, depth / 2, depth - 1, depth} {
t.Run(fmt.Sprintf("delta=%d", delta), func(t *testing.T) {
if e.HaveReadied() {
t.Errorf("got HaveReadied=true want=false; %#v", e)
}
if got, want := e.AddReadied(scratch), int(capacity); got != want {
t.Errorf("got addReadied=%d want=%d; %#v", got, want, e)
}
e.IncrementReadied(delta)
if got, want := e.HaveReadied(), delta != 0; got != want {
t.Errorf("got HaveReadied=%t want=%t; %#v", got, want, e)
}
if got, want := e.AddReadied(scratch), int(capacity-delta); got != want {
t.Errorf("got addReadied=%d want=%d; %#v", got, want, e)
}
if e.HaveQueued() {
t.Errorf("got HaveQueued=true want=false; %#v", e)
}
if got, want := e.GetQueued(scratch), 0; got != want {
t.Errorf("got getQueued=%d want=%d; %#v", got, want, e)
}
e.IncrementQueued(delta)
if got, want := e.HaveQueued(), delta != 0; got != want {
t.Errorf("got HaveQueued=%t want=%t; %#v", got, want, e)
}
if e.HaveReadied() {
t.Errorf("got HaveReadied=true want=false; %#v", e)
}
if delta == 0 {
if got, want := e.GetQueued(scratch), int(capacity); got != want {
t.Errorf("got getQueued=%d want=%d; %#v", got, want, e)
}
if inFlight := e.InFlight(); inFlight != 0 {
t.Errorf("got InFlight()=%d want=zero; %#v", inFlight, e)
}
} else {
if got, want := e.GetQueued(scratch), int(delta); got != want {
t.Errorf("got getQueued=%d want=%d; %#v", got, want, e)
}
if got, want := e.InFlight(), capacity-delta; got != want {
t.Errorf("got InFlight()=%d want=%d; %#v", got, want, e)
}
}
e.IncrementSent(delta)
if got, want := e.InFlight(), capacity; got != want {
t.Errorf("got InFlight()=%d want=%d; %#v", got, want, e)
}
if got, want := e.AddReadied(scratch), int(capacity); got != want {
t.Errorf("got addReadied=%d want=%d; %#v", got, want, e)
}
if got, want := e.GetQueued(scratch), 0; got != want {
t.Errorf("got getQueued=%d want=%d; %#v", got, want, e)
}
if e.HaveQueued() {
t.Errorf("got HaveQueued=true want=false; %#v", e)
}
if e.HaveReadied() {
t.Fatalf("got HaveReadied=true want=false; %#v", e)
}
})
}
})
}
}