github.com/cilium/cilium@v1.16.2/pkg/ipam/types/types_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package types
     5  
     6  import (
     7  	"net"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestTagsMatch(t *testing.T) {
    14  	require.Equal(t, true, Tags{"1": "1", "2": "2"}.Match(Tags{"1": "1"}))
    15  	require.Equal(t, true, Tags{"1": "1", "2": "2"}.Match(Tags{"2": "2"}))
    16  	require.Equal(t, false, Tags{"1": "1", "2": "2"}.Match(Tags{"3": "3"}))
    17  }
    18  
    19  type mockInterface struct {
    20  	id    string
    21  	pools map[string][]net.IP
    22  }
    23  
    24  func (m *mockInterface) DeepCopyInterface() Interface {
    25  	mc := &mockInterface{
    26  		id:    m.id,
    27  		pools: map[string][]net.IP{},
    28  	}
    29  	for id, pool := range m.pools {
    30  		pc := make([]net.IP, 0, len(pool))
    31  		for _, ip := range pool {
    32  			ipc := net.IP{}
    33  			copy(ipc, ip)
    34  			pc = append(pc, ipc)
    35  		}
    36  		mc.pools[id] = pc
    37  	}
    38  	return mc
    39  }
    40  
    41  func (m *mockInterface) InterfaceID() string {
    42  	return m.id
    43  }
    44  
    45  func (m *mockInterface) ForeachAddress(instanceID string, fn AddressIterator) error {
    46  	for poolID, ips := range m.pools {
    47  		for _, ip := range ips {
    48  			if err := fn(instanceID, m.id, ip.String(), poolID, ip); err != nil {
    49  				return err
    50  			}
    51  		}
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  func TestForeachAddresses(t *testing.T) {
    58  	m := NewInstanceMap()
    59  	m.Update("i-1", InterfaceRevision{
    60  		Resource: &mockInterface{
    61  			id: "intf0",
    62  			pools: map[string][]net.IP{
    63  				"s1": {net.ParseIP("1.1.1.1"), net.ParseIP("2.2.2.2")},
    64  			},
    65  		},
    66  	})
    67  	m.Update("i-2", InterfaceRevision{
    68  		Resource: &mockInterface{
    69  			id: "intf0",
    70  			pools: map[string][]net.IP{
    71  				"s1": {net.ParseIP("3.3.3.3"), net.ParseIP("4.4.4.4")},
    72  			},
    73  		},
    74  	})
    75  
    76  	// Iterate over all instances
    77  	addresses := 0
    78  	m.ForeachAddress("", func(instanceID, interfaceID, ip, poolID string, address Address) error {
    79  		_, ok := address.(net.IP)
    80  		require.Equal(t, true, ok)
    81  		addresses++
    82  		return nil
    83  	})
    84  	require.Equal(t, 4, addresses)
    85  
    86  	// Iterate over "i-1"
    87  	addresses = 0
    88  	m.ForeachAddress("i-1", func(instanceID, interfaceID, ip, poolID string, address Address) error {
    89  		addresses++
    90  		return nil
    91  	})
    92  	require.Equal(t, 2, addresses)
    93  
    94  	// Iterate over all interfaces
    95  	interfaces := 0
    96  	m.ForeachInterface("", func(instanceID, interfaceID string, iface InterfaceRevision) error {
    97  		interfaces++
    98  		return nil
    99  	})
   100  	require.Equal(t, 2, interfaces)
   101  }
   102  
   103  func TestGetInterface(t *testing.T) {
   104  	m := NewInstanceMap()
   105  	rev := InterfaceRevision{
   106  		Resource: &mockInterface{
   107  			id: "intf0",
   108  			pools: map[string][]net.IP{
   109  				"s1": {net.ParseIP("1.1.1.1"), net.ParseIP("2.2.2.2")},
   110  			},
   111  		},
   112  	}
   113  	m.Update("i-1", rev)
   114  
   115  	_, ok := m.GetInterface("inexistent", "inexistent")
   116  	require.Equal(t, false, ok)
   117  	_, ok = m.GetInterface("i-1", "inexistent")
   118  	require.Equal(t, false, ok)
   119  	_, ok = m.GetInterface("inexistent", "intf0")
   120  	require.Equal(t, false, ok)
   121  	intf, ok := m.GetInterface("i-1", "intf0")
   122  	require.Equal(t, true, ok)
   123  
   124  	require.EqualValues(t, rev, intf)
   125  }
   126  
   127  func TestInstanceMapNumInstances(t *testing.T) {
   128  	m := NewInstanceMap()
   129  	m.Update("i-1", InterfaceRevision{
   130  		Resource: &mockInterface{
   131  			id: "intf0",
   132  			pools: map[string][]net.IP{
   133  				"s1": {net.ParseIP("1.1.1.1"), net.ParseIP("2.2.2.2")},
   134  			},
   135  		},
   136  	})
   137  	m.Update("i-2", InterfaceRevision{
   138  		Resource: &mockInterface{
   139  			id: "intf0",
   140  			pools: map[string][]net.IP{
   141  				"s1": {net.ParseIP("3.3.3.3"), net.ParseIP("4.4.4.4")},
   142  			},
   143  		},
   144  	})
   145  	m.Update("i-2", InterfaceRevision{
   146  		Resource: &mockInterface{
   147  			id: "intf1",
   148  			pools: map[string][]net.IP{
   149  				"s1": {net.ParseIP("4.4.4.4"), net.ParseIP("5.5.5.5")},
   150  			},
   151  		},
   152  	})
   153  
   154  	require.Equal(t, 2, m.NumInstances())
   155  }
   156  
   157  func TestFirstSubnetWithAvailableAddresses(t *testing.T) {
   158  	sm := SubnetMap{
   159  		"s0": &Subnet{AvailableAddresses: 0},
   160  		"s1": &Subnet{AvailableAddresses: 1},
   161  		"s2": &Subnet{AvailableAddresses: 0},
   162  	}
   163  
   164  	subnetID, addresses := sm.FirstSubnetWithAvailableAddresses([]PoolID{})
   165  	require.Equal(t, PoolID("s1"), subnetID)
   166  	require.Equal(t, 1, addresses)
   167  
   168  	sm = SubnetMap{
   169  		"s0": &Subnet{AvailableAddresses: 0},
   170  		"s1": &Subnet{AvailableAddresses: 0},
   171  		"s2": &Subnet{AvailableAddresses: 0},
   172  	}
   173  	subnetID, addresses = sm.FirstSubnetWithAvailableAddresses([]PoolID{})
   174  	require.Equal(t, PoolNotExists, subnetID)
   175  	require.Equal(t, 0, addresses)
   176  
   177  	sm = SubnetMap{
   178  		"s0": &Subnet{AvailableAddresses: 0},
   179  		"s1": &Subnet{AvailableAddresses: 10},
   180  		"s2": &Subnet{AvailableAddresses: 20},
   181  	}
   182  	subnetID, addresses = sm.FirstSubnetWithAvailableAddresses([]PoolID{"s0", "s1"})
   183  	require.Equal(t, PoolID("s1"), subnetID)
   184  	require.Equal(t, 10, addresses)
   185  }