github.com/datadog/cilium@v1.6.12/pkg/ipam/allocator_test.go (about)

     1  // Copyright 2018-2020 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build !privileged_test
    16  
    17  package ipam
    18  
    19  import (
    20  	"net"
    21  	"time"
    22  
    23  	"github.com/cilium/cilium/common/addressing"
    24  	"github.com/cilium/cilium/pkg/datapath/fake"
    25  
    26  	. "gopkg.in/check.v1"
    27  )
    28  
    29  type ownerMock struct{}
    30  
    31  func (o *ownerMock) K8sEventReceived(scope string, action string, valid, equal bool) {}
    32  func (o *ownerMock) K8sEventProcessed(scope string, action string, status bool)      {}
    33  func (o *ownerMock) UpdateCiliumNodeResource()                                       {}
    34  
    35  func (s *IPAMSuite) TestAllocatedIPDump(c *C) {
    36  	fakeAddressing := fake.NewNodeAddressing()
    37  	ipam := NewIPAM(fakeAddressing, Configuration{EnableIPv4: true, EnableIPv6: true}, &ownerMock{})
    38  
    39  	ipv4 := fakeAddressing.IPv4().AllocationCIDR().IP
    40  	ipv6 := fakeAddressing.IPv6().AllocationCIDR().IP
    41  
    42  	for i := 0; i < 10; i++ {
    43  		_, err := addressing.NewCiliumIPv4(ipv4.String())
    44  		c.Assert(err, IsNil)
    45  		nextIP(ipv4)
    46  
    47  		_, err = addressing.NewCiliumIPv6(ipv6.String())
    48  		c.Assert(err, IsNil)
    49  		nextIP(ipv6)
    50  	}
    51  
    52  	allocv4, allocv6, status := ipam.Dump()
    53  	c.Assert(status, Not(Equals), "")
    54  
    55  	// Test the format of the dumped ip addresses
    56  	for ip := range allocv4 {
    57  		c.Assert(net.ParseIP(ip), NotNil)
    58  	}
    59  	for ip := range allocv6 {
    60  		c.Assert(net.ParseIP(ip), NotNil)
    61  	}
    62  }
    63  
    64  func (s *IPAMSuite) TestExpirationTimer(c *C) {
    65  	ip := net.ParseIP("1.1.1.1")
    66  	timeout := 50 * time.Millisecond
    67  
    68  	fakeAddressing := fake.NewNodeAddressing()
    69  	ipam := NewIPAM(fakeAddressing, Configuration{EnableIPv4: true, EnableIPv6: true}, &ownerMock{})
    70  
    71  	err := ipam.AllocateIP(ip, "foo")
    72  	c.Assert(err, IsNil)
    73  
    74  	uuid, err := ipam.StartExpirationTimer(ip, timeout)
    75  	c.Assert(err, IsNil)
    76  	c.Assert(uuid, Not(Equals), "")
    77  	// must fail, already registered
    78  	uuid, err = ipam.StartExpirationTimer(ip, timeout)
    79  	c.Assert(err, Not(IsNil))
    80  	c.Assert(uuid, Equals, "")
    81  	// must fail, already in use
    82  	err = ipam.AllocateIP(ip, "foo")
    83  	c.Assert(err, Not(IsNil))
    84  	// Let expiration timer expire
    85  	time.Sleep(2 * timeout)
    86  	// Must suceed, IP must be released again
    87  	err = ipam.AllocateIP(ip, "foo")
    88  	c.Assert(err, IsNil)
    89  	// register new expiration timer
    90  	uuid, err = ipam.StartExpirationTimer(ip, timeout)
    91  	c.Assert(err, IsNil)
    92  	c.Assert(uuid, Not(Equals), "")
    93  	// attempt to stop with an invalid uuid, must fail
    94  	err = ipam.StopExpirationTimer(ip, "unknown-uuid")
    95  	c.Assert(err, Not(IsNil))
    96  	// stop expiration with valid uuid
    97  	err = ipam.StopExpirationTimer(ip, uuid)
    98  	c.Assert(err, IsNil)
    99  	// Let expiration timer expire
   100  	time.Sleep(2 * timeout)
   101  	// must fail as IP is properly in use now
   102  	err = ipam.AllocateIP(ip, "foo")
   103  	c.Assert(err, Not(IsNil))
   104  	// release IP for real
   105  	err = ipam.ReleaseIP(ip)
   106  	c.Assert(err, IsNil)
   107  
   108  	// allocate IP again
   109  	err = ipam.AllocateIP(ip, "foo")
   110  	c.Assert(err, IsNil)
   111  	// register expiration timer
   112  	uuid, err = ipam.StartExpirationTimer(ip, timeout)
   113  	c.Assert(err, IsNil)
   114  	c.Assert(uuid, Not(Equals), "")
   115  	// release IP, must also stop expiration timer
   116  	err = ipam.ReleaseIP(ip)
   117  	c.Assert(err, IsNil)
   118  	// allocate same IP again
   119  	err = ipam.AllocateIP(ip, "foo")
   120  	c.Assert(err, IsNil)
   121  	// register expiration timer must succeed even though stop was never called
   122  	uuid, err = ipam.StartExpirationTimer(ip, timeout)
   123  	c.Assert(err, IsNil)
   124  	c.Assert(uuid, Not(Equals), "")
   125  	// release IP
   126  	err = ipam.ReleaseIP(ip)
   127  	c.Assert(err, IsNil)
   128  
   129  }
   130  
   131  func (s *IPAMSuite) TestAllocateNextWithExpiration(c *C) {
   132  	timeout := 50 * time.Millisecond
   133  
   134  	fakeAddressing := fake.NewNodeAddressing()
   135  	ipam := NewIPAM(fakeAddressing, Configuration{EnableIPv4: true, EnableIPv6: true}, &ownerMock{})
   136  
   137  	ipv4, ipv6, err := ipam.AllocateNextWithExpiration("", "foo", timeout)
   138  	c.Assert(err, IsNil)
   139  
   140  	// IPv4 address must be in use
   141  	err = ipam.AllocateIP(ipv4.IP, "foo")
   142  	c.Assert(err, Not(IsNil))
   143  	// IPv6 address must be in use
   144  	err = ipam.AllocateIP(ipv6.IP, "foo")
   145  	c.Assert(err, Not(IsNil))
   146  	// Let expiration timer expire
   147  	time.Sleep(2 * timeout)
   148  	// IPv4 address must be available again
   149  	err = ipam.AllocateIP(ipv4.IP, "foo")
   150  	c.Assert(err, IsNil)
   151  	// IPv6 address must be available again
   152  	err = ipam.AllocateIP(ipv6.IP, "foo")
   153  	c.Assert(err, IsNil)
   154  	// Release IPs
   155  	err = ipam.ReleaseIP(ipv4.IP)
   156  	c.Assert(err, IsNil)
   157  	err = ipam.ReleaseIP(ipv6.IP)
   158  	c.Assert(err, IsNil)
   159  
   160  	// Allocate IPs again and test stopping the expiration timer
   161  	ipv4, ipv6, err = ipam.AllocateNextWithExpiration("", "foo", timeout)
   162  	c.Assert(err, IsNil)
   163  
   164  	// Stop expiration timer for IPv4 address
   165  	err = ipam.StopExpirationTimer(ipv4.IP, ipv4.ExpirationUUID)
   166  	c.Assert(err, IsNil)
   167  
   168  	// Let expiration timer expire
   169  	time.Sleep(2 * timeout)
   170  
   171  	// IPv4 address must be in use
   172  	err = ipam.AllocateIP(ipv4.IP, "foo")
   173  	c.Assert(err, Not(IsNil))
   174  	// IPv6 address must be available again
   175  	err = ipam.AllocateIP(ipv6.IP, "foo")
   176  	c.Assert(err, IsNil)
   177  	// Release IPv4 address
   178  	err = ipam.ReleaseIP(ipv4.IP)
   179  	c.Assert(err, IsNil)
   180  }