github.com/better-concurrent/guc@v0.0.0-20190520022744-eb29266403a1/priorityblockingqueue_test.go (about)

     1  package guc
     2  
     3  import (
     4  	"container/list"
     5  	"testing"
     6  	"time"
     7  )
     8  
     9  func TestNewPriorityBlockingQueue(t *testing.T) {
    10  	p := NewPriorityBlockingQueue()
    11  	if !p.IsEmpty() {
    12  		t.Fatal("queue should be empty")
    13  	}
    14  }
    15  
    16  type sampleBlockingItem struct {
    17  	Value int
    18  }
    19  
    20  func (this *sampleBlockingItem) Equals(i interface{}) bool {
    21  	dst, ok := i.(*sampleBlockingItem)
    22  	if !ok {
    23  		return false
    24  	}
    25  	return this.Value == dst.Value
    26  }
    27  
    28  func (this *sampleBlockingItem) CompareTo(i interface{}) int {
    29  	return this.Value - i.(*sampleBlockingItem).Value
    30  }
    31  
    32  func newSampleBlockingItem(value int) *sampleBlockingItem {
    33  	return &sampleBlockingItem{
    34  		Value: value,
    35  	}
    36  }
    37  
    38  func newPreparedPriorityBlockingQueue() *PriorityBlockingQueue {
    39  	p := NewPriorityBlockingQueue()
    40  	p.Add(newSampleBlockingItem(6))
    41  	p.Add(newSampleBlockingItem(8))
    42  	p.Add(newSampleBlockingItem(3))
    43  	p.Add(newSampleBlockingItem(6))
    44  	p.Add(newSampleBlockingItem(33))
    45  	p.Add(newSampleBlockingItem(7))
    46  	p.Add(newSampleBlockingItem(2))
    47  	return p
    48  }
    49  
    50  func TestPriorityBlockingQueue_Add(t *testing.T) {
    51  	p := newPreparedPriorityBlockingQueue()
    52  	if p.IsEmpty() {
    53  		t.Fatal("queue should not be empty")
    54  	}
    55  	if p.priorityQueue.data.data[0].(*sampleBlockingItem).Value != 2 {
    56  		t.Fatal("first should be value 2")
    57  	}
    58  	if p.Size() != 7 {
    59  		t.Fatal("queue size should be 7")
    60  	}
    61  }
    62  
    63  func TestPriorityBlockingQueue_Contains(t *testing.T) {
    64  	p := newPreparedPriorityBlockingQueue()
    65  	if p.Contains(newSampleBlockingItem(100)) {
    66  		t.Fatal("queue should not contains value 100")
    67  	}
    68  	if !p.Contains(newSampleBlockingItem(6)) {
    69  		t.Fatal("queue should contains value 6")
    70  	}
    71  	if !p.Contains(newSampleBlockingItem(3)) {
    72  		t.Fatal("queue should contains value 3")
    73  	}
    74  }
    75  
    76  func TestPriorityBlockingQueue_ForEach(t *testing.T) {
    77  	p := newPreparedPriorityBlockingQueue()
    78  
    79  	l := list.New()
    80  	p.ForEach(func(i interface{}) {
    81  		l.PushBack(i)
    82  	})
    83  	if l.Len() != 7 {
    84  		t.Fatal("total number of foreach items are not 7")
    85  	}
    86  }
    87  
    88  func TestPriorityBlockingQueue_ToArray(t *testing.T) {
    89  	p := newPreparedPriorityBlockingQueue()
    90  
    91  	arr := p.ToArray()
    92  	if len(arr) != 7 {
    93  		t.Fatal("array size must be 7")
    94  	}
    95  	matched := false
    96  	for _, v := range arr {
    97  		if v.(*sampleBlockingItem).Value == 6 {
    98  			matched = true
    99  			break
   100  		}
   101  	}
   102  	if !matched {
   103  		t.Fatal("must have value 6 in array")
   104  	}
   105  }
   106  
   107  func TestPriorityBlockingQueue_FillArray(t *testing.T) {
   108  	p := newPreparedPriorityBlockingQueue()
   109  
   110  	arr := p.FillArray(make([]interface{}, 0))
   111  	if len(arr) != 7 {
   112  		t.Fatal("array size must be 7")
   113  	}
   114  	matched := false
   115  	for _, v := range arr {
   116  		if v.(*sampleBlockingItem).Value == 6 {
   117  			matched = true
   118  			break
   119  		}
   120  	}
   121  	if !matched {
   122  		t.Fatal("must have value 6 in array")
   123  	}
   124  
   125  	newArr := make([]interface{}, 7)
   126  	p.FillArray(newArr)
   127  	matched = false
   128  	for _, v := range newArr {
   129  		if v.(*sampleBlockingItem).Value == 6 {
   130  			matched = true
   131  			break
   132  		}
   133  	}
   134  	if !matched {
   135  		t.Fatal("must have value 6 in array")
   136  	}
   137  }
   138  
   139  func TestPriorityBlockingQueue_Remove(t *testing.T) {
   140  	p := newPreparedPriorityBlockingQueue()
   141  
   142  	b := p.Remove(newSampleBlockingItem(100))
   143  	if b {
   144  		t.Fatal("should return false")
   145  	}
   146  	if p.Size() != 7 {
   147  		t.Fatal("size should be 7")
   148  	}
   149  
   150  	b = p.Remove(newSampleBlockingItem(3))
   151  	if !b {
   152  		t.Fatal("should return true")
   153  	}
   154  	if p.Size() != 6 {
   155  		t.Fatal("size should be 6")
   156  	}
   157  
   158  	b = p.Remove(newSampleBlockingItem(6))
   159  	if !b {
   160  		t.Fatal("should return true")
   161  	}
   162  	if p.Size() != 5 {
   163  		t.Fatal("size should be 5")
   164  	}
   165  }
   166  
   167  func TestPriorityBlockingQueue_ContainsAll(t *testing.T) {
   168  	p := newPreparedPriorityBlockingQueue()
   169  
   170  	c := NewPriorityBlockingQueue()
   171  	c.Add(newSampleBlockingItem(6))
   172  	c.Add(newSampleBlockingItem(2))
   173  	if !p.ContainsAll(c) {
   174  		t.Fatal("should contains all")
   175  	}
   176  
   177  	c = NewPriorityBlockingQueue()
   178  	c.Add(newSampleBlockingItem(6))
   179  	c.Add(newSampleBlockingItem(100))
   180  	if p.ContainsAll(c) {
   181  		t.Fatal("should not contains all - 1")
   182  	}
   183  
   184  	c = NewPriorityBlockingQueue()
   185  	c.Add(newSampleBlockingItem(200))
   186  	c.Add(newSampleBlockingItem(100))
   187  	if p.ContainsAll(c) {
   188  		t.Fatal("should not contains all - 2")
   189  	}
   190  }
   191  
   192  func TestPriorityBlockingQueue_AddAll(t *testing.T) {
   193  	p := newPreparedPriorityBlockingQueue()
   194  	if p.Size() != 7 {
   195  		t.Fatal("queue size must be 7")
   196  	}
   197  
   198  	c := NewPriorityBlockingQueue()
   199  	c.Add(newSampleBlockingItem(200))
   200  	c.Add(newSampleBlockingItem(100))
   201  	if !p.AddAll(c) {
   202  		t.Fatal("add result should be true")
   203  	}
   204  
   205  	if !p.Contains(newSampleBlockingItem(100)) {
   206  		t.Fatal("queue should contains value 100")
   207  	}
   208  	if !p.Contains(newSampleBlockingItem(200)) {
   209  		t.Fatal("queue should contains value 200")
   210  	}
   211  	if p.Size() != 9 {
   212  		t.Fatal("queue size should be 9")
   213  	}
   214  }
   215  
   216  func TestPriorityBlockingQueue_RemoveAll(t *testing.T) {
   217  	p := newPreparedPriorityBlockingQueue()
   218  	if p.Size() != 7 {
   219  		t.Fatal("queue size must be 7")
   220  	}
   221  
   222  	c := NewPriorityBlockingQueue()
   223  	c.Add(newSampleBlockingItem(200))
   224  	c.Add(newSampleBlockingItem(100))
   225  	if p.RemoveAll(c) {
   226  		t.Fatal("remove all should return false")
   227  	}
   228  	if p.Size() != 7 {
   229  		t.Fatal("queue size should be 7")
   230  	}
   231  
   232  	c = NewPriorityBlockingQueue()
   233  	c.Add(newSampleBlockingItem(3))
   234  	c.Add(newSampleBlockingItem(100))
   235  	if !p.RemoveAll(c) {
   236  		t.Fatal("remove all should return true")
   237  	}
   238  	if p.Size() != 6 {
   239  		t.Fatal("queue size should be 6")
   240  	}
   241  
   242  	c = NewPriorityBlockingQueue()
   243  	c.Add(newSampleBlockingItem(8))
   244  	c.Add(newSampleBlockingItem(2))
   245  	if !p.RemoveAll(c) {
   246  		t.Fatal("remove all should return true")
   247  	}
   248  	if p.Size() != 4 {
   249  		t.Fatal("queue size should be 4")
   250  	}
   251  }
   252  
   253  func TestPriorityBlockingQueue_RemoveIf(t *testing.T) {
   254  	p := newPreparedPriorityBlockingQueue()
   255  	if p.Size() != 7 {
   256  		t.Fatal("queue size not match")
   257  	}
   258  
   259  	b := p.RemoveIf(func(i interface{}) bool {
   260  		return i.(*sampleBlockingItem).Value == 6
   261  	})
   262  	if !b {
   263  		t.Fatal("remove result should be true")
   264  	}
   265  	if p.Size() != 6 {
   266  		t.Fatal("queue size should be 6")
   267  	}
   268  
   269  	b = p.RemoveIf(func(i interface{}) bool {
   270  		return i.(*sampleBlockingItem).Value == 100
   271  	})
   272  	if b {
   273  		t.Fatal("remove result should be false")
   274  	}
   275  	if p.Size() != 6 {
   276  		t.Fatal("queue size should be 6")
   277  	}
   278  }
   279  
   280  func TestPriorityBlockingQueue_RetainAll(t *testing.T) {
   281  	{
   282  		p := newPreparedPriorityBlockingQueue()
   283  		c := NewPriorityBlockingQueue()
   284  		c.Add(newSampleBlockingItem(200))
   285  		c.Add(newSampleBlockingItem(100))
   286  		if !p.RetainAll(c) {
   287  			t.Fatal("remove all should return true")
   288  		}
   289  		if p.Size() != 0 {
   290  			t.Fatal("queue size should be 0")
   291  		}
   292  	}
   293  	{
   294  		p := newPreparedPriorityBlockingQueue()
   295  		c := NewPriorityBlockingQueue()
   296  		c.Add(newSampleBlockingItem(3))
   297  		c.Add(newSampleBlockingItem(100))
   298  		if !p.RetainAll(c) {
   299  			t.Fatal("remove all should return true")
   300  		}
   301  		if p.Size() != 1 {
   302  			t.Fatal("queue size should be 1")
   303  		}
   304  	}
   305  	{
   306  		p := newPreparedPriorityBlockingQueue()
   307  		c := NewPriorityBlockingQueue()
   308  		c.Add(newSampleBlockingItem(8))
   309  		c.Add(newSampleBlockingItem(2))
   310  		if !p.RetainAll(c) {
   311  			t.Fatal("remove all should return true")
   312  		}
   313  		if p.Size() != 2 {
   314  			t.Fatal("queue size should be 2")
   315  		}
   316  	}
   317  }
   318  
   319  func TestPriorityBlockingQueue_Clear(t *testing.T) {
   320  	p := newPreparedPriorityBlockingQueue()
   321  	if p.Size() != 7 {
   322  		t.Fatal("queue size not match")
   323  	}
   324  	p.Clear()
   325  	if p.Size() != 0 {
   326  		t.Fatal("queue size should be 0")
   327  	}
   328  	if !p.IsEmpty() {
   329  		t.Fatal("queue should be empty")
   330  	}
   331  }
   332  
   333  func TestPriorityBlockingQueue_Equals(t *testing.T) {
   334  	p := newPreparedPriorityBlockingQueue()
   335  	if !p.Equals(p) {
   336  		t.Fatal("queue should be equals to itself")
   337  	}
   338  	if p.Equals(newPreparedPriorityBlockingQueue()) {
   339  		t.Fatal("queue should not be equals to a new one")
   340  	}
   341  	if p.Equals(struct{}{}) {
   342  		t.Fatal("queue should not be equals to another object of other type")
   343  	}
   344  }
   345  
   346  func TestPriorityBlockingQueue_HashCode(t *testing.T) {
   347  	p := newPreparedPriorityBlockingQueue()
   348  	if p.HashCode() != p.HashCode() {
   349  		t.Fatal("hashcode must same")
   350  	}
   351  }
   352  
   353  func TestPriorityBlockingQueue_RemoveHead(t *testing.T) {
   354  	p := newPreparedPriorityBlockingQueue()
   355  	h := p.RemoveHead().(*sampleBlockingItem)
   356  	if h.Value != 2 {
   357  		t.Fatal("remove head must value 2")
   358  	}
   359  	if p.Size() != 6 {
   360  		t.Fatal("queue size must be 6")
   361  	}
   362  
   363  	emptyQueue := NewPriorityBlockingQueue()
   364  	r := func(p *PriorityBlockingQueue) (result bool) {
   365  		result = false
   366  		defer func() {
   367  			err := recover()
   368  			if err != nil {
   369  				result = true
   370  			}
   371  		}()
   372  		p.RemoveHead()
   373  		return
   374  	}(emptyQueue)
   375  	if !r {
   376  		t.Fatal("should panic when RemoveHead of an empty queue")
   377  	}
   378  }
   379  
   380  func TestPriorityBlockingQueue_Poll(t *testing.T) {
   381  	p := newPreparedPriorityBlockingQueue()
   382  	if p.Size() != 7 {
   383  		t.Fatal("queue size not match")
   384  	}
   385  
   386  	prev := -1
   387  	for i := 0; i < 7; i++ {
   388  		s := p.Poll().(*sampleBlockingItem)
   389  		if prev == -1 {
   390  			prev = s.Value
   391  			continue
   392  		}
   393  		if prev > s.Value {
   394  			t.Fatal("prev value:", prev, "should be <= current value:", s.Value)
   395  		}
   396  		prev = s.Value
   397  	}
   398  }
   399  
   400  func TestPriorityBlockingQueue_Peek(t *testing.T) {
   401  	p := newPreparedPriorityBlockingQueue()
   402  	h := p.Peek().(*sampleBlockingItem)
   403  	if h.Value != 2 {
   404  		t.Fatal("remove head must value 2")
   405  	}
   406  
   407  	emptyQueue := NewPriorityBlockingQueue()
   408  	r := emptyQueue.Peek()
   409  	if r != nil {
   410  		t.Fatal("peek of empty queue should be nil")
   411  	}
   412  }
   413  
   414  func TestPriorityBlockingQueue_Element(t *testing.T) {
   415  	p := newPreparedPriorityBlockingQueue()
   416  	h := p.Element().(*sampleBlockingItem)
   417  	if h.Value != 2 {
   418  		t.Fatal("element() must value 2")
   419  	}
   420  
   421  	emptyQueue := NewPriorityBlockingQueue()
   422  	r := func(p *PriorityBlockingQueue) (result bool) {
   423  		result = false
   424  		defer func() {
   425  			err := recover()
   426  			if err != nil {
   427  				result = true
   428  			}
   429  		}()
   430  		p.Element()
   431  		return
   432  	}(emptyQueue)
   433  	if !r {
   434  		t.Fatal("should panic when element() of an empty queue")
   435  	}
   436  }
   437  
   438  func TestPriorityBlockingQueue_Put(t *testing.T) {
   439  	p := newPreparedPriorityBlockingQueue()
   440  	p.Put(newSampleBlockingItem(100))
   441  	if p.Size() != 8 {
   442  		t.Fatal("queue size must be 8")
   443  	}
   444  	if !p.Contains(newSampleBlockingItem(100)) {
   445  		t.Fatal("queue must contains value 100")
   446  	}
   447  }
   448  
   449  func TestPriorityBlockingQueue_Offer(t *testing.T) {
   450  	p := newPreparedPriorityBlockingQueue()
   451  	p.Offer(newSampleBlockingItem(100))
   452  	if p.Size() != 8 {
   453  		t.Fatal("queue size must be 8")
   454  	}
   455  	if !p.Contains(newSampleBlockingItem(100)) {
   456  		t.Fatal("queue must contains value 100")
   457  	}
   458  }
   459  
   460  func TestPriorityBlockingQueue_OfferWithTimeout(t *testing.T) {
   461  	p := newPreparedPriorityBlockingQueue()
   462  	p.OfferWithTimeout(newSampleBlockingItem(100), 1*time.Hour)
   463  	if p.Size() != 8 {
   464  		t.Fatal("queue size must be 8")
   465  	}
   466  	if !p.Contains(newSampleBlockingItem(100)) {
   467  		t.Fatal("queue must contains value 100")
   468  	}
   469  }
   470  
   471  func TestPriorityBlockingQueue_Take(t *testing.T) {
   472  	{
   473  		p := newPreparedPriorityBlockingQueue()
   474  		i := p.Take()
   475  		if i == nil {
   476  			t.Fatal("take from queue should return a value")
   477  		}
   478  	}
   479  	{
   480  		p := NewPriorityBlockingQueue()
   481  		ch := make(chan struct{}, 1)
   482  		go func() {
   483  			<-ch
   484  			time.Sleep(50 * time.Millisecond)
   485  			p.Offer(newSampleBlockingItem(1))
   486  		}()
   487  		ch <- struct{}{}
   488  		i := p.Take()
   489  		if i.(*sampleBlockingItem).Value != 1 {
   490  			t.Fatal("shoudl have value 1")
   491  		}
   492  	}
   493  }
   494  
   495  func TestPriorityBlockingQueue_PollWithTimeout(t *testing.T) {
   496  	{
   497  		p := newPreparedPriorityBlockingQueue()
   498  		i := p.PollWithTimeout(1 * time.Second)
   499  		if i == nil {
   500  			t.Fatal("take from queue should return a value")
   501  		}
   502  	}
   503  	{
   504  		p := NewPriorityBlockingQueue()
   505  		ch := make(chan struct{}, 1)
   506  		go func() {
   507  			<-ch
   508  			time.Sleep(50 * time.Millisecond)
   509  			p.Offer(newSampleBlockingItem(1))
   510  		}()
   511  		ch <- struct{}{}
   512  		i := p.PollWithTimeout(1 * time.Second)
   513  		if i.(*sampleBlockingItem).Value != 1 {
   514  			t.Fatal("shoudl have value 1")
   515  		}
   516  	}
   517  }
   518  
   519  func TestPriorityBlockingQueue_RemainingCapacity(t *testing.T) {
   520  	p := newPreparedPriorityBlockingQueue()
   521  	if p.RemainingCapacity() <= 0 {
   522  		t.Fatal("remaining capacity should greater than 0")
   523  	}
   524  	p = NewPriorityBlockingQueue()
   525  	if p.RemainingCapacity() <= 0 {
   526  		t.Fatal("remaining capacity should greater than 0")
   527  	}
   528  }
   529  
   530  func TestPriorityBlockingQueue_DrainTo(t *testing.T) {
   531  	p := newPreparedPriorityBlockingQueue()
   532  	d := NewPriorityBlockingQueue()
   533  	if p.DrainTo(d) != 7 {
   534  		t.Fatal("drain result should be 7")
   535  	}
   536  	if d.Size() != 7 {
   537  		t.Fatal("dest size should be 7")
   538  	}
   539  	if !d.Contains(newSampleBlockingItem(6)) {
   540  		t.Fatal("dest should contain value 7")
   541  	}
   542  	if !d.Contains(newSampleBlockingItem(33)) {
   543  		t.Fatal("dest should contain value 33")
   544  	}
   545  	if !d.Contains(newSampleBlockingItem(3)) {
   546  		t.Fatal("dest should contain value 3")
   547  	}
   548  	if d.Contains(newSampleBlockingItem(0)) {
   549  		t.Fatal("dest should not contain value 0")
   550  	}
   551  }
   552  
   553  func TestPriorityBlockingQueue_DrainToWithLimit(t *testing.T) {
   554  	p := newPreparedPriorityBlockingQueue()
   555  	d := NewPriorityBlockingQueue()
   556  	if p.DrainToWithLimit(d, 2) != 2 {
   557  		t.Fatal("drain result should be 2")
   558  	}
   559  	if d.Size() != 2 {
   560  		t.Fatal("dest size should be 2")
   561  	}
   562  }
   563  
   564  func TestPriorityBlockingQueue_Iterator(t *testing.T) {
   565  	p := newPreparedPriorityBlockingQueue()
   566  	cnt := 0
   567  	matched := false
   568  	iter := p.Iterator()
   569  	if iter == nil {
   570  		t.Fatal("iter should not be nil")
   571  	}
   572  	for iter.HasNext() {
   573  		cnt++
   574  		if iter.Next().(*sampleBlockingItem).Value == 6 {
   575  			matched = true
   576  		}
   577  	}
   578  	if cnt != 7 {
   579  		t.Fatal("iter count should be 7")
   580  	}
   581  	if !matched {
   582  		t.Fatal("should contains value 6")
   583  	}
   584  }
   585  
   586  func TestPriorityBlockingQueueIter_ForEachRemaining(t *testing.T) {
   587  	p := newPreparedPriorityBlockingQueue()
   588  	iter := p.Iterator()
   589  
   590  	l := list.New()
   591  	iter.ForEachRemaining(func(i interface{}) {
   592  		l.PushBack(i)
   593  	})
   594  	if l.Len() != 7 {
   595  		t.Fatal("total number of foreach items are not 7")
   596  	}
   597  }
   598  
   599  func TestPriorityBlockingQueueIter_Remove(t *testing.T) {
   600  	p := newPreparedPriorityBlockingQueue()
   601  	iter := p.Iterator()
   602  	iter.HasNext()
   603  	iter.Remove()
   604  	iterImpl := iter.(*priorityBlockingQueueIter)
   605  	if len(iterImpl.data) != 7 {
   606  		t.Fatal("iter size should be 7")
   607  	}
   608  	if p.Size() != 6 {
   609  		t.Fatal("iter size should be 6")
   610  	}
   611  }