github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/cache/fastcache/file_test.go (about)

     1  package fastcache
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"sync"
     7  	"testing"
     8  )
     9  
    10  func TestSaveLoadSmall(t *testing.T) {
    11  	const filePath = "TestSaveLoadSmall.fastcache"
    12  	defer os.RemoveAll(filePath)
    13  
    14  	c := New(1)
    15  	defer c.Reset()
    16  
    17  	key := []byte("foobar")
    18  	value := []byte("abcdef")
    19  	c.Set(key, value)
    20  	if err := c.SaveToFile(filePath); err != nil {
    21  		t.Fatalf("SaveToFile error: %s", err)
    22  	}
    23  
    24  	c1, err := LoadFromFile(filePath)
    25  	if err != nil {
    26  		t.Fatalf("LoadFromFile error: %s", err)
    27  	}
    28  	vv := c1.Get(nil, key)
    29  	if string(vv) != string(value) {
    30  		t.Fatalf("unexpected value obtained from cache; got %q; want %q", vv, value)
    31  	}
    32  
    33  	// Verify that key can be overwritten.
    34  	newValue := []byte("234fdfd")
    35  	c1.Set(key, newValue)
    36  	vv = c1.Get(nil, key)
    37  	if string(vv) != string(newValue) {
    38  		t.Fatalf("unexpected new value obtained from cache; got %q; want %q", vv, newValue)
    39  	}
    40  }
    41  
    42  func TestSaveLoadFile(t *testing.T) {
    43  	for _, concurrency := range []int{0, 1, 2, 4, 10} {
    44  		t.Run(fmt.Sprintf("concurrency_%d", concurrency), func(t *testing.T) {
    45  			testSaveLoadFile(t, concurrency)
    46  		})
    47  	}
    48  }
    49  
    50  func testSaveLoadFile(t *testing.T, concurrency int) {
    51  	var s Stats
    52  	filePath := fmt.Sprintf("TestSaveLoadFile.%d.fastcache", concurrency)
    53  	defer os.RemoveAll(filePath)
    54  
    55  	const itemsCount = 10000
    56  	const maxBytes = bucketsCount * chunkSize * 2
    57  	c := New(maxBytes)
    58  	for i := 0; i < itemsCount; i++ {
    59  		k := []byte(fmt.Sprintf("key %d", i))
    60  		v := []byte(fmt.Sprintf("value %d", i))
    61  		c.Set(k, v)
    62  		vv := c.Get(nil, k)
    63  		if string(v) != string(vv) {
    64  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
    65  		}
    66  	}
    67  	if concurrency == 1 {
    68  		if err := c.SaveToFile(filePath); err != nil {
    69  			t.Fatalf("SaveToFile error: %s", err)
    70  		}
    71  	} else {
    72  		if err := c.SaveToFileConcurrent(filePath, concurrency); err != nil {
    73  			t.Fatalf("SaveToFileConcurrent(%d) error: %s", concurrency, err)
    74  		}
    75  	}
    76  	s.Reset()
    77  	c.UpdateStats(&s)
    78  	if s.EntriesCount != itemsCount {
    79  		t.Fatalf("unexpected entriesCount; got %d; want %d", s.EntriesCount, itemsCount)
    80  	}
    81  	c.Reset()
    82  
    83  	// Verify LoadFromFile
    84  	c, err := LoadFromFile(filePath)
    85  	if err != nil {
    86  		t.Fatalf("unexpected error: %s", err)
    87  	}
    88  	s.Reset()
    89  	c.UpdateStats(&s)
    90  	if s.EntriesCount != itemsCount {
    91  		t.Fatalf("unexpected entriesCount; got %d; want %d", s.EntriesCount, itemsCount)
    92  	}
    93  	for i := 0; i < itemsCount; i++ {
    94  		k := []byte(fmt.Sprintf("key %d", i))
    95  		v := []byte(fmt.Sprintf("value %d", i))
    96  		vv := c.Get(nil, k)
    97  		if string(v) != string(vv) {
    98  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
    99  		}
   100  	}
   101  	c.Reset()
   102  
   103  	// Verify LoadFromFileOrNew
   104  	c = LoadFromFileOrNew(filePath, maxBytes)
   105  	s.Reset()
   106  	c.UpdateStats(&s)
   107  	if s.EntriesCount != itemsCount {
   108  		t.Fatalf("unexpected entriesCount; got %d; want %d", s.EntriesCount, itemsCount)
   109  	}
   110  	for i := 0; i < itemsCount; i++ {
   111  		k := []byte(fmt.Sprintf("key %d", i))
   112  		v := []byte(fmt.Sprintf("value %d", i))
   113  		vv := c.Get(nil, k)
   114  		if string(v) != string(vv) {
   115  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
   116  		}
   117  	}
   118  	c.Reset()
   119  
   120  	// Overwrite existing keys
   121  	for i := 0; i < itemsCount; i++ {
   122  		k := []byte(fmt.Sprintf("key %d", i))
   123  		v := []byte(fmt.Sprintf("value %d", i))
   124  		c.Set(k, v)
   125  		vv := c.Get(nil, k)
   126  		if string(v) != string(vv) {
   127  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
   128  		}
   129  	}
   130  
   131  	// Add new keys
   132  	for i := 0; i < itemsCount; i++ {
   133  		k := []byte(fmt.Sprintf("new key %d", i))
   134  		v := []byte(fmt.Sprintf("new value %d", i))
   135  		c.Set(k, v)
   136  		vv := c.Get(nil, k)
   137  		if string(v) != string(vv) {
   138  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
   139  		}
   140  	}
   141  
   142  	// Verify all the keys exist
   143  	for i := 0; i < itemsCount; i++ {
   144  		k := []byte(fmt.Sprintf("key %d", i))
   145  		v := []byte(fmt.Sprintf("value %d", i))
   146  		vv := c.Get(nil, k)
   147  		if string(v) != string(vv) {
   148  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
   149  		}
   150  		k = []byte(fmt.Sprintf("new key %d", i))
   151  		v = []byte(fmt.Sprintf("new value %d", i))
   152  		vv = c.Get(nil, k)
   153  		if string(v) != string(vv) {
   154  			t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0])
   155  		}
   156  	}
   157  
   158  	// Verify incorrect maxBytes passed to LoadFromFileOrNew
   159  	c = LoadFromFileOrNew(filePath, maxBytes*10)
   160  	s.Reset()
   161  	c.UpdateStats(&s)
   162  	if s.EntriesCount != 0 {
   163  		t.Fatalf("unexpected non-zero entriesCount; got %d", s.EntriesCount)
   164  	}
   165  	c.Reset()
   166  }
   167  
   168  func TestSaveLoadConcurrent(t *testing.T) {
   169  	c := New(1024)
   170  	defer c.Reset()
   171  	c.Set([]byte("foo"), []byte("bar"))
   172  
   173  	stopCh := make(chan struct{})
   174  
   175  	// Start concurrent workers that run Get and Set on c.
   176  	var wgWorkers sync.WaitGroup
   177  	for i := 0; i < 5; i++ {
   178  		wgWorkers.Add(1)
   179  		go func() {
   180  			defer wgWorkers.Done()
   181  			var buf []byte
   182  			j := 0
   183  			for {
   184  				k := []byte(fmt.Sprintf("key %d", j))
   185  				v := []byte(fmt.Sprintf("value %d", j))
   186  				c.Set(k, v)
   187  				buf = c.Get(buf[:0], k)
   188  				if string(buf) != string(v) {
   189  					panic(fmt.Errorf("unexpected value for key %q; got %q; want %q", k, buf, v))
   190  				}
   191  				j++
   192  				select {
   193  				case <-stopCh:
   194  					return
   195  				default:
   196  				}
   197  			}
   198  		}()
   199  	}
   200  
   201  	// Start concurrent SaveToFile and LoadFromFile calls.
   202  	var wgSavers sync.WaitGroup
   203  	for i := 0; i < 4; i++ {
   204  		wgSavers.Add(1)
   205  		filePath := fmt.Sprintf("TestSaveToFileConcurrent.%d.fastcache", i)
   206  		go func() {
   207  			defer wgSavers.Done()
   208  			defer os.RemoveAll(filePath)
   209  			for j := 0; j < 3; j++ {
   210  				if err := c.SaveToFileConcurrent(filePath, 3); err != nil {
   211  					panic(fmt.Errorf("cannot save cache to %q: %s", filePath, err))
   212  				}
   213  				cc, err := LoadFromFile(filePath)
   214  				if err != nil {
   215  					panic(fmt.Errorf("cannot load cache from %q: %s", filePath, err))
   216  				}
   217  				var s Stats
   218  				cc.UpdateStats(&s)
   219  				if s.EntriesCount == 0 {
   220  					panic(fmt.Errorf("unexpected empty cache loaded from %q", filePath))
   221  				}
   222  				cc.Reset()
   223  			}
   224  		}()
   225  	}
   226  
   227  	wgSavers.Wait()
   228  
   229  	close(stopCh)
   230  	wgWorkers.Wait()
   231  }