Skip to content

Commit 690e5c7

Browse files
authored
Make verification cache detector type-aware (#4009)
This PR modifies the verification cache to be detector type-aware by adding the detector type to the cache keys. There is also a slight change to the key generation logic to prevent it from reslicing the passed-in Raw value. (We haven't seen any trouble from this so far, but I think it's good to disarm the footgun while I'm here.) When adding tests, I also realized that the existing tests were inconsistently named, so I cleaned them up. This resolves #3984.
1 parent 34339ea commit 690e5c7

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

pkg/verificationcache/verification_cache.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package verificationcache
22

33
import (
4+
"bytes"
5+
"encoding/binary"
46
"sync"
57
"time"
68

@@ -135,5 +137,11 @@ func (v *VerificationCache) getResultCacheKey(result detectors.Result) ([]byte,
135137
v.hashMu.Lock()
136138
defer v.hashMu.Unlock()
137139

138-
return v.hasher.Hash(append(result.Raw, result.RawV2...))
140+
keyBytes := bytes.Join([][]byte{result.Raw, result.RawV2}, nil)
141+
keyBytes, err := binary.Append(keyBytes, binary.BigEndian, result.DetectorType)
142+
if err != nil {
143+
return nil, err
144+
}
145+
146+
return v.hasher.Hash(keyBytes)
139147
}

pkg/verificationcache/verification_cache_test.go

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func (t *testDetector) FromData(_ context.Context, verify bool, _ []byte) ([]det
2323
t.fromDataCallCount = t.fromDataCallCount + 1
2424
var results []detectors.Result
2525
for _, r := range t.results {
26-
copy := detectors.Result{Redacted: r.Redacted, Raw: r.Raw, RawV2: r.RawV2}
26+
copy := detectors.Result{Redacted: r.Redacted, Raw: r.Raw, RawV2: r.RawV2, DetectorType: r.DetectorType}
2727
if verify {
2828
copy.CopyVerificationInfo(&r)
2929
}
@@ -49,7 +49,7 @@ func getResultCacheKey(t *testing.T, cache *VerificationCache, result detectors.
4949
return string(key)
5050
}
5151

52-
func TestVerificationCacheFromData_Passthrough(t *testing.T) {
52+
func TestVerificationCache_FromData_Passthrough(t *testing.T) {
5353
detector := testDetector{results: []detectors.Result{
5454
{Redacted: "hello", Raw: []byte("hello"), RawV2: []byte("helloV2"), Verified: true},
5555
}}
@@ -69,7 +69,7 @@ func TestVerificationCacheFromData_Passthrough(t *testing.T) {
6969
})
7070
}
7171

72-
func TestVerificationCacheFromData_VerifyFalseForceCacheUpdateFalse(t *testing.T) {
72+
func TestVerificationCache_FromData_VerifyFalseForceCacheUpdateFalse(t *testing.T) {
7373
detector := testDetector{results: []detectors.Result{
7474
{Redacted: "hello", Raw: []byte("hello"), RawV2: []byte("helloV2"), Verified: true},
7575
}}
@@ -96,7 +96,7 @@ func TestVerificationCacheFromData_VerifyFalseForceCacheUpdateFalse(t *testing.T
9696
assert.Equal(t, int32(0), metrics.ResultCacheMisses.Load())
9797
}
9898

99-
func TestFromDataCached_VerifyFalseForceCacheUpdateTrue(t *testing.T) {
99+
func TestVerificationCache_FromData_VerifyFalseForceCacheUpdateTrue(t *testing.T) {
100100
detector := testDetector{results: []detectors.Result{
101101
{Redacted: "hello", Raw: []byte("hello"), RawV2: []byte("helloV2"), Verified: true},
102102
{Redacted: "world", Raw: []byte("world"), RawV2: []byte("worldV2"), Verified: false},
@@ -129,7 +129,7 @@ func TestFromDataCached_VerifyFalseForceCacheUpdateTrue(t *testing.T) {
129129
assert.Equal(t, int32(0), metrics.ResultCacheMisses.Load())
130130
}
131131

132-
func TestFromDataCached_VerifyTrueForceCacheUpdateFalseAllCacheHits(t *testing.T) {
132+
func TestVerificationCache_FromData_VerifyTrueForceCacheUpdateFalseAllCacheHits(t *testing.T) {
133133
remoteResults := []detectors.Result{
134134
{Redacted: "hello", Raw: []byte("hello"), RawV2: []byte("helloV2"), Verified: true},
135135
{Redacted: "world", Raw: []byte("world"), RawV2: []byte("worldV2"), Verified: false},
@@ -169,7 +169,7 @@ func TestFromDataCached_VerifyTrueForceCacheUpdateFalseAllCacheHits(t *testing.T
169169
assert.Equal(t, int32(0), metrics.ResultCacheMisses.Load())
170170
}
171171

172-
func TestFromDataCached_VerifyTrueForceCacheUpdateFalseCacheMiss(t *testing.T) {
172+
func TestVerificationCache_FromData_VerifyTrueForceCacheUpdateFalseCacheMiss(t *testing.T) {
173173
detector := testDetector{results: []detectors.Result{
174174
{Redacted: "hello", Raw: []byte("hello"), RawV2: []byte("helloV2"), Verified: true},
175175
{Redacted: "world", Raw: []byte("world"), RawV2: []byte("worldV2"), Verified: false},
@@ -205,7 +205,7 @@ func TestFromDataCached_VerifyTrueForceCacheUpdateFalseCacheMiss(t *testing.T) {
205205
assert.Equal(t, int32(1), metrics.ResultCacheHitsWasted.Load())
206206
}
207207

208-
func TestFromDataCached_VerifyTrueForceCacheUpdateTrue(t *testing.T) {
208+
func TestVerificationCache_FromData_VerifyTrueForceCacheUpdateTrue(t *testing.T) {
209209
detector := testDetector{results: []detectors.Result{
210210
{Redacted: "hello", Raw: []byte("hello"), RawV2: []byte("helloV2"), Verified: true},
211211
{Redacted: "world", Raw: []byte("world"), RawV2: []byte("worldV2"), Verified: false},
@@ -238,3 +238,45 @@ func TestFromDataCached_VerifyTrueForceCacheUpdateTrue(t *testing.T) {
238238
assert.Equal(t, int32(0), metrics.ResultCacheMisses.Load())
239239
assert.Equal(t, int32(0), metrics.ResultCacheHitsWasted.Load())
240240
}
241+
242+
func TestVerificationCache_FromData_SameRawDifferentType_CacheMiss(t *testing.T) {
243+
detector1 := testDetector{results: []detectors.Result{
244+
{Redacted: "hello", Raw: []byte("hello"), Verified: true, DetectorType: -1},
245+
}}
246+
detector2 := testDetector{results: []detectors.Result{
247+
{Redacted: "hello", Raw: []byte("hello"), Verified: true, DetectorType: -2},
248+
}}
249+
cache := New(simple.NewCache[detectors.Result](), nil)
250+
_, err := cache.FromData(logContext.Background(), &detector1, true, false, nil)
251+
require.NoError(t, err)
252+
253+
res, err := cache.FromData(logContext.Background(), &detector2, true, false, nil)
254+
255+
if assert.NoError(t, err) {
256+
if assert.Len(t, res, 1) {
257+
assert.Equal(t, detectorspb.DetectorType(-2), res[0].DetectorType)
258+
}
259+
}
260+
assert.Len(t, cache.resultCache.Values(), 2)
261+
}
262+
263+
func TestVerificationCache_FromData_SameRawV2DifferentType_CacheMiss(t *testing.T) {
264+
detector1 := testDetector{results: []detectors.Result{
265+
{Redacted: "hello", RawV2: []byte("there"), Verified: true, DetectorType: -1},
266+
}}
267+
detector2 := testDetector{results: []detectors.Result{
268+
{Redacted: "hello", RawV2: []byte("there"), Verified: true, DetectorType: -2},
269+
}}
270+
cache := New(simple.NewCache[detectors.Result](), nil)
271+
_, err := cache.FromData(logContext.Background(), &detector1, true, false, nil)
272+
require.NoError(t, err)
273+
274+
res, err := cache.FromData(logContext.Background(), &detector2, true, false, nil)
275+
276+
if assert.NoError(t, err) {
277+
if assert.Len(t, res, 1) {
278+
assert.Equal(t, detectorspb.DetectorType(-2), res[0].DetectorType)
279+
}
280+
}
281+
assert.Len(t, cache.resultCache.Values(), 2)
282+
}

0 commit comments

Comments
 (0)