Skip to content

Basic GRPCRoute Conformance Tests #2745

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions conformance/base/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -507,3 +507,150 @@ spec:
resources:
requests:
cpu: 10m
---
apiVersion: v1
kind: Service
metadata:
name: grpc-infra-backend-v1
namespace: gateway-conformance-infra
spec:
selector:
app: grpc-infra-backend-v1
ports:
- protocol: TCP
port: 8080
targetPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-infra-backend-v1
namespace: gateway-conformance-infra
labels:
app: grpc-infra-backend-v1
spec:
replicas: 2
selector:
matchLabels:
app: grpc-infra-backend-v1
template:
metadata:
labels:
app: grpc-infra-backend-v1
spec:
containers:
- name: grpc-infra-backend-v1
# TODO: Migrate to gcr.io/k8s-staging-gateway-api once possible
image: us-docker.pkg.dev/grpc-testing/testing-images-public/gateway-api/echo-basic:alpha1
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: GRPC_ECHO_SERVER
value: "1"
resources:
requests:
cpu: 10m
---
apiVersion: v1
kind: Service
metadata:
name: grpc-infra-backend-v2
namespace: gateway-conformance-infra
spec:
selector:
app: grpc-infra-backend-v2
ports:
- protocol: TCP
port: 8080
targetPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-infra-backend-v2
namespace: gateway-conformance-infra
labels:
app: grpc-infra-backend-v2
spec:
replicas: 2
selector:
matchLabels:
app: grpc-infra-backend-v2
template:
metadata:
labels:
app: grpc-infra-backend-v2
spec:
containers:
- name: grpc-infra-backend-v2
# TODO: Migrate to gcr.io/k8s-staging-gateway-api once possible
image: us-docker.pkg.dev/grpc-testing/testing-images-public/gateway-api/echo-basic:alpha1
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: GRPC_ECHO_SERVER
value: "1"
resources:
requests:
cpu: 10m
---
apiVersion: v1
kind: Service
metadata:
name: grpc-infra-backend-v3
namespace: gateway-conformance-infra
spec:
selector:
app: grpc-infra-backend-v3
ports:
- protocol: TCP
port: 8080
targetPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-infra-backend-v3
namespace: gateway-conformance-infra
labels:
app: grpc-infra-backend-v3
spec:
replicas: 2
selector:
matchLabels:
app: grpc-infra-backend-v3
template:
metadata:
labels:
app: grpc-infra-backend-v3
spec:
containers:
- name: grpc-infra-backend-v3
# TODO: Migrate to gcr.io/k8s-staging-gateway-api once possible
image: us-docker.pkg.dev/grpc-testing/testing-images-public/gateway-api/echo-basic:alpha1
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: GRPC_ECHO_SERVER
value: "1"
resources:
requests:
cpu: 10m
1 change: 1 addition & 0 deletions conformance/echo-basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
echo-basic
16 changes: 16 additions & 0 deletions conformance/echo-basic/.go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module sigs.k8s.io/gateway-api/conformance/echo-basic

go 1.21

require (
golang.org/x/net v0.21.0
google.golang.org/grpc v1.53.0
google.golang.org/protobuf v1.28.1
)

require (
github.com/golang/protobuf v1.5.2 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
)
21 changes: 21 additions & 0 deletions conformance/echo-basic/.go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
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=
33 changes: 22 additions & 11 deletions conformance/echo-basic/echo-basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"golang.org/x/net/websocket"

g "sigs.k8s.io/gateway-api/conformance/echo-basic/grpc"
)

// RequestAssertions contains information about the request and the Ingress
Expand Down Expand Up @@ -62,7 +64,7 @@ type preserveSlashes struct {
}

func (s *preserveSlashes) ServeHTTP(w http.ResponseWriter, r *http.Request) {
r.URL.Path = strings.Replace(r.URL.Path, "//", "/", -1)
r.URL.Path = strings.ReplaceAll(r.URL.Path, "//", "/")
s.mux.ServeHTTP(w, r)
}

