github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/objstorage/objstorageprovider/remote_backing_test.go (about) 1 // Copyright 2023 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package objstorageprovider 6 7 import ( 8 "encoding/binary" 9 "testing" 10 11 "github.com/cockroachdb/pebble/internal/base" 12 "github.com/cockroachdb/pebble/objstorage" 13 "github.com/cockroachdb/pebble/objstorage/remote" 14 "github.com/cockroachdb/pebble/vfs" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestSharedObjectBacking(t *testing.T) { 19 for _, cleanup := range []objstorage.SharedCleanupMethod{objstorage.SharedRefTracking, objstorage.SharedNoCleanup} { 20 name := "ref-tracking" 21 if cleanup == objstorage.SharedNoCleanup { 22 name = "no-cleanup" 23 } 24 t.Run(name, func(t *testing.T) { 25 st := DefaultSettings(vfs.NewMem(), "") 26 sharedStorage := remote.NewInMem() 27 st.Remote.StorageFactory = remote.MakeSimpleFactory(map[remote.Locator]remote.Storage{ 28 "foo": sharedStorage, 29 }) 30 p, err := Open(st) 31 require.NoError(t, err) 32 defer p.Close() 33 34 const creatorID = objstorage.CreatorID(99) 35 require.NoError(t, p.SetCreatorID(creatorID)) 36 meta := objstorage.ObjectMetadata{ 37 DiskFileNum: base.FileNum(1).DiskFileNum(), 38 FileType: base.FileTypeTable, 39 } 40 meta.Remote.CreatorID = 100 41 meta.Remote.CreatorFileNum = base.FileNum(200).DiskFileNum() 42 meta.Remote.CleanupMethod = cleanup 43 meta.Remote.Locator = "foo" 44 meta.Remote.CustomObjectName = "obj-name" 45 meta.Remote.Storage = sharedStorage 46 47 h, err := p.RemoteObjectBacking(&meta) 48 require.NoError(t, err) 49 buf, err := h.Get() 50 require.NoError(t, err) 51 h.Close() 52 _, err = h.Get() 53 require.Error(t, err) 54 55 d1, err := decodeRemoteObjectBacking(base.FileTypeTable, base.FileNum(100).DiskFileNum(), buf) 56 require.NoError(t, err) 57 require.Equal(t, uint64(100), uint64(d1.meta.DiskFileNum.FileNum())) 58 require.Equal(t, base.FileTypeTable, d1.meta.FileType) 59 d1.meta.Remote.Storage = sharedStorage 60 require.Equal(t, meta.Remote, d1.meta.Remote) 61 if cleanup == objstorage.SharedRefTracking { 62 require.Equal(t, creatorID, d1.refToCheck.creatorID) 63 require.Equal(t, base.FileNum(1).DiskFileNum(), d1.refToCheck.fileNum) 64 } else { 65 require.Equal(t, objstorage.CreatorID(0), d1.refToCheck.creatorID) 66 require.Equal(t, base.FileNum(0).DiskFileNum(), d1.refToCheck.fileNum) 67 } 68 69 t.Run("unknown-tags", func(t *testing.T) { 70 // Append a tag that is safe to ignore. 71 buf2 := buf 72 buf2 = binary.AppendUvarint(buf2, 13) 73 buf2 = binary.AppendUvarint(buf2, 2) 74 buf2 = append(buf2, 1, 1) 75 76 d2, err := decodeRemoteObjectBacking(base.FileTypeTable, base.FileNum(100).DiskFileNum(), buf2) 77 require.NoError(t, err) 78 require.Equal(t, uint64(100), uint64(d2.meta.DiskFileNum.FileNum())) 79 require.Equal(t, base.FileTypeTable, d2.meta.FileType) 80 d2.meta.Remote.Storage = sharedStorage 81 require.Equal(t, meta.Remote, d2.meta.Remote) 82 if cleanup == objstorage.SharedRefTracking { 83 require.Equal(t, creatorID, d2.refToCheck.creatorID) 84 require.Equal(t, base.FileNum(1).DiskFileNum(), d2.refToCheck.fileNum) 85 } else { 86 require.Equal(t, objstorage.CreatorID(0), d2.refToCheck.creatorID) 87 require.Equal(t, base.FileNum(0).DiskFileNum(), d2.refToCheck.fileNum) 88 } 89 90 buf3 := buf2 91 buf3 = binary.AppendUvarint(buf3, tagNotSafeToIgnoreMask+5) 92 _, err = decodeRemoteObjectBacking(meta.FileType, meta.DiskFileNum, buf3) 93 require.Error(t, err) 94 require.Contains(t, err.Error(), "unknown tag") 95 }) 96 }) 97 } 98 } 99 100 func TestCreateSharedObjectBacking(t *testing.T) { 101 st := DefaultSettings(vfs.NewMem(), "") 102 sharedStorage := remote.NewInMem() 103 st.Remote.StorageFactory = remote.MakeSimpleFactory(map[remote.Locator]remote.Storage{ 104 "foo": sharedStorage, 105 }) 106 p, err := Open(st) 107 require.NoError(t, err) 108 defer p.Close() 109 110 require.NoError(t, p.SetCreatorID(1)) 111 112 backing, err := p.CreateExternalObjectBacking("foo", "custom-obj-name") 113 require.NoError(t, err) 114 d, err := decodeRemoteObjectBacking(base.FileTypeTable, base.FileNum(100).DiskFileNum(), backing) 115 require.NoError(t, err) 116 require.Equal(t, uint64(100), uint64(d.meta.DiskFileNum.FileNum())) 117 require.Equal(t, base.FileTypeTable, d.meta.FileType) 118 require.Equal(t, remote.Locator("foo"), d.meta.Remote.Locator) 119 require.Equal(t, "custom-obj-name", d.meta.Remote.CustomObjectName) 120 require.Equal(t, objstorage.SharedNoCleanup, d.meta.Remote.CleanupMethod) 121 } 122 123 func TestAttachRemoteObjects(t *testing.T) { 124 st := DefaultSettings(vfs.NewMem(), "") 125 sharedStorage := remote.NewInMem() 126 st.Remote.StorageFactory = remote.MakeSimpleFactory(map[remote.Locator]remote.Storage{ 127 "foo": sharedStorage, 128 }) 129 p, err := Open(st) 130 require.NoError(t, err) 131 defer p.Close() 132 require.NoError(t, p.SetCreatorID(1)) 133 backing, err := p.CreateExternalObjectBacking("foo", "custom-obj-name") 134 require.NoError(t, err) 135 _, err = p.AttachRemoteObjects([]objstorage.RemoteObjectToAttach{{ 136 FileType: base.FileTypeTable, 137 FileNum: base.FileNum(100).DiskFileNum(), 138 Backing: backing, 139 }}) 140 require.NoError(t, err) 141 142 // Sync, close, and reopen the provider and expect that we see 143 // our object. 144 require.NoError(t, p.Sync()) 145 require.NoError(t, p.Close()) 146 147 p, err = Open(st) 148 require.NoError(t, err) 149 defer p.Close() 150 require.NoError(t, p.SetCreatorID(1)) 151 objs := p.List() 152 require.Len(t, objs, 1) 153 o := objs[0] 154 require.Equal(t, remote.Locator("foo"), o.Remote.Locator) 155 require.Equal(t, "custom-obj-name", o.Remote.CustomObjectName) 156 require.Equal(t, uint64(100), uint64(o.DiskFileNum.FileNum())) 157 require.Equal(t, base.FileTypeTable, o.FileType) 158 }