kubo/exchange/bitswap/decision/peer_request_queue_test.go
Brian Tiger Chow 61e4300d59 feat(PQ)
refactor: peerRequestQueue

	it's a mistake to make one queue to fit all. Go's lack of algebraic
	types turns a generalized queue into a monstrosity of type
	checking/casting. Better to have individual queues for individual
	purposes.

	Conflicts:
		exchange/bitswap/decision/bench_test.go
		exchange/bitswap/decision/tasks/task_queue.go

	fix(bitswap.decision.PRQ): if peers match, always return result of pri comparison

	fix(bitswap.decision.Engine): push to the queue before notifying

	TOCTOU bug

	1. client notifies
	2. worker checks (finds nil)
	3. worker sleeps
	3. client pushes (worker missed the update)

	test(PQ): improve documentation and add test

	test(bitswap.decision.Engine): handling received messages

	License: MIT
	Signed-off-by: Brian Tiger Chow <brian@perfmode.com>
2015-01-18 15:09:54 -08:00

57 lines
1.3 KiB
Go

package decision
import (
"math"
"math/rand"
"sort"
"strings"
"testing"
"github.com/jbenet/go-ipfs/exchange/bitswap/wantlist"
"github.com/jbenet/go-ipfs/util"
"github.com/jbenet/go-ipfs/util/testutil"
)
func TestPushPop(t *testing.T) {
prq := newPRQ()
partner := testutil.RandPeerIDFatal(t)
alphabet := strings.Split("abcdefghijklmnopqrstuvwxyz", "")
vowels := strings.Split("aeiou", "")
consonants := func() []string {
var out []string
for _, letter := range alphabet {
skip := false
for _, vowel := range vowels {
if letter == vowel {
skip = true
}
}
if !skip {
out = append(out, letter)
}
}
return out
}()
sort.Strings(alphabet)
sort.Strings(vowels)
sort.Strings(consonants)
// add a bunch of blocks. cancel some. drain the queue. the queue should only have the kept entries
for _, index := range rand.Perm(len(alphabet)) { // add blocks for all letters
letter := alphabet[index]
t.Log(partner.String())
prq.Push(wantlist.Entry{Key: util.Key(letter), Priority: math.MaxInt32 - index}, partner)
}
for _, consonant := range consonants {
prq.Remove(util.Key(consonant), partner)
}
for _, expected := range vowels {
received := prq.Pop().Entry.Key
if received != util.Key(expected) {
t.Fatal("received", string(received), "expected", string(expected))
}
}
}