mirror of https://github.com/portainer/portainer
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.3 KiB
182 lines
4.3 KiB
3 years ago
|
package apikey
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
portainer "github.com/portainer/portainer/api"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
func Test_apiKeyCacheGet(t *testing.T) {
|
||
|
is := assert.New(t)
|
||
|
|
||
|
keyCache := NewAPIKeyCache(10)
|
||
|
|
||
|
// pre-populate cache
|
||
|
keyCache.cache.Add(string("foo"), entry{user: portainer.User{}, apiKey: portainer.APIKey{}})
|
||
|
keyCache.cache.Add(string(""), entry{user: portainer.User{}, apiKey: portainer.APIKey{}})
|
||
|
|
||
|
tests := []struct {
|
||
|
digest []byte
|
||
|
found bool
|
||
|
}{
|
||
|
{
|
||
|
digest: []byte("foo"),
|
||
|
found: true,
|
||
|
},
|
||
|
{
|
||
|
digest: []byte(""),
|
||
|
found: true,
|
||
|
},
|
||
|
{
|
||
|
digest: []byte("bar"),
|
||
|
found: false,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, test := range tests {
|
||
|
t.Run(string(test.digest), func(t *testing.T) {
|
||
|
_, _, found := keyCache.Get(test.digest)
|
||
|
is.Equal(test.found, found)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Test_apiKeyCacheSet(t *testing.T) {
|
||
|
is := assert.New(t)
|
||
|
|
||
|
keyCache := NewAPIKeyCache(10)
|
||
|
|
||
|
// pre-populate cache
|
||
|
keyCache.Set([]byte("bar"), portainer.User{ID: 2}, portainer.APIKey{})
|
||
|
keyCache.Set([]byte("foo"), portainer.User{ID: 1}, portainer.APIKey{})
|
||
|
|
||
|
// overwrite existing entry
|
||
|
keyCache.Set([]byte("foo"), portainer.User{ID: 3}, portainer.APIKey{})
|
||
|
|
||
|
val, ok := keyCache.cache.Get(string("bar"))
|
||
|
is.True(ok)
|
||
|
|
||
|
tuple := val.(entry)
|
||
|
is.Equal(portainer.User{ID: 2}, tuple.user)
|
||
|
|
||
|
val, ok = keyCache.cache.Get(string("foo"))
|
||
|
is.True(ok)
|
||
|
|
||
|
tuple = val.(entry)
|
||
|
is.Equal(portainer.User{ID: 3}, tuple.user)
|
||
|
}
|
||
|
|
||
|
func Test_apiKeyCacheDelete(t *testing.T) {
|
||
|
is := assert.New(t)
|
||
|
|
||
|
keyCache := NewAPIKeyCache(10)
|
||
|
|
||
|
t.Run("Delete an existing entry", func(t *testing.T) {
|
||
|
keyCache.cache.Add(string("foo"), entry{user: portainer.User{ID: 1}, apiKey: portainer.APIKey{}})
|
||
|
keyCache.Delete([]byte("foo"))
|
||
|
|
||
|
_, ok := keyCache.cache.Get(string("foo"))
|
||
|
is.False(ok)
|
||
|
})
|
||
|
|
||
|
t.Run("Delete a non-existing entry", func(t *testing.T) {
|
||
|
nonPanicFunc := func() { keyCache.Delete([]byte("non-existent-key")) }
|
||
|
is.NotPanics(nonPanicFunc)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func Test_apiKeyCacheLRU(t *testing.T) {
|
||
|
is := assert.New(t)
|
||
|
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
cacheLen int
|
||
|
key []string
|
||
|
foundKeys []string
|
||
|
evictedKeys []string
|
||
|
}{
|
||
|
{
|
||
|
name: "Cache length is 1, add 2 keys",
|
||
|
cacheLen: 1,
|
||
|
key: []string{"foo", "bar"},
|
||
|
foundKeys: []string{"bar"},
|
||
|
evictedKeys: []string{"foo"},
|
||
|
},
|
||
|
{
|
||
|
name: "Cache length is 1, add 3 keys",
|
||
|
cacheLen: 1,
|
||
|
key: []string{"foo", "bar", "baz"},
|
||
|
foundKeys: []string{"baz"},
|
||
|
evictedKeys: []string{"foo", "bar"},
|
||
|
},
|
||
|
{
|
||
|
name: "Cache length is 2, add 3 keys",
|
||
|
cacheLen: 2,
|
||
|
key: []string{"foo", "bar", "baz"},
|
||
|
foundKeys: []string{"bar", "baz"},
|
||
|
evictedKeys: []string{"foo"},
|
||
|
},
|
||
|
{
|
||
|
name: "Cache length is 2, add 4 keys",
|
||
|
cacheLen: 2,
|
||
|
key: []string{"foo", "bar", "baz", "qux"},
|
||
|
foundKeys: []string{"baz", "qux"},
|
||
|
evictedKeys: []string{"foo", "bar"},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, test := range tests {
|
||
|
t.Run(test.name, func(t *testing.T) {
|
||
|
keyCache := NewAPIKeyCache(test.cacheLen)
|
||
|
|
||
|
for _, key := range test.key {
|
||
|
keyCache.Set([]byte(key), portainer.User{ID: 1}, portainer.APIKey{})
|
||
|
}
|
||
|
|
||
|
for _, key := range test.foundKeys {
|
||
|
_, _, found := keyCache.Get([]byte(key))
|
||
|
is.True(found, "Key %s not found", key)
|
||
|
}
|
||
|
|
||
|
for _, key := range test.evictedKeys {
|
||
|
_, _, found := keyCache.Get([]byte(key))
|
||
|
is.False(found, "key %s should have been evicted", key)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Test_apiKeyCacheInvalidateUserKeyCache(t *testing.T) {
|
||
|
is := assert.New(t)
|
||
|
|
||
|
keyCache := NewAPIKeyCache(10)
|
||
|
|
||
|
t.Run("Removes users keys from cache", func(t *testing.T) {
|
||
|
keyCache.cache.Add(string("foo"), entry{user: portainer.User{ID: 1}, apiKey: portainer.APIKey{}})
|
||
|
|
||
|
ok := keyCache.InvalidateUserKeyCache(1)
|
||
|
is.True(ok)
|
||
|
|
||
|
_, ok = keyCache.cache.Get(string("foo"))
|
||
|
is.False(ok)
|
||
|
})
|
||
|
|
||
|
t.Run("Does not affect other keys", func(t *testing.T) {
|
||
|
keyCache.cache.Add(string("foo"), entry{user: portainer.User{ID: 1}, apiKey: portainer.APIKey{}})
|
||
|
keyCache.cache.Add(string("bar"), entry{user: portainer.User{ID: 2}, apiKey: portainer.APIKey{}})
|
||
|
|
||
|
ok := keyCache.InvalidateUserKeyCache(1)
|
||
|
is.True(ok)
|
||
|
|
||
|
ok = keyCache.InvalidateUserKeyCache(1)
|
||
|
is.False(ok)
|
||
|
|
||
|
_, ok = keyCache.cache.Get(string("foo"))
|
||
|
is.False(ok)
|
||
|
|
||
|
_, ok = keyCache.cache.Get(string("bar"))
|
||
|
is.True(ok)
|
||
|
})
|
||
|
}
|