github.com/saracen/git-lfs@v2.5.2+incompatible/lfsapi/ssh_test.go (about)

     1  package lfsapi
     2  
     3  import (
     4  	"errors"
     5  	"net/url"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestSSHCacheResolveFromCache(t *testing.T) {
    15  	ssh := newFakeResolver()
    16  	cache := withSSHCache(ssh).(*sshCache)
    17  	cache.endpoints["userandhost//1//path//post"] = &sshAuthResponse{
    18  		Href:      "cache",
    19  		createdAt: time.Now(),
    20  	}
    21  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
    22  
    23  	e := Endpoint{
    24  		SshUserAndHost: "userandhost",
    25  		SshPort:        "1",
    26  		SshPath:        "path",
    27  	}
    28  
    29  	res, err := cache.Resolve(e, "post")
    30  	assert.Nil(t, err)
    31  	assert.Equal(t, "cache", res.Href)
    32  }
    33  
    34  func TestSSHCacheResolveFromCacheWithFutureExpiresAt(t *testing.T) {
    35  	ssh := newFakeResolver()
    36  	cache := withSSHCache(ssh).(*sshCache)
    37  	cache.endpoints["userandhost//1//path//post"] = &sshAuthResponse{
    38  		Href:      "cache",
    39  		ExpiresAt: time.Now().Add(time.Duration(1) * time.Hour),
    40  		createdAt: time.Now(),
    41  	}
    42  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
    43  
    44  	e := Endpoint{
    45  		SshUserAndHost: "userandhost",
    46  		SshPort:        "1",
    47  		SshPath:        "path",
    48  	}
    49  
    50  	res, err := cache.Resolve(e, "post")
    51  	assert.Nil(t, err)
    52  	assert.Equal(t, "cache", res.Href)
    53  }
    54  
    55  func TestSSHCacheResolveFromCacheWithFutureExpiresIn(t *testing.T) {
    56  	ssh := newFakeResolver()
    57  	cache := withSSHCache(ssh).(*sshCache)
    58  	cache.endpoints["userandhost//1//path//post"] = &sshAuthResponse{
    59  		Href:      "cache",
    60  		ExpiresIn: 60 * 60,
    61  		createdAt: time.Now(),
    62  	}
    63  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
    64  
    65  	e := Endpoint{
    66  		SshUserAndHost: "userandhost",
    67  		SshPort:        "1",
    68  		SshPath:        "path",
    69  	}
    70  
    71  	res, err := cache.Resolve(e, "post")
    72  	assert.Nil(t, err)
    73  	assert.Equal(t, "cache", res.Href)
    74  }
    75  
    76  func TestSSHCacheResolveFromCacheWithPastExpiresAt(t *testing.T) {
    77  	ssh := newFakeResolver()
    78  	cache := withSSHCache(ssh).(*sshCache)
    79  	cache.endpoints["userandhost//1//path//post"] = &sshAuthResponse{
    80  		Href:      "cache",
    81  		ExpiresAt: time.Now().Add(time.Duration(-1) * time.Hour),
    82  		createdAt: time.Now(),
    83  	}
    84  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
    85  
    86  	e := Endpoint{
    87  		SshUserAndHost: "userandhost",
    88  		SshPort:        "1",
    89  		SshPath:        "path",
    90  	}
    91  
    92  	res, err := cache.Resolve(e, "post")
    93  	assert.Nil(t, err)
    94  	assert.Equal(t, "real", res.Href)
    95  }
    96  
    97  func TestSSHCacheResolveFromCacheWithPastExpiresIn(t *testing.T) {
    98  	ssh := newFakeResolver()
    99  	cache := withSSHCache(ssh).(*sshCache)
   100  	cache.endpoints["userandhost//1//path//post"] = &sshAuthResponse{
   101  		Href:      "cache",
   102  		ExpiresIn: -60 * 60,
   103  		createdAt: time.Now(),
   104  	}
   105  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
   106  
   107  	e := Endpoint{
   108  		SshUserAndHost: "userandhost",
   109  		SshPort:        "1",
   110  		SshPath:        "path",
   111  	}
   112  
   113  	res, err := cache.Resolve(e, "post")
   114  	assert.Nil(t, err)
   115  	assert.Equal(t, "real", res.Href)
   116  }
   117  
   118  func TestSSHCacheResolveFromCacheWithAmbiguousExpirationInfo(t *testing.T) {
   119  	ssh := newFakeResolver()
   120  	cache := withSSHCache(ssh).(*sshCache)
   121  	cache.endpoints["userandhost//1//path//post"] = &sshAuthResponse{
   122  		Href:      "cache",
   123  		ExpiresIn: 60 * 60,
   124  		ExpiresAt: time.Now().Add(-1 * time.Hour),
   125  		createdAt: time.Now(),
   126  	}
   127  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
   128  
   129  	e := Endpoint{
   130  		SshUserAndHost: "userandhost",
   131  		SshPort:        "1",
   132  		SshPath:        "path",
   133  	}
   134  
   135  	res, err := cache.Resolve(e, "post")
   136  	assert.Nil(t, err)
   137  	assert.Equal(t, "cache", res.Href)
   138  }
   139  
   140  func TestSSHCacheResolveWithoutError(t *testing.T) {
   141  	ssh := newFakeResolver()
   142  	cache := withSSHCache(ssh).(*sshCache)
   143  
   144  	assert.Equal(t, 0, len(cache.endpoints))
   145  
   146  	ssh.responses["userandhost"] = sshAuthResponse{Href: "real"}
   147  
   148  	e := Endpoint{
   149  		SshUserAndHost: "userandhost",
   150  		SshPort:        "1",
   151  		SshPath:        "path",
   152  	}
   153  
   154  	res, err := cache.Resolve(e, "post")
   155  	assert.Nil(t, err)
   156  	assert.Equal(t, "real", res.Href)
   157  
   158  	assert.Equal(t, 1, len(cache.endpoints))
   159  	cacheres, ok := cache.endpoints["userandhost//1//path//post"]
   160  	assert.True(t, ok)
   161  	assert.NotNil(t, cacheres)
   162  	assert.Equal(t, "real", cacheres.Href)
   163  
   164  	delete(ssh.responses, "userandhost")
   165  	res2, err := cache.Resolve(e, "post")
   166  	assert.Nil(t, err)
   167  	assert.Equal(t, "real", res2.Href)
   168  }
   169  
   170  func TestSSHCacheResolveWithError(t *testing.T) {
   171  	ssh := newFakeResolver()
   172  	cache := withSSHCache(ssh).(*sshCache)
   173  
   174  	assert.Equal(t, 0, len(cache.endpoints))
   175  
   176  	ssh.responses["userandhost"] = sshAuthResponse{Message: "resolve error", Href: "real"}
   177  
   178  	e := Endpoint{
   179  		SshUserAndHost: "userandhost",
   180  		SshPort:        "1",
   181  		SshPath:        "path",
   182  	}
   183  
   184  	res, err := cache.Resolve(e, "post")
   185  	assert.NotNil(t, err)
   186  	assert.Equal(t, "real", res.Href)
   187  
   188  	assert.Equal(t, 0, len(cache.endpoints))
   189  	delete(ssh.responses, "userandhost")
   190  	res2, err := cache.Resolve(e, "post")
   191  	assert.Nil(t, err)
   192  	assert.Equal(t, "", res2.Href)
   193  }
   194  
   195  func newFakeResolver() *fakeResolver {
   196  	return &fakeResolver{responses: make(map[string]sshAuthResponse)}
   197  }
   198  
   199  type fakeResolver struct {
   200  	responses map[string]sshAuthResponse
   201  }
   202  
   203  func (r *fakeResolver) Resolve(e Endpoint, method string) (sshAuthResponse, error) {
   204  	res := r.responses[e.SshUserAndHost]
   205  	var err error
   206  	if len(res.Message) > 0 {
   207  		err = errors.New(res.Message)
   208  	}
   209  
   210  	res.createdAt = time.Now()
   211  
   212  	return res, err
   213  }
   214  
   215  func TestSSHGetLFSExeAndArgs(t *testing.T) {
   216  	cli, err := NewClient(nil)
   217  	require.Nil(t, err)
   218  
   219  	endpoint := cli.Endpoints.Endpoint("download", "")
   220  	endpoint.SshUserAndHost = "user@foo.com"
   221  	endpoint.SshPath = "user/repo"
   222  
   223  	exe, args := sshGetLFSExeAndArgs(cli.OSEnv(), endpoint, "GET")
   224  	assert.Equal(t, "ssh", exe)
   225  	assert.Equal(t, []string{
   226  		"--",
   227  		"user@foo.com",
   228  		"git-lfs-authenticate user/repo download",
   229  	}, args)
   230  
   231  	exe, args = sshGetLFSExeAndArgs(cli.OSEnv(), endpoint, "HEAD")
   232  	assert.Equal(t, "ssh", exe)
   233  	assert.Equal(t, []string{
   234  		"--",
   235  		"user@foo.com",
   236  		"git-lfs-authenticate user/repo download",
   237  	}, args)
   238  
   239  	// this is going by endpoint.Operation, implicitly set by Endpoint() on L15.
   240  	exe, args = sshGetLFSExeAndArgs(cli.OSEnv(), endpoint, "POST")
   241  	assert.Equal(t, "ssh", exe)
   242  	assert.Equal(t, []string{
   243  		"--",
   244  		"user@foo.com",
   245  		"git-lfs-authenticate user/repo download",
   246  	}, args)
   247  
   248  	endpoint.Operation = "upload"
   249  	exe, args = sshGetLFSExeAndArgs(cli.OSEnv(), endpoint, "POST")
   250  	assert.Equal(t, "ssh", exe)
   251  	assert.Equal(t, []string{
   252  		"--",
   253  		"user@foo.com",
   254  		"git-lfs-authenticate user/repo upload",
   255  	}, args)
   256  }
   257  
   258  func TestSSHGetExeAndArgsSsh(t *testing.T) {
   259  	cli, err := NewClient(NewContext(nil, map[string]string{
   260  		"GIT_SSH_COMMAND": "",
   261  		"GIT_SSH":         "",
   262  	}, nil))
   263  	require.Nil(t, err)
   264  
   265  	endpoint := cli.Endpoints.Endpoint("download", "")
   266  	endpoint.SshUserAndHost = "user@foo.com"
   267  
   268  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   269  	assert.Equal(t, "ssh", exe)
   270  	assert.Equal(t, []string{"--", "user@foo.com"}, args)
   271  }
   272  
   273  func TestSSHGetExeAndArgsSshCustomPort(t *testing.T) {
   274  	cli, err := NewClient(NewContext(nil, map[string]string{
   275  		"GIT_SSH_COMMAND": "",
   276  		"GIT_SSH":         "",
   277  	}, nil))
   278  	require.Nil(t, err)
   279  
   280  	endpoint := cli.Endpoints.Endpoint("download", "")
   281  	endpoint.SshUserAndHost = "user@foo.com"
   282  	endpoint.SshPort = "8888"
   283  
   284  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   285  	assert.Equal(t, "ssh", exe)
   286  	assert.Equal(t, []string{"-p", "8888", "--", "user@foo.com"}, args)
   287  }
   288  
   289  func TestSSHGetExeAndArgsPlink(t *testing.T) {
   290  	plink := filepath.Join("Users", "joebloggs", "bin", "plink.exe")
   291  
   292  	cli, err := NewClient(NewContext(nil, map[string]string{
   293  		"GIT_SSH_COMMAND": "",
   294  		"GIT_SSH":         plink,
   295  	}, nil))
   296  	require.Nil(t, err)
   297  
   298  	endpoint := cli.Endpoints.Endpoint("download", "")
   299  	endpoint.SshUserAndHost = "user@foo.com"
   300  
   301  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   302  	assert.Equal(t, plink, exe)
   303  	assert.Equal(t, []string{"user@foo.com"}, args)
   304  }
   305  
   306  func TestSSHGetExeAndArgsPlinkCustomPort(t *testing.T) {
   307  	plink := filepath.Join("Users", "joebloggs", "bin", "plink")
   308  
   309  	cli, err := NewClient(NewContext(nil, map[string]string{
   310  		"GIT_SSH_COMMAND": "",
   311  		"GIT_SSH":         plink,
   312  	}, nil))
   313  	require.Nil(t, err)
   314  
   315  	endpoint := cli.Endpoints.Endpoint("download", "")
   316  	endpoint.SshUserAndHost = "user@foo.com"
   317  	endpoint.SshPort = "8888"
   318  
   319  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   320  	assert.Equal(t, plink, exe)
   321  	assert.Equal(t, []string{"-P", "8888", "user@foo.com"}, args)
   322  }
   323  
   324  func TestSSHGetExeAndArgsTortoisePlink(t *testing.T) {
   325  	plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink.exe")
   326  
   327  	cli, err := NewClient(NewContext(nil, map[string]string{
   328  		"GIT_SSH_COMMAND": "",
   329  		"GIT_SSH":         plink,
   330  	}, nil))
   331  	require.Nil(t, err)
   332  
   333  	endpoint := cli.Endpoints.Endpoint("download", "")
   334  	endpoint.SshUserAndHost = "user@foo.com"
   335  
   336  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   337  	assert.Equal(t, plink, exe)
   338  	assert.Equal(t, []string{"-batch", "user@foo.com"}, args)
   339  }
   340  
   341  func TestSSHGetExeAndArgsTortoisePlinkCustomPort(t *testing.T) {
   342  	plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink")
   343  
   344  	cli, err := NewClient(NewContext(nil, map[string]string{
   345  		"GIT_SSH_COMMAND": "",
   346  		"GIT_SSH":         plink,
   347  	}, nil))
   348  	require.Nil(t, err)
   349  
   350  	endpoint := cli.Endpoints.Endpoint("download", "")
   351  	endpoint.SshUserAndHost = "user@foo.com"
   352  	endpoint.SshPort = "8888"
   353  
   354  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   355  	assert.Equal(t, plink, exe)
   356  	assert.Equal(t, []string{"-batch", "-P", "8888", "user@foo.com"}, args)
   357  }
   358  
   359  func TestSSHGetExeAndArgsSshCommandPrecedence(t *testing.T) {
   360  	cli, err := NewClient(NewContext(nil, map[string]string{
   361  		"GIT_SSH_COMMAND": "sshcmd",
   362  		"GIT_SSH":         "bad",
   363  	}, nil))
   364  	require.Nil(t, err)
   365  
   366  	endpoint := cli.Endpoints.Endpoint("download", "")
   367  	endpoint.SshUserAndHost = "user@foo.com"
   368  
   369  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   370  	assert.Equal(t, "sshcmd", exe)
   371  	assert.Equal(t, []string{"user@foo.com"}, args)
   372  }
   373  
   374  func TestSSHGetExeAndArgsSshCommandArgs(t *testing.T) {
   375  	cli, err := NewClient(NewContext(nil, map[string]string{
   376  		"GIT_SSH_COMMAND": "sshcmd --args 1",
   377  	}, nil))
   378  	require.Nil(t, err)
   379  
   380  	endpoint := cli.Endpoints.Endpoint("download", "")
   381  	endpoint.SshUserAndHost = "user@foo.com"
   382  
   383  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   384  	assert.Equal(t, "sshcmd", exe)
   385  	assert.Equal(t, []string{"--args", "1", "user@foo.com"}, args)
   386  }
   387  
   388  func TestSSHGetExeAndArgsSshCommandArgsWithMixedQuotes(t *testing.T) {
   389  	cli, err := NewClient(NewContext(nil, map[string]string{
   390  		"GIT_SSH_COMMAND": "sshcmd foo 'bar \"baz\"'",
   391  	}, nil))
   392  	require.Nil(t, err)
   393  
   394  	endpoint := cli.Endpoints.Endpoint("download", "")
   395  	endpoint.SshUserAndHost = "user@foo.com"
   396  
   397  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   398  	assert.Equal(t, "sshcmd", exe)
   399  	assert.Equal(t, []string{"foo", `bar "baz"`, "user@foo.com"}, args)
   400  }
   401  
   402  func TestSSHGetExeAndArgsSshCommandCustomPort(t *testing.T) {
   403  	cli, err := NewClient(NewContext(nil, map[string]string{
   404  		"GIT_SSH_COMMAND": "sshcmd",
   405  	}, nil))
   406  	require.Nil(t, err)
   407  
   408  	endpoint := cli.Endpoints.Endpoint("download", "")
   409  	endpoint.SshUserAndHost = "user@foo.com"
   410  	endpoint.SshPort = "8888"
   411  
   412  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   413  	assert.Equal(t, "sshcmd", exe)
   414  	assert.Equal(t, []string{"-p", "8888", "user@foo.com"}, args)
   415  }
   416  
   417  func TestSSHGetLFSExeAndArgsWithCustomSSH(t *testing.T) {
   418  	cli, err := NewClient(NewContext(nil, map[string]string{
   419  		"GIT_SSH": "not-ssh",
   420  	}, nil))
   421  	require.Nil(t, err)
   422  
   423  	u, err := url.Parse("ssh://git@host.com:12345/repo")
   424  	require.Nil(t, err)
   425  
   426  	e := endpointFromSshUrl(u)
   427  	t.Logf("ENDPOINT: %+v", e)
   428  	assert.Equal(t, "12345", e.SshPort)
   429  	assert.Equal(t, "git@host.com", e.SshUserAndHost)
   430  	assert.Equal(t, "repo", e.SshPath)
   431  
   432  	exe, args := sshGetLFSExeAndArgs(cli.OSEnv(), e, "GET")
   433  	assert.Equal(t, "not-ssh", exe)
   434  	assert.Equal(t, []string{"-p", "12345", "git@host.com", "git-lfs-authenticate repo download"}, args)
   435  }
   436  
   437  func TestSSHGetLFSExeAndArgsInvalidOptionsAsHost(t *testing.T) {
   438  	cli, err := NewClient(nil)
   439  	require.Nil(t, err)
   440  
   441  	u, err := url.Parse("ssh://-oProxyCommand=gnome-calculator/repo")
   442  	require.Nil(t, err)
   443  	assert.Equal(t, "-oProxyCommand=gnome-calculator", u.Host)
   444  
   445  	e := endpointFromSshUrl(u)
   446  	t.Logf("ENDPOINT: %+v", e)
   447  	assert.Equal(t, "-oProxyCommand=gnome-calculator", e.SshUserAndHost)
   448  	assert.Equal(t, "repo", e.SshPath)
   449  
   450  	exe, args := sshGetLFSExeAndArgs(cli.OSEnv(), e, "GET")
   451  	assert.Equal(t, "ssh", exe)
   452  	assert.Equal(t, []string{"--", "-oProxyCommand=gnome-calculator", "git-lfs-authenticate repo download"}, args)
   453  }
   454  
   455  func TestSSHGetLFSExeAndArgsInvalidOptionsAsHostWithCustomSSH(t *testing.T) {
   456  	cli, err := NewClient(NewContext(nil, map[string]string{
   457  		"GIT_SSH": "not-ssh",
   458  	}, nil))
   459  	require.Nil(t, err)
   460  
   461  	u, err := url.Parse("ssh://--oProxyCommand=gnome-calculator/repo")
   462  	require.Nil(t, err)
   463  	assert.Equal(t, "--oProxyCommand=gnome-calculator", u.Host)
   464  
   465  	e := endpointFromSshUrl(u)
   466  	t.Logf("ENDPOINT: %+v", e)
   467  	assert.Equal(t, "--oProxyCommand=gnome-calculator", e.SshUserAndHost)
   468  	assert.Equal(t, "repo", e.SshPath)
   469  
   470  	exe, args := sshGetLFSExeAndArgs(cli.OSEnv(), e, "GET")
   471  	assert.Equal(t, "not-ssh", exe)
   472  	assert.Equal(t, []string{"oProxyCommand=gnome-calculator", "git-lfs-authenticate repo download"}, args)
   473  }
   474  
   475  func TestSSHGetExeAndArgsInvalidOptionsAsHost(t *testing.T) {
   476  	cli, err := NewClient(nil)
   477  	require.Nil(t, err)
   478  
   479  	u, err := url.Parse("ssh://-oProxyCommand=gnome-calculator")
   480  	require.Nil(t, err)
   481  	assert.Equal(t, "-oProxyCommand=gnome-calculator", u.Host)
   482  
   483  	e := endpointFromSshUrl(u)
   484  	t.Logf("ENDPOINT: %+v", e)
   485  	assert.Equal(t, "-oProxyCommand=gnome-calculator", e.SshUserAndHost)
   486  	assert.Equal(t, "", e.SshPath)
   487  
   488  	exe, args := sshGetExeAndArgs(cli.OSEnv(), e)
   489  	assert.Equal(t, "ssh", exe)
   490  	assert.Equal(t, []string{"--", "-oProxyCommand=gnome-calculator"}, args)
   491  }
   492  
   493  func TestSSHGetExeAndArgsInvalidOptionsAsPath(t *testing.T) {
   494  	cli, err := NewClient(nil)
   495  	require.Nil(t, err)
   496  
   497  	u, err := url.Parse("ssh://git@git-host.com/-oProxyCommand=gnome-calculator")
   498  	require.Nil(t, err)
   499  	assert.Equal(t, "git-host.com", u.Host)
   500  
   501  	e := endpointFromSshUrl(u)
   502  	t.Logf("ENDPOINT: %+v", e)
   503  	assert.Equal(t, "git@git-host.com", e.SshUserAndHost)
   504  	assert.Equal(t, "-oProxyCommand=gnome-calculator", e.SshPath)
   505  
   506  	exe, args := sshGetExeAndArgs(cli.OSEnv(), e)
   507  	assert.Equal(t, "ssh", exe)
   508  	assert.Equal(t, []string{"--", "git@git-host.com"}, args)
   509  }
   510  
   511  func TestParseBareSSHUrl(t *testing.T) {
   512  	e := endpointFromBareSshUrl("git@git-host.com:repo.git")
   513  	t.Logf("endpoint: %+v", e)
   514  	assert.Equal(t, "git@git-host.com", e.SshUserAndHost)
   515  	assert.Equal(t, "repo.git", e.SshPath)
   516  
   517  	e = endpointFromBareSshUrl("git@git-host.com/should-be-a-colon.git")
   518  	t.Logf("endpoint: %+v", e)
   519  	assert.Equal(t, "", e.SshUserAndHost)
   520  	assert.Equal(t, "", e.SshPath)
   521  
   522  	e = endpointFromBareSshUrl("-oProxyCommand=gnome-calculator")
   523  	t.Logf("endpoint: %+v", e)
   524  	assert.Equal(t, "", e.SshUserAndHost)
   525  	assert.Equal(t, "", e.SshPath)
   526  
   527  	e = endpointFromBareSshUrl("git@git-host.com:-oProxyCommand=gnome-calculator")
   528  	t.Logf("endpoint: %+v", e)
   529  	assert.Equal(t, "git@git-host.com", e.SshUserAndHost)
   530  	assert.Equal(t, "-oProxyCommand=gnome-calculator", e.SshPath)
   531  }
   532  
   533  func TestSSHGetExeAndArgsPlinkCommand(t *testing.T) {
   534  	plink := filepath.Join("Users", "joebloggs", "bin", "plink.exe")
   535  
   536  	cli, err := NewClient(NewContext(nil, map[string]string{
   537  		"GIT_SSH_COMMAND": plink,
   538  	}, nil))
   539  	require.Nil(t, err)
   540  
   541  	endpoint := cli.Endpoints.Endpoint("download", "")
   542  	endpoint.SshUserAndHost = "user@foo.com"
   543  
   544  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   545  	assert.Equal(t, plink, exe)
   546  	assert.Equal(t, []string{"user@foo.com"}, args)
   547  }
   548  
   549  func TestSSHGetExeAndArgsPlinkCommandCustomPort(t *testing.T) {
   550  	plink := filepath.Join("Users", "joebloggs", "bin", "plink")
   551  
   552  	cli, err := NewClient(NewContext(nil, map[string]string{
   553  		"GIT_SSH_COMMAND": plink,
   554  	}, nil))
   555  	require.Nil(t, err)
   556  
   557  	endpoint := cli.Endpoints.Endpoint("download", "")
   558  	endpoint.SshUserAndHost = "user@foo.com"
   559  	endpoint.SshPort = "8888"
   560  
   561  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   562  	assert.Equal(t, plink, exe)
   563  	assert.Equal(t, []string{"-P", "8888", "user@foo.com"}, args)
   564  }
   565  
   566  func TestSSHGetExeAndArgsTortoisePlinkCommand(t *testing.T) {
   567  	plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink.exe")
   568  
   569  	cli, err := NewClient(NewContext(nil, map[string]string{
   570  		"GIT_SSH_COMMAND": plink,
   571  	}, nil))
   572  	require.Nil(t, err)
   573  
   574  	endpoint := cli.Endpoints.Endpoint("download", "")
   575  	endpoint.SshUserAndHost = "user@foo.com"
   576  
   577  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   578  	assert.Equal(t, plink, exe)
   579  	assert.Equal(t, []string{"-batch", "user@foo.com"}, args)
   580  }
   581  
   582  func TestSSHGetExeAndArgsTortoisePlinkCommandCustomPort(t *testing.T) {
   583  	plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink")
   584  
   585  	cli, err := NewClient(NewContext(nil, map[string]string{
   586  		"GIT_SSH_COMMAND": plink,
   587  	}, nil))
   588  	require.Nil(t, err)
   589  
   590  	endpoint := cli.Endpoints.Endpoint("download", "")
   591  	endpoint.SshUserAndHost = "user@foo.com"
   592  	endpoint.SshPort = "8888"
   593  
   594  	exe, args := sshGetExeAndArgs(cli.OSEnv(), endpoint)
   595  	assert.Equal(t, plink, exe)
   596  	assert.Equal(t, []string{"-batch", "-P", "8888", "user@foo.com"}, args)
   597  }