From a8024050651f96482a2d677db66f0aae6572fde3 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Wed, 27 Sep 2023 00:12:52 +0300 Subject: [PATCH 01/21] add headers support --- api/openapi/api.yaml | 36 +++++++++++++++ example/simple/client/main.go | 23 ++++++++++ example/simple/stub/simple3.yaml | 13 ++++++ internal/app/rest_server.go | 1 + internal/app/storage.go | 79 +++++++++++++++++++++++++------- internal/domain/rest/api.gen.go | 41 +++++++++++------ pkg/sdk/api.gen.go | 41 +++++++++++------ pkg/storage/stubs.go | 48 +++++++++++++------ protoc-gen-gripmock/server.tmpl | 31 ++++++++++--- 9 files changed, 247 insertions(+), 66 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 51de3302..a12c9d8b 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -198,6 +198,11 @@ components: method: type: string example: SayHello + headers: + type: object + additionalProperties: + type: string + x-go-type-skip-optional-pointer: true data: type: object x-go-type: interface{} @@ -208,6 +213,11 @@ components: - data - error properties: + headers: + type: object + additionalProperties: + type: string + x-go-type-skip-optional-pointer: true data: type: object x-go-type: interface{} @@ -239,6 +249,8 @@ components: method: type: string example: SayHello + headers: + $ref: '#/components/schemas/StubHeaders' input: $ref: '#/components/schemas/StubInput' output: @@ -258,6 +270,25 @@ components: type: object additionalProperties: true x-go-type-skip-optional-pointer: true + StubHeaders: + type: object + x-go-type-skip-optional-pointer: true + properties: + equals: + type: object + additionalProperties: + type: string + x-go-type-skip-optional-pointer: true + contains: + type: object + additionalProperties: + type: string + x-go-type-skip-optional-pointer: true + matches: + type: object + additionalProperties: + type: string + x-go-type-skip-optional-pointer: true StubOutput: type: object required: @@ -267,6 +298,11 @@ components: data: type: object additionalProperties: true + headers: + type: object + additionalProperties: + type: string + x-go-type-skip-optional-pointer: true error: type: string example: Message not found diff --git a/example/simple/client/main.go b/example/simple/client/main.go index 88dd9165..8456d818 100644 --- a/example/simple/client/main.go +++ b/example/simple/client/main.go @@ -10,6 +10,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/encoding/gzip" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" pb "github.com/bavix/gripmock/protogen/example/simple" @@ -73,6 +74,28 @@ func main() { } log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) + md := metadata.New(map[string]string{"Authorization": "Basic dXNlcjp1c2Vy"}) + ctx = metadata.NewOutgoingContext(context.Background(), md) + + var headers metadata.MD + + name = "simple3" + r, err = c.SayHello(ctx, &pb.Request{Name: name}, grpc.Header(&headers)) + if err != nil { + log.Fatalf("error from grpc: %v", err) + } + if r.ReturnCode != 0 { + log.Fatalf("grpc server returned code: %d, expected code: %d", r.ReturnCode, 0) + } + header := headers["result"] + if len(header) == 0 { + log.Fatal("the service did not return headers") + } + if header[0] != "ok" { + log.Fatal("the service returned an incorrect header") + } + log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) + name = "simple3" r, err = c.SayHello(context.Background(), &pb.Request{Name: name}, grpc.UseCompressor(gzip.Name)) if err != nil { diff --git a/example/simple/stub/simple3.yaml b/example/simple/stub/simple3.yaml index df2356d8..dd9e36a1 100644 --- a/example/simple/stub/simple3.yaml +++ b/example/simple/stub/simple3.yaml @@ -7,3 +7,16 @@ data: message: Hello Simple3 return_code: 3 +- service: Gripmock + method: SayHello + headers: + contains: + authorization: Basic dXNlcjp1c2Vy # user:user + input: + equals: + name: simple3 + output: + data: + message: Authorization OK + headers: + result: ok diff --git a/internal/app/rest_server.go b/internal/app/rest_server.go index a8a96c78..d22eb9b9 100644 --- a/internal/app/rest_server.go +++ b/internal/app/rest_server.go @@ -52,6 +52,7 @@ type findStubPayload struct { ID *uuid.UUID `json:"id,omitempty"` Service string `json:"service"` Method string `json:"method"` + Headers map[string]interface{} `json:"headers"` Data map[string]interface{} `json:"data"` } diff --git a/internal/app/storage.go b/internal/app/storage.go index 61c52321..93e70467 100644 --- a/internal/app/storage.go +++ b/internal/app/storage.go @@ -13,11 +13,15 @@ import ( "github.com/bavix/gripmock/pkg/storage" ) +var ErrNotFound = errors.New("not found") + type matchFunc func(interface{}, interface{}) bool type closeMatch struct { - rule string - expect map[string]interface{} + rule string + expect map[string]interface{} + headerRule string + headerExpect map[string]interface{} } func findStub(stubStorage *storage.StubStorage, stub *findStubPayload) (*storage.Output, error) { @@ -41,36 +45,79 @@ func findStub(stubStorage *storage.StubStorage, stub *findStubPayload) (*storage } if stub.ID != nil { + stubStorage.MarkUsed(stubs[0].ID) + return &stubs[0].Output, nil } var closestMatch []closeMatch for _, strange := range stubs { - if expect := strange.Input.Equals; expect != nil { - closestMatch = append(closestMatch, closeMatch{"equals", expect}) - if equals(stub.Data, expect) { - return &strange.Output, nil + cmpData, cmpDataErr := inputCmp(strange.Input, stub.Data) + if cmpDataErr != nil { + if cmpData != nil { + closestMatch = append(closestMatch, *cmpData) } - } - if expect := strange.Input.Contains; expect != nil { - closestMatch = append(closestMatch, closeMatch{"contains", expect}) - if contains(strange.Input.Contains, stub.Data) { - return &strange.Output, nil - } + continue } - if expect := strange.Input.Matches; expect != nil { - closestMatch = append(closestMatch, closeMatch{"matches", expect}) - if matches(strange.Input.Matches, stub.Data) { - return &strange.Output, nil + if strange.CheckHeaders() { + if cmpHeaders, cmpHeadersErr := inputCmp(strange.Headers, stub.Headers); cmpHeadersErr != nil { + if cmpHeaders != nil { + closestMatch = append(closestMatch, closeMatch{ + rule: cmpData.rule, + expect: cmpData.expect, + headerRule: cmpHeaders.rule, + headerExpect: cmpHeaders.expect, + }) + } + + continue } } + + stubStorage.MarkUsed(strange.ID) + + return &strange.Output, nil } return nil, stubNotFoundError(stub, closestMatch) } +func inputCmp(input storage.Input, data map[string]interface{}) (*closeMatch, error) { + if expect := input.Equals; expect != nil { + closeMatchVal := closeMatch{rule: "equals", expect: expect} + + if equals(input.Equals, data) { + return &closeMatchVal, nil + } + + return &closeMatchVal, ErrNotFound + } + + if expect := input.Contains; expect != nil { + closeMatchVal := closeMatch{rule: "contains", expect: expect} + + if contains(input.Contains, data) { + return &closeMatchVal, nil + } + + return &closeMatchVal, ErrNotFound + } + + if expect := input.Matches; expect != nil { + closeMatchVal := closeMatch{rule: "matches", expect: expect} + + if matches(input.Matches, data) { + return &closeMatchVal, nil + } + + return &closeMatchVal, ErrNotFound + } + + return nil, ErrNotFound +} + func stubNotFoundError(stub *findStubPayload, closestMatches []closeMatch) error { template := fmt.Sprintf("Can't find stub \n\nService: %s \n\nMethod: %s \n\nInput\n\n", stub.Service, stub.Method) expectString, err := json.MarshalIndent(stub.Data, "", "\t") diff --git a/internal/domain/rest/api.gen.go b/internal/domain/rest/api.gen.go index f7541e72..fb939ebd 100644 --- a/internal/domain/rest/api.gen.go +++ b/internal/domain/rest/api.gen.go @@ -29,26 +29,36 @@ type MessageOK struct { // SearchRequest defines model for SearchRequest. type SearchRequest struct { - Data interface{} `json:"data"` - Id *ID `json:"id,omitempty"` - Method string `json:"method"` - Service string `json:"service"` + Data interface{} `json:"data"` + Headers map[string]string `json:"headers,omitempty"` + Id *ID `json:"id,omitempty"` + Method string `json:"method"` + Service string `json:"service"` } // SearchResponse defines model for SearchResponse. type SearchResponse struct { - Code *codes.Code `json:"code,omitempty"` - Data interface{} `json:"data"` - Error string `json:"error"` + Code *codes.Code `json:"code,omitempty"` + Data interface{} `json:"data"` + Error string `json:"error"` + Headers map[string]string `json:"headers,omitempty"` } // Stub defines model for Stub. type Stub struct { - Id *ID `json:"id,omitempty"` - Input StubInput `json:"input"` - Method string `json:"method"` - Output StubOutput `json:"output"` - Service string `json:"service"` + Headers StubHeaders `json:"headers,omitempty"` + Id *ID `json:"id,omitempty"` + Input StubInput `json:"input"` + Method string `json:"method"` + Output StubOutput `json:"output"` + Service string `json:"service"` +} + +// StubHeaders defines model for StubHeaders. +type StubHeaders struct { + Contains map[string]string `json:"contains,omitempty"` + Equals map[string]string `json:"equals,omitempty"` + Matches map[string]string `json:"matches,omitempty"` } // StubInput defines model for StubInput. @@ -63,9 +73,10 @@ type StubList = []Stub // StubOutput defines model for StubOutput. type StubOutput struct { - Code *codes.Code `json:"code,omitempty"` - Data map[string]interface{} `json:"data"` - Error string `json:"error"` + Code *codes.Code `json:"code,omitempty"` + Data map[string]interface{} `json:"data"` + Error string `json:"error"` + Headers map[string]string `json:"headers,omitempty"` } // AddStubJSONBody defines parameters for AddStub. diff --git a/pkg/sdk/api.gen.go b/pkg/sdk/api.gen.go index d519dab4..97210baf 100644 --- a/pkg/sdk/api.gen.go +++ b/pkg/sdk/api.gen.go @@ -33,26 +33,36 @@ type MessageOK struct { // SearchRequest defines model for SearchRequest. type SearchRequest struct { - Data interface{} `json:"data"` - Id *ID `json:"id,omitempty"` - Method string `json:"method"` - Service string `json:"service"` + Data interface{} `json:"data"` + Headers map[string]string `json:"headers,omitempty"` + Id *ID `json:"id,omitempty"` + Method string `json:"method"` + Service string `json:"service"` } // SearchResponse defines model for SearchResponse. type SearchResponse struct { - Code *codes.Code `json:"code,omitempty"` - Data interface{} `json:"data"` - Error string `json:"error"` + Code *codes.Code `json:"code,omitempty"` + Data interface{} `json:"data"` + Error string `json:"error"` + Headers map[string]string `json:"headers,omitempty"` } // Stub defines model for Stub. type Stub struct { - Id *ID `json:"id,omitempty"` - Input StubInput `json:"input"` - Method string `json:"method"` - Output StubOutput `json:"output"` - Service string `json:"service"` + Headers StubHeaders `json:"headers,omitempty"` + Id *ID `json:"id,omitempty"` + Input StubInput `json:"input"` + Method string `json:"method"` + Output StubOutput `json:"output"` + Service string `json:"service"` +} + +// StubHeaders defines model for StubHeaders. +type StubHeaders struct { + Contains map[string]string `json:"contains,omitempty"` + Equals map[string]string `json:"equals,omitempty"` + Matches map[string]string `json:"matches,omitempty"` } // StubInput defines model for StubInput. @@ -67,9 +77,10 @@ type StubList = []Stub // StubOutput defines model for StubOutput. type StubOutput struct { - Code *codes.Code `json:"code,omitempty"` - Data map[string]interface{} `json:"data"` - Error string `json:"error"` + Code *codes.Code `json:"code,omitempty"` + Data map[string]interface{} `json:"data"` + Error string `json:"error"` + Headers map[string]string `json:"headers,omitempty"` } // AddStubJSONBody defines parameters for AddStub. diff --git a/pkg/storage/stubs.go b/pkg/storage/stubs.go index a6fed21e..25322f91 100644 --- a/pkg/storage/stubs.go +++ b/pkg/storage/stubs.go @@ -16,6 +16,7 @@ type Stub struct { ID *uuid.UUID `json:"id,omitempty"` Service string `json:"service"` Method string `json:"method"` + Headers Input `json:"headers"` Input Input `json:"input"` Output Output `json:"output"` } @@ -29,6 +30,10 @@ func (s *Stub) GetID() uuid.UUID { return *s.ID } +func (s *Stub) CheckHeaders() bool { + return (len(s.Headers.Equals) + len(s.Headers.Matches) + len(s.Headers.Contains)) > 0 +} + type Input struct { Equals map[string]interface{} `json:"equals"` Contains map[string]interface{} `json:"contains"` @@ -36,15 +41,21 @@ type Input struct { } type Output struct { - Data map[string]interface{} `json:"data"` - Error string `json:"error"` - Code *codes.Code `json:"code,omitempty"` + Headers map[string]string `json:"headers"` + Data map[string]interface{} `json:"data"` + Error string `json:"error"` + Code *codes.Code `json:"code,omitempty"` } type storage struct { - ID uuid.UUID - Input Input - Output Output + ID uuid.UUID + Headers Input + Input Input + Output Output +} + +func (s *storage) CheckHeaders() bool { + return (len(s.Headers.Equals) + len(s.Headers.Matches) + len(s.Headers.Contains)) > 0 } type StubStorage struct { @@ -140,20 +151,27 @@ func (r *StubStorage) ItemsBy(service, method string, ID *uuid.UUID) ([]storage, return nil, err } + var resultWithHeaders []storage var result []storage for obj := it.Next(); obj != nil; obj = it.Next() { stub := obj.(*Stub) - r.used[stub.GetID()] = struct{}{} - result = append(result, storage{ - ID: stub.GetID(), - Input: stub.Input, - Output: stub.Output, - }) + s := storage{ + ID: stub.GetID(), + Headers: stub.Headers, + Input: stub.Input, + Output: stub.Output, + } + + if stub.CheckHeaders() { + resultWithHeaders = append(resultWithHeaders, s) + } else { + result = append(result, s) + } } - return result, nil + return append(resultWithHeaders, result...), nil } func (r *StubStorage) Unused() []Stub { @@ -187,6 +205,10 @@ func (r *StubStorage) Unused() []Stub { return result } +func (r *StubStorage) MarkUsed(id uuid.UUID) { + r.used[id] = struct{}{} +} + func (r *StubStorage) Stubs() []Stub { txn := r.db.Txn(false) defer txn.Abort() diff --git a/protoc-gen-gripmock/server.tmpl b/protoc-gen-gripmock/server.tmpl index 54891168..c9b2178f 100644 --- a/protoc-gen-gripmock/server.tmpl +++ b/protoc-gen-gripmock/server.tmpl @@ -15,6 +15,7 @@ import ( jsonpb "google.golang.org/protobuf/encoding/protojson" "golang.org/x/net/context" "google.golang.org/grpc" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/reflection" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/grpc/codes" @@ -80,7 +81,8 @@ type {{.Name}} struct{ {{ define "standard_method" }} func (s *{{.ServiceName}}) {{.Name}}(ctx context.Context, in *{{.Input}}) (*{{.Output}},error){ out := &{{.Output}}{} - err := findStub(ctx, "{{.ServiceName}}", "{{.Name}}", in, out) + md, _ := metadata.FromIncomingContext(ctx) + err := findStub(ctx, "{{.ServiceName}}", "{{.Name}}", md, in, out) return out, err } {{ end }} @@ -88,8 +90,10 @@ func (s *{{.ServiceName}}) {{.Name}}(ctx context.Context, in *{{.Input}}) (*{{.O {{ define "server_stream_method" }} func (s *{{.ServiceName}}) {{.Name}}(in *{{.Input}},srv {{.SvcPackage}}{{.ServiceName}}_{{.Name}}Server) error { out := &{{.Output}}{} - err := findStub(srv.Context(), "{{.ServiceName}}", "{{.Name}}", in, out) - if err!=nil { + ctx := srv.Context() + md, _ := metadata.FromIncomingContext(ctx) + err := findStub(ctx, "{{.ServiceName}}", "{{.Name}}", md, in, out) + if err != nil { return err } @@ -100,12 +104,14 @@ func (s *{{.ServiceName}}) {{.Name}}(in *{{.Input}},srv {{.SvcPackage}}{{.Servic {{ define "client_stream_method"}} func (s *{{.ServiceName}}) {{.Name}}(srv {{.SvcPackage}}{{.ServiceName}}_{{.Name}}Server) error { out := &{{.Output}}{} + ctx := srv.Context() + md, _ := metadata.FromIncomingContext(ctx) for { input,err := srv.Recv() if errors.Is(err, io.EOF) { return srv.SendAndClose(out) } - err = findStub(srv.Context(), "{{.ServiceName}}","{{.Name}}",input,out) + err = findStub(ctx, "{{.ServiceName}}","{{.Name}}",md,input,out) if err != nil { return err } @@ -115,6 +121,8 @@ func (s *{{.ServiceName}}) {{.Name}}(srv {{.SvcPackage}}{{.ServiceName}}_{{.Name {{ define "bidirectional_method"}} func (s *{{.ServiceName}}) {{.Name}}(srv {{.SvcPackage}}{{.ServiceName}}_{{.Name}}Server) error { + ctx := srv.Context() + md, _ := metadata.FromIncomingContext(ctx) for { in, err := srv.Recv() if errors.Is(err, io.EOF) { @@ -125,7 +133,7 @@ func (s *{{.ServiceName}}) {{.Name}}(srv {{.SvcPackage}}{{.ServiceName}}_{{.Name } out := &{{.Output}}{} - err = findStub(srv.Context(), "{{.ServiceName}}","{{.Name}}",in,out) + err = findStub(ctx, "{{.ServiceName}}","{{.Name}}", md, in, out) if err != nil { return err } @@ -154,16 +162,22 @@ type response struct { Error string `json:"error"` } -func findStub(ctx context.Context, service, method string, in, out protoreflect.ProtoMessage) error { +func findStub(ctx context.Context, service, method string, md metadata.MD, in, out protoreflect.ProtoMessage) error { api, err := sdk.NewClientWithResponses(fmt.Sprintf("http://localhost%s/api", HTTP_PORT)) if err != nil { return err } + headers := make(map[string]string, len(md)) + for h, v := range md { + headers[h] = strings.Join(v, ";") + } + searchStub, err := api.SearchStubsWithResponse(ctx, sdk.SearchStubsJSONRequestBody{ Service: service, Method: method, - Data: in, + Headers: headers, + Data: in, }) if err != nil { return err @@ -188,6 +202,9 @@ func findStub(ctx context.Context, service, method string, in, out protoreflect. return err } + mdResp := metadata.New(searchStub.JSON200.Headers) + grpc.SetHeader(ctx, mdResp) + return jsonpb.Unmarshal(data, out) } {{ end }} From f9ec724bf34a81115101e8902cf8481ce3698310 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 00:09:43 +0300 Subject: [PATCH 02/21] fix unit workflow --- .github/workflows/unit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 1be67025..b343857b 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: go get . - name: Test with Go - run: go test -json > TestResults-${{ matrix.go-version }}.json + run: go test -json ./... > TestResults-${{ matrix.go-version }}.json - name: Upload Go test results uses: actions/upload-artifact@v3 with: From e029feccf38d61276f3c5ddd2bba6f21d3a12360 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 00:13:56 +0300 Subject: [PATCH 03/21] update workflow --- .github/workflows/unit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index b343857b..283d0cee 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: go get . - name: Test with Go - run: go test -json ./... > TestResults-${{ matrix.go-version }}.json + run: go test -json ./... 2>&1 | tee -a TestResults-${{ matrix.go-version }}.json - name: Upload Go test results uses: actions/upload-artifact@v3 with: From 594d3b0234409f8766f32212ca17f3248d06a3eb Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 00:26:04 +0300 Subject: [PATCH 04/21] fix units --- stub/api_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/stub/api_test.go b/stub/api_test.go index 318dfd6b..d34977a8 100644 --- a/stub/api_test.go +++ b/stub/api_test.go @@ -55,7 +55,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodGet, "/api/stubs", nil) }, handler: api.ListStubs, - expect: "[{\"id\":\"43739ed8-2810-4f57-889b-4d3ff5795bce\",\"service\":\"Testing\",\"method\":\"TestMethod\",\"input\":{\"equals\":{\"Hola\":\"Mundo\"},\"contains\":null,\"matches\":null},\"output\":{\"data\":{\"Hello\":\"World\"},\"error\":\"\"}}]", + expect: "[{\"id\":\"43739ed8-2810-4f57-889b-4d3ff5795bce\",\"service\":\"Testing\",\"method\":\"TestMethod\",\"headers\":{\"equals\":null,\"contains\":null,\"matches\":null},\"input\":{\"equals\":{\"Hola\":\"Mundo\"},\"contains\":null,\"matches\":null},\"output\":{\"data\":{\"Hello\":\"World\"},\"error\":\"\",\"headers\":null}}]", }, { name: "unused stubs (all stubs)", @@ -63,7 +63,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodGet, "/api/stubs/unused", nil) }, handler: api.ListUnusedStubs, - expect: "[{\"id\":\"43739ed8-2810-4f57-889b-4d3ff5795bce\",\"service\":\"Testing\",\"method\":\"TestMethod\",\"input\":{\"equals\":{\"Hola\":\"Mundo\"},\"contains\":null,\"matches\":null},\"output\":{\"data\":{\"Hello\":\"World\"},\"error\":\"\"}}]", + expect: "[{\"id\":\"43739ed8-2810-4f57-889b-4d3ff5795bce\",\"service\":\"Testing\",\"method\":\"TestMethod\",\"headers\":{\"equals\":null,\"contains\":null,\"matches\":null},\"input\":{\"equals\":{\"Hola\":\"Mundo\"},\"contains\":null,\"matches\":null},\"output\":{\"data\":{\"Hello\":\"World\"},\"error\":\"\",\"headers\":null}}]", }, { name: "find stub equals", @@ -73,7 +73,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodPost, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"Hello\":\"World\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"Hello\":\"World\"},\"error\":\"\",\"headers\":null}\n", }, { name: "unused stubs (zero)", @@ -91,7 +91,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodPost, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"Hello\":\"World\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"Hello\":\"World\"},\"error\":\"\",\"headers\":null}\n", }, { name: "add nested stub equals", @@ -134,7 +134,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodPost, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"Hello\":\"World\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"Hello\":\"World\"},\"error\":\"\",\"headers\":null}\n", }, { name: "add stub contains", @@ -177,7 +177,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodGet, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"hello\":\"world\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"hello\":\"world\"},\"error\":\"\",\"headers\":null}\n", }, { name: "add nested stub contains", @@ -304,7 +304,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodPost, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":null,\"error\":\"error msg\",\"code\":3}\n", + expect: "{\"data\":null,\"error\":\"error msg\",\"code\":3,\"headers\":null}\n", }, { @@ -353,7 +353,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodPost, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":null,\"error\":\"error msg\"}\n", + expect: "{\"data\":null,\"error\":\"error msg\",\"headers\":null}\n", }, { name: "find nested stub contains", @@ -376,7 +376,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodGet, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"hello\":\"world\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"hello\":\"world\"},\"error\":\"\",\"headers\":null}\n", }, { name: "add stub matches regex", @@ -416,7 +416,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodGet, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"reply\":\"OK\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"reply\":\"OK\"},\"error\":\"\",\"headers\":null}\n", }, { name: "add nested stub matches regex", @@ -471,7 +471,7 @@ func TestStub(t *testing.T) { return httptest.NewRequest(http.MethodGet, "/api/stubs/search", bytes.NewReader([]byte(payload))) }, handler: api.SearchStubs, - expect: "{\"data\":{\"reply\":\"OK\"},\"error\":\"\"}\n", + expect: "{\"data\":{\"reply\":\"OK\"},\"error\":\"\",\"headers\":null}\n", }, { name: "error find stub contains", @@ -509,7 +509,7 @@ func TestStub(t *testing.T) { res, err := io.ReadAll(wrt.Result().Body) assert.NoError(t, err) - require.JSONEq(t, v.expect, string(res)) + require.JSONEq(t, v.expect, string(res), string(res)) }) } From 35b0fc7dafb541ebef7ec2bc5e3e7224fe68b435 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 00:28:19 +0300 Subject: [PATCH 05/21] lint fix --- pkg/storage/uuid_field_index.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/storage/uuid_field_index.go b/pkg/storage/uuid_field_index.go index 987d21b1..e3a60eee 100644 --- a/pkg/storage/uuid_field_index.go +++ b/pkg/storage/uuid_field_index.go @@ -67,7 +67,7 @@ func (u *UUIDFieldIndex) parseString(s string, enforceLength bool) ([]byte, erro if enforceLength && l != 36 { return nil, fmt.Errorf("UUID must be 36 characters") } else if l > 36 { - return nil, fmt.Errorf("Invalid UUID length. UUID have 36 characters; got %d", l) + return nil, fmt.Errorf("invalid UUID length. UUID have 36 characters; got %d", l) } hyphens := strings.Count(s, "-") @@ -79,12 +79,12 @@ func (u *UUIDFieldIndex) parseString(s string, enforceLength bool) ([]byte, erro sanitized := strings.Replace(s, "-", "", -1) sanitizedLength := len(sanitized) if sanitizedLength%2 != 0 { - return nil, fmt.Errorf("Input (without hyphens) must be even length") + return nil, fmt.Errorf("input (without hyphens) must be even length") } dec, err := hex.DecodeString(sanitized) if err != nil { - return nil, fmt.Errorf("Invalid UUID: %v", err) + return nil, fmt.Errorf("invalid UUID: %v", err) } return dec, nil From 34b933ff04cae601f6c3c7583e26fdd0d3a29246 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 12:44:12 +0300 Subject: [PATCH 06/21] bugfix --- example/simple/client/main.go | 49 ++++++++++++++++++++++++++++++++ example/simple/stub/simple3.yaml | 28 ++++++++++++++++++ gripmock.go | 4 +-- protoc-gen-gripmock/server.tmpl | 11 ++++++- stub/stub.go | 3 +- 5 files changed, 91 insertions(+), 4 deletions(-) diff --git a/example/simple/client/main.go b/example/simple/client/main.go index 8456d818..0a3db1e7 100644 --- a/example/simple/client/main.go +++ b/example/simple/client/main.go @@ -96,6 +96,55 @@ func main() { } log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) + md2 := metadata.New(map[string]string{"Authorization": "Basic dXNlcjp1c2Vy", "ab": "blue"}) + ctx = metadata.NewOutgoingContext(context.Background(), md2) + + var headers2 metadata.MD + + name = "simple3" + r, err = c.SayHello(ctx, &pb.Request{Name: name}, grpc.Header(&headers2)) + if err != nil { + log.Fatalf("error from grpc: %v", err) + } + if r.ReturnCode != 0 { + log.Fatalf("grpc server returned code: %d, expected code: %d", r.ReturnCode, 0) + } + if _, ok := headers2["result"]; !ok { + log.Fatal("header key `result` not found") + } + if len(headers2["result"]) != 3 { + log.Fatalf("the service did not return headers %+v", headers2) + } + if headers2["result"][0] != "blue" && headers2["result"][1] != "red" && headers2["result"][2] != "none" { + log.Fatal("the service returned an incorrect header") + } + log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) + + md3 := metadata.New(map[string]string{"Authorization": "Basic dXNlcjp1c2Vy", "ab": "red"}) + ctx = metadata.NewOutgoingContext(context.Background(), md3) + + var headers3 metadata.MD + + name = "simple3" + r, err = c.SayHello(ctx, &pb.Request{Name: name}, grpc.Header(&headers3)) + if err != nil { + log.Fatalf("error from grpc: %v", err) + } + if r.ReturnCode != 0 { + log.Fatalf("grpc server returned code: %d, expected code: %d", r.ReturnCode, 0) + } + if _, ok := headers3["result"]; !ok { + log.Fatal("header key `result` not found") + } + headers3.Get("result") + if len(headers3["result"]) != 3 { + log.Fatalf("the service did not return headers %+v", headers3) + } + if headers2["result"][0] != "red" && headers2["result"][1] != "blue" && headers2["result"][2] != "none" { + log.Fatal("the service returned an incorrect header") + } + log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) + name = "simple3" r, err = c.SayHello(context.Background(), &pb.Request{Name: name}, grpc.UseCompressor(gzip.Name)) if err != nil { diff --git a/example/simple/stub/simple3.yaml b/example/simple/stub/simple3.yaml index dd9e36a1..57164105 100644 --- a/example/simple/stub/simple3.yaml +++ b/example/simple/stub/simple3.yaml @@ -20,3 +20,31 @@ message: Authorization OK headers: result: ok +- service: Gripmock + method: SayHello + headers: + contains: + authorization: Basic dXNlcjp1c2Vy + ab: blue + input: + equals: + name: simple3 + output: + data: + message: Blue OK + headers: + result: blue;red;none +- service: Gripmock + method: SayHello + headers: + contains: + authorization: Basic dXNlcjp1c2Vy + ab: red + input: + equals: + name: simple3 + output: + data: + message: Red OK + headers: + result: red;blue;none diff --git a/gripmock.go b/gripmock.go index ed516019..0ba40351 100644 --- a/gripmock.go +++ b/gripmock.go @@ -24,9 +24,9 @@ import ( func main() { outputPointer := flag.String("o", "", "directory to output server.go. Default is $GOPATH/src/grpc/") grpcPort := flag.String("grpc-port", "4770", "Port of gRPC tcp server") - grpcBindAddr := flag.String("grpc-listen", "", "Adress the gRPC server will bind to. Default to localhost, set to 0.0.0.0 to use from another machine") + grpcBindAddr := flag.String("grpc-listen", "0.0.0.0", "Adress the gRPC server will bind to. Default to localhost, set to 0.0.0.0 to use from another machine") adminport := flag.String("admin-port", "4771", "Port of stub admin server") - adminBindAddr := flag.String("admin-listen", "", "Adress the admin server will bind to. Default to localhost, set to 0.0.0.0 to use from another machine") + adminBindAddr := flag.String("admin-listen", "0.0.0.0", "Adress the admin server will bind to. Default to localhost, set to 0.0.0.0 to use from another machine") stubPath := flag.String("stub", "", "Path where the stub files are (Optional)") imports := flag.String("imports", "/protobuf", "comma separated imports path. default path /protobuf is where gripmock Dockerfile install WKT protos") // for backwards compatibility diff --git a/protoc-gen-gripmock/server.tmpl b/protoc-gen-gripmock/server.tmpl index c9b2178f..626a5aae 100644 --- a/protoc-gen-gripmock/server.tmpl +++ b/protoc-gen-gripmock/server.tmpl @@ -202,7 +202,16 @@ func findStub(ctx context.Context, service, method string, md metadata.MD, in, o return err } - mdResp := metadata.New(searchStub.JSON200.Headers) + mdResp := make(metadata.MD, len(searchStub.JSON200.Headers)) + for k, v := range searchStub.JSON200.Headers { + splits := strings.Split(v, ";") + for i, s := range splits { + splits[i] = strings.TrimSpace(s) + } + + mdResp[k] = splits + } + grpc.SetHeader(ctx, mdResp) return jsonpb.Unmarshal(data, out) diff --git a/stub/stub.go b/stub/stub.go index ad1bb60c..66a292fa 100644 --- a/stub/stub.go +++ b/stub/stub.go @@ -3,6 +3,7 @@ package stub import ( "fmt" "log" + "net" "net/http" "os" @@ -25,7 +26,7 @@ func RunRestServer(ch chan struct{}, opt Options) { if opt.Port == "" { opt.Port = DefaultPort } - addr := opt.BindAddr + ":" + opt.Port + addr := net.JoinHostPort(opt.BindAddr, opt.Port) apiServer, _ := app.NewRestServer(opt.StubPath) From 20721a111925e99986e10c84c704e67b75187009 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 17:01:12 +0300 Subject: [PATCH 07/21] tab --- protoc-gen-gripmock/server.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protoc-gen-gripmock/server.tmpl b/protoc-gen-gripmock/server.tmpl index 626a5aae..42f5c462 100644 --- a/protoc-gen-gripmock/server.tmpl +++ b/protoc-gen-gripmock/server.tmpl @@ -12,7 +12,7 @@ import ( "net" "net/http" - jsonpb "google.golang.org/protobuf/encoding/protojson" + jsonpb "google.golang.org/protobuf/encoding/protojson" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" From 9a26dc0cc75d6ab9fcdd5a01ded5f7f733e15285 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 19:44:17 +0300 Subject: [PATCH 08/21] algorithm stabilization --- pkg/storage/stubs.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/storage/stubs.go b/pkg/storage/stubs.go index 25322f91..ec47acc9 100644 --- a/pkg/storage/stubs.go +++ b/pkg/storage/stubs.go @@ -2,6 +2,7 @@ package storage import ( "errors" + "slices" "sync/atomic" "github.com/google/uuid" @@ -30,10 +31,6 @@ func (s *Stub) GetID() uuid.UUID { return *s.ID } -func (s *Stub) CheckHeaders() bool { - return (len(s.Headers.Equals) + len(s.Headers.Matches) + len(s.Headers.Contains)) > 0 -} - type Input struct { Equals map[string]interface{} `json:"equals"` Contains map[string]interface{} `json:"contains"` @@ -54,8 +51,12 @@ type storage struct { Output Output } +func (s *storage) CountHeaders() int { + return len(s.Headers.Equals) + len(s.Headers.Matches) + len(s.Headers.Contains) +} + func (s *storage) CheckHeaders() bool { - return (len(s.Headers.Equals) + len(s.Headers.Matches) + len(s.Headers.Contains)) > 0 + return s.CountHeaders() > 0 } type StubStorage struct { @@ -151,7 +152,6 @@ func (r *StubStorage) ItemsBy(service, method string, ID *uuid.UUID) ([]storage, return nil, err } - var resultWithHeaders []storage var result []storage for obj := it.Next(); obj != nil; obj = it.Next() { @@ -164,14 +164,14 @@ func (r *StubStorage) ItemsBy(service, method string, ID *uuid.UUID) ([]storage, Output: stub.Output, } - if stub.CheckHeaders() { - resultWithHeaders = append(resultWithHeaders, s) - } else { - result = append(result, s) - } + result = append(result, s) } - return append(resultWithHeaders, result...), nil + slices.SortFunc(result, func(a, b storage) int { + return b.CountHeaders() - a.CountHeaders() + }) + + return result, nil } func (r *StubStorage) Unused() []Stub { From 1fd20eaa87d438eae5a119524245b30cb5f0a3c4 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 20:08:01 +0300 Subject: [PATCH 09/21] fix equals --- example/simple/stub/simple3.yaml | 2 +- protoc-gen-gripmock/server.tmpl | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/example/simple/stub/simple3.yaml b/example/simple/stub/simple3.yaml index 57164105..884387be 100644 --- a/example/simple/stub/simple3.yaml +++ b/example/simple/stub/simple3.yaml @@ -10,7 +10,7 @@ - service: Gripmock method: SayHello headers: - contains: + equals: authorization: Basic dXNlcjp1c2Vy # user:user input: equals: diff --git a/protoc-gen-gripmock/server.tmpl b/protoc-gen-gripmock/server.tmpl index 42f5c462..97be6dbe 100644 --- a/protoc-gen-gripmock/server.tmpl +++ b/protoc-gen-gripmock/server.tmpl @@ -4,6 +4,7 @@ package main import ( "bytes" "errors" + "slices" "encoding/json" "fmt" "io" @@ -168,8 +169,13 @@ func findStub(ctx context.Context, service, method string, md metadata.MD, in, o return err } + excludes := []string{":authority", "content-type", "grpc-accept-encoding", "user-agent"} headers := make(map[string]string, len(md)) for h, v := range md { + if slices.Contains(excludes, h) { + continue + } + headers[h] = strings.Join(v, ";") } From e88951860a933f77d1be147b2dca1886e2640699 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 20:15:29 +0300 Subject: [PATCH 10/21] fix spaces --- protoc-gen-gripmock/server.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protoc-gen-gripmock/server.tmpl b/protoc-gen-gripmock/server.tmpl index 97be6dbe..70b839d2 100644 --- a/protoc-gen-gripmock/server.tmpl +++ b/protoc-gen-gripmock/server.tmpl @@ -169,12 +169,12 @@ func findStub(ctx context.Context, service, method string, md metadata.MD, in, o return err } - excludes := []string{":authority", "content-type", "grpc-accept-encoding", "user-agent"} + excludes := []string{":authority", "content-type", "grpc-accept-encoding", "user-agent"} headers := make(map[string]string, len(md)) for h, v := range md { - if slices.Contains(excludes, h) { - continue - } + if slices.Contains(excludes, h) { + continue + } headers[h] = strings.Join(v, ";") } From 860949399bcc6f39deeed125b653ae80dbafd57f Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 20:18:09 +0300 Subject: [PATCH 11/21] lru update --- go.mod | 6 +++--- go.sum | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 944b683c..977015ca 100644 --- a/go.mod +++ b/go.mod @@ -24,8 +24,8 @@ require ( github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/hashicorp/go-immutable-radix v1.3.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect @@ -34,7 +34,7 @@ require ( golang.org/x/net v0.15.0 // indirect golang.org/x/sys v0.12.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b5ac2d90..d7a1035d 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,8 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= @@ -42,6 +44,8 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -118,6 +122,8 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3j golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= From e8f9ad29470a33a9b7b5953118c81b94674d17a0 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 21:29:58 +0300 Subject: [PATCH 12/21] removed the extra module --- Dockerfile | 2 +- go.mod | 4 ---- protoc-gen-gripmock/go.mod | 6 +++--- protoc-gen-gripmock/go.sum | 12 ++++++------ protogen/empty.go | 10 ++++++++++ protogen/example/empty.go | 11 ----------- protogen/example/go.mod | 16 ---------------- protogen/example/go.sum | 21 --------------------- protogen/go.mod | 13 +++++++++++++ protogen/go.sum | 21 +++++++++++++++++++++ 10 files changed, 54 insertions(+), 62 deletions(-) delete mode 100644 protogen/example/empty.go delete mode 100644 protogen/example/go.mod delete mode 100644 protogen/example/go.sum diff --git a/Dockerfile b/Dockerfile index 8746d8f8..a4ac77f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN mkdir /proto /stubs &&\ RUN cd /go/src/github.com/bavix/gripmock/protoc-gen-gripmock &&\ go install -v &&\ cd /go/src/github.com/bavix/gripmock/example/simple/client &&\ - go get -u all &&\ + go mod tidy &&\ cd /go/src/github.com/bavix/gripmock &&\ go install -v diff --git a/go.mod b/go.mod index 977015ca..1f53ce0f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.21 require ( github.com/bavix/gripmock/protogen v0.0.0 - github.com/bavix/gripmock/protogen/example v0.0.0 github.com/goccy/go-yaml v1.11.2 github.com/google/uuid v1.3.1 github.com/gorilla/handlers v1.5.1 @@ -39,8 +38,5 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -// this is for generated server to be able to run -replace github.com/bavix/gripmock/protogen/example v0.0.0 => ./protogen/example - // this is for example client to be able to run replace github.com/bavix/gripmock/protogen v0.0.0 => ./protogen diff --git a/protoc-gen-gripmock/go.mod b/protoc-gen-gripmock/go.mod index c9458eb3..f50dd3aa 100644 --- a/protoc-gen-gripmock/go.mod +++ b/protoc-gen-gripmock/go.mod @@ -3,13 +3,13 @@ module github.com/bavix/gripmock/protoc-gen-gripmock go 1.21 require ( - golang.org/x/text v0.12.0 - golang.org/x/tools v0.12.0 + golang.org/x/text v0.13.0 + golang.org/x/tools v0.13.0 google.golang.org/protobuf v1.31.0 ) require ( golang.org/x/mod v0.12.0 // indirect - golang.org/x/sys v0.11.0 // indirect + golang.org/x/sys v0.12.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect ) diff --git a/protoc-gen-gripmock/go.sum b/protoc-gen-gripmock/go.sum index a9a6e455..185a88b7 100644 --- a/protoc-gen-gripmock/go.sum +++ b/protoc-gen-gripmock/go.sum @@ -3,12 +3,12 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= diff --git a/protogen/empty.go b/protogen/empty.go index 356b3890..c5273334 100644 --- a/protogen/empty.go +++ b/protogen/empty.go @@ -1 +1,11 @@ package protogen + +import ( + _ "google.golang.org/grpc" + _ "google.golang.org/grpc/codes" + _ "google.golang.org/grpc/status" + _ "google.golang.org/protobuf/reflect/protoreflect" + _ "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/apipb" + _ "google.golang.org/protobuf/types/known/emptypb" +) diff --git a/protogen/example/empty.go b/protogen/example/empty.go deleted file mode 100644 index 975dd7b4..00000000 --- a/protogen/example/empty.go +++ /dev/null @@ -1,11 +0,0 @@ -package example - -import ( - _ "google.golang.org/grpc" - _ "google.golang.org/grpc/codes" - _ "google.golang.org/grpc/status" - _ "google.golang.org/protobuf/reflect/protoreflect" - _ "google.golang.org/protobuf/runtime/protoimpl" - _ "google.golang.org/protobuf/types/known/apipb" - _ "google.golang.org/protobuf/types/known/emptypb" -) diff --git a/protogen/example/go.mod b/protogen/example/go.mod deleted file mode 100644 index 29e18fba..00000000 --- a/protogen/example/go.mod +++ /dev/null @@ -1,16 +0,0 @@ -module github.com/bavix/gripmock/protogen/example - -go 1.21 - -require ( - google.golang.org/grpc v1.57.0 - google.golang.org/protobuf v1.31.0 -) - -require ( - github.com/golang/protobuf v1.5.3 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect -) diff --git a/protogen/example/go.sum b/protogen/example/go.sum deleted file mode 100644 index ddcffb68..00000000 --- a/protogen/example/go.sum +++ /dev/null @@ -1,21 +0,0 @@ -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/protogen/go.mod b/protogen/go.mod index 7be0513c..c2e9d31b 100644 --- a/protogen/go.mod +++ b/protogen/go.mod @@ -1,3 +1,16 @@ module github.com/bavix/gripmock/protogen go 1.21 + +require ( + google.golang.org/grpc v1.58.2 + google.golang.org/protobuf v1.31.0 +) + +require ( + github.com/golang/protobuf v1.5.3 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect +) diff --git a/protogen/go.sum b/protogen/go.sum index e69de29b..b5425ae0 100644 --- a/protogen/go.sum +++ b/protogen/go.sum @@ -0,0 +1,21 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= From 638a776e6c6a511f36479f27f3a8485ea0b484c4 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sat, 30 Sep 2023 21:36:51 +0300 Subject: [PATCH 13/21] fix docs --- README.md | 2 +- docs/api-stubs-search.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index daa81b2e..eecb2f69 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ Stub will respond with the expected response only if the request matches any rul So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. ### Input Matching Rule -Input matching has 3 rules to match an input: **equals**,**contains** and **regex** +Input matching has 3 rules to match an input: **equals**,**contains** and **matches**
Nested fields are allowed for input matching too for all JSON data types. (`string`, `bool`, `array`, etc.)
diff --git a/docs/api-stubs-search.md b/docs/api-stubs-search.md index e666faab..f1f5ec0e 100644 --- a/docs/api-stubs-search.md +++ b/docs/api-stubs-search.md @@ -83,7 +83,7 @@ Stub will respond with the expected response only if the request matches any rul So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. ### Input Matching Rule -Input matching has 3 rules to match an input: **equals**,**contains** and **regex** +Input matching has 3 rules to match an input: **equals**,**contains** and **matches**
Nested fields are allowed for input matching too for all JSON data types. (`string`, `bool`, `array`, etc.)
From f9ca6977e09b3db003f5fd5c9521301956b8cdb8 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sun, 1 Oct 2023 18:24:22 +0300 Subject: [PATCH 14/21] Update docs --- README.md | 74 ++++++++++++++++++++++++++++++++++++++++ docs/api-stubs-search.md | 66 +++++++++++++++++++++++++++++++++++ docs/overview.md | 1 + docs/quick-usage.md | 5 +++ 4 files changed, 146 insertions(+) diff --git a/README.md b/README.md index eecb2f69..00b5cc0b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ This service is a fork of the service [tokopedia/gripmock](https://github.com/to - Updated all deprecated dependencies [tokopedia#64](https://github.com/tokopedia/gripmock/issues/64); - Add yaml as json alternative for static stab's; - Add endpoint for healthcheck (/api/health/liveness, /api/health/readiness); +- Add support headers [tokopedia#144](https://github.com/tokopedia/gripmock/issues/144); - Add grpc error code [tokopedia#125](https://github.com/tokopedia/gripmock/issues/125); - Added gzip encoding support for grpc server [tokopedia#134](https://github.com/tokopedia/gripmock/pull/134); - Fixed issues with int64/uint64 [tokopedia#67](https://github.com/tokopedia/gripmock/pull/148); @@ -74,6 +75,9 @@ Stub Format is JSON text format. It has a skeleton as follows: { "service":"", // name of service defined in proto "method":"", // name of method that we want to mock + "headers":{ // Optional. headers matching rule. see Headers Matching Rule section below + // put rule here + }, "input":{ // input matching rule. see Input Matching Rule section below // put rule here }, @@ -81,6 +85,9 @@ Stub Format is JSON text format. It has a skeleton as follows: "data":{ // put result fields here }, + "headers":{ // Optional + // put result headers here + }, "error":"", // Optional. if you want to return error instead. "code":"" // Optional. Grpc response code. if code !=0 return error instead. } @@ -191,6 +198,73 @@ Nested fields are allowed for input matching too for all JSON data types. (`stri } ``` +## Headers Matching +Stub will respond with the expected response only if the request matches any rule. Stub service will serve `/api/stubs/search` endpoint with format: +```json +{ + "service":"", + "method":"", + "data":{ + // input that suppose to match with stored stubs + } +} +``` +So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. + +### Headers Matching Rule +Headers matching has 3 rules to match an input: **equals**,**contains** and **matches** +
+Headers can consist of a key and a value. If there are several values, then you need to list them separated by ";". Data type string. +
+**Gripmock** recursively goes over the fields and tries to match with given input. +
+**equals** will match the exact field name and value of input into expected stub. example stub JSON: +```json +{ + . + . + "headers":{ + "equals":{ + "authorization": "mytoken", + "system": "ec071904-93bf-4ded-b49c-d06097ddc6d5" + } + } + . + . +} +``` + +**contains** will match input that has the value declared expected fields. example stub JSON: +```json +{ + . + . + "headers":{ + "contains":{ + "field2":"hello" + } + } + . + . +} +``` + +**matches** using regex for matching fields expectation. example: + +```json +{ + . + . + "headers":{ + "matches":{ + "name":"^grip.*$" + } + } + . + . +} +``` + --- Supported by diff --git a/docs/api-stubs-search.md b/docs/api-stubs-search.md index f1f5ec0e..0d1939da 100644 --- a/docs/api-stubs-search.md +++ b/docs/api-stubs-search.md @@ -147,3 +147,69 @@ Nested fields are allowed for input matching too for all JSON data types. (`stri } ``` +## Headers Matching +Stub will respond with the expected response only if the request matches any rule. Stub service will serve `/api/stubs/search` endpoint with format: +```json +{ + "service":"", + "method":"", + "data":{ + // input that suppose to match with stored stubs + } +} +``` +So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. + +### Headers Matching Rule +Headers matching has 3 rules to match an input: **equals**,**contains** and **matches** +
+Headers can consist of a key and a value. If there are several values, then you need to list them separated by ";". Data type string. +
+**Gripmock** recursively goes over the fields and tries to match with given input. +
+**equals** will match the exact field name and value of input into expected stub. example stub JSON: +```json +{ + . + . + "headers":{ + "equals":{ + "authorization": "mytoken", + "system": "ec071904-93bf-4ded-b49c-d06097ddc6d5" + } + } + . + . +} +``` + +**contains** will match input that has the value declared expected fields. example stub JSON: +```json +{ + . + . + "headers":{ + "contains":{ + "field2":"hello" + } + } + . + . +} +``` + +**matches** using regex for matching fields expectation. example: + +```json +{ + . + . + "headers":{ + "matches":{ + "name":"^grip.*$" + } + } + . + . +} +``` diff --git a/docs/overview.md b/docs/overview.md index a55ac71d..3b8e3235 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -10,6 +10,7 @@ This service is a fork of the service [tokopedia/gripmock](https://github.com/to - Updated all deprecated dependencies [tokopedia#64](https://github.com/tokopedia/gripmock/issues/64); - Add yaml as json alternative for static stab's; - Add endpoint for healthcheck (/api/health/liveness, /api/health/readiness); +- Add support headers [tokopedia#144](https://github.com/tokopedia/gripmock/issues/144); - Add grpc error code [tokopedia#125](https://github.com/tokopedia/gripmock/issues/125); - Added gzip encoding support for grpc server [tokopedia#134](https://github.com/tokopedia/gripmock/pull/134); - Fixed issues with int64/uint64 [tokopedia#67](https://github.com/tokopedia/gripmock/pull/148); diff --git a/docs/quick-usage.md b/docs/quick-usage.md index 7930b4e0..070449c6 100644 --- a/docs/quick-usage.md +++ b/docs/quick-usage.md @@ -63,6 +63,11 @@ The result will not make you wait long, you should see the following: "id": "6c85b0fa-caaf-4640-a672-f56b7dd8074d", "service": "Gripmock", "method": "SayHello", + "headers": { + "equals": null, + "contains": null, + "matches": null + }, "input": { "equals": { "name": "gripmock" From b81ea7012c3816f7057ff63ed2f576fb1897f058 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sun, 1 Oct 2023 18:34:13 +0300 Subject: [PATCH 15/21] matching rules --- docs/_sidebar.md | 4 + docs/api-stubs-search.md | 145 +--------------------------------- docs/matching-rule-headers.md | 66 ++++++++++++++++ docs/matching-rule-input.md | 77 ++++++++++++++++++ 4 files changed, 149 insertions(+), 143 deletions(-) create mode 100644 docs/matching-rule-headers.md create mode 100644 docs/matching-rule-input.md diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 13378217..2dfda79c 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -6,6 +6,10 @@ - [One service](proto-one-file) - [N-Services in one](proto-multifiles) +- Matching Rule + - [Input](matching-rule-input) + - [Headers](matching-rule-headers) + - Static stubs - [JSON](static-stubs-json) - [YAML](static-stubs-yaml) diff --git a/docs/api-stubs-search.md b/docs/api-stubs-search.md index 0d1939da..b2af2e80 100644 --- a/docs/api-stubs-search.md +++ b/docs/api-stubs-search.md @@ -69,147 +69,6 @@ Response: } ``` -## Input Matching -Stub will respond with the expected response only if the request matches any rule. Stub service will serve `/api/stubs/search` endpoint with format: -```json -{ - "service":"", - "method":"", - "data":{ - // input that suppose to match with stored stubs - } -} -``` -So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. - -### Input Matching Rule -Input matching has 3 rules to match an input: **equals**,**contains** and **matches** -
-Nested fields are allowed for input matching too for all JSON data types. (`string`, `bool`, `array`, etc.) -
-**Gripmock** recursively goes over the fields and tries to match with given input. -
-**equals** will match the exact field name and value of input into expected stub. example stub JSON: -```json -{ - . - . - "input":{ - "equals":{ - "name":"gripmock", - "greetings": { - "english": "Hello World!", - "indonesian": "Halo Dunia!", - "turkish": "Merhaba Dünya!" - }, - "ok": true, - "numbers": [4, 8, 15, 16, 23, 42] - "null": null - } - } - . - . -} -``` - -**contains** will match input that has the value declared expected fields. example stub JSON: -```json -{ - . - . - "input":{ - "contains":{ - "field2":"hello", - "field4":{ - "field5": "value5" - } - } - } - . - . -} -``` - -**matches** using regex for matching fields expectation. example: - -```json -{ - . - . - "input":{ - "matches":{ - "name":"^grip.*$", - "cities": ["Jakarta", "Istanbul", ".*grad$"] - } - } - . - . -} -``` +[Input Matching](matching-rule-input.md ':include') -## Headers Matching -Stub will respond with the expected response only if the request matches any rule. Stub service will serve `/api/stubs/search` endpoint with format: -```json -{ - "service":"", - "method":"", - "data":{ - // input that suppose to match with stored stubs - } -} -``` -So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. - -### Headers Matching Rule -Headers matching has 3 rules to match an input: **equals**,**contains** and **matches** -
-Headers can consist of a key and a value. If there are several values, then you need to list them separated by ";". Data type string. -
-**Gripmock** recursively goes over the fields and tries to match with given input. -
-**equals** will match the exact field name and value of input into expected stub. example stub JSON: -```json -{ - . - . - "headers":{ - "equals":{ - "authorization": "mytoken", - "system": "ec071904-93bf-4ded-b49c-d06097ddc6d5" - } - } - . - . -} -``` - -**contains** will match input that has the value declared expected fields. example stub JSON: -```json -{ - . - . - "headers":{ - "contains":{ - "field2":"hello" - } - } - . - . -} -``` - -**matches** using regex for matching fields expectation. example: - -```json -{ - . - . - "headers":{ - "matches":{ - "name":"^grip.*$" - } - } - . - . -} -``` +[Headers Matching](matching-rule-headers.md ':include') diff --git a/docs/matching-rule-headers.md b/docs/matching-rule-headers.md new file mode 100644 index 00000000..fe3dbe1c --- /dev/null +++ b/docs/matching-rule-headers.md @@ -0,0 +1,66 @@ +## Headers Matching +Stub will respond with the expected response only if the request matches any rule. Stub service will serve `/api/stubs/search` endpoint with format: +```json +{ + "service":"", + "method":"", + "data":{ + // input that suppose to match with stored stubs + } +} +``` +So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. + +### Headers Matching Rule +Headers matching has 3 rules to match an input: **equals**,**contains** and **matches** +
+Headers can consist of a key and a value. If there are several values, then you need to list them separated by ";". Data type string. +
+**Gripmock** recursively goes over the fields and tries to match with given input. +
+**equals** will match the exact field name and value of input into expected stub. example stub JSON: +```json +{ + . + . + "headers":{ + "equals":{ + "authorization": "mytoken", + "system": "ec071904-93bf-4ded-b49c-d06097ddc6d5" + } + } + . + . +} +``` + +**contains** will match input that has the value declared expected fields. example stub JSON: +```json +{ + . + . + "headers":{ + "contains":{ + "field2":"hello" + } + } + . + . +} +``` + +**matches** using regex for matching fields expectation. example: + +```json +{ + . + . + "headers":{ + "matches":{ + "name":"^grip.*$" + } + } + . + . +} +``` diff --git a/docs/matching-rule-input.md b/docs/matching-rule-input.md new file mode 100644 index 00000000..9e9d3946 --- /dev/null +++ b/docs/matching-rule-input.md @@ -0,0 +1,77 @@ +## Input Matching +Stub will respond with the expected response only if the request matches any rule. Stub service will serve `/api/stubs/search` endpoint with format: +```json +{ + "service":"", + "method":"", + "data":{ + // input that suppose to match with stored stubs + } +} +``` +So if you do a `curl -X POST -d '{"service":"Greeter","method":"SayHello","data":{"name":"gripmock"}}' localhost:4771/api/stubs/search` stub service will find a match from listed stubs stored there. + +### Input Matching Rule +Input matching has 3 rules to match an input: **equals**,**contains** and **matches** +
+Nested fields are allowed for input matching too for all JSON data types. (`string`, `bool`, `array`, etc.) +
+**Gripmock** recursively goes over the fields and tries to match with given input. +
+**equals** will match the exact field name and value of input into expected stub. example stub JSON: +```json +{ + . + . + "input":{ + "equals":{ + "name":"gripmock", + "greetings": { + "english": "Hello World!", + "indonesian": "Halo Dunia!", + "turkish": "Merhaba Dünya!" + }, + "ok": true, + "numbers": [4, 8, 15, 16, 23, 42] + "null": null + } + } + . + . +} +``` + +**contains** will match input that has the value declared expected fields. example stub JSON: +```json +{ + . + . + "input":{ + "contains":{ + "field2":"hello", + "field4":{ + "field5": "value5" + } + } + } + . + . +} +``` + +**matches** using regex for matching fields expectation. example: + +```json +{ + . + . + "input":{ + "matches":{ + "name":"^grip.*$", + "cities": ["Jakarta", "Istanbul", ".*grad$"] + } + } + . + . +} +``` From d0cadf9c1d3d1a9320dc62b9dd51d02e66c9e50d Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sun, 1 Oct 2023 18:39:11 +0300 Subject: [PATCH 16/21] update version --- api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index a12c9d8b..bd3861e7 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -2,7 +2,7 @@ openapi: 3.0.2 servers: - url: /api info: - version: 2.0.1 + version: 2.1.0 title: GripMock API Schema tags: - name: stubs From 5a53fa3b57ca8b870917d482ed02c38885b69dd8 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sun, 1 Oct 2023 19:19:37 +0300 Subject: [PATCH 17/21] light image --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a4ac77f8..b84fa930 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,8 +23,6 @@ RUN mkdir /proto /stubs &&\ RUN cd /go/src/github.com/bavix/gripmock/protoc-gen-gripmock &&\ go install -v &&\ - cd /go/src/github.com/bavix/gripmock/example/simple/client &&\ - go mod tidy &&\ cd /go/src/github.com/bavix/gripmock &&\ go install -v From 5419a52c47c4b317660b74a4b02d8704c96c77e8 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sun, 1 Oct 2023 21:53:43 +0300 Subject: [PATCH 18/21] light image v2 --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b84fa930..3c66af7a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,8 @@ RUN apk -U --no-cache add bash git protobuf curl &&\ git clone --depth=1 https://github.com/protocolbuffers/protobuf.git /protobuf-repo &&\ mv /protobuf-repo/src/ /protobuf/ &&\ rm -rf /protobuf-repo &&\ - # cleanup + # cleanup \ + find /protobuf -not -name "*.proto" -type f -delete &&\ apk del git &&\ apk -v cache clean From 32b3933b74551779313fa55be384946e5f3115b0 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Sun, 1 Oct 2023 21:54:48 +0300 Subject: [PATCH 19/21] fix comment --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3c66af7a..57713a20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN apk -U --no-cache add bash git protobuf curl &&\ git clone --depth=1 https://github.com/protocolbuffers/protobuf.git /protobuf-repo &&\ mv /protobuf-repo/src/ /protobuf/ &&\ rm -rf /protobuf-repo &&\ - # cleanup \ + # cleanup find /protobuf -not -name "*.proto" -type f -delete &&\ apk del git &&\ apk -v cache clean From 4e128167160b9bd22a6c602109d0ea8e27bca0e1 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Mon, 2 Oct 2023 23:52:00 +0300 Subject: [PATCH 20/21] bugfix --- go.mod | 2 +- go.sum | 8 ++------ pkg/storage/stubs.go | 5 +++++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 1f53ce0f..a2edf4ee 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( golang.org/x/net v0.15.0 // indirect golang.org/x/sys v0.12.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d7a1035d..900dc6f1 100644 --- a/go.sum +++ b/go.sum @@ -33,7 +33,6 @@ github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -42,7 +41,6 @@ github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYi github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -120,10 +118,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/pkg/storage/stubs.go b/pkg/storage/stubs.go index ec47acc9..09175c92 100644 --- a/pkg/storage/stubs.go +++ b/pkg/storage/stubs.go @@ -3,6 +3,7 @@ package storage import ( "errors" "slices" + "sync" "sync/atomic" "github.com/google/uuid" @@ -60,6 +61,7 @@ func (s *storage) CheckHeaders() bool { } type StubStorage struct { + mu sync.Mutex used map[uuid.UUID]struct{} db *memdb.MemDB total int64 @@ -206,6 +208,9 @@ func (r *StubStorage) Unused() []Stub { } func (r *StubStorage) MarkUsed(id uuid.UUID) { + r.mu.Lock() + defer r.mu.Unlock() + r.used[id] = struct{}{} } From b86e5b433b9824c74e98244eec45676ad2e0386f Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Tue, 3 Oct 2023 21:29:21 +0300 Subject: [PATCH 21/21] added int64/uint64 test for returned data --- example/simple/client/main.go | 6 ++++ example/simple/simple.proto | 2 ++ example/simple/stub/uint64_int64.yml | 6 +++- protogen/example/simple/simple.pb.go | 39 +++++++++++++++++------ protogen/example/simple/simple_grpc.pb.go | 2 +- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/example/simple/client/main.go b/example/simple/client/main.go index 0a3db1e7..be26fb5f 100644 --- a/example/simple/client/main.go +++ b/example/simple/client/main.go @@ -186,5 +186,11 @@ func main() { if r.Message != "72057594037927936 18446744073709551615" { log.Fatalf("failed to get valid message: %v", r.Message) } + if r.Vint64 != 72057594037927936 { + log.Fatalf("expected: 72057594037927936, received: %d", r.Vint64) + } + if r.Vuint64 != 18446744073709551615 { + log.Fatalf("expected: 18446744073709551615, received: %d", r.Vuint64) + } log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) } diff --git a/example/simple/simple.proto b/example/simple/simple.proto index c8856d9e..cff540c1 100644 --- a/example/simple/simple.proto +++ b/example/simple/simple.proto @@ -21,4 +21,6 @@ message Request { message Reply { string message = 1; int32 return_code = 2; + int64 vint64 = 3; + uint64 vuint64 = 4; } \ No newline at end of file diff --git a/example/simple/stub/uint64_int64.yml b/example/simple/stub/uint64_int64.yml index bd798ae6..dac2d042 100644 --- a/example/simple/stub/uint64_int64.yml +++ b/example/simple/stub/uint64_int64.yml @@ -9,4 +9,8 @@ vuint64: 18446744073709551615 output: data: - message: "72057594037927936 18446744073709551615" \ No newline at end of file + message: "72057594037927936 18446744073709551615" + # {"high":72057594037927936,"low":0} + vint64: 72057594037927936 + # {"high":18446744073709551615,"low":18446744073709551615} + vuint64: 18446744073709551615 diff --git a/protogen/example/simple/simple.pb.go b/protogen/example/simple/simple.pb.go index d6073ef4..d83c90e8 100644 --- a/protogen/example/simple/simple.pb.go +++ b/protogen/example/simple/simple.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.30.0 -// protoc v4.23.4 +// protoc v4.24.3 // source: simple.proto package simple @@ -92,6 +92,8 @@ type Reply struct { Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` ReturnCode int32 `protobuf:"varint,2,opt,name=return_code,json=returnCode,proto3" json:"return_code,omitempty"` + Vint64 int64 `protobuf:"varint,3,opt,name=vint64,proto3" json:"vint64,omitempty"` + Vuint64 uint64 `protobuf:"varint,4,opt,name=vuint64,proto3" json:"vuint64,omitempty"` } func (x *Reply) Reset() { @@ -140,6 +142,20 @@ func (x *Reply) GetReturnCode() int32 { return 0 } +func (x *Reply) GetVint64() int64 { + if x != nil { + return x.Vint64 + } + return 0 +} + +func (x *Reply) GetVuint64() uint64 { + if x != nil { + return x.Vuint64 + } + return 0 +} + var File_simple_proto protoreflect.FileDescriptor var file_simple_proto_rawDesc = []byte{ @@ -149,18 +165,21 @@ var file_simple_proto_rawDesc = []byte{ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x76, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, - 0x76, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x22, 0x42, 0x0a, 0x05, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x76, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x22, 0x74, 0x0a, 0x05, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x32, 0x36, 0x0a, 0x08, 0x47, - 0x72, 0x69, 0x70, 0x6d, 0x6f, 0x63, 0x6b, 0x12, 0x2a, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, - 0x6c, 0x6c, 0x6f, 0x12, 0x0f, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x62, 0x61, 0x76, 0x69, 0x78, 0x2f, 0x67, 0x72, 0x69, 0x70, 0x6d, 0x6f, 0x63, 0x6b, - 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, + 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x76, 0x69, 0x6e, + 0x74, 0x36, 0x34, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x32, 0x36, 0x0a, + 0x08, 0x47, 0x72, 0x69, 0x70, 0x6d, 0x6f, 0x63, 0x6b, 0x12, 0x2a, 0x0a, 0x08, 0x53, 0x61, 0x79, + 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x0f, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2e, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x76, 0x69, 0x78, 0x2f, 0x67, 0x72, 0x69, 0x70, 0x6d, 0x6f, + 0x63, 0x6b, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protogen/example/simple/simple_grpc.pb.go b/protogen/example/simple/simple_grpc.pb.go index a431f6d4..8f457ad5 100644 --- a/protogen/example/simple/simple_grpc.pb.go +++ b/protogen/example/simple/simple_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.23.4 +// - protoc v4.24.3 // source: simple.proto package simple