Skip to content

Commit da71381

Browse files
Check gcs time before read (#8667)
1 parent 0c9471b commit da71381

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

enterprise/server/backends/pebble_cache/pebble_cache.go

+9
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,15 @@ func (p *PebbleCache) reader(ctx context.Context, db pebble.IPebbleDB, r *rspb.R
31773177
return nil, err
31783178
}
31793179

3180+
// If this is a GCS object, ensure the custom time is relatively recent
3181+
// so that we avoid saying something exists when it's been deleted by
3182+
// a GCS lifecycle rule.
3183+
if gcsMetadata := fileMetadata.GetStorageMetadata().GetGcsMetadata(); gcsMetadata != nil {
3184+
if p.gcsObjectIsPastTTL(gcsMetadata) {
3185+
return nil, status.NotFoundError("backing object may have expired")
3186+
}
3187+
}
3188+
31803189
blobDir := p.blobDir()
31813190
requestedCompression := r.GetCompressor()
31823191
cachedCompression := fileMetadata.GetFileRecord().GetCompressor()

enterprise/server/backends/pebble_cache/pebble_cache_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -3180,3 +3180,58 @@ func TestGCSBlobStorageOverwriteObjects(t *testing.T) {
31803180
assert.NoError(t, err, rn)
31813181
}
31823182
}
3183+
3184+
func TestGCSBlobStorageReadAfterTTL(t *testing.T) {
3185+
te := testenv.GetTestEnv(t)
3186+
te.SetAuthenticator(testauth.NewTestAuthenticator(emptyUserMap))
3187+
clock := clockwork.NewFakeClock()
3188+
ctx := getAnonContext(t, te)
3189+
3190+
var minGCSFileSize int64 = 1
3191+
var gcsTTLDays int64 = 1
3192+
3193+
mockGCS := mockgcs.New(clock)
3194+
mockGCS.SetBucketCustomTimeTTL(ctx, gcsTTLDays)
3195+
fileStorer := filestore.New(filestore.WithGCSBlobstore(mockGCS, "app-name"))
3196+
options := &pebble_cache.Options{
3197+
RootDirectory: testfs.MakeTempDir(t),
3198+
MaxSizeBytes: int64(1_000_000), // 1MB
3199+
Clock: clock,
3200+
FileStorer: fileStorer,
3201+
MaxInlineFileSizeBytes: 1,
3202+
MinGCSFileSizeBytes: &minGCSFileSize,
3203+
GCSTTLDays: &gcsTTLDays,
3204+
}
3205+
pc, err := pebble_cache.NewPebbleCache(te, options)
3206+
if err != nil {
3207+
t.Fatal(err)
3208+
}
3209+
3210+
require.NoError(t, pc.Start())
3211+
defer pc.Stop()
3212+
3213+
sampleData := make(map[*rspb.ResourceName][]byte)
3214+
for i := 0; i < 10; i++ {
3215+
rn, buf := testdigest.RandomCASResourceBuf(t, 100)
3216+
sampleData[rn] = buf
3217+
3218+
rn, buf = testdigest.RandomACResourceBuf(t, 100)
3219+
sampleData[rn] = buf
3220+
}
3221+
3222+
// Write some data.
3223+
var written []*rspb.ResourceName
3224+
for rn, buf := range sampleData {
3225+
require.NoError(t, pc.Set(ctx, rn, buf))
3226+
written = append(written, rn)
3227+
}
3228+
3229+
// Advance the clock past the TTL
3230+
clock.Advance(25 * time.Hour)
3231+
3232+
// Ensure nothing is found via Get/Read.
3233+
for _, rn := range written {
3234+
_, err := pc.Get(ctx, rn)
3235+
require.True(t, status.IsNotFoundError(err), err)
3236+
}
3237+
}

server/testutil/mockgcs/mockgcs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (m *mockGCS) Reader(ctx context.Context, blobName string) (io.ReadCloser, e
5555
return nil, status.NotFoundError("mock gcs blob not found")
5656
}
5757
if m.expired(blobName) {
58-
return nil, status.NotFoundError("mock gcs blob expired")
58+
return nil, status.InternalError("mock gcs blob expired")
5959
}
6060
return io.NopCloser(bytes.NewReader(blob.data)), nil
6161
}

0 commit comments

Comments
 (0)