396 lines
7.0 KiB
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)
|
|
}
|
|
}
|