github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/queue/queue_test.go (about)

     1  package queue
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func TestQueueClose(t *testing.T) {
    11  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    12  	q, err := OpenQueue(file)
    13  	if err != nil {
    14  		t.Error(err)
    15  	}
    16  	defer q.Drop()
    17  
    18  	if _, err = q.EnqueueString("value"); err != nil {
    19  		t.Error(err)
    20  	}
    21  
    22  	if q.Length() != 1 {
    23  		t.Errorf("Expected queue length of 1, got %d", q.Length())
    24  	}
    25  
    26  	q.Close()
    27  
    28  	if _, err = q.Dequeue(); err != ErrDBClosed {
    29  		t.Errorf("Expected to get database closed error, got %s", err.Error())
    30  	}
    31  
    32  	if q.Length() != 0 {
    33  		t.Errorf("Expected queue length of 0, got %d", q.Length())
    34  	}
    35  }
    36  
    37  func TestQueueDrop(t *testing.T) {
    38  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    39  	q, err := OpenQueue(file)
    40  	if err != nil {
    41  		t.Error(err)
    42  	}
    43  
    44  	if _, err = os.Stat(file); os.IsNotExist(err) {
    45  		t.Error(err)
    46  	}
    47  
    48  	q.Drop()
    49  
    50  	if _, err = os.Stat(file); err == nil {
    51  		t.Error("Expected directory for test database to have been deleted")
    52  	}
    53  }
    54  
    55  func TestQueueIncompatibleType(t *testing.T) {
    56  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    57  	pq, err := OpenPriorityQueue(file, ASC)
    58  	if err != nil {
    59  		t.Error(err)
    60  	}
    61  	defer pq.Drop()
    62  	pq.Close()
    63  
    64  	if _, err = OpenQueue(file); err != ErrIncompatibleType {
    65  		t.Error("Expected priority queue to return ErrIncompatibleTypes when opening queuePriorityQueue")
    66  	}
    67  }
    68  
    69  func TestQueueEnqueue(t *testing.T) {
    70  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    71  	q, err := OpenQueue(file)
    72  	if err != nil {
    73  		t.Error(err)
    74  	}
    75  	defer q.Drop()
    76  
    77  	for i := 1; i <= 10; i++ {
    78  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
    79  			t.Error(err)
    80  		}
    81  	}
    82  
    83  	if q.Length() != 10 {
    84  		t.Errorf("Expected queue size of 10, got %d", q.Length())
    85  	}
    86  }
    87  
    88  func TestQueueDequeue(t *testing.T) {
    89  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    90  	q, err := OpenQueue(file)
    91  	if err != nil {
    92  		t.Error(err)
    93  	}
    94  	defer q.Drop()
    95  
    96  	for i := 1; i <= 10; i++ {
    97  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
    98  			t.Error(err)
    99  		}
   100  	}
   101  
   102  	if q.Length() != 10 {
   103  		t.Errorf("Expected queue length of 10, got %d", q.Length())
   104  	}
   105  
   106  	deqItem, err := q.Dequeue()
   107  	if err != nil {
   108  		t.Error(err)
   109  	}
   110  
   111  	if q.Length() != 9 {
   112  		t.Errorf("Expected queue length of 9, got %d", q.Length())
   113  	}
   114  
   115  	compStr := "value for item 1"
   116  
   117  	if deqItem.ToString() != compStr {
   118  		t.Errorf("Expected string to be '%s', got '%s'", compStr, deqItem.ToString())
   119  	}
   120  }
   121  
   122  func TestQueueEncodeDecodePointerJSON(t *testing.T) {
   123  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   124  	q, err := OpenQueue(file)
   125  	if err != nil {
   126  		t.Error(err)
   127  	}
   128  	defer q.Drop()
   129  
   130  	type subObject struct {
   131  		Value *int
   132  	}
   133  
   134  	type object struct {
   135  		Value     int
   136  		SubObject subObject
   137  	}
   138  
   139  	val := 0
   140  	obj := object{
   141  		Value: 0,
   142  		SubObject: subObject{
   143  			Value: &val,
   144  		},
   145  	}
   146  
   147  	if _, err = q.EnqueueObjectAsJSON(obj); err != nil {
   148  		t.Error(err)
   149  	}
   150  
   151  	item, err := q.Dequeue()
   152  	if err != nil {
   153  		t.Error(err)
   154  	}
   155  
   156  	var itemObj object
   157  	if err := item.ToObjectFromJSON(&itemObj); err != nil {
   158  		t.Error(err)
   159  	}
   160  
   161  	if *itemObj.SubObject.Value != 0 {
   162  		t.Errorf("Expected object subobject value to be '0', got '%v'", *itemObj.SubObject.Value)
   163  	}
   164  }
   165  
   166  func TestQueuePeek(t *testing.T) {
   167  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   168  	q, err := OpenQueue(file)
   169  	if err != nil {
   170  		t.Error(err)
   171  	}
   172  	defer q.Drop()
   173  
   174  	compStr := "value for item"
   175  
   176  	if _, err = q.EnqueueString(compStr); err != nil {
   177  		t.Error(err)
   178  	}
   179  
   180  	peekItem, err := q.Peek()
   181  	if err != nil {
   182  		t.Error(err)
   183  	}
   184  
   185  	if peekItem.ToString() != compStr {
   186  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   187  	}
   188  
   189  	if q.Length() != 1 {
   190  		t.Errorf("Expected queue length of 1, got %d", q.Length())
   191  	}
   192  }
   193  
   194  func TestQueuePeekByOffset(t *testing.T) {
   195  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   196  	q, err := OpenQueue(file)
   197  	if err != nil {
   198  		t.Error(err)
   199  	}
   200  	defer q.Drop()
   201  
   202  	for i := 1; i <= 10; i++ {
   203  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
   204  			t.Error(err)
   205  		}
   206  	}
   207  
   208  	compStrFirst := "value for item 1"
   209  	compStrLast := "value for item 10"
   210  	compStr := "value for item 4"
   211  
   212  	peekFirstItem, err := q.PeekByOffset(0)
   213  	if err != nil {
   214  		t.Error(err)
   215  	}
   216  
   217  	if peekFirstItem.ToString() != compStrFirst {
   218  		t.Errorf("Expected string to be '%s', got '%s'", compStrFirst, peekFirstItem.ToString())
   219  	}
   220  
   221  	peekLastItem, err := q.PeekByOffset(9)
   222  	if err != nil {
   223  		t.Error(err)
   224  	}
   225  
   226  	if peekLastItem.ToString() != compStrLast {
   227  		t.Errorf("Expected string to be '%s', got '%s'", compStrLast, peekLastItem.ToString())
   228  	}
   229  
   230  	peekItem, err := q.PeekByOffset(3)
   231  	if err != nil {
   232  		t.Error(err)
   233  	}
   234  
   235  	if peekItem.ToString() != compStr {
   236  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   237  	}
   238  
   239  	if q.Length() != 10 {
   240  		t.Errorf("Expected queue length of 10, got %d", q.Length())
   241  	}
   242  }
   243  
   244  func TestQueuePeekByID(t *testing.T) {
   245  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   246  	q, err := OpenQueue(file)
   247  	if err != nil {
   248  		t.Error(err)
   249  	}
   250  	defer q.Drop()
   251  
   252  	for i := 1; i <= 10; i++ {
   253  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
   254  			t.Error(err)
   255  		}
   256  	}
   257  
   258  	compStr := "value for item 3"
   259  
   260  	peekItem, err := q.PeekByID(3)
   261  	if err != nil {
   262  		t.Error(err)
   263  	}
   264  
   265  	if peekItem.ToString() != compStr {
   266  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   267  	}
   268  
   269  	if q.Length() != 10 {
   270  		t.Errorf("Expected queue length of 10, got %d", q.Length())
   271  	}
   272  }
   273  
   274  func TestQueueUpdate(t *testing.T) {
   275  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   276  	q, err := OpenQueue(file)
   277  	if err != nil {
   278  		t.Error(err)
   279  	}
   280  	defer q.Drop()
   281  
   282  	for i := 1; i <= 10; i++ {
   283  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
   284  			t.Error(err)
   285  		}
   286  	}
   287  
   288  	item, err := q.PeekByID(3)
   289  	if err != nil {
   290  		t.Error(err)
   291  	}
   292  
   293  	oldCompStr := "value for item 3"
   294  	newCompStr := "new value for item 3"
   295  
   296  	if item.ToString() != oldCompStr {
   297  		t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString())
   298  	}
   299  
   300  	updatedItem, err := q.Update(item.ID, []byte(newCompStr))
   301  	if err != nil {
   302  		t.Error(err)
   303  	}
   304  
   305  	if updatedItem.ToString() != newCompStr {
   306  		t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString())
   307  	}
   308  
   309  	newItem, err := q.PeekByID(3)
   310  	if err != nil {
   311  		t.Error(err)
   312  	}
   313  
   314  	if newItem.ToString() != newCompStr {
   315  		t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString())
   316  	}
   317  }
   318  
   319  func TestQueueUpdateString(t *testing.T) {
   320  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   321  	q, err := OpenQueue(file)
   322  	if err != nil {
   323  		t.Error(err)
   324  	}
   325  	defer q.Drop()
   326  
   327  	for i := 1; i <= 10; i++ {
   328  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
   329  			t.Error(err)
   330  		}
   331  	}
   332  
   333  	item, err := q.PeekByID(3)
   334  	if err != nil {
   335  		t.Error(err)
   336  	}
   337  
   338  	oldCompStr := "value for item 3"
   339  	newCompStr := "new value for item 3"
   340  
   341  	if item.ToString() != oldCompStr {
   342  		t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString())
   343  	}
   344  
   345  	updatedItem, err := q.UpdateString(item.ID, newCompStr)
   346  	if err != nil {
   347  		t.Error(err)
   348  	}
   349  
   350  	if updatedItem.ToString() != newCompStr {
   351  		t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString())
   352  	}
   353  
   354  	newItem, err := q.PeekByID(3)
   355  	if err != nil {
   356  		t.Error(err)
   357  	}
   358  
   359  	if newItem.ToString() != newCompStr {
   360  		t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString())
   361  	}
   362  }
   363  
   364  func TestQueueUpdateObject(t *testing.T) {
   365  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   366  	q, err := OpenQueue(file)
   367  	if err != nil {
   368  		t.Error(err)
   369  	}
   370  	defer q.Drop()
   371  
   372  	type object struct {
   373  		Value int
   374  	}
   375  
   376  	for i := 1; i <= 10; i++ {
   377  		if _, err = q.EnqueueObject(object{i}); err != nil {
   378  			t.Error(err)
   379  		}
   380  	}
   381  
   382  	item, err := q.PeekByID(3)
   383  	if err != nil {
   384  		t.Error(err)
   385  	}
   386  
   387  	oldCompObj := object{3}
   388  	newCompObj := object{33}
   389  
   390  	var obj object
   391  	if err := item.ToObject(&obj); err != nil {
   392  		t.Error(err)
   393  	}
   394  
   395  	if obj != oldCompObj {
   396  		t.Errorf("Expected object to be '%+v', got '%+v'", oldCompObj, obj)
   397  	}
   398  
   399  	updatedItem, err := q.UpdateObject(item.ID, newCompObj)
   400  	if err != nil {
   401  		t.Error(err)
   402  	}
   403  
   404  	if err := updatedItem.ToObject(&obj); err != nil {
   405  		t.Error(err)
   406  	}
   407  
   408  	if obj != newCompObj {
   409  		t.Errorf("Expected current object to be '%+v', got '%+v'", newCompObj, obj)
   410  	}
   411  
   412  	newItem, err := q.PeekByID(3)
   413  	if err != nil {
   414  		t.Error(err)
   415  	}
   416  
   417  	if err := newItem.ToObject(&obj); err != nil {
   418  		t.Error(err)
   419  	}
   420  
   421  	if obj != newCompObj {
   422  		t.Errorf("Expected new object to be '%+v', got '%+v'", newCompObj, obj)
   423  	}
   424  }
   425  
   426  func TestQueueUpdateObjectAsJSON(t *testing.T) {
   427  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   428  	q, err := OpenQueue(file)
   429  	if err != nil {
   430  		t.Error(err)
   431  	}
   432  	defer q.Drop()
   433  
   434  	type subObject struct {
   435  		Value *int
   436  	}
   437  
   438  	type object struct {
   439  		Value     int
   440  		SubObject subObject
   441  	}
   442  
   443  	for i := 1; i <= 10; i++ {
   444  		obj := object{
   445  			Value: i,
   446  			SubObject: subObject{
   447  				Value: &i,
   448  			},
   449  		}
   450  
   451  		if _, err = q.EnqueueObjectAsJSON(obj); err != nil {
   452  			t.Error(err)
   453  		}
   454  	}
   455  
   456  	item, err := q.PeekByID(3)
   457  	if err != nil {
   458  		t.Error(err)
   459  	}
   460  
   461  	oldCompObjVal := 3
   462  	oldCompObj := object{
   463  		Value: 3,
   464  		SubObject: subObject{
   465  			Value: &oldCompObjVal,
   466  		},
   467  	}
   468  	newCompObjVal := 33
   469  	newCompObj := object{
   470  		Value: 33,
   471  		SubObject: subObject{
   472  			Value: &newCompObjVal,
   473  		},
   474  	}
   475  
   476  	var obj object
   477  	if err := item.ToObjectFromJSON(&obj); err != nil {
   478  		t.Error(err)
   479  	}
   480  
   481  	if *obj.SubObject.Value != *oldCompObj.SubObject.Value {
   482  		t.Errorf("Expected object subobject value to be '%+v', got '%+v'", *oldCompObj.SubObject.Value, *obj.SubObject.Value)
   483  	}
   484  
   485  	updatedItem, err := q.UpdateObjectAsJSON(item.ID, newCompObj)
   486  	if err != nil {
   487  		t.Error(err)
   488  	}
   489  
   490  	if err := updatedItem.ToObjectFromJSON(&obj); err != nil {
   491  		t.Error(err)
   492  	}
   493  
   494  	if *obj.SubObject.Value != *newCompObj.SubObject.Value {
   495  		t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value)
   496  	}
   497  
   498  	newItem, err := q.PeekByID(3)
   499  	if err != nil {
   500  		t.Error(err)
   501  	}
   502  
   503  	if err := newItem.ToObjectFromJSON(&obj); err != nil {
   504  		t.Error(err)
   505  	}
   506  
   507  	if *obj.SubObject.Value != *newCompObj.SubObject.Value {
   508  		t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value)
   509  	}
   510  }
   511  
   512  func TestQueueUpdateOutOfBounds(t *testing.T) {
   513  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   514  	q, err := OpenQueue(file)
   515  	if err != nil {
   516  		t.Error(err)
   517  	}
   518  	defer q.Drop()
   519  
   520  	for i := 1; i <= 10; i++ {
   521  		if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil {
   522  			t.Error(err)
   523  		}
   524  	}
   525  
   526  	if q.Length() != 10 {
   527  		t.Errorf("Expected queue length of 10, got %d", q.Length())
   528  	}
   529  
   530  	deqItem, err := q.Dequeue()
   531  	if err != nil {
   532  		t.Error(err)
   533  	}
   534  
   535  	if q.Length() != 9 {
   536  		t.Errorf("Expected queue length of 9, got %d", q.Length())
   537  	}
   538  
   539  	if _, err = q.Update(deqItem.ID, []byte(`new value`)); err != ErrOutOfBounds {
   540  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   541  	}
   542  
   543  	if _, err = q.Update(deqItem.ID+1, []byte(`new value`)); err != nil {
   544  		t.Error(err)
   545  	}
   546  }
   547  
   548  func TestQueueEmpty(t *testing.T) {
   549  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   550  	q, err := OpenQueue(file)
   551  	if err != nil {
   552  		t.Error(err)
   553  	}
   554  	defer q.Drop()
   555  
   556  	_, err = q.EnqueueString("value for item")
   557  	if err != nil {
   558  		t.Error(err)
   559  	}
   560  
   561  	_, err = q.Dequeue()
   562  	if err != nil {
   563  		t.Error(err)
   564  	}
   565  
   566  	_, err = q.Dequeue()
   567  	if err != ErrEmpty {
   568  		t.Errorf("Expected to get empty error, got %s", err.Error())
   569  	}
   570  }
   571  
   572  func TestQueueOutOfBounds(t *testing.T) {
   573  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   574  	q, err := OpenQueue(file)
   575  	if err != nil {
   576  		t.Error(err)
   577  	}
   578  	defer q.Drop()
   579  
   580  	_, err = q.EnqueueString("value for item")
   581  	if err != nil {
   582  		t.Error(err)
   583  	}
   584  
   585  	_, err = q.PeekByOffset(2)
   586  	if err != ErrOutOfBounds {
   587  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   588  	}
   589  }
   590  
   591  func BenchmarkQueueEnqueue(b *testing.B) {
   592  	// Open test database
   593  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   594  	q, err := OpenQueue(file)
   595  	if err != nil {
   596  		b.Error(err)
   597  	}
   598  	defer q.Drop()
   599  
   600  	b.ResetTimer()
   601  	b.ReportAllocs()
   602  
   603  	for n := 0; n < b.N; n++ {
   604  		_, _ = q.Enqueue([]byte("value"))
   605  	}
   606  }
   607  
   608  func BenchmarkQueueDequeue(b *testing.B) {
   609  	// Open test database
   610  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   611  	q, err := OpenQueue(file)
   612  	if err != nil {
   613  		b.Error(err)
   614  	}
   615  	defer q.Drop()
   616  
   617  	// Fill with dummy data
   618  	for n := 0; n < b.N; n++ {
   619  		if _, err = q.Enqueue([]byte("value")); err != nil {
   620  			b.Error(err)
   621  		}
   622  	}
   623  
   624  	// Start benchmark
   625  	b.ResetTimer()
   626  	b.ReportAllocs()
   627  
   628  	for n := 0; n < b.N; n++ {
   629  		_, _ = q.Dequeue()
   630  	}
   631  }