github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/zedtoken/zedtoken_test.go (about) 1 package zedtoken 2 3 import ( 4 "fmt" 5 "testing" 6 7 v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" 8 "github.com/shopspring/decimal" 9 "github.com/stretchr/testify/require" 10 11 "github.com/authzed/spicedb/internal/datastore/revisions" 12 "github.com/authzed/spicedb/pkg/datastore" 13 ) 14 15 var encodeRevisionTests = []datastore.Revision{ 16 revisions.NewForTransactionID(1), 17 revisions.NewForTransactionID(2), 18 revisions.NewForTransactionID(4), 19 revisions.NewForTransactionID(8), 20 revisions.NewForTransactionID(16), 21 revisions.NewForTransactionID(128), 22 revisions.NewForTransactionID(256), 23 revisions.NewForTransactionID(1621538189028928000), 24 } 25 26 func mustHLC(str string) datastore.Revision { 27 rev, err := revisions.HLCRevisionFromString(str) 28 if err != nil { 29 panic(err) 30 } 31 return rev 32 } 33 34 var encodeHLCRevisionTests = []datastore.Revision{ 35 mustHLC("1235"), 36 mustHLC("1234.0000000001"), 37 } 38 39 func TestZedTokenEncode(t *testing.T) { 40 for _, rev := range encodeRevisionTests { 41 rev := rev 42 t.Run(rev.String(), func(t *testing.T) { 43 require := require.New(t) 44 encoded, err := NewFromRevision(rev) 45 require.NoError(err) 46 47 decoded, err := DecodeRevision(encoded, revisions.CommonDecoder{ 48 Kind: revisions.TransactionID, 49 }) 50 require.NoError(err) 51 require.True(rev.Equal(decoded)) 52 }) 53 } 54 } 55 56 func TestZedTokenEncodeHLC(t *testing.T) { 57 for _, rev := range encodeHLCRevisionTests { 58 rev := rev 59 t.Run(rev.String(), func(t *testing.T) { 60 require := require.New(t) 61 encoded, err := NewFromRevision(rev) 62 require.NoError(err) 63 64 decoded, err := DecodeRevision(encoded, revisions.CommonDecoder{ 65 Kind: revisions.HybridLogicalClock, 66 }) 67 require.NoError(err) 68 require.True(rev.Equal(decoded)) 69 }) 70 } 71 } 72 73 var decodeTests = []struct { 74 format string 75 token string 76 expectedRevision datastore.Revision 77 expectError bool 78 }{ 79 { 80 format: "invalid", 81 token: "abc", 82 expectedRevision: datastore.NoRevision, 83 expectError: true, 84 }, 85 { 86 format: "V1 Zookie", 87 token: "CAESAA==", 88 expectedRevision: revisions.NewForTransactionID(0), 89 expectError: false, 90 }, 91 { 92 format: "V1 Zookie", 93 token: "CAESAggB", 94 expectedRevision: revisions.NewForTransactionID(1), 95 expectError: false, 96 }, 97 { 98 format: "V1 Zookie", 99 token: "CAESAggC", 100 expectedRevision: revisions.NewForTransactionID(2), 101 expectError: false, 102 }, 103 { 104 format: "V1 Zookie", 105 token: "CAESAwiAAg==", 106 expectedRevision: revisions.NewForTransactionID(256), 107 expectError: false, 108 }, 109 { 110 format: "V1 Zookie", 111 token: "CAIaAwoBMA==", 112 expectedRevision: revisions.NewForTransactionID(0), 113 expectError: false, 114 }, 115 { 116 format: "V1 ZedToken", 117 token: "CAIaAwoBMQ==", 118 expectedRevision: revisions.NewForTransactionID(1), 119 expectError: false, 120 }, 121 { 122 format: "V1 ZedToken", 123 token: "CAIaAwoBMg==", 124 expectedRevision: revisions.NewForTransactionID(2), 125 expectError: false, 126 }, 127 { 128 format: "V1 ZedToken", 129 token: "CAIaAwoBNA==", 130 expectedRevision: revisions.NewForTransactionID(4), 131 expectError: false, 132 }, 133 } 134 135 func TestDecode(t *testing.T) { 136 for _, testCase := range decodeTests { 137 testCase := testCase 138 testName := fmt.Sprintf("%s(%s)=>%s", testCase.format, testCase.token, testCase.expectedRevision) 139 t.Run(testName, func(t *testing.T) { 140 require := require.New(t) 141 142 decoded, err := DecodeRevision(&v1.ZedToken{ 143 Token: testCase.token, 144 }, revisions.CommonDecoder{ 145 Kind: revisions.TransactionID, 146 }) 147 if testCase.expectError { 148 require.Error(err) 149 } else { 150 require.NoError(err) 151 require.True( 152 testCase.expectedRevision.Equal(decoded), 153 "%s != %s", 154 testCase.expectedRevision, 155 decoded, 156 ) 157 } 158 }) 159 } 160 } 161 162 var hlcDecodeTests = []struct { 163 format string 164 token string 165 expectedRevision datastore.Revision 166 expectError bool 167 }{ 168 { 169 format: "V1 ZedToken", 170 token: "CAIaFQoTMTYyMTUzODE4OTAyODkyODAwMA==", 171 expectedRevision: func() datastore.Revision { 172 r, err := revisions.NewForHLC(decimal.NewFromInt(1621538189028928000)) 173 if err != nil { 174 panic(err) 175 } 176 return r 177 }(), 178 expectError: false, 179 }, 180 { 181 format: "V1 ZedToken", 182 token: "GiAKHjE2OTM1NDA5NDAzNzMwNDU3MjcuMDAwMDAwMDAwMQ==", 183 expectedRevision: (func() datastore.Revision { 184 v, err := decimal.NewFromString("1693540940373045727.0000000001") 185 if err != nil { 186 panic(err) 187 } 188 189 r, err := revisions.NewForHLC(v) 190 if err != nil { 191 panic(err) 192 } 193 194 return r 195 })(), 196 expectError: false, 197 }, 198 } 199 200 func TestHLCDecode(t *testing.T) { 201 for _, testCase := range hlcDecodeTests { 202 testCase := testCase 203 testName := fmt.Sprintf("%s(%s)=>%s", testCase.format, testCase.token, testCase.expectedRevision) 204 t.Run(testName, func(t *testing.T) { 205 require := require.New(t) 206 207 decoded, err := DecodeRevision(&v1.ZedToken{ 208 Token: testCase.token, 209 }, revisions.CommonDecoder{ 210 Kind: revisions.HybridLogicalClock, 211 }) 212 if testCase.expectError { 213 require.Error(err) 214 } else { 215 require.NoError(err) 216 require.True( 217 testCase.expectedRevision.Equal(decoded), 218 "%s != %s", 219 testCase.expectedRevision, 220 decoded, 221 ) 222 } 223 }) 224 } 225 }