Skip to content

Commit 14059d0

Browse files
authored
Add unimplemented gRPC server embeds to mock servers (#179)
1 parent b13574e commit 14059d0

File tree

5 files changed

+98
-0
lines changed

5 files changed

+98
-0
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ grpc-mock:
8383
mockgen -package operatorservicemock -source operatorservice/v1/service_grpc.pb.go -destination operatorservicemock/v1/service_grpc.pb.mock.go
8484
mockgen -package workflowservicemock -source workflowservice/v1/service_grpc.pb.go -destination workflowservicemock/v1/service_grpc.pb.mock.go
8585
mockgen -package cloudservicemock -source cloud/cloudservice/v1/service_grpc.pb.go -destination cloud/cloudservicemock/v1/service_grpc.pb.mock.go
86+
go run ./cmd/mockgen-fix OperatorService operatorservicemock/v1/service_grpc.pb.mock.go
87+
go run ./cmd/mockgen-fix WorkflowService workflowservicemock/v1/service_grpc.pb.mock.go
88+
go run ./cmd/mockgen-fix CloudService cloud/cloudservicemock/v1/service_grpc.pb.mock.go
8689

8790
.PHONY: proxy
8891
proxy:

cloud/cloudservicemock/v1/service_grpc.pb.mock.go

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/mockgen-fix/main.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// The MIT License
2+
//
3+
// Copyright (c) 2022 Temporal Technologies Inc. All rights reserved.
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in
13+
// all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
// THE SOFTWARE.
22+
23+
package main
24+
25+
import (
26+
"fmt"
27+
"go/format"
28+
"log"
29+
"os"
30+
"strings"
31+
)
32+
33+
func main() {
34+
if err := run(); err != nil {
35+
log.Fatal(err)
36+
}
37+
}
38+
39+
func run() error {
40+
// This code fixes the generated mock service server code to properly embed
41+
// the necessary unimplemented struct and add the interface assertion
42+
43+
if len(os.Args) != 3 {
44+
return fmt.Errorf("must provide service name and code filename as arguments")
45+
}
46+
// Read file
47+
b, err := os.ReadFile(os.Args[2])
48+
if err != nil {
49+
return fmt.Errorf("unable to read file: %w", err)
50+
}
51+
source := string(b)
52+
serviceName := os.Args[1]
53+
54+
// Find the first "Server struct {" location
55+
toFind := fmt.Sprintf("Mock%vServer struct {\n", serviceName)
56+
structIndex := strings.Index(source, toFind)
57+
if structIndex < 0 || strings.LastIndex(source, toFind) != structIndex {
58+
return fmt.Errorf("expected single server struct in file")
59+
}
60+
structIndex += len(toFind)
61+
62+
// At the first newline we need to embed the unimplemented server
63+
source = source[:structIndex] +
64+
fmt.Sprintf("\t%v.Unimplemented%vServer\n", strings.ToLower(serviceName), serviceName) +
65+
source[structIndex:]
66+
67+
// After the closing brace, we need to add the type assertion to ensure
68+
// interface conformance
69+
endBrace := structIndex + strings.Index(source[structIndex:], "}\n") + 2
70+
source = source[:endBrace] +
71+
fmt.Sprintf(
72+
"\nvar _ %v.%vServer = (*Mock%vServer)(nil)\n\n",
73+
strings.ToLower(serviceName),
74+
serviceName,
75+
serviceName,
76+
) +
77+
source[endBrace:]
78+
79+
// Format and write
80+
if b, err := format.Source([]byte(source)); err != nil {
81+
return fmt.Errorf("failed formatting: %w", err)
82+
} else if err := os.WriteFile(os.Args[2], b, 0644); err != nil {
83+
return fmt.Errorf("failed writing: %w", err)
84+
}
85+
return nil
86+
}

operatorservicemock/v1/service_grpc.pb.mock.go

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

workflowservicemock/v1/service_grpc.pb.mock.go

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)