You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2024/05/04 17:31:07 UTC

(plc4x) 01/01: fix(plc4py): Get the integration test at least running

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

hutcheb pushed a commit to branch plc4py/integration-test
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 9c0969c8bb37ebf65573e1d0e0640e5429b4af57
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Sat May 4 19:30:56 2024 +0200

    fix(plc4py): Get the integration test at least running
---
 code-generation/language-python/pom.xml            |   2 +-
 .../python/complex-type-template.python.ftlh       |  21 +-
 .../src/test/resources/integration-test/pom.xml    | 119 --------
 .../java/test/readwrite/utils/StaticHelper.java    |  90 ------
 .../src/test/resources/plc4py/plc4py/__init__.py   |  16 ++
 .../resources/plc4py/plc4py/protocols/__init__.py  |  16 ++
 .../plc4py/plc4py/protocols/test/StaticHelper.py   |  29 ++
 .../plc4py/plc4py/protocols/test/__init__.py       |  16 ++
 .../src/test/resources/plc4py/pom.xml              | 305 +++++++++++++++++++++
 9 files changed, 392 insertions(+), 222 deletions(-)

diff --git a/code-generation/language-python/pom.xml b/code-generation/language-python/pom.xml
index 3653c065d7..292d1489d9 100644
--- a/code-generation/language-python/pom.xml
+++ b/code-generation/language-python/pom.xml
@@ -34,7 +34,7 @@
 
   <properties>
     <!-- Disabled for now as the python code doesn't seem to build -->
-    <skip-code-generation-tests>true</skip-code-generation-tests>
+    <skip-code-generation-tests>false</skip-code-generation-tests>
     <project.build.outputTimestamp>2024-02-16T14:53:02Z</project.build.outputTimestamp>
   </properties>
 
diff --git a/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh b/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
index 2e64858ea1..b179f1acaf 100644
--- a/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
+++ b/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
@@ -275,13 +275,12 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
         # Optional Field (${optionalField.name}) (Can be skipped, if the value is null)
-        if ${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}:
                             <#if optionalField.type.isEnumTypeReference()>
-            write_buffer.${helper.getEnumDataWriterCall(optionalField.type, optionalField.name, "value")}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}")
+        write_buffer.${helper.getEnumDataWriterCall(optionalField.type, optionalField.name, "value")}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}")
                             <#elseif optionalField.type.isDataIoTypeReference()>
-            write_buffer.${helper.getDataWriterCall(typedField.type, optionalField.name)}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}", <#list optionalField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(optionalField, helper.anyTypeReference, param, parserArguments)}<#sep>, </#sep></#list>)))
+        write_buffer.${helper.getDataWriterCall(typedField.type, optionalField.name)}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}", <#list optionalField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(optionalField, helper.anyTypeReference, param, parserArguments)}<#sep>, </#sep></#list>)))
                             <#else>
-            write_buffer.${helper.getDataWriterCall(typedField.type, optionalField.name)}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}"<#if optionalField.conditionExpression.present></#if>)
+        write_buffer.${helper.getDataWriterCall(typedField.type, optionalField.name)}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}"<#if optionalField.conditionExpression.present></#if>)
                             </#if>
                         <#break>
                     <#case "padding">
@@ -437,21 +436,20 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
         <#assign optionalField = field.asOptionalField().orElseThrow()>
 
         # Optional Field (${optionalField.name})
-        if ${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}:
         <#if optionalField.type.isSimpleTypeReference()>
             <#assign simpleTypeReference = optionalField.type.asSimpleTypeReference().orElseThrow()>
             <#if simpleTypeReference.isVstringTypeReference()>
                 <#assign vstringTypeReference = simpleTypeReference.asVstringTypeReference().orElseThrow()>
-            length_in_bits += ${helper.toSerializationExpression(optionalField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)}
+        length_in_bits += ${helper.toSerializationExpression(optionalField, helper.intTypeReference, vstringTypeReference.getLengthExpression(), parserArguments)}
             <#else>
-            length_in_bits += ${simpleTypeReference.sizeInBits}
+        length_in_bits += ${simpleTypeReference.sizeInBits}
             </#if>
         <#elseif helper.isEnumField(field)>
