Fix a bug introduced in 6952516 which led to the app being unable to start if logging was enabled but no explicit path was set. In this case, the expected behaviour is to fallback to a log file in the XDG file hierarchy, but this was lost due to broken config file defaults handling. This commit separates the behaviour when setting defaults when reading an existing configuration, from those set when creating a brand new configuration.
194 lines
5.6 KiB
Go
194 lines
5.6 KiB
Go
package config_test
|
|
|
|
import (
|
|
_ "embed"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.netflux.io/rob/octoplex/internal/config"
|
|
"git.netflux.io/rob/octoplex/internal/shortid"
|
|
gocmp "github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
//go:embed testdata/complete.yml
|
|
var configComplete []byte
|
|
|
|
//go:embed testdata/logfile.yml
|
|
var configLogfile []byte
|
|
|
|
//go:embed testdata/no-logfile.yml
|
|
var configNoLogfile []byte
|
|
|
|
//go:embed testdata/invalid-destination-url.yml
|
|
var configInvalidDestinationURL []byte
|
|
|
|
//go:embed testdata/multiple-invalid-destination-urls.yml
|
|
var configMultipleInvalidDestinationURLs []byte
|
|
|
|
func TestConfigServiceCurrent(t *testing.T) {
|
|
suffix := "current_" + shortid.New().String()
|
|
systemConfigDirFunc := buildSystemConfigDirFunc(suffix)
|
|
systemConfigDir, _ := systemConfigDirFunc()
|
|
|
|
service, err := config.NewService(systemConfigDirFunc, 1)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { require.NoError(t, os.RemoveAll(systemConfigDir)) })
|
|
|
|
// Ensure defaults are set:
|
|
assert.True(t, service.Current().Sources.RTMP.Enabled)
|
|
}
|
|
|
|
func TestConfigServiceCreateConfig(t *testing.T) {
|
|
suffix := "read_or_create_" + shortid.New().String()
|
|
systemConfigDirFunc := buildSystemConfigDirFunc(suffix)
|
|
systemConfigDir, _ := systemConfigDirFunc()
|
|
|
|
service, err := config.NewService(systemConfigDirFunc, 1)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { require.NoError(t, os.RemoveAll(systemConfigDir)) })
|
|
|
|
cfg, err := service.ReadOrCreateConfig()
|
|
require.NoError(t, err)
|
|
require.False(t, cfg.LogFile.Enabled, "expected logging to be disabled")
|
|
require.Empty(t, cfg.LogFile.Path, "expected no log file")
|
|
|
|
p := filepath.Join(systemConfigDir, "octoplex", "config.yaml")
|
|
cfgBytes, err := os.ReadFile(p)
|
|
require.NoError(t, err, "config file was not created")
|
|
|
|
var readCfg config.Config
|
|
require.NoError(t, yaml.Unmarshal(cfgBytes, &readCfg))
|
|
assert.True(t, readCfg.Sources.RTMP.Enabled, "default values not set")
|
|
}
|
|
|
|
func TestConfigServiceReadConfig(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
configBytes []byte
|
|
want func(*testing.T, config.Config)
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "complete",
|
|
configBytes: configComplete,
|
|
want: func(t *testing.T, cfg config.Config) {
|
|
require.Empty(
|
|
t,
|
|
gocmp.Diff(
|
|
config.Config{
|
|
LogFile: config.LogFile{
|
|
Enabled: true,
|
|
Path: "test.log",
|
|
},
|
|
Sources: config.Sources{
|
|
RTMP: config.RTMPSource{
|
|
Enabled: true,
|
|
StreamKey: "s3cr3t",
|
|
},
|
|
},
|
|
Destinations: []config.Destination{
|
|
{
|
|
Name: "my stream",
|
|
URL: "rtmp://rtmp.example.com:1935/live",
|
|
},
|
|
},
|
|
},
|
|
cfg,
|
|
cmpopts.IgnoreUnexported(config.LogFile{}),
|
|
),
|
|
)
|
|
},
|
|
},
|
|
{
|
|
name: "logging enabled, logfile",
|
|
configBytes: configLogfile,
|
|
want: func(t *testing.T, cfg config.Config) {
|
|
assert.Equal(t, "/tmp/octoplex.log", cfg.LogFile.Path)
|
|
},
|
|
},
|
|
{
|
|
name: "logging enabled, no logfile",
|
|
configBytes: configNoLogfile,
|
|
want: func(t *testing.T, cfg config.Config) {
|
|
assert.True(t, strings.HasSuffix(cfg.LogFile.GetPath(), "/octoplex/octoplex.log"), "expected %q to end with /tmp/octoplex.log", cfg.LogFile.GetPath())
|
|
},
|
|
},
|
|
{
|
|
name: "invalid destination URL",
|
|
configBytes: configInvalidDestinationURL,
|
|
wantErr: "destination URL must start with rtmp://",
|
|
},
|
|
{
|
|
name: "multiple invalid destination URLs",
|
|
configBytes: configMultipleInvalidDestinationURLs,
|
|
wantErr: "destination URL must start with rtmp://\ndestination URL must start with rtmp://",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
suffix := "read_or_create_" + shortid.New().String()
|
|
systemConfigDirFunc := buildSystemConfigDirFunc(suffix)
|
|
systemConfigDir, _ := systemConfigDirFunc()
|
|
appConfigDir := buildAppConfigDir(suffix)
|
|
|
|
require.NoError(t, os.MkdirAll(appConfigDir, 0744))
|
|
t.Cleanup(func() { require.NoError(t, os.RemoveAll(systemConfigDir)) })
|
|
|
|
configPath := filepath.Join(appConfigDir, "config.yaml")
|
|
require.NoError(t, os.WriteFile(configPath, tc.configBytes, 0644))
|
|
|
|
service, err := config.NewService(buildSystemConfigDirFunc(suffix), 1)
|
|
require.NoError(t, err)
|
|
|
|
cfg, err := service.ReadOrCreateConfig()
|
|
|
|
if tc.wantErr == "" {
|
|
require.NoError(t, err)
|
|
tc.want(t, cfg)
|
|
} else {
|
|
require.EqualError(t, err, tc.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConfigServiceSetConfig(t *testing.T) {
|
|
suffix := "set_config_" + shortid.New().String()
|
|
systemConfigDirFunc := buildSystemConfigDirFunc(suffix)
|
|
systemConfigDir, _ := systemConfigDirFunc()
|
|
|
|
service, err := config.NewService(systemConfigDirFunc, 1)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { require.NoError(t, os.RemoveAll(systemConfigDir)) })
|
|
|
|
cfg := config.Config{LogFile: config.LogFile{Enabled: true, Path: "test.log"}}
|
|
require.NoError(t, service.SetConfig(cfg))
|
|
|
|
cfg, err = service.ReadOrCreateConfig()
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "test.log", cfg.LogFile.Path)
|
|
assert.True(t, cfg.LogFile.Enabled)
|
|
}
|
|
|
|
// buildAppConfigDir returns a temporary directory which mimics
|
|
// $XDG_CONFIG_HOME/octoplex.
|
|
func buildAppConfigDir(suffix string) string {
|
|
return filepath.Join(os.TempDir(), "config_test_"+suffix, "octoplex")
|
|
}
|
|
|
|
// buildSystemConfigDirFunc returns a function that creates a temporary
|
|
// directory which mimics $XDG_CONFIG_HOME.
|
|
func buildSystemConfigDirFunc(suffix string) func() (string, error) {
|
|
return func() (string, error) {
|
|
return filepath.Join(os.TempDir(), "config_test_"+suffix), nil
|
|
}
|
|
}
|