Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 1a120f6

Browse files
committed
transport: ssh, mocked SSH server, fixes #332
Signed-off-by: Máximo Cuadros <[email protected]>
1 parent 47fc5cb commit 1a120f6

File tree

2 files changed

+100
-25
lines changed

2 files changed

+100
-25
lines changed

.travis.yml

-9
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,6 @@ before_install:
2323
- git config --global user.email "[email protected]"
2424
- git config --global user.name "Travis CI"
2525

26-
# we only decrypt the SSH key when we aren't in a pull request
27-
- >
28-
if [ "$TRAVIS_PULL_REQUEST" = "false" ] ; then \
29-
bash .travis/install_key.sh; \
30-
export SSH_TEST_PRIVATE_KEY=$HOME/.travis/deploy.pem; \
31-
else \
32-
export SSH_AUTH_SOCK=""; \
33-
fi
34-
3526
install:
3627
- go get -v -t ./...
3728

+100-16
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,131 @@
11
package ssh
22

33
import (
4+
"fmt"
5+
"io"
6+
"io/ioutil"
7+
"log"
8+
"net"
49
"os"
10+
"os/exec"
11+
"path/filepath"
512

613
"gopkg.in/src-d/go-git.v4/plumbing/transport"
714
"gopkg.in/src-d/go-git.v4/plumbing/transport/test"
815

16+
"github.com/gliderlabs/ssh"
17+
"github.com/src-d/go-git-fixtures"
18+
stdssh "golang.org/x/crypto/ssh"
919
. "gopkg.in/check.v1"
1020
)
1121

1222
type UploadPackSuite struct {
1323
test.UploadPackSuite
24+
fixtures.Suite
25+
26+
port int
27+
base string
1428
}
1529

1630
var _ = Suite(&UploadPackSuite{})
1731

1832
func (s *UploadPackSuite) SetUpSuite(c *C) {
19-
s.setAuthBuilder(c)
20-
s.UploadPackSuite.Client = DefaultClient
33+
s.Suite.SetUpSuite(c)
2134

22-
ep, err := transport.NewEndpoint("[email protected]:git-fixtures/basic.git")
35+
l, err := net.Listen("tcp", "localhost:0")
2336
c.Assert(err, IsNil)
24-
s.UploadPackSuite.Endpoint = ep
2537

26-
ep, err = transport.NewEndpoint("[email protected]:git-fixtures/empty.git")
38+
s.port = l.Addr().(*net.TCPAddr).Port
39+
s.base, err = ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
2740
c.Assert(err, IsNil)
28-
s.UploadPackSuite.EmptyEndpoint = ep
2941

30-
ep, err = transport.NewEndpoint("[email protected]:git-fixtures/non-existent.git")
42+
s.UploadPackSuite.Client = NewClient(&stdssh.ClientConfig{
43+
HostKeyCallback: stdssh.InsecureIgnoreHostKey(),
44+
})
45+
46+
s.UploadPackSuite.Endpoint = s.prepareRepository(c, fixtures.Basic().One(), "basic.git")
47+
s.UploadPackSuite.EmptyEndpoint = s.prepareRepository(c, fixtures.ByTag("empty").One(), "empty.git")
48+
s.UploadPackSuite.NonExistentEndpoint = s.newEndpoint(c, "non-existent.git")
49+
50+
server := &ssh.Server{Handler: handlerSSH}
51+
go func() {
52+
log.Fatal(server.Serve(l))
53+
}()
54+
}
55+
56+
func (s *UploadPackSuite) prepareRepository(c *C, f *fixtures.Fixture, name string) transport.Endpoint {
57+
fs := f.DotGit()
58+
59+
err := fixtures.EnsureIsBare(fs)
60+
c.Assert(err, IsNil)
61+
62+
path := filepath.Join(s.base, name)
63+
err = os.Rename(fs.Root(), path)
3164
c.Assert(err, IsNil)
32-
s.UploadPackSuite.NonExistentEndpoint = ep
65+
66+
return s.newEndpoint(c, name)
67+
}
68+
69+
func (s *UploadPackSuite) newEndpoint(c *C, name string) transport.Endpoint {
70+
ep, err := transport.NewEndpoint(fmt.Sprintf(
71+
"ssh://git@localhost:%d%s/%s", s.port, s.base, name,
72+
))
73+
74+
c.Assert(err, IsNil)
75+
return ep
76+
}
77+
78+
func handlerSSH(s ssh.Session) {
79+
cmd, stdin, stderr, stdout, err := buildCommand(s.Command())
80+
if err != nil {
81+
fmt.Println(err)
82+
return
83+
}
84+
85+
if err := cmd.Start(); err != nil {
86+
fmt.Println(err)
87+
return
88+
}
89+
90+
go func() {
91+
defer stdin.Close()
92+
io.Copy(stdin, s)
93+
}()
94+
95+
go func() {
96+
defer stderr.Close()
97+
io.Copy(s.Stderr(), stderr)
98+
}()
99+
100+
defer stdout.Close()
101+
io.Copy(s, stdout)
102+
103+
if err := cmd.Wait(); err != nil {
104+
return
105+
}
33106
}
34107

35-
func (s *UploadPackSuite) setAuthBuilder(c *C) {
36-
privateKey := os.Getenv("SSH_TEST_PRIVATE_KEY")
37-
if privateKey != "" {
38-
DefaultAuthBuilder = func(user string) (AuthMethod, error) {
39-
return NewPublicKeysFromFile(user, privateKey, "")
40-
}
108+
func buildCommand(c []string) (cmd *exec.Cmd, stdin io.WriteCloser, stderr, stdout io.ReadCloser, err error) {
109+
if len(c) < 2 {
110+
err = fmt.Errorf("invalid command")
111+
return
112+
}
113+
114+
cmd = exec.Command(c[0], c[1:]...)
115+
stdout, err = cmd.StdoutPipe()
116+
if err != nil {
117+
return
41118
}
42119

43-
if privateKey == "" && os.Getenv("SSH_AUTH_SOCK") == "" {
44-
c.Skip("SSH_AUTH_SOCK or SSH_TEST_PRIVATE_KEY are required")
120+
stdin, err = cmd.StdinPipe()
121+
if err != nil {
45122
return
46123
}
124+
125+
stderr, err = cmd.StderrPipe()
126+
if err != nil {
127+
return
128+
}
129+
130+
return
47131
}

0 commit comments

Comments
 (0)