@@ -9,59 +9,132 @@ import (
99
1010func TestParseURL (t * testing.T ) {
1111 testCases := []struct {
12+ doc string
1213 url string
14+ remoteCommand []string
1315 expectedArgs []string
1416 expectedError string
17+ expectedSpec Spec
1518 }{
1619 {
17- url : "ssh://foo" ,
20+ doc : "bare ssh URL" ,
21+ url : "ssh://example.com" ,
1822 expectedArgs : []string {
19- "--" , "foo" ,
23+ "--" , "example.com" ,
24+ },
25+ expectedSpec : Spec {
26+ Host : "example.com" ,
2027 },
2128 },
2229 {
23- url : "ssh://me@foo:10022" ,
30+ doc : "bare ssh URL and remote command" ,
31+ url : "ssh://example.com" ,
32+ remoteCommand : []string {
33+ "docker" , "system" , "dial-stdio" ,
34+ },
2435 expectedArgs : []string {
25- "-l" , "me" ,
26- "-p" , "10022" ,
27- "--" , "foo" ,
36+ "--" , "example.com" ,
37+ "docker" , "system" , "dial-stdio" ,
38+ },
39+ expectedSpec : Spec {
40+ Host : "example.com" ,
2841 },
2942 },
3043 {
31- url : "ssh://me:passw0rd@foo" ,
32- expectedError : "plain-text password is not supported" ,
44+ doc : "ssh URL with path and remote command and flag" ,
45+ url : "ssh://example.com/var/run/docker.sock" ,
46+ remoteCommand : []string {
47+ "docker" , "--host" , "unix:///var/run/docker.sock" , "system" , "dial-stdio" ,
48+ },
49+ expectedArgs : []string {
50+ "--" , "example.com" ,
51+ "docker" , "--host" , "unix:///var/run/docker.sock" , "system" , "dial-stdio" ,
52+ },
53+ expectedSpec : Spec {
54+ Host : "example.com" ,
55+ Path : "/var/run/docker.sock" ,
56+ },
3357 },
3458 {
35- url : "ssh://foo/bar" ,
59+ doc : "ssh URL with username and port" ,
60+ url : "ssh://me@example.com:10022" ,
3661 expectedArgs : []string {
37- "--" , "foo" ,
62+ "-l" , "me" ,
63+ "-p" , "10022" ,
64+ "--" , "example.com" ,
65+ },
66+ expectedSpec : Spec {
67+ User : "me" ,
68+ Host : "example.com" ,
69+ Port : "10022" ,
3870 },
3971 },
4072 {
41- url : "ssh://foo?bar" ,
42- expectedError : `extra query after the host: "bar"` ,
73+ doc : "ssh URL with username, port, and path" ,
74+ url : "ssh://me@example.com:10022/var/run/docker.sock" ,
75+ expectedArgs : []string {
76+ "-l" , "me" ,
77+ "-p" , "10022" ,
78+ "--" , "example.com" ,
79+ },
80+ expectedSpec : Spec {
81+ User : "me" ,
82+ Host : "example.com" ,
83+ Port : "10022" ,
84+ Path : "/var/run/docker.sock" ,
85+ },
86+ },
87+ {
88+ doc : "malformed URL" ,
89+ url : "malformed %%url" ,
90+ expectedError : `invalid ssh URL: invalid URL escape "%%u"` ,
91+ },
92+ {
93+ doc : "URL missing scheme" ,
94+ url : "no-scheme.example.com" ,
95+ expectedError : "invalid ssh URL: no scheme provided" ,
4396 },
4497 {
45- url : "ssh://foo#bar" ,
46- expectedError : `extra fragment after the host: "bar"` ,
98+ doc : "invalid URL with password" ,
99+ url : "ssh://me:passw0rd@example.com" ,
100+ expectedError : "invalid ssh URL: plain-text password is not supported" ,
47101 },
48102 {
103+ doc : "invalid URL with query parameter" ,
104+ url : "ssh://example.com?foo=bar&bar=baz" ,
105+ expectedError : `invalid ssh URL: query parameters are not allowed: "foo=bar&bar=baz"` ,
106+ },
107+ {
108+ doc : "invalid URL with fragment" ,
109+ url : "ssh://example.com#bar" ,
110+ expectedError : `invalid ssh URL: fragments are not allowed: "bar"` ,
111+ },
112+ {
113+ doc : "invalid URL without hostname" ,
49114 url : "ssh://" ,
50- expectedError : "no host specified" ,
115+ expectedError : "invalid ssh URL: hostname is empty" ,
116+ },
117+ {
118+ url : "ssh:///no-hostname" ,
119+ expectedError : "invalid ssh URL: hostname is empty" ,
51120 },
52121 {
53- url : "foo://bar" ,
54- expectedError : `expected scheme ssh, got "foo"` ,
122+ doc : "invalid URL with unsupported scheme" ,
123+ url : "https://example.com" ,
124+ expectedError : `invalid ssh URL: incorrect scheme: https` ,
55125 },
56126 }
57127 for _ , tc := range testCases {
58- t .Run (tc .url , func (t * testing.T ) {
128+ t .Run (tc .doc , func (t * testing.T ) {
59129 sp , err := ParseURL (tc .url )
60130 if tc .expectedError == "" {
61131 assert .NilError (t , err )
62- assert .Check (t , is .DeepEqual (tc .expectedArgs , sp .Args ()))
132+ actualArgs := sp .Args (tc .remoteCommand ... )
133+ assert .Check (t , is .DeepEqual (actualArgs , tc .expectedArgs ))
134+ assert .Check (t , is .Equal (* sp , tc .expectedSpec ))
63135 } else {
64- assert .ErrorContains (t , err , tc .expectedError )
136+ assert .Check (t , is .Error (err , tc .expectedError ))
137+ assert .Check (t , is .Nil (sp ))
65138 }
66139 })
67140 }
0 commit comments