mirror of https://github.com/containers/podman.git
				
				
				
			
		
			
				
	
	
		
			539 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			539 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
| package libpod
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"reflect"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 
 | |
| 	"github.com/containers/podman/v3/libpod/define"
 | |
| 	"github.com/containers/podman/v3/libpod/network/types"
 | |
| )
 | |
| 
 | |
| func Test_ocicniPortsToNetTypesPorts(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name string
 | |
| 		arg  []types.OCICNIPortMapping
 | |
| 		want []types.PortMapping
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "no ports",
 | |
| 			arg:  nil,
 | |
| 			want: nil,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "empty ports",
 | |
| 			arg:  []types.OCICNIPortMapping{},
 | |
| 			want: nil,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "single port",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "two separate ports",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      9000,
 | |
| 					ContainerPort: 90,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      9000,
 | |
| 					ContainerPort: 90,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "two ports joined",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 81,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         2,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "three ports with different container port are not joined",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 79,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8082,
 | |
| 					ContainerPort: 82,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 79,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8082,
 | |
| 					ContainerPort: 82,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "three ports joined (not sorted)",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 81,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8082,
 | |
| 					ContainerPort: 82,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         3,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "different protocols ports are not joined",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 81,
 | |
| 					Protocol:      "udp",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 81,
 | |
| 					Protocol:      "udp",
 | |
| 					Range:         1,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "different host ip ports are not joined",
 | |
| 			arg: []types.OCICNIPortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					HostIP:        "192.168.1.1",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 81,
 | |
| 					Protocol:      "tcp",
 | |
| 					HostIP:        "192.168.1.2",
 | |
| 				},
 | |
| 			},
 | |
| 			want: []types.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8080,
 | |
| 					ContainerPort: 80,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 					HostIP:        "192.168.1.1",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8081,
 | |
| 					ContainerPort: 81,
 | |
| 					Protocol:      "tcp",
 | |
| 					Range:         1,
 | |
