code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/checkpoints_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package sqlstore_test 17 18 import ( 19 "context" 20 "fmt" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/datanode/entities" 25 "code.vegaprotocol.io/vega/datanode/sqlstore" 26 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/require" 29 ) 30 31 func addCheckpoint(t *testing.T, ctx context.Context, ns *sqlstore.Checkpoints, hash, blockHash string, blockHeight int64, block entities.Block, 32 seqNum uint64, 33 ) entities.Checkpoint { 34 t.Helper() 35 c := entities.Checkpoint{ 36 Hash: hash, 37 BlockHash: blockHash, 38 BlockHeight: blockHeight, 39 VegaTime: block.VegaTime, 40 SeqNum: seqNum, 41 } 42 ns.Add(ctx, c) 43 return c 44 } 45 46 func TestCheckpoints(t *testing.T) { 47 ctx := tempTransaction(t) 48 49 checkpointStore := sqlstore.NewCheckpoints(connectionSource) 50 blockStore := sqlstore.NewBlocks(connectionSource) 51 block1 := addTestBlock(t, ctx, blockStore) 52 block2 := addTestBlock(t, ctx, blockStore) 53 54 checkpoint1 := addCheckpoint(t, ctx, checkpointStore, "myHash", "myBlockHash", 1, block1, 0) 55 checkpoint2 := addCheckpoint(t, ctx, checkpointStore, "myOtherHash", "myOtherBlockHash", 2, block2, 0) 56 57 t.Run("GetAll", func(t *testing.T) { 58 expected := []entities.Checkpoint{checkpoint2, checkpoint1} 59 pagination := entities.CursorPagination{NewestFirst: true} 60 actual, _, err := checkpointStore.GetAll(ctx, pagination) 61 require.NoError(t, err) 62 assert.Equal(t, expected, actual) 63 }) 64 } 65 66 func TestCheckpointsSameHashAndBlock(t *testing.T) { 67 ctx := tempTransaction(t) 68 69 checkpointStore := sqlstore.NewCheckpoints(connectionSource) 70 blockStore := sqlstore.NewBlocks(connectionSource) 71 block1 := addTestBlock(t, ctx, blockStore) 72 73 checkpoint1 := addCheckpoint(t, ctx, checkpointStore, "myHash", "myBlockHash", 1, block1, 0) 74 checkpoint2 := addCheckpoint(t, ctx, checkpointStore, "myHash", "myBlockHash", 1, block1, 1) 75 76 t.Run("GetAll", func(t *testing.T) { 77 expected := []entities.Checkpoint{checkpoint1, checkpoint2} 78 pagination := entities.CursorPagination{NewestFirst: true} 79 actual, _, err := checkpointStore.GetAll(ctx, pagination) 80 require.NoError(t, err) 81 assert.Equal(t, expected, actual) 82 }) 83 } 84 85 func TestCheckpointPagination(t *testing.T) { 86 t.Run("should return all checkpoints if no pagination is specified", testCheckpointPaginationNoPagination) 87 t.Run("should return first page of checkpoints if first is provided", testCheckpointPaginationFirst) 88 t.Run("should return last page of checkpoints if last is provided", testCheckpointPaginationLast) 89 t.Run("should return specified page of checkpoints if first and after is specified", testCheckpointPaginationFirstAndAfter) 90 t.Run("should return specified page of checkpoints if last and before is specified", testCheckpointPaginationLastAndBefore) 91 92 t.Run("should return all checkpoints if no pagination is specified - newest first", testCheckpointPaginationNoPaginationNewestFirst) 93 t.Run("should return first page of checkpoints if first is provided - newest first", testCheckpointPaginationFirstNewestFirst) 94 t.Run("should return last page of checkpoints if last is provided - newest first", testCheckpointPaginationLastNewestFirst) 95 t.Run("should return specified page of checkpoints if first and after is specified - newest first", testCheckpointPaginationFirstAndAfterNewestFirst) 96 t.Run("should return specified page of checkpoints if last and before is specified - newest first", testCheckpointPaginationLastAndBeforeNewestFirst) 97 } 98 99 func testCheckpointPaginationNoPagination(t *testing.T) { 100 ctx := tempTransaction(t) 101 102 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 103 104 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, false) 105 require.NoError(t, err) 106 got, pageInfo, err := cs.GetAll(ctx, pagination) 107 require.NoError(t, err) 108 want := checkpoints 109 assert.Equal(t, want, got) 110 assert.Equal(t, entities.PageInfo{ 111 HasNextPage: false, 112 HasPreviousPage: false, 113 StartCursor: checkpoints[0].Cursor().Encode(), 114 EndCursor: checkpoints[9].Cursor().Encode(), 115 }, pageInfo) 116 } 117 118 func testCheckpointPaginationFirst(t *testing.T) { 119 ctx := tempTransaction(t) 120 121 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 122 123 first := int32(3) 124 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, false) 125 require.NoError(t, err) 126 got, pageInfo, err := cs.GetAll(ctx, pagination) 127 require.NoError(t, err) 128 want := checkpoints[:3] 129 assert.Equal(t, want, got) 130 assert.Equal(t, entities.PageInfo{ 131 HasNextPage: true, 132 HasPreviousPage: false, 133 StartCursor: checkpoints[0].Cursor().Encode(), 134 EndCursor: checkpoints[2].Cursor().Encode(), 135 }, pageInfo) 136 } 137 138 func testCheckpointPaginationLast(t *testing.T) { 139 ctx := tempTransaction(t) 140 141 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 142 143 last := int32(3) 144 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, false) 145 require.NoError(t, err) 146 got, pageInfo, err := cs.GetAll(ctx, pagination) 147 require.NoError(t, err) 148 want := checkpoints[7:] 149 assert.Equal(t, want, got) 150 assert.Equal(t, entities.PageInfo{ 151 HasNextPage: false, 152 HasPreviousPage: true, 153 StartCursor: checkpoints[7].Cursor().Encode(), 154 EndCursor: checkpoints[9].Cursor().Encode(), 155 }, pageInfo) 156 } 157 158 func testCheckpointPaginationFirstAndAfter(t *testing.T) { 159 ctx := tempTransaction(t) 160 161 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 162 163 first := int32(3) 164 after := checkpoints[2].Cursor().Encode() 165 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, false) 166 require.NoError(t, err) 167 got, pageInfo, err := cs.GetAll(ctx, pagination) 168 require.NoError(t, err) 169 want := checkpoints[3:6] 170 assert.Equal(t, want, got) 171 assert.Equal(t, entities.PageInfo{ 172 HasNextPage: true, 173 HasPreviousPage: true, 174 StartCursor: checkpoints[3].Cursor().Encode(), 175 EndCursor: checkpoints[5].Cursor().Encode(), 176 }, pageInfo) 177 } 178 179 func testCheckpointPaginationLastAndBefore(t *testing.T) { 180 ctx := tempTransaction(t) 181 182 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 183 184 last := int32(3) 185 before := checkpoints[7].Cursor().Encode() 186 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, false) 187 require.NoError(t, err) 188 got, pageInfo, err := cs.GetAll(ctx, pagination) 189 require.NoError(t, err) 190 want := checkpoints[4:7] 191 assert.Equal(t, want, got) 192 assert.Equal(t, entities.PageInfo{ 193 HasNextPage: true, 194 HasPreviousPage: true, 195 StartCursor: checkpoints[4].Cursor().Encode(), 196 EndCursor: checkpoints[6].Cursor().Encode(), 197 }, pageInfo) 198 } 199 200 func testCheckpointPaginationNoPaginationNewestFirst(t *testing.T) { 201 ctx := tempTransaction(t) 202 203 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 204 checkpoints = entities.ReverseSlice(checkpoints) 205 206 pagination, err := entities.NewCursorPagination(nil, nil, nil, nil, true) 207 require.NoError(t, err) 208 got, pageInfo, err := cs.GetAll(ctx, pagination) 209 require.NoError(t, err) 210 want := checkpoints 211 assert.Equal(t, want, got) 212 assert.Equal(t, entities.PageInfo{ 213 HasNextPage: false, 214 HasPreviousPage: false, 215 StartCursor: checkpoints[0].Cursor().Encode(), 216 EndCursor: checkpoints[9].Cursor().Encode(), 217 }, pageInfo) 218 } 219 220 func testCheckpointPaginationFirstNewestFirst(t *testing.T) { 221 ctx := tempTransaction(t) 222 223 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 224 checkpoints = entities.ReverseSlice(checkpoints) 225 226 first := int32(3) 227 pagination, err := entities.NewCursorPagination(&first, nil, nil, nil, true) 228 require.NoError(t, err) 229 got, pageInfo, err := cs.GetAll(ctx, pagination) 230 require.NoError(t, err) 231 want := checkpoints[:3] 232 assert.Equal(t, want, got) 233 assert.Equal(t, entities.PageInfo{ 234 HasNextPage: true, 235 HasPreviousPage: false, 236 StartCursor: checkpoints[0].Cursor().Encode(), 237 EndCursor: checkpoints[2].Cursor().Encode(), 238 }, pageInfo) 239 } 240 241 func testCheckpointPaginationLastNewestFirst(t *testing.T) { 242 ctx := tempTransaction(t) 243 244 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 245 checkpoints = entities.ReverseSlice(checkpoints) 246 247 last := int32(3) 248 pagination, err := entities.NewCursorPagination(nil, nil, &last, nil, true) 249 require.NoError(t, err) 250 got, pageInfo, err := cs.GetAll(ctx, pagination) 251 require.NoError(t, err) 252 want := checkpoints[7:] 253 assert.Equal(t, want, got) 254 assert.Equal(t, entities.PageInfo{ 255 HasNextPage: false, 256 HasPreviousPage: true, 257 StartCursor: checkpoints[7].Cursor().Encode(), 258 EndCursor: checkpoints[9].Cursor().Encode(), 259 }, pageInfo) 260 } 261 262 func testCheckpointPaginationFirstAndAfterNewestFirst(t *testing.T) { 263 ctx := tempTransaction(t) 264 265 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 266 checkpoints = entities.ReverseSlice(checkpoints) 267 268 first := int32(3) 269 after := checkpoints[2].Cursor().Encode() 270 pagination, err := entities.NewCursorPagination(&first, &after, nil, nil, true) 271 require.NoError(t, err) 272 got, pageInfo, err := cs.GetAll(ctx, pagination) 273 require.NoError(t, err) 274 want := checkpoints[3:6] 275 assert.Equal(t, want, got) 276 assert.Equal(t, entities.PageInfo{ 277 HasNextPage: true, 278 HasPreviousPage: true, 279 StartCursor: checkpoints[3].Cursor().Encode(), 280 EndCursor: checkpoints[5].Cursor().Encode(), 281 }, pageInfo) 282 } 283 284 func testCheckpointPaginationLastAndBeforeNewestFirst(t *testing.T) { 285 ctx := tempTransaction(t) 286 287 cs, checkpoints := setupCheckpointPaginationTest(t, ctx) 288 checkpoints = entities.ReverseSlice(checkpoints) 289 290 last := int32(3) 291 before := checkpoints[7].Cursor().Encode() 292 pagination, err := entities.NewCursorPagination(nil, nil, &last, &before, true) 293 require.NoError(t, err) 294 got, pageInfo, err := cs.GetAll(ctx, pagination) 295 require.NoError(t, err) 296 want := checkpoints[4:7] 297 assert.Equal(t, want, got) 298 assert.Equal(t, entities.PageInfo{ 299 HasNextPage: true, 300 HasPreviousPage: true, 301 StartCursor: checkpoints[4].Cursor().Encode(), 302 EndCursor: checkpoints[6].Cursor().Encode(), 303 }, pageInfo) 304 } 305 306 func setupCheckpointPaginationTest(t *testing.T, ctx context.Context) (*sqlstore.Checkpoints, []entities.Checkpoint) { 307 t.Helper() 308 bs := sqlstore.NewBlocks(connectionSource) 309 cs := sqlstore.NewCheckpoints(connectionSource) 310 blockTime := time.Date(2022, 7, 27, 8, 0, 0, 0, time.Local) 311 checkPoints := make([]entities.Checkpoint, 10) 312 313 for i := 0; i < 10; i++ { 314 blockTime = blockTime.Add(time.Minute) 315 block := addTestBlockForTime(t, ctx, bs, blockTime) 316 hash := int64(i + 1) 317 checkPoints[i] = addCheckpoint(t, ctx, cs, fmt.Sprintf("TestHash%02d", hash), fmt.Sprintf("TestBlockHash%02d", hash), hash, block, uint64(i)) 318 } 319 320 return cs, checkPoints 321 }