github.com/docker/docker-ce@v17.12.1-ce-rc2+incompatible/components/cli/opts/port_test.go (about) 1 package opts 2 3 import ( 4 "testing" 5 6 "github.com/docker/cli/internal/test/testutil" 7 "github.com/docker/docker/api/types/swarm" 8 "github.com/stretchr/testify/assert" 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 for _, tc := range testCases { 101 var port PortOpt 102 assert.NoError(t, port.Set(tc.value)) 103 assert.Len(t, port.Value(), len(tc.expected)) 104 for _, expectedPortConfig := range tc.expected { 105 assertContains(t, port.Value(), expectedPortConfig) 106 } 107 } 108 } 109 110 func TestPortOptValidComplexSyntax(t *testing.T) { 111 testCases := []struct { 112 value string 113 expected []swarm.PortConfig 114 }{ 115 { 116 value: "target=80", 117 expected: []swarm.PortConfig{ 118 { 119 TargetPort: 80, 120 Protocol: "tcp", 121 PublishMode: swarm.PortConfigPublishModeIngress, 122 }, 123 }, 124 }, 125 { 126 value: "target=80,protocol=tcp", 127 expected: []swarm.PortConfig{ 128 { 129 Protocol: "tcp", 130 TargetPort: 80, 131 PublishMode: swarm.PortConfigPublishModeIngress, 132 }, 133 }, 134 }, 135 { 136 value: "target=80,published=8080,protocol=tcp", 137 expected: []swarm.PortConfig{ 138 { 139 Protocol: "tcp", 140 TargetPort: 80, 141 PublishedPort: 8080, 142 PublishMode: swarm.PortConfigPublishModeIngress, 143 }, 144 }, 145 }, 146 { 147 value: "published=80,target=8080,protocol=tcp", 148 expected: []swarm.PortConfig{ 149 { 150 Protocol: "tcp", 151 TargetPort: 8080, 152 PublishedPort: 80, 153 PublishMode: swarm.PortConfigPublishModeIngress, 154 }, 155 }, 156 }, 157 { 158 value: "target=80,published=8080,protocol=tcp,mode=host", 159 expected: []swarm.PortConfig{ 160 { 161 Protocol: "tcp", 162 TargetPort: 80, 163 PublishedPort: 8080, 164 PublishMode: "host", 165 }, 166 }, 167 }, 168 { 169 value: "target=80,published=8080,mode=host", 170 expected: []swarm.PortConfig{ 171 { 172 TargetPort: 80, 173 PublishedPort: 8080, 174 PublishMode: "host", 175 Protocol: "tcp", 176 }, 177 }, 178 }, 179 { 180 value: "target=80,published=8080,mode=ingress", 181 expected: []swarm.PortConfig{ 182 { 183 TargetPort: 80, 184 PublishedPort: 8080, 185 PublishMode: "ingress", 186 Protocol: "tcp", 187 }, 188 }, 189 }, 190 } 191 for _, tc := range testCases { 192 var port PortOpt 193 assert.NoError(t, port.Set(tc.value)) 194 assert.Len(t, port.Value(), len(tc.expected)) 195 for _, expectedPortConfig := range tc.expected { 196 assertContains(t, port.Value(), expectedPortConfig) 197 } 198 } 199 } 200 201 func TestPortOptInvalidComplexSyntax(t *testing.T) { 202 testCases := []struct { 203 value string 204 expectedError string 205 }{ 206 { 207 value: "invalid,target=80", 208 expectedError: "invalid field", 209 }, 210 { 211 value: "invalid=field", 212 expectedError: "invalid field", 213 }, 214 { 215 value: "protocol=invalid", 216 expectedError: "invalid protocol value", 217 }, 218 { 219 value: "target=invalid", 220 expectedError: "invalid syntax", 221 }, 222 { 223 value: "published=invalid", 224 expectedError: "invalid syntax", 225 }, 226 { 227 value: "mode=invalid", 228 expectedError: "invalid publish mode value", 229 }, 230 { 231 value: "published=8080,protocol=tcp,mode=ingress", 232 expectedError: "missing mandatory field", 233 }, 234 { 235 value: `target=80,protocol="tcp,mode=ingress"`, 236 expectedError: "non-quoted-field", 237 }, 238 { 239 value: `target=80,"protocol=tcp,mode=ingress"`, 240 expectedError: "invalid protocol value", 241 }, 242 } 243 for _, tc := range testCases { 244 var port PortOpt 245 testutil.ErrorContains(t, port.Set(tc.value), tc.expectedError) 246 } 247 } 248 249 func TestPortOptInvalidSimpleSyntax(t *testing.T) { 250 testCases := []struct { 251 value string 252 expectedError string 253 }{ 254 { 255 value: "9999999", 256 expectedError: "Invalid containerPort: 9999999", 257 }, 258 { 259 value: "80/xyz", 260 expectedError: "Invalid proto: xyz", 261 }, 262 { 263 value: "tcp", 264 expectedError: "Invalid containerPort: tcp", 265 }, 266 { 267 value: "udp", 268 expectedError: "Invalid containerPort: udp", 269 }, 270 { 271 value: "", 272 expectedError: "No port specified: <empty>", 273 }, 274 { 275 value: "1.1.1.1:80:80", 276 expectedError: "hostip is not supported", 277 }, 278 } 279 for _, tc := range testCases { 280 var port PortOpt 281 assert.EqualError(t, port.Set(tc.value), tc.expectedError) 282 } 283 } 284 285 func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) { 286 var contains = false 287 for _, portConfig := range portConfigs { 288 if portConfig == expected { 289 contains = true 290 break 291 } 292 } 293 if !contains { 294 t.Errorf("expected %v to contain %v, did not", portConfigs, expected) 295 } 296 }