diff --git a/.gitlab/ci/.test.yml b/.gitlab/ci/.test.yml index 99ea33631f607a038a048980053d81213e401721..3b75284de8ce802e4de40ba735c79ef5256306b2 100644 --- a/.gitlab/ci/.test.yml +++ b/.gitlab/ci/.test.yml @@ -39,3 +39,9 @@ integration-test-gosdn: script: - go test -p 1 ./integration-tests/* <<: *test + + +unit-test: + script: + - make unit-test-new + <<: *test diff --git a/Makefile b/Makefile index 0a27ad738954590c14fa0d9c3785e88a80921998..d71678d43462d27283feaa458a73670b1c0d13d7 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,9 @@ integration-tests-debug-up: generate-certs containerize-gosdn containerize-plugi integration-tests-debug-down: docker-compose -f dev_env_data/docker-compose/integration-test_docker-compose.yml down +unit-test-new: install-tools + go test -p 1 ./cli/... + # Warning: Depending on your go and development configuration might also clean caches, modules and docker containers from your other projects. clean: rm -rf $(BUILD_ARTIFACTS_PATH) diff --git a/cli/cmd/networkElementCreate.go b/cli/cmd/networkElementCreate.go index 121c732388818ed247e17d19096fb53277b65966..5aa2397bc9531fb999981ba807078ee00d068861 100644 --- a/cli/cmd/networkElementCreate.go +++ b/cli/cmd/networkElementCreate.go @@ -49,7 +49,7 @@ if they diverge from the default credentials (user:'admin' and pw:'arista').`, Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Creating new network element") - err := checkIPPort(address) + err := checkIPorHostnameAndPort(address) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/utils.go b/cli/cmd/utils.go index ca51618da5b45ff5fde1c0691adeab6c9664498e..6342452096618474ef34e994b866fe7e2646ed21 100644 --- a/cli/cmd/utils.go +++ b/cli/cmd/utils.go @@ -41,20 +41,30 @@ import ( gpb "github.com/openconfig/gnmi/proto/gnmi" gnmiv "github.com/openconfig/gnmi/value" "github.com/openconfig/goyang/pkg/yang" + "golang.org/x/net/idna" "google.golang.org/grpc/metadata" ) -func checkIPPort(string) error { +func checkIPorHostnameAndPort(address string) error { // check if address is in the format <IP>:<port> - ip, _, err := net.SplitHostPort(address) - if err != nil { - return err + ipOrHostname, _, err := net.SplitHostPort(address) + if err != nil || ipOrHostname == "" { + errorMessage := fmt.Sprintf("address '%s' is not in the format <IP/Hostname>:<port>", address) + return errors.New(errorMessage) } - // Check IP - ip2 := net.ParseIP(ip) - if ip2 == nil { - return errors.New("invalid IP") + + // If not IP, check if valid Hostname + _, err = idna.Lookup.ToASCII(ipOrHostname) + if err != nil { + // Check if valid ipIP + ip2 := net.ParseIP(ipOrHostname) + if ip2 == nil { + errorMessage := fmt.Sprintf("address '%s' is neither a valid IP nor a hostname", ipOrHostname) + return errors.New(errorMessage) + + } } + return nil } diff --git a/cli/cmd/utils_test.go b/cli/cmd/utils_test.go new file mode 100644 index 0000000000000000000000000000000000000000..c3b557e2908077f89554da138b6bc1970424ca90 --- /dev/null +++ b/cli/cmd/utils_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "testing" +) + +func TestCheckIPorHostnameAndPort(t *testing.T) { + // Test cases for valid IP addresses or hostnames with ports + validCases := []string{ + "127.0.0.1:8080", + "localhost:8080", + "example.com:8080", + "[::1]:8080", + "[2001:db8::1]:1234", + } + + for _, addr := range validCases { + err := checkIPorHostnameAndPort(addr) + if err != nil { + t.Errorf("Expected no error for address %s, but got: %v", addr, err) + } + } +} + +func TestCheckIPorHostnameAndPortInvalid(t *testing.T) { + // Test cases for invalid IP addresses or hostnames with ports + invalidCases := []string{ + ":8080", // Missing IP address or hostname + "example.com", // Missing port + } + + for _, addr := range invalidCases { + err := checkIPorHostnameAndPort(addr) + if err == nil { + t.Errorf("Expected error for address %s, but got no error", addr) + } + } +}