Expand All @@ -77,6 +79,11 @@ type Context struct {
var context Context

func main() {
if os.Getenv("GRPC_ECHO_SERVER") != "" {
g.Main()
return
}

httpPort := os.Getenv("HTTP_PORT")
if httpPort == "" {
httpPort = "3000"
Expand Down Expand Up @@ -109,7 +116,7 @@ func main() {

go func() {
fmt.Printf("Starting server, listening on port %s (http)\n", httpPort)
err := http.ListenAndServe(fmt.Sprintf(":%s", httpPort), httpHandler)
err := http.ListenAndServe(fmt.Sprintf(":%s", httpPort), httpHandler) //nolint:gosec
if err != nil {
errchan <- err
}
Expand Down Expand Up @@ -137,12 +144,12 @@ func wsHandler(ws *websocket.Conn) {
fmt.Println("established websocket connection", ws.RemoteAddr())
// Echo websocket frames from the connection back to the client
// until io.EOF
io.Copy(ws, ws)
_, _ = io.Copy(ws, ws)
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
func healthHandler(w http.ResponseWriter, r *http.Request) { //nolint:revive
w.WriteHeader(200)
w.Write([]byte(`OK`))
_, _ = w.Write([]byte(`OK`))
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -224,7 +231,7 @@ func echoHandler(w http.ResponseWriter, r *http.Request) {
writeEchoResponseHeaders(w, r.Header)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Write(js)
_, _ = w.Write(js)
}

func writeEchoResponseHeaders(w http.ResponseWriter, headers http.Header) {
Expand All @@ -242,7 +249,7 @@ func writeEchoResponseHeaders(w http.ResponseWriter, headers http.Header) {
}
}

func processError(w http.ResponseWriter, err error, code int) {
func processError(w http.ResponseWriter, err error, code int) { //nolint:unparam
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Content-Type-Options", "nosniff")
body, err := json.Marshal(struct {
Expand All @@ -257,7 +264,7 @@ func processError(w http.ResponseWriter, err error, code int) {
}

w.WriteHeader(code)
w.Write(body)
_, _ = w.Write(body)
}

func listenAndServeTLS(addr string, serverCert string, serverPrivKey string, clientCA string, handler http.Handler) error {
Expand All @@ -280,7 +287,7 @@ func listenAndServeTLS(addr string, serverCert string, serverPrivKey string, cli
config.ClientCAs = certPool
}

srv := &http.Server{
srv := &http.Server{ //nolint:gosec
Addr: addr,
Handler: handler,
TLSConfig: &config,
Expand Down Expand Up @@ -311,11 +318,15 @@ func tlsStateToAssertions(connectionState *tls.ConnectionState) *TLSAssertions {
// Convert peer certificates to PEM blocks.
for _, c := range connectionState.PeerCertificates {
var out strings.Builder
pem.Encode(&out, &pem.Block{
err := pem.Encode(&out, &pem.Block{
Type: "CERTIFICATE",
Bytes: c.Raw,
})
state.PeerCertificates = append(state.PeerCertificates, out.String())
if err != nil {
fmt.Printf("failed to encode certificate: %v\n", err)
} else {
state.PeerCertificates = append(state.PeerCertificates, out.String())
}
}

return &state
Expand Down
8 changes: 4 additions & 4 deletions conformance/echo-basic/echo-basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

func TestHealthHandler(t *testing.T) {
// Test a valid health check
req, err := http.NewRequest("GET", "/health", nil)
req, err := http.NewRequest("GET", "/health", nil) //nolint:noctx
if err != nil {
t.Fatal(err)
}
Expand All @@ -50,7 +50,7 @@ func TestHealthHandler(t *testing.T) {

func TestDelayResponse(t *testing.T) {
// Test with a valid delay integer value
req, err := http.NewRequest("GET", "/?delay=1s", nil)
req, err := http.NewRequest("GET", "/?delay=1s", nil) //nolint:noctx
if err != nil {
t.Fatal(err)
}
Expand All @@ -61,7 +61,7 @@ func TestDelayResponse(t *testing.T) {
}

// Test with a valid delay decimal value
req, err = http.NewRequest("GET", "/?delay=0.1s", nil)
req, err = http.NewRequest("GET", "/?delay=0.1s", nil) //nolint:noctx
if err != nil {
t.Fatal(err)
}
Expand All @@ -72,7 +72,7 @@ func TestDelayResponse(t *testing.T) {
}

// Test with an invalid delay value
req, err = http.NewRequest("GET", "/?delay=invalid", nil)
req, err = http.NewRequest("GET", "/?delay=invalid", nil) //nolint:noctx
if err != nil {
t.Fatal(err)
}
Expand Down
7 changes: 0 additions & 7 deletions conformance/echo-basic/go.mod

This file was deleted.

4 changes: 0 additions & 4 deletions conformance/echo-basic/go.sum

This file was deleted.

Loading