diff --git a/go.mod b/go.mod index e474300c..47d78dfb 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/apache/cassandra-gocql-driver/v2 v2.0.0 github.com/datastax/go-cassandra-native-protocol v0.0.0-20260130100129-9d5b43677a33 github.com/google/uuid v1.1.1 + github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/jpillora/backoff v1.0.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/mcuadros/go-defaults v1.2.0 diff --git a/go.sum b/go.sum index fcd1572b..88d35ec8 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= diff --git a/integration-tests/setup/testcluster.go b/integration-tests/setup/testcluster.go index b7336ecd..48151268 100644 --- a/integration-tests/setup/testcluster.go +++ b/integration-tests/setup/testcluster.go @@ -448,6 +448,7 @@ func NewTestConfig(originHost string, targetHost string) *config.Config { conf.ProxyMaxClientConnections = 1000 conf.ProxyMaxStreamIds = 2048 + conf.ProxyMaxPreparedStatementCacheSize = 10000 conf.RequestResponseMaxWorkers = -1 conf.WriteMaxWorkers = -1 diff --git a/proxy/pkg/config/config.go b/proxy/pkg/config/config.go index fe3cebdb..730aa1e0 100644 --- a/proxy/pkg/config/config.go +++ b/proxy/pkg/config/config.go @@ -74,11 +74,12 @@ type Config struct { // Proxy bucket - ProxyListenAddress string `default:"localhost" split_words:"true" yaml:"proxy_listen_address"` - ProxyListenPort int `default:"14002" split_words:"true" yaml:"proxy_listen_port"` - ProxyRequestTimeoutMs int `default:"10000" split_words:"true" yaml:"proxy_request_timeout_ms"` - ProxyMaxClientConnections int `default:"1000" split_words:"true" yaml:"proxy_max_client_connections"` - ProxyMaxStreamIds int `default:"2048" split_words:"true" yaml:"proxy_max_stream_ids"` + ProxyListenAddress string `default:"localhost" split_words:"true" yaml:"proxy_listen_address"` + ProxyListenPort int `default:"14002" split_words:"true" yaml:"proxy_listen_port"` + ProxyRequestTimeoutMs int `default:"10000" split_words:"true" yaml:"proxy_request_timeout_ms"` + ProxyMaxClientConnections int `default:"1000" split_words:"true" yaml:"proxy_max_client_connections"` + ProxyMaxStreamIds int `default:"2048" split_words:"true" yaml:"proxy_max_stream_ids"` + ProxyMaxPreparedStatementCacheSize int `default:"10000" split_words:"true" yaml:"proxy_max_prepared_statement_cache_size"` ProxyTlsCaPath string `split_words:"true" yaml:"proxy_tls_ca_path"` ProxyTlsCertPath string `split_words:"true" yaml:"proxy_tls_cert_path"` diff --git a/proxy/pkg/zdmproxy/cqlparser_test.go b/proxy/pkg/zdmproxy/cqlparser_test.go index 1637e7d7..fb00b754 100644 --- a/proxy/pkg/zdmproxy/cqlparser_test.go +++ b/proxy/pkg/zdmproxy/cqlparser_test.go @@ -57,14 +57,14 @@ func TestInspectFrame(t *testing.T) { targetPreparedId: []byte("LOCAL"), prepareRequestInfo: NewPrepareRequestInfo(NewInterceptedRequestInfo(local, newStarSelectClause()), nil, false, "SELECT * FROM system.local", ""), } - psCache := NewPreparedStatementCache() - psCache.cache["BOTH"] = bothCacheEntry - psCache.cache["ORIGIN"] = originCacheEntry - psCache.cache["TARGET"] = targetCacheEntry - psCache.interceptedCache["PEERS"] = peersCacheEntry - psCache.interceptedCache["PEERS_KS"] = peersKsCacheEntry - psCache.interceptedCache["LOCAL"] = localCacheEntry - psCache.interceptedCache["LOCAL_KS"] = localKsCacheEntry + psCache := createPSCacheForTests(t) + psCache.cache.Add("BOTH", bothCacheEntry) + psCache.cache.Add("ORIGIN", originCacheEntry) + psCache.cache.Add("TARGET", targetCacheEntry) + psCache.interceptedCache.Add("PEERS", peersCacheEntry) + psCache.interceptedCache.Add("PEERS_KS", peersKsCacheEntry) + psCache.interceptedCache.Add("LOCAL", localCacheEntry) + psCache.interceptedCache.Add("LOCAL_KS", localKsCacheEntry) mh := newFakeMetricHandler() km := "" primaryClusterTarget := common.ClusterTypeTarget diff --git a/proxy/pkg/zdmproxy/cqlparser_adv_workloads_utils_test.go b/proxy/pkg/zdmproxy/cqlparser_utils_test.go similarity index 93% rename from proxy/pkg/zdmproxy/cqlparser_adv_workloads_utils_test.go rename to proxy/pkg/zdmproxy/cqlparser_utils_test.go index 5de43327..9c38dd99 100644 --- a/proxy/pkg/zdmproxy/cqlparser_adv_workloads_utils_test.go +++ b/proxy/pkg/zdmproxy/cqlparser_utils_test.go @@ -27,7 +27,7 @@ func getGeneralParamsForTests(t *testing.T) params { require.Nil(t, err) return params{ - psCache: NewPreparedStatementCache(), + psCache: createPSCacheForTests(t), mh: newFakeMetricHandler(), kn: "", primaryCluster: common.ClusterTypeOrigin, @@ -38,6 +38,12 @@ func getGeneralParamsForTests(t *testing.T) params { } } +func createPSCacheForTests(t *testing.T) *PreparedStatementCache { + psCache, err := NewPreparedStatementCache(1000) + require.Nil(t, err) + return psCache +} + func buildQueryMessageForTests(queryString string) *message.Query { var defaultTimestamp int64 = 1647023221311969 var serialConsistency = primitive.ConsistencyLevelLocalSerial diff --git a/proxy/pkg/zdmproxy/proxy.go b/proxy/pkg/zdmproxy/proxy.go index ffd4f1c2..39edbb1d 100644 --- a/proxy/pkg/zdmproxy/proxy.go +++ b/proxy/pkg/zdmproxy/proxy.go @@ -391,7 +391,10 @@ func (p *ZdmProxy) initializeGlobalStructures() error { p.globalClientHandlersWg = &sync.WaitGroup{} p.clientHandlersShutdownRequestCtx, p.clientHandlersShutdownRequestCancelFn = context.WithCancel(context.Background()) - p.PreparedStatementCache = NewPreparedStatementCache() + p.PreparedStatementCache, err = NewPreparedStatementCache(p.Conf.ProxyMaxPreparedStatementCacheSize) + if err != nil { + return err + } p.controlConnShutdownCtx, p.controlConnCancelFn = context.WithCancel(context.Background()) p.controlConnShutdownWg = &sync.WaitGroup{} diff --git a/proxy/pkg/zdmproxy/pscache.go b/proxy/pkg/zdmproxy/pscache.go index b3233431..810c5cd8 100644 --- a/proxy/pkg/zdmproxy/pscache.go +++ b/proxy/pkg/zdmproxy/pscache.go @@ -3,34 +3,57 @@ package zdmproxy import ( "encoding/hex" "fmt" + "sync" + "github.com/datastax/go-cassandra-native-protocol/message" + "github.com/hashicorp/golang-lru/v2/simplelru" log "github.com/sirupsen/logrus" - "sync" ) type PreparedStatementCache struct { - cache map[string]PreparedData // Map containing the prepared queries (raw bytes) keyed on prepareId - index map[string]string // Map that can be used as an index to look up origin prepareIds by target prepareId + cache *simplelru.LRU[string, PreparedData] // Map containing the prepared queries (raw bytes) keyed on prepareId + index map[string]string // Map that can be used as an index to look up origin prepareIds by target prepareId - interceptedCache map[string]PreparedData // Map containing the prepared queries for intercepted requests + interceptedCache *simplelru.LRU[string, PreparedData] // Map containing the prepared queries for intercepted requests lock *sync.RWMutex } -func NewPreparedStatementCache() *PreparedStatementCache { +func NewPreparedStatementCache(maxSize int) (*PreparedStatementCache, error) { + indexMap := make(map[string]string) + + cache, err := simplelru.NewLRU[string, PreparedData](maxSize, func(key string, value PreparedData) { + // this is called by LRU.Add() so we already have a lock here + delete(indexMap, string(value.GetTargetPreparedId())) + }) + if err != nil { + return nil, fmt.Errorf("error initializing the PreparedStatementCache cache map: %v", err) + } + + interceptedCache, err := simplelru.NewLRU[string, PreparedData](maxSize, nil) + if err != nil { + return nil, fmt.Errorf("error initializing the PreparedStatementCache interceptedCache map: %v", err) + } + return &PreparedStatementCache{ - cache: make(map[string]PreparedData), - index: make(map[string]string), - interceptedCache: make(map[string]PreparedData), + cache: cache, + index: indexMap, + interceptedCache: interceptedCache, lock: &sync.RWMutex{}, - } + }, nil } func (psc PreparedStatementCache) GetPreparedStatementCacheSize() float64 { psc.lock.RLock() defer psc.lock.RUnlock() - return float64(len(psc.cache) + len(psc.interceptedCache)) + cacheLen := psc.cache.Len() + interceptedCacheLen := psc.interceptedCache.Len() + + log.Debugf("PS Cache Size: %v, PS Intercepted Size: %v, PS Index Size: %v.", + cacheLen, interceptedCacheLen, len(psc.index)) + + return float64(cacheLen + interceptedCacheLen) } func (psc *PreparedStatementCache) Store( @@ -42,7 +65,7 @@ func (psc *PreparedStatementCache) Store( psc.lock.Lock() defer psc.lock.Unlock() - psc.cache[originPrepareIdStr] = NewPreparedData(originPreparedResult, targetPreparedResult, prepareRequestInfo) + psc.cache.Add(originPrepareIdStr, NewPreparedData(originPreparedResult, targetPreparedResult, prepareRequestInfo)) psc.index[targetPrepareIdStr] = originPrepareIdStr log.Debugf("Storing PS cache entry: {OriginPreparedId=%v, TargetPreparedId: %v, RequestInfo: %v}", @@ -55,25 +78,31 @@ func (psc *PreparedStatementCache) StoreIntercepted(preparedResult *message.Prep defer psc.lock.Unlock() preparedData := NewPreparedData(preparedResult, preparedResult, prepareRequestInfo) - psc.interceptedCache[prepareIdStr] = preparedData + psc.interceptedCache.Add(prepareIdStr, preparedData) log.Debugf("Storing intercepted PS cache entry: {PreparedId=%v, RequestInfo: %v}", hex.EncodeToString(preparedResult.PreparedQueryId), prepareRequestInfo) } func (psc *PreparedStatementCache) Get(originPreparedId []byte) (PreparedData, bool) { - psc.lock.RLock() - defer psc.lock.RUnlock() - data, ok := psc.cache[string(originPreparedId)] - if !ok { - data, ok = psc.interceptedCache[string(originPreparedId)] + psc.lock.Lock() + defer psc.lock.Unlock() + data, ok := psc.cache.Get(string(originPreparedId)) + if ok { + return data, true + } + + data, ok = psc.interceptedCache.Get(string(originPreparedId)) + if ok { + return data, true } - return data, ok + + return nil, false } func (psc *PreparedStatementCache) GetByTargetPreparedId(targetPreparedId []byte) (PreparedData, bool) { - psc.lock.RLock() - defer psc.lock.RUnlock() + psc.lock.Lock() + defer psc.lock.Unlock() originPreparedId, ok := psc.index[string(targetPreparedId)] if !ok { @@ -81,7 +110,7 @@ func (psc *PreparedStatementCache) GetByTargetPreparedId(targetPreparedId []byte return nil, false } - data, ok := psc.cache[originPreparedId] + data, ok := psc.cache.Get(originPreparedId) if !ok { log.Errorf("Could not get prepared data by target id even though there is an entry on the index map. "+ "This is most likely a bug. OriginPreparedId = %v, TargetPreparedId = %v", originPreparedId, targetPreparedId) diff --git a/proxy/pkg/zdmproxy/pscache_test.go b/proxy/pkg/zdmproxy/pscache_test.go new file mode 100644 index 00000000..e6d6db8a --- /dev/null +++ b/proxy/pkg/zdmproxy/pscache_test.go @@ -0,0 +1,274 @@ +package zdmproxy + +import ( + "fmt" + "testing" + + "github.com/datastax/go-cassandra-native-protocol/message" + "github.com/stretchr/testify/require" +) + +const MaxPSCacheSizeForTests = 10 +const OriginIdPrefix = "originId_" +const TargetIdPrefix = "targetId_" +const InterceptedIdPrefix = "interceptedId_" + +type CacheMapType string + +const ( + CacheMapTypeOrigin = CacheMapType("CACHE-ORIGIN") + CacheMapTypeTarget = CacheMapType("INDEX-TARGET") + CacheMapTypeIntercepted = CacheMapType("INTERCEPTED") + CacheMapTypeNone = CacheMapType("NONE") +) + +/* +* +This test has the sole purpose to verify that all three cache maps ("cache", "index" and "intercepted") honour the configured size limit and behave in an LRU fashion +It does not represent a realistic usage of the PS Cache: elements are added to all three cache maps, which would not normally happen, and the data inserted in it is intentionally dummy +*/ +func TestPreparedStatementCache_StoreIntoAllCacheMaps(t *testing.T) { + + tests := []struct { + name string + numElementsToAdd int + elementSuffixesToAccess []int + expectedCacheMapSize int + expectedElementSuffixesInCache []int + }{ + { + name: "insert less elements than capacity, nothing accessed, nothing evicted", + numElementsToAdd: 9, + elementSuffixesToAccess: []int{}, + expectedCacheMapSize: 9, + expectedElementSuffixesInCache: []int{0, 1, 2, 3, 4, 5, 6, 7, 8}, + }, + { + name: "insert as many elements as capacity, nothing accessed, nothing evicted", + numElementsToAdd: 10, + elementSuffixesToAccess: []int{}, + expectedCacheMapSize: 10, + expectedElementSuffixesInCache: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + { + name: "insert more elements than capacity, nothing accessed, overflowing oldest ones should be evicted", + numElementsToAdd: 13, + elementSuffixesToAccess: []int{}, + expectedCacheMapSize: MaxPSCacheSizeForTests, + expectedElementSuffixesInCache: []int{3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + }, + { + name: "insert more elements than capacity, only recent ones accessed, overflowing oldest ones should be evicted", + numElementsToAdd: 13, + elementSuffixesToAccess: []int{5, 7, 9}, + expectedCacheMapSize: MaxPSCacheSizeForTests, + expectedElementSuffixesInCache: []int{3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + }, + { + name: "insert more elements than capacity, overflowing oldest ones accessed, non-accessed oldest ones should be evicted", + numElementsToAdd: 13, + elementSuffixesToAccess: []int{0, 2}, + expectedCacheMapSize: MaxPSCacheSizeForTests, + expectedElementSuffixesInCache: []int{0, 2, 5, 6, 7, 8, 9, 10, 11, 12}, + }, + { + name: "insert more elements than capacity, overflowing oldest and recent ones accessed, non-accessed oldest ones should be evicted", + numElementsToAdd: 13, + elementSuffixesToAccess: []int{0, 2, 3, 8}, + expectedCacheMapSize: MaxPSCacheSizeForTests, + expectedElementSuffixesInCache: []int{0, 2, 3, 6, 7, 8, 9, 10, 11, 12}, + }, + } + + dummyPrepareRequestInfo := NewPrepareRequestInfo(NewGenericRequestInfo(forwardToBoth, false, false), []*term{}, false, "", "") + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + psCache, err := NewPreparedStatementCache(MaxPSCacheSizeForTests) + require.Nil(tt, err, "Error creating the PSCache", err) + + if test.numElementsToAdd < MaxPSCacheSizeForTests { + // no overflow or evictions, just insert all elements + for i := 0; i < test.numElementsToAdd; i++ { + originPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(OriginIdPrefix, i)), + } + targetPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(TargetIdPrefix, i)), + } + psCache.Store(originPreparedResult, targetPreparedResult, dummyPrepareRequestInfo) + + interceptedPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(InterceptedIdPrefix, i)), + } + psCache.StoreIntercepted(interceptedPreparedResult, dummyPrepareRequestInfo) + } + } else { + // fill the cache + for i := 0; i < MaxPSCacheSizeForTests; i++ { + originPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(OriginIdPrefix, i)), + } + targetPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(TargetIdPrefix, i)), + } + psCache.Store(originPreparedResult, targetPreparedResult, dummyPrepareRequestInfo) + + interceptedPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(InterceptedIdPrefix, i)), + } + psCache.StoreIntercepted(interceptedPreparedResult, dummyPrepareRequestInfo) + } + + // access the specified elements + for _, elementSuffix := range test.elementSuffixesToAccess { + // access the specified elements to make them recently used + foundInOriginMap := checkIfElementIsInOriginMap(psCache, elementSuffix) + require.True(tt, foundInOriginMap, "element could not be found in origin map", elementSuffix) + foundInTargetMap := checkIfElementIsInTargetMap(psCache, elementSuffix) + require.True(tt, foundInTargetMap, "element could not be found in target map", elementSuffix) + foundInInterceptedMap := checkIfElementIsInInterceptedMap(psCache, elementSuffix) + require.True(tt, foundInInterceptedMap, "element could not be found in intercepted map", elementSuffix) + } + + // add more elements + for i := MaxPSCacheSizeForTests; i < test.numElementsToAdd; i++ { + originPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(OriginIdPrefix, i)), + } + targetPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(TargetIdPrefix, i)), + } + psCache.Store(originPreparedResult, targetPreparedResult, dummyPrepareRequestInfo) + + interceptedPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte(fmt.Sprint(InterceptedIdPrefix, i)), + } + psCache.StoreIntercepted(interceptedPreparedResult, dummyPrepareRequestInfo) + } + } + + require.Equal(tt, test.expectedCacheMapSize, psCache.cache.Len()) + require.Equal(tt, test.expectedCacheMapSize, len(psCache.index)) + require.Equal(tt, test.expectedCacheMapSize, psCache.interceptedCache.Len()) + require.Equal(tt, float64(test.expectedCacheMapSize*2), psCache.GetPreparedStatementCacheSize()) + + for _, elementSuffix := range test.expectedElementSuffixesInCache { + foundInOriginMap := checkIfElementIsInOriginMap(psCache, elementSuffix) + require.True(tt, foundInOriginMap, "element could not be found in origin map", elementSuffix) + foundInTargetMap := checkIfElementIsInTargetMap(psCache, elementSuffix) + require.True(tt, foundInTargetMap, "element could not be found in target map", elementSuffix) + foundInInterceptedMap := checkIfElementIsInInterceptedMap(psCache, elementSuffix) + require.True(tt, foundInInterceptedMap, "element could not be found in intercepted map", elementSuffix) + } + + }) + } + +} + +func checkIfElementIsInOriginMap(psCache *PreparedStatementCache, elementSuffix int) bool { + originId := fmt.Sprint(OriginIdPrefix, elementSuffix) + // not using psCache.Get, which is tested separately + _, foundOriginId := psCache.cache.Get(originId) + return foundOriginId +} + +func checkIfElementIsInTargetMap(psCache *PreparedStatementCache, elementSuffix int) bool { + targetId := fmt.Sprint(TargetIdPrefix, elementSuffix) + // not using psCache.GetByTargetPreparedId, which is tested separately + _, foundTargetId := psCache.index[targetId] + return foundTargetId +} + +func checkIfElementIsInInterceptedMap(psCache *PreparedStatementCache, elementSuffix int) bool { + interceptedId := fmt.Sprint(InterceptedIdPrefix, elementSuffix) + // not using psCache.Get, which is tested separately + _, foundInterceptedId := psCache.interceptedCache.Get(interceptedId) + return foundInterceptedId +} + +/* +* +This test focuses on ensuring that Get and GetByTargetPreparedId work correctly. +It inserts elements directly into the cache maps to avoid coupling this test to the logic in the PS Cache's store methods. +It uses dummy, non-realistic data. +*/ +func TestPreparedStatementCache_GetFromCache(t *testing.T) { + + tests := []struct { + name string + elementId string + cacheMapType CacheMapType + }{ + { + name: "Add to origin cache map, found by Get", + elementId: "someOriginId", + cacheMapType: CacheMapTypeOrigin, + }, + { + name: "Add to target cache map, found by GetByTargetId", + elementId: "someTargetId", + cacheMapType: CacheMapTypeTarget, + }, + { + name: "Add to intercepted cache map, found by Get", + elementId: "someInterceptedId", + cacheMapType: CacheMapTypeTarget, + }, + { + name: "Not added, not found", + elementId: "someElementId", + cacheMapType: CacheMapTypeNone, + }, + } + + dummyPreparedResult := &message.PreparedResult{ + PreparedQueryId: []byte("dummy"), + } + dummyPreparedData := NewPreparedData(dummyPreparedResult, dummyPreparedResult, NewPrepareRequestInfo(NewGenericRequestInfo(forwardToBoth, false, false), []*term{}, false, "", "")) + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + psCache, err := NewPreparedStatementCache(MaxPSCacheSizeForTests) + require.Nil(tt, err, "Error creating the PSCache", err) + + switch test.cacheMapType { + case CacheMapTypeOrigin: + psCache.cache.Add(test.elementId, dummyPreparedData) + + _, foundByGet := psCache.Get([]byte(test.elementId)) + require.True(tt, foundByGet) + + _, foundByGetByTargetPreparedId := psCache.GetByTargetPreparedId([]byte(test.elementId)) + require.False(tt, foundByGetByTargetPreparedId) + case CacheMapTypeTarget: + psCache.index[test.elementId] = "origin_" + test.elementId + psCache.cache.Add("origin_"+test.elementId, dummyPreparedData) + + _, foundByGet := psCache.Get([]byte(test.elementId)) + require.False(tt, foundByGet) + + _, foundByGetByTargetPreparedId := psCache.GetByTargetPreparedId([]byte(test.elementId)) + require.True(tt, foundByGetByTargetPreparedId) + case CacheMapTypeIntercepted: + psCache.interceptedCache.Add(test.elementId, dummyPreparedData) + + _, foundByGet := psCache.Get([]byte(test.elementId)) + require.True(tt, foundByGet) + + _, foundByGetByTargetPreparedId := psCache.GetByTargetPreparedId([]byte(test.elementId)) + require.False(tt, foundByGetByTargetPreparedId) + case CacheMapTypeNone: + _, foundByGet := psCache.Get([]byte(test.elementId)) + require.False(tt, foundByGet) + + _, foundByGetByTargetPreparedId := psCache.GetByTargetPreparedId([]byte(test.elementId)) + require.False(tt, foundByGetByTargetPreparedId) + default: + t.Fatal("Unknown or missing cache map type") + } + }) + } + +}