open-vault/command/agentproxyshared/cache/cachememdb/cache_memdb_test.go

396 lines
7.0 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cachememdb
import (
"context"
"testing"
"github.com/go-test/deep"
)
func testContextInfo() *ContextInfo {
ctx, cancelFunc := context.WithCancel(context.Background())
return &ContextInfo{
Ctx: ctx,
CancelFunc: cancelFunc,
}
}
func TestNew(t *testing.T) {
_, err := New()
if err != nil {
t.Fatal(err)
}
}
func TestCacheMemDB_Get(t *testing.T) {
cache, err := New()
if err != nil {
t.Fatal(err)
}
// Test invalid index name
_, err = cache.Get("foo", "bar")
if err == nil {
t.Fatal("expected error")
}
// Test on empty cache
index, err := cache.Get(IndexNameID, "foo")
if err != nil {
t.Fatal(err)
}
if index != nil {
t.Fatalf("expected nil index, got: %v", index)
}
// Populate cache
in := &Index{
ID: "test_id",
Namespace: "test_ns/",
RequestPath: "/v1/request/path",
Token: "test_token",
TokenAccessor: "test_accessor",
Lease: "test_lease",
Response: []byte("hello world"),
}
if err := cache.Set(in); err != nil {
t.Fatal(err)
}
testCases := []struct {
name string
indexName string
indexValues []interface{}
}{
{
"by_index_id",
"id",
[]interface{}{in.ID},
},
{
"by_request_path",
"request_path",
[]interface{}{in.Namespace, in.RequestPath},
},
{
"by_lease",
"lease",
[]interface{}{in.Lease},
},
{
"by_token",
"token",
[]interface{}{in.Token},
},
{
"by_token_accessor",
"token_accessor",
[]interface{}{in.TokenAccessor},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
out, err := cache.Get(tc.indexName, tc.indexValues...)
if err != nil {
t.Fatal(err)
}
if diff := deep.Equal(in, out); diff != nil {
t.Fatal(diff)
}
})
}
}
func TestCacheMemDB_GetByPrefix(t *testing.T) {
cache, err := New()
if err != nil {
t.Fatal(err)
}
// Test invalid index name
_, err = cache.GetByPrefix("foo", "bar", "baz")
if err == nil {
t.Fatal("expected error")
}
// Test on empty cache
index, err := cache.GetByPrefix(IndexNameRequestPath, "foo", "bar")
if err != nil {
t.Fatal(err)
}
if index != nil {
t.Fatalf("expected nil index, got: %v", index)
}
// Populate cache
in := &Index{
ID: "test_id",
Namespace: "test_ns/",
RequestPath: "/v1/request/path/1",
Token: "test_token",
TokenParent: "test_token_parent",
TokenAccessor: "test_accessor",
Lease: "path/to/test_lease/1",
LeaseToken: "test_lease_token",
Response: []byte("hello world"),
}
if err := cache.Set(in); err != nil {
t.Fatal(err)
}
// Populate cache
in2 := &Index{
ID: "test_id_2",
Namespace: "test_ns/",
RequestPath: "/v1/request/path/2",
Token: "test_token2",
TokenParent: "test_token_parent",
TokenAccessor: "test_accessor2",
Lease: "path/to/test_lease/2",
LeaseToken: "test_lease_token",
Response: []byte("hello world"),
}
if err := cache.Set(in2); err != nil {
t.Fatal(err)
}
testCases := []struct {
name string
indexName string
indexValues []interface{}
}{
{
"by_request_path",
"request_path",
[]interface{}{"test_ns/", "/v1/request/path"},
},
{
"by_lease",
"lease",
[]interface{}{"path/to/test_lease"},
},
{
"by_token_parent",
"token_parent",
[]interface{}{"test_token_parent"},
},
{
"by_lease_token",
"lease_token",
[]interface{}{"test_lease_token"},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
out, err := cache.GetByPrefix(tc.indexName, tc.indexValues...)
if err != nil {
t.Fatal(err)
}
if diff := deep.Equal([]*Index{in, in2}, out); diff != nil {
t.Fatal(diff)
}
})
}
}
func TestCacheMemDB_Set(t *testing.T) {
cache, err := New()
if err != nil {
t.Fatal(err)
}
testCases := []struct {
name string
index *Index
wantErr bool
}{
{
"nil",
nil,
true,
},
{
"empty_fields",
&Index{},
true,
},
{
"missing_required_fields",
&Index{
Lease: "foo",
},
true,
},
{
"all_fields",
&Index{
ID: "test_id",
Namespace: "test_ns/",
RequestPath: "/v1/request/path",
Token: "test_token",
TokenAccessor: "test_accessor",
Lease: "test_lease",
RenewCtxInfo: testContextInfo(),
},
false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if err := cache.Set(tc.index); (err != nil) != tc.wantErr {
t.Fatalf("CacheMemDB.Set() error = %v, wantErr = %v", err, tc.wantErr)
}
})
}
}
func TestCacheMemDB_Evict(t *testing.T) {
cache, err := New()
if err != nil {
t.Fatal(err)
}
// Test on empty cache
if err := cache.Evict(IndexNameID, "foo"); err != nil {
t.Fatal(err)
}
testIndex := &Index{
ID: "test_id",
Namespace: "test_ns/",
RequestPath: "/v1/request/path",
Token: "test_token",
TokenAccessor: "test_token_accessor",
Lease: "test_lease",
RenewCtxInfo: testContextInfo(),
}
testCases := []struct {
name string
indexName string
indexValues []interface{}
insertIndex *Index
wantErr bool
}{
{
"empty_params",
"",
[]interface{}{""},
nil,
true,
},
{
"invalid_params",
"foo",
[]interface{}{"bar"},
nil,
true,
},
{
"by_id",
"id",
[]interface{}{"test_id"},
testIndex,
false,
},
{
"by_request_path",
"request_path",
[]interface{}{"test_ns/", "/v1/request/path"},
testIndex,
false,
},
{
"by_token",
"token",
[]interface{}{"test_token"},
testIndex,
false,
},
{
"by_token_accessor",
"token_accessor",
[]interface{}{"test_accessor"},
testIndex,
false,
},
{
"by_lease",
"lease",
[]interface{}{"test_lease"},
testIndex,
false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.insertIndex != nil {
if err := cache.Set(tc.insertIndex); err != nil {
t.Fatal(err)
}
}
if err := cache.Evict(tc.indexName, tc.indexValues...); (err != nil) != tc.wantErr {
t.Fatal(err)
}
// Verify that the cache doesn't contain the entry any more
index, err := cache.Get(tc.indexName, tc.indexValues...)
if (err != nil) != tc.wantErr {
t.Fatal(err)
}
if index != nil {
t.Fatalf("expected nil entry, got = %#v", index)
}
})
}
}
func TestCacheMemDB_Flush(t *testing.T) {
cache, err := New()
if err != nil {
t.Fatal(err)
}
// Populate cache
in := &Index{
ID: "test_id",
Token: "test_token",
Lease: "test_lease",
Namespace: "test_ns/",
RequestPath: "/v1/request/path",
Response: []byte("hello world"),
}
if err := cache.Set(in); err != nil {
t.Fatal(err)
}
// Reset the cache
if err := cache.Flush(); err != nil {
t.Fatal(err)
}
// Check the cache doesn't contain inserted index
out, err := cache.Get(IndexNameID, "test_id")
if err != nil {
t.Fatal(err)
}
if out != nil {
t.Fatalf("expected cache to be empty, got = %v", out)
}
}