github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/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  }