~james-page/ubuntu/saucy/juju-core/1.16.5

« back to all changes in this revision

Viewing changes to src/code.google.com/p/go.crypto/ssh/test/test_unix_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-09-03 14:22:22 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20130903142222-9mes2r8wqr0bs7lp
Tags: 1.13.3-0ubuntu1
New upstream point release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
        "os/exec"
25
25
        "os/user"
26
26
        "path/filepath"
27
 
        "sync"
28
27
        "testing"
29
28
        "text/template"
30
 
        "time"
31
29
 
32
30
        "code.google.com/p/go.crypto/ssh"
33
31
)
82
80
        configfile string
83
81
        cmd        *exec.Cmd
84
82
        output     bytes.Buffer // holds stderr from sshd process
 
83
 
 
84
        // Client half of the network connection.
 
85
        clientConn net.Conn
85
86
}
86
87
 
87
88
func username() string {
135
136
        return config
136
137
}
137
138
 
 
139
// unixConnection creates two halves of a connected net.UnixConn.  It
 
140
// is used for connecting the Go SSH client with sshd without opening
 
141
// ports.
 
142
func unixConnection() (*net.UnixConn, *net.UnixConn, error) {
 
143
        dir, err := ioutil.TempDir("", "unixConnection")
 
144
        if err != nil {
 
145
                return nil, nil, err
 
146
        }
 
147
        defer os.Remove(dir)
 
148
 
 
149
        addr := filepath.Join(dir, "ssh")
 
150
        listener, err := net.Listen("unix", addr)
 
151
        if err != nil {
 
152
                return nil, nil, err
 
153
        }
 
154
        defer listener.Close()
 
155
        c1, err := net.Dial("unix", addr)
 
156
        if err != nil {
 
157
                return nil, nil, err
 
158
        }
 
159
 
 
160
        c2, err := listener.Accept()
 
161
        if err != nil {
 
162
                c1.Close()
 
163
                return nil, nil, err
 
164
        }
 
165
 
 
166
        return c1.(*net.UnixConn), c2.(*net.UnixConn), nil
 
167
}
 
168
 
138
169
func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.ClientConn, error) {
139
170
        sshd, err := exec.LookPath("sshd")
140
171
        if err != nil {
141
172
                s.t.Skipf("skipping test: %v", err)
142
173
        }
 
174
 
 
175
        c1, c2, err := unixConnection()
 
176
        if err != nil {
 
177
                s.t.Fatalf("unixConnection: %v", err)
 
178
        }
 
179
 
143
180
        s.cmd = exec.Command(sshd, "-f", s.configfile, "-i", "-e")
144
 
        r1, w1, err := os.Pipe()
145
 
        if err != nil {
146
 
                s.t.Fatal(err)
147
 
        }
148
 
        s.cmd.Stdout = w1
149
 
        r2, w2, err := os.Pipe()
150
 
        if err != nil {
151
 
                s.t.Fatal(err)
152
 
        }
153
 
        s.cmd.Stdin = r2
 
181
        f, err := c2.File()
 
182
        if err != nil {
 
183
                s.t.Fatalf("UnixConn.File: %v", err)
 
184
        }
 
185
        s.cmd.Stdin = f
 
186
        s.cmd.Stdout = f
154
187
        s.cmd.Stderr = os.Stderr
155
188
        if err := s.cmd.Start(); err != nil {
156
189
                s.t.Fail()
157
190
                s.Shutdown()
158
191
                s.t.Fatalf("s.cmd.Start: %v", err)
159
192
        }
160
 
 
161
 
        return ssh.Client(&client{wc: w2, r: r1}, config)
 
193
        s.clientConn = c1
 
194
        return ssh.Client(c1, config)
162
195
}
163
196
 
164
197
func (s *server) Dial(config *ssh.ClientConfig) *ssh.ClientConn {
185
218
        s.cleanup()
186
219
}
187
220
 
188
 
// client wraps a pair of Reader/WriteClosers to implement the
189
 
// net.Conn interface. Importantly, client also mocks the
190
 
// ability of net.Conn to support concurrent calls to Read/Write
191
 
// and Close. See golang.org/issue/5138 for more details.
192
 
type client struct {
193
 
        wc         io.WriteCloser
194
 
        r          io.Reader
195
 
        sync.Mutex // protects refcount and closing
196
 
        refcount   int
197
 
        closing    bool
198
 
}
199
 
 
200
 
var errClosing = errors.New("use of closed network connection")
201
 
 
202
 
func (c *client) LocalAddr() net.Addr              { return nil }
203
 
func (c *client) RemoteAddr() net.Addr             { return nil }
204
 
func (c *client) SetDeadline(time.Time) error      { return nil }
205
 
func (c *client) SetReadDeadline(time.Time) error  { return nil }
206
 
func (c *client) SetWriteDeadline(time.Time) error { return nil }
207
 
 
208
 
// incref, decref are copied from the net package (see net/fd_unix.go) to
209
 
// implement the concurrent Close contract that net.Conn implementations
210
 
// from that that package provide.
211
 
 
212
 
func (c *client) incRef(closing bool) error {
213
 
        c.Lock()
214
 
        defer c.Unlock()
215
 
        if c.closing {
216
 
                return errClosing
217
 
        }
218
 
        c.refcount++
219
 
        if closing {
220
 
                c.closing = true
221
 
        }
222
 
        return nil
223
 
}
224
 
 
225
 
func (c *client) decRef() {
226
 
        c.Lock()
227
 
        defer c.Unlock()
228
 
        c.refcount--
229
 
        if c.closing && c.refcount == 0 {
230
 
                c.wc.Close()
231
 
        }
232
 
}
233
 
 
234
 
func (c *client) Close() error {
235
 
        if err := c.incRef(true); err != nil {
236
 
                return err
237
 
        }
238
 
        c.decRef()
239
 
        return nil
240
 
}
241
 
 
242
 
func (c *client) Read(b []byte) (int, error) {
243
 
        if err := c.incRef(false); err != nil {
244
 
                return 0, err
245
 
        }
246
 
        defer c.decRef()
247
 
        return c.r.Read(b)
248
 
}
249
 
 
250
 
func (c *client) Write(b []byte) (int, error) {
251
 
        if err := c.incRef(false); err != nil {
252
 
                return 0, err
253
 
        }
254
 
        defer c.decRef()
255
 
        return c.wc.Write(b)
256
 
}
257
 
 
258
221
// newServer returns a new mock ssh server.
259
222
func newServer(t *testing.T) *server {
260
223
        dir, err := ioutil.TempDir("", "sshtest")