// Copyright (C) 2021 Simon Ruderich // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package config import ( "fmt" "os" "reflect" "testing" "github.com/google/go-cmp/cmp" ) func TestLoadGroups(t *testing.T) { cwd, err := os.Getwd() if err != nil { t.Fatal(err) } defer os.Chdir(cwd) err = os.Chdir("../testdata/project") if err != nil { t.Fatal(err) } hosts, err := LoadHosts() if err != nil { t.Fatal(err) } err = os.Chdir(cwd) if err != nil { t.Fatal(err) } tests := []struct { path string cfg *Config hosts *Hosts exp map[string][]string expErr error }{ { "../testdata/project", &Config{ GroupOrder: []string{ "detected_linux", "detected_freebsd", }, }, hosts, map[string][]string{ "group": { "detected_linux", "detected_freebsd", "host1.example.org", }, "group:remove": { "host2", "detected_mips", }, "group2": { "all", }, "group2:remove": { "remove", }, "all_except_some": { "all", }, "all_except_some:remove": { "host1.example.org", "group2", }, "remove": { "host1.example.org", "host2", "host3.example.net", }, "remove:remove": { "host2", }, }, nil, }, { "../testdata/project", &Config{ GroupOrder: []string{ "detected_freebsd", "does-not-exist", }, }, hosts, nil, fmt.Errorf("config.yaml: group_order: group \"does-not-exist\" does not exist"), }, { "../testdata/project", &Config{ GroupOrder: []string{ "detected_freebsd", "special:group", }, }, hosts, nil, fmt.Errorf("config.yaml: group_order: invalid group name \"special:group\""), }, { "../testdata/project", &Config{ GroupOrder: []string{ "detected_freebsd", "group:remove", }, }, hosts, nil, fmt.Errorf("config.yaml: group_order: invalid group name \"group:remove\""), }, { "../testdata/group-invalid-all", &Config{}, hosts, nil, fmt.Errorf("groups.yaml: group \"all\": conflict with pre-defined group \"all\""), }, { "../testdata/group-invalid-all-remove", &Config{}, hosts, nil, fmt.Errorf("groups.yaml: group \"all:remove\": conflict with pre-defined group \"all:remove\""), }, { "../testdata/group-invalid-conflict", &Config{}, hosts, nil, fmt.Errorf("groups.yaml: group \"host2\": conflict with existing host"), }, { "../testdata/group-invalid-detected", &Config{}, &Hosts{}, nil, fmt.Errorf("groups.yaml: group \"detected_linux\": name must not start with \"detected\" (reserved for detected groups)"), }, { "../testdata/group-invalid-member", &Config{}, &Hosts{}, nil, fmt.Errorf("groups.yaml: group \"group1\": member \"special:member\" must not contain \":\""), }, { "../testdata/group-invalid-missing", &Config{}, &Hosts{}, nil, fmt.Errorf("groups.yaml: group \"1group2\": group \"does-not-exist\" not found"), }, { "../testdata/group-invalid-name", &Config{}, &Hosts{}, nil, fmt.Errorf("groups.yaml: group \"invalid.group.name\": name contains invalid characters (must match ^[a-z0-9_-]+$)"), }, } for _, tc := range tests { err := os.Chdir(tc.path) if err != nil { t.Fatal(err) } res, err := LoadGroups(tc.cfg, tc.hosts) if !reflect.DeepEqual(tc.exp, res) { t.Errorf("%s: res: %s", tc.path, cmp.Diff(tc.exp, res)) } // Ugly but the simplest way to compare errors (including nil) if fmt.Sprintf("%s", err) != fmt.Sprintf("%s", tc.expErr) { t.Errorf("%s: err = %#v, want %#v", tc.path, err, tc.expErr) } err = os.Chdir(cwd) if err != nil { t.Fatal(err) } } } func TestResolveHostGroups(t *testing.T) { cwd, err := os.Getwd() if err != nil { t.Fatal(err) } defer os.Chdir(cwd) err = os.Chdir("../testdata/project") if err != nil { t.Fatal(err) } allHosts, err := LoadHosts() if err != nil { t.Fatal(err) } allGroups, err := LoadGroups(&Config{}, allHosts) if err != nil { t.Fatal(err) } tests := []struct { name string host string detected []string exp []string expErr error }{ { "host1", "host1.example.org", nil, []string{ "all", "group", "host1.example.org", "remove", }, nil, }, { "host2", "host2", nil, []string{ "all", "group2", "host2", }, nil, }, { "host3", "host3.example.net", nil, []string{ "all", "all_except_some", "host3.example.net", "remove", }, nil, }, { "unknown host", "unknown", nil, []string{ "all", "group2", "unknown", }, nil, }, { "host1, detected_mips", "host1.example.org", []string{ "detected_mips", }, []string{ "all", "detected_mips", "host1.example.org", "remove", }, nil, }, { "host2, detected_linux", "host2", []string{ "detected_linux", }, []string{ "all", "detected_linux", "group2", "host2", }, nil, }, } for _, tc := range tests { res, err := ResolveHostGroups(tc.host, allGroups, tc.detected) if !reflect.DeepEqual(tc.exp, res) { t.Errorf("%s: res: %s", tc.name, cmp.Diff(tc.exp, res)) } // Ugly but the simplest way to compare errors (including nil) if fmt.Sprintf("%s", err) != fmt.Sprintf("%s", tc.expErr) { t.Errorf("%s: err = %#v, want %#v", tc.name, err, tc.expErr) } } }