github.1git.de/docker/cli@v26.1.3+incompatible/opts/hosts_test.go (about) 1 package opts 2 3 import ( 4 "fmt" 5 "testing" 6 7 "gotest.tools/v3/assert" 8 is "gotest.tools/v3/assert/cmp" 9 ) 10 11 func TestParseHost(t *testing.T) { 12 invalid := []string{ 13 "something with spaces", 14 "://", 15 "unknown://", 16 "tcp://:port", 17 "tcp://invalid:port", 18 } 19 20 valid := map[string]string{ 21 "": defaultHost, 22 " ": defaultHost, 23 " ": defaultHost, 24 "fd://": "fd://", 25 "fd://something": "fd://something", 26 "tcp://host:": fmt.Sprintf("tcp://host:%s", defaultHTTPPort), 27 "tcp://": defaultTCPHost, 28 "tcp://:2375": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultHTTPPort), 29 "tcp://:2376": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultTLSHTTPPort), 30 "tcp://0.0.0.0:8080": "tcp://0.0.0.0:8080", 31 "tcp://192.168.0.0:12000": "tcp://192.168.0.0:12000", 32 "tcp://192.168:8080": "tcp://192.168:8080", 33 "tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P 34 " tcp://:7777/path ": fmt.Sprintf("tcp://%s:7777/path", defaultHTTPHost), 35 "tcp://docker.com:2375": "tcp://docker.com:2375", 36 "unix://": "unix://" + defaultUnixSocket, 37 "unix://path/to/socket": "unix://path/to/socket", 38 "npipe://": "npipe://" + defaultNamedPipe, 39 "npipe:////./pipe/foo": "npipe:////./pipe/foo", 40 } 41 42 for _, value := range invalid { 43 if _, err := ParseHost(false, value); err == nil { 44 t.Errorf("Expected an error for %v, got [nil]", value) 45 } 46 } 47 48 for value, expected := range valid { 49 if actual, err := ParseHost(false, value); err != nil || actual != expected { 50 t.Errorf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err) 51 } 52 } 53 } 54 55 func TestParseDockerDaemonHost(t *testing.T) { 56 invalids := map[string]string{ 57 "tcp:a.b.c.d": "", 58 "tcp:a.b.c.d/path": "", 59 "udp://127.0.0.1": "invalid bind address format: udp://127.0.0.1", 60 "udp://127.0.0.1:2375": "invalid bind address format: udp://127.0.0.1:2375", 61 "tcp://unix:///run/docker.sock": "invalid proto, expected tcp: unix:///run/docker.sock", 62 " tcp://:7777/path ": "invalid bind address format: tcp://:7777/path ", //nolint:gocritic // ignore mapKey: suspucious whitespace 63 "": "invalid bind address format: ", 64 } 65 valids := map[string]string{ 66 "0.0.0.1:": "tcp://0.0.0.1:2375", 67 "0.0.0.1:5555": "tcp://0.0.0.1:5555", 68 "0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path", 69 "[::1]:": "tcp://[::1]:2375", 70 "[::1]:5555/path": "tcp://[::1]:5555/path", 71 "[0:0:0:0:0:0:0:1]:": "tcp://[0:0:0:0:0:0:0:1]:2375", 72 "[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path", 73 ":6666": fmt.Sprintf("tcp://%s:6666", defaultHTTPHost), 74 ":6666/path": fmt.Sprintf("tcp://%s:6666/path", defaultHTTPHost), 75 "tcp://": defaultTCPHost, 76 "tcp://:7777": fmt.Sprintf("tcp://%s:7777", defaultHTTPHost), 77 "tcp://:7777/path": fmt.Sprintf("tcp://%s:7777/path", defaultHTTPHost), 78 "unix:///run/docker.sock": "unix:///run/docker.sock", 79 "unix://": "unix://" + defaultUnixSocket, 80 "fd://": "fd://", 81 "fd://something": "fd://something", 82 "localhost:": "tcp://localhost:2375", 83 "localhost:5555": "tcp://localhost:5555", 84 "localhost:5555/path": "tcp://localhost:5555/path", 85 } 86 for invalidAddr, expectedError := range invalids { 87 if addr, err := parseDockerDaemonHost(invalidAddr); err == nil || expectedError != "" && err.Error() != expectedError { 88 t.Errorf("tcp %v address expected error %q return, got %q and addr %v", invalidAddr, expectedError, err, addr) 89 } 90 } 91 for validAddr, expectedAddr := range valids { 92 if addr, err := parseDockerDaemonHost(validAddr); err != nil || addr != expectedAddr { 93 t.Errorf("%v -> expected %v, got (%v) addr (%v)", validAddr, expectedAddr, err, addr) 94 } 95 } 96 } 97 98 func TestParseTCP(t *testing.T) { 99 defaultHTTPHost := "tcp://127.0.0.1:2376" 100 invalids := map[string]string{ 101 "tcp:a.b.c.d": "", 102 "tcp:a.b.c.d/path": "", 103 "udp://127.0.0.1": "invalid proto, expected tcp: udp://127.0.0.1", 104 "udp://127.0.0.1:2375": "invalid proto, expected tcp: udp://127.0.0.1:2375", 105 } 106 valids := map[string]string{ 107 "": defaultHTTPHost, 108 "tcp://": defaultHTTPHost, 109 "0.0.0.1:": "tcp://0.0.0.1:2376", 110 "0.0.0.1:5555": "tcp://0.0.0.1:5555", 111 "0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path", 112 ":6666": "tcp://127.0.0.1:6666", 113 ":6666/path": "tcp://127.0.0.1:6666/path", 114 "tcp://:7777": "tcp://127.0.0.1:7777", 115 "tcp://:7777/path": "tcp://127.0.0.1:7777/path", 116 "[::1]:": "tcp://[::1]:2376", 117 "[::1]:5555": "tcp://[::1]:5555", 118 "[::1]:5555/path": "tcp://[::1]:5555/path", 119 "[0:0:0:0:0:0:0:1]:": "tcp://[0:0:0:0:0:0:0:1]:2376", 120 "[0:0:0:0:0:0:0:1]:5555": "tcp://[0:0:0:0:0:0:0:1]:5555", 121 "[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path", 122 "localhost:": "tcp://localhost:2376", 123 "localhost:5555": "tcp://localhost:5555", 124 "localhost:5555/path": "tcp://localhost:5555/path", 125 } 126 for invalidAddr, expectedError := range invalids { 127 if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || expectedError != "" && err.Error() != expectedError { 128 t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr) 129 } 130 } 131 for validAddr, expectedAddr := range valids { 132 if addr, err := ParseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr { 133 t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr) 134 } 135 } 136 } 137 138 func TestParseInvalidUnixAddrInvalid(t *testing.T) { 139 if _, err := parseSimpleProtoAddr("unix", "tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "invalid proto, expected unix: tcp://127.0.0.1" { 140 t.Fatalf("Expected an error, got %v", err) 141 } 142 if _, err := parseSimpleProtoAddr("unix", "unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "invalid proto, expected unix: tcp://127.0.0.1" { 143 t.Fatalf("Expected an error, got %v", err) 144 } 145 if v, err := parseSimpleProtoAddr("unix", "", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" { 146 t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock") 147 } 148 } 149 150 func TestValidateExtraHosts(t *testing.T) { 151 tests := []struct { 152 doc string 153 input string 154 expectedOut string // Expect output==input if not set. 155 expectedErr string // Expect success if not set. 156 }{ 157 { 158 doc: "IPv4, colon sep", 159 input: `myhost:192.168.0.1`, 160 }, 161 { 162 doc: "IPv4, eq sep", 163 input: `myhost=192.168.0.1`, 164 expectedOut: `myhost:192.168.0.1`, 165 }, 166 { 167 doc: "Weird but permitted, IPv4 with brackets", 168 input: `myhost=[192.168.0.1]`, 169 expectedOut: `myhost:192.168.0.1`, 170 }, 171 { 172 doc: "Host and domain", 173 input: `host.and.domain.invalid:10.0.2.1`, 174 }, 175 { 176 doc: "IPv6, colon sep", 177 input: `anipv6host:2003:ab34:e::1`, 178 }, 179 { 180 doc: "IPv6, colon sep, brackets", 181 input: `anipv6host:[2003:ab34:e::1]`, 182 expectedOut: `anipv6host:2003:ab34:e::1`, 183 }, 184 { 185 doc: "IPv6, eq sep, brackets", 186 input: `anipv6host=[2003:ab34:e::1]`, 187 expectedOut: `anipv6host:2003:ab34:e::1`, 188 }, 189 { 190 doc: "IPv6 localhost, colon sep", 191 input: `ipv6local:::1`, 192 }, 193 { 194 doc: "IPv6 localhost, eq sep", 195 input: `ipv6local=::1`, 196 expectedOut: `ipv6local:::1`, 197 }, 198 { 199 doc: "IPv6 localhost, eq sep, brackets", 200 input: `ipv6local=[::1]`, 201 expectedOut: `ipv6local:::1`, 202 }, 203 { 204 doc: "IPv6 localhost, non-canonical, colon sep", 205 input: `ipv6local:0:0:0:0:0:0:0:1`, 206 }, 207 { 208 doc: "IPv6 localhost, non-canonical, eq sep", 209 input: `ipv6local=0:0:0:0:0:0:0:1`, 210 expectedOut: `ipv6local:0:0:0:0:0:0:0:1`, 211 }, 212 { 213 doc: "IPv6 localhost, non-canonical, eq sep, brackets", 214 input: `ipv6local=[0:0:0:0:0:0:0:1]`, 215 expectedOut: `ipv6local:0:0:0:0:0:0:0:1`, 216 }, 217 { 218 doc: "host-gateway special case, colon sep", 219 input: `host.docker.internal:host-gateway`, 220 }, 221 { 222 doc: "host-gateway special case, eq sep", 223 input: `host.docker.internal=host-gateway`, 224 expectedOut: `host.docker.internal:host-gateway`, 225 }, 226 { 227 doc: "Bad address, colon sep", 228 input: `myhost:192.notanipaddress.1`, 229 expectedErr: `invalid IP address in add-host: "192.notanipaddress.1"`, 230 }, 231 { 232 doc: "Bad address, eq sep", 233 input: `myhost=192.notanipaddress.1`, 234 expectedErr: `invalid IP address in add-host: "192.notanipaddress.1"`, 235 }, 236 { 237 doc: "No sep", 238 input: `thathost-nosemicolon10.0.0.1`, 239 expectedErr: `bad format for add-host: "thathost-nosemicolon10.0.0.1"`, 240 }, 241 { 242 doc: "Bad IPv6", 243 input: `anipv6host:::::1`, 244 expectedErr: `invalid IP address in add-host: "::::1"`, 245 }, 246 { 247 doc: "Bad IPv6, trailing colons", 248 input: `ipv6local:::0::`, 249 expectedErr: `invalid IP address in add-host: "::0::"`, 250 }, 251 { 252 doc: "Bad IPv6, missing close bracket", 253 input: `ipv6addr=[::1`, 254 expectedErr: `invalid IP address in add-host: "[::1"`, 255 }, 256 { 257 doc: "Bad IPv6, missing open bracket", 258 input: `ipv6addr=::1]`, 259 expectedErr: `invalid IP address in add-host: "::1]"`, 260 }, 261 { 262 doc: "Missing address, colon sep", 263 input: `myhost.invalid:`, 264 expectedErr: `invalid IP address in add-host: ""`, 265 }, 266 { 267 doc: "Missing address, eq sep", 268 input: `myhost.invalid=`, 269 expectedErr: `invalid IP address in add-host: ""`, 270 }, 271 { 272 doc: "IPv6 localhost, bad name", 273 input: `:=::1`, 274 expectedErr: `bad format for add-host: ":=::1"`, 275 }, 276 { 277 doc: "No input", 278 input: ``, 279 expectedErr: `bad format for add-host: ""`, 280 }, 281 } 282 283 for _, tc := range tests { 284 tc := tc 285 if tc.expectedOut == "" { 286 tc.expectedOut = tc.input 287 } 288 t.Run(tc.input, func(t *testing.T) { 289 actualOut, actualErr := ValidateExtraHost(tc.input) 290 if tc.expectedErr == "" { 291 assert.Check(t, is.Equal(tc.expectedOut, actualOut)) 292 assert.NilError(t, actualErr) 293 } else { 294 assert.Check(t, actualOut == "") 295 assert.Check(t, is.Error(actualErr, tc.expectedErr)) 296 } 297 }) 298 } 299 }