mirror of https://github.com/elisescu/tty-share
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
2.3 KiB
Go
118 lines
2.3 KiB
Go
7 years ago
|
package testing
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"net"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type fakeWriteCb func(io.Writer, []byte) (int, error)
|
||
|
|
||
|
// Use this carefully. Not thread safe
|
||
|
type fakeTCPConn struct {
|
||
|
readPipe *io.PipeReader
|
||
|
writePipe *io.PipeWriter
|
||
|
debug bool
|
||
|
writeCb fakeWriteCb
|
||
|
deadline time.Time
|
||
|
}
|
||
|
|
||
|
func NewFakeTCPConn(debug bool, writeCb fakeWriteCb) *fakeTCPConn {
|
||
|
ret := &fakeTCPConn{debug: debug}
|
||
|
ret.readPipe, ret.writePipe = io.Pipe()
|
||
|
ret.writeCb = writeCb
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) Write(b []byte) (int, error) {
|
||
|
if conn.debug {
|
||
|
fmt.Printf("fakeTCP.Write: %s\n", string(b))
|
||
|
}
|
||
|
|
||
|
if conn.writeCb != nil {
|
||
|
return conn.writeCb(conn.writePipe, b)
|
||
|
}
|
||
|
return conn.writePipe.Write(b)
|
||
|
}
|
||
|
|
||
|
// If Read times out, the connection can't be used anymore.
|
||
|
// TODO: maybe fix that
|
||
|
func (conn *fakeTCPConn) Read(b []byte) (int, error) {
|
||
|
c := make(chan int)
|
||
|
n := 0
|
||
|
err := error(nil)
|
||
|
|
||
|
doRead := func() {
|
||
|
n, err = conn.readPipe.Read(b)
|
||
|
|
||
|
if conn.debug {
|
||
|
fmt.Printf("fakeTCP.Read: %s\n", string(b))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If we have no deadline, then let Read wait forever
|
||
|
var zeroTime time.Time
|
||
|
if conn.deadline == zeroTime {
|
||
|
doRead()
|
||
|
return n, err
|
||
|
}
|
||
|
|
||
|
// Otherwise, do the read in a go routine
|
||
|
go func() {
|
||
|
doRead()
|
||
|
close(c)
|
||
|
}()
|
||
|
|
||
|
select {
|
||
|
case <-c:
|
||
|
return n, err
|
||
|
case <-time.After(conn.deadline.Sub(time.Now())):
|
||
|
// TODO: we timed out. What to do? Close the pipe?
|
||
|
conn.writePipe.CloseWithError(errors.New("timeout"))
|
||
|
conn.readPipe.CloseWithError(errors.New("timeout"))
|
||
|
// don't return here - closing with error, will make the readPipe.Read return
|
||
|
// the above error, passed to ClosedWithError
|
||
|
}
|
||
|
|
||
|
return n, err
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) Close() (err error) {
|
||
|
err = conn.writePipe.Close()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
err = conn.readPipe.Close()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) LocalAddr() net.Addr {
|
||
|
panic("LocalAddr not implemented")
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) RemoteAddr() net.Addr {
|
||
|
panic("RemoteAddr not implemented")
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) SetDeadline(t time.Time) error {
|
||
|
conn.deadline = t
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) SetReadDeadline(t time.Time) error {
|
||
|
panic("SetReadDeadline not implemented")
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (conn *fakeTCPConn) SetWriteDeadline(t time.Time) error {
|
||
|
panic("SetWriteDeadline not implemented")
|
||
|
return nil
|
||
|
}
|