olivetin/service/internal/configcheck/rebuild_test.go

202 lines
5.0 KiB
Go

package configcheck_test
import (
"os"
"path/filepath"
"testing"
"github.com/OliveTin/OliveTin/internal/config"
"github.com/OliveTin/OliveTin/internal/configcheck"
"github.com/OliveTin/OliveTin/internal/configissues"
"github.com/OliveTin/OliveTin/internal/entities"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRebuildTemplateParseDefault(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
cfg.Actions = []*config.Action{
{
Title: "Deploy",
ID: "deploy",
Entity: "host",
Arguments: []config.ActionArgument{
{
Name: "ansible_host",
Type: "ascii_identifier",
Default: `{{ host.name | default "All" }}`,
},
},
},
}
configcheck.Rebuild(cfg)
issues := configissues.List()
require.NotEmpty(t, issues)
assert.True(t, hasCode(issues, configissues.CodeTemplateParse))
assert.True(t, hasCode(issues, configissues.CodeEntityEmpty))
assert.False(t, hasCode(issues, configissues.CodeCronEntityBinding))
}
func TestRebuildValidTemplateDefault(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
cfg.Actions = []*config.Action{
{
Title: "Sleep",
ID: "sleep",
Arguments: []config.ActionArgument{
{
Name: "ssh_host",
Type: "ascii_identifier",
Default: `{{ host.hostname }}`,
},
},
},
}
configcheck.Rebuild(cfg)
assert.False(t, hasCode(configissues.List(), configissues.CodeTemplateParse))
}
func TestRebuildCronEntityBinding(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
cfg.Actions = []*config.Action{
{
Title: "Nightly",
ID: "nightly",
Entity: "host",
ExecOnCron: []string{"0 1 * * *"},
},
}
configcheck.Rebuild(cfg)
assert.True(t, hasCode(configissues.List(), configissues.CodeCronEntityBinding))
}
func TestRebuildInvalidCron(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
cfg.Actions = []*config.Action{
{
Title: "Broken cron",
ID: "broken",
ExecOnCron: []string{"not a cron line"},
},
}
configcheck.Rebuild(cfg)
assert.True(t, hasCode(configissues.List(), configissues.CodeCronInvalid))
}
func TestRebuildMissingEntityFile(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
dir := t.TempDir()
cfg.SetDir(dir)
cfg.Entities = []*config.EntityFile{
{Name: "host", File: "missing-hosts.yaml"},
}
configcheck.Rebuild(cfg)
assert.True(t, hasCode(configissues.List(), configissues.CodeEntityFile))
}
func TestRebuildEntityFileLoadsAndClearsEmpty(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
dir := t.TempDir()
cfg.SetDir(dir)
entityPath := filepath.Join(dir, "hosts.yaml")
require.NoError(t, os.WriteFile(entityPath, []byte("- name: cradle\n"), 0o644))
cfg.Entities = []*config.EntityFile{
{Name: "host", File: "hosts.yaml"},
}
cfg.Actions = []*config.Action{
{Title: "Wake", ID: "wake", Entity: "host"},
}
entities.AddEntity("host", "0", map[string]any{"name": "cradle"})
t.Cleanup(func() { entities.ClearEntitiesOfType("host") })
configcheck.Rebuild(cfg)
issues := configissues.List()
assert.False(t, hasCode(issues, configissues.CodeEntityFile))
assert.False(t, hasCode(issues, configissues.CodeEntityEmpty))
}
func TestRebuildIncludesActionConfigFile(t *testing.T) {
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
cfg.Actions = []*config.Action{
{
Title: "Nightly",
ID: "nightly",
Entity: "host",
SourceFile: "/etc/OliveTin/config.d/16-gitops-sr-soe.yaml",
ExecOnCron: []string{"0 1 * * *"},
},
}
configcheck.Rebuild(cfg)
var found bool
for _, issue := range configissues.List() {
if issue.Code == configissues.CodeCronEntityBinding {
assert.Equal(t, "/etc/OliveTin/config.d/16-gitops-sr-soe.yaml", issue.ConfigFile)
found = true
}
}
assert.True(t, found)
}
func TestRebuildSkipsEntityEmptyBeforeLoadAttempt(t *testing.T) {
entities.ResetEntityLoadAttempts()
configissues.BeginConfigLoad()
cfg := config.DefaultConfig()
cfg.Entities = []*config.EntityFile{{Name: "container", File: "containers.json"}}
cfg.Actions = []*config.Action{
{Title: "Start container", ID: "start", Entity: "container"},
}
configcheck.Rebuild(cfg)
assert.False(t, hasCode(configissues.List(), configissues.CodeEntityEmpty))
entities.MarkEntityLoadAttempted("container")
configcheck.Rebuild(cfg)
assert.True(t, hasCode(configissues.List(), configissues.CodeEntityEmpty))
}
func TestStickyEnvUnsetSurvivesRebuild(t *testing.T) {
configissues.BeginConfigLoad()
configissues.ReportSticky(configissues.Issue{
Severity: configissues.SeverityWarning,
Code: configissues.CodeEnvUnset,
Message: "unset",
Source: "MISSING_VAR",
})
configcheck.Rebuild(config.DefaultConfig())
assert.True(t, hasCode(configissues.List(), configissues.CodeEnvUnset))
}
func hasCode(issues []configissues.Issue, code string) bool {
for _, issue := range issues {
if issue.Code == code {
return true
}
}
return false
}