github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/chain_link_v2_test.go (about) 1 package libkb 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/keybase/client/go/msgpack" 8 keybase1 "github.com/keybase/client/go/protocol/keybase1" 9 "github.com/stretchr/testify/require" 10 ) 11 12 // requireErrorHasSuffix makes sure that err's string has 13 // expectedErrSuffix's string as a suffix. This is necessary as 14 // go-codec prepends stuff to any errors it catches. 15 func requireErrorHasSuffix(t *testing.T, expectedErrSuffix, err error) { 16 t.Helper() 17 require.Error(t, err) 18 require.True(t, strings.HasSuffix(err.Error(), expectedErrSuffix.Error()), "Expected %q to have %q as a suffix", err, expectedErrSuffix) 19 } 20 21 // Test that various ways in which OuterLinkV2WithMetadata may be 22 // encoded/decoded all fail. 23 24 func TestOuterLinkV2WithMetadataEncode(t *testing.T) { 25 var o OuterLinkV2WithMetadata 26 _, err := msgpack.Encode(o) 27 requireErrorHasSuffix(t, errCodecEncodeSelf, err) 28 _, err = msgpack.Encode(&o) 29 requireErrorHasSuffix(t, errCodecEncodeSelf, err) 30 } 31 32 func TestOuterLinkV2WithMetadataDecode(t *testing.T) { 33 var o OuterLinkV2WithMetadata 34 err := msgpack.Decode(&o, []byte{0x1, 0x2}) 35 requireErrorHasSuffix(t, errCodecDecodeSelf, err) 36 } 37 38 type outerLinkV2WithMetadataEmbedder struct { 39 OuterLinkV2WithMetadata 40 } 41 42 func TestOuterLinkV2WithMetadataEmbedderEncode(t *testing.T) { 43 var o outerLinkV2WithMetadataEmbedder 44 _, err := msgpack.Encode(o) 45 requireErrorHasSuffix(t, errCodecEncodeSelf, err) 46 } 47 48 func TestOuterLinkV2WithMetadataEmbedderDecode(t *testing.T) { 49 var o outerLinkV2WithMetadataEmbedder 50 err := msgpack.Decode(&o, []byte{0x1, 0x2}) 51 requireErrorHasSuffix(t, errCodecDecodeSelf, err) 52 } 53 54 type outerLinkV2WithMetadataPointerEmbedder struct { 55 *OuterLinkV2WithMetadata 56 } 57 58 func TestOuterLinkV2WithMetadataPointerEmbedderEncode(t *testing.T) { 59 o := outerLinkV2WithMetadataPointerEmbedder{ 60 OuterLinkV2WithMetadata: &OuterLinkV2WithMetadata{}, 61 } 62 _, err := msgpack.Encode(o) 63 requireErrorHasSuffix(t, errCodecEncodeSelf, err) 64 } 65 66 func TestOuterLinkV2WithMetadataPointerEmbedderDecode(t *testing.T) { 67 var o outerLinkV2WithMetadataPointerEmbedder 68 err := msgpack.Decode(&o, []byte{0x1, 0x2}) 69 requireErrorHasSuffix(t, errCodecDecodeSelf, err) 70 } 71 72 type outerLinkV2WithMetadataContainer struct { 73 O OuterLinkV2WithMetadata 74 } 75 76 func TestOuterLinkV2WithMetadataContainerEncode(t *testing.T) { 77 var o outerLinkV2WithMetadataContainer 78 _, err := msgpack.Encode(o) 79 requireErrorHasSuffix(t, errCodecEncodeSelf, err) 80 } 81 82 func TestOuterLinkV2WithMetadataContainerDecode(t *testing.T) { 83 bytes, err := msgpack.Encode(map[string]interface{}{ 84 "O": []byte{0x01, 0x02}, 85 }) 86 require.NoError(t, err) 87 88 var o outerLinkV2WithMetadataContainer 89 err = msgpack.Decode(&o, bytes) 90 requireErrorHasSuffix(t, errCodecDecodeSelf, err) 91 } 92 93 type outerLinkV2WithMetadataPointerContainer struct { 94 O *OuterLinkV2WithMetadata 95 } 96 97 func TestOuterLinkV2WithMetadataPointerContainerEncode(t *testing.T) { 98 o := outerLinkV2WithMetadataPointerContainer{ 99 O: &OuterLinkV2WithMetadata{}, 100 } 101 _, err := msgpack.Encode(o) 102 requireErrorHasSuffix(t, errCodecEncodeSelf, err) 103 } 104 105 func TestOuterLinkV2WithMetadataPointerContainerDecode(t *testing.T) { 106 bytes, err := msgpack.Encode(map[string]interface{}{ 107 "O": []byte{0x01, 0x02}, 108 }) 109 require.NoError(t, err) 110 111 var o outerLinkV2WithMetadataPointerContainer 112 err = msgpack.Decode(&o, bytes) 113 requireErrorHasSuffix(t, errCodecDecodeSelf, err) 114 } 115 116 func serdeOuterLink(t *testing.T, tc TestContext, seqno keybase1.Seqno, highSkipSeqno *keybase1.Seqno, highSkipHash LinkID) OuterLinkV2 { 117 m := NewMetaContextForTest(tc) 118 119 AddEnvironmentFeatureForTest(tc, EnvironmentFeatureAllowHighSkips) 120 121 var highSkip *HighSkip 122 if highSkipSeqno != nil { 123 highSkipPre := NewHighSkip(*highSkipSeqno, highSkipHash) 124 highSkip = &highSkipPre 125 } 126 encoded, err := encodeOuterLink(m, LinkTypeLeave, seqno, nil, nil, false, keybase1.SeqType_PUBLIC, false, highSkip) 127 require.NoError(t, err) 128 129 o2 := OuterLinkV2{} 130 err = msgpack.Decode(&o2, encoded) 131 require.NoError(t, err) 132 return o2 133 } 134 135 func highSkipMatch(ol OuterLinkV2, highSkip *HighSkip) error { 136 return ol.AssertFields(ol.Version, ol.Seqno, ol.Prev, ol.Curr, ol.LinkType, ol.SeqType, ol.IgnoreIfUnsupported, highSkip) 137 } 138 139 func TestHighSkipBackwardsCompatibility(t *testing.T) { 140 tc := SetupTest(t, "test_high_skip_backwards_compatibility", 1) 141 defer tc.Cleanup() 142 143 seqno := keybase1.Seqno(1) 144 highSkipSeqno := keybase1.Seqno(0) 145 146 o := serdeOuterLink(t, tc, seqno, nil, nil) 147 require.True(t, o.HighSkipSeqno == nil) 148 require.True(t, o.HighSkipHash == nil) 149 require.NoError(t, highSkipMatch(o, nil)) 150 151 o = serdeOuterLink(t, tc, seqno, &highSkipSeqno, nil) 152 require.True(t, *o.HighSkipSeqno == 0) 153 require.True(t, o.HighSkipHash == nil) 154 highSkip := NewHighSkip(keybase1.Seqno(0), nil) 155 badHighSkip1 := NewHighSkip(keybase1.Seqno(0), []byte{0, 5, 2}) 156 badHighSkip2 := NewHighSkip(keybase1.Seqno(2), nil) 157 require.NoError(t, highSkipMatch(o, &highSkip)) 158 require.Error(t, highSkipMatch(o, &badHighSkip1)) 159 require.Error(t, highSkipMatch(o, &badHighSkip2)) 160 161 seqno = keybase1.Seqno(10) 162 highSkipSeqno = keybase1.Seqno(5) 163 164 highSkipHash := []byte{0, 6, 2, 42, 123} 165 o = serdeOuterLink(t, tc, seqno, &highSkipSeqno, highSkipHash) 166 highSkip = NewHighSkip(keybase1.Seqno(5), highSkipHash) 167 badHighSkip1 = NewHighSkip(keybase1.Seqno(5), []byte{0, 5, 2}) 168 badHighSkip2 = NewHighSkip(keybase1.Seqno(5), nil) 169 require.NoError(t, highSkipMatch(o, &highSkip)) 170 require.Error(t, highSkipMatch(o, &badHighSkip1)) 171 require.Error(t, highSkipMatch(o, &badHighSkip2)) 172 }