github.com/shiroyuki/docker@v1.9.0/pkg/parsers/parsers_test.go (about) 1 package parsers 2 3 import ( 4 "reflect" 5 "runtime" 6 "strings" 7 "testing" 8 ) 9 10 func TestParseDockerDaemonHost(t *testing.T) { 11 var ( 12 defaultHTTPHost = "tcp://localhost:2375" 13 defaultHTTPSHost = "tcp://localhost:2376" 14 defaultUnix = "/var/run/docker.sock" 15 defaultHOST = "unix:///var/run/docker.sock" 16 ) 17 if runtime.GOOS == "windows" { 18 defaultHOST = defaultHTTPHost 19 } 20 invalids := map[string]string{ 21 "0.0.0.0": "Invalid bind address format: 0.0.0.0", 22 "tcp:a.b.c.d": "Invalid bind address format: tcp:a.b.c.d", 23 "tcp:a.b.c.d/path": "Invalid bind address format: tcp:a.b.c.d/path", 24 "udp://127.0.0.1": "Invalid bind address format: udp://127.0.0.1", 25 "udp://127.0.0.1:2375": "Invalid bind address format: udp://127.0.0.1:2375", 26 "tcp://unix:///run/docker.sock": "Invalid bind address format: unix", 27 "tcp": "Invalid bind address format: tcp", 28 "unix": "Invalid bind address format: unix", 29 "fd": "Invalid bind address format: fd", 30 } 31 valids := map[string]string{ 32 "0.0.0.1:": "tcp://0.0.0.1:2375", 33 "0.0.0.1:5555": "tcp://0.0.0.1:5555", 34 "0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path", 35 ":6666": "tcp://localhost:6666", 36 ":6666/path": "tcp://localhost:6666/path", 37 "": defaultHOST, 38 " ": defaultHOST, 39 " ": defaultHOST, 40 "tcp://": defaultHTTPHost, 41 "tcp://:7777": "tcp://localhost:7777", 42 "tcp://:7777/path": "tcp://localhost:7777/path", 43 " tcp://:7777/path ": "tcp://localhost:7777/path", 44 "unix:///run/docker.sock": "unix:///run/docker.sock", 45 "unix://": "unix:///var/run/docker.sock", 46 "fd://": "fd://", 47 "fd://something": "fd://something", 48 "localhost:": "tcp://localhost:2375", 49 "localhost:5555": "tcp://localhost:5555", 50 "localhost:5555/path": "tcp://localhost:5555/path", 51 } 52 for invalidAddr, expectedError := range invalids { 53 if addr, err := ParseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", invalidAddr); err == nil || err.Error() != expectedError { 54 t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr) 55 } 56 } 57 for validAddr, expectedAddr := range valids { 58 if addr, err := ParseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", validAddr); err != nil || addr != expectedAddr { 59 t.Errorf("%v -> expected %v, got (%v) addr (%v)", validAddr, expectedAddr, err, addr) 60 } 61 } 62 } 63 64 func TestParseTCP(t *testing.T) { 65 var ( 66 defaultHTTPHost = "tcp://127.0.0.1:2376" 67 ) 68 invalids := map[string]string{ 69 "0.0.0.0": "Invalid bind address format: 0.0.0.0", 70 "tcp:a.b.c.d": "Invalid bind address format: tcp:a.b.c.d", 71 "tcp:a.b.c.d/path": "Invalid bind address format: tcp:a.b.c.d/path", 72 "udp://127.0.0.1": "Invalid proto, expected tcp: udp://127.0.0.1", 73 "udp://127.0.0.1:2375": "Invalid proto, expected tcp: udp://127.0.0.1:2375", 74 } 75 valids := map[string]string{ 76 "": defaultHTTPHost, 77 "tcp://": defaultHTTPHost, 78 "0.0.0.1:": "tcp://0.0.0.1:2376", 79 "0.0.0.1:5555": "tcp://0.0.0.1:5555", 80 "0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path", 81 ":6666": "tcp://127.0.0.1:6666", 82 ":6666/path": "tcp://127.0.0.1:6666/path", 83 "tcp://:7777": "tcp://127.0.0.1:7777", 84 "tcp://:7777/path": "tcp://127.0.0.1:7777/path", 85 } 86 for invalidAddr, expectedError := range invalids { 87 if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || err.Error() != expectedError { 88 t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr) 89 } 90 } 91 for validAddr, expectedAddr := range valids { 92 if addr, err := ParseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr { 93 t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr) 94 } 95 } 96 } 97 98 func TestParseInvalidUnixAddrInvalid(t *testing.T) { 99 if _, err := ParseUnixAddr("tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" { 100 t.Fatalf("Expected an error, got %v", err) 101 } 102 if _, err := ParseUnixAddr("unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" { 103 t.Fatalf("Expected an error, got %v", err) 104 } 105 if v, err := ParseUnixAddr("", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" { 106 t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock") 107 } 108 } 109 110 func TestParseRepositoryTag(t *testing.T) { 111 if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" { 112 t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag) 113 } 114 if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" { 115 t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag) 116 } 117 if repo, digest := ParseRepositoryTag("root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); repo != "root" || digest != "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" { 118 t.Errorf("Expected repo: '%s' and digest: '%s', got '%s' and '%s'", "root", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", repo, digest) 119 } 120 if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" { 121 t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag) 122 } 123 if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" { 124 t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag) 125 } 126 if repo, digest := ParseRepositoryTag("user/repo@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); repo != "user/repo" || digest != "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" { 127 t.Errorf("Expected repo: '%s' and digest: '%s', got '%s' and '%s'", "user/repo", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", repo, digest) 128 } 129 if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" { 130 t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag) 131 } 132 if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" { 133 t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag) 134 } 135 if repo, digest := ParseRepositoryTag("url:5000/repo@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); repo != "url:5000/repo" || digest != "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" { 136 t.Errorf("Expected repo: '%s' and digest: '%s', got '%s' and '%s'", "url:5000/repo", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", repo, digest) 137 } 138 } 139 140 func TestParseKeyValueOpt(t *testing.T) { 141 invalids := map[string]string{ 142 "": "Unable to parse key/value option: ", 143 "key": "Unable to parse key/value option: key", 144 } 145 for invalid, expectedError := range invalids { 146 if _, _, err := ParseKeyValueOpt(invalid); err == nil || err.Error() != expectedError { 147 t.Fatalf("Expected error %v for %v, got %v", expectedError, invalid, err) 148 } 149 } 150 valids := map[string][]string{ 151 "key=value": {"key", "value"}, 152 " key = value ": {"key", "value"}, 153 "key=value1=value2": {"key", "value1=value2"}, 154 " key = value1 = value2 ": {"key", "value1 = value2"}, 155 } 156 for valid, expectedKeyValue := range valids { 157 key, value, err := ParseKeyValueOpt(valid) 158 if err != nil { 159 t.Fatal(err) 160 } 161 if key != expectedKeyValue[0] || value != expectedKeyValue[1] { 162 t.Fatalf("Expected {%v: %v} got {%v: %v}", expectedKeyValue[0], expectedKeyValue[1], key, value) 163 } 164 } 165 } 166 167 func TestParsePortRange(t *testing.T) { 168 if start, end, err := ParsePortRange("8000-8080"); err != nil || start != 8000 || end != 8080 { 169 t.Fatalf("Error: %s or Expecting {start,end} values {8000,8080} but found {%d,%d}.", err, start, end) 170 } 171 } 172 173 func TestParsePortRangeEmpty(t *testing.T) { 174 if _, _, err := ParsePortRange(""); err == nil || err.Error() != "Empty string specified for ports." { 175 t.Fatalf("Expected error 'Empty string specified for ports.', got %v", err) 176 } 177 } 178 179 func TestParsePortRangeWithNoRange(t *testing.T) { 180 start, end, err := ParsePortRange("8080") 181 if err != nil { 182 t.Fatal(err) 183 } 184 if start != 8080 || end != 8080 { 185 t.Fatalf("Expected start and end to be the same and equal to 8080, but were %v and %v", start, end) 186 } 187 } 188 189 func TestParsePortRangeIncorrectRange(t *testing.T) { 190 if _, _, err := ParsePortRange("9000-8080"); err == nil || !strings.Contains(err.Error(), "Invalid range specified for the Port") { 191 t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err) 192 } 193 } 194 195 func TestParsePortRangeIncorrectEndRange(t *testing.T) { 196 if _, _, err := ParsePortRange("8000-a"); err == nil || !strings.Contains(err.Error(), "invalid syntax") { 197 t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err) 198 } 199 200 if _, _, err := ParsePortRange("8000-30a"); err == nil || !strings.Contains(err.Error(), "invalid syntax") { 201 t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err) 202 } 203 } 204 205 func TestParsePortRangeIncorrectStartRange(t *testing.T) { 206 if _, _, err := ParsePortRange("a-8000"); err == nil || !strings.Contains(err.Error(), "invalid syntax") { 207 t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err) 208 } 209 210 if _, _, err := ParsePortRange("30a-8000"); err == nil || !strings.Contains(err.Error(), "invalid syntax") { 211 t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err) 212 } 213 } 214 215 func TestParseLink(t *testing.T) { 216 name, alias, err := ParseLink("name:alias") 217 if err != nil { 218 t.Fatalf("Expected not to error out on a valid name:alias format but got: %v", err) 219 } 220 if name != "name" { 221 t.Fatalf("Link name should have been name, got %s instead", name) 222 } 223 if alias != "alias" { 224 t.Fatalf("Link alias should have been alias, got %s instead", alias) 225 } 226 // short format definition 227 name, alias, err = ParseLink("name") 228 if err != nil { 229 t.Fatalf("Expected not to error out on a valid name only format but got: %v", err) 230 } 231 if name != "name" { 232 t.Fatalf("Link name should have been name, got %s instead", name) 233 } 234 if alias != "name" { 235 t.Fatalf("Link alias should have been name, got %s instead", alias) 236 } 237 // empty string link definition is not allowed 238 if _, _, err := ParseLink(""); err == nil || !strings.Contains(err.Error(), "empty string specified for links") { 239 t.Fatalf("Expected error 'empty string specified for links' but got: %v", err) 240 } 241 // more than two colons are not allowed 242 if _, _, err := ParseLink("link:alias:wrong"); err == nil || !strings.Contains(err.Error(), "bad format for links: link:alias:wrong") { 243 t.Fatalf("Expected error 'bad format for links: link:alias:wrong' but got: %v", err) 244 } 245 } 246 247 func TestParseUintList(t *testing.T) { 248 valids := map[string]map[int]bool{ 249 "": {}, 250 "7": {7: true}, 251 "1-6": {1: true, 2: true, 3: true, 4: true, 5: true, 6: true}, 252 "0-7": {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true}, 253 "0,3-4,7,8-10": {0: true, 3: true, 4: true, 7: true, 8: true, 9: true, 10: true}, 254 "0-0,0,1-4": {0: true, 1: true, 2: true, 3: true, 4: true}, 255 "03,1-3": {1: true, 2: true, 3: true}, 256 "3,2,1": {1: true, 2: true, 3: true}, 257 "0-2,3,1": {0: true, 1: true, 2: true, 3: true}, 258 } 259 for k, v := range valids { 260 out, err := ParseUintList(k) 261 if err != nil { 262 t.Fatalf("Expected not to fail, got %v", err) 263 } 264 if !reflect.DeepEqual(out, v) { 265 t.Fatalf("Expected %v, got %v", v, out) 266 } 267 } 268 269 invalids := []string{ 270 "this", 271 "1--", 272 "1-10,,10", 273 "10-1", 274 "-1", 275 "-1,0", 276 } 277 for _, v := range invalids { 278 if out, err := ParseUintList(v); err == nil { 279 t.Fatalf("Expected failure with %s but got %v", v, out) 280 } 281 } 282 }