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/02/26 12:52:40 UTC

[plc4x] branch feature/driver-testsuite updated (4b65179 -> 3905652)

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

cdutz pushed a change to branch feature/driver-testsuite
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from 4b65179  - Worked on getting the test-channel to actually work - Implemented a first somewhat working version of the driver-testsuite execution code
     new b822a45  - Fixed a wrong default endianess problem n the WriteBuffer
     new 3905652  - Continued working on the driver testsuite    - Got the PLC io side working    - Got the sending of requests side working    - TODO: Finish the processing and validation of responses

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../test/resources/testsuite/S7DriverTestsuite.xml |  35 +++---
 .../java/io/netty/bootstrap/Plc4xBootstrap.java    |  17 ---
 .../java/spi/connection/NettyChannelFactory.java   |  23 ++--
 .../plc4x/java/spi/generation/WriteBuffer.java     |   2 +-
 .../plc4x/test/driver/DriverTestsuiteRunner.java   | 122 +++++++++++++++------
 .../java/org/apache/plc4x/test/driver/Lalala.java  |  44 ++++++++
 .../plc4x/test/driver/model/DriverTestsuite.java   |  10 +-
 .../apache/plc4x/test/driver/model/StepType.java   |   3 +-
 .../apache/plc4x/test/driver/model/TestStep.java   |   8 +-
 .../plc4x/test/driver/model/api/TestField.java     |  34 +++---
 .../test/driver/model/api/TestFieldRequest.java}   |  16 +--
 .../test/driver/model/api/TestReadRequest.java     |  25 ++---
 .../plc4x/test/driver/model/api/TestRequest.java   |  10 +-
 .../test/driver/model/api/TestWriteRequest.java    |  25 ++---
 .../main/resources/schemas/driver-testsuite.xsd    |  57 ++++++----
 15 files changed, 269 insertions(+), 162 deletions(-)
 create mode 100644 plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/Lalala.java
 copy sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/python/AliasNode.java => plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestField.java (60%)
 copy plc4j/{examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/model/DummyField.java => utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestFieldRequest.java} (67%)
 copy sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/python/ExprNode.java => plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestReadRequest.java (64%)
 copy sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/python/Node.java => plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestRequest.java (80%)
 copy sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/python/ExprNode.java => plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestWriteRequest.java (64%)


[plc4x] 01/02: - Fixed a wrong default endianess problem n the WriteBuffer

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b822a456ff9313d70b797952da28ee25482ce411
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Feb 26 13:51:08 2020 +0100

    - Fixed a wrong default endianess problem n the WriteBuffer
---
 .../src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
