github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/libnetwork/portallocator/portallocator_test.go (about)

     1  package portallocator
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"testing"
     7  )
     8  
     9  func resetPortAllocator() {
    10  	instance = newInstance()
    11  }
    12  
    13  func TestRequestNewPort(t *testing.T) {
    14  	p := Get()
    15  	defer resetPortAllocator()
    16  
    17  	port, err := p.RequestPort(defaultIP, "tcp", 0)
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  
    22  	if expected := p.Begin; port != expected {
    23  		t.Fatalf("Expected port %d got %d", expected, port)
    24  	}
    25  }
    26  
    27  func TestRequestSpecificPort(t *testing.T) {
    28  	p := Get()
    29  	defer resetPortAllocator()
    30  
    31  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	if port != 5000 {
    37  		t.Fatalf("Expected port 5000 got %d", port)
    38  	}
    39  }
    40  
    41  func TestReleasePort(t *testing.T) {
    42  	p := Get()
    43  
    44  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    45  	if err != nil {
    46  		t.Fatal(err)
    47  	}
    48  	if port != 5000 {
    49  		t.Fatalf("Expected port 5000 got %d", port)
    50  	}
    51  
    52  	if err := p.ReleasePort(defaultIP, "tcp", 5000); err != nil {
    53  		t.Fatal(err)
    54  	}
    55  }
    56  
    57  func TestReuseReleasedPort(t *testing.T) {
    58  	p := Get()
    59  	defer resetPortAllocator()
    60  
    61  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  	if port != 5000 {
    66  		t.Fatalf("Expected port 5000 got %d", port)
    67  	}
    68  
    69  	if err := p.ReleasePort(defaultIP, "tcp", 5000); err != nil {
    70  		t.Fatal(err)
    71  	}
    72  
    73  	port, err = p.RequestPort(defaultIP, "tcp", 5000)
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  	if port != 5000 {
    78  		t.Fatalf("Expected port 5000 got %d", port)
    79  	}
    80  }
    81  
    82  func TestReleaseUnreadledPort(t *testing.T) {
    83  	p := Get()
    84  	defer resetPortAllocator()
    85  
    86  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  	if port != 5000 {
    91  		t.Fatalf("Expected port 5000 got %d", port)
    92  	}
    93  
    94  	_, err = p.RequestPort(defaultIP, "tcp", 5000)
    95  
    96  	switch err.(type) {
    97  	case ErrPortAlreadyAllocated:
    98  	default:
    99  		t.Fatalf("Expected port allocation error got %s", err)
   100  	}
   101  }
   102  
   103  func TestUnknowProtocol(t *testing.T) {
   104  	if _, err := Get().RequestPort(defaultIP, "tcpp", 0); err != ErrUnknownProtocol {
   105  		t.Fatalf("Expected error %s got %s", ErrUnknownProtocol, err)
   106  	}
   107  }
   108  
   109  func TestAllocateAllPorts(t *testing.T) {
   110  	p := Get()
   111  	defer resetPortAllocator()
   112  
   113  	for i := 0; i <= p.End-p.Begin; i++ {
   114  		port, err := p.RequestPort(defaultIP, "tcp", 0)
   115  		if err != nil {
   116  			t.Fatal(err)
   117  		}
   118  
   119  		if expected := p.Begin + i; port != expected {
   120  			t.Fatalf("Expected port %d got %d", expected, port)
   121  		}
   122  	}
   123  
   124  	if _, err := p.RequestPort(defaultIP, "tcp", 0); err != ErrAllPortsAllocated {
   125  		t.Fatalf("Expected error %s got %s", ErrAllPortsAllocated, err)
   126  	}
   127  
   128  	_, err := p.RequestPort(defaultIP, "udp", 0)
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  
   133  	// release a port in the middle and ensure we get another tcp port
   134  	port := p.Begin + 5
   135  	if err := p.ReleasePort(defaultIP, "tcp", port); err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	newPort, err := p.RequestPort(defaultIP, "tcp", 0)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	if newPort != port {
   143  		t.Fatalf("Expected port %d got %d", port, newPort)
   144  	}
   145  
   146  	// now pm.last == newPort, release it so that it's the only free port of
   147  	// the range, and ensure we get it back
   148  	if err := p.ReleasePort(defaultIP, "tcp", newPort); err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	port, err = p.RequestPort(defaultIP, "tcp", 0)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	if newPort != port {
   156  		t.Fatalf("Expected port %d got %d", newPort, port)
   157  	}
   158  }
   159  
   160  func BenchmarkAllocatePorts(b *testing.B) {
   161  	p := Get()
   162  	defer resetPortAllocator()
   163  
   164  	for i := 0; i < b.N; i++ {
   165  		for i := 0; i <= p.End-p.Begin; i++ {
   166  			port, err := p.RequestPort(defaultIP, "tcp", 0)
   167  			if err != nil {
   168  				b.Fatal(err)
   169  			}
   170  
   171  			if expected := p.Begin + i; port != expected {
   172  				b.Fatalf("Expected port %d got %d", expected, port)
   173  			}
   174  		}
   175  		if err := p.ReleaseAll(); err != nil {
   176  			b.Fatal(err)
   177  		}
   178  	}
   179  }
   180  
   181  func TestPortAllocation(t *testing.T) {
   182  	p := Get()
   183  	defer resetPortAllocator()
   184  
   185  	ip := net.ParseIP("192.168.0.1")
   186  	ip2 := net.ParseIP("192.168.0.2")
   187  	if port, err := p.RequestPort(ip, "tcp", 80); err != nil {
   188  		t.Fatal(err)
   189  	} else if port != 80 {
   190  		t.Fatalf("Acquire(80) should return 80, not %d", port)
   191  	}
   192  	port, err := p.RequestPort(ip, "tcp", 0)
   193  	if err != nil {
   194  		t.Fatal(err)
   195  	}
   196  	if port <= 0 {
   197  		t.Fatalf("Acquire(0) should return a non-zero port")
   198  	}
   199  
   200  	if _, err := p.RequestPort(ip, "tcp", port); err == nil {
   201  		t.Fatalf("Acquiring a port already in use should return an error")
   202  	}
   203  
   204  	if newPort, err := p.RequestPort(ip, "tcp", 0); err != nil {
   205  		t.Fatal(err)
   206  	} else if newPort == port {
   207  		t.Fatalf("Acquire(0) allocated the same port twice: %d", port)
   208  	}
   209  
   210  	if _, err := p.RequestPort(ip, "tcp", 80); err == nil {
   211  		t.Fatalf("Acquiring a port already in use should return an error")
   212  	}
   213  	if _, err := p.RequestPort(ip2, "tcp", 80); err != nil {
   214  		t.Fatalf("It should be possible to allocate the same port on a different interface")
   215  	}
   216  	if _, err := p.RequestPort(ip2, "tcp", 80); err == nil {
   217  		t.Fatalf("Acquiring a port already in use should return an error")
   218  	}
   219  	if err := p.ReleasePort(ip, "tcp", 80); err != nil {
   220  		t.Fatal(err)
   221  	}
   222  	if _, err := p.RequestPort(ip, "tcp", 80); err != nil {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	port, err = p.RequestPort(ip, "tcp", 0)
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  	port2, err := p.RequestPort(ip, "tcp", port+1)
   231  	if err != nil {
   232  		t.Fatal(err)
   233  	}
   234  	port3, err := p.RequestPort(ip, "tcp", 0)
   235  	if err != nil {
   236  		t.Fatal(err)
   237  	}
   238  	if port3 == port2 {
   239  		t.Fatal("Requesting a dynamic port should never allocate a used port")
   240  	}
   241  }
   242  
   243  func TestPortAllocationWithCustomRange(t *testing.T) {
   244  	p := Get()
   245  	defer resetPortAllocator()
   246  
   247  	start, end := 8081, 8082
   248  	specificPort := 8000
   249  
   250  	//get an ephemeral port.
   251  	port1, err := p.RequestPortInRange(defaultIP, "tcp", 0, 0)
   252  	if err != nil {
   253  		t.Fatal(err)
   254  	}
   255  
   256  	//request invalid ranges
   257  	if _, err := p.RequestPortInRange(defaultIP, "tcp", 0, end); err == nil {
   258  		t.Fatalf("Expected error for invalid range %d-%d", 0, end)
   259  	}
   260  	if _, err := p.RequestPortInRange(defaultIP, "tcp", start, 0); err == nil {
   261  		t.Fatalf("Expected error for invalid range %d-%d", 0, end)
   262  	}
   263  	if _, err := p.RequestPortInRange(defaultIP, "tcp", 8081, 8080); err == nil {
   264  		t.Fatalf("Expected error for invalid range %d-%d", 0, end)
   265  	}
   266  
   267  	//request a single port
   268  	port, err := p.RequestPortInRange(defaultIP, "tcp", specificPort, specificPort)
   269  	if err != nil {
   270  		t.Fatal(err)
   271  	}
   272  	if port != specificPort {
   273  		t.Fatalf("Expected port %d, got %d", specificPort, port)
   274  	}
   275  
   276  	//get a port from the range
   277  	port2, err := p.RequestPortInRange(defaultIP, "tcp", start, end)
   278  	if err != nil {
   279  		t.Fatal(err)
   280  	}
   281  	if port2 < start || port2 > end {
   282  		t.Fatalf("Expected a port between %d and %d, got %d", start, end, port2)
   283  	}
   284  	//get another ephemeral port (should be > port1)
   285  	port3, err := p.RequestPortInRange(defaultIP, "tcp", 0, 0)
   286  	if err != nil {
   287  		t.Fatal(err)
   288  	}
   289  	if port3 < port1 {
   290  		t.Fatalf("Expected new port > %d in the ephemeral range, got %d", port1, port3)
   291  	}
   292  	//get another (and in this case the only other) port from the range
   293  	port4, err := p.RequestPortInRange(defaultIP, "tcp", start, end)
   294  	if err != nil {
   295  		t.Fatal(err)
   296  	}
   297  	if port4 < start || port4 > end {
   298  		t.Fatalf("Expected a port between %d and %d, got %d", start, end, port4)
   299  	}
   300  	if port4 == port2 {
   301  		t.Fatal("Allocated the same port from a custom range")
   302  	}
   303  	//request 3rd port from the range of 2
   304  	if _, err := p.RequestPortInRange(defaultIP, "tcp", start, end); err != ErrAllPortsAllocated {
   305  		t.Fatalf("Expected error %s got %s", ErrAllPortsAllocated, err)
   306  	}
   307  }
   308  
   309  func TestNoDuplicateBPR(t *testing.T) {
   310  	p := Get()
   311  	defer resetPortAllocator()
   312  
   313  	if port, err := p.RequestPort(defaultIP, "tcp", p.Begin); err != nil {
   314  		t.Fatal(err)
   315  	} else if port != p.Begin {
   316  		t.Fatalf("Expected port %d got %d", p.Begin, port)
   317  	}
   318  
   319  	if port, err := p.RequestPort(defaultIP, "tcp", 0); err != nil {
   320  		t.Fatal(err)
   321  	} else if port == p.Begin {
   322  		t.Fatalf("Acquire(0) allocated the same port twice: %d", port)
   323  	}
   324  }
   325  
   326  func TestChangePortRange(t *testing.T) {
   327  	var tests = []struct {
   328  		begin  int
   329  		end    int
   330  		setErr error
   331  		reqRlt int
   332  	}{
   333  		{defaultPortRangeEnd + 1, defaultPortRangeEnd + 10, fmt.Errorf("begin out of range"), 0},
   334  		{defaultPortRangeStart - 10, defaultPortRangeStart - 1, fmt.Errorf("end out of range"), 0},
   335  		{defaultPortRangeEnd, defaultPortRangeStart, fmt.Errorf("out of order"), 0},
   336  		{defaultPortRangeStart + 100, defaultPortRangeEnd + 10, nil, defaultPortRangeStart + 100},
   337  		{0, 0, nil, defaultPortRangeStart}, // revert to default if no value given
   338  		{defaultPortRangeStart - 100, defaultPortRangeEnd, nil, defaultPortRangeStart + 1},
   339  	}
   340  	p := Get()
   341  	port := 0
   342  	for _, c := range tests {
   343  		t.Logf("test: port allocate range %v-%v, setErr=%v, reqPort=%v",
   344  			c.begin, c.end, c.setErr, c.reqRlt)
   345  		err := p.SetPortRange(c.begin, c.end)
   346  		if (c.setErr == nil && c.setErr != err) ||
   347  			(c.setErr != nil && err == nil) {
   348  			t.Fatalf("Unexpected set range result, expected=%v, actual=%v", c.setErr, err)
   349  		}
   350  		if err != nil {
   351  			continue
   352  		}
   353  		if port > 0 {
   354  			err := p.ReleasePort(defaultIP, "tcp", port)
   355  			if err != nil {
   356  				t.Fatalf("Releasing port %v failed, err=%v", port, err)
   357  			}
   358  		}
   359  
   360  		port, err = p.RequestPort(defaultIP, "tcp", 0)
   361  		if err != nil {
   362  			t.Fatalf("Request failed, err %v", err)
   363  		}
   364  		if port != c.reqRlt {
   365  			t.Fatalf("Incorrect port returned, expected=%v, actual=%v", c.reqRlt, port)
   366  		}
   367  	}
   368  }