summaryrefslogtreecommitdiff
path: root/libgo/go/exp/ssh/session_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/exp/ssh/session_test.go')
-rw-r--r--libgo/go/exp/ssh/session_test.go149
1 files changed, 149 insertions, 0 deletions
diff --git a/libgo/go/exp/ssh/session_test.go b/libgo/go/exp/ssh/session_test.go
new file mode 100644
index 00000000000..4be7746d17e
--- /dev/null
+++ b/libgo/go/exp/ssh/session_test.go
@@ -0,0 +1,149 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+// Session tests.
+
+import (
+ "bytes"
+ "io"
+ "testing"
+)
+
+// dial constructs a new test server and returns a *ClientConn.
+func dial(t *testing.T) *ClientConn {
+ pw := password("tiger")
+ serverConfig.PasswordCallback = func(user, pass string) bool {
+ return user == "testuser" && pass == string(pw)
+ }
+ serverConfig.PubKeyCallback = nil
+
+ l, err := Listen("tcp", "127.0.0.1:0", serverConfig)
+ if err != nil {
+ t.Fatalf("unable to listen: %s", err)
+ }
+ go func() {
+ defer l.Close()
+ conn, err := l.Accept()
+ if err != nil {
+ t.Errorf("Unable to accept: %v", err)
+ return
+ }
+ defer conn.Close()
+ if err := conn.Handshake(); err != nil {
+ t.Errorf("Unable to handshake: %v", err)
+ return
+ }
+ for {
+ ch, err := conn.Accept()
+ if err == io.EOF {
+ return
+ }
+ if err != nil {
+ t.Errorf("Unable to accept incoming channel request: %v", err)
+ return
+ }
+ if ch.ChannelType() != "session" {
+ ch.Reject(UnknownChannelType, "unknown channel type")
+ continue
+ }
+ ch.Accept()
+ go func() {
+ defer ch.Close()
+ // this string is returned to stdout
+ shell := NewServerShell(ch, "golang")
+ shell.ReadLine()
+ type exitMsg struct {
+ PeersId uint32
+ Request string
+ WantReply bool
+ Status uint32
+ }
+ // TODO(dfc) casting to the concrete type should not be
+ // necessary to send a packet.
+ msg := exitMsg{
+ PeersId: ch.(*channel).theirId,
+ Request: "exit-status",
+ WantReply: false,
+ Status: 0,
+ }
+ ch.(*channel).serverConn.writePacket(marshal(msgChannelRequest, msg))
+ }()
+ }
+ t.Log("done")
+ }()
+
+ config := &ClientConfig{
+ User: "testuser",
+ Auth: []ClientAuth{
+ ClientAuthPassword(pw),
+ },
+ }
+
+ c, err := Dial("tcp", l.Addr().String(), config)
+ if err != nil {
+ t.Fatalf("unable to dial remote side: %s", err)
+ }
+ return c
+}
+
+// Test a simple string is returned to session.Stdout.
+func TestSessionShell(t *testing.T) {
+ conn := dial(t)
+ defer conn.Close()
+ session, err := conn.NewSession()
+ if err != nil {
+ t.Fatalf("Unable to request new session: %s", err)
+ }
+ defer session.Close()
+ stdout := new(bytes.Buffer)
+ session.Stdout = stdout
+ if err := session.Shell(); err != nil {
+ t.Fatalf("Unable to execute command: %s", err)
+ }
+ if err := session.Wait(); err != nil {
+ t.Fatalf("Remote command did not exit cleanly: %s", err)
+ }
+ actual := stdout.String()
+ if actual != "golang" {
+ t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual)
+ }
+}
+
+// TODO(dfc) add support for Std{in,err}Pipe when the Server supports it.
+
+// Test a simple string is returned via StdoutPipe.
+func TestSessionStdoutPipe(t *testing.T) {
+ conn := dial(t)
+ defer conn.Close()
+ session, err := conn.NewSession()
+ if err != nil {
+ t.Fatalf("Unable to request new session: %s", err)
+ }
+ defer session.Close()
+ stdout, err := session.StdoutPipe()
+ if err != nil {
+ t.Fatalf("Unable to request StdoutPipe(): %v", err)
+ }
+ var buf bytes.Buffer
+ if err := session.Shell(); err != nil {
+ t.Fatalf("Unable to execute command: %s", err)
+ }
+ done := make(chan bool, 1)
+ go func() {
+ if _, err := io.Copy(&buf, stdout); err != nil {
+ t.Errorf("Copy of stdout failed: %v", err)
+ }
+ done <- true
+ }()
+ if err := session.Wait(); err != nil {
+ t.Fatalf("Remote command did not exit cleanly: %s", err)
+ }
+ <-done
+ actual := buf.String()
+ if actual != "golang" {
+ t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual)
+ }
+}