Repository: fortio/fortio (go)

Issue:
Delay is capped at 1.5 second without mention
Thanks for fortio, which I'm using to compare stacks - it's a great tool!

Something took me a bit by surprise, which is that the `delay` parameter is set to 1.5 second if I put it to anything higher.

The code seems to confirm that:
* https://github.com/istio/fortio/blob/cdb21807bcf3b2b83b94aba311d1a58d5c4ea311/fhttp/http_utils.go#L345
* https://github.com/istio/fortio/blob/cdb21807bcf3b2b83b94aba311d1a58d5c4ea311/fhttp/http_utils.go#L364

I think having an error instead of capping out would be less surprising (just my opinion!).


Pull request description:
Make maximum delay a configurable dynamic flag
Change at runtime to 6s (from 1.5s default):
http://localhost:8080/fortio/flags/set?name=max-echo-delay&value=6s

Fixes #272

Patch:
diff --git a/fhttp/http_utils.go b/fhttp/http_utils.go
index 8b03799..ab400e0 100644
--- a/fhttp/http_utils.go
+++ b/fhttp/http_utils.go
@@ -16,6 +16,7 @@ package fhttp // import "fortio.org/fortio/fhttp"
 
 import (
 	"encoding/base64"
+	"flag"
 	"fmt"
 	"html/template"
 	"io"
@@ -26,6 +27,7 @@ import (
 	"time"
 	"unicode/utf8"
 
+	"fortio.org/fortio/dflag"
 	"fortio.org/fortio/fnet"
 	"fortio.org/fortio/log"
 	"fortio.org/fortio/stats"
@@ -335,8 +337,9 @@ func generateSize(sizeInput string) (size int) {
 }
 
 // MaxDelay is the maximum delay allowed for the echoserver responses.
-// 1.5s so we can test the default 1s timeout in envoy.
-const MaxDelay = 1500 * time.Millisecond
+// It is a dynamic flag with default value of 1.5s so we can test the default 1s timeout in envoy.
+var MaxDelay = dflag.DynDuration(flag.CommandLine, "max-echo-delay", 1500*time.Millisecond,
+	"Maximum sleep time for delay= echo server parameter. dynamic flag.")
 
 // generateDelay from string, format: delay="100ms" for 100% 100ms delay
 // delay="10ms:20,20ms:10,1s:0.5" for 20% 10ms, 10% 20ms, 0.5% 1s and 69.5% 0
@@ -355,8 +358,8 @@ func generateDelay(delay string) time.Duration {
 			return -1
 		}
 		log.Debugf("Parsed delay %s -> %d", delay, d)
-		if d > MaxDelay {
-			d = MaxDelay
+		if d > MaxDelay.Get() {
+			d = MaxDelay.Get()
 		}
 		return d
 	}
@@ -375,8 +378,8 @@ func generateDelay(delay string) time.Duration {
 			log.Warnf("Bad input delay %v -> %v, not a number before colon", delay, l2[0])
 			return -1
 		}
-		if d > MaxDelay {
-			d = MaxDelay
+		if d > MaxDelay.Get() {
+			d = MaxDelay.Get()
 		}
 		percStr := removeTrailingPercent(l2[1])
 		p, err := strconv.ParseFloat(percStr, 32)


Test patch:
diff --git a/fhttp/http_test.go b/fhttp/http_test.go
index e84eba4..bd75109 100644
--- a/fhttp/http_test.go
+++ b/fhttp/http_test.go
@@ -353,8 +353,8 @@ func TestParseDelay(t *testing.T) {
 		{"20ms:101", -1},
 		{"20ms:101%", -1},
 		{"10ms:45,100ms:56", -1},
-		// Max delay case:
-		{"10s:45,10s:55", MaxDelay},
+		// Max delay case: (for 1.5s default)
+		{"10s:45,10s:55", MaxDelay.Get()},
 		// Good cases
 		{"100ms", 100 * time.Millisecond},
 		{"100ms:100", 100 * time.Millisecond},