aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/transport/ssh
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2017-11-20 18:19:50 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2017-11-20 18:19:50 +0100
commit319bac952a9c8a141942d8b22b4c83d06c41a0d4 (patch)
tree9c41b78cbe303b00f381cf2dca4d4f8b592d3cb9 /plumbing/transport/ssh
parent47fc5cbffe92111d8737de8120f168bab4f5c539 (diff)
downloadgo-git-319bac952a9c8a141942d8b22b4c83d06c41a0d4.tar.gz
transport: ssh, mocked SSH server, fixes #332
Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
Diffstat (limited to 'plumbing/transport/ssh')
-rw-r--r--plumbing/transport/ssh/upload_pack_test.go124
1 files changed, 108 insertions, 16 deletions
diff --git a/plumbing/transport/ssh/upload_pack_test.go b/plumbing/transport/ssh/upload_pack_test.go
index cb9baa5..04f7b1c 100644
--- a/plumbing/transport/ssh/upload_pack_test.go
+++ b/plumbing/transport/ssh/upload_pack_test.go
@@ -1,47 +1,139 @@
package ssh
import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "net"
"os"
+ "os/exec"
+ "path/filepath"
+ "strings"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/plumbing/transport/test"
+ "github.com/gliderlabs/ssh"
+ "github.com/src-d/go-git-fixtures"
+ stdssh "golang.org/x/crypto/ssh"
. "gopkg.in/check.v1"
)
type UploadPackSuite struct {
test.UploadPackSuite
+ fixtures.Suite
+
+ port int
+ base string
}
var _ = Suite(&UploadPackSuite{})
func (s *UploadPackSuite) SetUpSuite(c *C) {
- s.setAuthBuilder(c)
- s.UploadPackSuite.Client = DefaultClient
+ s.Suite.SetUpSuite(c)
+
+ l, err := net.Listen("tcp", "localhost:0")
+ c.Assert(err, IsNil)
- ep, err := transport.NewEndpoint("git@github.com:git-fixtures/basic.git")
+ s.port = l.Addr().(*net.TCPAddr).Port
+ s.base, err = ioutil.TempDir(os.TempDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
c.Assert(err, IsNil)
- s.UploadPackSuite.Endpoint = ep
- ep, err = transport.NewEndpoint("git@github.com:git-fixtures/empty.git")
+ DefaultAuthBuilder = func(user string) (AuthMethod, error) {
+ return &Password{User: user}, nil
+ }
+
+ s.UploadPackSuite.Client = NewClient(&stdssh.ClientConfig{
+ HostKeyCallback: stdssh.InsecureIgnoreHostKey(),
+ })
+
+ s.UploadPackSuite.Endpoint = s.prepareRepository(c, fixtures.Basic().One(), "basic.git")
+ s.UploadPackSuite.EmptyEndpoint = s.prepareRepository(c, fixtures.ByTag("empty").One(), "empty.git")
+ s.UploadPackSuite.NonExistentEndpoint = s.newEndpoint(c, "non-existent.git")
+
+ server := &ssh.Server{Handler: handlerSSH}
+ go func() {
+ log.Fatal(server.Serve(l))
+ }()
+}
+
+func (s *UploadPackSuite) prepareRepository(c *C, f *fixtures.Fixture, name string) transport.Endpoint {
+ fs := f.DotGit()
+
+ err := fixtures.EnsureIsBare(fs)
c.Assert(err, IsNil)
- s.UploadPackSuite.EmptyEndpoint = ep
- ep, err = transport.NewEndpoint("git@github.com:git-fixtures/non-existent.git")
+ path := filepath.Join(s.base, name)
+ err = os.Rename(fs.Root(), path)
c.Assert(err, IsNil)
- s.UploadPackSuite.NonExistentEndpoint = ep
+
+ return s.newEndpoint(c, name)
+}
+
+func (s *UploadPackSuite) newEndpoint(c *C, name string) transport.Endpoint {
+ ep, err := transport.NewEndpoint(fmt.Sprintf(
+ "ssh://git@localhost:%d/%s/%s", s.port, filepath.ToSlash(s.base), name,
+ ))
+
+ c.Assert(err, IsNil)
+ return ep
}
-func (s *UploadPackSuite) setAuthBuilder(c *C) {
- privateKey := os.Getenv("SSH_TEST_PRIVATE_KEY")
- if privateKey != "" {
- DefaultAuthBuilder = func(user string) (AuthMethod, error) {
- return NewPublicKeysFromFile(user, privateKey, "")
- }
+func handlerSSH(s ssh.Session) {
+ cmd, stdin, stderr, stdout, err := buildCommand(s.Command())
+ if err != nil {
+ fmt.Println(err)
+ return
}
- if privateKey == "" && os.Getenv("SSH_AUTH_SOCK") == "" {
- c.Skip("SSH_AUTH_SOCK or SSH_TEST_PRIVATE_KEY are required")
+ if err := cmd.Start(); err != nil {
+ fmt.Println(err)
return
}
+
+ go func() {
+ defer stdin.Close()
+ io.Copy(stdin, s)
+ }()
+
+ go func() {
+ defer stderr.Close()
+ io.Copy(s.Stderr(), stderr)
+ }()
+
+ defer stdout.Close()
+ io.Copy(s, stdout)
+
+ if err := cmd.Wait(); err != nil {
+ return
+ }
+}
+
+func buildCommand(c []string) (cmd *exec.Cmd, stdin io.WriteCloser, stderr, stdout io.ReadCloser, err error) {
+ if len(c) != 2 {
+ err = fmt.Errorf("invalid command")
+ return
+ }
+
+ // fix for Windows environments
+ path := strings.Replace(c[1], "/C:/", "C:/", 1)
+
+ cmd = exec.Command(c[0], path)
+ stdout, err = cmd.StdoutPipe()
+ if err != nil {
+ return
+ }
+
+ stdin, err = cmd.StdinPipe()
+ if err != nil {
+ return
+ }
+
+ stderr, err = cmd.StderrPipe()
+ if err != nil {
+ return
+ }
+
+ return
}