...

Source file src/github.com/docker/cli/opts/hosts_test.go

Documentation: github.com/docker/cli/opts

     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  }
   300  

View as plain text