github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/cli/opts/port_test.go (about) 1 package opts 2 3 import ( 4 "testing" 5 6 "github.com/docker/docker/api/types/swarm" 7 "gotest.tools/v3/assert" 8 is "gotest.tools/v3/assert/cmp" 9 ) 10 11 func TestPortOptValidSimpleSyntax(t *testing.T) { 12 testCases := []struct { 13 value string 14 expected []swarm.PortConfig 15 }{ 16 { 17 value: "80", 18 expected: []swarm.PortConfig{ 19 { 20 Protocol: "tcp", 21 TargetPort: 80, 22 PublishMode: swarm.PortConfigPublishModeIngress, 23 }, 24 }, 25 }, 26 { 27 value: "80:8080", 28 expected: []swarm.PortConfig{ 29 { 30 Protocol: "tcp", 31 TargetPort: 8080, 32 PublishedPort: 80, 33 PublishMode: swarm.PortConfigPublishModeIngress, 34 }, 35 }, 36 }, 37 { 38 value: "8080:80/tcp", 39 expected: []swarm.PortConfig{ 40 { 41 Protocol: "tcp", 42 TargetPort: 80, 43 PublishedPort: 8080, 44 PublishMode: swarm.PortConfigPublishModeIngress, 45 }, 46 }, 47 }, 48 { 49 value: "80:8080/udp", 50 expected: []swarm.PortConfig{ 51 { 52 Protocol: "udp", 53 TargetPort: 8080, 54 PublishedPort: 80, 55 PublishMode: swarm.PortConfigPublishModeIngress, 56 }, 57 }, 58 }, 59 { 60 value: "80-81:8080-8081/tcp", 61 expected: []swarm.PortConfig{ 62 { 63 Protocol: "tcp", 64 TargetPort: 8080, 65 PublishedPort: 80, 66 PublishMode: swarm.PortConfigPublishModeIngress, 67 }, 68 { 69 Protocol: "tcp", 70 TargetPort: 8081, 71 PublishedPort: 81, 72 PublishMode: swarm.PortConfigPublishModeIngress, 73 }, 74 }, 75 }, 76 { 77 value: "80-82:8080-8082/udp", 78 expected: []swarm.PortConfig{ 79 { 80 Protocol: "udp", 81 TargetPort: 8080, 82 PublishedPort: 80, 83 PublishMode: swarm.PortConfigPublishModeIngress, 84 }, 85 { 86 Protocol: "udp", 87 TargetPort: 8081, 88 PublishedPort: 81, 89 PublishMode: swarm.PortConfigPublishModeIngress, 90 }, 91 { 92 Protocol: "udp", 93 TargetPort: 8082, 94 PublishedPort: 82, 95 PublishMode: swarm.PortConfigPublishModeIngress, 96 }, 97 }, 98 }, 99 { 100 value: "80-82:8080/udp", 101 expected: []swarm.PortConfig{ 102 { 103 Protocol: "udp", 104 TargetPort: 8080, 105 PublishedPort: 80, 106 PublishMode: swarm.PortConfigPublishModeIngress, 107 }, 108 { 109 Protocol: "udp", 110 TargetPort: 8080, 111 PublishedPort: 81, 112 PublishMode: swarm.PortConfigPublishModeIngress, 113 }, 114 { 115 Protocol: "udp", 116 TargetPort: 8080, 117 PublishedPort: 82, 118 PublishMode: swarm.PortConfigPublishModeIngress, 119 }, 120 }, 121 }, 122 { 123 value: "80-80:8080/tcp", 124 expected: []swarm.PortConfig{ 125 { 126 Protocol: "tcp", 127 TargetPort: 8080, 128 PublishedPort: 80, 129 PublishMode: swarm.PortConfigPublishModeIngress, 130 }, 131 }, 132 }, 133 } 134 for _, tc := range testCases { 135 var port PortOpt 136 assert.NilError(t, port.Set(tc.value)) 137 assert.Check(t, is.Len(port.Value(), len(tc.expected))) 138 for _, expectedPortConfig := range tc.expected { 139 assertContains(t, port.Value(), expectedPortConfig) 140 } 141 } 142 } 143 144 func TestPortOptValidComplexSyntax(t *testing.T) { 145 testCases := []struct { 146 value string 147 expected []swarm.PortConfig 148 }{ 149 { 150 value: "target=80", 151 expected: []swarm.PortConfig{ 152 { 153 TargetPort: 80, 154 Protocol: "tcp", 155 PublishMode: swarm.PortConfigPublishModeIngress, 156 }, 157 }, 158 }, 159 { 160 value: "target=80,protocol=tcp", 161 expected: []swarm.PortConfig{ 162 { 163 Protocol: "tcp", 164 TargetPort: 80, 165 PublishMode: swarm.PortConfigPublishModeIngress, 166 }, 167 }, 168 }, 169 { 170 value: "target=80,published=8080,protocol=tcp", 171 expected: []swarm.PortConfig{ 172 { 173 Protocol: "tcp", 174 TargetPort: 80, 175 PublishedPort: 8080, 176 PublishMode: swarm.PortConfigPublishModeIngress, 177 }, 178 }, 179 }, 180 { 181 value: "published=80,target=8080,protocol=tcp", 182 expected: []swarm.PortConfig{ 183 { 184 Protocol: "tcp", 185 TargetPort: 8080, 186 PublishedPort: 80, 187 PublishMode: swarm.PortConfigPublishModeIngress, 188 }, 189 }, 190 }, 191 { 192 value: "target=80,published=8080,protocol=tcp,mode=host", 193 expected: []swarm.PortConfig{ 194 { 195 Protocol: "tcp", 196 TargetPort: 80, 197 PublishedPort: 8080, 198 PublishMode: "host", 199 }, 200 }, 201 }, 202 { 203 value: "target=80,published=8080,mode=host", 204 expected: []swarm.PortConfig{ 205 { 206 TargetPort: 80, 207 PublishedPort: 8080, 208 PublishMode: "host", 209 Protocol: "tcp", 210 }, 211 }, 212 }, 213 { 214 value: "target=80,published=8080,mode=ingress", 215 expected: []swarm.PortConfig{ 216 { 217 TargetPort: 80, 218 PublishedPort: 8080, 219 PublishMode: "ingress", 220 Protocol: "tcp", 221 }, 222 }, 223 }, 224 } 225 for _, tc := range testCases { 226 var port PortOpt 227 assert.NilError(t, port.Set(tc.value)) 228 assert.Check(t, is.Len(port.Value(), len(tc.expected))) 229 for _, expectedPortConfig := range tc.expected { 230 assertContains(t, port.Value(), expectedPortConfig) 231 } 232 } 233 } 234 235 func TestPortOptInvalidComplexSyntax(t *testing.T) { 236 testCases := []struct { 237 value string 238 expectedError string 239 }{ 240 { 241 value: "invalid,target=80", 242 expectedError: "invalid field", 243 }, 244 { 245 value: "invalid=field", 246 expectedError: "invalid field", 247 }, 248 { 249 value: "protocol=invalid", 250 expectedError: "invalid protocol value", 251 }, 252 { 253 value: "target=invalid", 254 expectedError: "invalid syntax", 255 }, 256 { 257 value: "published=invalid", 258 expectedError: "invalid syntax", 259 }, 260 { 261 value: "mode=invalid", 262 expectedError: "invalid publish mode value", 263 }, 264 { 265 value: "published=8080,protocol=tcp,mode=ingress", 266 expectedError: "missing mandatory field", 267 }, 268 { 269 value: `target=80,protocol="tcp,mode=ingress"`, 270 expectedError: "non-quoted-field", 271 }, 272 { 273 value: `target=80,"protocol=tcp,mode=ingress"`, 274 expectedError: "invalid protocol value", 275 }, 276 } 277 for _, tc := range testCases { 278 var port PortOpt 279 assert.ErrorContains(t, port.Set(tc.value), tc.expectedError) 280 } 281 } 282 283 func TestPortOptInvalidSimpleSyntax(t *testing.T) { 284 testCases := []struct { 285 value string 286 expectedError string 287 }{ 288 { 289 value: "9999999", 290 expectedError: "Invalid containerPort: 9999999", 291 }, 292 { 293 value: "80/xyz", 294 expectedError: "Invalid proto: xyz", 295 }, 296 { 297 value: "tcp", 298 expectedError: "Invalid containerPort: tcp", 299 }, 300 { 301 value: "udp", 302 expectedError: "Invalid containerPort: udp", 303 }, 304 { 305 value: "", 306 expectedError: "No port specified: <empty>", 307 }, 308 { 309 value: "1.1.1.1:80:80", 310 expectedError: "hostip is not supported", 311 }, 312 } 313 for _, tc := range testCases { 314 var port PortOpt 315 assert.Error(t, port.Set(tc.value), tc.expectedError) 316 } 317 } 318 319 func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) { 320 var contains = false 321 for _, portConfig := range portConfigs { 322 if portConfig == expected { 323 contains = true 324 break 325 } 326 } 327 if !contains { 328 t.Errorf("expected %v to contain %v, did not", portConfigs, expected) 329 } 330 }