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 2019/07/01 13:56:43 UTC

[plc4x] branch develop updated: - Implemented a helper to create test-suites for generated protocols in java. - Refactored the code generation to be a bit more generic and use shared interfaces.

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

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


The following commit(s) were added to refs/heads/develop by this push:
     new 1f3144b  - Implemented a helper to create test-suites for generated protocols in java. - Refactored the code generation to be a bit more generic and use shared interfaces.
1f3144b is described below

commit 1f3144bf26db3db40cac2a1ac54082456296c673
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Jul 1 15:56:35 2019 +0200

    - Implemented a helper to create test-suites for generated protocols in java.
    - Refactored the code generation to be a bit more generic and use shared interfaces.
---
 .../language/java/JavaLanguageTemplateHelper.java  |  30 ++++-
 .../main/resources/templates/java/io-template.ftlh |  48 ++++---
 .../resources/templates/java/pojo-template.ftlh    |   3 +-
 .../java/org/apache/plc4x/java/utils/Message.java  |  23 ++++
 .../org/apache/plc4x/java/utils/MessageIO.java     |  28 +++++
 plc4j/utils/pom.xml                                |   5 +-
 plc4j/utils/protocol-test-utils/pom.xml            |  72 +++++++++++
 .../protocol/test/ProtocolTestsuiteRunner.java     | 140 +++++++++++++++++++++
 .../exceptions/ProtocolTestsuiteException.java     |  32 +++++
 .../protocol/test/model/ProtocolTestsuite.java     |  42 +++++++
 .../apache/plc4x/protocol/test/model/Testcase.java |  61 +++++++++
 .../src/main/resources/schemas/testsuite.xsd       |  54 ++++++++
 pom.xml                                            |  16 +++
 sandbox/test-java-knxnetip-driver/pom.xml          |   6 +
 .../org/apache/plc4x/java/knxnetip/IOTest.java     |  14 ++-
 .../plc4x/java/knxnetip/KNXNetIpTestsuite.java     |  30 +++++
 .../test/resources/testsuite/KNXNetIPTestsuite.xml |  60 +++++++++
 .../src/test/java/BenchmarkGeneratedS7.java        |   5 +-
 18 files changed, 639 insertions(+), 30 deletions(-)

diff --git a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 39af1a1..5f43830 100644
--- a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -24,14 +24,14 @@ import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLang
 import org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
-import org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField;
-import org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField;
-import org.apache.plc4x.plugins.codegenerator.types.fields.TypedField;
+import org.apache.plc4x.plugins.codegenerator.types.fields.*;
 import org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.terms.*;
 
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.regex.Matcher;
@@ -331,6 +331,30 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
         }
     }
 
+    public Collection<ComplexTypeReference> getComplexTypes(ComplexTypeDefinition complexTypeDefinition) {
+        Map<String, ComplexTypeReference> types = new HashMap<>();
+        for (Field field : complexTypeDefinition.getFields()) {
+            if(field instanceof TypedField) {
+                TypedField typedField = (TypedField) field;
+                if(typedField.getType() instanceof ComplexTypeReference) {
+                    ComplexTypeReference complexTypeReference = (ComplexTypeReference) typedField.getType();
+                    types.put(complexTypeReference.getName(),  complexTypeReference);
+                }
+            } else if(field instanceof SwitchField) {
+                SwitchField switchField = (SwitchField) field;
+                for (DiscriminatedComplexTypeDefinition cas : switchField.getCases()) {
+                    types.put(cas.getName(), new ComplexTypeReference() {
+                        @Override
+                        public String getName() {
+                            return cas.getName();
+                        }
+                    });
+                }
+            }
+        }
+        return types.values();
+    }
+
     public boolean isSimpleType(TypeReference typeReference) {
         return typeReference instanceof SimpleTypeReference;
     }
diff --git a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
index d790f0b..085f4a2 100644
--- a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
@@ -39,10 +39,8 @@ ${packageName?replace(".", "/")}/io/${typeName}IO.java
 package ${packageName}.io;
 
 import ${packageName}.*;
