olivetin/service/internal/config/config_reloader_test.go

137 lines
3.7 KiB
Go

package config
import (
"os"
"testing"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/rawbytes"
"github.com/knadh/koanf/v2"
"github.com/stretchr/testify/assert"
)
var stringEnvConfigYaml = `
PageTitle: ${{ INPUT }}
`
var stringEnvInterpolationConfigYaml = `
PageTitle: Olivetin - ${{ INPUT }}
`
var boolEnvConfigYaml = `
CheckForUpdates: ${{ INPUT }}
`
var numericEnvConfigYaml = `
LogHistoryPageSize: ${{ INPUT }}
`
var argsSyntaxConfigYaml = `
actions:
- title: Ping host
id: ping_host
shell: ping {{ host }} -c ${{ INPUT }}
icon: ping
timeout: 100
popupOnStart: execution-dialog-stdout-only
arguments:
- name: host
title: Host
type: ascii_identifier
default: example.com
description: The host that you want to ping
`
func pageTitleSelector(cfg *Config) any {
return cfg.PageTitle
}
func checkForUpdatesSelector(cfg *Config) any {
return cfg.CheckForUpdates
}
func logHistoryPageSizeSelector(cfg *Config) any {
return cfg.LogHistoryPageSize
}
var envConfigTests = []struct {
yaml string
input string
output any
selector func(*Config) any
}{
// Test that it works for string type config fields, both standalone and as part of a larger string value.
{stringEnvConfigYaml, "A Nice Title", "A Nice Title", pageTitleSelector},
{stringEnvInterpolationConfigYaml, "A Nice Title", "Olivetin - A Nice Title", pageTitleSelector},
// Test that unset variables turn into empty strings.
{stringEnvConfigYaml, "", "", pageTitleSelector},
// Test that it works for bool type config fields for intuitive bool->string conversions.
{boolEnvConfigYaml, "FALSE", false, checkForUpdatesSelector},
{boolEnvConfigYaml, "false", false, checkForUpdatesSelector},
{boolEnvConfigYaml, "False", false, checkForUpdatesSelector},
{boolEnvConfigYaml, "TRUE", true, checkForUpdatesSelector},
{boolEnvConfigYaml, "true", true, checkForUpdatesSelector},
{boolEnvConfigYaml, "True", true, checkForUpdatesSelector},
{boolEnvConfigYaml, "0", false, checkForUpdatesSelector},
{boolEnvConfigYaml, "1", true, checkForUpdatesSelector},
// Test that unset variables turn into false bools.
{boolEnvConfigYaml, "", false, checkForUpdatesSelector},
// Test that it works for numeric type config fields.
{numericEnvConfigYaml, "2048", int64(2048), logHistoryPageSizeSelector},
// Test that unset variables turn into zero numbers.
{numericEnvConfigYaml, "", int64(0), logHistoryPageSizeSelector},
// Test that it doesn't interfere with similar arguments
{argsSyntaxConfigYaml, "5", "ping {{ host }} -c 5", func(cfg *Config) any {
if len(cfg.Actions) > 0 {
return cfg.Actions[0].Shell
}
return ""
}},
}
func setTestEnvInput(t *testing.T, input string) {
t.Helper()
if input != "" {
if err := os.Setenv("INPUT", input); err != nil {
t.Fatalf("Setenv INPUT: %v", err)
}
return
}
if err := os.Unsetenv("INPUT"); err != nil {
t.Fatalf("Unsetenv INPUT: %v", err)
}
}
func loadConfigFromYAML(t *testing.T, yamlStr string, cfg *Config) bool {
t.Helper()
k := koanf.New(".")
if err := k.Load(rawbytes.Provider([]byte(yamlStr)), yaml.Parser()); err != nil {
t.Errorf("Error loading YAML: %v", err)
return false
}
return unmarshalRoot(k, cfg)
}
func TestEnvInConfig(t *testing.T) {
originalInput, hadInput := os.LookupEnv("INPUT")
t.Cleanup(func() {
if hadInput {
setTestEnvInput(t, originalInput)
return
}
setTestEnvInput(t, "")
})
for _, tt := range envConfigTests {
cfg := DefaultConfig()
setTestEnvInput(t, tt.input)
if !loadConfigFromYAML(t, tt.yaml, cfg) {
t.Errorf("Error unmarshalling config for env=%q", tt.input)
continue
}
field := tt.selector(cfg)
assert.Equal(t, tt.output, field,
"Unmarshaled config field doesn't match expected value: env=%q", tt.input)
}
}