github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/bserver_remote_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 10 "github.com/keybase/client/go/kbfs/env" 11 12 "github.com/keybase/client/go/kbfs/idutil" 13 "github.com/keybase/client/go/kbfs/kbfsblock" 14 "github.com/keybase/client/go/kbfs/kbfscrypto" 15 "github.com/keybase/client/go/kbfs/tlf" 16 "github.com/keybase/client/go/protocol/keybase1" 17 "github.com/keybase/go-framed-msgpack-rpc/rpc" 18 "github.com/stretchr/testify/require" 19 "golang.org/x/net/context" 20 ) 21 22 type fakeBlockEntry struct { 23 folder string 24 buf []byte 25 blockKey string 26 refs map[keybase1.BlockRefNonce]keybase1.BlockReference 27 } 28 29 type fakeBServerClient struct { 30 keybase1.BlockInterface 31 entries map[keybase1.BlockIdCombo]fakeBlockEntry 32 } 33 34 func (fc *fakeBServerClient) PutBlock( 35 ctx context.Context, arg keybase1.PutBlockArg) error { 36 var refs map[keybase1.BlockRefNonce]keybase1.BlockReference 37 if e, ok := fc.entries[arg.Bid]; ok { 38 refs = e.refs 39 } else { 40 refs = make(map[keybase1.BlockRefNonce]keybase1.BlockReference) 41 fc.entries[arg.Bid] = fakeBlockEntry{ 42 arg.Folder, arg.Buf, arg.BlockKey, refs, 43 } 44 } 45 refs[keybase1.BlockRefNonce{}] = keybase1.BlockReference{ 46 Bid: arg.Bid, 47 } 48 return nil 49 } 50 51 func (fc *fakeBServerClient) GetBlock(ctx context.Context, arg keybase1.GetBlockArg) (keybase1.GetBlockRes, error) { 52 e, ok := fc.entries[arg.Bid] 53 if !ok { 54 return keybase1.GetBlockRes{}, kbfsblock.ServerErrorBlockNonExistent{} 55 } 56 return keybase1.GetBlockRes{ 57 Buf: e.buf, 58 BlockKey: e.blockKey, 59 }, nil 60 } 61 62 func (fc *fakeBServerClient) AddReference(ctx context.Context, arg keybase1.AddReferenceArg) error { 63 e, ok := fc.entries[arg.Ref.Bid] 64 if !ok { 65 return kbfsblock.ServerErrorBlockNonExistent{} 66 } 67 e.refs[arg.Ref.Nonce] = arg.Ref 68 return nil 69 } 70 71 type testBlockServerRemoteConfig struct { 72 codecGetter 73 logMaker 74 signer kbfscrypto.Signer 75 sessionGetter idutil.CurrentSessionGetter 76 diskBlockCache DiskBlockCache 77 } 78 79 var _ blockServerRemoteConfig = (*testBlockServerRemoteConfig)(nil) 80 81 func (c testBlockServerRemoteConfig) Signer() kbfscrypto.Signer { 82 return c.signer 83 } 84 85 func (c testBlockServerRemoteConfig) CurrentSessionGetter() idutil.CurrentSessionGetter { 86 return c.sessionGetter 87 } 88 89 func (c testBlockServerRemoteConfig) DiskBlockCache() DiskBlockCache { 90 return c.diskBlockCache 91 } 92 93 func (c testBlockServerRemoteConfig) Mode() InitMode { 94 return modeTest{} 95 } 96 97 func (c testBlockServerRemoteConfig) IsTestMode() bool { 98 return true 99 } 100 101 // Test that putting a block, and getting it back, works 102 func TestBServerRemotePutAndGet(t *testing.T) { 103 currentUID := keybase1.MakeTestUID(1) 104 fc := fakeBServerClient{ 105 entries: make(map[keybase1.BlockIdCombo]fakeBlockEntry), 106 } 107 config := testBlockServerRemoteConfig{newTestCodecGetter(), 108 newTestLogMaker(t), nil, nil, nil} 109 b := newBlockServerRemoteWithClient(&env.KBFSContext{}, config, &fc) 110 111 tlfID := tlf.FakeID(2, tlf.Private) 112 bCtx := kbfsblock.MakeFirstContext( 113 currentUID.AsUserOrTeam(), keybase1.BlockType_DATA) 114 data := []byte{1, 2, 3, 4} 115 bID, err := kbfsblock.MakePermanentID( 116 data, kbfscrypto.EncryptionSecretboxWithKeyNonce) 117 require.NoError(t, err) 118 119 serverHalf, err := kbfscrypto.MakeRandomBlockCryptKeyServerHalf() 120 require.NoError(t, err) 121 ctx := context.Background() 122 err = b.Put(ctx, tlfID, bID, bCtx, data, serverHalf, DiskBlockAnyCache) 123 require.NoError(t, err) 124 125 // Now get the same block back. 126 buf, sh, err := b.Get(ctx, tlfID, bID, bCtx, DiskBlockAnyCache) 127 require.NoError(t, err) 128 require.Equal(t, data, buf) 129 require.Equal(t, serverHalf, sh) 130 131 // Add a reference. 132 nonce, err := kbfsblock.MakeRefNonce() 133 require.NoError(t, err) 134 bCtx2 := kbfsblock.MakeContext( 135 currentUID.AsUserOrTeam(), keybase1.MakeTestUID(2).AsUserOrTeam(), 136 nonce, keybase1.BlockType_DATA) 137 err = b.AddBlockReference(ctx, tlfID, bID, bCtx2) 138 require.NoError(t, err) 139 140 // Now get the same block back. 141 buf, sh, err = b.Get(ctx, tlfID, bID, bCtx2, DiskBlockAnyCache) 142 require.NoError(t, err) 143 require.Equal(t, data, buf) 144 require.Equal(t, serverHalf, sh) 145 } 146 147 // If we cancel the RPC before the RPC returns, the call should error quickly. 148 func TestBServerRemotePutCanceled(t *testing.T) { 149 currentUID := keybase1.MakeTestUID(1) 150 serverConn, conn := rpc.MakeConnectionForTest(t) 151 config := testBlockServerRemoteConfig{newTestCodecGetter(), 152 newTestLogMaker(t), nil, nil, nil} 153 b := newBlockServerRemoteWithClient(&env.KBFSContext{}, config, 154 keybase1.BlockClient{Cli: conn.GetClient()}) 155 156 f := func(ctx context.Context) error { 157 bID := kbfsblock.FakeID(1) 158 tlfID := tlf.FakeID(2, tlf.Private) 159 bCtx := kbfsblock.MakeFirstContext( 160 currentUID.AsUserOrTeam(), keybase1.BlockType_DATA) 161 data := []byte{1, 2, 3, 4} 162 serverHalf := kbfscrypto.MakeBlockCryptKeyServerHalf( 163 [32]byte{0x1}) 164 return b.Put(ctx, tlfID, bID, bCtx, data, serverHalf, DiskBlockAnyCache) 165 } 166 testRPCWithCanceledContext(t, serverConn, f) 167 }