You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/10/30 14:34:29 UTC

[plc4x] branch feature/plc4go updated: - Fixed a bug in the modbus driver, not correctly incrementing the unitIdentifier - Fixed a bug in the xml-serialization of read- and write-requests - Added a testcase for automatic splitting of requests - Refactored the TestTransport to have separate read- and write-buffers and added methods to fill the read-buffer and drain the write-buffer (This eliminates race-conditions in the testsuite)

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/plc4go
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/feature/plc4go by this push:
     new 042c90e  - Fixed a bug in the modbus driver, not correctly incrementing the unitIdentifier - Fixed a bug in the xml-serialization of read- and write-requests - Added a testcase for automatic splitting of requests - Refactored the TestTransport to have separate read- and write-buffers and added methods to fill the read-buffer and drain the write-buffer (This eliminates race-conditions in the testsuite)
042c90e is described below

commit 042c90e9c54c9b1a55a44a5764b46f1512891843
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Oct 30 15:34:22 2020 +0100

    - Fixed a bug in the modbus driver, not correctly incrementing the unitIdentifier
    - Fixed a bug in the xml-serialization of read- and write-requests
    - Added a testcase for automatic splitting of requests
    - Refactored the TestTransport to have separate read- and write-buffers and added methods to fill the read-buffer and drain the write-buffer (This eliminates race-conditions in the testsuite)
---
 .../resources/protocols/modbus/DriverTestsuite.xml | 102 +++++++++++++++
 .../testing/protocols/modbus/DriverTestsuite.xml   | 142 ++++++++++++---------
 .../plc4go/internal/plc4go/modbus/ModbusReader.go  |   6 +-
 .../internal/plc4go/model/DefaultPlcReadRequest.go |   4 +-
 .../internal/plc4go/testutils/DriverTestRunner.go  |  47 +++++--
 .../plc4go/internal/plc4go/testutils/TestUtils.go  |   2 +-
 .../plc4go/transports/TransportInstance.go         |  19 +--
 .../plc4go/transports/test/TestTransport.go        |  75 ++++++-----
 8 files changed, 281 insertions(+), 116 deletions(-)

diff --git a/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml b/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
index 1dd995f..4d8f8cb 100644
--- a/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
+++ b/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
@@ -229,4 +229,106 @@
     </steps>
   </testcase>
 
