github.com/Jeffail/benthos/v3@v3.65.0/lib/cache/memory_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/Jeffail/benthos/v3/lib/log"
     9  	"github.com/Jeffail/benthos/v3/lib/metrics"
    10  	"github.com/Jeffail/benthos/v3/lib/types"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  //------------------------------------------------------------------------------
    16  
    17  func TestMemoryCache(t *testing.T) {
    18  	testLog := log.Noop()
    19  
    20  	conf := NewConfig()
    21  	conf.Type = "memory"
    22  
    23  	c, err := New(conf, nil, testLog, metrics.Noop())
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  
    28  	expErr := types.ErrKeyNotFound
    29  	if _, act := c.Get("foo"); act != expErr {
    30  		t.Errorf("Wrong error returned: %v != %v", act, expErr)
    31  	}
    32  
    33  	if err = c.Set("foo", []byte("1")); err != nil {
    34  		t.Error(err)
    35  	}
    36  
    37  	exp := "1"
    38  	if act, err := c.Get("foo"); err != nil {
    39  		t.Error(err)
    40  	} else if string(act) != exp {
    41  		t.Errorf("Wrong result: %v != %v", string(act), exp)
    42  	}
    43  
    44  	if err = c.Add("bar", []byte("2")); err != nil {
    45  		t.Error(err)
    46  	}
    47  
    48  	exp = "2"
    49  	if act, err := c.Get("bar"); err != nil {
    50  		t.Error(err)
    51  	} else if string(act) != exp {
    52  		t.Errorf("Wrong result: %v != %v", string(act), exp)
    53  	}
    54  
    55  	expErr = types.ErrKeyAlreadyExists
    56  	if act := c.Add("foo", []byte("2")); expErr != act {
    57  		t.Errorf("Wrong error returned: %v != %v", act, expErr)
    58  	}
    59  
    60  	if err = c.Set("foo", []byte("3")); err != nil {
    61  		t.Error(err)
    62  	}
    63  
    64  	exp = "3"
    65  	if act, err := c.Get("foo"); err != nil {
    66  		t.Error(err)
    67  	} else if string(act) != exp {
    68  		t.Errorf("Wrong result: %v != %v", string(act), exp)
    69  	}
    70  
    71  	if err = c.Delete("foo"); err != nil {
    72  		t.Error(err)
    73  	}
    74  
    75  	if _, err = c.Get("foo"); err != types.ErrKeyNotFound {
    76  		t.Errorf("Wrong error returned: %v != %v", err, types.ErrKeyNotFound)
    77  	}
    78  }
    79  
    80  func TestMemoryCacheCompaction(t *testing.T) {
    81  	conf := NewConfig()
    82  	conf.Type = "memory"
    83  	conf.Memory.TTL = 0
    84  	conf.Memory.CompactionInterval = "1ns"
    85  
    86  	c, err := New(conf, nil, log.Noop(), metrics.Noop())
    87  	require.NoError(t, err)
    88  
    89  	_, err = c.Get("foo")
    90  	assert.Equal(t, types.ErrKeyNotFound, err)
    91  
    92  	err = c.Set("foo", []byte("1"))
    93  	require.NoError(t, err)
    94  
    95  	_, err = c.Get("foo")
    96  	assert.Equal(t, types.ErrKeyNotFound, err)
    97  
    98  	<-time.After(time.Millisecond * 50)
    99  
   100  	// This should trigger compaction.
   101  	err = c.Add("bar", []byte("2"))
   102  	require.NoError(t, err)
   103  
   104  	_, err = c.Get("bar")
   105  	assert.Equal(t, types.ErrKeyNotFound, err)
   106  }
   107  
   108  func TestMemoryCacheInitValues(t *testing.T) {
   109  	conf := NewConfig()
   110  	conf.Type = "memory"
   111  	conf.Memory.TTL = 0
   112  	conf.Memory.CompactionInterval = ""
   113  	conf.Memory.InitValues = map[string]string{
   114  		"foo":  "bar",
   115  		"foo2": "bar2",
   116  	}
   117  
   118  	c, err := New(conf, nil, log.Noop(), metrics.Noop())
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	exp := "bar"
   124  	if act, err := c.Get("foo"); err != nil {
   125  		t.Error(err)
   126  	} else if string(act) != exp {
   127  		t.Errorf("Wrong result: %v != %v", string(act), exp)
   128  	}
   129  
   130  	// This should trigger compaction.
   131  	if err = c.Add("foo3", []byte("bar3")); err != nil {
   132  		t.Error(err)
   133  	}
   134  
   135  	exp = "bar"
   136  	if act, err := c.Get("foo"); err != nil {
   137  		t.Error(err)
   138  	} else if string(act) != exp {
   139  		t.Errorf("Wrong result: %v != %v", string(act), exp)
   140  	}
   141  
   142  	exp = "bar2"
   143  	if act, err := c.Get("foo2"); err != nil {
   144  		t.Error(err)
   145  	} else if string(act) != exp {
   146  		t.Errorf("Wrong result: %v != %v", string(act), exp)
   147  	}
   148  }
   149  
   150  func TestMemoryCacheCompactionOnRead(t *testing.T) {
   151  	testLog := log.Noop()
   152  
   153  	conf := NewConfig()
   154  	conf.Type = "memory"
   155  	conf.Memory.TTL = 0
   156  	conf.Memory.CompactionInterval = "1ns"
   157  
   158  	c, err := New(conf, nil, testLog, metrics.Noop())
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  
   163  	expErr := types.ErrKeyNotFound
   164  	if _, act := c.Get("foo"); act != expErr {
   165  		t.Errorf("Wrong error returned: %v != %v", act, expErr)
   166  	}
   167  
   168  	if err = c.Set("foo", []byte("1")); err != nil {
   169  		t.Error(err)
   170  	}
   171  
   172  	<-time.After(time.Millisecond * 50)
   173  
   174  	// This should trigger compaction.
   175  	if _, act := c.Get("foo"); act != expErr {
   176  		t.Errorf("Wrong error returned: %v != %v", act, expErr)
   177  	}
   178  }
   179  
   180  //------------------------------------------------------------------------------
   181  
   182  func BenchmarkMemoryShards1(b *testing.B) {
   183  	conf := NewConfig()
   184  	conf.Type = TypeMemory
   185  	conf.Memory.TTL = 0
   186  	conf.Memory.CompactionInterval = ""
   187  
   188  	c, err := New(conf, nil, log.Noop(), metrics.Noop())
   189  	require.NoError(b, err)
   190  
   191  	b.ResetTimer()
   192  
   193  	for i := 0; i < b.N; i++ {
   194  		key, value := fmt.Sprintf("key%v", i), []byte(fmt.Sprintf("foo%v", i))
   195  
   196  		assert.NoError(b, c.Set(key, value))
   197  
   198  		res, err := c.Get(key)
   199  		require.NoError(b, err)
   200  		assert.Equal(b, value, res)
   201  	}
   202  }
   203  
   204  func BenchmarkMemoryShards10(b *testing.B) {
   205  	conf := NewConfig()
   206  	conf.Type = TypeMemory
   207  	conf.Memory.TTL = 0
   208  	conf.Memory.CompactionInterval = ""
   209  	conf.Memory.Shards = 10
   210  
   211  	c, err := New(conf, nil, log.Noop(), metrics.Noop())
   212  	require.NoError(b, err)
   213  
   214  	b.ResetTimer()
   215  
   216  	for i := 0; i < b.N; i++ {
   217  		key, value := fmt.Sprintf("key%v", i), []byte(fmt.Sprintf("foo%v", i))
   218  
   219  		assert.NoError(b, c.Set(key, value))
   220  
   221  		res, err := c.Get(key)
   222  		require.NoError(b, err)
   223  		assert.Equal(b, value, res)
   224  	}
   225  }
   226  
   227  func BenchmarkMemoryShards100(b *testing.B) {
   228  	conf := NewConfig()
   229  	conf.Type = TypeMemory
   230  	conf.Memory.TTL = 0
   231  	conf.Memory.CompactionInterval = ""
   232  	conf.Memory.Shards = 10
   233  
   234  	c, err := New(conf, nil, log.Noop(), metrics.Noop())
   235  	require.NoError(b, err)
   236  
   237  	b.ResetTimer()
   238  
   239  	for i := 0; i < b.N; i++ {
   240  		key, value := fmt.Sprintf("key%v", i), []byte(fmt.Sprintf("foo%v", i))
   241  
   242  		assert.NoError(b, c.Set(key, value))
   243  
   244  		res, err := c.Get(key)
   245  		require.NoError(b, err)
   246  		assert.Equal(b, value, res)
   247  	}
   248  }