github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/portallocator/portallocator_test.go (about)

     1  package portallocator
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"testing"
     7  
     8  	_ "github.com/docker/libnetwork/testutils"
     9  )
    10  
    11  func resetPortAllocator() {
    12  	instance = newInstance()
    13  }
    14  
    15  func TestRequestNewPort(t *testing.T) {
    16  	p := Get()
    17  	defer resetPortAllocator()
    18  
    19  	port, err := p.RequestPort(defaultIP, "tcp", 0)
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  
    24  	if expected := p.Begin; port != expected {
    25  		t.Fatalf("Expected port %d got %d", expected, port)
    26  	}
    27  }
    28  
    29  func TestRequestSpecificPort(t *testing.T) {
    30  	p := Get()
    31  	defer resetPortAllocator()
    32  
    33  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  
    38  	if port != 5000 {
    39  		t.Fatalf("Expected port 5000 got %d", port)
    40  	}
    41  }
    42  
    43  func TestReleasePort(t *testing.T) {
    44  	p := Get()
    45  
    46  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  	if port != 5000 {
    51  		t.Fatalf("Expected port 5000 got %d", port)
    52  	}
    53  
    54  	if err := p.ReleasePort(defaultIP, "tcp", 5000); err != nil {
    55  		t.Fatal(err)
    56  	}
    57  }
    58  
    59  func TestReuseReleasedPort(t *testing.T) {
    60  	p := Get()
    61  	defer resetPortAllocator()
    62  
    63  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    64  	if err != nil {
    65  		t.Fatal(err)
    66  	}
    67  	if port != 5000 {
    68  		t.Fatalf("Expected port 5000 got %d", port)
    69  	}
    70  
    71  	if err := p.ReleasePort(defaultIP, "tcp", 5000); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	port, err = p.RequestPort(defaultIP, "tcp", 5000)
    76  	if err != nil {
    77  		t.Fatal(err)
    78  	}
    79  	if port != 5000 {
    80  		t.Fatalf("Expected port 5000 got %d", port)
    81  	}
    82  }
    83  
    84  func TestReleaseUnreadledPort(t *testing.T) {
    85  	p := Get()
    86  	defer resetPortAllocator()
    87  
    88  	port, err := p.RequestPort(defaultIP, "tcp", 5000)
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  	if port != 5000 {
    93  		t.Fatalf("Expected port 5000 got %d", port)
    94  	}
    95  
    96  	_, err = p.RequestPort(defaultIP, "tcp", 5000)
    97  
    98  	switch err.(type) {
    99  	case ErrPortAlreadyAllocated:
   100  	default:
   101  		t.Fatalf("Expected port allocation error got %s", err)
   102  	}
   103  }
   104  
   105  func TestUnknowProtocol(t *testing.T) {
   106  	if _, err := Get().RequestPort(defaultIP, "tcpp", 0); err != ErrUnknownProtocol {
   107  		t.Fatalf("Expected error %s got %s", ErrUnknownProtocol, err)
   108  	}
   109  }
   110  
   111  func TestAllocateAllPorts(t *testing.T) {
   112  	p := Get()
   113  	defer resetPortAllocator()
   114  
   115  	for i := 0; i <= p.End-p.Begin; i++ {
   116  		port, err := p.RequestPort(defaultIP, "tcp", 0)
   117  		if err != nil {
   118  			t.Fatal(err)
   119  		}
   120  
   121  		if expected := p.Begin + i; port != expected {
   122  			t.Fatalf("Expected port %d got %d", expected, port)
   123  		}
   124  	}
   125  
   126  	if _, err := p.RequestPort(defaultIP, "tcp", 0); err != ErrAllPortsAllocated {
   127  		t.Fatalf("Expected error %s got %s", ErrAllPortsAllocated, err)
   128  	}
   129  
   130  	_, err := p.RequestPort(defaultIP, "udp", 0)
   131  	if err != nil {
   132  		t.Fatal(err)
   133  	}
   134  
   135  	// release a port in the middle and ensure we get another tcp port
   136  	port := p.Begin + 5
   137  	if err := p.ReleasePort(defaultIP, "tcp", port); err != nil {
   138  		t.Fatal(err)
   139  	}
   140  	newPort, err := p.RequestPort(defaultIP, "tcp", 0)
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	if newPort != port {
   145  		t.Fatalf("Expected port %d got %d", port, newPort)
   146  	}
   147  
   148  	// now pm.last == newPort, release it so that it's the only free port of
   149  	// the range, and ensure we get it back
   150  	if err := p.ReleasePort(defaultIP, "tcp", newPort); err != nil {
   151  		t.Fatal(err)
   152  	}
   153  	port, err = p.RequestPort(defaultIP, "tcp", 0)
   154  	if err != nil {
   155  		t.Fatal(err)
   156  	}
   157  	if newPort != port {
   158  		t.Fatalf("Expected port %d got %d", newPort, port)
   159  	}
   160  }
   161  
   162  func BenchmarkAllocatePorts(b *testing.B) {
   163  	p := Get()
   164  	defer resetPortAllocator()
   165  
   166  	for i := 0; i < b.N; i++ {
   167  		for i := 0; i <= p.End-p.Begin; i++ {
   168  			port, err := p.RequestPort(defaultIP, "tcp", 0)
   169  			if err != nil {
   170  				b.Fatal(err)
   171  			}
   172  
   173  			if expected := p.Begin + i; port != expected {
   174  				b.Fatalf("Expected port %d got %d", expected, port)
   175  			}
   176  		}
   177  		p.ReleaseAll()
   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  }