From 501326531d4d8d18f6105f53e52b5ebbccd23e20 Mon Sep 17 00:00:00 2001 From: Alex Jia Date: Tue, 23 Oct 2018 21:42:59 +0800 Subject: [PATCH] test: api_network_test: add new check points Signed-off-by: Alex Jia --- apis/opts/networks.go | 115 --------------------------- apis/opts/networks_test.go | 158 ++++++++++++++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 118 deletions(-) diff --git a/apis/opts/networks.go b/apis/opts/networks.go index 16b9bee96f..e69de29bb2 100644 --- a/apis/opts/networks.go +++ b/apis/opts/networks.go @@ -1,115 +0,0 @@ -package opts - -import ( - "fmt" - "net" - "strings" - - "github.com/alibaba/pouch/apis/types" -) - -// ParseNetworks parses network configurations of container. -func ParseNetworks(networks []string) (*types.NetworkingConfig, string, error) { - var networkMode string - if len(networks) == 0 { - networkMode = "bridge" - } - networkingConfig := &types.NetworkingConfig{ - EndpointsConfig: map[string]*types.EndpointSettings{}, - } - for _, network := range networks { - name, parameter, mode, err := parseNetwork(network) - if err != nil { - return nil, "", err - } - - if networkMode == "" || mode == "mode" { - networkMode = name - } - - if name == "container" { - networkMode = fmt.Sprintf("%s:%s", name, parameter) - } else if ipaddr := net.ParseIP(parameter); ipaddr != nil { - networkingConfig.EndpointsConfig[name] = &types.EndpointSettings{ - IPAddress: parameter, - IPAMConfig: &types.EndpointIPAMConfig{ - IPV4Address: parameter, - }, - } - } - } - - return networkingConfig, networkMode, nil -} - -// network format as below: -// [network]:[ip_address], such as: mynetwork:172.17.0.2 or mynetwork(ip alloc by ipam) or 172.17.0.2(default network is bridge) -// [network_mode]:[parameter], such as: host(use host network) or container:containerID(use exist container network) -// [network_mode]:[parameter]:mode, such as: mynetwork:172.17.0.2:mode(if the container has multi-networks, the network is the default network mode) -func parseNetwork(network string) (string, string, string, error) { - var ( - name string - parameter string - mode string - ) - if network == "" { - return "", "", "", fmt.Errorf("invalid network: cannot be empty") - } - arr := strings.Split(network, ":") - switch len(arr) { - case 1: - if ipaddr := net.ParseIP(arr[0]); ipaddr != nil { - parameter = arr[0] - } else { - name = arr[0] - } - case 2: - name = arr[0] - if name == "container" { - parameter = arr[1] - } else if ipaddr := net.ParseIP(arr[1]); ipaddr != nil { - parameter = arr[1] - } else { - mode = arr[1] - } - default: - name = arr[0] - parameter = arr[1] - mode = arr[2] - } - - return name, parameter, mode, nil -} - -// ValidateNetworks verifies network configurations of container. -func ValidateNetworks(nwConfig *types.NetworkingConfig) error { - if nwConfig == nil || len(nwConfig.EndpointsConfig) == 0 { - return nil - } - - // FIXME(ziren): this limitation may be removed in future - // Now not create more then one interface for container is not allowed - if len(nwConfig.EndpointsConfig) > 1 { - l := make([]string, 0, len(nwConfig.EndpointsConfig)) - for k := range nwConfig.EndpointsConfig { - l = append(l, k) - } - - return fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", ")) - } - - // len(nwConfig.EndpointsConfig) == 1 - for k, v := range nwConfig.EndpointsConfig { - if v == nil { - return fmt.Errorf("no EndpointSettings for %s", k) - } - if v.IPAMConfig != nil { - if v.IPAMConfig.IPV4Address != "" && net.ParseIP(v.IPAMConfig.IPV4Address).To4() == nil { - return fmt.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPV4Address) - } - // TODO: check IPv6Address - } - } - - return nil -} diff --git a/apis/opts/networks_test.go b/apis/opts/networks_test.go index 07ee834ecc..1ec2601e2a 100644 --- a/apis/opts/networks_test.go +++ b/apis/opts/networks_test.go @@ -18,9 +18,68 @@ func TestParseNetworks(t *testing.T) { args args want *types.NetworkingConfig want1 string + err error wantErr bool }{ - // TODO: Add test cases. + { + name: "networks is null then return 'bridge' mode", + args: args{ + networks: []string{}, + }, + want: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{}, + }, + want1: "bridge", + wantErr: false, + }, + { + name: "invalid network: cannot be empty", + args: args{ + networks: []string{""}, + }, + err: fmt.Errorf("invalid network: cannot be empty"), + wantErr: true, + }, + { + name: "if networkMode is null or mode is 'mode' then return name as mode", + args: args{ + networks: []string{"foo:bar:mode"}, + }, + want: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{}, + }, + want1: "foo", + wantErr: false, + }, + { + name: "if name is 'container' then return name and parameter as mode", + args: args{ + networks: []string{"container:e8e153651a0d:mode"}, + }, + want: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{}, + }, + want1: "container:e8e153651a0d", + wantErr: false, + }, + { + name: "name is not 'container'", + args: args{ + networks: []string{"foo:127.0.0.1"}, + }, + want: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{ + "foo": { + IPAddress: "127.0.0.1", + IPAMConfig: &types.EndpointIPAMConfig{ + IPV4Address: "127.0.0.1", + }, + }, + }, + }, + want1: "foo", + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -35,6 +94,9 @@ func TestParseNetworks(t *testing.T) { if got1 != tt.want1 { t.Errorf("ParseNetworks() got1 = %v, want %v", got1, tt.want1) } + if (err != nil) && !reflect.DeepEqual(err, tt.err) { + t.Errorf("ParseNetworks() = %v, want %v", err, tt.err) + } }) } } @@ -46,15 +108,105 @@ func TestVerifyNetworks(t *testing.T) { tests := []struct { name string args args + err error wantErr bool }{ - // TODO: Add test cases. + { + name: "return expected nil 1", + args: args{ + nwConfig: &types.NetworkingConfig{}, + }, + wantErr: false, + }, + { + name: "return expected nil 2", + args: args{ + nwConfig: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{}, + }, + }, + wantErr: false, + }, + { + name: "test IPAMConfig.IPV4Address", + args: args{ + nwConfig: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{ + "Networks": { + IPAMConfig: &types.EndpointIPAMConfig{ + IPV4Address: "127.0.0.1", + }, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "test IPAddress, Gateway, IPV4Address and IPV6Address", + args: args{ + nwConfig: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{ + "Networks": { + Links: []string{}, + Aliases: []string{}, + EndpointID: "", + NetworkID: "", + MacAddress: "", + IPAddress: "127.0.0.1", + Gateway: "192.168.1.1", + IPAMConfig: &types.EndpointIPAMConfig{ + IPV4Address: "192.168.1.1", + IPV6Address: "2001:0db8:85a3:08d3:1319:8a2e:0370:1234", + LinkLocalIps: []string{ + "1.2.3.4", + }, + }, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "container cannot be connected to network endpoints", + args: args{ + nwConfig: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{ + "foo": {}, + "bar": {}, + }, + }, + }, + wantErr: true, + err: fmt.Errorf("Container cannot be connected to network endpoints: bar, foo"), + }, + { + name: "invalid IPv4 address", + args: args{ + nwConfig: &types.NetworkingConfig{ + EndpointsConfig: map[string]*types.EndpointSettings{ + "foo": { + IPAMConfig: &types.EndpointIPAMConfig{ + IPV4Address: "foo.bar", + }, + }, + }, + }, + }, + wantErr: true, + err: fmt.Errorf("invalid IPv4 address: foo.bar"), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := ValidateNetworks(tt.args.nwConfig); (err != nil) != tt.wantErr { + err := ValidateNetworks(tt.args.nwConfig) + if (err != nil) != tt.wantErr { t.Errorf("VerifyNetworks() error = %v, wantErr %v", err, tt.wantErr) } + if tt.wantErr && !reflect.DeepEqual(err, tt.err) { + t.Errorf("ParseNetworks() = %v, want %v", err, tt.err) + } }) } }