github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/stats/cache_test.go (about)

     1  package stats
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io/ioutil"
     7  	"os"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	"github.com/qri-io/dataset"
    13  )
    14  
    15  func TestLocalCache(t *testing.T) {
    16  	tmp, err := ioutil.TempDir("", "test_os_cache")
    17  	if err != nil {
    18  		t.Fatal(err)
    19  	}
    20  	defer os.RemoveAll(tmp)
    21  
    22  	ctx := context.Background()
    23  	// create a cache with a  100 byte max size
    24  	cache, err := NewLocalCache(tmp, 100)
    25  	if err != nil {
    26  		t.Fatal(err)
    27  	}
    28  
    29  	// put data at path "statsA"
    30  	statsA := &dataset.Stats{
    31  		Qri: dataset.KindStats.String(),
    32  		Stats: []interface{}{
    33  			map[string]interface{}{"type": "numeric"},
    34  			map[string]interface{}{"type": "blah"},
    35  		},
    36  	}
    37  	if err = cache.PutStats(ctx, "/mem/statsA", statsA); err != nil {
    38  		t.Errorf("expected putting json data to not fail. got: %s", err)
    39  	}
    40  
    41  	gotStatsA, err := cache.GetStats(ctx, "/mem/statsA")
    42  	if err != nil {
    43  		t.Errorf("unexpected error getting stats: %q", err)
    44  	}
    45  	if diff := cmp.Diff(statsA, gotStatsA); diff != "" {
    46  		t.Errorf("response mismatch (-want +got):\n%s", diff)
    47  	}
    48  
    49  	// overwrite data at path "statsA"
    50  	statsA = &dataset.Stats{
    51  		Qri: dataset.KindStats.String(),
    52  		Stats: []interface{}{
    53  			map[string]interface{}{"type": "numeric"},
    54  			map[string]interface{}{"type": "blah"},
    55  			map[string]interface{}{"type": "blah"},
    56  			map[string]interface{}{"type": "blah"},
    57  		},
    58  	}
    59  	if err = cache.PutStats(ctx, "/mem/statsA", statsA); err != nil {
    60  		t.Errorf("expected putting json data to not fail. got: %s", err)
    61  	}
    62  
    63  	gotStatsA, err = cache.GetStats(ctx, "/mem/statsA")
    64  	if err != nil {
    65  		t.Errorf("unexpected error getting stats: %q", err)
    66  	}
    67  	if diff := cmp.Diff(statsA, gotStatsA); diff != "" {
    68  		t.Errorf("response mismatch (-want +got):\n%s", diff)
    69  	}
    70  
    71  	// add data that'll overflow the cache max size
    72  	statsB := &dataset.Stats{
    73  		Qri: dataset.KindStats.String(),
    74  		Stats: []interface{}{
    75  			// big value to overflow cache
    76  			strings.Repeat("o", 70),
    77  		},
    78  	}
    79  
    80  	if err = cache.PutStats(ctx, "/mem/statsB", statsB); err != nil {
    81  		t.Errorf("expected putting long stats to not fail. got: %s", err)
    82  	}
    83  
    84  	// expect statsA to now ErrCacheMiss b/c it's been garbage-collected when
    85  	// statsB exceeded the max size
    86  	if _, err := cache.GetStats(ctx, "/mem/statsA"); err == nil {
    87  		t.Errorf("expected error getting stats after max-size exceeded. got nil")
    88  	}
    89  
    90  	f, err := ioutil.TempFile("", "stats_cache_test_local_file")
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	path := f.Name()
    95  	defer os.Remove(path)
    96  
    97  	fileStats := &dataset.Stats{
    98  		Stats: []interface{}{
    99  			map[string]interface{}{
   100  				"hello": "world",
   101  			},
   102  		},
   103  	}
   104  
   105  	if err = cache.PutStats(ctx, path, fileStats); err != nil {
   106  		t.Errorf("putting local file stats: %q", err)
   107  	}
   108  
   109  	if _, err := cache.GetStats(ctx, path); err != nil {
   110  		t.Errorf("expected local cached stats to exist. got error: %q", err)
   111  	}
   112  
   113  	if err := os.Chmod(path, 0621); err != nil {
   114  		t.Fatal(err)
   115  	}
   116  
   117  	_, err = cache.GetStats(ctx, path)
   118  	if !errors.Is(err, ErrCacheMiss) {
   119  		t.Errorf("expected local cached stats to return ErrCacheMiss after local path file permissions change. got error: %q", err)
   120  	}
   121  }