index bffaeee..53d5fc5 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
@@ -36,7 +36,7 @@ public class WriteBuffer {
     private final boolean littleEndian;
 
     public WriteBuffer(int size) {
-        this(size, true);
+        this(size, false);
     }
 
     public WriteBuffer(int size, boolean littleEndian) {


[plc4x] 02/02: - Continued working on the driver testsuite - Got the PLC io side working - Got the sending of requests side working - TODO: Finish the processing and validation of responses

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 39056526f207d42dec8e5f47748d2c8dd1811acc
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Feb 26 13:52:33 2020 +0100

    - Continued working on the driver testsuite
       - Got the PLC io side working
       - Got the sending of requests side working
       - TODO: Finish the processing and validation of responses
---
 .../test/resources/testsuite/S7DriverTestsuite.xml |  35 +++---
 .../java/io/netty/bootstrap/Plc4xBootstrap.java    |  17 ---
 .../java/spi/connection/NettyChannelFactory.java   |  23 ++--
 .../plc4x/test/driver/DriverTestsuiteRunner.java   | 122 +++++++++++++++------
 .../java/org/apache/plc4x/test/driver/Lalala.java  |  44 ++++++++
 .../plc4x/test/driver/model/DriverTestsuite.java   |  10 +-
 .../apache/plc4x/test/driver/model/StepType.java   |   3 +-
 .../apache/plc4x/test/driver/model/TestStep.java   |   8 +-
 .../model/{TestStep.java => api/TestField.java}    |  28 +++--
 .../{TestStep.java => api/TestFieldRequest.java}   |  22 ++--
 .../{TestStep.java => api/TestReadRequest.java}    |  26 ++---
 .../model/{TestStep.java => api/TestRequest.java}  |  24 +---
 .../{TestStep.java => api/TestWriteRequest.java}   |  26 ++---
 .../main/resources/schemas/driver-testsuite.xsd    |  57 ++++++----
 14 files changed, 274 insertions(+), 171 deletions(-)

diff --git a/plc4j/drivers/s7/src/test/resources/testsuite/S7DriverTestsuite.xml b/plc4j/drivers/s7/src/test/resources/testsuite/S7DriverTestsuite.xml
index 518c651..015d5cd 100644
--- a/plc4j/drivers/s7/src/test/resources/testsuite/S7DriverTestsuite.xml
+++ b/plc4j/drivers/s7/src/test/resources/testsuite/S7DriverTestsuite.xml
@@ -26,7 +26,7 @@
 
   <setup>
     <!-- First the driver is expected to send a COTP connection request -->
-    <send-plc-message>
+    <send-plc-message name="Send COTP Connection Request">
       <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
         <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketConnectionRequest">
           <parameters>
@@ -48,7 +48,7 @@
       </TPKTPacket>
     </send-plc-message>
     <!-- The PLC will send a COTP connection response -->
-    <receive-plc-message>
+    <receive-plc-message name="Receive COTP Connection Response">
       <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
         <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketConnectionResponse">
           <parameters>
@@ -70,7 +70,7 @@
       </TPKTPacket>
     </receive-plc-message>
     <!-- After that the driver will send a S7 connection request -->
-    <send-plc-message>
+    <send-plc-message name="Send S7 Connection Request">
       <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
         <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketData">
           <parameters/>
@@ -89,7 +89,7 @@
       </TPKTPacket>
     </send-plc-message>
     <!-- The PLC will send a S7 connection response -->
-    <receive-plc-message>
+    <receive-plc-message name="Receive S7 Connection Response">
       <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
         <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketData">
           <parameters/>
@@ -110,7 +110,7 @@
       </TPKTPacket>
     </receive-plc-message>
     <!-- Next we'll query some type information -->
-    <send-plc-message>
+    <send-plc-message name="Send S7 Identification Request">
       <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
         <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketData">
           <parameters/>
@@ -151,7 +151,7 @@
       </TPKTPacket>
     </send-plc-message>
     <!-- Which the PLC will gladly provide to us -->
-    <receive-plc-message>
+    <receive-plc-message name="Receive S7 Identification Response">
       <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
         <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketData">
           <parameters/>
@@ -219,15 +219,21 @@
   <testcase>
     <name>Single element read request</name>
     <steps>
-      <!--api-request-message>
-
-      </api-request-message-->
-      <send-plc-message>
+      <api-request name="Send Read Request">
+        <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>%Q0.0:BOOL</address>
+            </field>
+          </fields>
+        </TestReadRequest>      </api-request>
+      <send-plc-message name="Send S7 Read Request">
         <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
           <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketData">
             <parameters/>
             <payload className="org.apache.plc4x.java.s7.readwrite.S7MessageRequest">
-              <tpduReference>11</tpduReference>
+              <tpduReference>10</tpduReference>
               <parameter className="org.apache.plc4x.java.s7.readwrite.S7ParameterReadVarRequest">
                 <items>
                   <items className="org.apache.plc4x.java.s7.readwrite.S7VarRequestParameterItemAddress">
@@ -245,16 +251,16 @@
               <payload/>
             </payload>
             <eot>true</eot>
-            <tpduRef>11</tpduRef>
+            <tpduRef>10</tpduRef>
           </payload>
         </TPKTPacket>
       </send-plc-message>
-      <receive-plc-message>
+      <receive-plc-message name="Receive S7 Read Response">
         <TPKTPacket className="org.apache.plc4x.java.s7.readwrite.TPKTPacket">
           <payload className="org.apache.plc4x.java.s7.readwrite.COTPPacketData">
             <parameters/>
             <payload className="org.apache.plc4x.java.s7.readwrite.S7MessageResponseData">
-              <tpduReference>11</tpduReference>
+              <tpduReference>10</tpduReference>
               <parameter className="org.apache.plc4x.java.s7.readwrite.S7ParameterReadVarResponse">
                 <numItems>1</numItems>
               </parameter>
@@ -279,6 +285,7 @@
       <!--api-response-message>
 
       </api-response-message-->
+      <delay>1000</delay>
     </steps>
   </testcase>
 
diff --git a/plc4j/spi/src/main/java/io/netty/bootstrap/Plc4xBootstrap.java b/plc4j/spi/src/main/java/io/netty/bootstrap/Plc4xBootstrap.java
index 133f2cb..621439e 100644
--- a/plc4j/spi/src/main/java/io/netty/bootstrap/Plc4xBootstrap.java
+++ b/plc4j/spi/src/main/java/io/netty/bootstrap/Plc4xBootstrap.java
@@ -19,10 +19,6 @@ under the License.
 package io.netty.bootstrap;
 
 import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelPromise;
-
-import java.net.SocketAddress;
 
 public class Plc4xBootstrap extends Bootstrap {
 
@@ -50,17 +46,4 @@ public class Plc4xBootstrap extends Bootstrap {
         super.init(channel);
     }
 
-    @Override
-    public ChannelFuture connect(SocketAddress remoteAddress) {
-        final ChannelFuture connectFuture = super.connect(remoteAddress);
-
-        if("Plc4xEmbeddedEventLoop".equals(group.getClass().getSimpleName())) {
-            if (connectFuture instanceof ChannelPromise) {
-                ChannelPromise connectPromise = (ChannelPromise) connectFuture;
-                connectPromise.setSuccess();
-            }
-        }
-        return connectFuture;
-    }
-
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java
index 8bfc55a..c42a845 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/NettyChannelFactory.java
@@ -105,14 +105,23 @@ public abstract class NettyChannelFactory implements ChannelFactory {
                     workerGroup.shutdownGracefully();
                 }
             });
-            // Wait for sync
-            f.sync();
-            f.awaitUninterruptibly(); // jf: unsure if we need that
-            // Wait till the session is finished initializing.
-            return f.channel();
-        } catch (InterruptedException e) {
+
+            final Channel channel = f.channel();
+
+            // It seems the embedded channel operates differently.
+            // Intentionally using the class name as we don't want to require a
+            // hard dependency on the test-channel.
+            if(!"Plc4xEmbeddedChannel".equals(channel.getClass().getSimpleName())) {
+                // Wait for sync
+                f.sync();
+                // Wait till the session is finished initializing.
+                f.awaitUninterruptibly(); // jf: unsure if we need that
+            }
+
+            return channel;
+/*        } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
-            throw new PlcConnectionException("Error creating channel.", e);
+            throw new PlcConnectionException("Error creating channel.", e);*/
         } catch (Exception e) {
             throw new PlcConnectionException("Error creating channel.", e);
         }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java
