LEFT | RIGHT |
(no file at all) | |
| 1 // Copyright 2013 The Go Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. |
| 4 |
| 5 package ssh |
| 6 |
| 7 import ( |
| 8 "io" |
| 9 "sync" |
| 10 "testing" |
| 11 ) |
| 12 |
| 13 // An in-memory packetConn. It is safe to call Close and writePacket |
| 14 // from different goroutines. |
| 15 type memTransport struct { |
| 16 eof bool |
| 17 pending [][]byte |
| 18 write *memTransport |
| 19 sync.Mutex |
| 20 *sync.Cond |
| 21 } |
| 22 |
| 23 func (t *memTransport) readPacket() ([]byte, error) { |
| 24 t.Lock() |
| 25 defer t.Unlock() |
| 26 for { |
| 27 if len(t.pending) > 0 { |
| 28 r := t.pending[0] |
| 29 t.pending = t.pending[1:] |
| 30 return r, nil |
| 31 } |
| 32 if t.eof { |
| 33 return nil, io.EOF |
| 34 } |
| 35 t.Cond.Wait() |
| 36 } |
| 37 } |
| 38 |
| 39 func (t *memTransport) Close() error { |
| 40 t.write.Lock() |
| 41 defer t.write.Unlock() |
| 42 if t.write.eof { |
| 43 return io.EOF |
| 44 } |
| 45 t.write.eof = true |
| 46 t.write.Cond.Broadcast() |
| 47 return nil |
| 48 } |
| 49 |
| 50 func (t *memTransport) writePacket(p []byte) error { |
| 51 t.write.Lock() |
| 52 defer t.write.Unlock() |
| 53 if t.write.eof { |
| 54 return io.EOF |
| 55 } |
| 56 t.write.pending = append(t.write.pending, p) |
| 57 t.write.Cond.Signal() |
| 58 return nil |
| 59 } |
| 60 |
| 61 func memPipe() (a, b packetConn) { |
| 62 t1 := memTransport{} |
| 63 t2 := memTransport{} |
| 64 t1.write = &t2 |
| 65 t2.write = &t1 |
| 66 t1.Cond = sync.NewCond(&t1.Mutex) |
| 67 t2.Cond = sync.NewCond(&t2.Mutex) |
| 68 return &t1, &t2 |
| 69 } |
| 70 |
| 71 func TestmemPipe(t *testing.T) { |
| 72 a, b := memPipe() |
| 73 if err := a.writePacket([]byte{42}); err != nil { |
| 74 t.Fatalf("writePacket: %v", err) |
| 75 } |
| 76 if err := a.Close(); err != nil { |
| 77 t.Fatal("Close: ", err) |
| 78 } |
| 79 p, err := b.readPacket() |
| 80 if err != nil { |
| 81 t.Fatal("readPacket: ", err) |
| 82 } |
| 83 if len(p) != 1 || p[0] != 42 { |
| 84 t.Fatalf("got %v, want {42}", p) |
| 85 } |
| 86 p, err = b.readPacket() |
| 87 if err != io.EOF { |
| 88 t.Fatalf("got %v, %v, want EOF", p, err) |
| 89 } |
| 90 } |
| 91 |
| 92 func TestDoubleClose(t *testing.T) { |
| 93 a, _ := memPipe() |
| 94 err := a.Close() |
| 95 if err != nil { |
| 96 t.Errorf("Close: %v", err) |
| 97 } |
| 98 err = a.Close() |
| 99 if err != io.EOF { |
| 100 t.Errorf("expect EOF on double close.") |
| 101 } |
| 102 } |
LEFT | RIGHT |