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