193 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
|    Copyright The containerd Authors.
 | |
| 
 | |
|    Licensed under the Apache License, Version 2.0 (the "License");
 | |
|    you may not use this file except in compliance with the License.
 | |
|    You may obtain a copy of the License at
 | |
| 
 | |
|        http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
|    Unless required by applicable law or agreed to in writing, software
 | |
|    distributed under the License is distributed on an "AS IS" BASIS,
 | |
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|    See the License for the specific language governing permissions and
 | |
|    limitations under the License.
 | |
| */
 | |
| 
 | |
| package server
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"net"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/containerd/go-cni"
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
 | |
| )
 | |
| 
 | |
| func TestToCNIPortMappings(t *testing.T) {
 | |
| 	for _, test := range []struct {
 | |
| 		desc            string
 | |
| 		criPortMappings []*runtime.PortMapping
 | |
| 		cniPortMappings []cni.PortMapping
 | |
| 	}{
 | |
| 		{
 | |
| 			desc: "empty CRI port mapping should map to empty CNI port mapping",
 | |
| 		},
 | |
| 		{
 | |
| 			desc: "CRI port mapping should be converted to CNI port mapping properly",
 | |
| 			criPortMappings: []*runtime.PortMapping{
 | |
| 				{
 | |
| 					Protocol:      runtime.Protocol_UDP,
 | |
| 					ContainerPort: 1234,
 | |
| 					HostPort:      5678,
 | |
| 					HostIp:        "123.124.125.126",
 | |
| 				},
 | |
| 				{
 | |
| 					Protocol:      runtime.Protocol_TCP,
 | |
| 					ContainerPort: 4321,
 | |
| 					HostPort:      8765,
 | |
| 					HostIp:        "126.125.124.123",
 | |
| 				},
 | |
| 				{
 | |
| 					Protocol:      runtime.Protocol_SCTP,
 | |
| 					ContainerPort: 1234,
 | |
| 					HostPort:      5678,
 | |
| 					HostIp:        "123.124.125.126",
 | |
| 				},
 | |
| 			},
 | |
| 			cniPortMappings: []cni.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      5678,
 | |
| 					ContainerPort: 1234,
 | |
| 					Protocol:      "udp",
 | |
| 					HostIP:        "123.124.125.126",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      8765,
 | |
| 					ContainerPort: 4321,
 | |
| 					Protocol:      "tcp",
 | |
| 					HostIP:        "126.125.124.123",
 | |
| 				},
 | |
| 				{
 | |
| 					HostPort:      5678,
 | |
| 					ContainerPort: 1234,
 | |
| 					Protocol:      "sctp",
 | |
| 					HostIP:        "123.124.125.126",
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			desc: "CRI port mapping without host port should be skipped",
 | |
| 			criPortMappings: []*runtime.PortMapping{
 | |
| 				{
 | |
| 					Protocol:      runtime.Protocol_UDP,
 | |
| 					ContainerPort: 1234,
 | |
| 					HostIp:        "123.124.125.126",
 | |
| 				},
 | |
| 				{
 | |
| 					Protocol:      runtime.Protocol_TCP,
 | |
| 					ContainerPort: 4321,
 | |
| 					HostPort:      8765,
 | |
| 					HostIp:        "126.125.124.123",
 | |
| 				},
 | |
| 			},
 | |
| 			cniPortMappings: []cni.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8765,
 | |
| 					ContainerPort: 4321,
 | |
| 					Protocol:      "tcp",
 | |
| 					HostIP:        "126.125.124.123",
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			desc: "CRI port mapping with unsupported protocol should be skipped",
 | |
| 			criPortMappings: []*runtime.PortMapping{
 | |
| 				{
 | |
| 					Protocol:      runtime.Protocol_TCP,
 | |
| 					ContainerPort: 4321,
 | |
| 					HostPort:      8765,
 | |
| 					HostIp:        "126.125.124.123",
 | |
| 				},
 | |
| 			},
 | |
| 			cniPortMappings: []cni.PortMapping{
 | |
| 				{
 | |
| 					HostPort:      8765,
 | |
| 					ContainerPort: 4321,
 | |
| 					Protocol:      "tcp",
 | |
| 					HostIP:        "126.125.124.123",
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	} {
 | |
| 		test := test
 | |
| 		t.Run(test.desc, func(t *testing.T) {
 | |
| 			assert.Equal(t, test.cniPortMappings, toCNIPortMappings(test.criPortMappings))
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestSelectPodIP(t *testing.T) {
 | |
| 	for _, test := range []struct {
 | |
| 		desc                  string
 | |
| 		ips                   []string
 | |
| 		expectedIP            string
 | |
| 		expectedAdditionalIPs []string
 | |
| 		pref                  string
 | |
| 	}{
 | |
| 		{
 | |
| 			desc:                  "ipv4 should be picked even if ipv6 comes first",
 | |
| 			ips:                   []string{"2001:db8:85a3::8a2e:370:7334", "192.168.17.43"},
 | |
| 			expectedIP:            "192.168.17.43",
 | |
| 			expectedAdditionalIPs: []string{"2001:db8:85a3::8a2e:370:7334"},
 | |
| 		},
 | |
| 		{
 | |
| 			desc:                  "ipv6 should be picked even if ipv4 comes first",
 | |
| 			ips:                   []string{"192.168.17.43", "2001:db8:85a3::8a2e:370:7334"},
 | |
| 			expectedIP:            "2001:db8:85a3::8a2e:370:7334",
 | |
| 			expectedAdditionalIPs: []string{"192.168.17.43"},
 | |
| 			pref:                  "ipv6",
 | |
| 		},
 | |
| 		{
 | |
| 			desc:                  "order should reflect ip selection",
 | |
| 			ips:                   []string{"2001:db8:85a3::8a2e:370:7334", "192.168.17.43"},
 | |
| 			expectedIP:            "2001:db8:85a3::8a2e:370:7334",
 | |
| 			expectedAdditionalIPs: []string{"192.168.17.43"},
 | |
| 			pref:                  "cni",
 | |
| 		},
 | |
| 		{
 | |
| 			desc:                  "ipv4 should be picked when there is only ipv4",
 | |
| 			ips:                   []string{"192.168.17.43"},
 | |
| 			expectedIP:            "192.168.17.43",
 | |
| 			expectedAdditionalIPs: nil,
 | |
| 		},
 | |
| 		{
 | |
| 			desc:                  "ipv6 should be picked when there is no ipv4",
 | |
| 			ips:                   []string{"2001:db8:85a3::8a2e:370:7334"},
 | |
| 			expectedIP:            "2001:db8:85a3::8a2e:370:7334",
 | |
| 			expectedAdditionalIPs: nil,
 | |
| 		},
 | |
| 		{
 | |
| 			desc:                  "the first ipv4 should be picked when there are multiple ipv4", // unlikely to happen
 | |
| 			ips:                   []string{"2001:db8:85a3::8a2e:370:7334", "192.168.17.43", "2001:db8:85a3::8a2e:370:7335", "192.168.17.45"},
 | |
| 			expectedIP:            "192.168.17.43",
 | |
| 			expectedAdditionalIPs: []string{"2001:db8:85a3::8a2e:370:7334", "2001:db8:85a3::8a2e:370:7335", "192.168.17.45"},
 | |
| 		},
 | |
| 	} {
 | |
| 		test := test
 | |
| 		t.Run(test.desc, func(t *testing.T) {
 | |
| 			var ipConfigs []*cni.IPConfig
 | |
| 			for _, ip := range test.ips {
 | |
| 				ipConfigs = append(ipConfigs, &cni.IPConfig{
 | |
| 					IP: net.ParseIP(ip),
 | |
| 				})
 | |
| 			}
 | |
| 			ip, additionalIPs := selectPodIPs(context.Background(), ipConfigs, test.pref)
 | |
| 			assert.Equal(t, test.expectedIP, ip)
 | |
| 			assert.Equal(t, test.expectedAdditionalIPs, additionalIPs)
 | |
| 		})
 | |
| 	}
 | |
| }
 | 