+  <testcase>
+    <name>Multi element read request</name>
+    <steps>
+      <api-request name="Receive Read Request from application">
+        <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
+          <fields>
+            <field className="org.apache.plc4x.test.driver.model.api.TestField">
+              <name>hurz1</name>
+              <address>holding-register:1:REAL</address>
+            </field>
+            <field className="org.apache.plc4x.test.driver.model.api.TestField">
+              <name>hurz2</name>
+              <address>holding-register:3:REAL</address>
+            </field>
+          </fields>
+        </TestReadRequest>
+      </api-request>
+      <outgoing-plc-message name="Send First Item Modbus Input-Register Read Request">
+        <!-- 000a00000006010300000004 -->
+        <parser-arguments>
+          <response>false</response>
+        </parser-arguments>
+        <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+          <transactionIdentifier>1</transactionIdentifier>
+          <unitIdentifier>1</unitIdentifier>
+          <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
+            <startingAddress>0</startingAddress>
+            <quantity>2</quantity>
+          </pdu>
+        </ModbusTcpADU>
+      </outgoing-plc-message>
+      <incoming-plc-message name="Receive First Item Modbus Input-Register Read Response">
+        <!-- 000b0000000b0103080000000000000000 -->
+        <parser-arguments>
+          <response>true</response>
+        </parser-arguments>
+        <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+          <transactionIdentifier>1</transactionIdentifier>
+          <unitIdentifier>1</unitIdentifier>
+          <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersResponse">
+            <value>QEkP20BJD9s=</value>
+          </pdu>
+        </ModbusTcpADU>
+      </incoming-plc-message>
+      <outgoing-plc-message name="Send Second Item Modbus Input-Register Read Request">
+        <parser-arguments>
+          <response>false</response>
+        </parser-arguments>
+        <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+          <transactionIdentifier>1</transactionIdentifier>
+          <unitIdentifier>2</unitIdentifier>
+          <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
+            <startingAddress>2</startingAddress>
+            <quantity>2</quantity>
+          </pdu>
+        </ModbusTcpADU>
+      </outgoing-plc-message>
+      <incoming-plc-message name="Receive Second Item Modbus Input-Register Read Response">
+        <parser-arguments>
+          <response>true</response>
+        </parser-arguments>
+        <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+          <transactionIdentifier>1</transactionIdentifier>
+          <unitIdentifier>2</unitIdentifier>
+          <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersResponse">
+            <value>QEkP20BJD9s=</value>
+          </pdu>
+        </ModbusTcpADU>
+      </incoming-plc-message>
+      <api-response name="Report Read Response to application">
+        <PlcReadResponse>
+          <PlcReadRequest>
+            <fields>
+              <hurz1>
+                <ModbusFieldHoldingRegister>
+                  <address>0</address>
+                  <numberOfElements>1</numberOfElements>
+                  <dataType>IEC61131_REAL</dataType>
+                </ModbusFieldHoldingRegister>
+              </hurz1>
+              <hurz2>
+                <ModbusFieldHoldingRegister>
+                  <address>2</address>
+                  <numberOfElements>1</numberOfElements>
+                  <dataType>IEC61131_REAL</dataType>
+                </ModbusFieldHoldingRegister>
+              </hurz2>
+            </fields>
+          </PlcReadRequest>
+          <values>
+            <hurz1 result="OK">
+              <PlcREAL>3.1415927</PlcREAL>
+            </hurz1>
+            <hurz2 result="OK">
+              <PlcREAL>3.1415927</PlcREAL>
+            </hurz2>
+          </values>
+        </PlcReadResponse>
+      </api-response>
+    </steps>
+  </testcase>
+
 </test:driver-testsuite>
diff --git a/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml b/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
index 1dd995f..afd165f 100644
--- a/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
+++ b/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
@@ -26,18 +26,15 @@
 
   <driver-name>modbus</driver-name>
 
-  <!-- Single element read BOOL (Coil) -->
-
-
-  <!--testcase>
-    <name>Single element read BOOL</name>
+  <testcase>
+    <name>Single element read request</name>
     <steps>
       <api-request name="Receive Read Request from application">
         <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
           <fields>
             <field className="org.apache.plc4x.test.driver.model.api.TestField">
               <name>hurz</name>
-              <address>holding-register:1:BOOL</address>
+              <address>holding-register:1:REAL</address>
             </field>
           </fields>
         </TestReadRequest>
@@ -47,11 +44,11 @@
           <response>false</response>
         </parser-arguments>
         <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
-          <transactionIdentifier>10</transactionIdentifier>
+          <transactionIdentifier>1</transactionIdentifier>
           <unitIdentifier>1</unitIdentifier>
           <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
             <startingAddress>0</startingAddress>
-            <quantity>4</quantity>
+            <quantity>2</quantity>
           </pdu>
         </ModbusTcpADU>
       </outgoing-plc-message>
@@ -60,7 +57,7 @@
           <response>true</response>
         </parser-arguments>
         <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
-          <transactionIdentifier>10</transactionIdentifier>
+          <transactionIdentifier>1</transactionIdentifier>
           <unitIdentifier>1</unitIdentifier>
           <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersResponse">
             <value>QEkP20BJD9s=</value>
@@ -68,53 +65,42 @@
         </ModbusTcpADU>
       </incoming-plc-message>
       <api-response name="Report Read Response to application">
