From 7290579e7d4e96c37880ffedbb1e0e44653211ef Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Wed, 20 Dec 2017 10:11:57 -0800 Subject: [PATCH] fn: tests: adding hot container timeout and huge memory cases (#611) * fn: adding hot container timeout and huge memory cases *) switching TestRouteRunnerTimeout to fn-test-utils to handle both hot and cold. *) in server_test added content-length handling as protocol http does not create content-length if it is not present. --- api/server/runner_test.go | 23 +++++++++++++--------- api/server/server_test.go | 41 ++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/api/server/runner_test.go b/api/server/runner_test.go index f7f65c85d..4fa9c0e74 100644 --- a/api/server/runner_test.go +++ b/api/server/runner_test.go @@ -243,8 +243,10 @@ func TestRouteRunnerTimeout(t *testing.T) { {Name: "myapp", Config: models.Config{}}, }, []*models.Route{ - {Path: "/sleeper", AppName: "myapp", Image: "fnproject/sleeper", Type: "sync", Memory: 128, Timeout: 4, IdleTimeout: 30}, - {Path: "/waitmemory", AppName: "myapp", Image: "fnproject/sleeper", Type: "sync", Memory: hugeMem, Timeout: 1, IdleTimeout: 30}, + {Path: "/cold", AppName: "myapp", Image: "fnproject/fn-test-utils", Type: "sync", Memory: 128, Timeout: 4, IdleTimeout: 30}, + {Path: "/hot", AppName: "myapp", Image: "fnproject/fn-test-utils", Type: "sync", Format: "http", Memory: 128, Timeout: 4, IdleTimeout: 30}, + {Path: "/bigmem-cold", AppName: "myapp", Image: "fnproject/fn-test-utils", Type: "sync", Memory: hugeMem, Timeout: 1, IdleTimeout: 30}, + {Path: "/bigmem-hot", AppName: "myapp", Image: "fnproject/fn-test-utils", Type: "sync", Format: "http", Memory: hugeMem, Timeout: 1, IdleTimeout: 30}, }, nil, ) @@ -261,17 +263,20 @@ func TestRouteRunnerTimeout(t *testing.T) { expectedCode int expectedHeaders map[string][]string }{ - {"/r/myapp/sleeper", `{"sleep": 0}`, "POST", http.StatusOK, nil}, - {"/r/myapp/sleeper", `{"sleep": 5}`, "POST", http.StatusGatewayTimeout, nil}, - {"/r/myapp/waitmemory", `{"sleep": 0}`, "POST", http.StatusServiceUnavailable, map[string][]string{"Retry-After": {"15"}}}, + {"/r/myapp/cold", `{"sleepTime": 0, "isDebug": true}`, "POST", http.StatusOK, nil}, + {"/r/myapp/cold", `{"sleepTime": 5000, "isDebug": true}`, "POST", http.StatusGatewayTimeout, nil}, + {"/r/myapp/hot", `{"sleepTime": 5000, "isDebug": true}`, "POST", http.StatusGatewayTimeout, nil}, + {"/r/myapp/hot", `{"sleepTime": 0, "isDebug": true}`, "POST", http.StatusOK, nil}, + {"/r/myapp/bigmem-cold", `{"sleepTime": 0, "isDebug": true}`, "POST", http.StatusServiceUnavailable, map[string][]string{"Retry-After": {"15"}}}, + {"/r/myapp/bigmem-hot", `{"sleepTime": 0, "isDebug": true}`, "POST", http.StatusServiceUnavailable, map[string][]string{"Retry-After": {"15"}}}, } { body := strings.NewReader(test.body) _, rec := routerRequest(t, srv.Router, test.method, test.path, body) if rec.Code != test.expectedCode { t.Log(buf.String()) - t.Errorf("Test %d: Expected status code to be %d but was %d", - i, test.expectedCode, rec.Code) + t.Errorf("Test %d: Expected status code to be %d but was %d body: %#v", + i, test.expectedCode, rec.Code, rec.Body.String()) } if test.expectedHeaders == nil { @@ -280,8 +285,8 @@ func TestRouteRunnerTimeout(t *testing.T) { for name, header := range test.expectedHeaders { if header[0] != rec.Header().Get(name) { t.Log(buf.String()) - t.Errorf("Test %d: Expected header `%s` to be %s but was %s", - i, name, header[0], rec.Header().Get(name)) + t.Errorf("Test %d: Expected header `%s` to be %s but was %s body: %#v", + i, name, header[0], rec.Header().Get(name), rec.Body.String()) } } } diff --git a/api/server/server_test.go b/api/server/server_test.go index 89d930d56..be1acdaa9 100644 --- a/api/server/server_test.go +++ b/api/server/server_test.go @@ -9,6 +9,7 @@ import ( "net/http" "net/http/httptest" "os" + "strconv" "strings" "testing" @@ -33,30 +34,52 @@ func testServer(ds models.Datastore, mq models.MessageQueue, logDB models.LogSto ) } -func routerRequest(t *testing.T, router *gin.Engine, method, path string, body io.Reader) (*http.Request, *httptest.ResponseRecorder) { +func createRequest(t *testing.T, method, path string, body io.Reader) *http.Request { + + bodyLen := int64(0) + + // HACK: derive content-length since protocol/http does not add content-length + // if it's not present. + if body != nil { + buf := &bytes.Buffer{} + nRead, err := io.Copy(buf, body) + if err != nil { + t.Fatalf("Test: Could not copy %s request body to %s: %v", method, path, err) + } + + bodyLen = nRead + body = buf + } + req, err := http.NewRequest(method, "http://127.0.0.1:8080"+path, body) if err != nil { t.Fatalf("Test: Could not create %s request to %s: %v", method, path, err) } + + if body != nil { + req.ContentLength = bodyLen + req.Header.Set("Content-Length", strconv.FormatInt(bodyLen, 10)) + } + + return req +} + +func routerRequest(t *testing.T, router *gin.Engine, method, path string, body io.Reader) (*http.Request, *httptest.ResponseRecorder) { + req := createRequest(t, method, path, body) return routerRequest2(t, router, req) } func routerRequest2(t *testing.T, router *gin.Engine, req *http.Request) (*http.Request, *httptest.ResponseRecorder) { - rec := httptest.NewRecorder() + rec.Body = new(bytes.Buffer) router.ServeHTTP(rec, req) - return req, rec } func newRouterRequest(t *testing.T, method, path string, body io.Reader) (*http.Request, *httptest.ResponseRecorder) { - req, err := http.NewRequest(method, "http://127.0.0.1:8080"+path, body) - if err != nil { - t.Fatalf("Test: Could not create %s request to %s: %v", method, path, err) - } - + req := createRequest(t, method, path, body) rec := httptest.NewRecorder() - + rec.Body = new(bytes.Buffer) return req, rec }