diff options
| author | jEzEk <[email protected]> | 2018-10-29 19:41:24 +0100 |
|---|---|---|
| committer | jEzEk <[email protected]> | 2018-10-30 18:04:49 +0100 |
| commit | 01e3ef92338ac79a57aa6542633770366db1ff52 (patch) | |
| tree | 108435e9adc85caf8b359e07a82ed41890126086 /dummyNetConn.go | |
| parent | 788010f11d65572ca0cea2caf65ade6db4a274de (diff) | |
refactor to testingTools.go with more tests
leak testing added
dummy X server replier fo dummy net.Conn tests
Diffstat (limited to 'dummyNetConn.go')
| -rw-r--r-- | dummyNetConn.go | 261 |
1 files changed, 0 insertions, 261 deletions
diff --git a/dummyNetConn.go b/dummyNetConn.go deleted file mode 100644 index 91bae4f..0000000 --- a/dummyNetConn.go +++ /dev/null @@ -1,261 +0,0 @@ -package xgb - -import ( - "bytes" - "errors" - "io" - "net" - "time" -) - -type dAddr struct { - s string -} - -func (_ dAddr) Network() string { return "dummy" } -func (a dAddr) String() string { return a.s } - -var ( - dNCErrNotImplemented = errors.New("command not implemented") - dNCErrClosed = errors.New("server closed") - dNCErrWrite = errors.New("server write failed") - dNCErrRead = errors.New("server read failed") - dNCErrResponse = errors.New("server response error") -) - -type dNCIoResult struct { - n int - err error -} -type dNCIo struct { - b []byte - result chan dNCIoResult -} - -type dNCCWriteLock struct{} -type dNCCWriteUnlock struct{} -type dNCCWriteError struct{} -type dNCCWriteSuccess struct{} -type dNCCReadLock struct{} -type dNCCReadUnlock struct{} -type dNCCReadError struct{} -type dNCCReadSuccess struct{} - -// dummy net.Conn interface. Needs to be constructed via newDummyNetConn([...]) function. -type dNC struct { - reply func([]byte) []byte - addr dAddr - in, out chan dNCIo - control chan interface{} - done chan struct{} -} - -// Results running dummy server, satisfying net.Conn interface for test purposes. -// 'name' parameter will be returned via (*dNC).Local/RemoteAddr().String() -// 'reply' parameter function will be runned only on successful (*dNC).Write(b) with 'b' as parameter to 'reply'. The result will be stored in internal buffer and can be retrieved later via (*dNC).Read([...]) method. -// It is users responsibility to stop and clean up resources with (*dNC).Close, if not needed anymore. -// By default, the (*dNC).Write([...]) and (*dNC).Read([...]) methods are unlocked and will not result in error. -//TODO make (*dNC).SetDeadline, (*dNC).SetReadDeadline, (*dNC).SetWriteDeadline work proprely. -func newDummyNetConn(name string, reply func([]byte) []byte) *dNC { - - s := &dNC{ - reply, - dAddr{name}, - make(chan dNCIo), make(chan dNCIo), - make(chan interface{}), - make(chan struct{}), - } - - in, out := s.in, chan dNCIo(nil) - buf := &bytes.Buffer{} - errorRead, errorWrite := false, false - lockRead := false - - go func() { - defer close(s.done) - for { - select { - case dxsio := <-in: - if errorWrite { - dxsio.result <- dNCIoResult{0, dNCErrWrite} - break - } - - response := s.reply(dxsio.b) - - buf.Write(response) - dxsio.result <- dNCIoResult{len(dxsio.b), nil} - - if !lockRead && buf.Len() > 0 && out == nil { - out = s.out - } - case dxsio := <-out: - if errorRead { - dxsio.result <- dNCIoResult{0, dNCErrRead} - break - } - - n, err := buf.Read(dxsio.b) - dxsio.result <- dNCIoResult{n, err} - - if buf.Len() == 0 { - out = nil - } - case ci := <-s.control: - if ci == nil { - return - } - switch ci.(type) { - case dNCCWriteLock: - in = nil - case dNCCWriteUnlock: - in = s.in - case dNCCWriteError: - errorWrite = true - case dNCCWriteSuccess: - errorWrite = false - case dNCCReadLock: - out = nil - lockRead = true - case dNCCReadUnlock: - lockRead = false - if buf.Len() > 0 && out == nil { - out = s.out - } - case dNCCReadError: - errorRead = true - case dNCCReadSuccess: - errorRead = false - default: - } - } - } - }() - return s -} - -// Shuts down dummy net.Conn server. Every blocking or future method calls will do nothing and result in error. -// Result will be dNCErrClosed if server was allready closed. -// Server can not be unclosed. -func (s *dNC) Close() error { - select { - case s.control <- nil: - <-s.done - return nil - case <-s.done: - } - return dNCErrClosed -} - -// Performs a write action to server. -// If not locked by (*dNC).WriteLock, it results in error or success. If locked, this method will block until unlocked, or closed. -// -// This method can be set to result in error or success, via (*dNC).WriteError() or (*dNC).WriteSuccess() methods. -// -// If setted to result in error, the 'reply' function will NOT be called and internal buffer will NOT increasethe. -// Result will be (0, dNCErrWrite). -// -// If setted to result in success, the 'reply' function will be called and its result will be writen to internal buffer. -// If there is something in the internal buffer, the (*dNC).Read([...]) will be unblocked (if not previously locked with (*dNC).ReadLock). -// Result will be (len(b), nil) -// -// If server was closed previously, result will be (0, dNCErrClosed). -func (s *dNC) Write(b []byte) (int, error) { - resChan := make(chan dNCIoResult) - select { - case s.in <- dNCIo{b, resChan}: - res := <-resChan - return res.n, res.err - case <-s.done: - } - return 0, dNCErrClosed -} - -// Performs a read action from server. -// If locked by (*dNC).ReadLock(), this method will block until unlocked with (*dNC).ReadUnlock(), or server closes. -// -// If not locked, this method can be setted to result imidiatly in error, will block if internal buffer is empty or will perform an read operation from internal buffer. -// -// If setted to result in error via (*dNC).ReadError(), the result will be (0, dNCErrWrite). -// -// If not locked and not setted to result in error via (*dNC).ReadSuccess(), this method will block until internall buffer is not empty, than it returns the result of the buffer read operation via (*bytes.Buffer).Read([...]). -// If the internal buffer is empty after this method, all follwing (*dNC).Read([...]), requests will block until internall buffer is filled after successful write requests. -// -// If server was closed previously, result will be (0, io.EOF). -func (s *dNC) Read(b []byte) (int, error) { - resChan := make(chan dNCIoResult) - select { - case s.out <- dNCIo{b, resChan}: - res := <-resChan - return res.n, res.err - case <-s.done: - } - return 0, io.EOF -} -func (s *dNC) LocalAddr() net.Addr { return s.addr } -func (s *dNC) RemoteAddr() net.Addr { return s.addr } -func (s *dNC) SetDeadline(t time.Time) error { return dNCErrNotImplemented } -func (s *dNC) SetReadDeadline(t time.Time) error { return dNCErrNotImplemented } -func (s *dNC) SetWriteDeadline(t time.Time) error { return dNCErrNotImplemented } - -func (s *dNC) Control(i interface{}) error { - select { - case s.control <- i: - return nil - case <-s.done: - } - return dNCErrClosed -} - -// Locks writing. All write requests will be blocked until write is unlocked with (*dNC).WriteUnlock, or server closes. -func (s *dNC) WriteLock() error { - return s.Control(dNCCWriteLock{}) -} - -// Unlocks writing. All blocked write requests until now will be accepted. -func (s *dNC) WriteUnlock() error { - return s.Control(dNCCWriteUnlock{}) -} - -// Unlocks writing and makes (*dNC).Write to result (0, dNCErrWrite). -func (s *dNC) WriteError() error { - if err := s.WriteUnlock(); err != nil { - return err - } - return s.Control(dNCCWriteError{}) -} - -// Unlocks writing and makes (*dNC).Write([...]) not result in error. See (*dNC).Write for details. -func (s *dNC) WriteSuccess() error { - if err := s.WriteUnlock(); err != nil { - return err - } - return s.Control(dNCCWriteSuccess{}) -} - -// Locks reading. All read requests will be blocked until read is unlocked with (*dNC).ReadUnlock, or server closes. -// (*dNC).Read([...]) wil block even after successful write. -func (s *dNC) ReadLock() error { - return s.Control(dNCCReadLock{}) -} - -// Unlocks reading. If the internall buffer is not empty, next read will not block. -func (s *dNC) ReadUnlock() error { - return s.Control(dNCCReadUnlock{}) -} - -// Unlocks read and makes every blocked and following (*dNC).Read([...]) imidiatly result in error. See (*dNC).Read for details. -func (s *dNC) ReadError() error { - if err := s.ReadUnlock(); err != nil { - return err - } - return s.Control(dNCCReadError{}) -} - -// Unlocks read and makes every blocked and following (*dNC).Read([...]) requests be handled, if according to internal buffer. See (*dNC).Read for details. -func (s *dNC) ReadSuccess() error { - if err := s.ReadUnlock(); err != nil { - return err - } - return s.Control(dNCCReadSuccess{}) -} |
