mirror of
https://github.com/openfaas/faas.git
synced 2025-06-08 16:26:47 +00:00
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>
268 lines
6.4 KiB
Go
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)
|
|
}
|
|
}
|