| 					HostIP:        "192.168.1.2",
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 	for _, tt := range tests {
 | |
| 		tt := tt
 | |
| 		t.Run(tt.name, func(t *testing.T) {
 | |
| 			result := ocicniPortsToNetTypesPorts(tt.arg)
 | |
| 			assert.Equal(t, tt.want, result, "ports do not match")
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func Test_resultToBasicNetworkConfig(t *testing.T) {
 | |
| 	testCases := []struct {
 | |
| 		description           string
 | |
| 		expectError           bool
 | |
| 		inputResult           types.StatusBlock
 | |
| 		expectedNetworkConfig define.InspectBasicNetworkConfig
 | |
| 	}{
 | |
| 		{
 | |
| 			description: "single secondary IPv4 address is shown as define.Address",
 | |
| 			inputResult: types.StatusBlock{
 | |
| 				Interfaces: map[string]types.NetInterface{
 | |
| 					"eth1": {
 | |
| 						Subnets: []types.NetAddress{
 | |
| 							{
 | |
| 								Gateway: net.ParseIP("172.26.0.1"),
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("172.26.0.2"),
 | |
| 										Mask: net.CIDRMask(20, 32),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 							{
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("172.26.0.3"),
 | |
| 										Mask: net.CIDRMask(10, 32),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			expectedNetworkConfig: define.InspectBasicNetworkConfig{
 | |
| 				IPAddress:   "172.26.0.2",
 | |
| 				IPPrefixLen: 20,
 | |
| 				Gateway:     "172.26.0.1",
 | |
| 				SecondaryIPAddresses: []define.Address{
 | |
| 					{
 | |
| 						Addr:         "172.26.0.3",
 | |
| 						PrefixLength: 10,
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			description: "multiple secondary IPv4 addresses are shown as define.Address",
 | |
| 			inputResult: types.StatusBlock{
 | |
| 				Interfaces: map[string]types.NetInterface{
 | |
| 					"eth1": {
 | |
| 						Subnets: []types.NetAddress{
 | |
| 							{
 | |
| 								Gateway: net.ParseIP("172.26.0.1"),
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("172.26.0.2"),
 | |
| 										Mask: net.CIDRMask(20, 32),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 							{
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("172.26.0.3"),
 | |
| 										Mask: net.CIDRMask(10, 32),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 							{
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("172.26.0.4"),
 | |
| 										Mask: net.CIDRMask(24, 32),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			expectedNetworkConfig: define.InspectBasicNetworkConfig{
 | |
| 				IPAddress:   "172.26.0.2",
 | |
| 				IPPrefixLen: 20,
 | |
| 				Gateway:     "172.26.0.1",
 | |
| 				SecondaryIPAddresses: []define.Address{
 | |
| 					{
 | |
| 						Addr:         "172.26.0.3",
 | |
| 						PrefixLength: 10,
 | |
| 					},
 | |
| 					{
 | |
| 						Addr:         "172.26.0.4",
 | |
| 						PrefixLength: 24,
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			description: "single secondary IPv6 address is shown as define.Address",
 | |
| 			inputResult: types.StatusBlock{
 | |
| 				Interfaces: map[string]types.NetInterface{
 | |
| 					"eth1": {
 | |
| 						Subnets: []types.NetAddress{
 | |
| 							{
 | |
| 								Gateway: net.ParseIP("ff02::fb"),
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("ff02::fc"),
 | |
| 										Mask: net.CIDRMask(20, 128),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 							{
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("ff02::fd"),
 | |
| 										Mask: net.CIDRMask(10, 128),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			expectedNetworkConfig: define.InspectBasicNetworkConfig{
 | |
| 				GlobalIPv6Address:   "ff02::fc",
 | |
| 				GlobalIPv6PrefixLen: 20,
 | |
| 				IPv6Gateway:         "ff02::fb",
 | |
| 				SecondaryIPv6Addresses: []define.Address{
 | |
| 					{
 | |
| 						Addr:         "ff02::fd",
 | |
| 						PrefixLength: 10,
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			description: "multiple secondary IPv6 addresses are shown as define.Address",
 | |
| 			inputResult: types.StatusBlock{
 | |
| 				Interfaces: map[string]types.NetInterface{
 | |
| 					"eth1": {
 | |
| 						Subnets: []types.NetAddress{
 | |
| 							{
 | |
| 								Gateway: net.ParseIP("ff02::fb"),
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("ff02::fc"),
 | |
| 										Mask: net.CIDRMask(20, 128),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 							{
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("ff02::fd"),
 | |
| 										Mask: net.CIDRMask(10, 128),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 							{
 | |
| 								IPNet: types.IPNet{
 | |
| 									IPNet: net.IPNet{
 | |
| 										IP:   net.ParseIP("ff02::fe"),
 | |
| 										Mask: net.CIDRMask(24, 128),
 | |
| 									},
 | |
| 								},
 | |
| 							},
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			expectedNetworkConfig: define.InspectBasicNetworkConfig{
 | |
| 				GlobalIPv6Address:   "ff02::fc",
 | |
| 				GlobalIPv6PrefixLen: 20,
 | |
| 				IPv6Gateway:         "ff02::fb",
 | |
| 				SecondaryIPv6Addresses: []define.Address{
 | |
| 					{
 | |
| 						Addr:         "ff02::fd",
 | |
| 						PrefixLength: 10,
 | |
| 					},
 | |
| 					{
 | |
| 						Addr:         "ff02::fe",
 | |
| 						PrefixLength: 24,
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, tcl := range testCases {
 | |
| 		tc := tcl
 | |
| 		t.Run(tc.description, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			actualNetworkConfig, err := resultToBasicNetworkConfig(tc.inputResult)
 | |
| 
 | |
| 			if tc.expectError && err == nil {
 | |
| 				t.Fatalf("Expected error didn't happen")
 | |
| 			}
 | |
| 
 | |
| 			if !tc.expectError && err != nil {
 | |
| 				t.Fatalf("Unexpected error happened: %v", err)
 | |
| 			}
 | |
| 
 | |
| 			if !reflect.DeepEqual(tc.expectedNetworkConfig, actualNetworkConfig) {
 | |
| 				t.Fatalf(
 | |
| 					"Expected networkConfig %+v didn't match actual value %+v", tc.expectedNetworkConfig, actualNetworkConfig)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func benchmarkOCICNIPortsToNetTypesPorts(b *testing.B, ports []types.OCICNIPortMapping) {
 | |
| 	for n := 0; n < b.N; n++ {
 | |
| 		ocicniPortsToNetTypesPorts(ports)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPortsNoPorts(b *testing.B) {
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, nil)
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPorts1(b *testing.B) {
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, []types.OCICNIPortMapping{
 | |
| 		{
 | |
| 			HostPort:      8080,
 | |
| 			ContainerPort: 80,
 | |
| 			Protocol:      "tcp",
 | |
| 		},
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPorts10(b *testing.B) {
 | |
| 	ports := make([]types.OCICNIPortMapping, 0, 10)
 | |
| 	for i := int32(8080); i < 8090; i++ {
 | |
| 		ports = append(ports, types.OCICNIPortMapping{
 | |
| 			HostPort:      i,
 | |
| 			ContainerPort: i,
 | |
| 			Protocol:      "tcp",
 | |
| 		})
 | |
| 	}
 | |
| 	b.ResetTimer()
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, ports)
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPorts100(b *testing.B) {
 | |
| 	ports := make([]types.OCICNIPortMapping, 0, 100)
 | |
| 	for i := int32(8080); i < 8180; i++ {
 | |
| 		ports = append(ports, types.OCICNIPortMapping{
 | |
| 			HostPort:      i,
 | |
| 			ContainerPort: i,
 | |
| 			Protocol:      "tcp",
 | |
| 		})
 | |
| 	}
 | |
| 	b.ResetTimer()
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, ports)
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPorts1k(b *testing.B) {
 | |
| 	ports := make([]types.OCICNIPortMapping, 0, 1000)
 | |
| 	for i := int32(8080); i < 9080; i++ {
 | |
| 		ports = append(ports, types.OCICNIPortMapping{
 | |
| 			HostPort:      i,
 | |
| 			ContainerPort: i,
 | |
| 			Protocol:      "tcp",
 | |
| 		})
 | |
| 	}
 | |
| 	b.ResetTimer()
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, ports)
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPorts10k(b *testing.B) {
 | |
| 	ports := make([]types.OCICNIPortMapping, 0, 30000)
 | |
| 	for i := int32(8080); i < 18080; i++ {
 | |
| 		ports = append(ports, types.OCICNIPortMapping{
 | |
| 			HostPort:      i,
 | |
| 			ContainerPort: i,
 | |
| 			Protocol:      "tcp",
 | |
| 		})
 | |
| 	}
 | |
| 	b.ResetTimer()
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, ports)
 | |
| }
 | |
| 
 | |
| func Benchmark_ocicniPortsToNetTypesPorts1m(b *testing.B) {
 | |
| 	ports := make([]types.OCICNIPortMapping, 0, 1000000)
 | |
| 	for j := 0; j < 20; j++ {
 | |
| 		for i := int32(1); i <= 50000; i++ {
 | |
| 			ports = append(ports, types.OCICNIPortMapping{
 | |
| 				HostPort:      i,
 | |
| 				ContainerPort: i,
 | |
| 				Protocol:      "tcp",
 | |
| 				HostIP:        fmt.Sprintf("192.168.1.%d", j),
 | |
| 			})
 | |
| 		}
 | |
| 	}
 | |
| 	b.ResetTimer()
 | |
| 	benchmarkOCICNIPortsToNetTypesPorts(b, ports)
 | |
| }
 |