├── .env ├── .envrc ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bin └── .gitkeep ├── buf.gen.yaml ├── buf.yaml ├── cmd ├── client │ ├── detail.go │ ├── health.go │ ├── interceptor.go │ ├── main.go │ ├── metadata.go │ └── status.go └── server │ ├── change_health.go │ ├── detail.go │ ├── interceptor.go │ ├── main.go │ ├── metadata.go │ └── status.go ├── go.mod ├── go.sum └── internal ├── level ├── log.go └── log_test.go ├── stats └── handler.go └── testing ├── services.go ├── testing.pb.go ├── testing.proto └── testing_grpc.pb.go /.env: -------------------------------------------------------------------------------- 1 | PORT=3000 2 | LOG_LEVEL=DEBUG 3 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | dotenv 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _output 2 | bin/* 3 | !bin/.gitkeep 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2020 codehex 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PKG=github.com/Code-Hex/testing-grpc 2 | OUTPUT_DIR=_output 3 | 4 | .PHONY: build 5 | build: 6 | @echo "+ $@" 7 | @echo "+ build server" 8 | go build -o bin/server -trimpath -mod=readonly \ 9 | github.com/Code-Hex/testing-grpc/cmd/server 10 | @echo "+ build client" 11 | go build -o bin/client -trimpath -mod=readonly \ 12 | github.com/Code-Hex/testing-grpc/cmd/client 13 | 14 | proto/compile: 15 | buf generate internal/testing 16 | 17 | proto/clean: 18 | rm -f internal/testing/*.pb.go 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # testing-grpc 2 | 3 | A server and client developed to understand the behavior of gRPC. Mainly intended to be useful for application development using gRPC. 4 | 5 | [![asciicast](https://asciinema.org/a/352507.svg)](https://asciinema.org/a/352507) 6 | 7 | (ascii-art is generated by [neo-cowsay](https://github.com/Code-Hex/neo-cowsay)) 8 | ## build 9 | 10 | ``` 11 | $ make build 12 | 13 | # startup server (default port 3000) 14 | $ ./bin/server 15 | 16 | # startup client (default port 3000) 17 | $ ./bin/client 18 | ``` 19 | 20 | If you want to change port, you can change the environment variable of `PORT`. and you can use `.env` file :D 21 | 22 | ## supported 23 | 24 | - Unary 25 | - [x] status 26 | - [x] error details 27 | - [x] metadata 28 | - [x] [health check](https://github.com/grpc/grpc-go/tree/master/examples/features/health) 29 | - [x] interceptor 30 | - [x] stats 31 | - If you want to disable logging, please set `LOG_LEVEL` to `INFO`. see `.env` file. 32 | - [ ] channelz 33 | 34 | ## gRPC documents 35 | 36 | - [gRPC Concepts Overview](https://github.com/grpc/grpc/blob/master/CONCEPTS.md) 37 | - [Error Handling – gRPC](https://grpc.io/docs/guides/error/) 38 | - [grpc/grpc documents](https://github.com/grpc/grpc/tree/master/doc) 39 | - [go-grpc Learn More](https://github.com/grpc/grpc-go#learn-more) 40 | - [Low-level technical docs](https://github.com/grpc/grpc-go/tree/master/Documentation) 41 | - [features example](https://github.com/grpc/grpc-go/tree/master/examples/features) 42 | - [Language Guide (proto3)](https://developers.google.com/protocol-buffers/docs/proto3) 43 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Hex/testing-grpc/432dc9179fafcf7caf5be41a533496ab22fcb953/bin/.gitkeep -------------------------------------------------------------------------------- /buf.gen.yaml: -------------------------------------------------------------------------------- 1 | # buf.gen.yaml defines a local generation template. 2 | # For details, see https://docs.buf.build/configuration/v1/buf-gen-yaml 3 | version: v1 4 | plugins: 5 | - name: go 6 | out: internal/testing 7 | opt: paths=source_relative 8 | - name: go-grpc 9 | out: internal/testing 10 | opt: 11 | - paths=source_relative 12 | - require_unimplemented_servers=false 13 | -------------------------------------------------------------------------------- /buf.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | deps: 3 | - buf.build/protocolbuffers/wellknowntypes 4 | breaking: 5 | use: 6 | - FILE 7 | lint: 8 | use: 9 | - DEFAULT 10 | -------------------------------------------------------------------------------- /cmd/client/detail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "github.com/ktr0731/go-fuzzyfinder" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | var details = []testing.DetailGetRequest_Code{ 12 | testing.DetailGetRequest_OK, 13 | testing.DetailGetRequest_RETRY_INFO, 14 | testing.DetailGetRequest_DEBUG_INFO, 15 | testing.DetailGetRequest_QUOTA_FAILURE, 16 | testing.DetailGetRequest_ERROR_INFO, 17 | testing.DetailGetRequest_PRECONDITION_FAILURE, 18 | testing.DetailGetRequest_BAD_REQUEST, 19 | testing.DetailGetRequest_REQUEST_INFO, 20 | testing.DetailGetRequest_RESOURCE_INFO, 21 | testing.DetailGetRequest_HELP, 22 | testing.DetailGetRequest_LOCALIZED_MESSAGE, 23 | testing.DetailGetRequest_COMBINED_ALL, 24 | } 25 | 26 | func (c *Client) runDetailClient(ctx context.Context) error { 27 | idx, err := fuzzyfinder.Find(details, func(i int) string { 28 | return details[i].String() 29 | }) 30 | if err != nil { 31 | if errors.Is(err, fuzzyfinder.ErrAbort) { 32 | return nil 33 | } 34 | return errors.WithStack(err) 35 | } 36 | req := &testing.DetailGetRequest{ 37 | Code: details[idx], 38 | } 39 | resp, err := c.DetailClient.Get(ctx, req) 40 | if err != nil { 41 | loggingDetails(err) 42 | } else { 43 | log.Info().Interface("response", resp).Msg("success") 44 | } 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /cmd/client/health.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "github.com/ktr0731/go-fuzzyfinder" 8 | "github.com/pkg/errors" 9 | healthpb "google.golang.org/grpc/health/grpc_health_v1" 10 | ) 11 | 12 | var healthStatus = []testing.SetRequest_HealthCheckStatus{ 13 | testing.SetRequest_UNKNOWN, 14 | testing.SetRequest_SERVING, 15 | testing.SetRequest_NOT_SERVING, 16 | testing.SetRequest_SERVICE_UNKNOWN, 17 | } 18 | 19 | func (c *Client) runChangeHealth(ctx context.Context) error { 20 | idx, err := fuzzyfinder.Find(healthStatus, func(i int) string { 21 | return healthStatus[i].String() 22 | }) 23 | if err != nil { 24 | if errors.Is(err, fuzzyfinder.ErrAbort) { 25 | return nil 26 | } 27 | return errors.WithStack(err) 28 | } 29 | resp, err := c.ChangeHealth.Set(ctx, &testing.SetRequest{Status: healthStatus[idx]}) 30 | if err != nil { 31 | loggingDetails(err) 32 | } else { 33 | log.Info().Interface("response", resp).Msg("success") 34 | } 35 | return nil 36 | } 37 | 38 | func (c *Client) runHealthClient(ctx context.Context) error { 39 | req := &healthpb.HealthCheckRequest{ 40 | Service: testing.ChangeHealth, 41 | } 42 | resp, err := c.HealthClient.Check(ctx, req) 43 | if err != nil { 44 | loggingDetails(err) 45 | } else { 46 | log.Info().Stringer("response", resp.Status).Msg("success") 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /cmd/client/interceptor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "github.com/Songmu/prompter" 8 | "google.golang.org/grpc" 9 | ) 10 | 11 | func DoLogServerInterceptor(s string) grpc.UnaryClientInterceptor { 12 | return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 13 | if method != "/testing.Interceptor/Echo" { 14 | return invoker(ctx, method, req, reply, cc, opts...) 15 | } 16 | log.Info(). 17 | Interface("method", method). 18 | Interface("req", req). 19 | Msg(s) 20 | 21 | err := invoker(ctx, method, req, reply, cc, opts...) 22 | 23 | log.Info(). 24 | Interface("reply", reply). 25 | Err(err). 26 | Msg(s) 27 | 28 | return err 29 | } 30 | } 31 | 32 | func (c *Client) runInterceptorClient(ctx context.Context) { 33 | msg := prompter.Prompt("message", "default-message") 34 | resp, err := c.InterceptorClient.Echo(ctx, &testing.EchoRequest{Msg: msg}) 35 | if err != nil { 36 | loggingDetails(err) 37 | } else { 38 | log.Info().Interface("response", resp).Msg("success") 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cmd/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | 10 | "github.com/Code-Hex/testing-grpc/internal/level" 11 | "github.com/Code-Hex/testing-grpc/internal/stats" 12 | "github.com/Code-Hex/testing-grpc/internal/testing" 13 | "github.com/Songmu/prompter" 14 | grpczerolog "github.com/cheapRoc/grpc-zerolog" 15 | "github.com/jhump/protoreflect/grpcreflect" 16 | "github.com/ktr0731/go-fuzzyfinder" 17 | "github.com/pkg/errors" 18 | "github.com/rs/zerolog" 19 | "google.golang.org/grpc" 20 | "google.golang.org/grpc/grpclog" 21 | healthpb "google.golang.org/grpc/health/grpc_health_v1" 22 | rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" 23 | "google.golang.org/grpc/status" 24 | 25 | // Necessary to print errdetails. 26 | _ "google.golang.org/genproto/googleapis/rpc/errdetails" 27 | ) 28 | 29 | var log zerolog.Logger 30 | 31 | func init() { 32 | log = zerolog.New( 33 | zerolog.ConsoleWriter{ 34 | Out: os.Stderr, 35 | }). 36 | With(). 37 | Timestamp(). 38 | Logger(). 39 | Level(level.Log(os.Getenv("LOG_LEVEL"))) 40 | grpclog.SetLoggerV2(grpczerolog.New(log)) 41 | } 42 | 43 | func main() { 44 | if err := run(context.Background()); err != nil { 45 | fmt.Fprintf(os.Stderr, "%+v\n", err) 46 | os.Exit(1) 47 | } 48 | } 49 | 50 | func run(ctx context.Context) error { 51 | port := os.Getenv("PORT") 52 | if port == "" { 53 | port = "3000" 54 | } 55 | 56 | conn, err := grpc.Dial(":"+port, 57 | grpc.WithInsecure(), 58 | grpc.WithStatsHandler(stats.NewHandler(log)), 59 | grpc.WithChainUnaryInterceptor( 60 | DoLogServerInterceptor("A"), 61 | DoLogServerInterceptor("B"), 62 | ), 63 | ) 64 | if err != nil { 65 | return errors.WithStack(err) 66 | } 67 | 68 | client := &Client{ 69 | StatusClient: testing.NewStatusClient(conn), 70 | DetailClient: testing.NewDetailClient(conn), 71 | MetadataClient: testing.NewMetadataClient(conn), 72 | ChangeHealth: testing.NewChangeHealthClient(conn), 73 | HealthClient: healthpb.NewHealthClient(conn), 74 | InterceptorClient: testing.NewInterceptorClient(conn), 75 | } 76 | reflectClient := newServerReflectionClient(ctx, conn) 77 | 78 | sigCh := make(chan os.Signal, 1) 79 | signal.Notify(sigCh, syscall.SIGTERM, os.Interrupt) 80 | ctx, cancel := context.WithCancel(ctx) 81 | 82 | go func() { 83 | <-sigCh 84 | cancel() 85 | }() 86 | 87 | // List gRPC services 88 | services, err := reflectClient.ListServices() 89 | if err != nil { 90 | return errors.WithStack(err) 91 | } 92 | 93 | LOOP: 94 | for { 95 | select { 96 | case <-ctx.Done(): 97 | break LOOP 98 | default: 99 | } 100 | 101 | // grpc.reflection.v1alpha.ServerReflection 102 | si, err := fuzzyfinder.Find(services, func(i int) string { 103 | return services[i] 104 | }) 105 | if err != nil { 106 | if errors.Is(err, fuzzyfinder.ErrAbort) { 107 | return nil 108 | } 109 | return errors.WithStack(err) 110 | } 111 | 112 | switch services[si] { 113 | case testing.Status: 114 | if err := client.runStatusClient(ctx); err != nil { 115 | return err 116 | } 117 | case testing.Detail: 118 | if err := client.runDetailClient(ctx); err != nil { 119 | return err 120 | } 121 | case testing.Metadata: 122 | if err := client.runMetadataClient(ctx); err != nil { 123 | return err 124 | } 125 | case testing.ChangeHealth: 126 | if err := client.runChangeHealth(ctx); err != nil { 127 | return err 128 | } 129 | case "grpc.health.v1.Health": 130 | if err := client.runHealthClient(ctx); err != nil { 131 | return err 132 | } 133 | case testing.Interceptor: 134 | client.runInterceptorClient(ctx) 135 | default: 136 | continue LOOP 137 | } 138 | if !prompter.YN("continue?", true) { 139 | break 140 | } 141 | } 142 | 143 | return nil 144 | } 145 | 146 | type Client struct { 147 | StatusClient testing.StatusClient 148 | DetailClient testing.DetailClient 149 | MetadataClient testing.MetadataClient 150 | ChangeHealth testing.ChangeHealthClient 151 | HealthClient healthpb.HealthClient 152 | InterceptorClient testing.InterceptorClient 153 | } 154 | 155 | func newServerReflectionClient(ctx context.Context, conn *grpc.ClientConn) *grpcreflect.Client { 156 | cli := rpb.NewServerReflectionClient(conn) 157 | return grpcreflect.NewClient(ctx, cli) 158 | } 159 | 160 | func loggingDetails(err error) { 161 | logging := log.Error().Err(err) 162 | st, ok := status.FromError(err) 163 | if ok { 164 | for idx, d := range st.Details() { 165 | logging.Interface( 166 | fmt.Sprintf("details[%d]", idx), 167 | d, 168 | ) 169 | } 170 | } 171 | logging.Msg("error") 172 | } 173 | -------------------------------------------------------------------------------- /cmd/client/metadata.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/Songmu/prompter" 8 | "github.com/golang/protobuf/ptypes/empty" 9 | "google.golang.org/grpc/metadata" 10 | ) 11 | 12 | func (c *Client) runMetadataClient(ctx context.Context) error { 13 | md := make([]string, 0) 14 | // https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md#sending-metadata 15 | for { 16 | key := prompter.Prompt("key", "default-key") 17 | value := prompter.Prompt("values (Become an array by comma-separated)", "default-value") 18 | vals := strings.Split(value, ",") 19 | for _, val := range vals { 20 | md = append(md, key, val) 21 | } 22 | if !prompter.YN("metadata continue?", true) { 23 | break 24 | } 25 | } 26 | ctx = metadata.AppendToOutgoingContext(ctx, md...) 27 | resp, err := c.MetadataClient.Get(ctx, &empty.Empty{}) 28 | if err != nil { 29 | loggingDetails(err) 30 | } else { 31 | log.Info().Interface("response", resp).Msg("success") 32 | } 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /cmd/client/status.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "github.com/ktr0731/go-fuzzyfinder" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | var statuses = []testing.StatusGetRequest_Code{ 12 | testing.StatusGetRequest_OK, 13 | testing.StatusGetRequest_CANCELED, 14 | testing.StatusGetRequest_UNKNOWN, 15 | testing.StatusGetRequest_INVALIDARGUMENT, 16 | testing.StatusGetRequest_DEADLINE_EXCEEDED, 17 | testing.StatusGetRequest_NOT_FOUND, 18 | testing.StatusGetRequest_ALREADY_EXISTS, 19 | testing.StatusGetRequest_PERMISSION_DENIED, 20 | testing.StatusGetRequest_RESOURCE_EXHAUSTED, 21 | testing.StatusGetRequest_FAILED_PRECONDITION, 22 | testing.StatusGetRequest_ABORTED, 23 | testing.StatusGetRequest_OUT_OF_RANGE, 24 | testing.StatusGetRequest_UNIMPLEMENTED, 25 | testing.StatusGetRequest_INTERNAL, 26 | testing.StatusGetRequest_UNAVAILABLE, 27 | testing.StatusGetRequest_DATALOSS, 28 | testing.StatusGetRequest_UNAUTHENTICATED, 29 | } 30 | 31 | func (c *Client) runStatusClient(ctx context.Context) error { 32 | idx, err := fuzzyfinder.Find(statuses, func(i int) string { 33 | return statuses[i].String() 34 | }) 35 | if err != nil { 36 | if errors.Is(err, fuzzyfinder.ErrAbort) { 37 | return nil 38 | } 39 | return errors.WithStack(err) 40 | } 41 | req := &testing.StatusGetRequest{ 42 | Code: statuses[idx], 43 | } 44 | resp, err := c.StatusClient.Get(ctx, req) 45 | if err != nil { 46 | loggingDetails(err) 47 | } else { 48 | log.Info().Interface("response", resp).Msg("success") 49 | } 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /cmd/server/change_health.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "google.golang.org/grpc/health" 8 | healthpb "google.golang.org/grpc/health/grpc_health_v1" 9 | emptypb "google.golang.org/protobuf/types/known/emptypb" 10 | ) 11 | 12 | type ChangeHealth struct { 13 | healthcheck *health.Server 14 | } 15 | 16 | func newChangeHealth(healthcheck *health.Server) *ChangeHealth { 17 | healthcheck.SetServingStatus( 18 | testing.ChangeHealth, 19 | healthpb.HealthCheckResponse_SERVING, 20 | ) 21 | return &ChangeHealth{healthcheck: healthcheck} 22 | } 23 | 24 | var _ testing.ChangeHealthServer = (*ChangeHealth)(nil) 25 | 26 | func (c *ChangeHealth) Set(ctx context.Context, req *testing.SetRequest) (*emptypb.Empty, error) { 27 | c.healthcheck.SetServingStatus( 28 | testing.ChangeHealth, 29 | convToServingStatus(req.Status), 30 | ) 31 | return &emptypb.Empty{}, nil 32 | } 33 | 34 | func convToServingStatus(s testing.SetRequest_HealthCheckStatus) healthpb.HealthCheckResponse_ServingStatus { 35 | switch s { 36 | case testing.SetRequest_SERVING: 37 | return healthpb.HealthCheckResponse_SERVING 38 | case testing.SetRequest_NOT_SERVING: 39 | return healthpb.HealthCheckResponse_NOT_SERVING 40 | case testing.SetRequest_SERVICE_UNKNOWN: 41 | return healthpb.HealthCheckResponse_SERVICE_UNKNOWN 42 | } 43 | return healthpb.HealthCheckResponse_UNKNOWN 44 | } 45 | -------------------------------------------------------------------------------- /cmd/server/detail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "runtime" 7 | "sort" 8 | "strings" 9 | 10 | "github.com/Code-Hex/testing-grpc/internal/testing" 11 | "github.com/pkg/errors" 12 | "google.golang.org/genproto/googleapis/rpc/errdetails" 13 | "google.golang.org/grpc/codes" 14 | "google.golang.org/grpc/status" 15 | "google.golang.org/protobuf/proto" 16 | "google.golang.org/protobuf/runtime/protoiface" 17 | "google.golang.org/protobuf/runtime/protoimpl" 18 | durationpb "google.golang.org/protobuf/types/known/durationpb" 19 | ) 20 | 21 | var _ testing.DetailServer = (*Detail)(nil) 22 | 23 | type Detail struct{} 24 | 25 | func (d *Detail) Get(ctx context.Context, req *testing.DetailGetRequest) (*testing.DetailGetResponse, error) { 26 | if err := convertToDetails(req.Code); err != nil { 27 | return nil, err 28 | } 29 | return &testing.DetailGetResponse{ 30 | Msg: "OK details!!", 31 | }, nil 32 | } 33 | 34 | var details = map[testing.DetailGetRequest_Code]proto.Message{ 35 | testing.DetailGetRequest_RETRY_INFO: &errdetails.RetryInfo{ 36 | RetryDelay: &durationpb.Duration{ 37 | Seconds: 2, 38 | Nanos: 100, 39 | }, 40 | }, 41 | testing.DetailGetRequest_DEBUG_INFO: &errdetails.DebugInfo{ 42 | StackEntries: stackTraces(), 43 | Detail: "debug info testing", 44 | }, 45 | testing.DetailGetRequest_QUOTA_FAILURE: &errdetails.QuotaFailure{ 46 | Violations: []*errdetails.QuotaFailure_Violation{ 47 | { 48 | Subject: "memory quota", 49 | Description: "used 1GB", 50 | }, 51 | { 52 | Subject: "API quota", 53 | Description: "used 100request/1month", 54 | }, 55 | }, 56 | }, 57 | testing.DetailGetRequest_ERROR_INFO: &errdetails.ErrorInfo{ 58 | Reason: "i/o timeout between application and database", 59 | Domain: "items", 60 | Metadata: map[string]string{ 61 | "query": "SELECT * FROM items", 62 | "function": "makeItem", 63 | }, 64 | }, 65 | testing.DetailGetRequest_PRECONDITION_FAILURE: &errdetails.PreconditionFailure{ 66 | Violations: []*errdetails.PreconditionFailure_Violation{ 67 | { 68 | Type: "ENUM_USER_SERVICE_DOWN", 69 | Subject: "user-service", 70 | Description: "Terms of service not accepted", 71 | }, 72 | }, 73 | }, 74 | testing.DetailGetRequest_BAD_REQUEST: &errdetails.BadRequest{ 75 | FieldViolations: []*errdetails.BadRequest_FieldViolation{ 76 | { 77 | Field: "request.item.id", 78 | Description: "invalid format", 79 | }, 80 | { 81 | Field: "request.category.sku_id", 82 | Description: "unexpected format: expected uppercases", 83 | }, 84 | }, 85 | }, 86 | testing.DetailGetRequest_REQUEST_INFO: &errdetails.RequestInfo{ 87 | RequestId: "8DA1D58282DD43138804B7E75C86A50F", 88 | ServingData: "c3RhY2t0cmFjZQo=", 89 | }, 90 | testing.DetailGetRequest_RESOURCE_INFO: &errdetails.ResourceInfo{ 91 | ResourceType: "file", 92 | ResourceName: "codeowners", 93 | Owner: "codehex", 94 | Description: "permission denied", 95 | }, 96 | testing.DetailGetRequest_HELP: &errdetails.Help{ 97 | Links: []*errdetails.Help_Link{ 98 | { 99 | Description: "please contact users team", 100 | Url: "http://wiki.users-team.com", 101 | }, 102 | }, 103 | }, 104 | testing.DetailGetRequest_LOCALIZED_MESSAGE: &errdetails.LocalizedMessage{ 105 | Locale: "en-US", 106 | Message: "message to en-US", 107 | }, 108 | } 109 | 110 | func convertToDetails(c testing.DetailGetRequest_Code) error { 111 | switch c { 112 | case testing.DetailGetRequest_RETRY_INFO: 113 | return makeDetailsErr(codes.Unavailable, "retry please", details[c]) 114 | case testing.DetailGetRequest_DEBUG_INFO: 115 | return makeDetailsErr(codes.Internal, "something wrong", details[c]) 116 | case testing.DetailGetRequest_QUOTA_FAILURE: 117 | return makeDetailsErr(codes.Unavailable, "limit exceeded", details[c]) 118 | case testing.DetailGetRequest_ERROR_INFO: 119 | return makeDetailsErr(codes.Internal, "caused internal error", details[c]) 120 | case testing.DetailGetRequest_PRECONDITION_FAILURE: 121 | return makeDetailsErr(codes.FailedPrecondition, "caused some error", details[c]) 122 | case testing.DetailGetRequest_BAD_REQUEST: 123 | return makeDetailsErr(codes.InvalidArgument, "invalid retuest fields", details[c]) 124 | case testing.DetailGetRequest_REQUEST_INFO: 125 | return makeDetailsErr(codes.Internal, "something wrong", details[c]) 126 | case testing.DetailGetRequest_RESOURCE_INFO: 127 | return makeDetailsErr(codes.PermissionDenied, "resource error", details[c]) 128 | case testing.DetailGetRequest_HELP: 129 | return makeDetailsErr(codes.Unavailable, "temporary unavailable", details[c]) 130 | case testing.DetailGetRequest_LOCALIZED_MESSAGE: 131 | return makeDetailsErr(codes.Internal, "something wrong", details[c]) 132 | case testing.DetailGetRequest_COMBINED_ALL: 133 | keys := make([]testing.DetailGetRequest_Code, 0, len(details)) 134 | for key := range details { 135 | keys = append(keys, key) 136 | } 137 | sort.Slice(keys, func(i, j int) bool { 138 | return keys[i] < keys[j] 139 | }) 140 | d := make([]proto.Message, len(details)) 141 | for i, key := range keys { 142 | d[i] = details[key] 143 | } 144 | return makeDetailsErr(codes.Unknown, "combined all details", d...) 145 | } 146 | return nil 147 | } 148 | 149 | func stackTraces() []string { 150 | pc := make([]uintptr, 3) 151 | n := runtime.Callers(0, pc) 152 | if n == 0 { 153 | return []string{} 154 | } 155 | ret := make([]string, 0, 3) 156 | frames := runtime.CallersFrames(pc[:n]) 157 | for { 158 | frame, more := frames.Next() 159 | // To keep this example's output stable 160 | // even if there are changes in the testing package, 161 | // stop unwinding when we leave package runtime. 162 | if !strings.Contains(frame.File, "runtime/") { 163 | break 164 | } 165 | ret = append(ret, 166 | fmt.Sprintf( 167 | "file: %s, line: %d, %s", 168 | frame.File, frame.Line, frame.Function, 169 | ), 170 | ) 171 | if !more { 172 | break 173 | } 174 | } 175 | return ret 176 | } 177 | 178 | func makeDetailsErr(code codes.Code, msg string, d ...proto.Message) error { 179 | detailsV1 := make([]protoiface.MessageV1, len(d)) 180 | for i, m := range d { 181 | detailsV1[i] = protoimpl.X.ProtoMessageV1Of(m) 182 | } 183 | st, err := status.New(code, msg).WithDetails(detailsV1...) 184 | if err != nil { 185 | return errors.WithStack(err) 186 | } 187 | return st.Err() 188 | } 189 | -------------------------------------------------------------------------------- /cmd/server/interceptor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "google.golang.org/grpc" 8 | ) 9 | 10 | func DoLogServerInterceptor(s string) grpc.UnaryServerInterceptor { 11 | return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 12 | if info.FullMethod != "/testing.Interceptor/Echo" { 13 | return handler(ctx, req) 14 | } 15 | log.Info(). 16 | Interface("info", info). 17 | Interface("req", req). 18 | Msg(s) 19 | 20 | resp, err := handler(ctx, req) 21 | 22 | log.Info(). 23 | Interface("response", resp). 24 | Err(err). 25 | Msg(s) 26 | 27 | return resp, err 28 | } 29 | } 30 | 31 | type Interceptor struct{} 32 | 33 | var _ testing.InterceptorServer = (*Interceptor)(nil) 34 | 35 | func (i *Interceptor) Echo(_ context.Context, req *testing.EchoRequest) (*testing.EchoResponse, error) { 36 | log.Info(). 37 | Str("msg", req.Msg). 38 | Msg("called Echo()") 39 | return &testing.EchoResponse{Msg: req.Msg}, nil 40 | } 41 | -------------------------------------------------------------------------------- /cmd/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | 11 | "github.com/Code-Hex/testing-grpc/internal/level" 12 | "github.com/Code-Hex/testing-grpc/internal/stats" 13 | "github.com/Code-Hex/testing-grpc/internal/testing" 14 | grpczerolog "github.com/cheapRoc/grpc-zerolog" 15 | "github.com/pkg/errors" 16 | "github.com/rs/zerolog" 17 | "google.golang.org/grpc" 18 | "google.golang.org/grpc/grpclog" 19 | "google.golang.org/grpc/health" 20 | healthpb "google.golang.org/grpc/health/grpc_health_v1" 21 | "google.golang.org/grpc/reflection" 22 | ) 23 | 24 | var log zerolog.Logger 25 | 26 | func init() { 27 | log = zerolog.New( 28 | zerolog.ConsoleWriter{ 29 | Out: os.Stderr, 30 | }). 31 | With(). 32 | Timestamp(). 33 | Logger(). 34 | Level(level.Log(os.Getenv("LOG_LEVEL"))) 35 | 36 | grpclog.SetLoggerV2(grpczerolog.New(log)) 37 | } 38 | 39 | func main() { 40 | if err := run(context.Background()); err != nil { 41 | fmt.Fprintf(os.Stderr, "%+v\n", err) 42 | os.Exit(1) 43 | } 44 | } 45 | 46 | func run(ctx context.Context) error { 47 | srv := newServer() 48 | 49 | port := os.Getenv("PORT") 50 | if port == "" { 51 | port = "3000" 52 | } 53 | 54 | ln, err := net.Listen("tcp", "localhost:"+port) 55 | if err != nil { 56 | return errors.WithStack(err) 57 | } 58 | log.Info().Str("port", port).Msg("Running server") 59 | 60 | go srv.Serve(ln) 61 | 62 | sigCh := make(chan os.Signal, 1) 63 | signal.Notify(sigCh, syscall.SIGTERM, os.Interrupt) 64 | select { 65 | case <-sigCh: 66 | log.Info().Msg("received SIGTERM, exiting server gracefully") 67 | case <-ctx.Done(): 68 | } 69 | go srv.GracefulStop() 70 | 71 | return nil 72 | } 73 | 74 | func newServer() *grpc.Server { 75 | srv := grpc.NewServer( 76 | grpc.StatsHandler(stats.NewHandler(log)), 77 | grpc.ChainUnaryInterceptor( 78 | DoLogServerInterceptor("A"), 79 | DoLogServerInterceptor("B"), 80 | ), 81 | ) 82 | 83 | // health check service 84 | healthcheck := health.NewServer() 85 | healthpb.RegisterHealthServer(srv, healthcheck) 86 | 87 | // register gRPC services 88 | testing.RegisterStatusServer(srv, &Status{}) 89 | testing.RegisterDetailServer(srv, &Detail{}) 90 | testing.RegisterMetadataServer(srv, &Metadata{}) 91 | testing.RegisterChangeHealthServer(srv, newChangeHealth(healthcheck)) 92 | testing.RegisterInterceptorServer(srv, &Interceptor{}) 93 | 94 | // enable reflection 95 | reflection.Register(srv) 96 | 97 | return srv 98 | } 99 | -------------------------------------------------------------------------------- /cmd/server/metadata.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "sort" 6 | 7 | "github.com/Code-Hex/testing-grpc/internal/testing" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/metadata" 10 | "google.golang.org/grpc/status" 11 | emptypb "google.golang.org/protobuf/types/known/emptypb" 12 | ) 13 | 14 | var _ testing.MetadataServer = (*Metadata)(nil) 15 | 16 | type Metadata struct{} 17 | 18 | func (m *Metadata) Get(ctx context.Context, _ *emptypb.Empty) (*testing.MetadataGetResponse, error) { 19 | // https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md#retrieving-metadata-from-context 20 | md, ok := metadata.FromIncomingContext(ctx) 21 | if !ok { 22 | return nil, status.Error(codes.NotFound, "metadata is not found") 23 | } 24 | keys := make([]string, 0, len(md)) 25 | for key := range md { 26 | keys = append(keys, key) 27 | } 28 | sort.Strings(keys) 29 | 30 | entries := make([]*testing.MetadataGetResponse_Entry, len(keys)) 31 | for i, key := range keys { 32 | entries[i] = &testing.MetadataGetResponse_Entry{ 33 | Key: key, 34 | Value: md[key], 35 | } 36 | } 37 | return &testing.MetadataGetResponse{ 38 | Metadata: entries, 39 | }, nil 40 | } 41 | -------------------------------------------------------------------------------- /cmd/server/status.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/Code-Hex/testing-grpc/internal/testing" 7 | "google.golang.org/grpc/codes" 8 | "google.golang.org/grpc/status" 9 | ) 10 | 11 | var _ testing.StatusServer = (*Status)(nil) 12 | 13 | type Status struct{} 14 | 15 | func (s *Status) Get(ctx context.Context, req *testing.StatusGetRequest) (*testing.StatusGetResponse, error) { 16 | if err := convertToCode(req.Code); err != nil { 17 | return nil, err 18 | } 19 | return &testing.StatusGetResponse{ 20 | Msg: "Hello, World", 21 | }, nil 22 | } 23 | 24 | func codeErr(code codes.Code) error { 25 | return status.Error(code, code.String()) 26 | } 27 | 28 | func convertToCode(c testing.StatusGetRequest_Code) error { 29 | switch c { 30 | case testing.StatusGetRequest_CANCELED: 31 | return codeErr(codes.Canceled) 32 | case testing.StatusGetRequest_UNKNOWN: 33 | return codeErr(codes.Unknown) 34 | case testing.StatusGetRequest_INVALIDARGUMENT: 35 | return codeErr(codes.InvalidArgument) 36 | case testing.StatusGetRequest_DEADLINE_EXCEEDED: 37 | return codeErr(codes.DeadlineExceeded) 38 | case testing.StatusGetRequest_NOT_FOUND: 39 | return codeErr(codes.NotFound) 40 | case testing.StatusGetRequest_ALREADY_EXISTS: 41 | return codeErr(codes.AlreadyExists) 42 | case testing.StatusGetRequest_PERMISSION_DENIED: 43 | return codeErr(codes.PermissionDenied) 44 | case testing.StatusGetRequest_RESOURCE_EXHAUSTED: 45 | return codeErr(codes.ResourceExhausted) 46 | case testing.StatusGetRequest_FAILED_PRECONDITION: 47 | return codeErr(codes.FailedPrecondition) 48 | case testing.StatusGetRequest_ABORTED: 49 | return codeErr(codes.Aborted) 50 | case testing.StatusGetRequest_OUT_OF_RANGE: 51 | return codeErr(codes.OutOfRange) 52 | case testing.StatusGetRequest_UNIMPLEMENTED: 53 | return codeErr(codes.Unimplemented) 54 | case testing.StatusGetRequest_INTERNAL: 55 | return codeErr(codes.Internal) 56 | case testing.StatusGetRequest_UNAVAILABLE: 57 | return codeErr(codes.Unavailable) 58 | case testing.StatusGetRequest_DATALOSS: 59 | return codeErr(codes.DataLoss) 60 | case testing.StatusGetRequest_UNAUTHENTICATED: 61 | return codeErr(codes.Unauthenticated) 62 | } 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Code-Hex/testing-grpc 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/Songmu/prompter v0.5.1 7 | github.com/cheapRoc/grpc-zerolog v0.0.0-20180425150930-27ca9d023ead 8 | github.com/golang/protobuf v1.5.3 9 | github.com/jhump/protoreflect v1.15.1 10 | github.com/ktr0731/go-fuzzyfinder v0.2.1 11 | github.com/pkg/errors v0.9.1 12 | github.com/rs/zerolog v1.19.0 13 | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 14 | google.golang.org/grpc v1.56.2 15 | google.golang.org/protobuf v1.31.0 16 | ) 17 | -------------------------------------------------------------------------------- /internal/level/log.go: -------------------------------------------------------------------------------- 1 | package level 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/rs/zerolog" 7 | ) 8 | 9 | func Log(s string) zerolog.Level { 10 | switch strings.ToUpper(s) { 11 | case "INFO": 12 | return zerolog.InfoLevel 13 | case "WARN": 14 | return zerolog.WarnLevel 15 | case "ERROR": 16 | return zerolog.ErrorLevel 17 | } 18 | return zerolog.DebugLevel 19 | } 20 | -------------------------------------------------------------------------------- /internal/level/log_test.go: -------------------------------------------------------------------------------- 1 | package level 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/rs/zerolog" 7 | ) 8 | 9 | func TestLog(t *testing.T) { 10 | tests := []struct { 11 | name string 12 | s string 13 | want zerolog.Level 14 | }{ 15 | { 16 | name: "DEBUG", 17 | s: "", 18 | want: zerolog.DebugLevel, 19 | }, 20 | { 21 | name: "INFO", 22 | s: "info", 23 | want: zerolog.InfoLevel, 24 | }, 25 | { 26 | name: "WARN", 27 | s: "WARN", 28 | want: zerolog.WarnLevel, 29 | }, 30 | { 31 | name: "ERROR", 32 | s: "error", 33 | want: zerolog.ErrorLevel, 34 | }, 35 | } 36 | for _, tt := range tests { 37 | t.Run(tt.name, func(t *testing.T) { 38 | got := Log(tt.s) 39 | if tt.want != got { 40 | t.Errorf("Log() = %v, want %v", got, tt.want) 41 | } 42 | }) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /internal/stats/handler.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/rs/zerolog" 7 | "google.golang.org/grpc/stats" 8 | "google.golang.org/grpc/status" 9 | ) 10 | 11 | var _ stats.Handler = (*Handler)(nil) 12 | 13 | type Handler struct { 14 | logger zerolog.Logger 15 | } 16 | 17 | func NewHandler(logger zerolog.Logger) *Handler { 18 | return &Handler{logger} 19 | } 20 | 21 | func (h *Handler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { 22 | h.logger.Debug(). 23 | Str("FullMethodName", info.FullMethodName). 24 | Bool("FailFast", info.FailFast). 25 | Msg("TagRPC") 26 | return ctx 27 | } 28 | 29 | func (h *Handler) HandleRPC(ctx context.Context, s stats.RPCStats) { 30 | switch st := s.(type) { 31 | case *stats.Begin: 32 | h.logger.Debug(). 33 | Bool("IsClient", st.IsClient()). 34 | Time("BeginTime", st.BeginTime). 35 | Bool("FailFast", st.FailFast). 36 | Msg("stats Begin") 37 | case *stats.OutHeader: 38 | h.logger.Debug(). 39 | Bool("IsClient", st.IsClient()). 40 | Str("Compression", st.Compression). 41 | Interface("Header", st.Header). 42 | Str("FullMethod", st.FullMethod). 43 | Stringer("RemoteAddr", st.RemoteAddr). 44 | Stringer("LocalAddr", st.LocalAddr). 45 | Msg("stats OutHeader") 46 | case *stats.OutPayload: 47 | h.logger.Debug(). 48 | Bool("IsClient", st.IsClient()). 49 | Interface("Payload", st.Payload). 50 | Bytes("Data", st.Data). 51 | Int("Length", st.Length). 52 | Int("WireLength", st.WireLength). 53 | Time("SentTime", st.SentTime). 54 | Msg("stats OutPayload") 55 | case *stats.OutTrailer: 56 | h.logger.Debug(). 57 | Bool("IsClient", st.IsClient()). 58 | Int("WireLength", st.WireLength). 59 | Interface("Trailer", st.Trailer). 60 | Msg("stats OutTrailer") 61 | case *stats.InHeader: 62 | h.logger.Debug(). 63 | Bool("IsClient", st.IsClient()). 64 | Int("WireLength", st.WireLength). 65 | Str("Compression", st.Compression). 66 | Interface("Header", st.Header). 67 | Str("FullMethod", st.FullMethod). 68 | Stringer("RemoteAddr", st.RemoteAddr). 69 | Stringer("LocalAddr", st.LocalAddr). 70 | Msg("stats InHeader") 71 | case *stats.InPayload: 72 | h.logger.Debug(). 73 | Bool("IsClient", st.IsClient()). 74 | Interface("Payload", st.Payload). 75 | Bytes("Data", st.Data). 76 | Int("Length", st.Length). 77 | Int("WireLength", st.WireLength). 78 | Time("RecvTime", st.RecvTime). 79 | Msg("stats InPayload") 80 | case *stats.InTrailer: 81 | h.logger.Debug(). 82 | Bool("IsClient", st.IsClient()). 83 | Int("WireLength", st.WireLength). 84 | Interface("Trailer", st.Trailer). 85 | Msg("stats InTrailer") 86 | case *stats.End: 87 | ev := h.logger.Debug(). 88 | Bool("IsClient", st.IsClient()). 89 | Time("BeginTime", st.BeginTime). 90 | Time("EndTime", st.EndTime). 91 | Interface("Trailer", st.Trailer). 92 | Err(st.Error) 93 | gRPCst, ok := status.FromError(st.Error) 94 | if ok { 95 | ev = ev.Interface("details", gRPCst.Details()) 96 | } 97 | ev.Msg("stats End") 98 | default: 99 | h.logger.Error(). 100 | Interface("stats", st).Msg("unknwon") 101 | } 102 | } 103 | 104 | func (h *Handler) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context { 105 | h.logger.Debug(). 106 | Stringer("RemoteAddr", info.RemoteAddr). 107 | Stringer("LocalAddr", info.LocalAddr). 108 | Msg("TagConn") 109 | return context.Background() 110 | } 111 | 112 | func (h *Handler) HandleConn(ctx context.Context, st stats.ConnStats) { 113 | h.logger.Debug(). 114 | Bool("IsClient", st.IsClient()). 115 | Msg("HandleConn") 116 | } 117 | -------------------------------------------------------------------------------- /internal/testing/services.go: -------------------------------------------------------------------------------- 1 | package testing 2 | 3 | const ( 4 | Status = "testing.Status" 5 | Detail = "testing.Detail" 6 | Metadata = "testing.Metadata" 7 | ChangeHealth = "testing.ChangeHealth" 8 | Interceptor = "testing.Interceptor" 9 | ) 10 | -------------------------------------------------------------------------------- /internal/testing/testing.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.1 4 | // protoc (unknown) 5 | // source: testing.proto 6 | 7 | package testing 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | emptypb "google.golang.org/protobuf/types/known/emptypb" 13 | reflect "reflect" 14 | sync "sync" 15 | ) 16 | 17 | const ( 18 | // Verify that this generated code is sufficiently up-to-date. 19 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 20 | // Verify that runtime/protoimpl is sufficiently up-to-date. 21 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 22 | ) 23 | 24 | type StatusGetRequest_Code int32 25 | 26 | const ( 27 | StatusGetRequest_OK StatusGetRequest_Code = 0 28 | StatusGetRequest_CANCELED StatusGetRequest_Code = 1 29 | StatusGetRequest_UNKNOWN StatusGetRequest_Code = 2 30 | StatusGetRequest_INVALIDARGUMENT StatusGetRequest_Code = 3 31 | StatusGetRequest_DEADLINE_EXCEEDED StatusGetRequest_Code = 4 32 | StatusGetRequest_NOT_FOUND StatusGetRequest_Code = 5 33 | StatusGetRequest_ALREADY_EXISTS StatusGetRequest_Code = 6 34 | StatusGetRequest_PERMISSION_DENIED StatusGetRequest_Code = 7 35 | StatusGetRequest_RESOURCE_EXHAUSTED StatusGetRequest_Code = 8 36 | StatusGetRequest_FAILED_PRECONDITION StatusGetRequest_Code = 9 37 | StatusGetRequest_ABORTED StatusGetRequest_Code = 10 38 | StatusGetRequest_OUT_OF_RANGE StatusGetRequest_Code = 11 39 | StatusGetRequest_UNIMPLEMENTED StatusGetRequest_Code = 12 40 | StatusGetRequest_INTERNAL StatusGetRequest_Code = 13 41 | StatusGetRequest_UNAVAILABLE StatusGetRequest_Code = 14 42 | StatusGetRequest_DATALOSS StatusGetRequest_Code = 15 43 | StatusGetRequest_UNAUTHENTICATED StatusGetRequest_Code = 16 44 | ) 45 | 46 | // Enum value maps for StatusGetRequest_Code. 47 | var ( 48 | StatusGetRequest_Code_name = map[int32]string{ 49 | 0: "OK", 50 | 1: "CANCELED", 51 | 2: "UNKNOWN", 52 | 3: "INVALIDARGUMENT", 53 | 4: "DEADLINE_EXCEEDED", 54 | 5: "NOT_FOUND", 55 | 6: "ALREADY_EXISTS", 56 | 7: "PERMISSION_DENIED", 57 | 8: "RESOURCE_EXHAUSTED", 58 | 9: "FAILED_PRECONDITION", 59 | 10: "ABORTED", 60 | 11: "OUT_OF_RANGE", 61 | 12: "UNIMPLEMENTED", 62 | 13: "INTERNAL", 63 | 14: "UNAVAILABLE", 64 | 15: "DATALOSS", 65 | 16: "UNAUTHENTICATED", 66 | } 67 | StatusGetRequest_Code_value = map[string]int32{ 68 | "OK": 0, 69 | "CANCELED": 1, 70 | "UNKNOWN": 2, 71 | "INVALIDARGUMENT": 3, 72 | "DEADLINE_EXCEEDED": 4, 73 | "NOT_FOUND": 5, 74 | "ALREADY_EXISTS": 6, 75 | "PERMISSION_DENIED": 7, 76 | "RESOURCE_EXHAUSTED": 8, 77 | "FAILED_PRECONDITION": 9, 78 | "ABORTED": 10, 79 | "OUT_OF_RANGE": 11, 80 | "UNIMPLEMENTED": 12, 81 | "INTERNAL": 13, 82 | "UNAVAILABLE": 14, 83 | "DATALOSS": 15, 84 | "UNAUTHENTICATED": 16, 85 | } 86 | ) 87 | 88 | func (x StatusGetRequest_Code) Enum() *StatusGetRequest_Code { 89 | p := new(StatusGetRequest_Code) 90 | *p = x 91 | return p 92 | } 93 | 94 | func (x StatusGetRequest_Code) String() string { 95 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 96 | } 97 | 98 | func (StatusGetRequest_Code) Descriptor() protoreflect.EnumDescriptor { 99 | return file_testing_proto_enumTypes[0].Descriptor() 100 | } 101 | 102 | func (StatusGetRequest_Code) Type() protoreflect.EnumType { 103 | return &file_testing_proto_enumTypes[0] 104 | } 105 | 106 | func (x StatusGetRequest_Code) Number() protoreflect.EnumNumber { 107 | return protoreflect.EnumNumber(x) 108 | } 109 | 110 | // Deprecated: Use StatusGetRequest_Code.Descriptor instead. 111 | func (StatusGetRequest_Code) EnumDescriptor() ([]byte, []int) { 112 | return file_testing_proto_rawDescGZIP(), []int{0, 0} 113 | } 114 | 115 | type DetailGetRequest_Code int32 116 | 117 | const ( 118 | DetailGetRequest_OK DetailGetRequest_Code = 0 119 | DetailGetRequest_RETRY_INFO DetailGetRequest_Code = 1 120 | DetailGetRequest_DEBUG_INFO DetailGetRequest_Code = 2 121 | DetailGetRequest_QUOTA_FAILURE DetailGetRequest_Code = 3 122 | DetailGetRequest_ERROR_INFO DetailGetRequest_Code = 4 123 | DetailGetRequest_PRECONDITION_FAILURE DetailGetRequest_Code = 5 124 | DetailGetRequest_BAD_REQUEST DetailGetRequest_Code = 6 125 | DetailGetRequest_REQUEST_INFO DetailGetRequest_Code = 7 126 | DetailGetRequest_RESOURCE_INFO DetailGetRequest_Code = 8 127 | DetailGetRequest_HELP DetailGetRequest_Code = 9 128 | DetailGetRequest_LOCALIZED_MESSAGE DetailGetRequest_Code = 10 129 | DetailGetRequest_COMBINED_ALL DetailGetRequest_Code = 20 130 | ) 131 | 132 | // Enum value maps for DetailGetRequest_Code. 133 | var ( 134 | DetailGetRequest_Code_name = map[int32]string{ 135 | 0: "OK", 136 | 1: "RETRY_INFO", 137 | 2: "DEBUG_INFO", 138 | 3: "QUOTA_FAILURE", 139 | 4: "ERROR_INFO", 140 | 5: "PRECONDITION_FAILURE", 141 | 6: "BAD_REQUEST", 142 | 7: "REQUEST_INFO", 143 | 8: "RESOURCE_INFO", 144 | 9: "HELP", 145 | 10: "LOCALIZED_MESSAGE", 146 | 20: "COMBINED_ALL", 147 | } 148 | DetailGetRequest_Code_value = map[string]int32{ 149 | "OK": 0, 150 | "RETRY_INFO": 1, 151 | "DEBUG_INFO": 2, 152 | "QUOTA_FAILURE": 3, 153 | "ERROR_INFO": 4, 154 | "PRECONDITION_FAILURE": 5, 155 | "BAD_REQUEST": 6, 156 | "REQUEST_INFO": 7, 157 | "RESOURCE_INFO": 8, 158 | "HELP": 9, 159 | "LOCALIZED_MESSAGE": 10, 160 | "COMBINED_ALL": 20, 161 | } 162 | ) 163 | 164 | func (x DetailGetRequest_Code) Enum() *DetailGetRequest_Code { 165 | p := new(DetailGetRequest_Code) 166 | *p = x 167 | return p 168 | } 169 | 170 | func (x DetailGetRequest_Code) String() string { 171 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 172 | } 173 | 174 | func (DetailGetRequest_Code) Descriptor() protoreflect.EnumDescriptor { 175 | return file_testing_proto_enumTypes[1].Descriptor() 176 | } 177 | 178 | func (DetailGetRequest_Code) Type() protoreflect.EnumType { 179 | return &file_testing_proto_enumTypes[1] 180 | } 181 | 182 | func (x DetailGetRequest_Code) Number() protoreflect.EnumNumber { 183 | return protoreflect.EnumNumber(x) 184 | } 185 | 186 | // Deprecated: Use DetailGetRequest_Code.Descriptor instead. 187 | func (DetailGetRequest_Code) EnumDescriptor() ([]byte, []int) { 188 | return file_testing_proto_rawDescGZIP(), []int{2, 0} 189 | } 190 | 191 | type SetRequest_HealthCheckStatus int32 192 | 193 | const ( 194 | SetRequest_UNKNOWN SetRequest_HealthCheckStatus = 0 195 | SetRequest_SERVING SetRequest_HealthCheckStatus = 1 196 | SetRequest_NOT_SERVING SetRequest_HealthCheckStatus = 2 197 | SetRequest_SERVICE_UNKNOWN SetRequest_HealthCheckStatus = 3 198 | ) 199 | 200 | // Enum value maps for SetRequest_HealthCheckStatus. 201 | var ( 202 | SetRequest_HealthCheckStatus_name = map[int32]string{ 203 | 0: "UNKNOWN", 204 | 1: "SERVING", 205 | 2: "NOT_SERVING", 206 | 3: "SERVICE_UNKNOWN", 207 | } 208 | SetRequest_HealthCheckStatus_value = map[string]int32{ 209 | "UNKNOWN": 0, 210 | "SERVING": 1, 211 | "NOT_SERVING": 2, 212 | "SERVICE_UNKNOWN": 3, 213 | } 214 | ) 215 | 216 | func (x SetRequest_HealthCheckStatus) Enum() *SetRequest_HealthCheckStatus { 217 | p := new(SetRequest_HealthCheckStatus) 218 | *p = x 219 | return p 220 | } 221 | 222 | func (x SetRequest_HealthCheckStatus) String() string { 223 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 224 | } 225 | 226 | func (SetRequest_HealthCheckStatus) Descriptor() protoreflect.EnumDescriptor { 227 | return file_testing_proto_enumTypes[2].Descriptor() 228 | } 229 | 230 | func (SetRequest_HealthCheckStatus) Type() protoreflect.EnumType { 231 | return &file_testing_proto_enumTypes[2] 232 | } 233 | 234 | func (x SetRequest_HealthCheckStatus) Number() protoreflect.EnumNumber { 235 | return protoreflect.EnumNumber(x) 236 | } 237 | 238 | // Deprecated: Use SetRequest_HealthCheckStatus.Descriptor instead. 239 | func (SetRequest_HealthCheckStatus) EnumDescriptor() ([]byte, []int) { 240 | return file_testing_proto_rawDescGZIP(), []int{5, 0} 241 | } 242 | 243 | type StatusGetRequest struct { 244 | state protoimpl.MessageState 245 | sizeCache protoimpl.SizeCache 246 | unknownFields protoimpl.UnknownFields 247 | 248 | Code StatusGetRequest_Code `protobuf:"varint,1,opt,name=code,proto3,enum=testing.StatusGetRequest_Code" json:"code,omitempty"` 249 | } 250 | 251 | func (x *StatusGetRequest) Reset() { 252 | *x = StatusGetRequest{} 253 | if protoimpl.UnsafeEnabled { 254 | mi := &file_testing_proto_msgTypes[0] 255 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 256 | ms.StoreMessageInfo(mi) 257 | } 258 | } 259 | 260 | func (x *StatusGetRequest) String() string { 261 | return protoimpl.X.MessageStringOf(x) 262 | } 263 | 264 | func (*StatusGetRequest) ProtoMessage() {} 265 | 266 | func (x *StatusGetRequest) ProtoReflect() protoreflect.Message { 267 | mi := &file_testing_proto_msgTypes[0] 268 | if protoimpl.UnsafeEnabled && x != nil { 269 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 270 | if ms.LoadMessageInfo() == nil { 271 | ms.StoreMessageInfo(mi) 272 | } 273 | return ms 274 | } 275 | return mi.MessageOf(x) 276 | } 277 | 278 | // Deprecated: Use StatusGetRequest.ProtoReflect.Descriptor instead. 279 | func (*StatusGetRequest) Descriptor() ([]byte, []int) { 280 | return file_testing_proto_rawDescGZIP(), []int{0} 281 | } 282 | 283 | func (x *StatusGetRequest) GetCode() StatusGetRequest_Code { 284 | if x != nil { 285 | return x.Code 286 | } 287 | return StatusGetRequest_OK 288 | } 289 | 290 | type StatusGetResponse struct { 291 | state protoimpl.MessageState 292 | sizeCache protoimpl.SizeCache 293 | unknownFields protoimpl.UnknownFields 294 | 295 | Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` 296 | } 297 | 298 | func (x *StatusGetResponse) Reset() { 299 | *x = StatusGetResponse{} 300 | if protoimpl.UnsafeEnabled { 301 | mi := &file_testing_proto_msgTypes[1] 302 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 303 | ms.StoreMessageInfo(mi) 304 | } 305 | } 306 | 307 | func (x *StatusGetResponse) String() string { 308 | return protoimpl.X.MessageStringOf(x) 309 | } 310 | 311 | func (*StatusGetResponse) ProtoMessage() {} 312 | 313 | func (x *StatusGetResponse) ProtoReflect() protoreflect.Message { 314 | mi := &file_testing_proto_msgTypes[1] 315 | if protoimpl.UnsafeEnabled && x != nil { 316 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 317 | if ms.LoadMessageInfo() == nil { 318 | ms.StoreMessageInfo(mi) 319 | } 320 | return ms 321 | } 322 | return mi.MessageOf(x) 323 | } 324 | 325 | // Deprecated: Use StatusGetResponse.ProtoReflect.Descriptor instead. 326 | func (*StatusGetResponse) Descriptor() ([]byte, []int) { 327 | return file_testing_proto_rawDescGZIP(), []int{1} 328 | } 329 | 330 | func (x *StatusGetResponse) GetMsg() string { 331 | if x != nil { 332 | return x.Msg 333 | } 334 | return "" 335 | } 336 | 337 | type DetailGetRequest struct { 338 | state protoimpl.MessageState 339 | sizeCache protoimpl.SizeCache 340 | unknownFields protoimpl.UnknownFields 341 | 342 | Code DetailGetRequest_Code `protobuf:"varint,1,opt,name=code,proto3,enum=testing.DetailGetRequest_Code" json:"code,omitempty"` 343 | } 344 | 345 | func (x *DetailGetRequest) Reset() { 346 | *x = DetailGetRequest{} 347 | if protoimpl.UnsafeEnabled { 348 | mi := &file_testing_proto_msgTypes[2] 349 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 350 | ms.StoreMessageInfo(mi) 351 | } 352 | } 353 | 354 | func (x *DetailGetRequest) String() string { 355 | return protoimpl.X.MessageStringOf(x) 356 | } 357 | 358 | func (*DetailGetRequest) ProtoMessage() {} 359 | 360 | func (x *DetailGetRequest) ProtoReflect() protoreflect.Message { 361 | mi := &file_testing_proto_msgTypes[2] 362 | if protoimpl.UnsafeEnabled && x != nil { 363 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 364 | if ms.LoadMessageInfo() == nil { 365 | ms.StoreMessageInfo(mi) 366 | } 367 | return ms 368 | } 369 | return mi.MessageOf(x) 370 | } 371 | 372 | // Deprecated: Use DetailGetRequest.ProtoReflect.Descriptor instead. 373 | func (*DetailGetRequest) Descriptor() ([]byte, []int) { 374 | return file_testing_proto_rawDescGZIP(), []int{2} 375 | } 376 | 377 | func (x *DetailGetRequest) GetCode() DetailGetRequest_Code { 378 | if x != nil { 379 | return x.Code 380 | } 381 | return DetailGetRequest_OK 382 | } 383 | 384 | type DetailGetResponse struct { 385 | state protoimpl.MessageState 386 | sizeCache protoimpl.SizeCache 387 | unknownFields protoimpl.UnknownFields 388 | 389 | Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` 390 | } 391 | 392 | func (x *DetailGetResponse) Reset() { 393 | *x = DetailGetResponse{} 394 | if protoimpl.UnsafeEnabled { 395 | mi := &file_testing_proto_msgTypes[3] 396 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 397 | ms.StoreMessageInfo(mi) 398 | } 399 | } 400 | 401 | func (x *DetailGetResponse) String() string { 402 | return protoimpl.X.MessageStringOf(x) 403 | } 404 | 405 | func (*DetailGetResponse) ProtoMessage() {} 406 | 407 | func (x *DetailGetResponse) ProtoReflect() protoreflect.Message { 408 | mi := &file_testing_proto_msgTypes[3] 409 | if protoimpl.UnsafeEnabled && x != nil { 410 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 411 | if ms.LoadMessageInfo() == nil { 412 | ms.StoreMessageInfo(mi) 413 | } 414 | return ms 415 | } 416 | return mi.MessageOf(x) 417 | } 418 | 419 | // Deprecated: Use DetailGetResponse.ProtoReflect.Descriptor instead. 420 | func (*DetailGetResponse) Descriptor() ([]byte, []int) { 421 | return file_testing_proto_rawDescGZIP(), []int{3} 422 | } 423 | 424 | func (x *DetailGetResponse) GetMsg() string { 425 | if x != nil { 426 | return x.Msg 427 | } 428 | return "" 429 | } 430 | 431 | type MetadataGetResponse struct { 432 | state protoimpl.MessageState 433 | sizeCache protoimpl.SizeCache 434 | unknownFields protoimpl.UnknownFields 435 | 436 | Metadata []*MetadataGetResponse_Entry `protobuf:"bytes,1,rep,name=metadata,proto3" json:"metadata,omitempty"` 437 | } 438 | 439 | func (x *MetadataGetResponse) Reset() { 440 | *x = MetadataGetResponse{} 441 | if protoimpl.UnsafeEnabled { 442 | mi := &file_testing_proto_msgTypes[4] 443 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 444 | ms.StoreMessageInfo(mi) 445 | } 446 | } 447 | 448 | func (x *MetadataGetResponse) String() string { 449 | return protoimpl.X.MessageStringOf(x) 450 | } 451 | 452 | func (*MetadataGetResponse) ProtoMessage() {} 453 | 454 | func (x *MetadataGetResponse) ProtoReflect() protoreflect.Message { 455 | mi := &file_testing_proto_msgTypes[4] 456 | if protoimpl.UnsafeEnabled && x != nil { 457 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 458 | if ms.LoadMessageInfo() == nil { 459 | ms.StoreMessageInfo(mi) 460 | } 461 | return ms 462 | } 463 | return mi.MessageOf(x) 464 | } 465 | 466 | // Deprecated: Use MetadataGetResponse.ProtoReflect.Descriptor instead. 467 | func (*MetadataGetResponse) Descriptor() ([]byte, []int) { 468 | return file_testing_proto_rawDescGZIP(), []int{4} 469 | } 470 | 471 | func (x *MetadataGetResponse) GetMetadata() []*MetadataGetResponse_Entry { 472 | if x != nil { 473 | return x.Metadata 474 | } 475 | return nil 476 | } 477 | 478 | type SetRequest struct { 479 | state protoimpl.MessageState 480 | sizeCache protoimpl.SizeCache 481 | unknownFields protoimpl.UnknownFields 482 | 483 | Status SetRequest_HealthCheckStatus `protobuf:"varint,1,opt,name=status,proto3,enum=testing.SetRequest_HealthCheckStatus" json:"status,omitempty"` 484 | } 485 | 486 | func (x *SetRequest) Reset() { 487 | *x = SetRequest{} 488 | if protoimpl.UnsafeEnabled { 489 | mi := &file_testing_proto_msgTypes[5] 490 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 491 | ms.StoreMessageInfo(mi) 492 | } 493 | } 494 | 495 | func (x *SetRequest) String() string { 496 | return protoimpl.X.MessageStringOf(x) 497 | } 498 | 499 | func (*SetRequest) ProtoMessage() {} 500 | 501 | func (x *SetRequest) ProtoReflect() protoreflect.Message { 502 | mi := &file_testing_proto_msgTypes[5] 503 | if protoimpl.UnsafeEnabled && x != nil { 504 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 505 | if ms.LoadMessageInfo() == nil { 506 | ms.StoreMessageInfo(mi) 507 | } 508 | return ms 509 | } 510 | return mi.MessageOf(x) 511 | } 512 | 513 | // Deprecated: Use SetRequest.ProtoReflect.Descriptor instead. 514 | func (*SetRequest) Descriptor() ([]byte, []int) { 515 | return file_testing_proto_rawDescGZIP(), []int{5} 516 | } 517 | 518 | func (x *SetRequest) GetStatus() SetRequest_HealthCheckStatus { 519 | if x != nil { 520 | return x.Status 521 | } 522 | return SetRequest_UNKNOWN 523 | } 524 | 525 | type EchoRequest struct { 526 | state protoimpl.MessageState 527 | sizeCache protoimpl.SizeCache 528 | unknownFields protoimpl.UnknownFields 529 | 530 | Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` 531 | } 532 | 533 | func (x *EchoRequest) Reset() { 534 | *x = EchoRequest{} 535 | if protoimpl.UnsafeEnabled { 536 | mi := &file_testing_proto_msgTypes[6] 537 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 538 | ms.StoreMessageInfo(mi) 539 | } 540 | } 541 | 542 | func (x *EchoRequest) String() string { 543 | return protoimpl.X.MessageStringOf(x) 544 | } 545 | 546 | func (*EchoRequest) ProtoMessage() {} 547 | 548 | func (x *EchoRequest) ProtoReflect() protoreflect.Message { 549 | mi := &file_testing_proto_msgTypes[6] 550 | if protoimpl.UnsafeEnabled && x != nil { 551 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 552 | if ms.LoadMessageInfo() == nil { 553 | ms.StoreMessageInfo(mi) 554 | } 555 | return ms 556 | } 557 | return mi.MessageOf(x) 558 | } 559 | 560 | // Deprecated: Use EchoRequest.ProtoReflect.Descriptor instead. 561 | func (*EchoRequest) Descriptor() ([]byte, []int) { 562 | return file_testing_proto_rawDescGZIP(), []int{6} 563 | } 564 | 565 | func (x *EchoRequest) GetMsg() string { 566 | if x != nil { 567 | return x.Msg 568 | } 569 | return "" 570 | } 571 | 572 | type EchoResponse struct { 573 | state protoimpl.MessageState 574 | sizeCache protoimpl.SizeCache 575 | unknownFields protoimpl.UnknownFields 576 | 577 | Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` 578 | } 579 | 580 | func (x *EchoResponse) Reset() { 581 | *x = EchoResponse{} 582 | if protoimpl.UnsafeEnabled { 583 | mi := &file_testing_proto_msgTypes[7] 584 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 585 | ms.StoreMessageInfo(mi) 586 | } 587 | } 588 | 589 | func (x *EchoResponse) String() string { 590 | return protoimpl.X.MessageStringOf(x) 591 | } 592 | 593 | func (*EchoResponse) ProtoMessage() {} 594 | 595 | func (x *EchoResponse) ProtoReflect() protoreflect.Message { 596 | mi := &file_testing_proto_msgTypes[7] 597 | if protoimpl.UnsafeEnabled && x != nil { 598 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 599 | if ms.LoadMessageInfo() == nil { 600 | ms.StoreMessageInfo(mi) 601 | } 602 | return ms 603 | } 604 | return mi.MessageOf(x) 605 | } 606 | 607 | // Deprecated: Use EchoResponse.ProtoReflect.Descriptor instead. 608 | func (*EchoResponse) Descriptor() ([]byte, []int) { 609 | return file_testing_proto_rawDescGZIP(), []int{7} 610 | } 611 | 612 | func (x *EchoResponse) GetMsg() string { 613 | if x != nil { 614 | return x.Msg 615 | } 616 | return "" 617 | } 618 | 619 | type MetadataGetResponse_Entry struct { 620 | state protoimpl.MessageState 621 | sizeCache protoimpl.SizeCache 622 | unknownFields protoimpl.UnknownFields 623 | 624 | Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` 625 | Value []string `protobuf:"bytes,2,rep,name=value,proto3" json:"value,omitempty"` 626 | } 627 | 628 | func (x *MetadataGetResponse_Entry) Reset() { 629 | *x = MetadataGetResponse_Entry{} 630 | if protoimpl.UnsafeEnabled { 631 | mi := &file_testing_proto_msgTypes[8] 632 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 633 | ms.StoreMessageInfo(mi) 634 | } 635 | } 636 | 637 | func (x *MetadataGetResponse_Entry) String() string { 638 | return protoimpl.X.MessageStringOf(x) 639 | } 640 | 641 | func (*MetadataGetResponse_Entry) ProtoMessage() {} 642 | 643 | func (x *MetadataGetResponse_Entry) ProtoReflect() protoreflect.Message { 644 | mi := &file_testing_proto_msgTypes[8] 645 | if protoimpl.UnsafeEnabled && x != nil { 646 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 647 | if ms.LoadMessageInfo() == nil { 648 | ms.StoreMessageInfo(mi) 649 | } 650 | return ms 651 | } 652 | return mi.MessageOf(x) 653 | } 654 | 655 | // Deprecated: Use MetadataGetResponse_Entry.ProtoReflect.Descriptor instead. 656 | func (*MetadataGetResponse_Entry) Descriptor() ([]byte, []int) { 657 | return file_testing_proto_rawDescGZIP(), []int{4, 0} 658 | } 659 | 660 | func (x *MetadataGetResponse_Entry) GetKey() string { 661 | if x != nil { 662 | return x.Key 663 | } 664 | return "" 665 | } 666 | 667 | func (x *MetadataGetResponse_Entry) GetValue() []string { 668 | if x != nil { 669 | return x.Value 670 | } 671 | return nil 672 | } 673 | 674 | var File_testing_proto protoreflect.FileDescriptor 675 | 676 | var file_testing_proto_rawDesc = []byte{ 677 | 0x0a, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 678 | 0x07, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 679 | 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 680 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x02, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 681 | 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x63, 0x6f, 682 | 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 683 | 0x6e, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 684 | 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xb4, 685 | 0x02, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 686 | 0x0c, 0x0a, 0x08, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 687 | 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 688 | 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 689 | 0x15, 0x0a, 0x11, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 690 | 0x45, 0x44, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 691 | 0x55, 0x4e, 0x44, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, 692 | 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 693 | 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x07, 694 | 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x58, 0x48, 695 | 0x41, 0x55, 0x53, 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 696 | 0x45, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 697 | 0x09, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x10, 698 | 0x0a, 0x0c, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x0b, 699 | 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 700 | 0x44, 0x10, 0x0c, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 701 | 0x0d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 702 | 0x10, 0x0e, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x0f, 703 | 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 704 | 0x54, 0x45, 0x44, 0x10, 0x10, 0x22, 0x25, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x47, 705 | 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 706 | 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x9d, 0x02, 0x0a, 707 | 0x10, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 708 | 0x74, 0x12, 0x32, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 709 | 0x1e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 710 | 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 711 | 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xd4, 0x01, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x06, 712 | 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x54, 0x52, 0x59, 0x5f, 713 | 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x42, 0x55, 0x47, 0x5f, 714 | 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x51, 0x55, 0x4f, 0x54, 0x41, 0x5f, 715 | 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x52, 0x52, 716 | 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x52, 0x45, 717 | 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 718 | 0x45, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 719 | 0x53, 0x54, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 720 | 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 721 | 0x43, 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x45, 0x4c, 722 | 0x50, 0x10, 0x09, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 723 | 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x4f, 724 | 0x4d, 0x42, 0x49, 0x4e, 0x45, 0x44, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x14, 0x22, 0x25, 0x0a, 0x11, 725 | 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 726 | 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 727 | 0x6d, 0x73, 0x67, 0x22, 0x86, 0x01, 0x0a, 0x13, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 728 | 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 729 | 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 730 | 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 731 | 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 732 | 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x2f, 0x0a, 0x05, 0x45, 733 | 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 734 | 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 735 | 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa0, 0x01, 0x0a, 736 | 0x0a, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x73, 737 | 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x74, 0x65, 738 | 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 739 | 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 740 | 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x53, 0x0a, 0x11, 0x48, 0x65, 741 | 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 742 | 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 743 | 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 744 | 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x45, 745 | 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x22, 746 | 0x1f, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 747 | 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 748 | 0x22, 0x20, 0x0a, 0x0c, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 749 | 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 750 | 0x73, 0x67, 0x32, 0x46, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3c, 0x0a, 0x03, 751 | 0x47, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x74, 752 | 0x61, 0x74, 0x75, 0x73, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 753 | 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x47, 754 | 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x46, 0x0a, 0x06, 0x44, 0x65, 755 | 0x74, 0x61, 0x69, 0x6c, 0x12, 0x3c, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x74, 0x65, 756 | 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x47, 0x65, 0x74, 0x52, 757 | 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 758 | 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 759 | 0x73, 0x65, 0x32, 0x47, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3b, 760 | 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 761 | 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 762 | 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 763 | 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x42, 0x0a, 0x0c, 0x43, 764 | 0x68, 0x61, 0x6e, 0x67, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x32, 0x0a, 0x03, 0x53, 765 | 0x65, 0x74, 0x12, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x74, 766 | 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 767 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 768 | 0x42, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x33, 769 | 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x14, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 770 | 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x74, 771 | 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 772 | 0x6e, 0x73, 0x65, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 773 | 0x6d, 0x2f, 0x43, 0x6f, 0x64, 0x65, 0x2d, 0x48, 0x65, 0x78, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 774 | 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 775 | 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 776 | 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 777 | } 778 | 779 | var ( 780 | file_testing_proto_rawDescOnce sync.Once 781 | file_testing_proto_rawDescData = file_testing_proto_rawDesc 782 | ) 783 | 784 | func file_testing_proto_rawDescGZIP() []byte { 785 | file_testing_proto_rawDescOnce.Do(func() { 786 | file_testing_proto_rawDescData = protoimpl.X.CompressGZIP(file_testing_proto_rawDescData) 787 | }) 788 | return file_testing_proto_rawDescData 789 | } 790 | 791 | var file_testing_proto_enumTypes = make([]protoimpl.EnumInfo, 3) 792 | var file_testing_proto_msgTypes = make([]protoimpl.MessageInfo, 9) 793 | var file_testing_proto_goTypes = []interface{}{ 794 | (StatusGetRequest_Code)(0), // 0: testing.StatusGetRequest.Code 795 | (DetailGetRequest_Code)(0), // 1: testing.DetailGetRequest.Code 796 | (SetRequest_HealthCheckStatus)(0), // 2: testing.SetRequest.HealthCheckStatus 797 | (*StatusGetRequest)(nil), // 3: testing.StatusGetRequest 798 | (*StatusGetResponse)(nil), // 4: testing.StatusGetResponse 799 | (*DetailGetRequest)(nil), // 5: testing.DetailGetRequest 800 | (*DetailGetResponse)(nil), // 6: testing.DetailGetResponse 801 | (*MetadataGetResponse)(nil), // 7: testing.MetadataGetResponse 802 | (*SetRequest)(nil), // 8: testing.SetRequest 803 | (*EchoRequest)(nil), // 9: testing.EchoRequest 804 | (*EchoResponse)(nil), // 10: testing.EchoResponse 805 | (*MetadataGetResponse_Entry)(nil), // 11: testing.MetadataGetResponse.Entry 806 | (*emptypb.Empty)(nil), // 12: google.protobuf.Empty 807 | } 808 | var file_testing_proto_depIdxs = []int32{ 809 | 0, // 0: testing.StatusGetRequest.code:type_name -> testing.StatusGetRequest.Code 810 | 1, // 1: testing.DetailGetRequest.code:type_name -> testing.DetailGetRequest.Code 811 | 11, // 2: testing.MetadataGetResponse.metadata:type_name -> testing.MetadataGetResponse.Entry 812 | 2, // 3: testing.SetRequest.status:type_name -> testing.SetRequest.HealthCheckStatus 813 | 3, // 4: testing.Status.Get:input_type -> testing.StatusGetRequest 814 | 5, // 5: testing.Detail.Get:input_type -> testing.DetailGetRequest 815 | 12, // 6: testing.Metadata.Get:input_type -> google.protobuf.Empty 816 | 8, // 7: testing.ChangeHealth.Set:input_type -> testing.SetRequest 817 | 9, // 8: testing.Interceptor.Echo:input_type -> testing.EchoRequest 818 | 4, // 9: testing.Status.Get:output_type -> testing.StatusGetResponse 819 | 6, // 10: testing.Detail.Get:output_type -> testing.DetailGetResponse 820 | 7, // 11: testing.Metadata.Get:output_type -> testing.MetadataGetResponse 821 | 12, // 12: testing.ChangeHealth.Set:output_type -> google.protobuf.Empty 822 | 10, // 13: testing.Interceptor.Echo:output_type -> testing.EchoResponse 823 | 9, // [9:14] is the sub-list for method output_type 824 | 4, // [4:9] is the sub-list for method input_type 825 | 4, // [4:4] is the sub-list for extension type_name 826 | 4, // [4:4] is the sub-list for extension extendee 827 | 0, // [0:4] is the sub-list for field type_name 828 | } 829 | 830 | func init() { file_testing_proto_init() } 831 | func file_testing_proto_init() { 832 | if File_testing_proto != nil { 833 | return 834 | } 835 | if !protoimpl.UnsafeEnabled { 836 | file_testing_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 837 | switch v := v.(*StatusGetRequest); i { 838 | case 0: 839 | return &v.state 840 | case 1: 841 | return &v.sizeCache 842 | case 2: 843 | return &v.unknownFields 844 | default: 845 | return nil 846 | } 847 | } 848 | file_testing_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 849 | switch v := v.(*StatusGetResponse); i { 850 | case 0: 851 | return &v.state 852 | case 1: 853 | return &v.sizeCache 854 | case 2: 855 | return &v.unknownFields 856 | default: 857 | return nil 858 | } 859 | } 860 | file_testing_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 861 | switch v := v.(*DetailGetRequest); i { 862 | case 0: 863 | return &v.state 864 | case 1: 865 | return &v.sizeCache 866 | case 2: 867 | return &v.unknownFields 868 | default: 869 | return nil 870 | } 871 | } 872 | file_testing_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 873 | switch v := v.(*DetailGetResponse); i { 874 | case 0: 875 | return &v.state 876 | case 1: 877 | return &v.sizeCache 878 | case 2: 879 | return &v.unknownFields 880 | default: 881 | return nil 882 | } 883 | } 884 | file_testing_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { 885 | switch v := v.(*MetadataGetResponse); i { 886 | case 0: 887 | return &v.state 888 | case 1: 889 | return &v.sizeCache 890 | case 2: 891 | return &v.unknownFields 892 | default: 893 | return nil 894 | } 895 | } 896 | file_testing_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { 897 | switch v := v.(*SetRequest); i { 898 | case 0: 899 | return &v.state 900 | case 1: 901 | return &v.sizeCache 902 | case 2: 903 | return &v.unknownFields 904 | default: 905 | return nil 906 | } 907 | } 908 | file_testing_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { 909 | switch v := v.(*EchoRequest); i { 910 | case 0: 911 | return &v.state 912 | case 1: 913 | return &v.sizeCache 914 | case 2: 915 | return &v.unknownFields 916 | default: 917 | return nil 918 | } 919 | } 920 | file_testing_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { 921 | switch v := v.(*EchoResponse); i { 922 | case 0: 923 | return &v.state 924 | case 1: 925 | return &v.sizeCache 926 | case 2: 927 | return &v.unknownFields 928 | default: 929 | return nil 930 | } 931 | } 932 | file_testing_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { 933 | switch v := v.(*MetadataGetResponse_Entry); i { 934 | case 0: 935 | return &v.state 936 | case 1: 937 | return &v.sizeCache 938 | case 2: 939 | return &v.unknownFields 940 | default: 941 | return nil 942 | } 943 | } 944 | } 945 | type x struct{} 946 | out := protoimpl.TypeBuilder{ 947 | File: protoimpl.DescBuilder{ 948 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 949 | RawDescriptor: file_testing_proto_rawDesc, 950 | NumEnums: 3, 951 | NumMessages: 9, 952 | NumExtensions: 0, 953 | NumServices: 5, 954 | }, 955 | GoTypes: file_testing_proto_goTypes, 956 | DependencyIndexes: file_testing_proto_depIdxs, 957 | EnumInfos: file_testing_proto_enumTypes, 958 | MessageInfos: file_testing_proto_msgTypes, 959 | }.Build() 960 | File_testing_proto = out.File 961 | file_testing_proto_rawDesc = nil 962 | file_testing_proto_goTypes = nil 963 | file_testing_proto_depIdxs = nil 964 | } 965 | -------------------------------------------------------------------------------- /internal/testing/testing.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package testing; 4 | 5 | option go_package = "github.com/Code-Hex/testing-grpc/internal/testing;testing"; 6 | 7 | import "google/protobuf/empty.proto"; 8 | 9 | service Status { 10 | rpc Get(StatusGetRequest) returns (StatusGetResponse); 11 | } 12 | 13 | message StatusGetRequest { 14 | enum Code { 15 | OK = 0; 16 | CANCELED = 1; 17 | UNKNOWN = 2; 18 | INVALIDARGUMENT = 3; 19 | DEADLINE_EXCEEDED = 4; 20 | NOT_FOUND = 5; 21 | ALREADY_EXISTS = 6; 22 | PERMISSION_DENIED = 7; 23 | RESOURCE_EXHAUSTED = 8; 24 | FAILED_PRECONDITION = 9; 25 | ABORTED = 10; 26 | OUT_OF_RANGE = 11; 27 | UNIMPLEMENTED = 12; 28 | INTERNAL = 13; 29 | UNAVAILABLE = 14; 30 | DATALOSS = 15; 31 | UNAUTHENTICATED = 16; 32 | } 33 | Code code = 1; 34 | } 35 | 36 | message StatusGetResponse { 37 | string msg = 1; 38 | } 39 | 40 | service Detail { 41 | rpc Get(DetailGetRequest) returns (DetailGetResponse); 42 | } 43 | 44 | message DetailGetRequest { 45 | enum Code { 46 | OK = 0; 47 | RETRY_INFO = 1; 48 | DEBUG_INFO = 2; 49 | QUOTA_FAILURE = 3; 50 | ERROR_INFO = 4; 51 | PRECONDITION_FAILURE = 5; 52 | BAD_REQUEST = 6; 53 | REQUEST_INFO = 7; 54 | RESOURCE_INFO = 8; 55 | HELP = 9; 56 | LOCALIZED_MESSAGE = 10; 57 | COMBINED_ALL = 20; 58 | } 59 | Code code = 1; 60 | } 61 | 62 | message DetailGetResponse { 63 | string msg = 1; 64 | } 65 | 66 | service Metadata { 67 | rpc Get(google.protobuf.Empty) returns (MetadataGetResponse); 68 | } 69 | 70 | message MetadataGetResponse { 71 | message Entry { 72 | string key = 1; 73 | repeated string value = 2; 74 | } 75 | repeated Entry metadata = 1; 76 | } 77 | 78 | service ChangeHealth { 79 | rpc Set(SetRequest) returns (google.protobuf.Empty); 80 | } 81 | 82 | message SetRequest { 83 | enum HealthCheckStatus { 84 | UNKNOWN = 0; 85 | SERVING = 1; 86 | NOT_SERVING = 2; 87 | SERVICE_UNKNOWN = 3; 88 | } 89 | HealthCheckStatus status = 1; 90 | } 91 | 92 | service Interceptor { 93 | rpc Echo(EchoRequest) returns (EchoResponse); 94 | } 95 | 96 | message EchoRequest { 97 | string msg = 1; 98 | } 99 | 100 | message EchoResponse { 101 | string msg = 1; 102 | } 103 | -------------------------------------------------------------------------------- /internal/testing/testing_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.2.0 4 | // - protoc (unknown) 5 | // source: testing.proto 6 | 7 | package testing 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | emptypb "google.golang.org/protobuf/types/known/emptypb" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.32.0 or later. 20 | const _ = grpc.SupportPackageIsVersion7 21 | 22 | // StatusClient is the client API for Status service. 23 | // 24 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 25 | type StatusClient interface { 26 | Get(ctx context.Context, in *StatusGetRequest, opts ...grpc.CallOption) (*StatusGetResponse, error) 27 | } 28 | 29 | type statusClient struct { 30 | cc grpc.ClientConnInterface 31 | } 32 | 33 | func NewStatusClient(cc grpc.ClientConnInterface) StatusClient { 34 | return &statusClient{cc} 35 | } 36 | 37 | func (c *statusClient) Get(ctx context.Context, in *StatusGetRequest, opts ...grpc.CallOption) (*StatusGetResponse, error) { 38 | out := new(StatusGetResponse) 39 | err := c.cc.Invoke(ctx, "/testing.Status/Get", in, out, opts...) 40 | if err != nil { 41 | return nil, err 42 | } 43 | return out, nil 44 | } 45 | 46 | // StatusServer is the server API for Status service. 47 | // All implementations should embed UnimplementedStatusServer 48 | // for forward compatibility 49 | type StatusServer interface { 50 | Get(context.Context, *StatusGetRequest) (*StatusGetResponse, error) 51 | } 52 | 53 | // UnimplementedStatusServer should be embedded to have forward compatible implementations. 54 | type UnimplementedStatusServer struct { 55 | } 56 | 57 | func (UnimplementedStatusServer) Get(context.Context, *StatusGetRequest) (*StatusGetResponse, error) { 58 | return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") 59 | } 60 | 61 | // UnsafeStatusServer may be embedded to opt out of forward compatibility for this service. 62 | // Use of this interface is not recommended, as added methods to StatusServer will 63 | // result in compilation errors. 64 | type UnsafeStatusServer interface { 65 | mustEmbedUnimplementedStatusServer() 66 | } 67 | 68 | func RegisterStatusServer(s grpc.ServiceRegistrar, srv StatusServer) { 69 | s.RegisterService(&Status_ServiceDesc, srv) 70 | } 71 | 72 | func _Status_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 73 | in := new(StatusGetRequest) 74 | if err := dec(in); err != nil { 75 | return nil, err 76 | } 77 | if interceptor == nil { 78 | return srv.(StatusServer).Get(ctx, in) 79 | } 80 | info := &grpc.UnaryServerInfo{ 81 | Server: srv, 82 | FullMethod: "/testing.Status/Get", 83 | } 84 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 85 | return srv.(StatusServer).Get(ctx, req.(*StatusGetRequest)) 86 | } 87 | return interceptor(ctx, in, info, handler) 88 | } 89 | 90 | // Status_ServiceDesc is the grpc.ServiceDesc for Status service. 91 | // It's only intended for direct use with grpc.RegisterService, 92 | // and not to be introspected or modified (even as a copy) 93 | var Status_ServiceDesc = grpc.ServiceDesc{ 94 | ServiceName: "testing.Status", 95 | HandlerType: (*StatusServer)(nil), 96 | Methods: []grpc.MethodDesc{ 97 | { 98 | MethodName: "Get", 99 | Handler: _Status_Get_Handler, 100 | }, 101 | }, 102 | Streams: []grpc.StreamDesc{}, 103 | Metadata: "testing.proto", 104 | } 105 | 106 | // DetailClient is the client API for Detail service. 107 | // 108 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 109 | type DetailClient interface { 110 | Get(ctx context.Context, in *DetailGetRequest, opts ...grpc.CallOption) (*DetailGetResponse, error) 111 | } 112 | 113 | type detailClient struct { 114 | cc grpc.ClientConnInterface 115 | } 116 | 117 | func NewDetailClient(cc grpc.ClientConnInterface) DetailClient { 118 | return &detailClient{cc} 119 | } 120 | 121 | func (c *detailClient) Get(ctx context.Context, in *DetailGetRequest, opts ...grpc.CallOption) (*DetailGetResponse, error) { 122 | out := new(DetailGetResponse) 123 | err := c.cc.Invoke(ctx, "/testing.Detail/Get", in, out, opts...) 124 | if err != nil { 125 | return nil, err 126 | } 127 | return out, nil 128 | } 129 | 130 | // DetailServer is the server API for Detail service. 131 | // All implementations should embed UnimplementedDetailServer 132 | // for forward compatibility 133 | type DetailServer interface { 134 | Get(context.Context, *DetailGetRequest) (*DetailGetResponse, error) 135 | } 136 | 137 | // UnimplementedDetailServer should be embedded to have forward compatible implementations. 138 | type UnimplementedDetailServer struct { 139 | } 140 | 141 | func (UnimplementedDetailServer) Get(context.Context, *DetailGetRequest) (*DetailGetResponse, error) { 142 | return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") 143 | } 144 | 145 | // UnsafeDetailServer may be embedded to opt out of forward compatibility for this service. 146 | // Use of this interface is not recommended, as added methods to DetailServer will 147 | // result in compilation errors. 148 | type UnsafeDetailServer interface { 149 | mustEmbedUnimplementedDetailServer() 150 | } 151 | 152 | func RegisterDetailServer(s grpc.ServiceRegistrar, srv DetailServer) { 153 | s.RegisterService(&Detail_ServiceDesc, srv) 154 | } 155 | 156 | func _Detail_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 157 | in := new(DetailGetRequest) 158 | if err := dec(in); err != nil { 159 | return nil, err 160 | } 161 | if interceptor == nil { 162 | return srv.(DetailServer).Get(ctx, in) 163 | } 164 | info := &grpc.UnaryServerInfo{ 165 | Server: srv, 166 | FullMethod: "/testing.Detail/Get", 167 | } 168 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 169 | return srv.(DetailServer).Get(ctx, req.(*DetailGetRequest)) 170 | } 171 | return interceptor(ctx, in, info, handler) 172 | } 173 | 174 | // Detail_ServiceDesc is the grpc.ServiceDesc for Detail service. 175 | // It's only intended for direct use with grpc.RegisterService, 176 | // and not to be introspected or modified (even as a copy) 177 | var Detail_ServiceDesc = grpc.ServiceDesc{ 178 | ServiceName: "testing.Detail", 179 | HandlerType: (*DetailServer)(nil), 180 | Methods: []grpc.MethodDesc{ 181 | { 182 | MethodName: "Get", 183 | Handler: _Detail_Get_Handler, 184 | }, 185 | }, 186 | Streams: []grpc.StreamDesc{}, 187 | Metadata: "testing.proto", 188 | } 189 | 190 | // MetadataClient is the client API for Metadata service. 191 | // 192 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 193 | type MetadataClient interface { 194 | Get(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*MetadataGetResponse, error) 195 | } 196 | 197 | type metadataClient struct { 198 | cc grpc.ClientConnInterface 199 | } 200 | 201 | func NewMetadataClient(cc grpc.ClientConnInterface) MetadataClient { 202 | return &metadataClient{cc} 203 | } 204 | 205 | func (c *metadataClient) Get(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*MetadataGetResponse, error) { 206 | out := new(MetadataGetResponse) 207 | err := c.cc.Invoke(ctx, "/testing.Metadata/Get", in, out, opts...) 208 | if err != nil { 209 | return nil, err 210 | } 211 | return out, nil 212 | } 213 | 214 | // MetadataServer is the server API for Metadata service. 215 | // All implementations should embed UnimplementedMetadataServer 216 | // for forward compatibility 217 | type MetadataServer interface { 218 | Get(context.Context, *emptypb.Empty) (*MetadataGetResponse, error) 219 | } 220 | 221 | // UnimplementedMetadataServer should be embedded to have forward compatible implementations. 222 | type UnimplementedMetadataServer struct { 223 | } 224 | 225 | func (UnimplementedMetadataServer) Get(context.Context, *emptypb.Empty) (*MetadataGetResponse, error) { 226 | return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") 227 | } 228 | 229 | // UnsafeMetadataServer may be embedded to opt out of forward compatibility for this service. 230 | // Use of this interface is not recommended, as added methods to MetadataServer will 231 | // result in compilation errors. 232 | type UnsafeMetadataServer interface { 233 | mustEmbedUnimplementedMetadataServer() 234 | } 235 | 236 | func RegisterMetadataServer(s grpc.ServiceRegistrar, srv MetadataServer) { 237 | s.RegisterService(&Metadata_ServiceDesc, srv) 238 | } 239 | 240 | func _Metadata_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 241 | in := new(emptypb.Empty) 242 | if err := dec(in); err != nil { 243 | return nil, err 244 | } 245 | if interceptor == nil { 246 | return srv.(MetadataServer).Get(ctx, in) 247 | } 248 | info := &grpc.UnaryServerInfo{ 249 | Server: srv, 250 | FullMethod: "/testing.Metadata/Get", 251 | } 252 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 253 | return srv.(MetadataServer).Get(ctx, req.(*emptypb.Empty)) 254 | } 255 | return interceptor(ctx, in, info, handler) 256 | } 257 | 258 | // Metadata_ServiceDesc is the grpc.ServiceDesc for Metadata service. 259 | // It's only intended for direct use with grpc.RegisterService, 260 | // and not to be introspected or modified (even as a copy) 261 | var Metadata_ServiceDesc = grpc.ServiceDesc{ 262 | ServiceName: "testing.Metadata", 263 | HandlerType: (*MetadataServer)(nil), 264 | Methods: []grpc.MethodDesc{ 265 | { 266 | MethodName: "Get", 267 | Handler: _Metadata_Get_Handler, 268 | }, 269 | }, 270 | Streams: []grpc.StreamDesc{}, 271 | Metadata: "testing.proto", 272 | } 273 | 274 | // ChangeHealthClient is the client API for ChangeHealth service. 275 | // 276 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 277 | type ChangeHealthClient interface { 278 | Set(ctx context.Context, in *SetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 279 | } 280 | 281 | type changeHealthClient struct { 282 | cc grpc.ClientConnInterface 283 | } 284 | 285 | func NewChangeHealthClient(cc grpc.ClientConnInterface) ChangeHealthClient { 286 | return &changeHealthClient{cc} 287 | } 288 | 289 | func (c *changeHealthClient) Set(ctx context.Context, in *SetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 290 | out := new(emptypb.Empty) 291 | err := c.cc.Invoke(ctx, "/testing.ChangeHealth/Set", in, out, opts...) 292 | if err != nil { 293 | return nil, err 294 | } 295 | return out, nil 296 | } 297 | 298 | // ChangeHealthServer is the server API for ChangeHealth service. 299 | // All implementations should embed UnimplementedChangeHealthServer 300 | // for forward compatibility 301 | type ChangeHealthServer interface { 302 | Set(context.Context, *SetRequest) (*emptypb.Empty, error) 303 | } 304 | 305 | // UnimplementedChangeHealthServer should be embedded to have forward compatible implementations. 306 | type UnimplementedChangeHealthServer struct { 307 | } 308 | 309 | func (UnimplementedChangeHealthServer) Set(context.Context, *SetRequest) (*emptypb.Empty, error) { 310 | return nil, status.Errorf(codes.Unimplemented, "method Set not implemented") 311 | } 312 | 313 | // UnsafeChangeHealthServer may be embedded to opt out of forward compatibility for this service. 314 | // Use of this interface is not recommended, as added methods to ChangeHealthServer will 315 | // result in compilation errors. 316 | type UnsafeChangeHealthServer interface { 317 | mustEmbedUnimplementedChangeHealthServer() 318 | } 319 | 320 | func RegisterChangeHealthServer(s grpc.ServiceRegistrar, srv ChangeHealthServer) { 321 | s.RegisterService(&ChangeHealth_ServiceDesc, srv) 322 | } 323 | 324 | func _ChangeHealth_Set_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 325 | in := new(SetRequest) 326 | if err := dec(in); err != nil { 327 | return nil, err 328 | } 329 | if interceptor == nil { 330 | return srv.(ChangeHealthServer).Set(ctx, in) 331 | } 332 | info := &grpc.UnaryServerInfo{ 333 | Server: srv, 334 | FullMethod: "/testing.ChangeHealth/Set", 335 | } 336 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 337 | return srv.(ChangeHealthServer).Set(ctx, req.(*SetRequest)) 338 | } 339 | return interceptor(ctx, in, info, handler) 340 | } 341 | 342 | // ChangeHealth_ServiceDesc is the grpc.ServiceDesc for ChangeHealth service. 343 | // It's only intended for direct use with grpc.RegisterService, 344 | // and not to be introspected or modified (even as a copy) 345 | var ChangeHealth_ServiceDesc = grpc.ServiceDesc{ 346 | ServiceName: "testing.ChangeHealth", 347 | HandlerType: (*ChangeHealthServer)(nil), 348 | Methods: []grpc.MethodDesc{ 349 | { 350 | MethodName: "Set", 351 | Handler: _ChangeHealth_Set_Handler, 352 | }, 353 | }, 354 | Streams: []grpc.StreamDesc{}, 355 | Metadata: "testing.proto", 356 | } 357 | 358 | // InterceptorClient is the client API for Interceptor service. 359 | // 360 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 361 | type InterceptorClient interface { 362 | Echo(ctx context.Context, in *EchoRequest, opts ...grpc.CallOption) (*EchoResponse, error) 363 | } 364 | 365 | type interceptorClient struct { 366 | cc grpc.ClientConnInterface 367 | } 368 | 369 | func NewInterceptorClient(cc grpc.ClientConnInterface) InterceptorClient { 370 | return &interceptorClient{cc} 371 | } 372 | 373 | func (c *interceptorClient) Echo(ctx context.Context, in *EchoRequest, opts ...grpc.CallOption) (*EchoResponse, error) { 374 | out := new(EchoResponse) 375 | err := c.cc.Invoke(ctx, "/testing.Interceptor/Echo", in, out, opts...) 376 | if err != nil { 377 | return nil, err 378 | } 379 | return out, nil 380 | } 381 | 382 | // InterceptorServer is the server API for Interceptor service. 383 | // All implementations should embed UnimplementedInterceptorServer 384 | // for forward compatibility 385 | type InterceptorServer interface { 386 | Echo(context.Context, *EchoRequest) (*EchoResponse, error) 387 | } 388 | 389 | // UnimplementedInterceptorServer should be embedded to have forward compatible implementations. 390 | type UnimplementedInterceptorServer struct { 391 | } 392 | 393 | func (UnimplementedInterceptorServer) Echo(context.Context, *EchoRequest) (*EchoResponse, error) { 394 | return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented") 395 | } 396 | 397 | // UnsafeInterceptorServer may be embedded to opt out of forward compatibility for this service. 398 | // Use of this interface is not recommended, as added methods to InterceptorServer will 399 | // result in compilation errors. 400 | type UnsafeInterceptorServer interface { 401 | mustEmbedUnimplementedInterceptorServer() 402 | } 403 | 404 | func RegisterInterceptorServer(s grpc.ServiceRegistrar, srv InterceptorServer) { 405 | s.RegisterService(&Interceptor_ServiceDesc, srv) 406 | } 407 | 408 | func _Interceptor_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 409 | in := new(EchoRequest) 410 | if err := dec(in); err != nil { 411 | return nil, err 412 | } 413 | if interceptor == nil { 414 | return srv.(InterceptorServer).Echo(ctx, in) 415 | } 416 | info := &grpc.UnaryServerInfo{ 417 | Server: srv, 418 | FullMethod: "/testing.Interceptor/Echo", 419 | } 420 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 421 | return srv.(InterceptorServer).Echo(ctx, req.(*EchoRequest)) 422 | } 423 | return interceptor(ctx, in, info, handler) 424 | } 425 | 426 | // Interceptor_ServiceDesc is the grpc.ServiceDesc for Interceptor service. 427 | // It's only intended for direct use with grpc.RegisterService, 428 | // and not to be introspected or modified (even as a copy) 429 | var Interceptor_ServiceDesc = grpc.ServiceDesc{ 430 | ServiceName: "testing.Interceptor", 431 | HandlerType: (*InterceptorServer)(nil), 432 | Methods: []grpc.MethodDesc{ 433 | { 434 | MethodName: "Echo", 435 | Handler: _Interceptor_Echo_Handler, 436 | }, 437 | }, 438 | Streams: []grpc.StreamDesc{}, 439 | Metadata: "testing.proto", 440 | } 441 | --------------------------------------------------------------------------------