-        <DefaultPlcReadResponse className="org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse">
-          <request className="org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest">
-            <hurz className="org.apache.plc4x.java.modbus.field.ModbusFieldHoldingRegister">
-              <address>0</address>
-              <dataType>IEC61131_REAL</dataType>
-              <lengthBytes>8</lengthBytes>
-              <lengthWords>4</lengthWords>
-              <dataTypeSize>4</dataTypeSize>
+        <PlcReadResponse>
+          <PlcReadRequest>
+            <fields>
+              <hurz>
+                <ModbusFieldHoldingRegister>
+                  <address>0</address>
+                  <numberOfElements>1</numberOfElements>
+                  <dataType>IEC61131_REAL</dataType>
+                </ModbusFieldHoldingRegister>
+              </hurz>
+            </fields>
+          </PlcReadRequest>
+          <values>
+            <hurz result="OK">
+              <PlcREAL>3.1415927</PlcREAL>
             </hurz>
-          </request>
-          <hurz>
-            <code>OK</code>
-            <value className="org.apache.plc4x.java.api.value.PlcList">
-              <object>java.util.Collections..UnmodifiableRandomAccessList</object>
-              <object>org.apache.plc4x.java.api.value.PlcREAL</object>
-              <object>
-                <object>java.lang.Float</object>
-                <object>3.1415927</object>
-              </object>
-              <object>org.apache.plc4x.java.api.value.PlcREAL</object>
-              <object>
-                <object>java.lang.Float</object>
-                <object>3.1415927</object>
-              </object>
-            </value>
-          </hurz>
-        </DefaultPlcReadResponse>
+          </values>
+        </PlcReadResponse>
       </api-response>
     </steps>
-  </testcase-->
-
+  </testcase>
 
   <testcase>
-    <name>Single element read request</name>
+    <name>Array element read request</name>
     <steps>
       <api-request name="Receive Read Request from application">
         <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
           <fields>
             <field className="org.apache.plc4x.test.driver.model.api.TestField">
               <name>hurz</name>
-              <address>holding-register:1:REAL</address>
+              <address>holding-register:1:REAL[2]</address>
             </field>
           </fields>
         </TestReadRequest>
       </api-request>
       <outgoing-plc-message name="Send Modbus Input-Register Read Request">
-        <!-- 000a00000006010300000004 -->
         <parser-arguments>
           <response>false</response>
         </parser-arguments>
@@ -123,12 +109,11 @@
           <unitIdentifier>1</unitIdentifier>
           <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
             <startingAddress>0</startingAddress>
-            <quantity>2</quantity>
+            <quantity>4</quantity>
           </pdu>
         </ModbusTcpADU>
       </outgoing-plc-message>
       <incoming-plc-message name="Receive Modbus Input-Register Read Response">
-        <!-- 000b0000000b0103080000000000000000 -->
         <parser-arguments>
           <response>true</response>
         </parser-arguments>
@@ -147,7 +132,7 @@
               <hurz>
                 <ModbusFieldHoldingRegister>
                   <address>0</address>
-                  <numberOfElements>1</numberOfElements>
+                  <numberOfElements>2</numberOfElements>
                   <dataType>IEC61131_REAL</dataType>
                 </ModbusFieldHoldingRegister>
               </hurz>
@@ -155,7 +140,10 @@
           </PlcReadRequest>
           <values>
             <hurz result="OK">
-              <PlcREAL>3.1415927</PlcREAL>
+              <PlcList>
+                <PlcREAL>3.1415927</PlcREAL>
+                <PlcREAL>3.1415927</PlcREAL>
+              </PlcList>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -164,19 +152,23 @@
   </testcase>
 
   <testcase>
-    <name>Array element read request</name>
+    <name>Multi element read request</name>
     <steps>
       <api-request name="Receive Read Request from application">
         <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
           <fields>
             <field className="org.apache.plc4x.test.driver.model.api.TestField">
-              <name>hurz</name>
-              <address>holding-register:1:REAL[2]</address>
+              <name>hurz1</name>
+              <address>holding-register:1:REAL</address>
+            </field>
+            <field className="org.apache.plc4x.test.driver.model.api.TestField">
+              <name>hurz2</name>
+              <address>holding-register:3:REAL</address>
             </field>
           </fields>
         </TestReadRequest>
       </api-request>
