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

     1  package queue
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func TestPrefixQueueClose(t *testing.T) {
    11  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    12  	pq, err := OpenPrefixQueue(file)
    13  	if err != nil {
    14  		t.Error(err)
    15  	}
    16  	defer pq.Drop()
    17  
    18  	if _, err = pq.EnqueueString("prefix", "value"); err != nil {
    19  		t.Error(err)
    20  	}
    21  
    22  	if pq.Length() != 1 {
    23  		t.Errorf("Expected queue length of 1, got %d", pq.Length())
    24  	}
    25  
    26  	pq.Close()
    27  
    28  	if _, err = pq.DequeueString("prefix"); err != ErrDBClosed {
    29  		t.Errorf("Expected to get database closed error, got %s", err.Error())
    30  	}
    31  
    32  	if pq.Length() != 0 {
    33  		t.Errorf("Expected queue length of 0, got %d", pq.Length())
    34  	}
    35  }
    36  
    37  func TestPrefixQueueDrop(t *testing.T) {
    38  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    39  	pq, err := OpenPrefixQueue(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  	pq.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 TestPrefixQueueIncompatibleType(t *testing.T) {
    56  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    57  	prq, err := OpenPriorityQueue(file, ASC)
    58  	if err != nil {
    59  		t.Error(err)
    60  	}
    61  	defer prq.Drop()
    62  	prq.Close()
    63  
    64  	if _, err = OpenPrefixQueue(file); err != ErrIncompatibleType {
    65  		t.Error("Expected priority queue to return ErrIncompatibleTypes when opening queuePriorityQueue")
    66  	}
    67  }
    68  
    69  func TestPrefixQueueEnqueue(t *testing.T) {
    70  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    71  	pq, err := OpenPrefixQueue(file)
    72  	if err != nil {
    73  		t.Error(err)
    74  	}
    75  	defer pq.Drop()
    76  
    77  	for i := 1; i <= 10; i++ {
    78  		if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil {
    79  			t.Error(err)
    80  		}
    81  	}
    82  
    83  	if pq.Length() != 10 {
    84  		t.Errorf("Expected queue size of 10, got %d", pq.Length())
    85  	}
    86  }
    87  
    88  func TestPrefixQueueDequeue(t *testing.T) {
    89  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    90  	pq, err := OpenPrefixQueue(file)
    91  	if err != nil {
    92  		t.Error(err)
    93  	}
    94  	defer pq.Drop()
    95  
    96  	for i := 1; i <= 10; i++ {
    97  		if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil {
    98  			t.Error(err)
    99  		}
   100  	}
   101  
   102  	if pq.Length() != 10 {
   103  		t.Errorf("Expected queue length of 10, got %d", pq.Length())
   104  	}
   105  
   106  	deqItem, err := pq.DequeueString("prefix")
   107  	if err != nil {
   108  		t.Error(err)
   109  	}
   110  
   111  	if pq.Length() != 9 {
   112  		t.Errorf("Expected queue length of 9, got %d", pq.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 TestPrefixQueueEncodeDecodePointerJSON(t *testing.T) {
   123  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   124  	pq, err := OpenPrefixQueue(file)
   125  	if err != nil {
   126  		t.Error(err)
   127  	}
   128  	defer pq.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 = pq.EnqueueObjectAsJSON([]byte("prefix"), obj); err != nil {
   148  		t.Error(err)
   149  	}
   150  
   151  	item, err := pq.Dequeue([]byte("prefix"))
   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 TestPrefixQueuePeek(t *testing.T) {
   167  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   168  	pq, err := OpenPrefixQueue(file)
   169  	if err != nil {
   170  		t.Error(err)
   171  	}
   172  	defer pq.Drop()
   173  
   174  	compStr := "value for item"
   175  
   176  	if _, err = pq.EnqueueString("prefix", compStr); err != nil {
   177  		t.Error(err)
   178  	}
   179  
   180  	peekItem, err := pq.PeekString("prefix")
   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 pq.Length() != 1 {
   190  		t.Errorf("Expected queue length of 1, got %d", pq.Length())
   191  	}
   192  }
   193  
   194  func TestPrefixQueuePeekByID(t *testing.T) {
   195  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   196  	pq, err := OpenPrefixQueue(file)
   197  	if err != nil {
   198  		t.Error(err)
   199  	}
   200  	defer pq.Drop()
   201  
   202  	for i := 1; i <= 10; i++ {
   203  		if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil {
   204  			t.Error(err)
   205  		}
   206  	}
   207  
   208  	compStr := "value for item 3"
   209  
   210  	peekItem, err := pq.PeekByIDString("prefix", 3)
   211  	if err != nil {
   212  		t.Error(err)
   213  	}
   214  
   215  	if peekItem.ToString() != compStr {
   216  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   217  	}
   218  
   219  	if pq.Length() != 10 {
   220  		t.Errorf("Expected queue length of 10, got %d", pq.Length())
   221  	}
   222  }
   223  
   224  func TestPrefixQueueUpdate(t *testing.T) {
   225  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   226  	pq, err := OpenPrefixQueue(file)
   227  	if err != nil {
   228  		t.Error(err)
   229  	}
   230  	defer pq.Drop()
   231  
   232  	for i := 1; i <= 10; i++ {
   233  		if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil {
   234  			t.Error(err)
   235  		}
   236  	}
   237  
   238  	item, err := pq.PeekByIDString("prefix", 3)
   239  	if err != nil {
   240  		t.Error(err)
   241  	}
   242  
   243  	oldCompStr := "value for item 3"
   244  	newCompStr := "new value for item 3"
   245  
   246  	if item.ToString() != oldCompStr {
   247  		t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString())
   248  	}
   249  
   250  	updatedItem, err := pq.UpdateString("prefix", item.ID, newCompStr)
   251  	if err != nil {
   252  		t.Error(err)
   253  	}
   254  
   255  	if updatedItem.ToString() != newCompStr {
   256  		t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString())
   257  	}
   258  
   259  	newItem, err := pq.PeekByIDString("prefix", 3)
   260  	if err != nil {
   261  		t.Error(err)
   262  	}
   263  
   264  	if newItem.ToString() != newCompStr {
   265  		t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString())
   266  	}
   267  }
   268  
   269  func TestPrefixQueueUpdateString(t *testing.T) {
   270  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   271  	pq, err := OpenPrefixQueue(file)
   272  	if err != nil {
   273  		t.Error(err)
   274  	}
   275  	defer pq.Drop()
   276  
   277  	for i := 1; i <= 10; i++ {
   278  		if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil {
   279  			t.Error(err)
   280  		}
   281  	}
   282  
   283  	item, err := pq.PeekByIDString("prefix", 3)
   284  	if err != nil {
   285  		t.Error(err)
   286  	}
   287  
   288  	oldCompStr := "value for item 3"
   289  	newCompStr := "new value for item 3"
   290  
   291  	if item.ToString() != oldCompStr {
   292  		t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString())
   293  	}
   294  
   295  	updatedItem, err := pq.UpdateString("prefix", item.ID, newCompStr)
   296  	if err != nil {
   297  		t.Error(err)
   298  	}
   299  
   300  	if updatedItem.ToString() != newCompStr {
   301  		t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString())
   302  	}
   303  
   304  	newItem, err := pq.PeekByIDString("prefix", 3)
   305  	if err != nil {
   306  		t.Error(err)
   307  	}
   308  
   309  	if newItem.ToString() != newCompStr {
   310  		t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString())
   311  	}
   312  }
   313  
   314  func TestPrefixQueueUpdateObject(t *testing.T) {
   315  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   316  	pq, err := OpenPrefixQueue(file)
   317  	if err != nil {
   318  		t.Error(err)
   319  	}
   320  	defer pq.Drop()
   321  
   322  	type object struct {
   323  		Value int
   324  	}
   325  
   326  	for i := 1; i <= 10; i++ {
   327  		if _, err = pq.EnqueueObject([]byte("prefix"), object{i}); err != nil {
   328  			t.Error(err)
   329  		}
   330  	}
   331  
   332  	item, err := pq.PeekByIDString("prefix", 3)
   333  	if err != nil {
   334  		t.Error(err)
   335  	}
   336  
   337  	oldCompObj := object{3}
   338  	newCompObj := object{33}
   339  
   340  	var obj object
   341  	if err := item.ToObject(&obj); err != nil {
   342  		t.Error(err)
   343  	}
   344  
   345  	if obj != oldCompObj {
   346  		t.Errorf("Expected object to be '%+v', got '%+v'", oldCompObj, obj)
   347  	}
   348  
   349  	updatedItem, err := pq.UpdateObject([]byte("prefix"), item.ID, newCompObj)
   350  	if err != nil {
   351  		t.Error(err)
   352  	}
   353  
   354  	if err := updatedItem.ToObject(&obj); err != nil {
   355  		t.Error(err)
   356  	}
   357  
   358  	if obj != newCompObj {
   359  		t.Errorf("Expected current object to be '%+v', got '%+v'", newCompObj, obj)
   360  	}
   361  
   362  	newItem, err := pq.PeekByIDString("prefix", 3)
   363  	if err != nil {
   364  		t.Error(err)
   365  	}
   366  
   367  	if err := newItem.ToObject(&obj); err != nil {
   368  		t.Error(err)
   369  	}
   370  
   371  	if obj != newCompObj {
   372  		t.Errorf("Expected new object to be '%+v', got '%+v'", newCompObj, obj)
   373  	}
   374  }
   375  
   376  func TestPrefixQueueUpdateObjectAsJSON(t *testing.T) {
   377  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   378  	pq, err := OpenPrefixQueue(file)
   379  	if err != nil {
   380  		t.Error(err)
   381  	}
   382  	defer pq.Drop()
   383  
   384  	type subObject struct {
   385  		Value *int
   386  	}
   387  
   388  	type object struct {
   389  		Value     int
   390  		SubObject subObject
   391  	}
   392  
   393  	for i := 1; i <= 10; i++ {
   394  		obj := object{
   395  			Value: i,
   396  			SubObject: subObject{
   397  				Value: &i,
   398  			},
   399  		}
   400  
   401  		if _, err = pq.EnqueueObjectAsJSON([]byte("prefix"), obj); err != nil {
   402  			t.Error(err)
   403  		}
   404  	}
   405  
   406  	item, err := pq.PeekByIDString("prefix", 3)
   407  	if err != nil {
   408  		t.Error(err)
   409  	}
   410  
   411  	oldCompObjVal := 3
   412  	oldCompObj := object{
   413  		Value: 3,
   414  		SubObject: subObject{
   415  			Value: &oldCompObjVal,
   416  		},
   417  	}
   418  	newCompObjVal := 33
   419  	newCompObj := object{
   420  		Value: 33,
   421  		SubObject: subObject{
   422  			Value: &newCompObjVal,
   423  		},
   424  	}
   425  
   426  	var obj object
   427  	if err := item.ToObjectFromJSON(&obj); err != nil {
   428  		t.Error(err)
   429  	}
   430  
   431  	if *obj.SubObject.Value != *oldCompObj.SubObject.Value {
   432  		t.Errorf("Expected object subobject value to be '%+v', got '%+v'", *oldCompObj.SubObject.Value, *obj.SubObject.Value)
   433  	}
   434  
   435  	updatedItem, err := pq.UpdateObjectAsJSON([]byte("prefix"), item.ID, newCompObj)
   436  	if err != nil {
   437  		t.Error(err)
   438  	}
   439  
   440  	if err := updatedItem.ToObjectFromJSON(&obj); err != nil {
   441  		t.Error(err)
   442  	}
   443  
   444  	if *obj.SubObject.Value != *newCompObj.SubObject.Value {
   445  		t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value)
   446  	}
   447  
   448  	newItem, err := pq.PeekByIDString("prefix", 3)
   449  	if err != nil {
   450  		t.Error(err)
   451  	}
   452  
   453  	if err := newItem.ToObjectFromJSON(&obj); err != nil {
   454  		t.Error(err)
   455  	}
   456  
   457  	if *obj.SubObject.Value != *newCompObj.SubObject.Value {
   458  		t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value)
   459  	}
   460  }
   461  
   462  func TestPrefixQueueUpdateOutOfBounds(t *testing.T) {
   463  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   464  	pq, err := OpenPrefixQueue(file)
   465  	if err != nil {
   466  		t.Error(err)
   467  	}
   468  	defer pq.Drop()
   469  
   470  	for i := 1; i <= 10; i++ {
   471  		if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil {
   472  			t.Error(err)
   473  		}
   474  	}
   475  
   476  	if pq.Length() != 10 {
   477  		t.Errorf("Expected queue length of 10, got %d", pq.Length())
   478  	}
   479  
   480  	deqItem, err := pq.DequeueString("prefix")
   481  	if err != nil {
   482  		t.Error(err)
   483  	}
   484  
   485  	if pq.Length() != 9 {
   486  		t.Errorf("Expected queue length of 9, got %d", pq.Length())
   487  	}
   488  
   489  	if _, err = pq.Update([]byte("prefix"), deqItem.ID, []byte(`new value`)); err != ErrOutOfBounds {
   490  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   491  	}
   492  
   493  	if _, err = pq.Update([]byte("prefix"), deqItem.ID+1, []byte(`new value`)); err != nil {
   494  		t.Error(err)
   495  	}
   496  }
   497  
   498  func TestPrefixQueueEmpty(t *testing.T) {
   499  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   500  	pq, err := OpenPrefixQueue(file)
   501  	if err != nil {
   502  		t.Error(err)
   503  	}
   504  	defer pq.Drop()
   505  
   506  	_, err = pq.EnqueueString("prefix", "value for item")
   507  	if err != nil {
   508  		t.Error(err)
   509  	}
   510  
   511  	_, err = pq.DequeueString("prefix")
   512  	if err != nil {
   513  		t.Error(err)
   514  	}
   515  
   516  	_, err = pq.DequeueString("prefix")
   517  	if err != ErrEmpty {
   518  		t.Errorf("Expected to get empty error, got %s", err.Error())
   519  	}
   520  }
   521  
   522  func TestPrefixQueueOutOfBounds(t *testing.T) {
   523  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   524  	pq, err := OpenPrefixQueue(file)
   525  	if err != nil {
   526  		t.Error(err)
   527  	}
   528  	defer pq.Drop()
   529  
   530  	_, err = pq.EnqueueString("prefix", "value for item")
   531  	if err != nil {
   532  		t.Error(err)
   533  	}
   534  
   535  	_, err = pq.PeekByIDString("prefix", 2)
   536  	if err != ErrOutOfBounds {
   537  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   538  	}
   539  }
   540  
   541  func BenchmarkPrefixQueueEnqueue(b *testing.B) {
   542  	// Open test database
   543  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   544  	pq, err := OpenPrefixQueue(file)
   545  	if err != nil {
   546  		b.Error(err)
   547  	}
   548  	defer pq.Drop()
   549  
   550  	b.ResetTimer()
   551  	b.ReportAllocs()
   552  
   553  	for n := 0; n < b.N; n++ {
   554  		_, _ = pq.Enqueue([]byte("prefix"), []byte("value"))
   555  	}
   556  }
   557  
   558  func BenchmarkPrefixQueueDequeue(b *testing.B) {
   559  	// Open test database
   560  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   561  	pq, err := OpenPrefixQueue(file)
   562  	if err != nil {
   563  		b.Error(err)
   564  	}
   565  	defer pq.Drop()
   566  
   567  	// Fill with dummy data
   568  	for n := 0; n < b.N; n++ {
   569  		if _, err = pq.Enqueue([]byte("prefix"), []byte("value")); err != nil {
   570  			b.Error(err)
   571  		}
   572  	}
   573  
   574  	// Start benchmark
   575  	b.ResetTimer()
   576  	b.ReportAllocs()
   577  
   578  	for n := 0; n < b.N; n++ {
   579  		_, _ = pq.Dequeue([]byte("prefix"))
   580  	}
   581  }