1// Copyright (C) 2019 Storj Labs, Inc. 2// See LICENSE for copying information. 3 4package trust_test 5 6import ( 7 "context" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 "github.com/zeebo/errs" 16 17 "storj.io/common/testcontext" 18 "storj.io/storj/storagenode/trust" 19) 20 21func TestCacheLoadCreatesDirectory(t *testing.T) { 22 ctx := testcontext.New(t) 23 defer ctx.Cleanup() 24 25 cachePath := filepath.Join(ctx.Dir(), "sub", "cache.json") 26 27 _, err := trust.LoadCache(cachePath) 28 require.NoError(t, err) 29 30 fi, err := os.Stat(filepath.Dir(cachePath)) 31 require.NoError(t, err, "cache directory should exist") 32 require.True(t, fi.IsDir()) 33 34 _, err = os.Stat(cachePath) 35 require.True(t, os.IsNotExist(err), "cache file should not exist") 36} 37 38func TestCacheLoadFailure(t *testing.T) { 39 ctx := testcontext.New(t) 40 defer ctx.Cleanup() 41 42 cachePath := ctx.File("cache.json") 43 44 // Use the directory itself as the path 45 _, err := trust.LoadCache(ctx.Dir()) 46 assert.Error(t, err) 47 48 // Load malformed JSON 49 require.NoError(t, ioutil.WriteFile(cachePath, []byte("BAD"), 0644)) 50 _, err = trust.LoadCache(cachePath) 51 assert.EqualError(t, err, "trust: malformed cache: invalid character 'B' looking for beginning of value") 52} 53 54func TestCachePersistence(t *testing.T) { 55 url1, err := trust.ParseSatelliteURL("121RTSDpyNZVcEU84Ticf2L1ntiuUimbWgfATz21tuvgk3vzoA6@foo.test:7777") 56 require.NoError(t, err) 57 58 url2, err := trust.ParseSatelliteURL("12L9ZFwhzVpuEKMUNUqkaTLGzwY9G24tbiigLiXpmZWKwmcNDDs@b.bar.test:7777") 59 require.NoError(t, err) 60 61 entry1 := trust.Entry{ 62 SatelliteURL: url1, 63 Authoritative: false, 64 } 65 66 entry2 := trust.Entry{ 67 SatelliteURL: url2, 68 Authoritative: true, 69 } 70 71 for _, tt := range []struct { 72 name string 73 entriesBefore map[string][]trust.Entry 74 lookup []trust.Entry 75 set []trust.Entry 76 save bool 77 entriesAfter map[string][]trust.Entry 78 }{ 79 { 80 name: "new cache without save", 81 }, 82 { 83 name: "new cache with save", 84 save: true, 85 entriesAfter: map[string][]trust.Entry{}, 86 }, 87 { 88 name: "set without save", 89 set: []trust.Entry{entry1, entry2}, 90 save: false, 91 }, 92 { 93 name: "set and save", 94 set: []trust.Entry{entry1, entry2}, 95 save: true, 96 entriesAfter: map[string][]trust.Entry{ 97 "key": {entry1, entry2}, 98 }, 99 }, 100 { 101 name: "replace without saving", 102 entriesBefore: map[string][]trust.Entry{ 103 "key": {entry1}, 104 }, 105 lookup: []trust.Entry{entry1}, 106 set: []trust.Entry{entry1, entry2}, 107 save: false, 108 entriesAfter: map[string][]trust.Entry{ 109 "key": {entry1}, 110 }, 111 }, 112 { 113 name: "replace and save", 114 entriesBefore: map[string][]trust.Entry{ 115 "key": {entry1}, 116 }, 117 lookup: []trust.Entry{entry1}, 118 set: []trust.Entry{entry1, entry2}, 119 save: true, 120 entriesAfter: map[string][]trust.Entry{ 121 "key": {entry1, entry2}, 122 }, 123 }, 124 } { 125 tt := tt // quiet linting 126 t.Run(tt.name, func(t *testing.T) { 127 ctx := testcontext.New(t) 128 defer ctx.Cleanup() 129 130 cachePath := ctx.File("cache.json") 131 132 if tt.entriesBefore != nil { 133 require.NoError(t, trust.SaveCacheData(cachePath, &trust.CacheData{Entries: tt.entriesBefore})) 134 } 135 136 cache, err := trust.LoadCache(cachePath) 137 require.NoError(t, err) 138 139 entries, ok := cache.Lookup("key") 140 if tt.lookup == nil { 141 require.False(t, ok, "lookup should fail") 142 require.Nil(t, entries, "failed lookup should produce nil entries slice") 143 } else { 144 require.True(t, ok, "lookup should succeed") 145 require.Equal(t, tt.lookup, entries) 146 } 147 148 if tt.set != nil { 149 cache.Set("key", tt.set) 150 } 151 152 if tt.save { 153 require.NoError(t, cache.Save(context.Background())) 154 } 155 156 cacheAfter, err := trust.LoadCacheData(cachePath) 157 if tt.entriesAfter == nil { 158 require.Error(t, err) 159 if !assert.True(t, os.IsNotExist(errs.Unwrap(err)), "cache file should not exist") { 160 require.FailNow(t, "Expected cache file to not exist", "err=%w", err) 161 } 162 } else { 163 require.NoError(t, err) 164 require.Equal(t, &trust.CacheData{Entries: tt.entriesAfter}, cacheAfter) 165 } 166 }) 167 } 168 169} 170