public void UnicastMessage_SingleFailingException(Type exceptionType)
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Retries = 1;
            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(2);
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw (Exception)Activator.CreateInstance(exceptionType); });

            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Return(new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                new DiscreteCollection(true, false, true, false, false, false, false, false)));

            transport.OnValidateResponse(null, null);
            LastCall.IgnoreArguments();

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);

            transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            mocks.VerifyAll();
        }
        public void UnicastMessage_AcknowlegeSlaveException()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            // set the wait to retry property to a small value so the test completes quickly
            transport.WaitToRetryMilliseconds = 5;

            transport.Write(null);
            LastCall.IgnoreArguments();

            // return a slave exception a greater number of times than number of retries to make sure we aren't just retrying
            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new SlaveExceptionResponse(1, Modbus.ReadHoldingRegisters + Modbus.ExceptionOffset, Modbus.Acknowledge))
            .Repeat.Times(transport.Retries + 1);

            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1)));

            transport.Stub(x => x.OnValidateResponse(null, null))
            .IgnoreArguments()
            .Return(true);

            mocks.ReplayAll();

            ReadHoldingInputRegistersRequest  request          = new ReadHoldingInputRegistersRequest(Modbus.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse expectedResponse = new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1));
            ReadHoldingInputRegistersResponse response         = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            Assert.AreEqual(expectedResponse.MessageFrame, response.MessageFrame);

            mocks.VerifyAll();
        }
        public void UnicastMessage_ReReads_IfShouldRetryReturnTrue()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.RetryOnOldResponseThreshold = 3;
            transport.Stub(x => x.Write(null)).IgnoreArguments();

            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1)))
            .Repeat.Times(2)
            .Message("ReadResponse should be called twice, one for the retry");

            transport.Expect(x => x.OnValidateResponse(null, null)).IgnoreArguments();

            Expect.Call(transport.OnShouldRetryResponse(null, null))
            .IgnoreArguments()
            .Return(true)
            .Repeat.Times(1);
            Expect.Call(transport.OnShouldRetryResponse(null, null))
            .IgnoreArguments()
            .Return(false)
            .Repeat.Times(1);

            mocks.ReplayAll();
            ReadHoldingInputRegistersRequest  request  = new ReadHoldingInputRegistersRequest(Modbus.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse response = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            mocks.VerifyAll();
        }
        public void UnicastMessage()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments();
            // read 4 coils from slave id 2
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Return(new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                new DiscreteCollection(true, false, true, false, false, false, false, false)));
            transport.OnValidateResponse(null, null);
            LastCall.IgnoreArguments();

            mocks.ReplayAll();

            ReadCoilsInputsRequest  request          = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);
            ReadCoilsInputsResponse expectedResponse = new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                                                   new DiscreteCollection(true, false, true, false, false, false, false, false));
            ReadCoilsInputsResponse response = transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            Assert.Equal(expectedResponse.MessageFrame, response.MessageFrame);

            mocks.VerifyAll();
        }
        public void UnicastMessage_ReReadsIfValidateResponseIsFalse()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.WaitToRetryMilliseconds = 5;

            transport.Write(null);
            LastCall.IgnoreArguments();

            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1)))
            .Repeat.Times(2)
            .Message("ReadResponse should be called twice, one for the retry");

            Expect.Call(transport.OnValidateResponse(null, null))
            .IgnoreArguments()
            .Return(false)
            .Repeat.Times(1);
            Expect.Call(transport.OnValidateResponse(null, null))
            .IgnoreArguments()
            .Return(true)
            .Repeat.Times(1);

            mocks.ReplayAll();
            ReadHoldingInputRegistersRequest  request  = new ReadHoldingInputRegistersRequest(Modbus.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse response = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            mocks.VerifyAll();
        }
        public void UnicastMessage_ErrorSlaveException()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments();
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw new SlaveException(); });

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadInputs, 2, 3, 4);

            Assert.Throws <SlaveException>(() => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mocks.VerifyAll();
        }
        public void UnicastMessage_TimeoutException()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(Modbus.DefaultRetries + 1);
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw new TimeoutException(); })
            .Repeat.Times(Modbus.DefaultRetries + 1);

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadInputs, 2, 3, 4);

            transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            mocks.VerifyAll();
        }
        public void UnicastMessage_WrongResponseFunctionCode()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(Modbus.DefaultRetries + 1);
            // read 4 coils from slave id 2
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Return(new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 0, new DiscreteCollection()))
            .Repeat.Times(Modbus.DefaultRetries + 1);

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadInputs, 2, 3, 4);

            Assert.Throws <IOException>(() => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mocks.VerifyAll();
        }
        public void UnicastMessage_TooManyFailingExceptions(Type exceptionType)
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(transport.Retries + 1);

            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw (Exception)Activator.CreateInstance(exceptionType); })
            .Repeat.Times(transport.Retries + 1);

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);

            Assert.Throws(exceptionType, () => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mocks.VerifyAll();
        }
        public void UnicastMessage_TooManyFailingExceptions(Type exceptionType)
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(transport.Retries + 1);

            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw (Exception)Activator.CreateInstance(exceptionType); })
            .Repeat.Times(transport.Retries + 1);

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);

            Action action = () => transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            typeof(AssertUtility).GetMethod("Throws", BindingFlags.Public | BindingFlags.Static).
            MakeGenericMethod(new Type[] { exceptionType }).
            Invoke(transport, new object[] { action });

            mocks.VerifyAll();
        }