diff --git a/examples/gateway/handlers.go b/examples/gateway/handlers.go index 7581125b91c..b0099bc3f60 100644 --- a/examples/gateway/handlers.go +++ b/examples/gateway/handlers.go @@ -1,6 +1,7 @@ package gateway import ( + "fmt" "net/http" "path" "strings" @@ -44,5 +45,9 @@ func preflightHandler(w http.ResponseWriter, r *http.Request) { methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"} w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ",")) glog.Infof("preflight request for %s", r.URL.Path) - return +} + +func healthzHandler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + fmt.Fprintln(w, "ok") } diff --git a/examples/gateway/main.go b/examples/gateway/main.go index c59fd1f2991..d21cbcb4a0b 100644 --- a/examples/gateway/main.go +++ b/examples/gateway/main.go @@ -37,6 +37,7 @@ func Run(ctx context.Context, opts Options) error { mux := http.NewServeMux() mux.HandleFunc("/swagger/", swaggerServer(opts.SwaggerDir)) + mux.HandleFunc("/healthz", healthzHandler) gw, err := newGateway(ctx, opts.GRPCServer.Network, opts.GRPCServer.Addr, opts.Mux) if err != nil { diff --git a/examples/integration/integration_test.go b/examples/integration/integration_test.go index 97b72dba717..ea86d9f5a34 100644 --- a/examples/integration/integration_test.go +++ b/examples/integration/integration_test.go @@ -13,7 +13,6 @@ import ( "strings" "sync" "testing" - "time" "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" @@ -60,8 +59,9 @@ func TestForwardResponseOption(t *testing.T) { return } }() - - time.Sleep(100 * time.Millisecond) + if err := waitForGateway(ctx, 8081); err != nil { + t.Errorf("waitForGateway(ctx, 8081) failed with %v; want success", err) + } testEcho(t, 8081, "application/vnd.docker.plugins.v1.1+json") } diff --git a/examples/integration/main_test.go b/examples/integration/main_test.go index 2ce46ae4595..cbe26a799a7 100644 --- a/examples/integration/main_test.go +++ b/examples/integration/main_test.go @@ -4,6 +4,7 @@ import ( "context" "flag" "fmt" + "net/http" "os" "testing" "time" @@ -32,6 +33,30 @@ func runGateway(ctx context.Context, addr string, opts ...gwruntime.ServeMuxOpti }) } +func waitForGateway(ctx context.Context, port uint16) error { + t := time.NewTimer(10 * time.Second) + + var err error + for { + if r, err := http.Get(fmt.Sprintf("http://localhost:%d/healthz", port)); err == nil { + if r.StatusCode == http.StatusOK { + return nil + } + err = fmt.Errorf("server localhost:%d returned an unexpected status %d", port, r.StatusCode) + } + + glog.Infof("Waiting for localhost:%d to get ready", port) + s := time.NewTimer(10 * time.Millisecond) + select { + case <-ctx.Done(): + return err + case <-t.C: + return err + case <-s.C: + } + } +} + func runServers(ctx context.Context) <-chan error { ch := make(chan error, 2) go func() { @@ -57,7 +82,9 @@ func TestMain(m *testing.M) { ch := make(chan int, 1) go func() { - time.Sleep(100 * time.Millisecond) + if err := waitForGateway(ctx, 8080); err != nil { + glog.Errorf("waitForGateway(ctx, 8080) failed with %v; want success", err) + } ch <- m.Run() }() diff --git a/examples/integration/proto_error_test.go b/examples/integration/proto_error_test.go index a893da0db17..84a631f9b1c 100644 --- a/examples/integration/proto_error_test.go +++ b/examples/integration/proto_error_test.go @@ -29,11 +29,9 @@ func TestWithProtoErrorHandler(t *testing.T) { const port = 8082 go runServer(ctx, t, port) - - // Waiting for the server's getting available. - // TODO(yugui) find a better way to wait - time.Sleep(100 * time.Millisecond) - + if err := waitForGateway(ctx, 8082); err != nil { + t.Errorf("waitForGateway(ctx, 8082) failed with %v; want success", err) + } testEcho(t, port, "application/json") testEchoBody(t, port) } @@ -50,9 +48,9 @@ func TestABEWithProtoErrorHandler(t *testing.T) { const port = 8083 go runServer(ctx, t, port) - // Waiting for the server's getting available. - // TODO(yugui) find a better way to wait - time.Sleep(100 * time.Millisecond) + if err := waitForGateway(ctx, 8083); err != nil { + t.Errorf("waitForGateway(ctx, 8083) failed with %v; want success", err) + } testABECreate(t, port) testABECreateBody(t, port) @@ -122,10 +120,9 @@ func TestUnknownPathWithProtoError(t *testing.T) { const port = 8084 go runServer(ctx, t, port) - - // Waiting for the server's getting available. - // TODO(yugui) find a better way to wait - time.Sleep(100 * time.Millisecond) + if err := waitForGateway(ctx, 8084); err != nil { + t.Errorf("waitForGateway(ctx, 8084) failed with %v; want success", err) + } url := fmt.Sprintf("http://localhost:%d", port) resp, err := http.Post(url, "application/json", strings.NewReader("{}"))