diff --git a/Makefile b/Makefile index 0babd543..a1734120 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ WW_BUILD_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree all: vendor wwctl wwclient bash_completion man_page +build: lint test-it vet all + # set the go tools into the tools bin. setup_tools: $(GO_TOOLS_BIN) $(GOLANGCI_LINT) @@ -48,6 +50,22 @@ lint: setup_tools @echo Running golangci-lint... @$(GOLANGCI_LINT) run --build-tags "$(WW_BUILD_GO_BUILD_TAGS)" --skip-dirs internal/pkg/staticfiles ./... +vet: + go vet ./... + +test-it: + go test -v ./... + +# Generate test coverage +test-cover: ## Run test coverage and generate html report + rm -fr coverage + mkdir coverage + go list -f '{{if gt (len .TestGoFiles) 0}}"go test -covermode count -coverprofile {{.Name}}.coverprofile -coverpkg ./... {{.ImportPath}}"{{end}}' ./... | xargs -I {} bash -c {} + echo "mode: count" > coverage/cover.out + grep -h -v "^mode:" *.coverprofile >> "coverage/cover.out" + rm *.coverprofile + go tool cover -html=coverage/cover.out -o=coverage/cover.html + debian: all files: all diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 596a6b43..27007dec 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -1,15 +1,13 @@ package node import ( + "errors" "fmt" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "gopkg.in/yaml.v2" "io/ioutil" "sort" "strings" - - "github.com/pkg/errors" - "gopkg.in/yaml.v2" - - "github.com/hpcng/warewulf/internal/pkg/wwlog" ) const ConfigFile = "/etc/warewulf/nodes.conf" @@ -266,35 +264,3 @@ func (config *nodeYaml) FindDiscoverableNode() (NodeInfo, string, error) { return ret, "", errors.New("No unconfigured nodes found") } - -func (config *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { - var ret NodeInfo - - n, _ := config.FindAllNodes() - - for _, node := range n { - for _, dev := range node.NetDevs { - if dev.Hwaddr.Get() == hwa { - return node, nil - } - } - } - - return ret, errors.New("No nodes found with HW Addr: " + hwa) -} - -func (config *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) { - var ret NodeInfo - - n, _ := config.FindAllNodes() - - for _, node := range n { - for _, dev := range node.NetDevs { - if dev.Ipaddr.Get() == ipaddr { - return node, nil - } - } - } - - return ret, errors.New("No nodes found with IP Addr: " + ipaddr) -} diff --git a/internal/pkg/node/util.go b/internal/pkg/node/util.go new file mode 100644 index 00000000..4b8bb9b3 --- /dev/null +++ b/internal/pkg/node/util.go @@ -0,0 +1,47 @@ +package node + +import ( + "errors" + "net" + "strings" +) + +func (config *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { + if _, err := net.ParseMAC(hwa); err != nil { + return NodeInfo{}, errors.New("invalid hardware address: " + hwa) + } + + var ret NodeInfo + + n, _ := config.FindAllNodes() + + for _, node := range n { + for _, dev := range node.NetDevs { + if strings.EqualFold(dev.Hwaddr.Get(), hwa) { + return node, nil + } + } + } + + return ret, errors.New("No nodes found with HW Addr: " + hwa) +} + +func (config *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) { + if net.ParseIP(ipaddr) == nil { + return NodeInfo{}, errors.New("invalid IP:" + ipaddr) + } + + var ret NodeInfo + + n, _ := config.FindAllNodes() + + for _, node := range n { + for _, dev := range node.NetDevs { + if dev.Ipaddr.Get() == ipaddr { + return node, nil + } + } + } + + return ret, errors.New("No nodes found with IP Addr: " + ipaddr) +} diff --git a/internal/pkg/node/util_test.go b/internal/pkg/node/util_test.go new file mode 100644 index 00000000..78f4127c --- /dev/null +++ b/internal/pkg/node/util_test.go @@ -0,0 +1,135 @@ +package node + +import ( + "gopkg.in/yaml.v2" + "testing" +) + +func NewTestNode() (nodeYaml, error) { + var data = ` +nodeprofiles: + default: + comment: This profile is automatically included for each node +nodes: + test_node: + profiles: + - default + network devices: + eth0: + default: true + hwaddr: 00:00:00:00:12:34 + ipaddr: 1.2.3.4 + ipcidr: "" + prefix: "" + netmask: "" + eno1: + default: true + hwaddr: ab:cd:ef:00:12:34 + ipaddr: 1.2.3.4 + ipcidr: "" + prefix: "" + netmask: "" + eno2: + default: true + hwaddr: aB:Cd:eF:12:34:56 + ipaddr: 1.2.3.4 + ipcidr: "" + prefix: "" + netmask: "" + test_node_IPv6: + profiles: + - default + network devices: + eth1: + default: false + hwaddr: "" + ipaddr: fd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef + ipcidr: "" + prefix: "" + netmask: "" +` + var ret nodeYaml + err := yaml.Unmarshal([]byte(data), &ret) + if err != nil { + return ret, err + } + return ret, nil +} + +func Test_nodeYaml_FindByHwaddr(t *testing.T) { + c, _ := NewTestNode() + //type fields struct { + // NodeProfiles map[string]*NodeConf + // Nodes map[string]*NodeConf + //} + type args struct { + hwa string + } + tests := []struct { + name string + //fields fields + config nodeYaml + args args + want string + wantErr bool + }{ + {"emptyString", c, args{hwa: ""}, "", true}, + {"noIpString", c, args{hwa: "this is not a MAC"}, "", true}, + {"intString", c, args{hwa: "4294967296"}, "", true}, + {"invalidMAC", c, args{hwa: "xx:00:00:00:12:34"}, "", true}, + {"validMACNotFound", c, args{hwa: "aa:FF:ee:65:43:21"}, "", true}, + {"validMAC", c, args{hwa: "ab:cd:ef:00:12:34"}, "test_node", false}, + {"validMAC2", c, args{hwa: "aB:Cd:eF:00:12:34"}, "test_node", false}, + {"validMAC3", c, args{hwa: "Ab:cD:Ef:12:34:56"}, "test_node", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := tt.config + got, err := config.FindByHwaddr(tt.args.hwa) + if (err != nil) != tt.wantErr { + t.Errorf("FindByHwaddr() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !(got.Id.Get() == tt.want) { + t.Errorf("FindByHwaddr() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_nodeYaml_FindByIpaddr(t *testing.T) { + c, _ := NewTestNode() + type args struct { + ipaddr string + } + tests := []struct { + name string + config nodeYaml + args args + want string + wantErr bool + }{ + {"emptyString", c, args{ipaddr: ""}, "", true}, + {"noIpString", c, args{ipaddr: "this is not an IP"}, "", true}, + {"intString", c, args{ipaddr: "4294967296"}, "", true}, + {"invalidIPv4", c, args{ipaddr: "1.2.3.256"}, "", true}, + {"invalidIPv6", c, args{ipaddr: "xd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef"}, "", true}, + {"validIPv4NotFound", c, args{ipaddr: "1.1.1.1"}, "", true}, + {"validIPv6NotFound", c, args{ipaddr: "fd1a:2b3c:4d5e:06f0:1234:5678:90ab:fedc"}, "", true}, + {"validIPv4", c, args{ipaddr: "1.2.3.4"}, "test_node", false}, + {"validIPv6", c, args{ipaddr: "fd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef"}, "test_node_IPv6", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := tt.config + got, err := config.FindByIpaddr(tt.args.ipaddr) + if (err != nil) != tt.wantErr { + t.Errorf("FindByIpaddr() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !(got.Id.Get() == tt.want) { + t.Errorf("FindByHwaddr() got = %v, want %v", got, tt.want) + } + }) + } +}