github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/mdserver_test.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libkbfs 6 7 import ( 8 "testing" 9 "time" 10 11 "github.com/keybase/client/go/kbfs/kbfscodec" 12 "github.com/keybase/client/go/kbfs/kbfscrypto" 13 "github.com/keybase/client/go/kbfs/kbfsmd" 14 "github.com/keybase/client/go/kbfs/tlf" 15 "github.com/keybase/client/go/protocol/keybase1" 16 "github.com/stretchr/testify/require" 17 18 "golang.org/x/net/context" 19 ) 20 21 func makeBRMDForTest(t *testing.T, codec kbfscodec.Codec, 22 id tlf.ID, h tlf.Handle, revision kbfsmd.Revision, uid keybase1.UID, 23 prevRoot kbfsmd.ID) *kbfsmd.RootMetadataV2 { 24 var md kbfsmd.RootMetadataV2 25 // MDv3 TODO: uncomment the below when we're ready for MDv3 26 // md := &kbfsmd.RootMetadataV3{} 27 md.SetTlfID(id) 28 md.SetSerializedPrivateMetadata([]byte{0x1}) 29 md.SetRevision(revision) 30 md.SetLastModifyingWriter(uid) 31 md.SetLastModifyingUser(uid) 32 kbfsmd.FakeInitialRekey(&md, h, kbfscrypto.TLFPublicKey{}) 33 md.SetPrevRoot(prevRoot) 34 return &md 35 } 36 37 func signRMDSForTest( 38 t *testing.T, codec kbfscodec.Codec, signer kbfscrypto.Signer, 39 brmd *kbfsmd.RootMetadataV2) *RootMetadataSigned { 40 ctx := context.Background() 41 42 // Encode and sign writer metadata. 43 err := brmd.SignWriterMetadataInternally(ctx, codec, signer) 44 require.NoError(t, err) 45 46 rmds, err := SignBareRootMetadata( 47 ctx, codec, signer, signer, brmd, time.Time{}) 48 require.NoError(t, err) 49 50 return rmds 51 } 52 53 // This should pass for both local and remote servers. 54 func TestMDServerBasics(t *testing.T) { 55 // setup 56 ctx := context.Background() 57 config := MakeTestConfigOrBust(t, "test_user") 58 defer CheckConfigAndShutdown(ctx, t, config) 59 mdServer := config.MDServer() 60 61 session, err := config.KBPKI().GetCurrentSession(ctx) 62 require.NoError(t, err) 63 uid := session.UID 64 65 // (1) get metadata -- allocates an ID 66 h, err := tlf.MakeHandle( 67 []keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil) 68 require.NoError(t, err) 69 70 id, rmds, err := mdServer.GetForHandle(ctx, h, kbfsmd.Merged, nil) 71 require.NoError(t, err) 72 require.Nil(t, rmds) 73 74 // (2) push some new metadata blocks 75 prevRoot := kbfsmd.ID{} 76 middleRoot := kbfsmd.ID{} 77 for i := kbfsmd.Revision(1); i <= 10; i++ { 78 brmd := makeBRMDForTest(t, config.Codec(), id, h, i, uid, prevRoot) 79 rmds := signRMDSForTest(t, config.Codec(), config.Crypto(), brmd) 80 // MDv3 TODO: pass actual key bundles 81 err = mdServer.Put(ctx, rmds, nil, nil, keybase1.MDPriorityNormal) 82 require.NoError(t, err) 83 prevRoot, err = kbfsmd.MakeID(config.Codec(), rmds.MD) 84 require.NoError(t, err) 85 if i == 5 { 86 middleRoot = prevRoot 87 } 88 } 89 90 // (3) trigger a conflict 91 brmd := makeBRMDForTest(t, config.Codec(), id, h, 10, uid, prevRoot) 92 rmds = signRMDSForTest(t, config.Codec(), config.Crypto(), brmd) 93 // MDv3 TODO: pass actual key bundles 94 err = mdServer.Put(ctx, rmds, nil, nil, keybase1.MDPriorityNormal) 95 require.IsType(t, kbfsmd.ServerErrorConflictRevision{}, err) 96 97 // (4) push some new unmerged metadata blocks linking to the 98 // middle merged block. 99 prevRoot = middleRoot 100 bid, err := config.Crypto().MakeRandomBranchID() 101 require.NoError(t, err) 102 for i := kbfsmd.Revision(6); i < 41; i++ { 103 brmd := makeBRMDForTest(t, config.Codec(), id, h, i, uid, prevRoot) 104 brmd.SetUnmerged() 105 brmd.SetBranchID(bid) 106 rmds := signRMDSForTest(t, config.Codec(), config.Crypto(), brmd) 107 // MDv3 TODO: pass actual key bundles 108 err = mdServer.Put(ctx, rmds, nil, nil, keybase1.MDPriorityNormal) 109 require.NoError(t, err) 110 prevRoot, err = kbfsmd.MakeID(config.Codec(), rmds.MD) 111 require.NoError(t, err) 112 } 113 114 // (5) check for proper unmerged head 115 head, err := mdServer.GetForTLF(ctx, id, bid, kbfsmd.Unmerged, nil) 116 require.NoError(t, err) 117 require.NotNil(t, head) 118 require.Equal(t, kbfsmd.Revision(40), head.MD.RevisionNumber()) 119 120 // (6a) try to get unmerged range 121 rmdses, err := mdServer.GetRange(ctx, id, bid, kbfsmd.Unmerged, 1, 100, nil) 122 require.NoError(t, err) 123 require.Equal(t, 35, len(rmdses)) 124 for i := kbfsmd.Revision(6); i < 41; i++ { 125 require.Equal(t, i, rmdses[i-6].MD.RevisionNumber()) 126 } 127 128 // (6b) try to get unmerged range subset. 129 rmdses, err = mdServer.GetRange(ctx, id, bid, kbfsmd.Unmerged, 7, 14, nil) 130 require.NoError(t, err) 131 require.Equal(t, 8, len(rmdses)) 132 for i := kbfsmd.Revision(7); i <= 14; i++ { 133 require.Equal(t, i, rmdses[i-7].MD.RevisionNumber()) 134 } 135 136 // (7) prune unmerged 137 err = mdServer.PruneBranch(ctx, id, bid) 138 require.NoError(t, err) 139 140 // (8) verify head is pruned 141 head, err = mdServer.GetForTLF(ctx, id, kbfsmd.NullBranchID, kbfsmd.Unmerged, nil) 142 require.NoError(t, err) 143 require.Nil(t, head) 144 145 // (9) verify revision history is pruned 146 rmdses, err = mdServer.GetRange(ctx, id, kbfsmd.NullBranchID, kbfsmd.Unmerged, 1, 100, nil) 147 require.NoError(t, err) 148 require.Equal(t, 0, len(rmdses)) 149 150 // (10) check for proper merged head 151 head, err = mdServer.GetForTLF(ctx, id, kbfsmd.NullBranchID, kbfsmd.Merged, nil) 152 require.NoError(t, err) 153 require.NotNil(t, head) 154 require.Equal(t, kbfsmd.Revision(10), head.MD.RevisionNumber()) 155 156 // (11) try to get merged range 157 rmdses, err = mdServer.GetRange(ctx, id, kbfsmd.NullBranchID, kbfsmd.Merged, 1, 100, nil) 158 require.NoError(t, err) 159 require.Equal(t, 10, len(rmdses)) 160 for i := kbfsmd.Revision(1); i <= 10; i++ { 161 require.Equal(t, i, rmdses[i-1].MD.RevisionNumber()) 162 } 163 } 164 165 // This should pass for both local and remote servers. Make sure that 166 // registering multiple TLFs for updates works. This is a regression 167 // test for https://keybase.atlassian.net/browse/KBFS-467 . 168 func TestMDServerRegisterForUpdate(t *testing.T) { 169 // setup 170 ctx := context.Background() 171 config := MakeTestConfigOrBust(t, "test_user") 172 defer CheckConfigAndShutdown(ctx, t, config) 173 mdServer := config.MDServer() 174 175 session, err := config.KBPKI().GetCurrentSession(ctx) 176 require.NoError(t, err) 177 id := session.UID.AsUserOrTeam() 178 179 // Create first TLF. 180 h1, err := tlf.MakeHandle([]keybase1.UserOrTeamID{id}, nil, nil, nil, nil) 181 require.NoError(t, err) 182 183 id1, _, err := mdServer.GetForHandle(ctx, h1, kbfsmd.Merged, nil) 184 require.NoError(t, err) 185 186 // Create second TLF, which should end up being different from 187 // the first one. 188 h2, err := tlf.MakeHandle([]keybase1.UserOrTeamID{id}, 189 []keybase1.UserOrTeamID{keybase1.UserOrTeamID(keybase1.PUBLIC_UID)}, 190 nil, nil, nil) 191 require.NoError(t, err) 192 193 id2, _, err := mdServer.GetForHandle(ctx, h2, kbfsmd.Merged, nil) 194 require.NoError(t, err) 195 require.NotEqual(t, id1, id2) 196 197 _, err = mdServer.RegisterForUpdate(ctx, id1, kbfsmd.RevisionInitial) 198 require.NoError(t, err) 199 200 _, err = mdServer.RegisterForUpdate(ctx, id2, kbfsmd.RevisionInitial) 201 require.NoError(t, err) 202 }