-            length_in_bits += ${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits}
+        length_in_bits += ${helper.getEnumBaseTypeReference(optionalField.type).sizeInBits}
         <#elseif optionalField.type.isDataIoTypeReference()>
-            length_in_bits += ${optionalField.type.asComplexTypeReference().orElseThrow().name}.length_in_bits(self.${helper.camelCaseToSnakeCase(optionalField.name)}<#if optionalField.type.asComplexTypeReference().orElseThrow().params?has_content>, <#list optionalField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(optionalField, helper.anyTypeReference, param, parserArguments)}<#sep>, </#sep></#list></#if>)
+        length_in_bits += ${optionalField.type.asComplexTypeReference().orElseThrow().name}.length_in_bits(self.${helper.camelCaseToSnakeCase(optionalField.name)}<#if optionalField.type.asComplexTypeReference().orElseThrow().params?has_content>, <#list optionalField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(optionalField, helper.anyTypeReference, param, parserArguments)}<#sep>, </#sep></#list></#if>)
         <#else>
-            length_in_bits += self.${helper.camelCaseToSnakeCase(optionalField.name)}.length_in_bits()
+        length_in_bits += self.${helper.camelCaseToSnakeCase(optionalField.name)}.length_in_bits()
         </#if>
 
         <#break>
@@ -670,8 +668,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                 <#assign typedField = field.asTypedField().orElseThrow()>
                 <#assign namedField = field.asNamedField().orElseThrow()>
         ${helper.camelCaseToSnakeCase(namedField.name)}: ${helper.getLanguageTypeNameForTypeReference(optionalField.type, false)} = None
-        if ${helper.toParseExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}:
-            ${helper.camelCaseToSnakeCase(namedField.name)} = read_buffer.${helper.getDataReaderCall(optionalField.type)}(logical_name="${namedField.name}"<#if optionalField.conditionExpression.present></#if>${helper.getFieldOptions(typedField, parserArguments)}<#if hasParserArguments>, ${parsedList}</#if>)
+        ${helper.camelCaseToSnakeCase(namedField.name)} = read_buffer.${helper.getDataReaderCall(optionalField.type)}(logical_name="${namedField.name}"<#if optionalField.conditionExpression.present></#if>${helper.getFieldOptions(typedField, parserArguments)}<#if hasParserArguments>, ${parsedList}</#if>)
 
                 <#break>
             <#case "padding">
diff --git a/code-generation/language-python/src/test/resources/integration-test/pom.xml b/code-generation/language-python/src/test/resources/integration-test/pom.xml
deleted file mode 100644
index 596cd238eb..0000000000
--- a/code-generation/language-python/src/test/resources/integration-test/pom.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?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
-
-      https://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>plc4x-code-generation</artifactId>
-    <version>@project.version@</version>
-    <relativePath>../../../..</relativePath>
-  </parent>
-
-  <artifactId>plc4py-python-mspec-test</artifactId>
-
-  <name>PLC4PY: Driver: Python Mspec Test</name>
-  <description></description>
-
-  <build>
-    <plugins>
-      <!--plugin>
-        <groupId>org.apache.plc4x.plugins</groupId>
-        <artifactId>plc4x-maven-plugin</artifactId>
-        <version>${plc4x-code-generation.version}</version>
-        <executions>
-          <execution>
-            <id>generate-driver</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>generate-driver</goal>
-            </goals>
-            <configuration>
-              <protocolName>test</protocolName>
-              <languageName>python</languageName>
-              <outputFlavor>read-write</outputFlavor>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin-->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <configuration>
-          <usedDependencies combine.children="append">
-            <usedDependency>org.apache.plc4x:plc4x-code-generation-language-python</usedDependency>
-            <usedDependency>org.apache.plc4x:plc4x-code-generation-protocol-test</usedDependency>
-          </usedDependencies>
-        </configuration>
-      </plugin>
-
-      <!--
-          Make the failsafe execute all integration-tests
-        -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>integration-test</goal>
-              <goal>verify</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <!--
-                Notice the @ instead of the $ as prefix? That's late evaluation.
-          -->
-          <!--argLine>@{failsafeArgLine}</argLine-->
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-<dependencies>
-    <dependency>
-      <groupId>org.apache.plc4x</groupId>
-      <artifactId>plc4x-code-generation-language-python</artifactId>
-      <version>@project.version@</version>
-      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.plc4x</groupId>
-      <artifactId>plc4x-code-generation-protocol-test</artifactId>
-      <version>@project.version@</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.plc4x</groupId>
-      <artifactId>plc4x-code-generation-protocol-test</artifactId>
-      <version>@project.version@</version>
-      <classifier>tests</classifier>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-
-  </dependencies>
-
-</project>
-
diff --git a/code-generation/language-python/src/test/resources/integration-test/src/main/java/org/apache/plc4x/java/test/readwrite/utils/StaticHelper.java b/code-generation/language-python/src/test/resources/integration-test/src/main/java/org/apache/plc4x/java/test/readwrite/utils/StaticHelper.java
deleted file mode 100644
index cc1f621980..0000000000
--- a/code-generation/language-python/src/test/resources/integration-test/src/main/java/org/apache/plc4x/java/test/readwrite/utils/StaticHelper.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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
- *
- *   https://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.test.readwrite.utils;
-
-import org.apache.plc4x.java.spi.generation.*;
-
-public class StaticHelper {
-
-    public static boolean parseBit(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeBit(WriteBuffer io, boolean data) {
-    }
-
-    public static byte parseByte(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeByte(WriteBuffer io, byte data) {
-    }
-
-    public static byte parseInt8(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeInt8(WriteBuffer io, byte data) {
-    }
-
-    public static short parseUint8(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeUint8(WriteBuffer io, short data) {
-    }
-
-    public static float parseFloat(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeFloat(WriteBuffer io, float data) {
-    }
-
-    public static double parseDouble(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeDouble(WriteBuffer io, double data) {
-    }
-
-    public static String parseString(ReadBuffer io) {
-        throw new IllegalArgumentException("Hurz!");
-    }
-
-    public static void serializeString(WriteBuffer io, String data) {
-    }
-
-    public static short readManualField(ReadBuffer io, short simpleField) {
-        return 0;
-    }
-
-    public static void writeManualField(WriteBuffer io, short simpleFlied) {
-
-    }
-
-    public static short crcInt8(int num) {
-        return (byte) num;
-    }
-
-    public static short crcUint8(int num) {
-        return (short) num;
-    }
-
-}
diff --git a/code-generation/language-python/src/test/resources/plc4py/plc4py/__init__.py b/code-generation/language-python/src/test/resources/plc4py/plc4py/__init__.py
new file mode 100644
index 0000000000..a67d5ea255
--- /dev/null
+++ b/code-generation/language-python/src/test/resources/plc4py/plc4py/__init__.py
@@ -0,0 +1,16 @@
+#  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.
diff --git a/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/__init__.py b/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/__init__.py
new file mode 100644
index 0000000000..a67d5ea255
--- /dev/null
+++ b/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/__init__.py
@@ -0,0 +1,16 @@
+#  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.
diff --git a/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/test/StaticHelper.py b/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/test/StaticHelper.py
new file mode 100644
index 0000000000..d0bf8a53c8
--- /dev/null
+++ b/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/test/StaticHelper.py
@@ -0,0 +1,29 @@
+#  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.
+
+from plc4py.spi.generation.ReadBuffer import ReadBuffer
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
+
+
+def ParseBit(read_buffer: ReadBuffer) -> bool:
+    return False
+
+
+def ParseBit(write_buffer: WriteBuffer, data: bool):
+    pass
+    
+    
\ No newline at end of file
diff --git a/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/test/__init__.py b/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/test/__init__.py
new file mode 100644
index 0000000000..a67d5ea255
--- /dev/null
+++ b/code-generation/language-python/src/test/resources/plc4py/plc4py/protocols/test/__init__.py
@@ -0,0 +1,16 @@
+#  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.
diff --git a/code-generation/language-python/src/test/resources/plc4py/pom.xml b/code-generation/language-python/src/test/resources/plc4py/pom.xml
new file mode 100644
index 0000000000..059fea2df2
--- /dev/null
+++ b/code-generation/language-python/src/test/resources/plc4py/pom.xml
@@ -0,0 +1,305 @@
+<?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>plc4x-code-generation</artifactId>
+    <version>@project.version@</version>
+    <relativePath>../../../..</relativePath>
+  </parent>
+
+  <artifactId>plc4py-python-mspec-test</artifactId>
+
+  <name>PLC4PY: Driver: Python Mspec Test</name>
+  <description></description>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>3.3.0</version>
+        <executions>
+          <execution>
+            <id>python-copy-setup</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>./</outputDirectory>
+              <resources>
+                <resource>
+                  <targetPath>.</targetPath>
+                  <directory>${project.basedir}/../../../../../plc4py/</directory>
+                  <includes>
+                    <include>setup.*</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>
+              <encoding>UTF-8</encoding>
+            </configuration>
+          </execution>
+          <execution>
+            <id>python-copy</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>./plc4py</outputDirectory>
+              <resources>
+                <resource>
+                  <targetPath>.</targetPath>
+                  <directory>${project.basedir}/../../../../../plc4py/plc4py</directory>
+                  <filtering>false</filtering>
+                </resource>
+              </resources>
+              <encoding>UTF-8</encoding>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <version>${plc4x-code-generation.version}</version>
+        <executions>
+          <execution>
+            <id>generate-driver</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>test</protocolName>
+              <languageName>python</languageName>
+              <outputFlavor>read-write</outputFlavor>
+              <outputDir>${project.basedir}/plc4py/protocols</outputDir>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.karaf.tooling</groupId>
+        <artifactId>karaf-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-feature-xml</id>
+            <phase>compile</phase>
+            <goals>
+              <!-- Generate the feature.xml -->
+              <goal>features-generate-descriptor</goal>
+              <!-- Check the feature.xml -->
+              <goal>verify</goal>
+            </goals>
+            <configuration>
+              <enableGeneration>true</enableGeneration>
+              <aggregateFeatures>true</aggregateFeatures>
+            </configuration>
+          </execution>
+          <execution>
+            <id>build-kar</id>
+            <phase>package</phase>
+            <goals>
+              <!--
+                Build a kar archive (Jar containing the feature.xml
+                as well as the module content and it's dependencies.
+              -->
+              <goal>kar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
+            <Bundle-Activator>org.apache.plc4x.java.osgi.DriverActivator</Bundle-Activator>
+            <Export-Service>org.apache.plc4x.java.api.PlcDriver,org.apache.plc4x.protocol.test
+            </Export-Service>
+            <Import-Package>
+              *
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <configuration>
+          <usedDependencies combine.children="append">
+            <usedDependency>org.apache.plc4x:plc4x-code-generation-language-python</usedDependency>
+            <usedDependency>org.apache.plc4x:plc4x-code-generation-protocol-test</usedDependency>
+          </usedDependencies>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>python-venv</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>${python.exe.bin}</executable>
+              <arguments>
+                <argument>-m</argument>
+                <argument>venv</argument>
+                <argument>./venv</argument>
+              </arguments>
+            </configuration>
+          </execution>
+
+          <execution>
+            <id>python-upgrade-pip</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>${python.venv.bin}${python.exe.bin}</executable>
+              <arguments>
+                <argument>-m</argument>
+                <argument>pip</argument>
+                <argument>install</argument>
+                <argument>--upgrade</argument>
+                <argument>pip</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>python-install</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>${python.venv.bin}pip3</executable>
+              <arguments>
+                <argument>install</argument>
+                <argument>.</argument>
+              </arguments>
+            </configuration>
+          </execution>
+
+          <execution>
+            <id>python-black</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>${python.venv.bin}${python.exe.bin}</executable>
+              <arguments>
+                <argument>-m</argument>
+                <argument>black</argument>
+                <argument>.</argument>
+              </arguments>
+            </configuration>
+          </execution>
+
+          <execution>
+            <id>python-test-compile</id>
+            <phase>test-compile</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>${python.venv.bin}pip3</executable>
+              <arguments>
+                <argument>install</argument>
+                <argument>.[dev]</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!--
+          Make the failsafe execute all integration-tests
+        -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>integration-test</goal>
+              <goal>verify</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <!--
+                Notice the @ instead of the $ as prefix? That's late evaluation.
+          -->
+          <!--argLine>@{failsafeArgLine}</argLine-->
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+<dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-language-python</artifactId>
+      <version>@project.version@</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-protocol-test</artifactId>
+      <version>@project.version@</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-protocol-test</artifactId>
+      <version>@project.version@</version>
+      <classifier>tests</classifier>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+</project>
+