-      <outgoing-plc-message name="Send Modbus Input-Register Read Request">
+      <outgoing-plc-message name="Send First Item Modbus Input-Register Read Request">
         <!-- 000a00000006010300000004 -->
         <parser-arguments>
           <response>false</response>
@@ -186,11 +178,11 @@
           <unitIdentifier>1</unitIdentifier>
           <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
             <startingAddress>0</startingAddress>
-            <quantity>4</quantity>
+            <quantity>2</quantity>
           </pdu>
         </ModbusTcpADU>
       </outgoing-plc-message>
-      <incoming-plc-message name="Receive Modbus Input-Register Read Response">
+      <incoming-plc-message name="Receive First Item Modbus Input-Register Read Response">
         <!-- 000b0000000b0103080000000000000000 -->
         <parser-arguments>
           <response>true</response>
@@ -203,26 +195,58 @@
           </pdu>
         </ModbusTcpADU>
       </incoming-plc-message>
+      <outgoing-plc-message name="Send Second Item Modbus Input-Register Read Request">
+        <parser-arguments>
+          <response>false</response>
+        </parser-arguments>
+        <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+          <transactionIdentifier>1</transactionIdentifier>
+          <unitIdentifier>2</unitIdentifier>
+          <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
+            <startingAddress>2</startingAddress>
+            <quantity>2</quantity>
+          </pdu>
+        </ModbusTcpADU>
+      </outgoing-plc-message>
+      <incoming-plc-message name="Receive Second Item Modbus Input-Register Read Response">
+        <parser-arguments>
+          <response>true</response>
+        </parser-arguments>
+        <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+          <transactionIdentifier>1</transactionIdentifier>
+          <unitIdentifier>2</unitIdentifier>
+          <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersResponse">
+            <value>QEkP20BJD9s=</value>
+          </pdu>
+        </ModbusTcpADU>
+      </incoming-plc-message>
       <api-response name="Report Read Response to application">
         <PlcReadResponse>
           <PlcReadRequest>
             <fields>
-              <hurz>
+              <hurz1>
                 <ModbusFieldHoldingRegister>
                   <address>0</address>
-                  <numberOfElements>2</numberOfElements>
+                  <numberOfElements>1</numberOfElements>
                   <dataType>IEC61131_REAL</dataType>
                 </ModbusFieldHoldingRegister>
-              </hurz>
+              </hurz1>
+              <hurz2>
+                <ModbusFieldHoldingRegister>
+                  <address>2</address>
+                  <numberOfElements>1</numberOfElements>
+                  <dataType>IEC61131_REAL</dataType>
+                </ModbusFieldHoldingRegister>
+              </hurz2>
             </fields>
           </PlcReadRequest>
           <values>
-            <hurz result="OK">
-              <PlcList>
-                <PlcREAL>3.1415927</PlcREAL>
-                <PlcREAL>3.1415927</PlcREAL>
-              </PlcList>
-            </hurz>
+            <hurz1 result="OK">
+              <PlcREAL>3.1415927</PlcREAL>
+            </hurz1>
+            <hurz2 result="OK">
+              <PlcREAL>3.1415927</PlcREAL>
+            </hurz2>
           </values>
         </PlcReadResponse>
       </api-response>
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
index d8ad0a8..ec10ac2 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
@@ -38,15 +38,15 @@ type ModbusReader struct {
 	spi.PlcReader
 }
 
