X-Git-Url: https://git.giacomolli.uk/onehouse/blobdiff_plain/c87607884883cca4e47736db79a11c03f175138f..db3091ee257788c92421a5b8b1af49d429ce8f8e:/driver/m31/tcp_client_test.go diff --git a/driver/m31/tcp_client_test.go b/driver/m31/tcp_client_test.go index 6e4979b..0067566 100644 --- a/driver/m31/tcp_client_test.go +++ b/driver/m31/tcp_client_test.go @@ -311,6 +311,59 @@ func TestTCPClientUsesCallerDeadlineAndStartsClosed(t *testing.T) { }) } +func TestTCPClientReadTimeoutStartsAfterRequestWrite(t *testing.T) { + synctest.Test(t, func(t *testing.T) { + conn, peer := net.Pipe() + c := &tcpClient{conn: conn, unit: 1} + t.Cleanup(func() { + require.NoError(t, c.Close()) + require.NoError(t, peer.Close()) + }) + + done := make(chan error, 1) + go func() { + time.Sleep(500 * time.Millisecond) + + var request [12]byte + + _, err := io.ReadFull(peer, request[:]) + done <- err + }() + + started := time.Now() + _, err := c.ReadCoils(t.Context(), 1) + require.Error(t, err) + require.NoError(t, <-done) + require.Equal(t, 2500*time.Millisecond, time.Since(started)) + }) +} + +func TestTCPClientStopsAfterCancelledRequestWrite(t *testing.T) { + synctest.Test(t, func(t *testing.T) { + conn, peer := net.Pipe() + t.Cleanup(func() { + require.NoError(t, peer.Close()) + }) + + ctx, cancel := context.WithCancel(t.Context()) + defer cancel() + + transport := &interruptConn{ + Conn: conn, + cancel: cancel, + interrupted: make(chan struct{}), + } + c := &tcpClient{conn: transport, unit: 1} + t.Cleanup(func() { + require.NoError(t, c.Close()) + }) + + _, err := c.ReadCoils(ctx, 1) + require.ErrorIs(t, err, context.Canceled) + require.NotErrorIs(t, err, os.ErrDeadlineExceeded) + }) +} + func TestTCPClientCancellationPreservesIndependentFailure(t *testing.T) { synctest.Test(t, func(t *testing.T) { conn, peer := net.Pipe() @@ -363,11 +416,15 @@ type interruptConn struct { interrupted chan struct{} } -func (c *interruptConn) Write([]byte) (int, error) { +func (c *interruptConn) Write(data []byte) (int, error) { c.cancel() <-c.interrupted - return 0, c.failure + if c.failure != nil { + return 0, c.failure + } + + return len(data), nil } func (c *interruptConn) SetDeadline(deadline time.Time) error {