faas/watchdog/requesthandler_test.go
Alex Ellis (VMware) 70e9a83e87 Allow override of HTTP port via env-var
HTTP port can now be overriden through use of "port" environmental
variable.

Prefer messaging "want" over "wanted" in error messages, this is more
idiomatic Golang.

Move away from Go ARMv6 (RPi Zero) and give ARMv7 as a minimum
version for release binaries.

Signed-off-by: Alex Ellis (VMware) <alexellis2@gmail.com>
2018-03-17 20:18:09 +00:00

268 lines
6.4 KiB
Go

// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
func TestHandler_make(t *testing.T) {
config := WatchdogConfig{}
handler := makeRequestHandler(&config)
if handler == nil {
t.Fail()
}
}
func TestHandler_HasCustomHeaderInFunction_WithCgi_Mode(t *testing.T) {
rr := httptest.NewRecorder()
body := ""
req, err := http.NewRequest("POST", "/", bytes.NewBufferString(body))
req.Header.Add("custom-header", "value")
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
faasProcess: "env",
cgiHeaders: true,
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusOK
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code - got: %v, want: %v",
status, required)
}
read, _ := ioutil.ReadAll(rr.Body)
val := string(read)
if !strings.Contains(val, "Http_ContentLength=0") {
t.Errorf(config.faasProcess+" should print: Http_ContentLength=0, got: %s\n", val)
}
if !strings.Contains(val, "Http_Custom_Header") {
t.Errorf(config.faasProcess+" should print: Http_Custom_Header, got: %s\n", val)
}
seconds := rr.Header().Get("X-Duration-Seconds")
if len(seconds) == 0 {
t.Errorf(config.faasProcess + " should have given a duration as an X-Duration-Seconds header\n")
}
}
func TestHandler_HasCustomHeaderInFunction_WithCgiMode_AndBody(t *testing.T) {
rr := httptest.NewRecorder()
body := "test"
req, err := http.NewRequest("POST", "/", bytes.NewBufferString(body))
req.Header.Add("custom-header", "value")
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
faasProcess: "env",
cgiHeaders: true,
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusOK
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code - got: %v, want: %v",
status, required)
}
read, _ := ioutil.ReadAll(rr.Body)
val := string(read)
if !strings.Contains(val, fmt.Sprintf("Http_ContentLength=%d", len(body))) {
t.Errorf("'env' should printed: Http_ContentLength=0, got: %s\n", val)
}
if !strings.Contains(val, "Http_Custom_Header") {
t.Errorf("'env' should printed: Http_Custom_Header, got: %s\n", val)
}
seconds := rr.Header().Get("X-Duration-Seconds")
if len(seconds) == 0 {
t.Errorf("Exec of cat should have given a duration as an X-Duration-Seconds header\n")
}
}
func TestHandler_DoesntHaveCustomHeaderInFunction_WithoutCgi_Mode(t *testing.T) {
rr := httptest.NewRecorder()
body := ""
req, err := http.NewRequest("POST", "/", bytes.NewBufferString(body))
req.Header.Add("custom-header", "value")
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
faasProcess: "env",
cgiHeaders: false,
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusOK
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code - got: %v, want: %v",
status, required)
}
read, _ := ioutil.ReadAll(rr.Body)
val := string(read)
if strings.Contains(val, "Http_Custom_Header") {
t.Errorf("'env' should not have printed: Http_Custom_Header, got: %s\n", val)
}
seconds := rr.Header().Get("X-Duration-Seconds")
if len(seconds) == 0 {
t.Errorf("Exec of cat should have given a duration as an X-Duration-Seconds header\n")
}
}
func TestHandler_HasXDurationSecondsHeader(t *testing.T) {
rr := httptest.NewRecorder()
body := "hello"
req, err := http.NewRequest("POST", "/", bytes.NewBufferString(body))
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
faasProcess: "cat",
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusOK
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code - got: %v, want: %v",
status, required)
}
seconds := rr.Header().Get("X-Duration-Seconds")
if len(seconds) == 0 {
t.Errorf("Exec of " + config.faasProcess + " should have given a duration as an X-Duration-Seconds header")
}
}
func TestHandler_RequestTimeoutFailsForExceededDuration(t *testing.T) {
rr := httptest.NewRecorder()
verbs := []string{"POST"}
for _, verb := range verbs {
body := "hello"
req, err := http.NewRequest(verb, "/", bytes.NewBufferString(body))
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
faasProcess: "sleep 2",
execTimeout: time.Duration(100) * time.Millisecond,
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusRequestTimeout
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code for verb [%s] - got: %v, want: %v",
verb, status, required)
}
}
}
func TestHandler_StatusOKAllowed_ForWriteableVerbs(t *testing.T) {
rr := httptest.NewRecorder()
verbs := []string{"POST", "PUT", "UPDATE", "DELETE"}
for _, verb := range verbs {
body := "hello"
req, err := http.NewRequest(verb, "/", bytes.NewBufferString(body))
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
faasProcess: "cat",
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusOK
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code for verb [%s] - got: %v, want: %v",
verb, status, required)
}
buf, _ := ioutil.ReadAll(rr.Body)
val := string(buf)
if val != body {
t.Errorf("Exec of cat did not return input value, %s", val)
}
}
}
func TestHandler_StatusMethodNotAllowed_ForUnknown(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest("UNKNOWN", "/", nil)
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusMethodNotAllowed
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code: got %v, want: %v",
status, required)
}
}
func TestHandler_StatusOKForGETAndNoBody(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", nil)
if err != nil {
t.Fatal(err)
}
config := WatchdogConfig{
// writeDebug: true,
faasProcess: "date",
}
handler := makeRequestHandler(&config)
handler(rr, req)
required := http.StatusOK
if status := rr.Code; status != required {
t.Errorf("handler returned wrong status code: got %v, want: %v",
status, required)
}
}