-func NewModbusReader(transactionIdentifier uint16, messageCodec spi.MessageCodec) ModbusReader {
-	return ModbusReader{
+func NewModbusReader(transactionIdentifier uint16, messageCodec spi.MessageCodec) *ModbusReader {
+	return &ModbusReader{
 		transactionIdentifier: transactionIdentifier,
 		unitIdentifier:        0,
 		messageCodec:          messageCodec,
 	}
 }
 
-func (m ModbusReader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequestResult {
+func (m *ModbusReader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequestResult {
 	result := make(chan model.PlcReadRequestResult)
 	// If we are requesting only one field, use a
 	if len(readRequest.GetFieldNames()) == 1 {
diff --git a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go b/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go
index afbd09f..4d34d93 100644
--- a/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go
+++ b/sandbox/plc4go/internal/plc4go/model/DefaultPlcReadRequest.go
@@ -144,7 +144,7 @@ func (m DefaultPlcReadRequest) MarshalXML(e *xml.Encoder, start xml.StartElement
 		return err
 	}
 
-	if err := e.EncodeToken(xml.StartElement{Name: xml.Name{Local: "Fields"}}); err != nil {
+	if err := e.EncodeToken(xml.StartElement{Name: xml.Name{Local: "fields"}}); err != nil {
 		return err
 	}
 	for fieldName, field := range m.Fields {
@@ -158,7 +158,7 @@ func (m DefaultPlcReadRequest) MarshalXML(e *xml.Encoder, start xml.StartElement
 			return err
 		}
 	}
-	if err := e.EncodeToken(xml.EndElement{Name: xml.Name{Local: "Fields"}}); err != nil {
+	if err := e.EncodeToken(xml.EndElement{Name: xml.Name{Local: "fields"}}); err != nil {
 		return err
 	}
 
diff --git a/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go b/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go
index aea4eda..cfaad1a 100644
--- a/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go
+++ b/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go
@@ -27,6 +27,7 @@ import (
 	"os"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/modbus/readwrite/model"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports/test"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
 	"plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go"
@@ -54,21 +55,34 @@ func (m DriverTestsuite) Run(driverManager plc4go.PlcDriverManager, testcase Tes
 		return errors.New("error getting a connection: " + connectionResult.Err.Error())
 	}
 
+	fmt.Printf("\n\n-------------------------------------------------------\nExecuting testcase: %s \n", testcase.name)
+
 	// Run the setup steps
 	for _, testStep := range m.setupSteps {
-		m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+		err := m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+		if err != nil {
+			return errors.New("error in setup step " + testStep.name + ": " + err.Error())
+		}
 	}
 
 	// Run the actual scenario steps
 	for _, testStep := range testcase.steps {
-		m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+		err := m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+		if err != nil {
+			return errors.New("error in step " + testStep.name + ": " + err.Error())
+		}
 	}
 
 	// Run the teardown steps
 	for _, testStep := range m.teardownSteps {
-		m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+		err := m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+		if err != nil {
+			return errors.New("error in teardown step " + testStep.name + ": " + err.Error())
+		}
 	}
 
+	fmt.Printf("-------------------------------------------------------\nDone\n-------------------------------------------------------\n")
+
 	return nil
 }
 
@@ -77,7 +91,12 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 	if !ok {
 		return errors.New("couldn't access connections transport instance")
 	}
-	transportInstance := mc.GetTransportInstance()
+	testTransportInstance, ok := mc.GetTransportInstance().(transports.TestTransportInstance)
+	if !ok {
+		return errors.New("transport must be of type TestTransport")
+	}
+
+	fmt.Printf(" - Executing step: %s \n", step.name)
 
 	switch step.stepType {
 	case StepType_API_REQUEST:
@@ -167,7 +186,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		// Serialize the model into bytes
 		ser, ok := message.(utils.Serializable)
 		if !ok {
-			return errors.New("error converting type into Serializable type: " + err.Error())
+			return errors.New("error converting type into Serializable type")
 		}
 		wb := utils.WriteBufferNew()
 		err = ser.Serialize(*wb)
@@ -177,7 +196,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		expectedRawOutput := wb.GetBytes()
 
 		// Read exactly this amount of bytes from the transport
-		rawOutput, err := transportInstance.Read(uint32(len(expectedRawOutput)))
+		rawOutput, err := testTransportInstance.DrainWriteBuffer(uint32(len(expectedRawOutput)))
 		if err != nil {
 			return errors.New("error getting bytes from transport: " + err.Error())
 		}
@@ -195,7 +214,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		if err != nil {
 			return errors.New("error decoding hex-encoded byte data: " + err.Error())
 		}
-		rawInput, err := transportInstance.Read(uint32(len(expectedRawInput)))
+		rawInput, err := testTransportInstance.DrainWriteBuffer(uint32(len(expectedRawInput)))
 		if err != nil {
 			return errors.New("error getting bytes from transport: " + err.Error())
 		}
@@ -220,7 +239,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		// Serialize the model into bytes
 		ser, ok := message.(utils.Serializable)
 		if !ok {
-			return errors.New("error converting type into Serializable type: " + err.Error())
+			return errors.New("error converting type into Serializable type")
 		}
 		wb := utils.WriteBufferNew()
 		err = ser.Serialize(*wb)
@@ -229,7 +248,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		}
 
 		// Send these bytes to the transport
-		err = transportInstance.Write(wb.GetBytes())
+		err = testTransportInstance.FillReadBuffer(wb.GetBytes())
 		if err != nil {
 			return errors.New("error writing data to transport: " + err.Error())
 		}
@@ -241,7 +260,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		}
 
 		// Send these bytes to the transport
-		err = transportInstance.Write(rawInput)
+		err = testTransportInstance.FillReadBuffer(rawInput)
 		if err != nil {
 			return errors.New("error writing data to transport: " + err.Error())
 		}
@@ -255,7 +274,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		time.Sleep(time.Duration(delay))
 	case StepType_TERMINATE:
 		// Simply close the transport connection
-		err := transportInstance.Close()
+		err := testTransportInstance.Close()
 		if err != nil {
 			return errors.New("error closing transport: " + err.Error())
 		}
@@ -318,7 +337,11 @@ func RunDriverTestsuite(t *testing.T, driver plc4go.PlcDriver, testPath string)
 	driverManager.RegisterDriver(driver)
 
 	for _, testcase := range testsuite.testcases {
-		testsuite.Run(driverManager, testcase)
+		err := testsuite.Run(driverManager, testcase)
+		if err != nil {
+			fmt.Printf("-------------------------------------------------------\nFailure\n%s\n-------------------------------------------------------\n", err.Error())
+			t.Fail()
+		}
 	}
 	// Execute the tests in the testsuite
 	fmt.Printf(testsuite.name)
diff --git a/sandbox/plc4go/internal/plc4go/testutils/TestUtils.go b/sandbox/plc4go/internal/plc4go/testutils/TestUtils.go
index a3e21ff..a81d561 100644
--- a/sandbox/plc4go/internal/plc4go/testutils/TestUtils.go
+++ b/sandbox/plc4go/internal/plc4go/testutils/TestUtils.go
@@ -46,7 +46,7 @@ func CompareResults(actualString []byte, referenceString []byte) error {
 		if err := enc.Encode(diff); err != nil {
 			return errors.New("Error outputting results: " + err.Error())
 		}
-		return errors.New("there were differences")
+		return errors.New("there were differences: Expected: \n" + string(referenceString) + "\nBut Got: \n" + string(actualString))
 	}
 	return nil
 }
diff --git a/sandbox/plc4go/internal/plc4go/transports/TransportInstance.go b/sandbox/plc4go/internal/plc4go/transports/TransportInstance.go
index c4ec070..2f16685 100644
--- a/sandbox/plc4go/internal/plc4go/transports/TransportInstance.go
+++ b/sandbox/plc4go/internal/plc4go/transports/TransportInstance.go
@@ -19,15 +19,18 @@
 package transports
 
 type TransportInstance interface {
+	Connect() error
+	Close() error
 
-    Connect() error
-    Close() error
-
-    GetNumReadableBytes() (uint32, error)
-    PeekReadableBytes(numBytes uint32) ([]uint8, error)
-    Read(numBytes uint32) ([]uint8, error)
-
-    Write(data []uint8) error
+	GetNumReadableBytes() (uint32, error)
+	PeekReadableBytes(numBytes uint32) ([]uint8, error)
+	Read(numBytes uint32) ([]uint8, error)
 
+	Write(data []uint8) error
 }
 
+type TestTransportInstance interface {
+	TransportInstance
+	FillReadBuffer(data []uint8) error
+	DrainWriteBuffer(numBytes uint32) ([]uint8, error)
+}
diff --git a/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go b/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go
index d8eb716..d46f468 100644
--- a/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go
+++ b/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go
@@ -19,74 +19,87 @@
 package test
 
 import (
-    "errors"
-    "net/url"
-    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports"
+	"errors"
+	"net/url"
+	"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports"
 )
 
 type TestTransport struct {
-    transports.Transport
+	transports.Transport
 }
 
 func NewTestTransport() *TestTransport {
-    return &TestTransport{}
+	return &TestTransport{}
 }
 
 func (m TestTransport) GetTransportCode() string {
-    return "test"
+	return "test"
 }
 
 func (m TestTransport) GetTransportName() string {
-    return "Test Transport"
+	return "Test Transport"
 }
 
 func (m TestTransport) CreateTransportInstance(transportUrl url.URL, options map[string][]string) (transports.TransportInstance, error) {
-    transportInstance := NewTestTransportInstance(&m)
-
-    castFunc := func(typ interface{}) (transports.TransportInstance, error) {
-        if transportInstance, ok := typ.(transports.TransportInstance); ok {
-            return transportInstance, nil
-        }
-        return nil, errors.New("couldn't cast to TransportInstance")
-    }
-    return castFunc(transportInstance)
+	transportInstance := NewTestTransportInstance(&m)
+
+	castFunc := func(typ interface{}) (transports.TransportInstance, error) {
+		if transportInstance, ok := typ.(transports.TransportInstance); ok {
+			return transportInstance, nil
+		}
+		return nil, errors.New("couldn't cast to TransportInstance")
+	}
+	return castFunc(transportInstance)
 }
 
 type TestTransportInstance struct {
-    buffer []byte
-    transport *TestTransport
+	readBuffer  []byte
+	writeBuffer []byte
+	transport   *TestTransport
 }
 
 func NewTestTransportInstance(transport *TestTransport) *TestTransportInstance {
-    return &TestTransportInstance {
-        buffer: []byte{},
-        transport: transport,
-    }
+	return &TestTransportInstance{
+		readBuffer:  []byte{},
+		writeBuffer: []byte{},
+		transport:   transport,
+	}
 }
 
 func (m *TestTransportInstance) Connect() error {
-    return nil
+	return nil
 }
 
 func (m *TestTransportInstance) Close() error {
-    return nil
+	return nil
 }
 
 func (m *TestTransportInstance) GetNumReadableBytes() (uint32, error) {
-    return uint32(len(m.buffer)), nil
+	return uint32(len(m.readBuffer)), nil
 }
 
 func (m *TestTransportInstance) PeekReadableBytes(numBytes uint32) ([]uint8, error) {
-    return m.buffer[0:numBytes], nil
+	return m.readBuffer[0:numBytes], nil
 }
 
 func (m *TestTransportInstance) Read(numBytes uint32) ([]uint8, error) {
-    data := m.buffer[0:int(numBytes)]
-    m.buffer = m.buffer[int(numBytes):]
-    return data, nil
+	data := m.readBuffer[0:int(numBytes)]
+	m.readBuffer = m.readBuffer[int(numBytes):]
+	return data, nil
 }
 
 func (m *TestTransportInstance) Write(data []uint8) error {
-    m.buffer = append(m.buffer, data...)
-    return nil
+	m.writeBuffer = append(m.writeBuffer, data...)
+	return nil
+}
+
+func (m *TestTransportInstance) FillReadBuffer(data []uint8) error {
+	m.readBuffer = append(m.readBuffer, data...)
+	return nil
+}
+
+func (m *TestTransportInstance) DrainWriteBuffer(numBytes uint32) ([]uint8, error) {
+	data := m.writeBuffer[0:int(numBytes)]
+	m.writeBuffer = m.writeBuffer[int(numBytes):]
+	return data, nil
 }