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  }