133 lines
5.4 KiB
Go
133 lines
5.4 KiB
Go
package config_test
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.yuntuo.hk/k2safe/go-omni/config"
|
|
)
|
|
|
|
func TestHTTPFileAndEnvironment(t *testing.T) {
|
|
for _, file := range []struct{ name, body string }{
|
|
{"server.json", `{"http":{"readHeaderTimeout":"2s","readTimeout":"3s","writeTimeout":"4s","idleTimeout":"5s","maxHeaderBytes":8192}}`},
|
|
{"server.yaml", "http:\n readHeaderTimeout: 2s\n readTimeout: 3s\n writeTimeout: 4s\n idleTimeout: 5s\n maxHeaderBytes: 8192\n"},
|
|
} {
|
|
t.Run(file.name, func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), file.name)
|
|
if err := os.WriteFile(path, []byte(file.body), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := config.LoadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := config.HTTPConfig{ReadHeaderTimeout: 2 * time.Second, ReadTimeout: 3 * time.Second, WriteTimeout: 4 * time.Second, IdleTimeout: 5 * time.Second, MaxHeaderBytes: 8192}
|
|
if cfg.HTTP != want {
|
|
t.Fatalf("HTTP: %+v", cfg.HTTP)
|
|
}
|
|
t.Setenv("HTTP_TEST_HTTP_READ_HEADER_TIMEOUT", "6s")
|
|
t.Setenv("HTTP_TEST_HTTP_READ_TIMEOUT", "7s")
|
|
t.Setenv("HTTP_TEST_HTTP_WRITE_TIMEOUT", "8s")
|
|
t.Setenv("HTTP_TEST_HTTP_IDLE_TIMEOUT", "9s")
|
|
t.Setenv("HTTP_TEST_HTTP_MAX_HEADER_BYTES", "16384")
|
|
if err := os.WriteFile(path, []byte(`{"http":{"readHeaderTimeout":"${HTTP_TEST_HTTP_READ_HEADER_TIMEOUT}","readTimeout":"${HTTP_TEST_HTTP_READ_TIMEOUT}","writeTimeout":"${HTTP_TEST_HTTP_WRITE_TIMEOUT}","idleTimeout":"${HTTP_TEST_HTTP_IDLE_TIMEOUT}","maxHeaderBytes":"${HTTP_TEST_HTTP_MAX_HEADER_BYTES}"}}`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := config.LoadProject(path, cfg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want = config.HTTPConfig{ReadHeaderTimeout: 6 * time.Second, ReadTimeout: 7 * time.Second, WriteTimeout: 8 * time.Second, IdleTimeout: 9 * time.Second, MaxHeaderBytes: 16384}
|
|
if got.HTTP != want {
|
|
t.Fatalf("overlay: %+v", got.HTTP)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHTTPInvalidAndUnsupportedSettings(t *testing.T) {
|
|
for _, key := range []string{"READ_HEADER_TIMEOUT", "READ_TIMEOUT", "WRITE_TIMEOUT", "IDLE_TIMEOUT", "MAX_HEADER_BYTES"} {
|
|
for _, value := range []string{"invalid", "-1"} {
|
|
t.Run(key+value, func(t *testing.T) {
|
|
if value == "-1" && key != "MAX_HEADER_BYTES" {
|
|
value = "-1s"
|
|
}
|
|
t.Setenv("HTTP_INVALID_HTTP_"+key, value)
|
|
names := map[string]string{"READ_HEADER_TIMEOUT": "readHeaderTimeout", "READ_TIMEOUT": "readTimeout", "WRITE_TIMEOUT": "writeTimeout", "IDLE_TIMEOUT": "idleTimeout", "MAX_HEADER_BYTES": "maxHeaderBytes"}
|
|
path := filepath.Join(t.TempDir(), "config.json")
|
|
if err := os.WriteFile(path, []byte(`{"http":{"`+names[key]+`":"${HTTP_INVALID_HTTP_`+key+`}"}}`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := config.LoadFile(path); err == nil {
|
|
t.Fatal("invalid HTTP value accepted")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
for _, http := range []config.HTTPConfig{{ReadHeaderTimeout: time.Second}, {ReadTimeout: time.Second}, {WriteTimeout: time.Second}} {
|
|
cfg := config.Default()
|
|
cfg.Transport = config.TransportHTTP2
|
|
cfg.TLS = config.TLSConfig{CertFile: "c", KeyFile: "k"}
|
|
cfg.HTTP = http
|
|
if err := cfg.ValidateTransport(); err == nil || !strings.Contains(err.Error(), "not supported") {
|
|
t.Fatalf("HTTP/2: %v", err)
|
|
}
|
|
}
|
|
cfg := config.Default()
|
|
cfg.Transport = config.TransportHTTP2
|
|
cfg.TLS = config.TLSConfig{CertFile: "c", KeyFile: "k"}
|
|
cfg.HTTP = config.HTTPConfig{IdleTimeout: time.Minute, MaxHeaderBytes: 8192}
|
|
if err := cfg.ValidateTransport(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, transport := range []string{config.TransportNative, config.TransportHTTP2} {
|
|
cfg.Transport = transport
|
|
cfg.HTTP = config.HTTPConfig{ErrorLog: log.New(io.Discard, "", 0)}
|
|
if err := cfg.ValidateTransport(); err == nil || !strings.Contains(err.Error(), "http.errorLog") {
|
|
t.Fatalf("ErrorLog silently ignored: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHTTPBodyAndCancellationSettings(t *testing.T) {
|
|
for _, cfg := range []config.HTTPConfig{
|
|
{DefaultMaxBodyBytes: -1}, {MaxBodyBytes: -1}, {DefaultMaxBodyBytes: 1<<40 + 1}, {MaxBodyBytes: 1<<40 + 1},
|
|
{DefaultMaxBodyBytes: 1024, MaxBodyBytes: 512}, {ShutdownCancelTimeout: -time.Second},
|
|
} {
|
|
if err := cfg.Validate(); err == nil {
|
|
t.Fatalf("invalid HTTP config accepted: %+v", cfg)
|
|
}
|
|
}
|
|
for _, transport := range []string{config.TransportNetHTTP, config.TransportNative, config.TransportHTTP2} {
|
|
cfg := config.Default()
|
|
cfg.Transport = transport
|
|
cfg.TLS = config.TLSConfig{CertFile: "c", KeyFile: "k"}
|
|
cfg.HTTP = config.HTTPConfig{DefaultMaxBodyBytes: 1 << 20, MaxBodyBytes: 16 << 20, ShutdownCancelTimeout: time.Second}
|
|
if err := cfg.ValidateTransport(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
t.Setenv("OMNI_BODY_HARD", "16777216")
|
|
for _, file := range []struct{ name, body string }{
|
|
{"config.json", `{"http":{"defaultMaxBodyBytes":1048576,"maxBodyBytes":"${OMNI_BODY_HARD}","shutdownCancelTimeout":"250ms"}}`},
|
|
{"config.yaml", "http:\n defaultMaxBodyBytes: 1048576\n maxBodyBytes: ${OMNI_BODY_HARD}\n shutdownCancelTimeout: 250ms\n"},
|
|
} {
|
|
path := filepath.Join(t.TempDir(), file.name)
|
|
if err := os.WriteFile(path, []byte(file.body), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := config.LoadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cfg.HTTP.DefaultMaxBodyBytes != 1<<20 || cfg.HTTP.MaxBodyBytes != 16<<20 || cfg.HTTP.ShutdownCancelTimeout != 250*time.Millisecond {
|
|
t.Fatalf("loaded %+v", cfg.HTTP)
|
|
}
|
|
}
|
|
}
|