package libpod import ( "fmt" "testing" "github.com/containers/podman/v3/libpod/network/types" "github.com/stretchr/testify/assert" ) 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 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) }