go.temporal.io/server@v1.23.0/common/cache/simple_test.go (about)

     1  // The MIT License (MIT)
     2  //
     3  // Copyright (c) 2017-2020 Uber Technologies Inc.
     4  //
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy
     6  // of this software and associated documentation files (the "Software"), to deal
     7  // in the Software without restriction, including without limitation the rights
     8  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  // copies of the Software, and to permit persons to whom the Software is
    10  // furnished to do so, subject to the following conditions:
    11  //
    12  // The above copyright notice and this permission notice shall be included in all
    13  // copies or substantial portions of the Software.
    14  //
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    18  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    19  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    20  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    21  // SOFTWARE.
    22  
    23  package cache
    24  
    25  import (
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func TestSimple(t *testing.T) {
    34  	cache := NewSimple(nil)
    35  
    36  	cache.Put("A", "Foo")
    37  	assert.Equal(t, "Foo", cache.Get("A"))
    38  	assert.Nil(t, cache.Get("B"))
    39  	assert.Equal(t, 1, cache.Size())
    40  
    41  	cache.Put("B", "Bar")
    42  	cache.Put("C", "Cid")
    43  	cache.Put("D", "Delt")
    44  	assert.Equal(t, 4, cache.Size())
    45  
    46  	assert.Equal(t, "Bar", cache.Get("B"))
    47  	assert.Equal(t, "Cid", cache.Get("C"))
    48  	assert.Equal(t, "Delt", cache.Get("D"))
    49  
    50  	cache.Put("A", "Foo2")
    51  	assert.Equal(t, "Foo2", cache.Get("A"))
    52  
    53  	cache.Put("E", "Epsi")
    54  	assert.Equal(t, "Epsi", cache.Get("E"))
    55  	assert.Equal(t, "Foo2", cache.Get("A"))
    56  
    57  	cache.Delete("A")
    58  	assert.Nil(t, cache.Get("A"))
    59  }
    60  
    61  func TestSimpleGenerics(t *testing.T) {
    62  	key := keyType{
    63  		dummyString: "some random key",
    64  		dummyInt:    59,
    65  	}
    66  	value := "some random value"
    67  
    68  	cache := NewSimple(nil)
    69  	cache.Put(key, value)
    70  
    71  	assert.Equal(t, value, cache.Get(key))
    72  	assert.Equal(t, value, cache.Get(keyType{
    73  		dummyString: "some random key",
    74  		dummyInt:    59,
    75  	}))
    76  	assert.Nil(t, cache.Get(keyType{
    77  		dummyString: "some other random key",
    78  		dummyInt:    56,
    79  	}))
    80  }
    81  
    82  func TestSimpleCacheConcurrentAccess(t *testing.T) {
    83  	cache := NewSimple(nil)
    84  	values := map[string]string{
    85  		"A": "foo",
    86  		"B": "bar",
    87  		"C": "zed",
    88  		"D": "dank",
    89  		"E": "ezpz",
    90  	}
    91  
    92  	for k, v := range values {
    93  		cache.Put(k, v)
    94  	}
    95  
    96  	start := make(chan struct{})
    97  	var wg sync.WaitGroup
    98  	for i := 0; i < 20; i++ {
    99  		wg.Add(2)
   100  
   101  		// concurrent get and put
   102  		go func() {
   103  			defer wg.Done()
   104  
   105  			<-start
   106  
   107  			for j := 0; j < 1000; j++ {
   108  				cache.Get("A")
   109  				cache.Put("A", "fooo")
   110  			}
   111  		}()
   112  
   113  		// concurrent iteration
   114  		go func() {
   115  			defer wg.Done()
   116  
   117  			<-start
   118  
   119  			for j := 0; j < 50; j++ {
   120  				it := cache.Iterator()
   121  				for it.HasNext() {
   122  					_ = it.Next()
   123  				}
   124  				it.Close()
   125  			}
   126  		}()
   127  	}
   128  
   129  	close(start)
   130  	wg.Wait()
   131  }
   132  
   133  func TestSimpleRemoveFunc(t *testing.T) {
   134  	ch := make(chan bool)
   135  	cache := NewSimple(&SimpleOptions{
   136  		RemovedFunc: func(i interface{}) {
   137  			_, ok := i.(*testing.T)
   138  			assert.True(t, ok)
   139  			ch <- true
   140  		},
   141  	})
   142  
   143  	cache.Put("testing", t)
   144  	cache.Delete("testing")
   145  	assert.Nil(t, cache.Get("testing"))
   146  
   147  	timeout := time.NewTimer(time.Millisecond * 300)
   148  	select {
   149  	case b := <-ch:
   150  		assert.True(t, b)
   151  	case <-timeout.C:
   152  		t.Error("RemovedFunc did not send true on channel ch")
   153  	}
   154  }
   155  
   156  func TestSimpleIterator(t *testing.T) {
   157  	expected := map[string]string{
   158  		"A": "Alpha",
   159  		"B": "Beta",
   160  		"G": "Gamma",
   161  		"D": "Delta",
   162  	}
   163  
   164  	cache := NewSimple(nil)
   165  
   166  	for k, v := range expected {
   167  		cache.Put(k, v)
   168  	}
   169  
   170  	actual := map[string]string{}
   171  
   172  	it := cache.Iterator()
   173  	for it.HasNext() {
   174  		entry := it.Next()
   175  		actual[entry.Key().(string)] = entry.Value().(string)
   176  	}
   177  	it.Close()
   178  	assert.Equal(t, expected, actual)
   179  
   180  	it = cache.Iterator()
   181  	for i := 0; i < len(expected); i++ {
   182  		entry := it.Next()
   183  		actual[entry.Key().(string)] = entry.Value().(string)
   184  	}
   185  	it.Close()
   186  	assert.Equal(t, expected, actual)
   187  }