index 5468ba1..ab378ad 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java
@@ -21,12 +21,14 @@ package org.apache.plc4x.test.driver;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.dataformat.xml.XmlMapper;
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 import io.netty.channel.embedded.Plc4xEmbeddedChannel;
 import org.apache.plc4x.java.PlcDriverManager;
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.spi.connection.ChannelExposingConnection;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.generation.*;
@@ -35,6 +37,10 @@ import org.apache.plc4x.test.driver.model.DriverTestsuite;
 import org.apache.plc4x.test.driver.model.StepType;
 import org.apache.plc4x.test.driver.model.TestStep;
 import org.apache.plc4x.test.driver.model.Testcase;
+import org.apache.plc4x.test.driver.model.api.TestField;
+import org.apache.plc4x.test.driver.model.api.TestReadRequest;
+import org.apache.plc4x.test.driver.model.api.TestRequest;
+import org.apache.plc4x.test.driver.model.api.TestWriteRequest;
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
@@ -82,7 +88,7 @@ public class DriverTestsuiteRunner {
             SAXReader reader = new SAXReader();
             Document document = reader.read(testsuiteDocumentXml);
             Element testsuiteXml = document.getRootElement();
-            boolean littleEndian = !"true".equals(testsuiteXml.attributeValue("bigEndian"));
+            boolean bigEndian = !"false".equals(testsuiteXml.attributeValue("bigEndian"));
             String testsuiteName = testsuiteXml.element(new QName("name")).getTextTrim();
             String driverName = testsuiteXml.element(new QName("driver-name")).getTextTrim();
             Element driverParametersElement = testsuiteXml.element(new QName("driver-parameters"));
@@ -137,7 +143,7 @@ public class DriverTestsuiteRunner {
 
             TimeUnit.MILLISECONDS.sleep(200);
 
-            return new DriverTestsuite(testsuiteName, connection, setupSteps, teardownSteps, testcases);
+            return new DriverTestsuite(testsuiteName, connection, setupSteps, teardownSteps, testcases, bigEndian);
         } catch (DocumentException e) {
             throw new DriverTestsuiteException("Error parsing testsuite xml", e);
         } catch (InterruptedException e) {
@@ -164,50 +170,72 @@ public class DriverTestsuiteRunner {
         }
     }
 
-    private void run(DriverTestsuite testSuite, Testcase testcase) throws DriverTestsuiteException {
-        final Plc4xEmbeddedChannel embeddedChannel = getEmbeddedChannel(testSuite);
-        if(!testSuite.getSetupSteps().isEmpty()) {
+    private void run(DriverTestsuite testsuite, Testcase testcase) throws DriverTestsuiteException {
+        final PlcConnection plcConnection = testsuite.getConnection();
+        final Plc4xEmbeddedChannel embeddedChannel = getEmbeddedChannel(testsuite);
+        final boolean bigEndian = testsuite.isBigEndian();
+        if(!testsuite.getSetupSteps().isEmpty()) {
             LOGGER.info("Running setup steps");
-            for (TestStep setupStep : testSuite.getSetupSteps()) {
-                executeStep(setupStep, embeddedChannel);
+            for (TestStep setupStep : testsuite.getSetupSteps()) {
+                executeStep(setupStep, plcConnection, embeddedChannel, bigEndian);
             }
             LOGGER.info("Finished setup steps");
         }
         LOGGER.info("Running test steps");
         for (TestStep step : testcase.getSteps()) {
-            executeStep(step, embeddedChannel);
+            executeStep(step, plcConnection, embeddedChannel, bigEndian);
         }
         LOGGER.info("Finished test steps");
-        if(!testSuite.getTeardownSteps().isEmpty()) {
+        if(!testsuite.getTeardownSteps().isEmpty()) {
             LOGGER.info("Running teardown steps");
-            for (TestStep teardownStep : testSuite.getTeardownSteps()) {
-                executeStep(teardownStep, embeddedChannel);
+            for (TestStep teardownStep : testsuite.getTeardownSteps()) {
+                executeStep(teardownStep, plcConnection, embeddedChannel, bigEndian);
             }
             LOGGER.info("Finished teardown steps");
         }
     }
 
-    private void executeStep(TestStep testStep, Plc4xEmbeddedChannel embeddedChannel) throws DriverTestsuiteException {
-        LOGGER.info("  - Running step " + testStep.getType());
-        ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
+    private void executeStep(TestStep testStep, PlcConnection plcConnection, Plc4xEmbeddedChannel embeddedChannel, boolean bigEndian) throws DriverTestsuiteException {
+        LOGGER.info("  - Running step: '" + testStep.getName() + "' - " + testStep.getType());
+        final ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
         final Element payload = testStep.getPayload();
-        final String className = payload.attributeValue(new QName("className"));
-        String referenceXml = payload.asXML();
         try {
-            final MessageIO messageIO = getMessageIOType(className).newInstance();
             switch (testStep.getType()) {
                 case SEND_PLC_BYTES: {
+                    final ByteBuf byteBuf = embeddedChannel.readOutbound();
+                    if(byteBuf == null) {
+                        throw new DriverTestsuiteException("No outbound message available");
+                    }
+                    final byte[] data = new byte[byteBuf.readableBytes()];
+                    byteBuf.readBytes(data);
+
+                    // TODO: Compare the read bytes with the expected byte array.
+
                     break;
                 }
                 case SEND_PLC_MESSAGE: {
+                    try {
+                        TimeUnit.MILLISECONDS.sleep(200);
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupt();
+                        throw new DriverTestsuiteException("Interrupted during delay.");
+                    }
+
                     final ByteBuf byteBuf = embeddedChannel.readOutbound();
-                    byte[] data = new byte[byteBuf.readableBytes()];
+                    if(byteBuf == null) {
+                        throw new DriverTestsuiteException("No outbound message available");
+                    }
+                    final byte[] data = new byte[byteBuf.readableBytes()];
                     byteBuf.readBytes(data);
-                    ReadBuffer readBuffer = new ReadBuffer(data);
+
+                    final ReadBuffer readBuffer = new ReadBuffer(data, !bigEndian);
                     try {
+                        final String className = payload.attributeValue(new QName("className"));
+                        final MessageIO messageIO = getMessageIOType(className).newInstance();
                         final Object parsedOutput = messageIO.parse(readBuffer);
-                        String xmlString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsedOutput);
-                        Diff diff = DiffBuilder.compare(referenceXml).withTest(xmlString).ignoreComments().ignoreWhitespace().build();
+                        final String xmlString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsedOutput);
+                        final String referenceXml = payload.asXML();
+                        final Diff diff = DiffBuilder.compare(referenceXml).withTest(xmlString).ignoreComments().ignoreWhitespace().build();
                         if (diff.hasDifferences()) {
                             System.out.println(xmlString);
                             throw new DriverTestsuiteException("Differences were found after parsing.\n" + diff.toString());
@@ -221,19 +249,43 @@ public class DriverTestsuiteRunner {
                     break;
                 }
                 case RECEIVE_PLC_MESSAGE: {
+                    final String className = payload.attributeValue(new QName("className"));
+                    final MessageIO messageIO = getMessageIOType(className).newInstance();
+                    final String referenceXml = payload.asXML();
                     final Message message = mapper.readValue(referenceXml, getMessageType(className));
-                    WriteBuffer writeBuffer = new WriteBuffer(1024);
+                    final WriteBuffer writeBuffer = new WriteBuffer(1024, !bigEndian);
                     try {
                         messageIO.serialize(writeBuffer, message);
-                        byte[] data = new byte[writeBuffer.getPos()];
+                        final byte[] data = new byte[writeBuffer.getPos()];
                         System.arraycopy(writeBuffer.getData(), 0, data, 0, writeBuffer.getPos());
-                        embeddedChannel.writeOutbound(data);
+                        embeddedChannel.writeInbound(Unpooled.wrappedBuffer(data));
                     } catch (ParseException e) {
                         throw new DriverTestsuiteException("Error serializing message", e);
                     }
                     break;
                 }
                 case API_REQUEST: {
+                    final String referenceXml = payload.asXML();
+                    final TestRequest request = mapper.readValue(referenceXml, TestRequest.class);
+                    if(request instanceof TestReadRequest) {
+                        final TestReadRequest readRequest = (TestReadRequest) request;
+                        final PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
+                        for (TestField testField : readRequest.getFields()) {
+                            builder.addItem(testField.getName(), testField.getAddress());
+                        }
+                        final PlcReadRequest plc4xRequest = builder.build();
+                        // Don't block here or the test will not be able to process the rest.
+                        plc4xRequest.execute().whenComplete((result, throwable) -> {
+                            // TODO: Do something in here ...
+                            if(result != null) {
+                                System.out.println("Success");
+                            } else {
+                                System.out.println("Failure " + throwable.getMessage());
+                            }
+                        });
+                    } else if(request instanceof TestWriteRequest) {
+
+                    }
                     break;
                 }
                 case API_RESPONSE: {
@@ -241,13 +293,16 @@ public class DriverTestsuiteRunner {
                 }
                 case DELAY: {
                     try {
-                        TimeUnit.MILLISECONDS.sleep(200);
+                        TimeUnit.MILLISECONDS.sleep(1000);
                     } catch (InterruptedException e) {
                         Thread.currentThread().interrupt();
                         throw new DriverTestsuiteException("Interrupted during delay.");
                     }
+                    break;
+                }
+                case TERMINATE: {
+                    embeddedChannel.close();
                 }
-
             }
         } catch (IOException e) {
             throw new DriverTestsuiteException("Error processing the xml", e);
@@ -260,8 +315,12 @@ public class DriverTestsuiteRunner {
     private TestStep parseTestStep(Element curElement) {
         final String elementName = curElement.getName();
         final StepType stepType = StepType.valueOf(elementName.toUpperCase().replace("-", "_"));
-        final Element definition = curElement.elementIterator().next();
-        return new TestStep(stepType, definition);
+        final String stepName = curElement.attributeValue(new QName("name"));
+        Element definition = null;
+        if(curElement.hasMixedContent()) {
+            definition = curElement.elementIterator().next();
+        }
+        return new TestStep(stepType, stepName, definition);
     }
 
     private Plc4xEmbeddedChannel getEmbeddedChannel(DriverTestsuite testSuite) {
@@ -282,19 +341,20 @@ public class DriverTestsuiteRunner {
             if(Message.class.isAssignableFrom(messageClass)) {
                 return (Class<? extends Message>) messageClass;
             }
-            throw new DriverTestsuiteException("IO class muss implement Message interface");
+            throw new DriverTestsuiteException("IO class must implement Message interface");
         } catch (ClassNotFoundException e) {
             throw new DriverTestsuiteException("Error loading message class", e);
         }
     }
 
-    private Class<? extends MessageIO> getMessageIOType(String messageClassName) throws DriverTestsuiteException {
+    @SuppressWarnings("unchecked")
+    private Class<? extends MessageIO<?,?>> getMessageIOType(String messageClassName) throws DriverTestsuiteException {
         String ioClassName = messageClassName.substring(0, messageClassName.lastIndexOf('.')) + ".io." +
             messageClassName.substring(messageClassName.lastIndexOf('.') + 1) + "IO";
         try {
             final Class<?> ioClass = Class.forName(ioClassName);
             if(MessageIO.class.isAssignableFrom(ioClass)) {
-                return (Class<? extends MessageIO>) ioClass;
+                return (Class<? extends MessageIO<?,?>>) ioClass;
             }
             throw new DriverTestsuiteException("IO class muss implement MessageIO interface");
         } catch (ClassNotFoundException e) {
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/Lalala.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/Lalala.java
new file mode 100644
index 0000000..d79a1d3
--- /dev/null
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/Lalala.java
@@ -0,0 +1,44 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.test.driver;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.apache.plc4x.test.driver.model.api.TestField;
+import org.apache.plc4x.test.driver.model.api.TestReadRequest;
+import org.apache.plc4x.test.driver.model.api.TestRequest;
+
+public class Lalala {
+    public static void main(String[] args) throws Exception {
+        ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
+
+        TestField[] testFields = new TestField[1];
+        testFields[0] = new TestField("hurz", "%Q0.0:BOOL");
+        TestRequest request = new TestReadRequest(testFields);
+
+        String xmlString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(request);
+
+        System.out.println(xmlString);
+
+        TestRequest newRequest = mapper.readValue(xmlString, TestRequest.class);
+
+        System.out.println(newRequest);
+    }
+
+}
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/DriverTestsuite.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/DriverTestsuite.java
index 8ee9dab..9c8d4a1 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/DriverTestsuite.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/DriverTestsuite.java
@@ -20,6 +20,7 @@ package org.apache.plc4x.test.driver.model;
 
 import org.apache.plc4x.java.api.PlcConnection;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 public class DriverTestsuite {
@@ -29,13 +30,16 @@ public class DriverTestsuite {
     private final List<TestStep> setupSteps;
     private final List<TestStep> teardownSteps;
     private final List<Testcase> testcases;
+    private final boolean bigEndian;
 
-    public DriverTestsuite(String name, PlcConnection connection, List<TestStep> setupSteps, List<TestStep> teardownSteps, List<Testcase> testcases) {
+    public DriverTestsuite(String name, PlcConnection connection, List<TestStep> setupSteps,
+                           List<TestStep> teardownSteps, List<Testcase> testcases, boolean bigEndian) {
         this.name = name;
         this.connection = connection;
         this.setupSteps = setupSteps;
         this.teardownSteps = teardownSteps;
         this.testcases = testcases;
+        this.bigEndian = bigEndian;
     }
 
     public String getName() {
@@ -58,4 +62,8 @@ public class DriverTestsuite {
         return testcases;
     }
 
+    public boolean isBigEndian() {
+        return bigEndian;
+    }
+
 }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/StepType.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/StepType.java
index 93d9f3f..c371331 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/StepType.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/StepType.java
@@ -36,6 +36,7 @@ public enum StepType {
     RECEIVE_PLC_BYTES,
     API_REQUEST,
     API_RESPONSE,
-    DELAY
+    DELAY,
+    TERMINATE
 
 }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
index 1e9e37d..0a44522 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
@@ -23,10 +23,12 @@ import org.dom4j.Element;
 public class TestStep {
 
     private final StepType type;
+    private final String name;
     private final Element payload;
 
-    public TestStep(StepType type, Element payload) {
+    public TestStep(StepType type, String name, Element payload) {
         this.type = type;
+        this.name = name;
         this.payload = payload;
     }
 
@@ -34,6 +36,10 @@ public class TestStep {
         return type;
     }
 
+    public String getName() {
+        return name;
+    }
+
     public Element getPayload() {
         return payload;
     }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestField.java
similarity index 52%
copy from plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
copy to plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestField.java
index 1e9e37d..03708ec 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestField.java
@@ -16,26 +16,30 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-package org.apache.plc4x.test.driver.model;
+package org.apache.plc4x.test.driver.model.api;
 
-import org.dom4j.Element;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
-public class TestStep {
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")
+public class TestField {
 
-    private final StepType type;
-    private final Element payload;
+    private final String name;
+    private final String address;
 
-    public TestStep(StepType type, Element payload) {
-        this.type = type;
-        this.payload = payload;
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public TestField(@JsonProperty("name") String name, @JsonProperty("address") String address) {
+        this.name = name;
+        this.address = address;
     }
 
-    public StepType getType() {
-        return type;
+    public String getName() {
+        return name;
     }
 
-    public Element getPayload() {
-        return payload;
+    public String getAddress() {
+        return address;
     }
 
 }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestFieldRequest.java
similarity index 66%
copy from plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
copy to plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestFieldRequest.java
index 1e9e37d..cf3dbf8 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestFieldRequest.java
@@ -16,26 +16,20 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-package org.apache.plc4x.test.driver.model;
+package org.apache.plc4x.test.driver.model.api;
 
-import org.dom4j.Element;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class TestStep {
+public abstract class TestFieldRequest implements TestRequest {
 
-    private final StepType type;
-    private final Element payload;
+    private final TestField[] fields;
 
-    public TestStep(StepType type, Element payload) {
-        this.type = type;
-        this.payload = payload;
+    public TestFieldRequest(@JsonProperty("fields") TestField[] fields) {
+        this.fields = fields;
     }
 
-    public StepType getType() {
-        return type;
-    }
-
-    public Element getPayload() {
-        return payload;
+    public TestField[] getFields() {
+        return fields;
     }
 
 }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestReadRequest.java
similarity index 59%
copy from plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
copy to plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestReadRequest.java
index 1e9e37d..f94c8fb 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestReadRequest.java
@@ -16,26 +16,18 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-package org.apache.plc4x.test.driver.model;
+package org.apache.plc4x.test.driver.model.api;
 
-import org.dom4j.Element;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
-public class TestStep {
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")
+public class TestReadRequest extends TestFieldRequest {
 
-    private final StepType type;
-    private final Element payload;
-
-    public TestStep(StepType type, Element payload) {
-        this.type = type;
-        this.payload = payload;
-    }
-
-    public StepType getType() {
-        return type;
-    }
-
-    public Element getPayload() {
-        return payload;
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public TestReadRequest(@JsonProperty("fields") TestField[] fields) {
+        super(fields);
     }
 
 }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestRequest.java
similarity index 65%
copy from plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
copy to plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestRequest.java
index 1e9e37d..c442d68 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestRequest.java
@@ -16,26 +16,10 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-package org.apache.plc4x.test.driver.model;
+package org.apache.plc4x.test.driver.model.api;
 
-import org.dom4j.Element;
-
-public class TestStep {
-
-    private final StepType type;
-    private final Element payload;
-
-    public TestStep(StepType type, Element payload) {
-        this.type = type;
-        this.payload = payload;
-    }
-
-    public StepType getType() {
-        return type;
-    }
-
-    public Element getPayload() {
-        return payload;
-    }
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")
+public interface TestRequest {
 }
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestWriteRequest.java
similarity index 59%
copy from plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
copy to plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestWriteRequest.java
index 1e9e37d..bc3d217 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/TestStep.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/model/api/TestWriteRequest.java
@@ -16,26 +16,18 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-package org.apache.plc4x.test.driver.model;
+package org.apache.plc4x.test.driver.model.api;
 
-import org.dom4j.Element;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
-public class TestStep {
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")
+public class TestWriteRequest extends TestFieldRequest {
 
-    private final StepType type;
-    private final Element payload;
-
-    public TestStep(StepType type, Element payload) {
-        this.type = type;
-        this.payload = payload;
-    }
-
-    public StepType getType() {
-        return type;
-    }
-
-    public Element getPayload() {
-        return payload;
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public TestWriteRequest(@JsonProperty("fields") TestField[] fields) {
+        super(fields);
     }
 
 }
diff --git a/plc4j/utils/test-utils/src/main/resources/schemas/driver-testsuite.xsd b/plc4j/utils/test-utils/src/main/resources/schemas/driver-testsuite.xsd
index a97399d..7008c34 100644
--- a/plc4j/utils/test-utils/src/main/resources/schemas/driver-testsuite.xsd
+++ b/plc4j/utils/test-utils/src/main/resources/schemas/driver-testsuite.xsd
@@ -49,13 +49,14 @@
                     <xs:complexType>
                         <xs:sequence minOccurs="1" maxOccurs="unbounded">
                             <xs:choice>
-                                <xs:element name="send-plc-message" type="xs:anyType"/>
-                                <xs:element name="send-plc-bytes" type="xs:hexBinary"/>
-                                <xs:element name="receive-plc-message" type="xs:anyType"/>
-                                <xs:element name="receive-plc-bytes" type="xs:hexBinary"/>
-                                <xs:element name="api-request" type="xs:anyType"/>
-                                <xs:element name="api-response" type="xs:anyType"/>
+                                <xs:element name="send-plc-message" type="messageStep"/>
+                                <xs:element name="send-plc-bytes" type="bytesStep"/>
+                                <xs:element name="receive-plc-message" type="messageStep"/>
+                                <xs:element name="receive-plc-bytes" type="bytesStep"/>
+                                <xs:element name="api-request" type="messageStep"/>
+                                <xs:element name="api-response" type="messageStep"/>
                                 <xs:element name="delay" type="xs:integer"/>
+                                <xs:element name="terminate"/>
                             </xs:choice>
                         </xs:sequence>
                     </xs:complexType>
@@ -66,14 +67,15 @@
                     <xs:complexType>
                         <xs:sequence minOccurs="1" maxOccurs="unbounded">
                             <xs:choice>
-                                <xs:element name="send-plc-message" type="xs:anyType"/>
-                                <xs:element name="send-plc-bytes" type="xs:hexBinary"/>
-                                <xs:element name="receive-plc-message" type="xs:anyType"/>
-                                <xs:element name="receive-plc-bytes" type="xs:hexBinary"/>
-                                <xs:element name="api-request" type="xs:anyType"/>
-                                <xs:element name="api-response" type="xs:anyType"/>
+                                <xs:element name="send-plc-message" type="messageStep"/>
+                                <xs:element name="send-plc-bytes" type="bytesStep"/>
+                                <xs:element name="receive-plc-message" type="messageStep"/>
+                                <xs:element name="receive-plc-bytes" type="bytesStep"/>
+                                <xs:element name="api-request" type="messageStep"/>
+                                <xs:element name="api-response" type="messageStep"/>
                                 <xs:element name="delay" type="xs:integer"/>
-                            </xs:choice>
+                                <xs:element name="terminate"/>
+                           </xs:choice>
                         </xs:sequence>
                     </xs:complexType>
                 </xs:element>
@@ -90,13 +92,14 @@
                                 <xs:complexType>
                                     <xs:sequence minOccurs="1" maxOccurs="unbounded">
                                         <xs:choice>
-                                            <xs:element name="send-plc-message" type="xs:anyType"/>
-                                            <xs:element name="send-plc-bytes" type="xs:hexBinary"/>
-                                            <xs:element name="receive-plc-message" type="xs:anyType"/>
-                                            <xs:element name="receive-plc-bytes" type="xs:hexBinary"/>
-                                            <xs:element name="api-request" type="xs:anyType"/>
-                                            <xs:element name="api-response" type="xs:anyType"/>
+                                            <xs:element name="send-plc-message" type="messageStep"/>
+                                            <xs:element name="send-plc-bytes" type="bytesStep"/>
+                                            <xs:element name="receive-plc-message" type="messageStep"/>
+                                            <xs:element name="receive-plc-bytes" type="bytesStep"/>
+                                            <xs:element name="api-request" type="messageStep"/>
+                                            <xs:element name="api-response" type="messageStep"/>
                                             <xs:element name="delay" type="xs:integer"/>
+                                            <xs:element name="terminate"/>
                                         </xs:choice>
                                     </xs:sequence>
                                 </xs:complexType>
@@ -110,4 +113,20 @@
         </xs:complexType>
     </xs:element>
 
+    <xs:complexType name="messageStep">
+        <xs:simpleContent>
+            <xs:extension base="xs:anyType">
+                <xs:attribute name="name" type="xs:string"/>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:complexType name="bytesStep">
+        <xs:simpleContent>
+            <xs:extension base="xs:hexBinary">
+                <xs:attribute name="name" type="xs:string"/>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
 </xs:schema>
\ No newline at end of file