aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/exp/ssh/server_shell_test.go
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2011-09-17 15:57:24 -0400
committerAdam Langley <agl@golang.org>2011-09-17 15:57:24 -0400
commit605e57d8fee696238f3338c415043f16a7743731 (patch)
treeeb90377904544cacd84f2c6a0e3d6de3ca86f5ef /src/pkg/exp/ssh/server_shell_test.go
parentb71a805cd5131ff6407a25af540e3dd80fa883c2 (diff)
downloadgo-605e57d8fee696238f3338c415043f16a7743731.tar.xz
exp/ssh: new package.
The typical UNIX method for controlling long running process is to send the process signals. Since this doesn't get you very far, various ad-hoc, remote-control protocols have been used over time by programs like Apache and BIND. Implementing an SSH server means that Go code will have a standard, secure way to do this in the future. R=bradfitz, borman, dave, gustavo, dsymonds, r, adg, rsc, rogpeppe, lvd, kevlar, raul.san CC=golang-dev https://golang.org/cl/4962064
Diffstat (limited to 'src/pkg/exp/ssh/server_shell_test.go')
-rw-r--r--src/pkg/exp/ssh/server_shell_test.go134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/pkg/exp/ssh/server_shell_test.go b/src/pkg/exp/ssh/server_shell_test.go
new file mode 100644
index 0000000000..622cf7cfad
--- /dev/null
+++ b/src/pkg/exp/ssh/server_shell_test.go
@@ -0,0 +1,134 @@
+// 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
+
+import (
+ "testing"
+ "os"
+)
+
+type MockChannel struct {
+ toSend []byte
+ bytesPerRead int
+ received []byte
+}
+
+func (c *MockChannel) Accept() os.Error {
+ return nil
+}
+
+func (c *MockChannel) Reject(RejectionReason, string) os.Error {
+ return nil
+}
+
+func (c *MockChannel) Read(data []byte) (n int, err os.Error) {
+ n = len(data)
+ if n == 0 {
+ return
+ }
+ if n > len(c.toSend) {
+ n = len(c.toSend)
+ }
+ if n == 0 {
+ return 0, os.EOF
+ }
+ if c.bytesPerRead > 0 && n > c.bytesPerRead {
+ n = c.bytesPerRead
+ }
+ copy(data, c.toSend[:n])
+ c.toSend = c.toSend[n:]
+ return
+}
+
+func (c *MockChannel) Write(data []byte) (n int, err os.Error) {
+ c.received = append(c.received, data...)
+ return len(data), nil
+}
+
+func (c *MockChannel) Close() os.Error {
+ return nil
+}
+
+func (c *MockChannel) AckRequest(ok bool) os.Error {
+ return nil
+}
+
+func (c *MockChannel) ChannelType() string {
+ return ""
+}
+
+func (c *MockChannel) ExtraData() []byte {
+ return nil
+}
+
+func TestClose(t *testing.T) {
+ c := &MockChannel{}
+ ss := NewServerShell(c, "> ")
+ line, err := ss.ReadLine()
+ if line != "" {
+ t.Errorf("Expected empty line but got: %s", line)
+ }
+ if err != os.EOF {
+ t.Errorf("Error should have been EOF but got: %s", err)
+ }
+}
+
+var keyPressTests = []struct {
+ in string
+ line string
+ err os.Error
+}{
+ {
+ "",
+ "",
+ os.EOF,
+ },
+ {
+ "\r",
+ "",
+ nil,
+ },
+ {
+ "foo\r",
+ "foo",
+ nil,
+ },
+ {
+ "a\x1b[Cb\r", // right
+ "ab",
+ nil,
+ },
+ {
+ "a\x1b[Db\r", // left
+ "ba",
+ nil,
+ },
+ {
+ "a\177b\r", // backspace
+ "b",
+ nil,
+ },
+}
+
+func TestKeyPresses(t *testing.T) {
+ for i, test := range keyPressTests {
+ for j := 0; j < len(test.in); j++ {
+ c := &MockChannel{
+ toSend: []byte(test.in),
+ bytesPerRead: j,
+ }
+ ss := NewServerShell(c, "> ")
+ line, err := ss.ReadLine()
+ if line != test.line {
+ t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line)
+ break
+ }
+ if err != test.err {
+ t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err)
+ break
+ }
+ }
+ }
+}