github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/access/rest/routes/execution_result_test.go (about) 1 package routes 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "strings" 8 "testing" 9 10 "google.golang.org/grpc/codes" 11 "google.golang.org/grpc/status" 12 13 mocks "github.com/stretchr/testify/mock" 14 15 "github.com/onflow/flow-go/access/mock" 16 "github.com/onflow/flow-go/engine/access/rest/util" 17 "github.com/onflow/flow-go/model/flow" 18 "github.com/onflow/flow-go/utils/unittest" 19 ) 20 21 func getResultByIDReq(id string, blockIDs []string) *http.Request { 22 endpoint := "/v1/execution_results" 23 24 var u string 25 if id != "" { 26 u = fmt.Sprintf("%s/%s", endpoint, id) 27 } else if len(blockIDs) > 0 { 28 p, _ := url.Parse(endpoint) 29 q := p.Query() 30 q.Add("block_id", strings.Join(blockIDs, ",")) 31 p.RawQuery = q.Encode() 32 u = p.String() 33 } 34 35 req, _ := http.NewRequest("GET", u, nil) 36 return req 37 } 38 39 func TestGetResultByID(t *testing.T) { 40 t.Run("get by ID", func(t *testing.T) { 41 backend := &mock.API{} 42 result := unittest.ExecutionResultFixture() 43 id := unittest.IdentifierFixture() 44 backend.Mock. 45 On("GetExecutionResultByID", mocks.Anything, id). 46 Return(result, nil). 47 Once() 48 req := getResultByIDReq(id.String(), nil) 49 50 expected := executionResultExpectedStr(result) 51 assertOKResponse(t, req, expected, backend) 52 mocks.AssertExpectationsForObjects(t, backend) 53 }) 54 55 t.Run("get by ID not found", func(t *testing.T) { 56 backend := &mock.API{} 57 id := unittest.IdentifierFixture() 58 backend.Mock. 59 On("GetExecutionResultByID", mocks.Anything, id). 60 Return(nil, status.Error(codes.NotFound, "block not found")). 61 Once() 62 63 req := getResultByIDReq(id.String(), nil) 64 assertResponse(t, req, http.StatusNotFound, `{"code":404,"message":"Flow resource not found: block not found"}`, backend) 65 mocks.AssertExpectationsForObjects(t, backend) 66 }) 67 } 68 69 func TestGetResultBlockID(t *testing.T) { 70 71 t.Run("get by block ID", func(t *testing.T) { 72 backend := &mock.API{} 73 blockID := unittest.IdentifierFixture() 74 result := unittest.ExecutionResultFixture(unittest.WithExecutionResultBlockID(blockID)) 75 76 backend.Mock. 77 On("GetExecutionResultForBlockID", mocks.Anything, blockID). 78 Return(result, nil). 79 Once() 80 81 req := getResultByIDReq("", []string{blockID.String()}) 82 83 expected := fmt.Sprintf(`[%s]`, executionResultExpectedStr(result)) 84 assertOKResponse(t, req, expected, backend) 85 mocks.AssertExpectationsForObjects(t, backend) 86 }) 87 88 t.Run("get by block ID not found", func(t *testing.T) { 89 backend := &mock.API{} 90 blockID := unittest.IdentifierFixture() 91 backend.Mock. 92 On("GetExecutionResultForBlockID", mocks.Anything, blockID). 93 Return(nil, status.Error(codes.NotFound, "block not found")). 94 Once() 95 96 req := getResultByIDReq("", []string{blockID.String()}) 97 assertResponse(t, req, http.StatusNotFound, `{"code":404,"message":"Flow resource not found: block not found"}`, backend) 98 mocks.AssertExpectationsForObjects(t, backend) 99 }) 100 } 101 102 func executionResultExpectedStr(result *flow.ExecutionResult) string { 103 chunks := make([]string, len(result.Chunks)) 104 for i, chunk := range result.Chunks { 105 chunks[i] = fmt.Sprintf(`{ 106 "block_id": "%s", 107 "collection_index": "%d", 108 "start_state": "%s", 109 "end_state": "%s", 110 "number_of_transactions": "%d", 111 "event_collection": "%s", 112 "index": "%d", 113 "total_computation_used": "%d" 114 }`, chunk.BlockID, chunk.CollectionIndex, util.ToBase64(chunk.StartState[:]), util.ToBase64(chunk.EndState[:]), 115 chunk.NumberOfTransactions, chunk.EventCollection.String(), chunk.Index, chunk.TotalComputationUsed) 116 } 117 chunksStr := fmt.Sprintf("[%s]", strings.Join(chunks, ",")) 118 expected := fmt.Sprintf(`{ 119 "id": "%s", 120 "block_id": "%s", 121 "events": [], 122 "chunks": %s, 123 "previous_result_id": "%s", 124 "_links": { 125 "_self": "/v1/execution_results/%s" 126 } 127 }`, result.ID(), result.BlockID, chunksStr, result.PreviousResultID.String(), result.ID()) 128 return expected 129 }