-import org.apache.plc4x.java.utils.EvaluationHelper;
-import org.apache.plc4x.java.utils.ReadBuffer;
-import org.apache.plc4x.java.utils.ParseException;
-import org.apache.plc4x.java.utils.WriteBuffer;
+<#if helper.getComplexTypes(type)?has_content>import ${packageName}.io.*;</#if>
+import org.apache.plc4x.java.utils.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,11 +49,29 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
-public class ${typeName}IO  {
+public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscriminatedType(type)>IO.${typeName}Builder</#if>, ${typeName}> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(${typeName}IO.class);
 
-    public static <#if helper.isDiscriminatedType(type)>${typeName}Builder<#else>${typeName}</#if> parse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForSpecType(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
+<#if helper.getComplexTypes(type)?has_content>
+    // IO Helpers.
+<#list helper.getComplexTypes(type) as complexType>
+    private final ${complexType.name}IO ${complexType.name?uncap_first}IO;
+</#list>
+
+    public ${typeName}IO() {
+<#list helper.getComplexTypes(type) as complexType>
+        ${complexType.name?uncap_first}IO = new ${complexType.name}IO();
+</#list>
+   }
+
+</#if>
+    public ${typeName}<#if helper.isDiscriminatedType(type)>Builder</#if> parse(ReadBuffer io, Object... args) throws ParseException {
+<#if type.parserArguments?has_content>
+<#list type.parserArguments as parserArgument>
+        ${helper.getLanguageTypeNameForSpecType(parserArgument.type)} ${parserArgument.name} = (${helper.getLanguageTypeNameForSpecType(parserArgument.type)}) args[${parserArgument?index}];
+</#list>
+</#if>
         int startPos = io.getPos();
         int curPos;
 <#list type.fields as field>
@@ -70,7 +86,7 @@ public class ${typeName}IO  {
         <#if helper.isCountArray(field)>
         ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[${field.name}Size];
         for(int i = 0; i < ${field.name}Size; i++) {
-            ${field.name}[i] = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>${parserArgument}<#sep>, </#sep></#list></#if>)</#if>;
+            ${field.name}[i] = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>${parserArgument}<#sep>, </#sep></#list></#if>)</#if>;
         }
         <#else>
         List<${helper.getLanguageTypeNameForField(field)}> ${field.name}List = <#if helper.isCountArray(field)>new ArrayList<>(size)<#else>new LinkedList<>()</#if>;
@@ -79,7 +95,7 @@ public class ${typeName}IO  {
             <#if field.lengthExpression.contains("curPos")>
             curPos = io.getPos() - startPos;
             </#if>
-            ${field.name}List.add(<#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${parserArgument})<#sep>, </#sep></#list></#if>)</#if>);
+            ${field.name}List.add(<#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${parserArgument})<#sep>, </#sep></#list></#if>)</#if>);
         }
         ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = ${field.name}List.toArray(new ${helper.getLanguageTypeNameForField(field)}[0]);
         </#if>
@@ -107,7 +123,7 @@ public class ${typeName}IO  {
         // Optional Field (Can be skipped, if a given expression evaluates to false)
         ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForType(field.type)};
         if(${helper.toDeserializationExpression(field.conditionExpression)}) {
-            ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.parse(io);</#if>;
+            ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io);</#if>;
         }
         <#break>
     <#case "reserved">
@@ -123,7 +139,7 @@ public class ${typeName}IO  {
     <#case "simple">
 
         // Simple field
-        ${helper.getLanguageTypeNameForField(field)} ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>${parserArgument}<#sep>, </#sep></#list></#if>)</#if>;
+        ${helper.getLanguageTypeNameForField(field)} ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>${parserArgument}<#sep>, </#sep></#list></#if>)</#if>;
         <#break>
     <#case "switch">
 
@@ -131,7 +147,7 @@ public class ${typeName}IO  {
         ${typeName}Builder builder = null;
         <#list field.cases as case>
         if(<#list case.discriminatorValues as discriminatorValue>EvaluationHelper.equals(${helper.toSwitchExpression(field.discriminatorNames[discriminatorValue?index])}, ${discriminatorValue})<#sep> && </#sep></#list>) {
-            builder = ${case.name}IO.parse(io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
+            builder = ${case.name?uncap_first}IO.parse(io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
         }<#sep> else </#sep>
         </#list>
         if (builder == null) {
@@ -151,7 +167,7 @@ public class ${typeName}IO  {
         </#if>
     }
 
-    public static void serialize(WriteBuffer io, ${typeName} value) throws ParseException {
+    public void serialize(WriteBuffer io, ${typeName} value) throws ParseException {
 <#list type.fields as field>
 <#switch field.typeName>
     <#case "array">
@@ -162,7 +178,7 @@ public class ${typeName}IO  {
                 <#if helper.isSimpleType(field.type)>
                 io.${helper.getWriteBufferReadMethodCall(field.type, "element")};
                 <#else>
-                ${helper.getLanguageTypeNameForField(field)}IO.serialize(io, element);
+                ${field.type.name?uncap_first}IO.serialize(io, element);
                 </#if>
             }
         }
@@ -193,7 +209,7 @@ public class ${typeName}IO  {
             <#if helper.isSimpleType(field.type)>
             io.${helper.getWriteBufferReadMethodCall(field.type, "value.get" + field.name?cap_first + "()")};
             <#else>
-            ${helper.getLanguageTypeNameForField(field)}IO.serialize(io, value.get${field.name?cap_first}());
+            ${field.type.name?uncap_first}IO.serialize(io, value.get${field.name?cap_first}());
             </#if>
         }
         <#break>
@@ -208,7 +224,7 @@ public class ${typeName}IO  {
         <#if helper.isSimpleType(field.type)>
         io.${helper.getWriteBufferReadMethodCall(field.type, "value.get" + field.name?cap_first + "()")};
         <#else>
-        ${helper.getLanguageTypeNameForField(field)}IO.serialize(io, value.get${field.name?cap_first}());
+        ${field.type.name?uncap_first}IO.serialize(io, value.get${field.name?cap_first}());
         </#if>
         <#break>
     <#case "switch">
@@ -216,7 +232,7 @@ public class ${typeName}IO  {
         // Switch field (Depending on the discriminator values, passes the instantiation to a sub-type)
         <#list field.cases as case>
         if(value instanceof ${case.name}) {
-            ${case.name}IO.serialize(io, (${case.name}) value);
+            ${case.name?uncap_first}IO.serialize(io, (${case.name}) value);
         }<#sep> else </#sep>
         </#list>
         <#break>
diff --git a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
index 33abe95..5b095bf 100644
--- a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
@@ -39,10 +39,11 @@ ${packageName?replace(".", "/")}/${typeName}.java
 package ${packageName};
 
 import com.fasterxml.jackson.annotation.*;
+import org.apache.plc4x.java.utils.Message;
 import org.apache.plc4x.java.utils.SizeAware;
 
 <#if type.abstract>@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")</#if>
-public<#if type.abstract> abstract</#if> class ${typeName}<#if type.parentType??> extends ${type.parentType.name}</#if> implements SizeAware {
+public<#if type.abstract> abstract</#if> class ${typeName}<#if type.parentType??> extends ${type.parentType.name}</#if> implements SizeAware, Message {
 
 <#if helper.isDiscriminatedType(type)>
 
diff --git a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/Message.java b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/Message.java
new file mode 100644
index 0000000..7bc60b6
--- /dev/null
+++ b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/Message.java
@@ -0,0 +1,23 @@
+/*
+ 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.java.utils;
+
+public interface Message {
+}
diff --git a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/MessageIO.java b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/MessageIO.java
new file mode 100644
index 0000000..03eb18d
--- /dev/null
+++ b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/MessageIO.java
@@ -0,0 +1,28 @@
+/*
+ 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.java.utils;
+
+public interface MessageIO<PARSER_TYPE, SERIALIZER_TYPE> {
+
+    PARSER_TYPE parse(ReadBuffer io, Object... args) throws ParseException;
+
+    void serialize(WriteBuffer io, SERIALIZER_TYPE value) throws ParseException;
+
+}
diff --git a/plc4j/utils/pom.xml b/plc4j/utils/pom.xml
index cde00e4..59de591 100644
--- a/plc4j/utils/pom.xml
+++ b/plc4j/utils/pom.xml
@@ -35,11 +35,12 @@
 
   <modules>
     <module>driver-base-java</module>
+    <module>protocol-test-utils</module>
+    <module>raw-sockets</module>
+    <module>test-utils</module>
 
     <module>connection-pool</module>
     <module>opm</module>
-    <module>raw-sockets</module>
-    <module>test-utils</module>
     <module>scraper</module>
   </modules>
 
diff --git a/plc4j/utils/protocol-test-utils/pom.xml b/plc4j/utils/protocol-test-utils/pom.xml
new file mode 100644
index 0000000..3cc9b8e
--- /dev/null
+++ b/plc4j/utils/protocol-test-utils/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x</groupId>
+    <artifactId>plc4j-utils</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc4j-utils-protocol-test-utils</artifactId>
+
+  <name>PLC4J: Utils: Protocol Test Utils</name>
+  <description>Set of utilities designed to help testing protocols.</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-driver-base-java</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.dom4j</groupId>
+      <artifactId>dom4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.dataformat</groupId>
+      <artifactId>jackson-dataformat-xml</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.xmlunit</groupId>
+      <artifactId>xmlunit-core</artifactId>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java
new file mode 100644
index 0000000..ab00e7e
--- /dev/null
+++ b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java
@@ -0,0 +1,140 @@
+/*
+ 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.protocol.test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.plc4x.java.utils.MessageIO;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.protocol.test.exceptions.ProtocolTestsuiteException;
+import org.apache.plc4x.protocol.test.model.ProtocolTestsuite;
+import org.apache.plc4x.protocol.test.model.Testcase;
+import org.dom4j.*;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+import org.dom4j.io.SAXReader;
+import org.xmlunit.builder.DiffBuilder;
+import org.xmlunit.diff.Diff;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ProtocolTestsuiteRunner {
+
+    private static final Namespace TEST_NAMESPACE = new Namespace("test", "https://plc4x.apache.org/schemas/testsuite.xsd");
+
+    private final String testsuiteDocument;
+
+    public ProtocolTestsuiteRunner(String testsuiteDocument) {
+        this.testsuiteDocument = testsuiteDocument;
+    }
+
+    @TestFactory
+    public List<DynamicTest> getTestsuiteTests() throws ProtocolTestsuiteException {
+        ProtocolTestsuite testSuite = parseTestsuite(ProtocolTestsuiteRunner.class.getResourceAsStream(testsuiteDocument));
+        List<DynamicTest> dynamicTests = new LinkedList<>();
+        for(Testcase testcase : testSuite.getTestcases()) {
+            String testcaseName = testcase.getName();
+            String testcaseLabel = testSuite.getName() + ": " + testcaseName;
+            DynamicTest test = DynamicTest.dynamicTest(testcaseLabel, () ->
+                run(testcase)
+            );
+            dynamicTests.add(test);
+        }
+        return dynamicTests;
+    }
+
+    private ProtocolTestsuite parseTestsuite(InputStream testsuiteDocumentXml) throws ProtocolTestsuiteException {
+        try {
+            SAXReader reader = new SAXReader();
+            Document document = reader.read(testsuiteDocumentXml);
+            Element testsuiteXml = document.getRootElement();
+            Element testsuiteName = testsuiteXml.element(new QName("name"));
+            List<Element> testcasesXml = testsuiteXml.elements(new QName("testcase"));
+            List<Testcase> testcases = new ArrayList<>(testcasesXml.size());
+            for(Element testcaseXml : testcasesXml) {
+                Element nameElement = testcaseXml.element(new QName("name"));
+                Element descriptionElement = testcaseXml.element(new QName("description"));
+                Element rawElement = testcaseXml.element(new QName("raw"));
+                Element rootTypeElement = testcaseXml.element(new QName("root-type"));
+                Element xmlElement = testcaseXml.element(new QName("xml"));
+
+                String name = nameElement.getTextTrim();
+                String description = (descriptionElement != null) ? descriptionElement.getTextTrim() : null;
+                byte[] raw = Hex.decodeHex(rawElement.getTextTrim());
+                String rootType = rootTypeElement.getTextTrim();
+
+                testcases.add(new Testcase(name, description, raw, rootType, xmlElement));
+            }
+            return new ProtocolTestsuite(testsuiteName.getTextTrim(), testcases);
+        } catch (DocumentException e) {
+            throw new ProtocolTestsuiteException("Error parsing testsuite xml", e);
+        } catch (DecoderException e) {
+            throw new ProtocolTestsuiteException("Error parsing testcase raw data", e);
+        }
+    }
+
+    private void run(Testcase testcase) throws ProtocolTestsuiteException {
+        ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
+        ReadBuffer readBuffer = new ReadBuffer(testcase.getRaw());
+        String referenceXml = testcase.getXml().elements().get(0).asXML();
+
+        MessageIO messageIO = getMessageIOForTestcase(testcase);
+        try {
+            Object msg = messageIO.parse(readBuffer);
+            String xmlString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(msg);
+            Diff diff = DiffBuilder.compare(referenceXml).withTest(xmlString).ignoreWhitespace().build();
+            if(diff.hasDifferences()) {
+                // TODO: Add some more information ...
+                throw new ProtocolTestsuiteException("Differences were found");
+            }
+        } catch (ParseException e) {
+            throw new ProtocolTestsuiteException("Unable to parse message", e);
+        } catch (JsonProcessingException e) {
+            throw new ProtocolTestsuiteException("Unable to serialize parsed message as XML string", e);
+        }
+    }
+
+    private MessageIO getMessageIOForTestcase(Testcase testcase) throws ProtocolTestsuiteException {
+        String className = testcase.getXml().elements().get(0).attributeValue(new QName("className"));
+        String ioClassName = className.substring(0, className.lastIndexOf('.') + 1) + "io." +
+            testcase.getRootType() + "IO";
+        try {
+            Class<?> ioClass = Class.forName(ioClassName);
+            Object inst = ioClass.getDeclaredConstructor().newInstance();
+            if(inst instanceof MessageIO) {
+                return (MessageIO) inst;
+            } else {
+                throw new ProtocolTestsuiteException("Found IO component class is not of type MessageIO");
+            }
+        } catch (InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException |
+            ClassNotFoundException e) {
+            throw new ProtocolTestsuiteException("Unable to instantiate IO component", e);
+        }
+    }
+
+}
diff --git a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/exceptions/ProtocolTestsuiteException.java b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/exceptions/ProtocolTestsuiteException.java
new file mode 100644
index 0000000..81500b5
--- /dev/null
+++ b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/exceptions/ProtocolTestsuiteException.java
@@ -0,0 +1,32 @@
+/*
+ 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.protocol.test.exceptions;
+
+public class ProtocolTestsuiteException extends Exception {
+
+    public ProtocolTestsuiteException(String message) {
+        super(message);
+    }
+
+    public ProtocolTestsuiteException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java
new file mode 100644
index 0000000..68b0ffe
--- /dev/null
+++ b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java
@@ -0,0 +1,42 @@
+/*
+ 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.protocol.test.model;
+
+import java.util.List;
+
+public class ProtocolTestsuite {
+
+    private final String name;
+    private final List<Testcase> testcases;
+
+    public ProtocolTestsuite(String name, List<Testcase> testcases) {
+        this.name = name;
+        this.testcases = testcases;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public List<Testcase> getTestcases() {
+        return testcases;
+    }
+
+}
diff --git a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/Testcase.java b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/Testcase.java
new file mode 100644
index 0000000..8df639b
--- /dev/null
+++ b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/Testcase.java
@@ -0,0 +1,61 @@
+/*
+ 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.protocol.test.model;
+
+import org.dom4j.Element;
+import org.w3c.dom.Document;
+
+public class Testcase {
+
+    private final String name;
+    private final String description;
+    private final byte[] raw;
+    private final String rootType;
+    private final Element xml;
+
+    public Testcase(String name, String description, byte[] raw, String rootType, Element xml) {
+        this.name = name;
+        this.description = description;
+        this.raw = raw;
+        this.rootType = rootType;
+        this.xml = xml;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public byte[] getRaw() {
+        return raw;
+    }
+
+    public String getRootType() {
+        return rootType;
+    }
+
+    public Element getXml() {
+        return xml;
+    }
+
+}
diff --git a/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd b/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd
new file mode 100644
index 0000000..5ef4977
--- /dev/null
+++ b/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<xs:schema targetNamespace="https://plc4x.apache.org/schemas/testsuite.xsd"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+    <xs:element name="testsuite">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="name" type="xs:string"/>
+                <!--
+                    Each testcase is a set of hexadecimal input and expected output.
+                    A test will parse the binary input and compare the parsed result
+                    with the expected output. If that matches, it serializes the model
+                    back to it's binary representation and then compares the binary
+                    output with the original.
+                -->
+                <xs:element name="testcase" maxOccurs="unbounded">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <!-- The name of the test, as it is output by the test-runner -->
+                            <xs:element name="name" type="xs:string"/>
+                            <!-- Some optional description of what the test should do -->
+                            <xs:element name="description" type="xs:string" minOccurs="0"/>
+                            <!-- A hexadecimal representation of the input to the parser -->
+                            <xs:element name="raw" type="xs:hexBinary"/>
+                            <!-- The root type we should use for serializing and parsing -->
+                            <xs:element name="root-type" type="xs:string"/>
+                            <!-- An Xml serialized representation of the expected model -->
+                            <xs:element name="xml" type="xs:anyType"/>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+</xs:schema>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 2fa24cb..e01a7f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -155,6 +155,7 @@
     <spock.version>1.2-groovy-2.5</spock.version>
     <t-digest.version>3.2</t-digest.version>
     <thrift.version>0.12.0</thrift.version>
+    <xmlunit.version>2.6.3</xmlunit.version>
 
     <!-- Site properties -->
     <asciidoctor.maven.plugin.version>2.0.0-RC.1</asciidoctor.maven.plugin.version>
@@ -538,6 +539,11 @@
         <scope>test</scope>
       </dependency>
       <dependency>
+        <groupId>org.dom4j</groupId>
+        <artifactId>dom4j</artifactId>
+        <version>2.1.1</version>
+      </dependency>
+      <dependency>
         <groupId>org.elasticsearch</groupId>
         <artifactId>elasticsearch</artifactId>
         <version>${elasticsearch.version}</version>
@@ -659,6 +665,16 @@
         <scope>test</scope>
       </dependency>
       <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-core</artifactId>
+        <version>${xmlunit.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-matchers</artifactId>
+        <version>${xmlunit.version}</version>
+      </dependency>
+      <dependency>
         <groupId>org.yaml</groupId>
         <artifactId>snakeyaml</artifactId>
         <version>${snakeyaml.version}</version>
diff --git a/sandbox/test-java-knxnetip-driver/pom.xml b/sandbox/test-java-knxnetip-driver/pom.xml
index bc23e19..cdcc0cc 100644
--- a/sandbox/test-java-knxnetip-driver/pom.xml
+++ b/sandbox/test-java-knxnetip-driver/pom.xml
@@ -66,6 +66,12 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-protocol-test-utils</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
       <scope>test</scope>
diff --git a/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/IOTest.java b/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/IOTest.java
index 5653814..8ce22ad 100644
--- a/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/IOTest.java
+++ b/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/IOTest.java
@@ -36,7 +36,7 @@ public class IOTest {
         byte[] rData = Hex.decodeHex("0610020500180801c0a82a46c4090801c0a82a46c40a0203");
         ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
         ReadBuffer rBuf = new ReadBuffer(rData);
-        KNXNetIPMessage packet = KNXNetIPMessageIO.parse(rBuf);
+        KNXNetIPMessage packet = new KNXNetIPMessageIO().parse(rBuf);
         String xml = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(packet);
         System.out.println(xml);
         KNXNetIPMessage pack2 = mapper.readValue(xml, KNXNetIPMessage.class);
@@ -48,7 +48,7 @@ public class IOTest {
         byte[] rData = Hex.decodeHex("0610020500180801c0a82a46c4090801c0a82a46c40a0203");
         ObjectMapper mapper = new ObjectMapper().enableDefaultTyping();
         ReadBuffer rBuf = new ReadBuffer(rData);
-        KNXNetIPMessage packet = KNXNetIPMessageIO.parse(rBuf);
+        KNXNetIPMessage packet = new KNXNetIPMessageIO().parse(rBuf);
         String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(packet);
         System.out.println(json);
         KNXNetIPMessage pack2 = mapper.readValue(json, KNXNetIPMessage.class);
@@ -59,13 +59,15 @@ public class IOTest {
     public void testParser() throws Exception {
         byte[] rData = Hex.decodeHex("0610020500180801c0a82a46c4090801c0a82a46c40a0203");
         long start = System.currentTimeMillis();
-        int numRunsParse = 2000000;
+        int numRunsParse = 20000;
+
+        KNXNetIPMessageIO knxNetIPMessageIO = new KNXNetIPMessageIO();
 
         // Benchmark the parsing code
         KNXNetIPMessage packet = null;
         for(int i = 0; i < numRunsParse; i++) {
             ReadBuffer rBuf = new ReadBuffer(rData);
-            packet = KNXNetIPMessageIO.parse(rBuf);
+            packet = knxNetIPMessageIO.parse(rBuf);
         }
         long endParsing = System.currentTimeMillis();
 
@@ -73,11 +75,11 @@ public class IOTest {
         System.out.println("That's " + ((float) (endParsing - start) / numRunsParse) + "ms per packet");
 
         // Benchmark the serializing code
-        int numRunsSerialize = 2000000;
+        int numRunsSerialize = 20000;
         byte[] oData = null;
         for(int i = 0; i < numRunsSerialize; i++) {
             WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
-            KNXNetIPMessageIO.serialize(wBuf, packet);
+            knxNetIPMessageIO.serialize(wBuf, packet);
             oData = wBuf.getData();
         }
         long endSerializing = System.currentTimeMillis();
diff --git a/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/KNXNetIpTestsuite.java b/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/KNXNetIpTestsuite.java
new file mode 100644
index 0000000..bb6fcde
--- /dev/null
+++ b/sandbox/test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/KNXNetIpTestsuite.java
@@ -0,0 +1,30 @@
+/*
+  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.java.knxnetip;
+
+import org.apache.plc4x.protocol.test.ProtocolTestsuiteRunner;
+
+public class KNXNetIpTestsuite extends ProtocolTestsuiteRunner {
+
+    public KNXNetIpTestsuite() {
+        super("/testsuite/KNXNetIPTestsuite.xml");
+    }
+
+}
diff --git a/sandbox/test-java-knxnetip-driver/src/test/resources/testsuite/KNXNetIPTestsuite.xml b/sandbox/test-java-knxnetip-driver/src/test/resources/testsuite/KNXNetIPTestsuite.xml
new file mode 100644
index 0000000..39274da
--- /dev/null
+++ b/sandbox/test-java-knxnetip-driver/src/test/resources/testsuite/KNXNetIPTestsuite.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/testsuite.xsd">
+
+  <name>KNXNet/IP</name>
+
+  <testcase>
+    <name>Default</name>
+    <raw>0610020500180801c0a82a46c4090801c0a82a46c40a0203</raw>
+    <root-type>KNXNetIPMessage</root-type>
+    <xml>
+      <ConnectionRequest className="org.apache.plc4x.java.knxnetip.ConnectionRequest">
+        <protocolVersion>16</protocolVersion>
+        <hpaiDiscoveryEndpoint>
+          <hostProtocolCode>1</hostProtocolCode>
+          <ipAddress>
+            <addr>
+              <addr>192</addr>
+              <addr>168</addr>
+              <addr>42</addr>
+              <addr>70</addr>
+            </addr>
+          </ipAddress>
+          <ipPort>50185</ipPort>
+        </hpaiDiscoveryEndpoint>
+        <hpaiDataEndpoint>
+          <hostProtocolCode>1</hostProtocolCode>
+          <ipAddress>
+            <addr>
+              <addr>192</addr>
+              <addr>168</addr>
+              <addr>42</addr>
+              <addr>70</addr>
+            </addr>
+          </ipAddress>
+          <ipPort>50186</ipPort>
+        </hpaiDataEndpoint>
+        <connectionRequestInformation className="org.apache.plc4x.java.knxnetip.ConnectionRequestInformationDeviceManagement"/>
+      </ConnectionRequest>
+    </xml>
+  </testcase>
+
+</test:testsuite>
\ No newline at end of file
diff --git a/sandbox/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java b/sandbox/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java
index 24fd194..e231fe9 100644
--- a/sandbox/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java
+++ b/sandbox/test-java-s7-driver/src/test/java/BenchmarkGeneratedS7.java
@@ -31,12 +31,13 @@ public class BenchmarkGeneratedS7 {
         byte[] rData = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
         long start = System.currentTimeMillis();
         int numRunsParse = 2000000;
+        TPKTPacketIO tpktPacketIO = new TPKTPacketIO();
 
         // Benchmark the parsing code
         TPKTPacket packet = null;
         for(int i = 0; i < numRunsParse; i++) {
             ReadBuffer rBuf = new ReadBuffer(rData);
-            packet = TPKTPacketIO.parse(rBuf);
+            packet = tpktPacketIO.parse(rBuf);
         }
         long endParsing = System.currentTimeMillis();
 
@@ -48,7 +49,7 @@ public class BenchmarkGeneratedS7 {
         byte[] oData = null;
         for(int i = 0; i < numRunsSerialize; i++) {
             WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
-            TPKTPacketIO.serialize(wBuf, packet);
+            tpktPacketIO.serialize(wBuf, packet);
             oData = wBuf.getData();
         }
         long endSerializing = System.currentTimeMillis();