github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/protocol/api_test.go (about) 1 package protocol 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/suite" 8 9 protocol "github.com/onflow/flow-go/state/protocol/mock" 10 "github.com/onflow/flow-go/storage" 11 storagemock "github.com/onflow/flow-go/storage/mock" 12 "github.com/onflow/flow-go/utils/unittest" 13 14 "google.golang.org/grpc/codes" 15 "google.golang.org/grpc/status" 16 ) 17 18 var CodesNotFoundErr = status.Errorf(codes.NotFound, "not found") 19 var StorageNotFoundErr = status.Errorf(codes.NotFound, "not found: %v", storage.ErrNotFound) 20 var InternalErr = status.Errorf(codes.Internal, "internal") 21 var OutputInternalErr = status.Errorf(codes.Internal, "failed to find: %v", status.Errorf(codes.Internal, "internal")) 22 23 type Suite struct { 24 suite.Suite 25 26 state *protocol.State 27 blocks *storagemock.Blocks 28 headers *storagemock.Headers 29 executionResults *storagemock.ExecutionResults 30 snapshot *protocol.Snapshot 31 } 32 33 func TestHandler(t *testing.T) { 34 suite.Run(t, new(Suite)) 35 } 36 37 func (suite *Suite) SetupTest() { 38 suite.snapshot = new(protocol.Snapshot) 39 40 suite.state = new(protocol.State) 41 suite.blocks = new(storagemock.Blocks) 42 suite.headers = new(storagemock.Headers) 43 suite.executionResults = new(storagemock.ExecutionResults) 44 } 45 46 func (suite *Suite) TestGetLatestFinalizedBlock_Success() { 47 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 48 49 // setup the mocks 50 block := unittest.BlockFixture() 51 header := block.Header 52 53 suite.snapshot. 54 On("Head"). 55 Return(header, nil). 56 Once() 57 58 suite.blocks. 59 On("ByID", header.ID()). 60 Return(&block, nil). 61 Once() 62 63 backend := New(suite.state, suite.blocks, suite.headers, nil) 64 65 // query the handler for the latest finalized block 66 responseBlock, err := backend.GetLatestBlock(context.Background(), false) 67 suite.checkResponse(responseBlock, err) 68 69 // make sure we got the latest block 70 suite.Require().Equal(block, *responseBlock) 71 72 suite.assertAllExpectations() 73 } 74 75 func (suite *Suite) TestGetLatestSealedBlock_Success() { 76 suite.state.On("Sealed").Return(suite.snapshot, nil).Maybe() 77 78 // setup the mocks 79 block := unittest.BlockFixture() 80 header := block.Header 81 82 suite.snapshot. 83 On("Head"). 84 Return(header, nil). 85 Once() 86 87 suite.blocks. 88 On("ByID", header.ID()). 89 Return(&block, nil). 90 Once() 91 92 backend := New(suite.state, suite.blocks, suite.headers, nil) 93 94 // query the handler for the latest finalized block 95 responseBlock, err := backend.GetLatestBlock(context.Background(), true) 96 suite.checkResponse(responseBlock, err) 97 98 // make sure we got the latest block 99 suite.Require().Equal(block, *responseBlock) 100 101 suite.assertAllExpectations() 102 } 103 104 func (suite *Suite) TestGetLatestBlock_StorageNotFoundFailure() { 105 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 106 107 // setup the mocks 108 block := unittest.BlockFixture() 109 header := block.Header 110 111 suite.snapshot. 112 On("Head"). 113 Return(header, storage.ErrNotFound). 114 Once() 115 116 backend := New(suite.state, suite.blocks, suite.headers, nil) 117 118 // query the handler for the latest finalized block 119 _, err := backend.GetLatestBlock(context.Background(), false) 120 suite.Require().Error(err) 121 suite.Require().ErrorIs(err, StorageNotFoundErr) 122 123 suite.assertAllExpectations() 124 } 125 126 func (suite *Suite) TestGetLatestBlock_CodesNotFoundFailure() { 127 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 128 129 // setup the mocks 130 block := unittest.BlockFixture() 131 header := block.Header 132 133 suite.snapshot. 134 On("Head"). 135 Return(header, CodesNotFoundErr). 136 Once() 137 138 backend := New(suite.state, suite.blocks, suite.headers, nil) 139 140 // query the handler for the latest finalized block 141 _, err := backend.GetLatestBlock(context.Background(), false) 142 suite.Require().Error(err) 143 suite.Require().ErrorIs(err, CodesNotFoundErr) 144 145 suite.assertAllExpectations() 146 } 147 148 func (suite *Suite) TestGetLatestBlock_InternalFailure() { 149 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 150 151 // setup the mocks 152 block := unittest.BlockFixture() 153 header := block.Header 154 155 suite.snapshot. 156 On("Head"). 157 Return(header, InternalErr). 158 Once() 159 160 backend := New(suite.state, suite.blocks, suite.headers, nil) 161 162 // query the handler for the latest finalized block 163 _, err := backend.GetLatestBlock(context.Background(), false) 164 suite.Require().Error(err) 165 suite.Require().ErrorIs(err, OutputInternalErr) 166 167 suite.assertAllExpectations() 168 } 169 170 func (suite *Suite) TestGetBlockById_Success() { 171 // setup the mocks 172 block := unittest.BlockFixture() 173 174 suite.blocks. 175 On("ByID", block.ID()). 176 Return(&block, nil). 177 Once() 178 179 backend := New(suite.state, suite.blocks, suite.headers, nil) 180 181 // query the handler for the latest sealed block 182 responseBlock, err := backend.GetBlockByID(context.Background(), block.ID()) 183 suite.checkResponse(responseBlock, err) 184 185 // make sure we got the latest block 186 suite.Require().Equal(block.ID(), responseBlock.ID()) 187 188 suite.assertAllExpectations() 189 } 190 191 func (suite *Suite) TestGetBlockById_StorageNotFoundFailure() { 192 // setup the mocks 193 block := unittest.BlockFixture() 194 195 suite.blocks. 196 On("ByID", block.ID()). 197 Return(&block, storage.ErrNotFound). 198 Once() 199 200 backend := New(suite.state, suite.blocks, suite.headers, nil) 201 202 // query the handler for the latest block 203 _, err := backend.GetBlockByID(context.Background(), block.ID()) 204 suite.Require().Error(err) 205 suite.Require().ErrorIs(err, StorageNotFoundErr) 206 207 suite.assertAllExpectations() 208 } 209 210 func (suite *Suite) TestGetBlockById_CodesNotFoundFailure() { 211 // setup the mocks 212 block := unittest.BlockFixture() 213 214 suite.blocks. 215 On("ByID", block.ID()). 216 Return(&block, CodesNotFoundErr). 217 Once() 218 219 backend := New(suite.state, suite.blocks, suite.headers, nil) 220 221 // query the handler for the latest block 222 _, err := backend.GetBlockByID(context.Background(), block.ID()) 223 suite.Require().Error(err) 224 suite.Require().ErrorIs(err, CodesNotFoundErr) 225 226 suite.assertAllExpectations() 227 } 228 229 func (suite *Suite) TestGetBlockById_InternalFailure() { 230 // setup the mocks 231 block := unittest.BlockFixture() 232 233 suite.blocks. 234 On("ByID", block.ID()). 235 Return(&block, InternalErr). 236 Once() 237 238 backend := New(suite.state, suite.blocks, suite.headers, nil) 239 240 // query the handler for the latest block 241 _, err := backend.GetBlockByID(context.Background(), block.ID()) 242 suite.Require().Error(err) 243 suite.Require().ErrorIs(err, OutputInternalErr) 244 245 suite.assertAllExpectations() 246 } 247 248 func (suite *Suite) TestGetBlockByHeight_Success() { 249 // setup the mocks 250 block := unittest.BlockFixture() 251 height := block.Header.Height 252 253 suite.blocks. 254 On("ByHeight", height). 255 Return(&block, nil). 256 Once() 257 258 backend := New(suite.state, suite.blocks, suite.headers, nil) 259 260 // query the handler for the latest block 261 responseBlock, err := backend.GetBlockByHeight(context.Background(), height) 262 suite.checkResponse(responseBlock, err) 263 264 // make sure we got the latest block 265 suite.Require().Equal(block.ID(), responseBlock.ID()) 266 267 suite.assertAllExpectations() 268 } 269 270 func (suite *Suite) TestGetBlockByHeight_StorageNotFoundFailure() { 271 // setup the mocks 272 block := unittest.BlockFixture() 273 height := block.Header.Height 274 275 suite.blocks. 276 On("ByHeight", height). 277 Return(&block, StorageNotFoundErr). 278 Once() 279 280 backend := New(suite.state, suite.blocks, suite.headers, nil) 281 282 // query the handler for the latest block 283 _, err := backend.GetBlockByHeight(context.Background(), height) 284 suite.Require().Error(err) 285 suite.Require().ErrorIs(err, StorageNotFoundErr) 286 287 suite.assertAllExpectations() 288 } 289 290 func (suite *Suite) TestGetBlockByHeight_CodesNotFoundFailure() { 291 // setup the mocks 292 block := unittest.BlockFixture() 293 height := block.Header.Height 294 295 suite.blocks. 296 On("ByHeight", height). 297 Return(&block, CodesNotFoundErr). 298 Once() 299 300 backend := New(suite.state, suite.blocks, suite.headers, nil) 301 302 // query the handler for the latest block 303 _, err := backend.GetBlockByHeight(context.Background(), height) 304 suite.Require().Error(err) 305 suite.Require().ErrorIs(err, CodesNotFoundErr) 306 307 suite.assertAllExpectations() 308 } 309 310 func (suite *Suite) TestGetBlockByHeight_InternalFailure() { 311 // setup the mocks 312 block := unittest.BlockFixture() 313 height := block.Header.Height 314 315 suite.blocks. 316 On("ByHeight", height). 317 Return(&block, InternalErr). 318 Once() 319 320 backend := New(suite.state, suite.blocks, suite.headers, nil) 321 322 // query the handler for the latest block 323 _, err := backend.GetBlockByHeight(context.Background(), height) 324 suite.Require().Error(err) 325 suite.Require().ErrorIs(err, OutputInternalErr) 326 327 suite.assertAllExpectations() 328 } 329 330 func (suite *Suite) TestGetLatestFinalizedBlockHeader_Success() { 331 // setup the mocks 332 blockHeader := unittest.BlockHeaderFixture() 333 334 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 335 suite.snapshot.On("Head").Return(blockHeader, nil).Once() 336 337 backend := New(suite.state, suite.blocks, suite.headers, nil) 338 339 // query the handler for the latest finalized block 340 responseBlockHeader, err := backend.GetLatestBlockHeader(context.Background(), false) 341 suite.checkResponse(responseBlockHeader, err) 342 343 // make sure we got the latest finalized block 344 suite.Require().Equal(blockHeader.ID(), responseBlockHeader.ID()) 345 suite.Require().Equal(blockHeader.Height, responseBlockHeader.Height) 346 suite.Require().Equal(blockHeader.ParentID, responseBlockHeader.ParentID) 347 348 suite.assertAllExpectations() 349 } 350 351 func (suite *Suite) TestGetLatestSealedBlockHeader_Success() { 352 // setup the mocks 353 blockHeader := unittest.BlockHeaderFixture() 354 355 suite.state.On("Sealed").Return(suite.snapshot, nil).Maybe() 356 suite.snapshot.On("Head").Return(blockHeader, nil).Once() 357 358 backend := New(suite.state, suite.blocks, suite.headers, nil) 359 360 // query the handler for the latest sealed block 361 responseBlockHeader, err := backend.GetLatestBlockHeader(context.Background(), true) 362 suite.checkResponse(responseBlockHeader, err) 363 364 // make sure we got the latest sealed block 365 suite.Require().Equal(blockHeader.ID(), responseBlockHeader.ID()) 366 suite.Require().Equal(blockHeader.Height, responseBlockHeader.Height) 367 suite.Require().Equal(blockHeader.ParentID, responseBlockHeader.ParentID) 368 369 suite.assertAllExpectations() 370 } 371 372 func (suite *Suite) TestGetLatestBlockHeader_StorageNotFoundFailure() { 373 // setup the mocks 374 blockHeader := unittest.BlockHeaderFixture() 375 376 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 377 suite.snapshot.On("Head").Return(blockHeader, storage.ErrNotFound).Once() 378 379 backend := New(suite.state, suite.blocks, suite.headers, nil) 380 381 // query the handler for the latest block 382 _, err := backend.GetLatestBlockHeader(context.Background(), false) 383 suite.Require().Error(err) 384 suite.Require().ErrorIs(err, StorageNotFoundErr) 385 386 suite.assertAllExpectations() 387 } 388 389 func (suite *Suite) TestGetLatestBlockHeader_CodesNotFoundFailure() { 390 // setup the mocks 391 blockHeader := unittest.BlockHeaderFixture() 392 393 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 394 suite.snapshot.On("Head").Return(blockHeader, CodesNotFoundErr).Once() 395 396 backend := New(suite.state, suite.blocks, suite.headers, nil) 397 398 // query the handler for the latest block 399 _, err := backend.GetLatestBlockHeader(context.Background(), false) 400 suite.Require().Error(err) 401 suite.Require().ErrorIs(err, CodesNotFoundErr) 402 403 suite.assertAllExpectations() 404 } 405 406 func (suite *Suite) TestGetLatestBlockHeader_InternalFailure() { 407 // setup the mocks 408 blockHeader := unittest.BlockHeaderFixture() 409 410 suite.state.On("Final").Return(suite.snapshot, nil).Maybe() 411 suite.snapshot.On("Head").Return(blockHeader, InternalErr).Once() 412 413 backend := New(suite.state, suite.blocks, suite.headers, nil) 414 415 // query the handler for the latest block 416 _, err := backend.GetLatestBlockHeader(context.Background(), false) 417 suite.Require().Error(err) 418 suite.Require().ErrorIs(err, OutputInternalErr) 419 420 suite.assertAllExpectations() 421 } 422 423 func (suite *Suite) TestGetBlockHeaderByID_Success() { 424 // setup the mocks 425 block := unittest.BlockFixture() 426 header := block.Header 427 428 suite.headers. 429 On("ByBlockID", block.ID()). 430 Return(header, nil). 431 Once() 432 433 backend := New(suite.state, suite.blocks, suite.headers, nil) 434 435 // query the handler for the latest block 436 responseBlockHeader, err := backend.GetBlockHeaderByID(context.Background(), block.ID()) 437 438 suite.checkResponse(responseBlockHeader, err) 439 440 // make sure we got the latest block 441 suite.Require().Equal(header.ID(), responseBlockHeader.ID()) 442 suite.Require().Equal(header.Height, responseBlockHeader.Height) 443 suite.Require().Equal(header.ParentID, responseBlockHeader.ParentID) 444 445 suite.assertAllExpectations() 446 } 447 448 func (suite *Suite) TestGetBlockHeaderByID_StorageNotFoundFailure() { 449 // setup the mocks 450 block := unittest.BlockFixture() 451 header := block.Header 452 453 suite.headers. 454 On("ByBlockID", block.ID()). 455 Return(header, StorageNotFoundErr). 456 Once() 457 458 backend := New(suite.state, suite.blocks, suite.headers, nil) 459 460 // query the handler for the block header 461 _, err := backend.GetBlockHeaderByID(context.Background(), block.ID()) 462 suite.Require().Error(err) 463 suite.Require().ErrorIs(err, StorageNotFoundErr) 464 465 suite.assertAllExpectations() 466 } 467 468 func (suite *Suite) TestGetBlockHeaderByID_CodesNotFoundFailure() { 469 // setup the mocks 470 block := unittest.BlockFixture() 471 header := block.Header 472 473 suite.headers. 474 On("ByBlockID", block.ID()). 475 Return(header, CodesNotFoundErr). 476 Once() 477 478 backend := New(suite.state, suite.blocks, suite.headers, nil) 479 480 // query the handler for the block header 481 _, err := backend.GetBlockHeaderByID(context.Background(), block.ID()) 482 suite.Require().Error(err) 483 suite.Require().ErrorIs(err, CodesNotFoundErr) 484 485 suite.assertAllExpectations() 486 } 487 488 func (suite *Suite) TestGetBlockHeaderByID_InternalFailure() { 489 // setup the mocks 490 block := unittest.BlockFixture() 491 header := block.Header 492 493 suite.headers. 494 On("ByBlockID", block.ID()). 495 Return(header, InternalErr). 496 Once() 497 498 backend := New(suite.state, suite.blocks, suite.headers, nil) 499 500 // query the handler for the block header 501 _, err := backend.GetBlockHeaderByID(context.Background(), block.ID()) 502 suite.Require().Error(err) 503 suite.Require().ErrorIs(err, OutputInternalErr) 504 505 suite.assertAllExpectations() 506 } 507 508 func (suite *Suite) TestGetBlockHeaderByHeight_Success() { 509 // setup the mocks 510 blockHeader := unittest.BlockHeaderFixture() 511 headerHeight := blockHeader.Height 512 513 suite.headers. 514 On("ByHeight", headerHeight). 515 Return(blockHeader, nil). 516 Once() 517 518 backend := New(suite.state, suite.blocks, suite.headers, nil) 519 520 // query the handler for the block header 521 responseBlockHeader, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight) 522 523 suite.checkResponse(responseBlockHeader, err) 524 525 // make sure we got the block header 526 suite.Require().Equal(blockHeader.Height, responseBlockHeader.Height) 527 suite.Require().Equal(blockHeader.ParentID, responseBlockHeader.ParentID) 528 529 suite.assertAllExpectations() 530 } 531 532 func (suite *Suite) TestGetBlockHeaderByHeight_StorageNotFoundFailure() { 533 // setup the mocks 534 blockHeader := unittest.BlockHeaderFixture() 535 headerHeight := blockHeader.Height 536 537 suite.headers. 538 On("ByHeight", headerHeight). 539 Return(blockHeader, StorageNotFoundErr). 540 Once() 541 542 backend := New(suite.state, suite.blocks, suite.headers, nil) 543 544 // query the handler for the block header 545 _, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight) 546 suite.Require().Error(err) 547 suite.Require().ErrorIs(err, StorageNotFoundErr) 548 549 suite.assertAllExpectations() 550 } 551 552 func (suite *Suite) TestGetBlockHeaderByHeight_CodesNotFoundFailure() { 553 // setup the mocks 554 blockHeader := unittest.BlockHeaderFixture() 555 headerHeight := blockHeader.Height 556 557 suite.headers. 558 On("ByHeight", headerHeight). 559 Return(blockHeader, CodesNotFoundErr). 560 Once() 561 562 backend := New(suite.state, suite.blocks, suite.headers, nil) 563 564 // query the handler for the block header 565 _, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight) 566 suite.Require().Error(err) 567 suite.Require().ErrorIs(err, CodesNotFoundErr) 568 569 suite.assertAllExpectations() 570 } 571 572 func (suite *Suite) TestGetBlockHeaderByHeight_InternalFailure() { 573 // setup the mocks 574 blockHeader := unittest.BlockHeaderFixture() 575 headerHeight := blockHeader.Height 576 577 suite.headers. 578 On("ByHeight", headerHeight). 579 Return(blockHeader, InternalErr). 580 Once() 581 582 backend := New(suite.state, suite.blocks, suite.headers, nil) 583 584 // query the handler for the block header 585 _, err := backend.GetBlockHeaderByHeight(context.Background(), headerHeight) 586 suite.Require().Error(err) 587 suite.Require().ErrorIs(err, OutputInternalErr) 588 589 suite.assertAllExpectations() 590 } 591 592 func (suite *Suite) checkResponse(resp interface{}, err error) { 593 suite.Require().NoError(err) 594 suite.Require().NotNil(resp) 595 } 596 597 func (suite *Suite) assertAllExpectations() { 598 suite.snapshot.AssertExpectations(suite.T()) 599 suite.state.AssertExpectations(suite.T()) 600 suite.blocks.AssertExpectations(suite.T()) 601 suite.headers.AssertExpectations(suite.T()) 602 suite.executionResults.AssertExpectations(suite.T()) 603 }