From c2af9ec8787ba14bf98e9197d1af12a6cdf3a998 Mon Sep 17 00:00:00 2001 From: strikerlulu Date: Sat, 18 Feb 2023 23:28:01 +0530 Subject: [PATCH] chore: initial commit --- Dockerfile.client | 16 +++ Dockerfile.server | 16 +++ README.md | 20 ++++ client/main.go | 49 +++++++++ docker-compose.yml | 14 +++ go.mod | 36 ++++++ go.sum | 95 ++++++++++++++++ pb/calc_service.pb.go | 219 +++++++++++++++++++++++++++++++++++++ pb/calc_service.proto | 16 +++ pb/calc_service_grpc.pb.go | 105 ++++++++++++++++++ server/main.go | 36 ++++++ server/main_test.go | 62 +++++++++++ 12 files changed, 684 insertions(+) create mode 100644 Dockerfile.client create mode 100644 Dockerfile.server create mode 100644 README.md create mode 100644 client/main.go create mode 100644 docker-compose.yml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 pb/calc_service.pb.go create mode 100644 pb/calc_service.proto create mode 100644 pb/calc_service_grpc.pb.go create mode 100644 server/main.go create mode 100644 server/main_test.go diff --git a/Dockerfile.client b/Dockerfile.client new file mode 100644 index 0000000..bbf1bd1 --- /dev/null +++ b/Dockerfile.client @@ -0,0 +1,16 @@ +FROM golang:1.19.1 + +WORKDIR /go/src/git.strikerlulu.me/strikerlulu/grpc-mocker/client + +COPY go.mod . +COPY go.sum . +RUN go mod download + +COPY . . +COPY pb ../pb + +RUN go install -v ./... + +EXPOSE 3000 + +CMD [ "client" ] diff --git a/Dockerfile.server b/Dockerfile.server new file mode 100644 index 0000000..6d2487e --- /dev/null +++ b/Dockerfile.server @@ -0,0 +1,16 @@ +FROM golang:1.19.1 + +WORKDIR /go/src/git.strikerlulu.me/strikerlulu/grpc-mocker/server + +COPY go.mod . +COPY go.sum . +RUN go mod download + +COPY . . +COPY pb ../pb + +RUN go install -v ./... + +EXPOSE 3000 + +CMD [ "server" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..2a06c96 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +## Just tinkering with grpc + + +### Setup +``` +docker-compose up +curl localhost:3001/add/3/2 +``` + +### Test mock server +``` +cd ./server +go test +``` +### To generate grpc code using protobuf compiler + +```sh +cd ./pd +protoc --go_out=. --go-grpc_out=. calc_service.proto +``` diff --git a/client/main.go b/client/main.go new file mode 100644 index 0000000..74c4d2f --- /dev/null +++ b/client/main.go @@ -0,0 +1,49 @@ +package main; + +import ( + "fmt" + "log" + "net/http" + "strconv" + + pb "git.strikerlulu.me/strikerlulu/grpc-mocker/pb" + + "github.com/gin-gonic/gin" + "google.golang.org/grpc" +) + +func main() { + conn, err := grpc.Dial("grpc-server:3000", grpc.WithInsecure()) + if err != nil { + log.Fatalf("Dial failed: %v", err) + } + client := pb.NewCalcServiceClient(conn) + + r := gin.Default() + r.GET("/add/:x/:y", func(c *gin.Context) { + + x, err := strconv.ParseUint(c.Param("x"), 10, 64) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid parameter X"}) + return + } + y, err := strconv.ParseUint(c.Param("y"), 10, 64) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid parameter Y"}) + return + } + + req := &pb.AdditionRequest{X: x,Y: y} + if res, err := client.Add(c, req); err == nil { + c.JSON(http.StatusOK, gin.H{ + "result": fmt.Sprint(res.Result), + }) + } else { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + }) + + if err := r.Run(":3000"); err != nil { + log.Fatalf("Failed to run server: %v", err) + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7795d1a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3' +services: + client: + build: + dockerfile: ./Dockerfile.client + ports: + - "3001:3000" + depends_on: + - grpc-server + grpc-server: + build: + dockerfile: ./Dockerfile.server + ports: + - "3002:3000" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c6d0881 --- /dev/null +++ b/go.mod @@ -0,0 +1,36 @@ +module git.strikerlulu.me/strikerlulu/grpc-mocker + +go 1.20 + +require github.com/stretchr/testify v1.8.1 + +require ( + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.11.1 // indirect + github.com/goccy/go-json v0.9.11 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect + golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gin-gonic/gin v1.8.2 + github.com/golang/protobuf v1.5.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/net v0.5.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.53.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..bc3062f --- /dev/null +++ b/go.sum @@ -0,0 +1,95 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.2 h1:UzKToD9/PoFj/V4rvlKqTRKnQYyz8Sc1MJlv4JHPtvY= +github.com/gin-gonic/gin v1.8.2/go.mod h1:qw5AYuDrzRTnhvusDsrov+fDIxp9Dleuu12h8nfB398= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pb/calc_service.pb.go b/pb/calc_service.pb.go new file mode 100644 index 0000000..47d952e --- /dev/null +++ b/pb/calc_service.pb.go @@ -0,0 +1,219 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: calc_service.proto + +package __ + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type AdditionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + X uint64 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` + Y uint64 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` +} + +func (x *AdditionRequest) Reset() { + *x = AdditionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_calc_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdditionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdditionRequest) ProtoMessage() {} + +func (x *AdditionRequest) ProtoReflect() protoreflect.Message { + mi := &file_calc_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdditionRequest.ProtoReflect.Descriptor instead. +func (*AdditionRequest) Descriptor() ([]byte, []int) { + return file_calc_service_proto_rawDescGZIP(), []int{0} +} + +func (x *AdditionRequest) GetX() uint64 { + if x != nil { + return x.X + } + return 0 +} + +func (x *AdditionRequest) GetY() uint64 { + if x != nil { + return x.Y + } + return 0 +} + +type AdditionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result uint64 `protobuf:"varint,3,opt,name=result,proto3" json:"result,omitempty"` +} + +func (x *AdditionResponse) Reset() { + *x = AdditionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_calc_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdditionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdditionResponse) ProtoMessage() {} + +func (x *AdditionResponse) ProtoReflect() protoreflect.Message { + mi := &file_calc_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdditionResponse.ProtoReflect.Descriptor instead. +func (*AdditionResponse) Descriptor() ([]byte, []int) { + return file_calc_service_proto_rawDescGZIP(), []int{1} +} + +func (x *AdditionResponse) GetResult() uint64 { + if x != nil { + return x.Result + } + return 0 +} + +var File_calc_service_proto protoreflect.FileDescriptor + +var file_calc_service_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x2d, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0c, 0x0a, 0x01, 0x78, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x01, 0x79, 0x22, 0x2a, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x32, 0x3f, 0x0a, 0x0b, 0x43, 0x61, 0x6c, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x30, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x41, + 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, + 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x04, 0x5a, 0x02, 0x2e, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_calc_service_proto_rawDescOnce sync.Once + file_calc_service_proto_rawDescData = file_calc_service_proto_rawDesc +) + +func file_calc_service_proto_rawDescGZIP() []byte { + file_calc_service_proto_rawDescOnce.Do(func() { + file_calc_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_calc_service_proto_rawDescData) + }) + return file_calc_service_proto_rawDescData +} + +var file_calc_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_calc_service_proto_goTypes = []interface{}{ + (*AdditionRequest)(nil), // 0: pb.AdditionRequest + (*AdditionResponse)(nil), // 1: pb.AdditionResponse +} +var file_calc_service_proto_depIdxs = []int32{ + 0, // 0: pb.CalcService.Add:input_type -> pb.AdditionRequest + 1, // 1: pb.CalcService.Add:output_type -> pb.AdditionResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_calc_service_proto_init() } +func file_calc_service_proto_init() { + if File_calc_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_calc_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdditionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_calc_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdditionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_calc_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_calc_service_proto_goTypes, + DependencyIndexes: file_calc_service_proto_depIdxs, + MessageInfos: file_calc_service_proto_msgTypes, + }.Build() + File_calc_service_proto = out.File + file_calc_service_proto_rawDesc = nil + file_calc_service_proto_goTypes = nil + file_calc_service_proto_depIdxs = nil +} diff --git a/pb/calc_service.proto b/pb/calc_service.proto new file mode 100644 index 0000000..8db2c59 --- /dev/null +++ b/pb/calc_service.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package pb; +option go_package = "./"; + +service CalcService { + rpc Add(AdditionRequest) returns (AdditionResponse); +} + +message AdditionRequest { + uint64 x = 1; + uint64 y = 2; +} + +message AdditionResponse { + uint64 result = 3; +} diff --git a/pb/calc_service_grpc.pb.go b/pb/calc_service_grpc.pb.go new file mode 100644 index 0000000..4eef89d --- /dev/null +++ b/pb/calc_service_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.12 +// source: calc_service.proto + +package __ + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// CalcServiceClient is the client API for CalcService service. +// +// 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. +type CalcServiceClient interface { + Add(ctx context.Context, in *AdditionRequest, opts ...grpc.CallOption) (*AdditionResponse, error) +} + +type calcServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCalcServiceClient(cc grpc.ClientConnInterface) CalcServiceClient { + return &calcServiceClient{cc} +} + +func (c *calcServiceClient) Add(ctx context.Context, in *AdditionRequest, opts ...grpc.CallOption) (*AdditionResponse, error) { + out := new(AdditionResponse) + err := c.cc.Invoke(ctx, "/pb.CalcService/Add", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CalcServiceServer is the server API for CalcService service. +// All implementations must embed UnimplementedCalcServiceServer +// for forward compatibility +type CalcServiceServer interface { + Add(context.Context, *AdditionRequest) (*AdditionResponse, error) + mustEmbedUnimplementedCalcServiceServer() +} + +// UnimplementedCalcServiceServer must be embedded to have forward compatible implementations. +type UnimplementedCalcServiceServer struct { +} + +func (UnimplementedCalcServiceServer) Add(context.Context, *AdditionRequest) (*AdditionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Add not implemented") +} +func (UnimplementedCalcServiceServer) mustEmbedUnimplementedCalcServiceServer() {} + +// UnsafeCalcServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CalcServiceServer will +// result in compilation errors. +type UnsafeCalcServiceServer interface { + mustEmbedUnimplementedCalcServiceServer() +} + +func RegisterCalcServiceServer(s grpc.ServiceRegistrar, srv CalcServiceServer) { + s.RegisterService(&CalcService_ServiceDesc, srv) +} + +func _CalcService_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AdditionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CalcServiceServer).Add(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.CalcService/Add", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CalcServiceServer).Add(ctx, req.(*AdditionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CalcService_ServiceDesc is the grpc.ServiceDesc for CalcService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CalcService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.CalcService", + HandlerType: (*CalcServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Add", + Handler: _CalcService_Add_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "calc_service.proto", +} diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..e5f88cf --- /dev/null +++ b/server/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "context" + "log" + "net" + + pb "git.strikerlulu.me/strikerlulu/grpc-mocker/pb" + + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +type CalcServer struct{ + pb.UnimplementedCalcServiceServer + response *pb.AdditionResponse + err error +} + +func (s *CalcServer) Add(ctx context.Context, r *pb.AdditionRequest) (*pb.AdditionResponse, error) { + result := r.X + r.Y + return &pb.AdditionResponse{Result: result}, nil +} + +func main() { + lis,err := net.Listen("tcp",":3000") + if err != nil { + log.Fatalf("Failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterCalcServiceServer(s, &CalcServer{}) + reflection.Register(s) + if err := s.Serve(lis); err != nil { + log.Fatalf("Failed to server: %v", err) + } +} diff --git a/server/main_test.go b/server/main_test.go new file mode 100644 index 0000000..345a8b1 --- /dev/null +++ b/server/main_test.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + "net" + "testing" + + pb "git.strikerlulu.me/strikerlulu/grpc-mocker/pb" + + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + "google.golang.org/grpc/test/bufconn" +) + +type mockServer struct { + pb.UnimplementedCalcServiceServer + response *pb.AdditionResponse + err error +} + +func (s *mockServer) Add(ctx context.Context, req *pb.AdditionRequest) (*pb.AdditionResponse, error) { + return s.response, s.err +} + +func TestCalcService(t *testing.T) { + bufSize := 1024 * 1024 + listener := bufconn.Listen(bufSize) + + // Create a gRPC server and register the mock service + server := grpc.NewServer() + mock := &mockServer{ + response: &pb.AdditionResponse{Result: 3}, + err: nil, + } + pb.RegisterCalcServiceServer(server, mock) + reflection.Register(server) + + go func() { + if err := server.Serve(listener); err != nil { + t.Fatalf("server failed to start: %v", err) + } + }() + + // Create a gRPC client to use in tests + conn, err := grpc.DialContext(context.Background(), "bufnet", + grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { + return listener.Dial() + }), + grpc.WithInsecure()) + if err != nil { + t.Fatalf("failed to dial bufnet: %v", err) + } + client := pb.NewCalcServiceClient(conn) + + resp, err := client.Add(context.Background(), &pb.AdditionRequest{X: 5,Y: 5}) + assert.NoError(t, err) + // we get mocker 3 instead of 5 + assert.Equal(t, uint64(3), resp.Result) + + server.Stop() +}