gitlab-org--gitlab-foss/workhorse/config_test.go

285 lines
8.3 KiB
Go

package main
import (
"flag"
"io"
"net/url"
"os"
"testing"
"time"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/queueing"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/upstream"
)
func TestDefaultConfig(t *testing.T) {
_, cfg, err := buildConfig("test", []string{"-config", "/dev/null"})
require.NoError(t, err, "build config")
require.Equal(t, 0*time.Second, cfg.ShutdownTimeout.Duration)
}
func TestConfigFile(t *testing.T) {
f, err := os.CreateTemp("", "workhorse-config-test")
require.NoError(t, err)
defer os.Remove(f.Name())
data := `
shutdown_timeout = "60s"
trusted_cidrs_for_x_forwarded_for = ["127.0.0.1/8", "192.168.0.1/8"]
trusted_cidrs_for_propagation = ["10.0.0.1/8"]
[redis]
password = "redis password"
[object_storage]
provider = "test provider"
[image_resizer]
max_scaler_procs = 123
[[listeners]]
network = "tcp"
addr = "localhost:3443"
[listeners.tls]
certificate = "/path/to/certificate"
key = "/path/to/private/key"
min_version = "tls1.1"
max_version = "tls1.2"
[[listeners]]
network = "tcp"
addr = "localhost:3444"
[metrics_listener]
network = "tcp"
addr = "localhost:3445"
[metrics_listener.tls]
certificate = "/path/to/certificate"
key = "/path/to/private/key"
`
_, err = io.WriteString(f, data)
require.NoError(t, err)
require.NoError(t, f.Close())
_, cfg, err := buildConfig("test", []string{"-config", f.Name()})
require.NoError(t, err, "build config")
// These are integration tests: we want to see that each section in the
// config file ends up in the config struct. We do not test all the
// fields in each section; that should happen in the tests of the
// internal/config package.
require.Equal(t, "redis password", cfg.Redis.Password)
require.Equal(t, "test provider", cfg.ObjectStorageCredentials.Provider)
require.Equal(t, uint32(123), cfg.ImageResizerConfig.MaxScalerProcs, "image resizer max_scaler_procs")
require.Equal(t, []string{"127.0.0.1/8", "192.168.0.1/8"}, cfg.TrustedCIDRsForXForwardedFor)
require.Equal(t, []string{"10.0.0.1/8"}, cfg.TrustedCIDRsForPropagation)
require.Equal(t, 60*time.Second, cfg.ShutdownTimeout.Duration)
listenerConfigs := []config.ListenerConfig{
{
Network: "tcp",
Addr: "localhost:3445",
Tls: &config.TlsConfig{
Certificate: "/path/to/certificate",
Key: "/path/to/private/key",
},
},
{
Network: "tcp",
Addr: "localhost:3443",
Tls: &config.TlsConfig{
Certificate: "/path/to/certificate",
Key: "/path/to/private/key",
MinVersion: "tls1.1",
MaxVersion: "tls1.2",
},
},
{
Network: "tcp",
Addr: "localhost:3444",
},
}
require.Len(t, cfg.Listeners, 2)
require.NotNil(t, cfg.MetricsListener)
for i, cfg := range []config.ListenerConfig{*cfg.MetricsListener, cfg.Listeners[0], cfg.Listeners[1]} {
require.Equal(t, listenerConfigs[i].Network, cfg.Network)
require.Equal(t, listenerConfigs[i].Addr, cfg.Addr)
}
for i, cfg := range []config.ListenerConfig{*cfg.MetricsListener, cfg.Listeners[0]} {
require.Equal(t, listenerConfigs[i].Tls.Certificate, cfg.Tls.Certificate)
require.Equal(t, listenerConfigs[i].Tls.Key, cfg.Tls.Key)
require.Equal(t, listenerConfigs[i].Tls.MinVersion, cfg.Tls.MinVersion)
require.Equal(t, listenerConfigs[i].Tls.MaxVersion, cfg.Tls.MaxVersion)
}
require.Nil(t, cfg.Listeners[1].Tls)
}
func TestTwoMetricsAddrsAreSpecifiedError(t *testing.T) {
f, err := os.CreateTemp("", "workhorse-config-test")
require.NoError(t, err)
defer os.Remove(f.Name())
data := `
[metrics_listener]
network = "tcp"
addr = "localhost:3445"
`
_, err = io.WriteString(f, data)
require.NoError(t, err)
require.NoError(t, f.Close())
args := []string{
"-config", f.Name(),
"-prometheusListenAddr", "prometheus listen addr",
}
_, _, err = buildConfig("test", args)
require.EqualError(t, err, "configFile: both prometheusListenAddr and metrics_listener can't be specified")
}
func TestConfigErrorHelp(t *testing.T) {
for _, f := range []string{"-h", "-help"} {
t.Run(f, func(t *testing.T) {
_, _, err := buildConfig("test", []string{f})
require.Equal(t, alreadyPrintedError{flag.ErrHelp}, err)
})
}
}
func TestConfigError(t *testing.T) {
for _, arg := range []string{"-foobar", "foobar"} {
t.Run(arg, func(t *testing.T) {
_, _, err := buildConfig("test", []string{arg})
require.Error(t, err)
require.IsType(t, alreadyPrintedError{}, err)
})
}
}
func TestConfigDefaults(t *testing.T) {
boot, cfg, err := buildConfig("test", nil)
require.NoError(t, err, "build config")
expectedBoot := &bootConfig{
secretPath: "./.gitlab_workhorse_secret",
listenAddr: "localhost:8181",
listenNetwork: "tcp",
logFormat: "text",
}
require.Equal(t, expectedBoot, boot)
expectedCfg := &config.Config{
Backend: upstream.DefaultBackend,
CableBackend: upstream.DefaultBackend,
Version: "(unknown version)",
DocumentRoot: "public",
ProxyHeadersTimeout: 5 * time.Minute,
APIQueueTimeout: queueing.DefaultTimeout,
APICILongPollingDuration: 50 * time.Nanosecond, // TODO this is meant to be 50*time.Second but it has been wrong for ages
ImageResizerConfig: config.DefaultImageResizerConfig,
}
require.Equal(t, expectedCfg, cfg)
}
func TestCableConfigDefault(t *testing.T) {
backendURL, err := url.Parse("http://localhost:1234")
require.NoError(t, err)
args := []string{
"-authBackend", backendURL.String(),
}
boot, cfg, err := buildConfig("test", args)
require.NoError(t, err, "build config")
expectedBoot := &bootConfig{
secretPath: "./.gitlab_workhorse_secret",
listenAddr: "localhost:8181",
listenNetwork: "tcp",
logFormat: "text",
}
require.Equal(t, expectedBoot, boot)
expectedCfg := &config.Config{
Backend: backendURL,
CableBackend: backendURL,
Version: "(unknown version)",
DocumentRoot: "public",
ProxyHeadersTimeout: 5 * time.Minute,
APIQueueTimeout: queueing.DefaultTimeout,
APICILongPollingDuration: 50 * time.Nanosecond,
ImageResizerConfig: config.DefaultImageResizerConfig,
}
require.Equal(t, expectedCfg, cfg)
}
func TestConfigFlagParsing(t *testing.T) {
backendURL, err := url.Parse("http://localhost:1234")
require.NoError(t, err)
cableURL, err := url.Parse("http://localhost:5678")
require.NoError(t, err)
args := []string{
"-version",
"-secretPath", "secret path",
"-listenAddr", "listen addr",
"-listenNetwork", "listen network",
"-listenUmask", "123",
"-pprofListenAddr", "pprof listen addr",
"-prometheusListenAddr", "prometheus listen addr",
"-logFile", "log file",
"-logFormat", "log format",
"-documentRoot", "document root",
"-developmentMode",
"-authBackend", backendURL.String(),
"-authSocket", "auth socket",
"-cableBackend", cableURL.String(),
"-cableSocket", "cable socket",
"-proxyHeadersTimeout", "10m",
"-apiLimit", "234",
"-apiQueueLimit", "345",
"-apiQueueDuration", "123s",
"-apiCiLongPollingDuration", "234s",
"-propagateCorrelationID",
}
boot, cfg, err := buildConfig("test", args)
require.NoError(t, err, "build config")
expectedBoot := &bootConfig{
secretPath: "secret path",
listenAddr: "listen addr",
listenNetwork: "listen network",
listenUmask: 123,
pprofListenAddr: "pprof listen addr",
prometheusListenAddr: "prometheus listen addr",
logFile: "log file",
logFormat: "log format",
printVersion: true,
}
require.Equal(t, expectedBoot, boot)
expectedCfg := &config.Config{
DocumentRoot: "document root",
DevelopmentMode: true,
Backend: backendURL,
Socket: "auth socket",
CableBackend: cableURL,
CableSocket: "cable socket",
Version: "(unknown version)",
ProxyHeadersTimeout: 10 * time.Minute,
APILimit: 234,
APIQueueLimit: 345,
APIQueueTimeout: 123 * time.Second,
APICILongPollingDuration: 234 * time.Second,
PropagateCorrelationID: true,
ImageResizerConfig: config.DefaultImageResizerConfig,
MetricsListener: &config.ListenerConfig{Network: "tcp", Addr: "prometheus listen addr"},
}
require.Equal(t, expectedCfg, cfg)
}