queue_test.go 3.03 KB
Newer Older
1 2 3
package queue

import (
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
4
	"fmt"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
5
	"sync"
6
	"testing"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
7
	"time"
8 9 10

	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
11 12

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
13 14 15 16 17 18
)

func newPeer(id string) *peer.Peer {
	return &peer.Peer{ID: peer.ID(id)}
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
19
func TestQueue(t *testing.T) {
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

	p1 := newPeer("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31")
	p2 := newPeer("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a32")
	p3 := newPeer("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
	p4 := newPeer("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a34")
	p5 := newPeer("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31")

	// these are the peer.IDs' XORKeySpace Key values:
	// [228 47 151 130 156 102 222 232 218 31 132 94 170 208 80 253 120 103 55 35 91 237 48 157 81 245 57 247 66 150 9 40]
	// [26 249 85 75 54 49 25 30 21 86 117 62 85 145 48 175 155 194 210 216 58 14 241 143 28 209 129 144 122 28 163 6]
	// [78 135 26 216 178 181 224 181 234 117 2 248 152 115 255 103 244 34 4 152 193 88 9 225 8 127 216 158 226 8 236 246]
	// [125 135 124 6 226 160 101 94 192 57 39 12 18 79 121 140 190 154 147 55 44 83 101 151 63 255 94 179 51 203 241 51]

	pq := NewXORDistancePQ(u.Key("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31"))
	pq.Enqueue(p3)
	pq.Enqueue(p1)
	pq.Enqueue(p2)
	pq.Enqueue(p4)
	pq.Enqueue(p5)
	pq.Enqueue(p1)

	// should come out as: p1, p4, p3, p2

	if d := pq.Dequeue(); d != p1 && d != p5 {
		t.Error("ordering failed")
	}

	if d := pq.Dequeue(); d != p1 && d != p5 {
		t.Error("ordering failed")
	}

	if d := pq.Dequeue(); d != p1 && d != p5 {
		t.Error("ordering failed")
	}

	if pq.Dequeue() != p4 {
		t.Error("ordering failed")
	}

	if pq.Dequeue() != p3 {
		t.Error("ordering failed")
	}

	if pq.Dequeue() != p2 {
		t.Error("ordering failed")
	}

}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
68 69 70 71 72 73 74 75

func newPeerTime(t time.Time) *peer.Peer {
	s := fmt.Sprintf("hmmm time: %v", t)
	h, _ := u.Hash([]byte(s))
	return &peer.Peer{ID: peer.ID(h)}
}

func TestSyncQueue(t *testing.T) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
76
	ctx := context.Background()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79

	pq := NewXORDistancePQ(u.Key("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31"))
	cq := NewChanQueue(ctx, pq)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
80
	wg := sync.WaitGroup{}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
81

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
82
	max := 10000
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
83 84 85 86 87
	consumerN := 10
	countsIn := make([]int, consumerN*2)
	countsOut := make([]int, consumerN)

	produce := func(p int) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
88 89 90
		defer wg.Done()

		tick := time.Tick(time.Microsecond * 100)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
91
		for i := 0; i < max; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
92 93
			select {
			case tim := <-tick:
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
94
				countsIn[p]++
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
95 96 97 98 99 100 101
				cq.EnqChan <- newPeerTime(tim)
			case <-ctx.Done():
				return
			}
		}
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
102
	consume := func(c int) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
103 104
		defer wg.Done()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
105 106 107
		for {
			select {
			case <-cq.DeqChan:
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
108
				countsOut[c]++
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
109 110 111
				if countsOut[c] >= max*2 {
					return
				}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
112 113 114 115 116 117
			case <-ctx.Done():
				return
			}
		}
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
118 119
	// make n * 2 producers and n consumers
	for i := 0; i < consumerN; i++ {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
120
		wg.Add(3)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
121 122 123
		go produce(i)
		go produce(consumerN + i)
		go consume(i)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
124 125
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
126
	wg.Wait()
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
127

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
128 129 130 131 132 133
	sum := func(ns []int) int {
		total := 0
		for _, n := range ns {
			total += n
		}
		return total
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
134 135
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
136
	if sum(countsIn) != sum(countsOut) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
137
		t.Errorf("didnt get all of them out: %d/%d", sum(countsOut), sum(countsIn))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
138
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
139
}