github.com/cenkalti/gopqueue@v0.0.0-20130928053223-7e7bc6b2cb51/pqueue_test.go (about) 1 // This package provides a priority queue implementation and 2 // scaffold interfaces. 3 // 4 // Copyright (C) 2011 by Krzysztof Kowalik <chris@nu7hat.ch> 5 package pqueue 6 7 import ( 8 "math/rand" 9 "testing" 10 "time" 11 ) 12 13 type DummyTask struct { 14 priority int 15 } 16 17 func NewDummyTask(p int) *DummyTask { 18 return &DummyTask{priority: p} 19 } 20 21 func (dt *DummyTask) Less(other interface{}) bool { 22 return dt.priority < other.(*DummyTask).priority 23 } 24 25 func TestNewQueue(t *testing.T) { 26 q := New(100) 27 if q.Limit != 100 { 28 t.Errorf("Expected to set queue limit on create") 29 } 30 } 31 32 func TestEnqueueAndDequeue(t *testing.T) { 33 q := New(0) 34 for _, x := range []int{1, 3, 4, 2, 7, 3} { 35 q.Enqueue(NewDummyTask(x)) 36 } 37 if q.Len() != 6 { 38 t.Errorf("Expected to enqueue all the items") 39 } 40 for _, x := range []int{1, 2, 3, 3, 4, 7} { 41 task := q.Dequeue().(*DummyTask) 42 if task.priority != x { 43 t.Errorf("Expected priority to be %d, given %d", x, task.priority) 44 } 45 } 46 if q.Len() != 0 { 47 t.Errorf("Expected to dequeue all the items") 48 } 49 } 50 51 func TestPeek(t *testing.T) { 52 q := New(0) 53 for _, x := range []int{3, 5, 2} { 54 q.Enqueue(NewDummyTask(x)) 55 } 56 min := q.Peek().(*DummyTask) 57 if min.priority != 2 { 58 t.Errorf("Expected peeked item to have priority 2") 59 } 60 61 q.Enqueue(NewDummyTask(1)) 62 min = q.Peek().(*DummyTask) 63 if min.priority != 1 { 64 t.Errorf("Expected peeked item to have priority 1") 65 } 66 } 67 68 func TestWaitForDequeue(t *testing.T) { 69 q := New(0) 70 dequeued := false 71 go func() { 72 if q.Dequeue() != nil { 73 dequeued = true 74 } 75 }() 76 <-time.After(1e9) 77 q.Enqueue(NewDummyTask(1)) 78 <-time.After(1e2) 79 if !dequeued { 80 t.Errorf("Expected to wait for dequeue") 81 } 82 } 83 84 func TestIsEmpty(t *testing.T) { 85 q := New(0) 86 if !q.IsEmpty() { 87 t.Errorf("Expected queue to be empty") 88 } 89 for _, x := range []int{1, 2, 3, 4} { 90 q.Enqueue(NewDummyTask(x)) 91 } 92 if q.IsEmpty() { 93 t.Errorf("Expected queue to not be empty") 94 } 95 } 96 97 func TestLimit(t *testing.T) { 98 q := New(10) 99 var err error 100 for i := 0; i < 20; i += 1 { 101 err = q.Enqueue(NewDummyTask(i)) 102 } 103 if err == nil || err.Error() != "Queue limit reached" { 104 t.Errorf("Expected to reach queue limit") 105 } 106 if q.Len() != 10 { 107 t.Errorf("Expected to enqueue only 10 items, %d enqueued", q.Len()) 108 } 109 } 110 111 func BenchmarkEnqueue(b *testing.B) { 112 b.StopTimer() 113 q := New(0) 114 b.StartTimer() 115 for i := 0; i < 200000; i += 1 { 116 q.Enqueue(NewDummyTask(rand.Intn(10))) 117 } 118 } 119 120 func BenchmarkMultiEnqueue(b *testing.B) { 121 b.StopTimer() 122 q := New(0) 123 done := make(chan bool) 124 b.StartTimer() 125 for i := 0; i < 4; i += 1 { 126 go func() { 127 for j := 0; j < 50000; j += 1 { 128 q.Enqueue(NewDummyTask(rand.Intn(10))) 129 } 130 done <- true 131 }() 132 } 133 for i := 0; i < 4; i += 1 { 134 <-done 135 } 136 } 137 138 func BenchmarkDequeue(b *testing.B) { 139 b.StopTimer() 140 q := New(0) 141 b.StartTimer() 142 go func() { 143 for i := 0; i < 200000; i += 1 { 144 q.Enqueue(NewDummyTask(rand.Intn(10))) 145 } 146 q.Enqueue(NewDummyTask(1000000)) 147 }() 148 for { 149 task := q.Dequeue().(*DummyTask) 150 if task.priority == 1000000 { 151 break 152 } 153 } 154 } 155 156 func BenchmarkMultiDequeue(b *testing.B) { 157 b.StopTimer() 158 q := New(0) 159 done := make(chan bool) 160 b.StartTimer() 161 go func() { 162 for i := 0; i < 200000; i += 1 { 163 q.Enqueue(NewDummyTask(rand.Intn(10))) 164 } 165 q.Enqueue(NewDummyTask(1000000)) 166 }() 167 for i := 0; i < 4; i += 1 { 168 go func() { 169 for { 170 task := q.Dequeue().(*DummyTask) 171 if task.priority == 1000000 { 172 done <- true 173 break 174 } 175 } 176 }() 177 } 178 <-done 179 }