From 70e9a83e87151dd60267bb9d11a65ff2d915c29e Mon Sep 17 00:00:00 2001 From: "Alex Ellis (VMware)" Date: Sat, 17 Mar 2018 20:18:09 +0000 Subject: [PATCH] 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) --- watchdog/Dockerfile | 5 ++--- watchdog/config_test.go | 25 +++++++++++++++++++++++++ watchdog/main.go | 4 ++++ watchdog/readconfig.go | 15 +++++++++++++++ watchdog/requesthandler_test.go | 24 ++++++++++++------------ 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/watchdog/Dockerfile b/watchdog/Dockerfile index 85d14799..3205ee5c 100644 --- a/watchdog/Dockerfile +++ b/watchdog/Dockerfile @@ -6,8 +6,7 @@ COPY main.go . COPY readconfig.go . COPY config_test.go . COPY requesthandler_test.go . -#COPY fastForkRequestHandler.go . -#COPY requestHandler.go . + COPY types types # Run a gofmt and exclude all vendored code. @@ -17,6 +16,6 @@ RUN go test -v ./... # Stripping via -ldflags "-s -w" RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags "-s -w" -installsuffix cgo -o watchdog . \ - && GOARM=6 GOARCH=arm CGO_ENABLED=0 GOOS=linux go build -a -ldflags "-s -w" -installsuffix cgo -o watchdog-armhf . \ + && GOARM=7 GOARCH=arm CGO_ENABLED=0 GOOS=linux go build -a -ldflags "-s -w" -installsuffix cgo -o watchdog-armhf . \ && GOARCH=arm64 CGO_ENABLED=0 GOOS=linux go build -a -ldflags "-s -w" -installsuffix cgo -o watchdog-arm64 . \ && GOOS=windows CGO_ENABLED=0 go build -a -ldflags "-s -w" -installsuffix cgo -o watchdog.exe . diff --git a/watchdog/config_test.go b/watchdog/config_test.go index 1c22e0cc..3c49c2d7 100644 --- a/watchdog/config_test.go +++ b/watchdog/config_test.go @@ -144,6 +144,31 @@ func TestRead_EmptyTimeoutConfig(t *testing.T) { } } +func TestRead_DefaultPortConfig(t *testing.T) { + defaults := NewEnvBucket() + + readConfig := ReadConfig{} + config := readConfig.Read(defaults) + want := 8080 + if config.port != want { + t.Logf("port got: %d, want: %d\n", config.port, want) + t.Fail() + } +} + +func TestRead_PortConfig(t *testing.T) { + defaults := NewEnvBucket() + defaults.Setenv("port", "8081") + + readConfig := ReadConfig{} + config := readConfig.Read(defaults) + want := 8081 + if config.port != want { + t.Logf("port got: %d, want: %d\n", config.port, want) + t.Fail() + } +} + func TestRead_ReadAndWriteTimeoutConfig(t *testing.T) { defaults := NewEnvBucket() defaults.Setenv("read_timeout", "10") diff --git a/watchdog/main.go b/watchdog/main.go index 836ca997..0682c211 100644 --- a/watchdog/main.go +++ b/watchdog/main.go @@ -193,6 +193,7 @@ func pipeRequest(config *WatchdogConfig, w http.ResponseWriter, r *http.Request, header := w.Header() debugHeaders(&header, "out") } + if len(bytesWritten) > 0 { log.Printf("%s - Duration: %f seconds", bytesWritten, execTime) } else { @@ -205,6 +206,7 @@ func getAdditionalEnvs(config *WatchdogConfig, r *http.Request, method string) [ if config.cgiHeaders { envs = os.Environ() + for k, v := range r.Header { kv := fmt.Sprintf("Http_%s=%s", strings.Replace(k, "-", "_", -1), v[0]) envs = append(envs, kv) @@ -216,6 +218,7 @@ func getAdditionalEnvs(config *WatchdogConfig, r *http.Request, method string) [ if config.writeDebug { log.Println("Query ", r.URL.RawQuery) } + if len(r.URL.RawQuery) > 0 { envs = append(envs, fmt.Sprintf("Http_Query=%s", r.URL.RawQuery)) } @@ -223,6 +226,7 @@ func getAdditionalEnvs(config *WatchdogConfig, r *http.Request, method string) [ if config.writeDebug { log.Println("Path ", r.URL.Path) } + if len(r.URL.Path) > 0 { envs = append(envs, fmt.Sprintf("Http_Path=%s", r.URL.Path)) } diff --git a/watchdog/readconfig.go b/watchdog/readconfig.go index af5d7c95..b4cc7355 100644 --- a/watchdog/readconfig.go +++ b/watchdog/readconfig.go @@ -43,6 +43,17 @@ func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { return duration } +func parseIntValue(val string, fallback int) int { + if len(val) > 0 { + parsedVal, parseErr := strconv.Atoi(val) + if parseErr == nil && parsedVal >= 0 { + return parsedVal + } + } + + return fallback +} + // Read fetches config from environmental variables. func (ReadConfig) Read(hasEnv HasEnv) WatchdogConfig { cfg := WatchdogConfig{ @@ -56,6 +67,7 @@ func (ReadConfig) Read(hasEnv HasEnv) WatchdogConfig { cfg.writeTimeout = parseIntOrDurationValue(hasEnv.Getenv("write_timeout"), time.Second*5) cfg.execTimeout = parseIntOrDurationValue(hasEnv.Getenv("exec_timeout"), time.Second*0) + cfg.port = parseIntValue(hasEnv.Getenv("port"), 8080) writeDebugEnv := hasEnv.Getenv("write_debug") if isBoolValueSet(writeDebugEnv) { @@ -109,4 +121,7 @@ type WatchdogConfig struct { // contentType forces a specific pre-defined value for all responses contentType string + + // port for HTTP server + port int } diff --git a/watchdog/requesthandler_test.go b/watchdog/requesthandler_test.go index afe4be04..f5cbfa7a 100644 --- a/watchdog/requesthandler_test.go +++ b/watchdog/requesthandler_test.go @@ -43,22 +43,22 @@ func TestHandler_HasCustomHeaderInFunction_WithCgi_Mode(t *testing.T) { required := http.StatusOK if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code: got %v, but wanted %v", + 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("'env' should printed: Http_ContentLength=0, got: %s\n", val) + t.Errorf(config.faasProcess+" should print: 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) + 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("Exec of cat should have given a duration as an X-Duration-Seconds header\n") + t.Errorf(config.faasProcess + " should have given a duration as an X-Duration-Seconds header\n") } } @@ -82,7 +82,7 @@ func TestHandler_HasCustomHeaderInFunction_WithCgiMode_AndBody(t *testing.T) { required := http.StatusOK if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code: got %v, but wanted %v", + t.Errorf("handler returned wrong status code - got: %v, want: %v", status, required) } @@ -120,7 +120,7 @@ func TestHandler_DoesntHaveCustomHeaderInFunction_WithoutCgi_Mode(t *testing.T) required := http.StatusOK if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code: got %v, but wanted %v", + t.Errorf("handler returned wrong status code - got: %v, want: %v", status, required) } @@ -154,13 +154,13 @@ func TestHandler_HasXDurationSecondsHeader(t *testing.T) { required := http.StatusOK if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code: got %v, but wanted %v", + 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 cat should have given a duration as an X-Duration-Seconds header\n") + t.Errorf("Exec of " + config.faasProcess + " should have given a duration as an X-Duration-Seconds header") } } @@ -186,7 +186,7 @@ func TestHandler_RequestTimeoutFailsForExceededDuration(t *testing.T) { required := http.StatusRequestTimeout if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code for verb [%s]: got %v, but wanted %v", + t.Errorf("handler returned wrong status code for verb [%s] - got: %v, want: %v", verb, status, required) } } @@ -212,7 +212,7 @@ func TestHandler_StatusOKAllowed_ForWriteableVerbs(t *testing.T) { required := http.StatusOK if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code for verb [%s]: got %v, but wanted %v", + t.Errorf("handler returned wrong status code for verb [%s] - got: %v, want: %v", verb, status, required) } @@ -238,7 +238,7 @@ func TestHandler_StatusMethodNotAllowed_ForUnknown(t *testing.T) { required := http.StatusMethodNotAllowed if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code: got %v, but wanted %v", + t.Errorf("handler returned wrong status code: got %v, want: %v", status, required) } } @@ -261,7 +261,7 @@ func TestHandler_StatusOKForGETAndNoBody(t *testing.T) { required := http.StatusOK if status := rr.Code; status != required { - t.Errorf("handler returned wrong status code: got %v, but wanted %v", + t.Errorf("handler returned wrong status code: got %v, want: %v", status, required) } }