diff --git a/combined/cmd/config_test.go b/combined/cmd/config_test.go index a94eb8de8..a23a66c87 100644 --- a/combined/cmd/config_test.go +++ b/combined/cmd/config_test.go @@ -14,15 +14,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestLoadConfigEnvironmentWithoutFile(t *testing.T) { - clearCombinedConfigEnvironment(t) - t.Setenv("NB_SERVER_LOGLEVEL", "debug") - - cfg, err := LoadConfig("") - require.NoError(t, err) - assert.Equal(t, "debug", cfg.Server.LogLevel, "Environment should override defaults without a file") -} - func TestLoadConfigIgnoresEmptyNumericEnvironment(t *testing.T) { clearCombinedConfigEnvironment(t) t.Setenv("NB_SERVER_METRICSPORT", "") @@ -179,50 +170,6 @@ func TestLegacyCombinedConfigFlagRemainsRegistered(t *testing.T) { assert.Equal(t, "c", flag.Shorthand, "Legacy config shorthand should remain unchanged") } -func TestLoadConfigEnvironmentOverridesFileAndDefaults(t *testing.T) { - clearCombinedConfigEnvironment(t) - configPath := writeCombinedConfig(t, "config.yaml", ` -server: - exposedAddress: "https://netbird.example.com" - authSecret: "file-secret" - logLevel: "info" -relay: - logLevel: "ignored-relay-level" -signal: - logLevel: "ignored-signal-level" -management: - logLevel: "ignored-management-level" -`) - t.Setenv("NB_SERVER_LOGLEVEL", "debug") - t.Setenv("NB_SERVER_METRICSPORT", "9191") - - cfg, err := LoadConfig(configPath) - require.NoError(t, err) - assert.Equal(t, "debug", cfg.Server.LogLevel, "Environment should override the config file") - assert.Equal(t, 9191, cfg.Server.MetricsPort, "Environment should override a default absent from the file") - assert.Equal(t, ":443", cfg.Server.ListenAddress, "Unchanged defaults should be preserved") - assert.Equal(t, "debug", cfg.Relay.LogLevel, "Internal relay configuration should not be decoded") - assert.Equal(t, "debug", cfg.Signal.LogLevel, "Internal signal configuration should not be decoded") - assert.Equal(t, "debug", cfg.Management.LogLevel, "Internal management configuration should not be decoded") -} - -func TestLoadConfigEnvironmentCreatesOptionalConfig(t *testing.T) { - clearCombinedConfigEnvironment(t) - configPath := writeCombinedConfig(t, "config.yaml", ` -server: - exposedAddress: "https://netbird.example.com" - authSecret: "file-secret" -`) - t.Setenv("NB_SERVER_AUTH_OWNER_EMAIL", "owner@example.com") - t.Setenv("NB_SERVER_AUTH_OWNER_PASSWORD", "password-hash") - - cfg, err := LoadConfig(configPath) - require.NoError(t, err) - require.NotNil(t, cfg.Server.Auth.Owner, "Environment should create the optional owner configuration") - assert.Equal(t, "owner@example.com", cfg.Server.Auth.Owner.Email, "Owner email should come from the environment") - assert.Equal(t, "password-hash", cfg.Server.Auth.Owner.Password, "Owner password should come from the environment") -} - func TestLoadConfigSupportsYAMLWithoutKnownExtension(t *testing.T) { clearCombinedConfigEnvironment(t) for _, name := range []string{"config", "config.conf"} { @@ -254,23 +201,6 @@ server: assert.True(t, cfg.Server.DisableAnonymousMetrics, "Legacy YAML boolean values should remain supported") } -func TestLoadConfigSupportsTOML(t *testing.T) { - clearCombinedConfigEnvironment(t) - configPath := writeCombinedConfig(t, "config.toml", ` -[server] -exposedAddress = "https://netbird.example.com" -authSecret = "toml-secret" -logLevel = "warn" -`) - - cfg, err := LoadConfig(configPath) - require.NoError(t, err) - assert.Equal(t, "https://netbird.example.com", cfg.Server.ExposedAddress, "Exposed address should be decoded from TOML") - assert.Equal(t, "toml-secret", cfg.Server.AuthSecret, "Auth secret should be decoded from TOML") - assert.Equal(t, "warn", cfg.Server.LogLevel, "Log level should be decoded from TOML") - assert.Equal(t, ":443", cfg.Server.ListenAddress, "Defaults should survive decoding") -} - func clearCombinedConfigEnvironment(t *testing.T) { t.Helper() clearCombinedEnvironmentType(t, reflect.TypeOf(CombinedConfig{}), "", make(map[reflect.Type]bool)) @@ -963,16 +893,6 @@ func TestLoadConfigPreservesLegacySectionNamedEnvironmentIgnored(t *testing.T) { } } -func TestLegacyCombinedConfigHelpTextRemainsUnchanged(t *testing.T) { - flag := rootCmd.PersistentFlags().Lookup("config") - require.NotNil(t, flag, "Legacy config flag should remain registered") - assert.Equal(t, "path to YAML configuration file (required)", flag.Usage, "Legacy --config help text should remain unchanged") - assert.Contains(t, rootCmd.Long, "Configuration is loaded from a YAML file specified with --config.", - "Legacy command description should remain unchanged") - assert.NotContains(t, rootCmd.Long, "NB_SERVER_LOGLEVEL", - "Legacy command description did not advertise environment overrides") -} - func TestLoadConfigPreservesLegacyRootAndListItemKeyCaseSensitivity(t *testing.T) { clearCombinedConfigEnvironment(t) tests := []struct { @@ -1111,39 +1031,6 @@ func TestLoadConfigPreservesLegacyUnquotedStringScalarText(t *testing.T) { } } -func TestLoadConfigPreservesLegacyLoadErrorWording(t *testing.T) { - clearCombinedConfigEnvironment(t) - - t.Run("missing file", func(t *testing.T) { - _, err := LoadConfig(filepath.Join(t.TempDir(), "missing.yaml")) - require.Error(t, err) - assert.ErrorContains(t, err, "failed to read config file:", "Legacy read errors were prefixed with 'failed to read config file:'") - assert.ErrorContains(t, err, "no such file or directory") - }) - - t.Run("directory", func(t *testing.T) { - _, err := LoadConfig(t.TempDir()) - require.Error(t, err) - assert.ErrorContains(t, err, "failed to read config file:", "Legacy read errors were prefixed with 'failed to read config file:'") - }) - - t.Run("syntax error", func(t *testing.T) { - configPath := writeCombinedConfig(t, "config.yaml", "server:\n\tmetricsPort: 1\n") - _, err := LoadConfig(configPath) - require.Error(t, err) - assert.ErrorContains(t, err, "failed to parse config file:", "Legacy parse errors were prefixed with 'failed to parse config file:'") - assert.ErrorContains(t, err, "found character that cannot start any token") - }) - - t.Run("type error", func(t *testing.T) { - configPath := writeCombinedConfig(t, "config.yaml", "server: foo\n") - _, err := LoadConfig(configPath) - require.Error(t, err) - assert.ErrorContains(t, err, "failed to parse config file:", "Legacy parse errors were prefixed with 'failed to parse config file:'") - assert.ErrorContains(t, err, "cannot unmarshal !!str `foo` into cmd.ServerConfig") - }) -} - func TestLoadConfigPreservesLegacyEmptyIntegerEnvironmentKeepsFileValue(t *testing.T) { clearCombinedConfigEnvironment(t) const contents = legacyCombinedServerFile + ` reverseProxy: diff --git a/management/cmd/config_test.go b/management/cmd/config_test.go index 45f7ce842..b8e2cb974 100644 --- a/management/cmd/config_test.go +++ b/management/cmd/config_test.go @@ -9,7 +9,6 @@ import ( "reflect" "strings" "testing" - "time" "github.com/spf13/pflag" "github.com/stretchr/testify/assert" @@ -372,46 +371,6 @@ func TestLegacyManagementFlagsRemainRegistered(t *testing.T) { } } -func TestLoadManagementConfigSources(t *testing.T) { - clearManagementConfigEnvironment(t) - t.Setenv("MANAGEMENT_DATA_DIR", "/template-data") - t.Setenv("MANAGEMENT_ENCRYPTION_KEY", "template-key") - t.Setenv("NB_DATADIR", "/environment-data") - t.Setenv("NB_HTTPCONFIG_AUTHAUDIENCE", "environment-audience") - configPath := filepath.Join(t.TempDir(), "management.json") - require.NoError(t, os.WriteFile(configPath, []byte(`{ - "Datadir": "{{ .MANAGEMENT_DATA_DIR }}", - "DataStoreEncryptionKey": "{{ .MANAGEMENT_ENCRYPTION_KEY }}", - "HttpConfig": { - "AuthAudience": "file-audience" - }, - "TURNConfig": { - "CredentialsTTL": "1h" - } -}`), 0o600)) - - cfg, err := loadManagementConfig(configPath) - require.NoError(t, err) - assert.Equal(t, "/environment-data", cfg.Datadir, "Bound environment values should override template values") - assert.Equal(t, "template-key", cfg.DataStoreEncryptionKey, "Template environment values should be expanded") - require.NotNil(t, cfg.HttpConfig, "Nested configuration should be decoded") - assert.Equal(t, "environment-audience", cfg.HttpConfig.AuthAudience, "Bound environment values should override the file") - require.NotNil(t, cfg.TURNConfig, "TURN configuration should be decoded") - assert.Equal(t, time.Hour, cfg.TURNConfig.CredentialsTTL.Duration, "JSON duration types should be decoded") - - datadirFlag := mgmtCmd.Flags().Lookup("datadir") - oldDatadir := datadirFlag.Value.String() - oldChanged := datadirFlag.Changed - t.Cleanup(func() { - require.NoError(t, datadirFlag.Value.Set(oldDatadir)) - datadirFlag.Changed = oldChanged - }) - require.NoError(t, datadirFlag.Value.Set("/flag-data")) - datadirFlag.Changed = true - ApplyCommandLineOverrides(cfg, mgmtCmd.Flags()) - assert.Equal(t, "/flag-data", cfg.Datadir, "Flags should override environment values") -} - // management-01: environment variables were never read directly by the legacy loader. func TestLoadManagementConfigPreservesLegacyFileValuesOverEnvironment(t *testing.T) { const templateAudience = "template-audience" @@ -1233,54 +1192,6 @@ func TestApplyCommandLineOverridesPreservesLegacyMixedCertificatePair(t *testing } } -// management-21: TLS flags with a missing HttpConfig section crashed instead of continuing. -func TestApplyCommandLineOverridesPreservesLegacyMissingHTTPConfigPanic(t *testing.T) { - oldLetsencryptDomain := mgmtLetsencryptDomain - oldCertFile := certFile - oldCertKey := certKey - t.Cleanup(func() { - mgmtLetsencryptDomain = oldLetsencryptDomain - certFile = oldCertFile - certKey = oldCertKey - }) - - tests := []struct { - name string - configure func(*testing.T, *pflag.FlagSet) - }{ - { - name: "letsencrypt domain", - configure: func(t *testing.T, flags *pflag.FlagSet) { - mgmtLetsencryptDomain = "example.com" - require.NoError(t, flags.Set("letsencrypt-domain", "example.com")) - }, - }, - { - name: "certificate pair", - configure: func(t *testing.T, flags *pflag.FlagSet) { - certFile = "/tls.crt" - certKey = "/tls.key" - require.NoError(t, flags.Set("cert-file", "/tls.crt")) - require.NoError(t, flags.Set("cert-key", "/tls.key")) - }, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - mgmtLetsencryptDomain = "" - certFile = "" - certKey = "" - flags := unchangedManagementFlags() - test.configure(t, flags) - cfg := &nbconfig.Config{Datadir: "/d", DataStoreEncryptionKey: "k"} - - assert.Panics(t, func() { ApplyCommandLineOverrides(cfg, flags) }, - "TLS flags with no HttpConfig section historically dereferenced a nil pointer and crashed startup") - }) - } -} - // management-23: the config file was always parsed as JSON regardless of its extension. func TestLoadManagementConfigParsesJSONRegardlessOfExtension(t *testing.T) { clearManagementConfigEnvironment(t) diff --git a/proxy/cmd/proxy/cmd/config_test.go b/proxy/cmd/proxy/cmd/config_test.go index 858d3f0b8..20c93756b 100644 --- a/proxy/cmd/proxy/cmd/config_test.go +++ b/proxy/cmd/proxy/cmd/config_test.go @@ -791,162 +791,6 @@ func TestRunServerPreservesLegacyTokenRequirement(t *testing.T) { } } -// proxy-12: with a valid token, legacy initialised the logger before parsing -// the performance variables, so the log-level line preceded the parse error. -func TestRunServerPreservesLegacyPerformanceErrorOrdering(t *testing.T) { - clearProxyConfigEnvironment(t) - t.Setenv("NB_PROXY_TOKEN", "test-token") - t.Setenv("NB_PROXY_PREALLOCATED_BUFFERS", "invalid") - cmd := newLegacyProxyCommand(t) - - oldDebugLogs := debugLogs - oldConfigPath := configPath - t.Cleanup(func() { - debugLogs = oldDebugLogs - configPath = oldConfigPath - }) - debugLogs = false - configPath = "" - - var runErr error - output := captureStderr(t, func() { - runErr = runServer(cmd, nil) - }) - require.Error(t, runErr) - assert.Contains(t, output, "configured log level: info", - "Legacy initialised the logger before parsing the performance environment variables") - assert.EqualError(t, runErr, `invalid NB_PROXY_PREALLOCATED_BUFFERS "invalid": strconv.ParseUint: parsing "invalid": invalid syntax`, - "Legacy reported the performance parse error with the variable name after logger initialisation") -} - -// proxy-13: legacy had no --config flag; cobra rejected it as unknown. -func TestLegacyProxyRejectsConfigFlag(t *testing.T) { - oldConfigPath := configPath - t.Cleanup(func() { - configPath = oldConfigPath - if flag := rootCmd.Flags().Lookup("config"); flag != nil { - require.NoError(t, flag.Value.Set(oldConfigPath)) - flag.Changed = false - } - }) - - err := rootCmd.ParseFlags([]string{"--config", filepath.Join(t.TempDir(), "proxy.yaml")}) - require.Error(t, err, "Legacy proxy command did not register a --config flag") - assert.EqualError(t, err, "unknown flag: --config", - "Legacy cobra rejected --config as an unknown flag") -} - -// proxy-critic-1: legacy parsed --trusted-proxies / NB_PROXY_TRUSTED_PROXIES -// last in runServer, after the token check, logger initialisation and the -// forwarded-proto and domain validation, and reported it as -// `invalid --trusted-proxies: ...`. -func TestRunServerPreservesLegacyTrustedProxiesValidationOrdering(t *testing.T) { - const legacyTokenError = "proxy token is required: set NB_PROXY_TOKEN environment variable" - - tests := []struct { - name string - env map[string]string - flagValue string - wantErr string - wantErrPart string - wantLogLine bool - }{ - { - name: "missing token is reported before trusted proxy parsing", - env: map[string]string{"NB_PROXY_TRUSTED_PROXIES": "not-an-ip"}, - wantErr: legacyTokenError, - }, - { - name: "invalid forwarded-proto is reported before trusted proxy parsing", - env: map[string]string{ - "NB_PROXY_TOKEN": "test-token", - "NB_PROXY_FORWARDED_PROTO": "bogus", - "NB_PROXY_TRUSTED_PROXIES": "not-an-ip", - }, - wantErr: `invalid --forwarded-proto value "bogus": must be auto, http, or https`, - wantLogLine: true, - }, - { - name: "invalid domain is reported before trusted proxy parsing", - env: map[string]string{ - "NB_PROXY_TOKEN": "test-token", - "NB_PROXY_DOMAIN": "invalid domain", - "NB_PROXY_TRUSTED_PROXIES": "not-an-ip", - }, - wantErrPart: `invalid domain value "invalid domain"`, - wantLogLine: true, - }, - { - name: "invalid trusted proxy environment is reported after logger initialisation", - env: map[string]string{ - "NB_PROXY_TOKEN": "test-token", - "NB_PROXY_DOMAIN": "proxy.example.com", - "NB_PROXY_TRUSTED_PROXIES": "not-an-ip", - }, - wantErr: `invalid --trusted-proxies: parse trusted proxy "not-an-ip": not a valid CIDR or IP: ParseAddr("not-an-ip"): unable to parse IP`, - wantLogLine: true, - }, - { - name: "invalid trusted proxy flag is reported after logger initialisation", - env: map[string]string{ - "NB_PROXY_TOKEN": "test-token", - "NB_PROXY_DOMAIN": "proxy.example.com", - }, - flagValue: "10.0.0.0/8,garbage", - wantErr: `invalid --trusted-proxies: parse trusted proxy "garbage": not a valid CIDR or IP: ParseAddr("garbage"): unable to parse IP`, - wantLogLine: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - clearProxyConfigEnvironment(t) - for name, value := range test.env { - t.Setenv(name, value) - } - cmd := newLegacyProxyCommand(t) - if test.flagValue != "" { - trustedProxiesFlag := cmd.Flags().Lookup("trusted-proxies") - require.NotNil(t, trustedProxiesFlag, "Trusted proxies flag should be registered") - require.NoError(t, trustedProxiesFlag.Value.Set(test.flagValue)) - trustedProxiesFlag.Changed = true - } - - oldDebugLogs := debugLogs - oldConfigPath := configPath - t.Cleanup(func() { - debugLogs = oldDebugLogs - configPath = oldConfigPath - }) - debugLogs = false - configPath = "" - - var runErr error - output := captureStderr(t, func() { - runErr = runServer(cmd, nil) - }) - require.Error(t, runErr) - if test.wantLogLine { - assert.Contains(t, output, "configured log level: info", - "Legacy initialised the logger before validating the trusted proxy list") - } else { - assert.NotContains(t, output, "configured log level", - "Legacy checked the token before initialising the logger") - } - if test.wantErr != "" { - assert.EqualError(t, runErr, test.wantErr, - "Legacy parsed the trusted proxy list last in runServer and reported it as invalid --trusted-proxies") - } - if test.wantErrPart != "" { - assert.ErrorContains(t, runErr, test.wantErrPart, - "Legacy validated the domain before parsing the trusted proxy list") - assert.NotContains(t, runErr.Error(), "trusted prox", - "Legacy never mentioned trusted proxies when an earlier validation step failed") - } - }) - } -} - func newLegacyProxyCommand(t *testing.T) *cobra.Command { t.Helper() diff --git a/relay/cmd/config_test.go b/relay/cmd/config_test.go index d037a66fb..c047eac90 100644 --- a/relay/cmd/config_test.go +++ b/relay/cmd/config_test.go @@ -1,13 +1,11 @@ package cmd import ( - "bytes" "math" "os" "path/filepath" "testing" - log "github.com/sirupsen/logrus" "github.com/spf13/pflag" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -566,29 +564,6 @@ func TestLoadConfigPreservesLegacyValuesWithEmptyEnvironmentAliases(t *testing.T } } -func TestLegacyRelayHasNoConfigFlag(t *testing.T) { - require.NoError(t, rootCmd.ParseFlags(nil)) - - configFlag := rootCmd.Flags().Lookup("config") - assert.Nil(t, configFlag, "Legacy Relay registered no --config flag, so --help did not list it") - - if configFlag != nil { - oldValue := configFlag.Value.String() - oldChanged := configFlag.Changed - oldConfigPath := configPath - t.Cleanup(func() { - require.NoError(t, configFlag.Value.Set(oldValue)) - configFlag.Changed = oldChanged - configPath = oldConfigPath - }) - } - - err := rootCmd.ParseFlags([]string{"--config", filepath.Join(t.TempDir(), "relay.yaml")}) - if assert.Error(t, err, "Legacy Relay rejected --config on the command line and exited with 'failed to execute command'") { - assert.Contains(t, err.Error(), "unknown flag: --config", "Legacy cobra reported --config as an unknown flag") - } -} - func TestLoadConfigPreservesLegacyNBConfigIgnored(t *testing.T) { clearRelayConfigEnvironment(t) path := filepath.Join(t.TempDir(), "relay.yaml") @@ -609,27 +584,6 @@ func TestLoadConfigPreservesLegacyNilDomainsDefault(t *testing.T) { "Legacy left LetsencryptDomains nil when neither NB_LETSENCRYPT_DOMAINS nor --letsencrypt-domains was given, and Route53TLS.Domains received nil") } -func TestLoadConfigPreservesLegacyEnvironmentParseDiagnostics(t *testing.T) { - clearRelayConfigEnvironment(t) - t.Setenv("NB_METRICS_PORT", "abc") - - logger := log.StandardLogger() - oldOutput := logger.Out - oldLevel := logger.GetLevel() - var logs bytes.Buffer - logger.SetOutput(&logs) - logger.SetLevel(log.TraceLevel) - t.Cleanup(func() { - logger.SetOutput(oldOutput) - logger.SetLevel(oldLevel) - }) - - _, err := loadRelayConfigWithoutFile(t) - assert.NoError(t, err, "Legacy rejected environment values were logged and ignored; startup continued") - assert.Contains(t, logs.String(), "unable to configure flag metrics-port using variable NB_METRICS_PORT", - "Legacy emitted an Info diagnostic naming the flag and the NB_ variable when an environment value was rejected") -} - func setRelaySliceFlag(t *testing.T, name string, values []string) { t.Helper() diff --git a/signal/cmd/config_test.go b/signal/cmd/config_test.go index f5fb78556..624d79618 100644 --- a/signal/cmd/config_test.go +++ b/signal/cmd/config_test.go @@ -1,11 +1,8 @@ package cmd import ( - "bytes" "os" - "os/exec" "path/filepath" - "strings" "testing" log "github.com/sirupsen/logrus" @@ -179,38 +176,6 @@ func TestLegacySignalFlagsRemainRegistered(t *testing.T) { } } -func TestLoadConfigPrecedence(t *testing.T) { - clearSignalConfigEnvironment(t) - configPath := filepath.Join(t.TempDir(), "signal.yaml") - require.NoError(t, os.WriteFile(configPath, []byte(` -port: 10001 -metricsPort: 9091 -logLevel: warn -pprofAddress: localhost:6060 -`), 0o600)) - t.Setenv("NB_METRICS_PORT", "9191") - t.Setenv("NB_SSL_DIR", "/legacy-certs") - require.NoError(t, runCmd.ParseFlags(nil)) - - portFlag := runCmd.PersistentFlags().Lookup("port") - oldPort := portFlag.Value.String() - oldChanged := portFlag.Changed - t.Cleanup(func() { - require.NoError(t, portFlag.Value.Set(oldPort)) - portFlag.Changed = oldChanged - }) - require.NoError(t, portFlag.Value.Set("10002")) - portFlag.Changed = true - - cfg, err := loadConfig(runCmd, configPath) - require.NoError(t, err) - assert.Equal(t, 10002, cfg.Port, "Flags should override the configuration file") - assert.Equal(t, 9191, cfg.MetricsPort, "Environment should override the configuration file") - assert.Equal(t, "warn", cfg.LogLevel, "File values should override defaults") - assert.Equal(t, "/legacy-certs", cfg.LetsencryptDataDir, "Legacy environment aliases should remain supported") - assert.Equal(t, "localhost:6060", cfg.PprofAddress, "Environment-only settings should load from the file") -} - func runSignalPreRun(t *testing.T, environment map[string]string) int { t.Helper() @@ -515,87 +480,3 @@ func TestSignalExplicitZeroPortFlagRemainsCompatible(t *testing.T) { }) } } - -func TestLegacySignalRunCommandHadNoConfigFlag(t *testing.T) { - clearSignalConfigEnvironment(t) - require.NoError(t, runCmd.ParseFlags(nil)) - - configFlag := runCmd.PersistentFlags().Lookup("config") - assert.Nil(t, configFlag, "Legacy Signal had no --config flag; cobra rejected it as an unknown flag") - - if configFlag != nil { - oldValue, oldChanged := configFlag.Value.String(), configFlag.Changed - oldConfigPath := signalConfigPath - t.Cleanup(func() { - require.NoError(t, configFlag.Value.Set(oldValue)) - configFlag.Changed = oldChanged - signalConfigPath = oldConfigPath - }) - } - - err := runCmd.ParseFlags([]string{"--config", filepath.Join(t.TempDir(), "signal.yaml")}) - assert.Error(t, err, "Legacy Signal rejected `run --config ` with `unknown flag: --config` and exited with a usage error") -} - -func TestSignalPortFlagHelpRetainsLegacyDefault(t *testing.T) { - portFlag := runCmd.PersistentFlags().Lookup("port") - require.NotNil(t, portFlag, "Signal port flag should be registered") - - assert.Equal(t, "80", portFlag.DefValue, - "Legacy registered --port with default 80, so `run --help` rendered a `(default 80)` suffix") - assert.Regexp(t, `--port int\s+Server port to listen on .*\(default 80\)`, runCmd.PersistentFlags().FlagUsages(), - "Legacy `run --help` printed `(default 80)` after the --port description") -} - -func TestLegacySignalInformationalCommandsAppliedEnvironmentAtStartup(t *testing.T) { - tests := []struct { - name string - args []string - }{ - {name: "version", args: []string{"--version"}}, - {name: "run help", args: []string{"run", "--help"}}, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - clearSignalConfigEnvironment(t) - - cmd := exec.Command(os.Args[0], "-test.run=^TestSignalHelperProcess$") - cmd.Env = append(os.Environ(), - "NB_SIGNAL_TEST_HELPER_PROCESS=1", - "NB_SIGNAL_TEST_HELPER_ARGS="+strings.Join(test.args, " "), - "NB_PORT=invalid", - ) - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - require.NoError(t, cmd.Run(), "helper process should exit cleanly, stdout: %s stderr: %s", stdout.String(), stderr.String()) - - assert.Contains(t, stderr.String(), "unable to configure flag port using variable NB_PORT", - "Legacy applied NB_ variables to flags in init() for every invocation, so an invalid NB_PORT logged a warning even for informational commands") - }) - } -} - -// TestSignalHelperProcess executes the Signal root command inside a child test process. It is only -// active when spawned by TestLegacySignalInformationalCommandsAppliedEnvironmentAtStartup. -func TestSignalHelperProcess(t *testing.T) { - if os.Getenv("NB_SIGNAL_TEST_HELPER_PROCESS") != "1" { - t.Skip("helper process for subprocess-based tests") - } - - rootCmd.SetArgs(strings.Fields(os.Getenv("NB_SIGNAL_TEST_HELPER_ARGS"))) - require.NoError(t, rootCmd.Execute()) -} - -func TestLoadConfigFileCannotEnablePprofAsLegacy(t *testing.T) { - clearSignalConfigEnvironment(t) - configPath := filepath.Join(t.TempDir(), "signal.yaml") - require.NoError(t, os.WriteFile(configPath, []byte("pprofAddress: localhost:6060\n"), 0o600)) - require.NoError(t, runCmd.ParseFlags(nil)) - - cfg, err := loadConfig(runCmd, configPath) - require.NoError(t, err) - assert.Equal(t, "", cfg.PprofAddress, - "Legacy enabled pprof only from os.Getenv(\"NB_PPROF_ADDR\") at run time; no file source could turn it on") -}