package impact import ( "reflect" "testing" ) func TestHieradataSelector(t *testing.T) { tests := []struct { name string path string rule string want Selector }{ {"common yaml", "common.yaml", RuleCommon, Selector{All: true}}, {"common eyaml", "common.eyaml", RuleCommon, Selector{All: true}}, {"node", "nodes/web01.example.net.yaml", RuleNode, Selector{Certname: "web01.example.net"}}, {"virtual", "virtual/physical.yaml", RuleVirtual, Selector{Virtual: "physical"}}, {"role tier1", "roles/infra.yaml", RuleRole, Selector{RoleTiers: []string{"infra"}}}, {"role tier2", "roles/infra/puppet.yaml", RuleRole, Selector{RoleTiers: []string{"infra", "puppet"}}}, {"role tier3", "roles/infra/puppet/master.yaml", RuleRole, Selector{RoleTiers: []string{"infra", "puppet", "master"}}}, {"role eyaml", "roles/apps/media.eyaml", RuleRole, Selector{RoleTiers: []string{"apps", "media"}}}, {"country", "country/au.yaml", RuleCountry, Selector{Country: "au"}}, {"country eyaml", "country/au.eyaml", RuleCountry, Selector{Country: "au"}}, {"country region", "country/au/region/syd1.yaml", RuleCountryRegion, Selector{Country: "au", Region: "syd1"}}, {"country region tier1", "country/au/region/syd1/infra.yaml", RuleCountryRegRole, Selector{Country: "au", Region: "syd1", RoleTiers: []string{"infra"}}}, {"country region tier3", "country/au/region/syd1/infra/puppet/master.eyaml", RuleCountryRegRole, Selector{Country: "au", Region: "syd1", RoleTiers: []string{"infra", "puppet", "master"}}}, {"country roles tier1", "country/au/roles/infra.yaml", RuleCountryRole, Selector{Country: "au", RoleTiers: []string{"infra"}}}, {"country roles tier3", "country/au/roles/infra/puppet/master.yaml", RuleCountryRole, Selector{Country: "au", RoleTiers: []string{"infra", "puppet", "master"}}}, {"os all releases", "os/AlmaLinux/all_releases.yaml", RuleOS, Selector{OSName: "AlmaLinux"}}, {"os major", "os/AlmaLinux/AlmaLinux9.yaml", RuleOS, Selector{OSName: "AlmaLinux", OSMajor: "9"}}, {"os major minor", "os/AlmaLinux/AlmaLinux9.7.yaml", RuleOS, Selector{OSName: "AlmaLinux", OSMajor: "9", OSMinor: "7"}}, {"os debian major", "os/Debian/Debian11.yaml", RuleOS, Selector{OSName: "Debian", OSMajor: "11"}}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { got, rule, ok := hieradataSelector(tc.path) if !ok { t.Fatalf("hieradataSelector(%q) not recognised", tc.path) } if rule != tc.rule { t.Errorf("rule = %q, want %q", rule, tc.rule) } if !reflect.DeepEqual(got, tc.want) { t.Errorf("selector = %#v, want %#v", got, tc.want) } }) } } func TestHieradataSelectorRejects(t *testing.T) { for _, p := range []string{ "README.md", "roles/a/b/c/d.yaml", "country/au/region/syd1/a/b/c/d.yaml", "os/AlmaLinux/AlmaLinux9.json", "whatever/thing.yaml", } { if _, _, ok := hieradataSelector(p); ok { t.Errorf("hieradataSelector(%q) unexpectedly recognised", p) } } } func TestManifestClasses(t *testing.T) { tests := []struct { module string rest []string want []string }{ {"profiles", []string{"base.pp"}, []string{"profiles::base"}}, {"profiles", []string{"base", "motd.pp"}, []string{"profiles::base::motd"}}, {"roles", []string{"infra", "k8s", "node.pp"}, []string{"roles::infra::k8s::node"}}, {"jellyfin", []string{"init.pp"}, []string{"jellyfin", "jellyfin::init"}}, {"profiles", []string{"cloudinit", "init.pp"}, []string{"profiles::cloudinit", "profiles::cloudinit::init"}}, } for _, tc := range tests { if got := ManifestClasses(tc.module, tc.rest); !reflect.DeepEqual(got, tc.want) { t.Errorf("ManifestClasses(%q, %v) = %v, want %v", tc.module, tc.rest, got, tc.want) } } } func TestClassifyPathRepoGlobal(t *testing.T) { for _, p := range []string{"hiera.yaml", "environment.conf", "Puppetfile", "manifests/site.pp"} { m := classifyPath(p, nil) if len(m.targets) != 1 || !m.targets[0].sel.All { t.Fatalf("classifyPath(%q) = %#v, want an all-hosts target", p, m) } if m.targets[0].rule != RuleRepoGlobal { t.Errorf("classifyPath(%q) rule = %q", p, m.targets[0].rule) } } } func TestClassifyPathIgnoredAndUnknown(t *testing.T) { for _, p := range []string{".woodpecker/test.yaml", "Gemfile", "doc/notes.md", "vendor/bundle/x.rb", "README.md"} { if m := classifyPath(p, nil); !m.ignored { t.Errorf("classifyPath(%q) should be ignored, got %#v", p, m) } } for _, p := range []string{"random/thing.txt", "hieradata/nope/deep/deeper/x.yaml"} { if m := classifyPath(p, nil); !m.unknown { t.Errorf("classifyPath(%q) should be unknown, got %#v", p, m) } } } func TestClassifyPathPluginsync(t *testing.T) { m := classifyPath("modules/libs/lib/facter/netbox.rb", nil) if len(m.targets) != 1 || !m.targets[0].sel.All || m.targets[0].rule != RulePluginsync { t.Fatalf("pluginsync path = %#v, want an all-hosts pluginsync target", m) } } func TestClassifyPathManifest(t *testing.T) { m := classifyPath("site/profiles/manifests/base/motd.pp", nil) if len(m.classes) != 1 || m.classes[0].name != "profiles::base::motd" { t.Fatalf("classes = %#v", m.classes) } }