mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: empty body tests for cold and hot (json/http) (#941)
This commit is contained in:
@@ -315,6 +315,80 @@ func TestRouteRunnerIOPipes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRouteRunnerExecEmptyBody(t *testing.T) {
|
||||||
|
buf := setLogBuffer()
|
||||||
|
isFailure := false
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if isFailure {
|
||||||
|
t.Log(buf.String())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
rCfg := map[string]string{"ENABLE_HEADER": "yes", "ENABLE_FOOTER": "yes"} // enable container start/end header/footer
|
||||||
|
rHdr := map[string][]string{"X-Function": {"Test"}}
|
||||||
|
rImg := "fnproject/fn-test-utils"
|
||||||
|
|
||||||
|
app := &models.App{Name: "soup"}
|
||||||
|
app.SetDefaults()
|
||||||
|
ds := datastore.NewMockInit(
|
||||||
|
[]*models.App{app},
|
||||||
|
[]*models.Route{
|
||||||
|
{Path: "/cold", AppID: app.ID, Image: rImg, Type: "sync", Memory: 64, Timeout: 10, IdleTimeout: 20, Headers: rHdr, Config: rCfg},
|
||||||
|
{Path: "/hothttp", AppID: app.ID, Image: rImg, Type: "sync", Format: "http", Memory: 64, Timeout: 10, IdleTimeout: 20, Headers: rHdr, Config: rCfg},
|
||||||
|
{Path: "/hotjson", AppID: app.ID, Image: rImg, Type: "sync", Format: "json", Memory: 64, Timeout: 10, IdleTimeout: 20, Headers: rHdr, Config: rCfg},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
rnr, cancelrnr := testRunner(t, ds)
|
||||||
|
defer cancelrnr()
|
||||||
|
|
||||||
|
srv := testServer(ds, &mqs.Mock{}, ds, rnr, ServerTypeFull)
|
||||||
|
|
||||||
|
expHeaders := map[string][]string{"X-Function": {"Test"}}
|
||||||
|
emptyBody := `{"echoContent": "_TRX_ID_", "isDebug": true, "isEmptyBody": true}`
|
||||||
|
|
||||||
|
// Test hot cases twice to rule out hot-containers corrupting next request.
|
||||||
|
testCases := []struct {
|
||||||
|
path string
|
||||||
|
}{
|
||||||
|
{"/r/soup/cold/"},
|
||||||
|
{"/r/soup/hothttp"},
|
||||||
|
{"/r/soup/hothttp"},
|
||||||
|
{"/r/soup/hotjson"},
|
||||||
|
{"/r/soup/hotjson"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range testCases {
|
||||||
|
trx := fmt.Sprintf("_trx_%d_", i)
|
||||||
|
body := strings.NewReader(strings.Replace(emptyBody, "_TRX_ID_", trx, 1))
|
||||||
|
_, rec := routerRequest(t, srv.Router, "GET", test.path, body)
|
||||||
|
respBytes, _ := ioutil.ReadAll(rec.Body)
|
||||||
|
respBody := string(respBytes)
|
||||||
|
maxBody := len(respBody)
|
||||||
|
if maxBody > 1024 {
|
||||||
|
maxBody = 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
if rec.Code != http.StatusOK {
|
||||||
|
isFailure = true
|
||||||
|
t.Errorf("Test %d: Expected status code to be %d but was %d. body: %s",
|
||||||
|
i, http.StatusOK, rec.Code, respBody[:maxBody])
|
||||||
|
} else if len(respBytes) != 0 {
|
||||||
|
isFailure = true
|
||||||
|
t.Errorf("Test %d: Expected empty body but got %d. body: %s",
|
||||||
|
i, len(respBytes), respBody[:maxBody])
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, header := range expHeaders {
|
||||||
|
if header[0] != rec.Header().Get(name) {
|
||||||
|
isFailure = true
|
||||||
|
t.Errorf("Test %d: Expected header `%s` to be %s but was %s. body: %s",
|
||||||
|
i, name, header[0], rec.Header().Get(name), respBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
func TestRouteRunnerExecution(t *testing.T) {
|
func TestRouteRunnerExecution(t *testing.T) {
|
||||||
buf := setLogBuffer()
|
buf := setLogBuffer()
|
||||||
isFailure := false
|
isFailure := false
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ type AppRequest struct {
|
|||||||
PostOutGarbage string `json:"postOutGarbage,omitempty"`
|
PostOutGarbage string `json:"postOutGarbage,omitempty"`
|
||||||
// spit this out in stderr after processing each request
|
// spit this out in stderr after processing each request
|
||||||
PostErrGarbage string `json:"postErrGarbage,omitempty"`
|
PostErrGarbage string `json:"postErrGarbage,omitempty"`
|
||||||
|
// test empty body
|
||||||
|
IsEmptyBody bool `json:"isEmptyBody,omitempty"`
|
||||||
// TODO: simulate slow read/slow write
|
// TODO: simulate slow read/slow write
|
||||||
// TODO: simulate partial IO write/read
|
// TODO: simulate partial IO write/read
|
||||||
// TODO: simulate high cpu usage (async and sync)
|
// TODO: simulate high cpu usage (async and sync)
|
||||||
@@ -133,7 +135,9 @@ func finalizeRequest(out *fdkresponse, req *AppRequest, resp *AppResponse) {
|
|||||||
out.JasonContentType = req.JasonContentType
|
out.JasonContentType = req.JasonContentType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !req.IsEmptyBody {
|
||||||
json.NewEncoder(out).Encode(resp)
|
json.NewEncoder(out).Encode(resp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processRequest(ctx context.Context, in io.Reader) (*AppRequest, *AppResponse) {
|
func processRequest(ctx context.Context, in io.Reader) (*AppRequest, *AppResponse) {
|
||||||
|
|||||||
Reference in New Issue
Block a user