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 }