You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2021/03/23 08:51:24 UTC

[plc4x] branch develop updated: plc4go: reactivated test by inserting artificial delay

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

sruehl 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 13f6d24  plc4go: reactivated test by inserting artificial delay
13f6d24 is described below

commit 13f6d24fd3f75a3c718a5f9620a451a3a0bb018e
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Mar 23 09:50:19 2021 +0100

    plc4go: reactivated test by inserting artificial delay
---
 .../cmd/main/drivers/tests/modbus_driver_test.go   |  5 +-
 plc4go/internal/plc4go/modbus/Field.go             |  4 ++
 .../interceptors/SingleItemRequestInterceptor.go   | 10 +++-
 .../plc4go/spi/model/DefaultPlcReadRequest.go      |  5 +-
 .../plc4go/spi/testutils/DriverTestRunner.go       | 22 ++++++++
 .../spi/testutils/ParserSerializerTestRunner.go    |  3 +-
 .../plc4go/spi/testutils/steptype_string.go        | 48 +++++++++++++++++
 .../plc4go/spi/transports/tcp/Transport.go         | 62 +++++++++++-----------
 .../plc4go/spi/transports/test/Transport.go        | 10 ++--
 .../plc4go/spi/transports/udp/Transport.go         | 60 ++++++++++-----------
 plc4go/pom.xml                                     | 16 ++++++
 11 files changed, 169 insertions(+), 76 deletions(-)

diff --git a/plc4go/cmd/main/drivers/tests/modbus_driver_test.go b/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
index 085804b..601c388 100644
--- a/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
+++ b/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
@@ -26,8 +26,5 @@ import (
 )
 
 func TestModbusDriver(t *testing.T) {
-	testutils.RunDriverTestsuite(t, modbus.NewDriver(), "assets/testing/protocols/modbus/DriverTestsuite.xml",
-		// TODO: this testcase has still some concurrency issues regarding the order of data
-		"Multi element read request",
-	)
+	testutils.RunDriverTestsuite(t, modbus.NewDriver(), "assets/testing/protocols/modbus/DriverTestsuite.xml")
 }
diff --git a/plc4go/internal/plc4go/modbus/Field.go b/plc4go/internal/plc4go/modbus/Field.go
index 1f8f2af..442f0ed 100644
--- a/plc4go/internal/plc4go/modbus/Field.go
+++ b/plc4go/internal/plc4go/modbus/Field.go
@@ -53,6 +53,10 @@ func NewModbusPlcFieldFromStrings(fieldType FieldType, addressString string, qua
 	if err != nil {
 		return nil, errors.Errorf("Couldn't parse address string '%s' into an int", addressString)
 	}
+	if quantityString == "" {
+		log.Debug().Msg("No quantity supplied, assuming 1")
+		quantityString = "1"
+	}
 	quantity, err := strconv.Atoi(quantityString)
 	if err != nil {
 		log.Warn().Err(err).Msgf("Error during atoi for %s. Falling back to 1", quantityString)
diff --git a/plc4go/internal/plc4go/spi/interceptors/SingleItemRequestInterceptor.go b/plc4go/internal/plc4go/spi/interceptors/SingleItemRequestInterceptor.go
index 7308096..0ec0c71 100644
--- a/plc4go/internal/plc4go/spi/interceptors/SingleItemRequestInterceptor.go
+++ b/plc4go/internal/plc4go/spi/interceptors/SingleItemRequestInterceptor.go
@@ -24,6 +24,7 @@ import (
 	"github.com/apache/plc4x/plc4go/internal/plc4go/spi/utils"
 	apiModel "github.com/apache/plc4x/plc4go/pkg/plc4go/model"
 	"github.com/apache/plc4x/plc4go/pkg/plc4go/values"
+	"github.com/rs/zerolog/log"
 )
 
 type SingleItemRequestInterceptor struct {
@@ -36,12 +37,15 @@ func NewSingleItemRequestInterceptor() SingleItemRequestInterceptor {
 func (m SingleItemRequestInterceptor) InterceptReadRequest(readRequest apiModel.PlcReadRequest) []apiModel.PlcReadRequest {
 	// If this request just has one field, go the shortcut
 	if len(readRequest.GetFieldNames()) == 1 {
+		log.Debug().Msg("We got only one request, no splitting required")
 		return []apiModel.PlcReadRequest{readRequest}
 	}
+	log.Trace().Msg("Splitting requests")
 	// In all other cases, create a new read request containing only one item
 	defaultReadRequest := readRequest.(model.DefaultPlcReadRequest)
 	var readRequests []apiModel.PlcReadRequest
 	for _, fieldName := range readRequest.GetFieldNames() {
+		log.Debug().Str("fieldName", fieldName).Msg("Splitting into own request")
 		field := readRequest.GetField(fieldName)
 		subReadRequest := model.NewDefaultPlcReadRequest(
 			map[string]apiModel.PlcField{fieldName: field},
@@ -55,9 +59,10 @@ func (m SingleItemRequestInterceptor) InterceptReadRequest(readRequest apiModel.
 
 func (m SingleItemRequestInterceptor) ProcessReadResponses(readRequest apiModel.PlcReadRequest, readResults []apiModel.PlcReadRequestResult) apiModel.PlcReadRequestResult {
 	if len(readResults) == 1 {
+		log.Debug().Msg("We got only one response, no merging required")
 		return readResults[0]
 	}
-
+	log.Trace().Msg("Merging requests")
 	responseCodes := map[string]apiModel.PlcResponseCode{}
 	val := map[string]values.PlcValue{}
 	var err *utils.MultiError = nil
@@ -70,6 +75,9 @@ func (m SingleItemRequestInterceptor) ProcessReadResponses(readRequest apiModel.
 				err.Errors = append(err.Errors, readResult.Err)
 			}
 		} else if readResult.Response != nil {
+			if len(readResult.Response.GetRequest().GetFieldNames()) > 1 {
+				log.Fatal().Int("numberOfFields", len(readResult.Response.GetRequest().GetFieldNames())).Msg("We should only get 1")
+			}
 			for _, fieldName := range readResult.Response.GetRequest().GetFieldNames() {
 				responseCodes[fieldName] = readResult.Response.GetResponseCode(fieldName)
 				val[fieldName] = readResult.Response.GetValue(fieldName)
diff --git a/plc4go/internal/plc4go/spi/model/DefaultPlcReadRequest.go b/plc4go/internal/plc4go/spi/model/DefaultPlcReadRequest.go
index 8a6e919..16dd1a1 100644
--- a/plc4go/internal/plc4go/spi/model/DefaultPlcReadRequest.go
+++ b/plc4go/internal/plc4go/spi/model/DefaultPlcReadRequest.go
@@ -23,6 +23,7 @@ import (
 	"github.com/apache/plc4x/plc4go/internal/plc4go/spi"
 	"github.com/apache/plc4x/plc4go/pkg/plc4go/model"
 	"github.com/pkg/errors"
+	"time"
 )
 
 type DefaultPlcReadRequestBuilder struct {
@@ -112,8 +113,8 @@ func (m DefaultPlcReadRequest) Execute() <-chan model.PlcReadRequestResult {
 	// Iterate over all requests and add the result-channels to the list
 	for _, subRequest := range readRequests {
 		subResultChannels = append(subResultChannels, m.Reader.Read(subRequest))
-		// TODO: Replace this with a real queueing of requests.
-		//time.Sleep(time.Millisecond * 20)
+		// TODO: Replace this with a real queueing of requests. Later on we need throttling. At the moment this avoids race condition as the read above writes to fast on the line which is a problem for the test
+		time.Sleep(time.Millisecond * 4)
 	}
 
 	// Create a new result-channel, which completes as soon as all sub-result-channels have returned
diff --git a/plc4go/internal/plc4go/spi/testutils/DriverTestRunner.go b/plc4go/internal/plc4go/spi/testutils/DriverTestRunner.go
index 88e709c..d304ac1 100644
--- a/plc4go/internal/plc4go/spi/testutils/DriverTestRunner.go
+++ b/plc4go/internal/plc4go/spi/testutils/DriverTestRunner.go
@@ -98,11 +98,13 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 
 	log.Info().Msgf(" - Executing step: %s \n", step.name)
 
+	log.Debug().Stringer("stepType", step.stepType).Msg("Handling step")
 	switch step.stepType {
 	case StepTypeApiRequest:
 		switch step.payload.Name {
 		case "TestReadRequest":
 			// Assemble a read-request according to the information in the test xml
+			log.Trace().Msg("Assemble read request")
 			rrb := connection.ReadRequestBuilder()
 			for _, fieldNode := range step.payload.GetChild("fields").GetChildren("field") {
 				fieldName := fieldNode.GetChild("name").Text
@@ -115,11 +117,13 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 			}
 
 			// Execute the read-request and store the response-channel in the testcase.
+			log.Trace().Msg("Execute read request")
 			if testcase.readRequestResultChannel != nil {
 				return errors.New("testcase read-request result channel already occupied")
 			}
 			testcase.readRequestResultChannel = readRequest.Execute()
 		case "TestWriteRequest":
+			log.Trace().Msg("Assemble write request")
 			wrb := connection.WriteRequestBuilder()
 			for _, fieldNode := range step.payload.GetChild("fields").GetChildren("field") {
 				fieldName := fieldNode.GetChild("name").Text
@@ -148,6 +152,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 			if err != nil {
 				return errors.Wrap(err, "Error creating write-request")
 			}
+			log.Trace().Msg("Execute write request")
 			if testcase.writeRequestResultChannel != nil {
 				return errors.New("testcase write-request result channel already occupied")
 			}
@@ -159,6 +164,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 			if testcase.readRequestResultChannel == nil {
 				return errors.New("no read response expected")
 			}
+			log.Trace().Msg("Waiting for read request result")
 			readRequestResult := <-testcase.readRequestResultChannel
 			// Serialize the response to XML
 			actualResponse, err := xml.Marshal(readRequestResult.Response)
@@ -176,6 +182,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 			if testcase.writeRequestResultChannel == nil {
 				return errors.New("no write response expected")
 			}
+			log.Trace().Msg("Waiting for write request result")
 			writeResponseResult := <-testcase.writeRequestResultChannel
 			// Serialize the response to XML
 			actualResponse, err := xml.Marshal(writeResponseResult.Response)
@@ -195,12 +202,14 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		payloadString := step.payload.XML()
 
 		// Parse the xml into a real model
+		log.Trace().Msg("parsing xml")
 		message, err := model2.ModbusXmlParserHelper{}.Parse(typeName, payloadString)
 		if err != nil {
 			return errors.Wrap(err, "error parsing xml")
 		}
 
 		// Serialize the model into bytes
+		log.Trace().Msg("Write to bytes")
 		ser, ok := message.(utils.Serializable)
 		if !ok {
 			return errors.New("error converting type into Serializable type")
@@ -215,6 +224,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 
 		now := time.Now()
 		// Read exactly this amount of bytes from the transport
+		log.Trace().Uint32("expectedRawOutputLength", expectedRawOutputLength).Msg("Reading bytes")
 		for testTransportInstance.GetNumDrainableBytes() < expectedRawOutputLength {
 			if time.Now().Sub(now) > 2*time.Second {
 				return errors.Errorf("error getting bytes from transport. Not enough data available: actual(%d)<expected(%d)", testTransportInstance.GetNumDrainableBytes(), expectedRawOutputLength)
@@ -227,6 +237,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		}
 
 		// Compare the bytes read with the ones we expect
+		log.Trace().Msg("Comparing outputs")
 		for i := range expectedRawOutput {
 			if expectedRawOutput[i] != rawOutput[i] {
 				return errors.Errorf("actual output doesn't match expected output:\nactual:   0x%X\nexpected: 0x%X", rawOutput, expectedRawOutput)
@@ -235,6 +246,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		// If there's a difference, parse the input and display it to simplify debugging
 	case StepTypeOutgoingPlcBytes:
 		// Read exactly this amount of bytes from the transport
+		log.Trace().Msg("Reading bytes")
 		expectedRawInput, err := hex.DecodeString(step.payload.Text)
 		if err != nil {
 			return errors.Wrap(err, "error decoding hex-encoded byte data")
@@ -245,6 +257,7 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		}
 
 		// Compare the bytes read with the ones we expect
+		log.Trace().Msg("Comparing bytes")
 		for i := range expectedRawInput {
 			if expectedRawInput[i] != rawInput[i] {
 				return errors.Errorf("actual output doesn't match expected output:\nactual:   0x%X\nexpected: 0x%X", rawInput, expectedRawInput)
@@ -256,12 +269,14 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		payloadString := step.payload.XML()
 
 		// Parse the xml into a real model
+		log.Trace().Msg("Parsing model")
 		message, err := model2.ModbusXmlParserHelper{}.Parse(typeName, payloadString)
 		if err != nil {
 			return errors.Wrap(err, "error parsing xml")
 		}
 
 		// Serialize the model into bytes
+		log.Trace().Msg("Serializing bytes")
 		ser, ok := message.(utils.Serializable)
 		if !ok {
 			return errors.New("error converting type into Serializable type")
@@ -273,32 +288,38 @@ func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *
 		}
 
 		// Send these bytes to the transport
+		log.Trace().Msg("Writing to transport")
 		err = testTransportInstance.FillReadBuffer(wb.GetBytes())
 		if err != nil {
 			return errors.Wrap(err, "error writing data to transport")
 		}
 	case StepTypeIncomingPlcBytes:
 		// Get the raw hex-data.
+		log.Trace().Msg("Get hex data")
 		rawInput, err := hex.DecodeString(step.payload.Text)
 		if err != nil {
 			return errors.Wrap(err, "error decoding hex-encoded byte data: ")
 		}
 
 		// Send these bytes to the transport
+		log.Trace().Msg("Writing bytes to transport")
 		err = testTransportInstance.FillReadBuffer(rawInput)
 		if err != nil {
 			return errors.Wrap(err, "error writing data to transport")
 		}
 	case StepTypeDelay:
 		// Get the number of milliseconds
+		log.Trace().Msg("Getting millis")
 		delay, err := strconv.Atoi(step.payload.Text)
 		if err != nil {
 			return errors.Wrap(err, "invalid delay format")
 		}
 		// Sleep for that long
+		log.Debug().Int("delay", delay).Msg("Sleeping")
 		time.Sleep(time.Duration(delay))
 	case StepTypeTerminate:
 		// Simply close the transport connection
+		log.Trace().Msg("closing transport")
 		err := testTransportInstance.Close()
 		if err != nil {
 			return errors.Wrap(err, "error closing transport")
@@ -328,6 +349,7 @@ type TestStep struct {
 
 type StepType uint8
 
+//go:generate stringer -type StepType
 const (
 	StepTypeOutgoingPlcMessage StepType = 0x01
 	StepTypeOutgoingPlcBytes   StepType = 0x02
diff --git a/plc4go/internal/plc4go/spi/testutils/ParserSerializerTestRunner.go b/plc4go/internal/plc4go/spi/testutils/ParserSerializerTestRunner.go
index ecf6048..3ee5eb0 100644
--- a/plc4go/internal/plc4go/spi/testutils/ParserSerializerTestRunner.go
+++ b/plc4go/internal/plc4go/spi/testutils/ParserSerializerTestRunner.go
@@ -160,8 +160,9 @@ func RunParserSerializerTestsuite(t *testing.T, testPath string, skippedTestCase
 				}
 
 				if curFailed {
-					// All worked
+					// All failed
 					t.Logf("FAILED")
+					t.Fail()
 				} else {
 					// All worked
 					t.Logf("SUCCESS")
diff --git a/plc4go/internal/plc4go/spi/testutils/steptype_string.go b/plc4go/internal/plc4go/spi/testutils/steptype_string.go
new file mode 100644
index 0000000..c99ce3e
--- /dev/null
+++ b/plc4go/internal/plc4go/spi/testutils/steptype_string.go
@@ -0,0 +1,48 @@
+// Licensed to 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. Apache Software Foundation (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.
+
+// Code generated by "stringer -type StepType"; DO NOT EDIT.
+
+package testutils
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[StepTypeOutgoingPlcMessage-1]
+	_ = x[StepTypeOutgoingPlcBytes-2]
+	_ = x[StepTypeIncomingPlcMessage-3]
+	_ = x[StepTypeIncomingPlcBytes-4]
+	_ = x[StepTypeApiRequest-5]
+	_ = x[StepTypeApiResponse-6]
+	_ = x[StepTypeDelay-7]
+	_ = x[StepTypeTerminate-8]
+}
+
+const _StepType_name = "StepTypeOutgoingPlcMessageStepTypeOutgoingPlcBytesStepTypeIncomingPlcMessageStepTypeIncomingPlcBytesStepTypeApiRequestStepTypeApiResponseStepTypeDelayStepTypeTerminate"
+
+var _StepType_index = [...]uint8{0, 26, 50, 76, 100, 118, 137, 150, 167}
+
+func (i StepType) String() string {
+	i -= 1
+	if i >= StepType(len(_StepType_index)-1) {
+		return "StepType(" + strconv.FormatInt(int64(i+1), 10) + ")"
+	}
+	return _StepType_name[_StepType_index[i]:_StepType_index[i+1]]
+}
diff --git a/plc4go/internal/plc4go/spi/transports/tcp/Transport.go b/plc4go/internal/plc4go/spi/transports/tcp/Transport.go
index ba1d12b..5b9c23f 100644
--- a/plc4go/internal/plc4go/spi/transports/tcp/Transport.go
+++ b/plc4go/internal/plc4go/spi/transports/tcp/Transport.go
@@ -67,21 +67,19 @@ func (m Transport) CreateTransportInstance(transportUrl url.URL, options map[str
 			portVal, err := strconv.Atoi(val[0])
 			if err != nil {
 				return nil, errors.Wrap(err, "error setting default tcp port")
-			} else {
-				port = portVal
 			}
+			port = portVal
 		} else {
 			return nil, errors.New("error setting port. No explicit or default port provided")
 		}
 	}
 	var connectTimeout uint32 = 1000
 	if val, ok := options["connect-timeout"]; ok {
-		ival, err := strconv.Atoi(val[0])
+		integerValue, err := strconv.Atoi(val[0])
 		if err != nil {
 			return nil, errors.Wrap(err, "error setting connect-timeout")
-		} else {
-			connectTimeout = uint32(ival)
 		}
+		connectTimeout = uint32(integerValue)
 	}
 
 	// Potentially resolve the ip address, if a hostname was provided
@@ -144,45 +142,45 @@ func (m *TransportInstance) Close() error {
 }
 
 func (m *TransportInstance) GetNumReadableBytes() (uint32, error) {
-	if m.reader != nil {
-		_, _ = m.reader.Peek(1)
-		return uint32(m.reader.Buffered()), nil
+	if m.reader == nil {
+		return 0, nil
 	}
-	return 0, nil
+	_, _ = m.reader.Peek(1)
+	return uint32(m.reader.Buffered()), nil
 }
 
 func (m *TransportInstance) PeekReadableBytes(numBytes uint32) ([]uint8, error) {
-	if m.reader != nil {
-		return m.reader.Peek(int(numBytes))
+	if m.reader == nil {
+		return nil, errors.New("error peeking from transport. No reader available")
 	}
-	return nil, errors.New("error peeking from transport. No reader available")
+	return m.reader.Peek(int(numBytes))
 }
 
 func (m *TransportInstance) Read(numBytes uint32) ([]uint8, error) {
-	if m.reader != nil {
-		data := make([]uint8, numBytes)
-		for i := uint32(0); i < numBytes; i++ {
-			val, err := m.reader.ReadByte()
-			if err != nil {
-				return nil, errors.Wrap(err, "error reading")
-			}
-			data[i] = val
+	if m.reader == nil {
+		return nil, errors.New("error reading from transport. No reader available")
+	}
+	data := make([]uint8, numBytes)
+	for i := uint32(0); i < numBytes; i++ {
+		val, err := m.reader.ReadByte()
+		if err != nil {
+			return nil, errors.Wrap(err, "error reading")
 		}
-		return data, nil
+		data[i] = val
 	}
-	return nil, errors.New("error reading from transport. No reader available")
+	return data, nil
 }
 
 func (m *TransportInstance) Write(data []uint8) error {
-	if m.tcpConn != nil {
-		num, err := m.tcpConn.Write(data)
-		if err != nil {
-			return errors.Wrap(err, "error writing")
-		}
-		if num != len(data) {
-			return errors.New("error writing: not all bytes written")
-		}
-		return nil
+	if m.tcpConn == nil {
+		return errors.New("error writing to transport. No writer available")
 	}
-	return errors.New("error writing to transport. No writer available")
+	num, err := m.tcpConn.Write(data)
+	if err != nil {
+		return errors.Wrap(err, "error writing")
+	}
+	if num != len(data) {
+		return errors.New("error writing: not all bytes written")
+	}
+	return nil
 }
diff --git a/plc4go/internal/plc4go/spi/transports/test/Transport.go b/plc4go/internal/plc4go/spi/transports/test/Transport.go
index 23b4349..7ca1124 100644
--- a/plc4go/internal/plc4go/spi/transports/test/Transport.go
+++ b/plc4go/internal/plc4go/spi/transports/test/Transport.go
@@ -84,25 +84,25 @@ func (m *TransportInstance) GetNumReadableBytes() (uint32, error) {
 }
 
 func (m *TransportInstance) PeekReadableBytes(numBytes uint32) ([]uint8, error) {
-	log.Trace().Msg("Peek readable bytes")
+	log.Trace().Msgf("Peek %d readable bytes", numBytes)
 	return m.readBuffer[0:numBytes], nil
 }
 
 func (m *TransportInstance) Read(numBytes uint32) ([]uint8, error) {
-	log.Trace().Msg("Read")
+	log.Trace().Msgf("Read num bytes %d", numBytes)
 	data := m.readBuffer[0:int(numBytes)]
 	m.readBuffer = m.readBuffer[int(numBytes):]
 	return data, nil
 }
 
 func (m *TransportInstance) Write(data []uint8) error {
-	log.Trace().Msg("Write")
+	log.Trace().Msgf("Write data 0x%x", data)
 	m.writeBuffer = append(m.writeBuffer, data...)
 	return nil
 }
 
 func (m *TransportInstance) FillReadBuffer(data []uint8) error {
-	log.Trace().Msg("FillReadBuffer")
+	log.Trace().Msgf("FillReadBuffer with 0x%x", data)
 	m.readBuffer = append(m.readBuffer, data...)
 	return nil
 }
@@ -113,7 +113,7 @@ func (m *TransportInstance) GetNumDrainableBytes() uint32 {
 }
 
 func (m *TransportInstance) DrainWriteBuffer(numBytes uint32) ([]uint8, error) {
-	log.Trace().Msg("Drain write buffer")
+	log.Trace().Msgf("Drain write buffer with number of bytes %d", numBytes)
 	data := m.writeBuffer[0:int(numBytes)]
 	m.writeBuffer = m.writeBuffer[int(numBytes):]
 	return data, nil
diff --git a/plc4go/internal/plc4go/spi/transports/udp/Transport.go b/plc4go/internal/plc4go/spi/transports/udp/Transport.go
index 762a5f0..a1adb4f 100644
--- a/plc4go/internal/plc4go/spi/transports/udp/Transport.go
+++ b/plc4go/internal/plc4go/spi/transports/udp/Transport.go
@@ -66,16 +66,14 @@ func (m Transport) CreateTransportInstanceForLocalAddress(transportUrl url.URL,
 			portVal, err := strconv.Atoi(val)
 			if err != nil {
 				return nil, errors.Wrap(err, "error setting port")
-			} else {
-				remotePort = portVal
 			}
+			remotePort = portVal
 		} else if val, ok := options["defaultUdpPort"]; ok && len(val) > 0 {
 			portVal, err := strconv.Atoi(val[0])
 			if err != nil {
 				return nil, errors.Wrap(err, "error setting default udp port")
-			} else {
-				remotePort = portVal
 			}
+			remotePort = portVal
 		} else {
 			return nil, errors.New("error setting port. No explicit or default port provided")
 		}
@@ -174,45 +172,45 @@ func (m *TransportInstance) Close() error {
 }
 
 func (m *TransportInstance) GetNumReadableBytes() (uint32, error) {
-	if m.reader != nil {
-		_, _ = m.reader.Peek(1)
-		return uint32(m.reader.Buffered()), nil
+	if m.reader == nil {
+		return 0, nil
 	}
-	return 0, nil
+	_, _ = m.reader.Peek(1)
+	return uint32(m.reader.Buffered()), nil
 }
 
 func (m *TransportInstance) PeekReadableBytes(numBytes uint32) ([]uint8, error) {
-	if m.reader != nil {
-		return m.reader.Peek(int(numBytes))
+	if m.reader == nil {
+		return nil, errors.New("error peeking from transport. No reader available")
 	}
-	return nil, errors.New("error peeking from transport. No reader available")
+	return m.reader.Peek(int(numBytes))
 }
 
 func (m *TransportInstance) Read(numBytes uint32) ([]uint8, error) {
-	if m.reader != nil {
-		data := make([]uint8, numBytes)
-		for i := uint32(0); i < numBytes; i++ {
-			val, err := m.reader.ReadByte()
-			if err != nil {
-				return nil, errors.Wrap(err, "error reading")
-			}
-			data[i] = val
+	if m.reader == nil {
+		return nil, errors.New("error reading from transport. No reader available")
+	}
+	data := make([]uint8, numBytes)
+	for i := uint32(0); i < numBytes; i++ {
+		val, err := m.reader.ReadByte()
+		if err != nil {
+			return nil, errors.Wrap(err, "error reading")
 		}
-		return data, nil
+		data[i] = val
 	}
-	return nil, errors.New("error reading from transport. No reader available")
+	return data, nil
 }
 
 func (m *TransportInstance) Write(data []uint8) error {
-	if m.udpConn != nil {
-		num, err := m.udpConn.WriteToUDP(data, m.RemoteAddress)
-		if err != nil {
-			return errors.Wrap(err, "error writing")
-		}
-		if num != len(data) {
-			return errors.New("error writing: not all bytes written")
-		}
-		return nil
+	if m.udpConn == nil {
+		return errors.New("error writing to transport. No writer available")
+	}
+	num, err := m.udpConn.WriteToUDP(data, m.RemoteAddress)
+	if err != nil {
+		return errors.Wrap(err, "error writing")
+	}
+	if num != len(data) {
+		return errors.New("error writing: not all bytes written")
 	}
-	return errors.New("error writing to transport. No writer available")
+	return nil
 }
diff --git a/plc4go/pom.xml b/plc4go/pom.xml
index 71fa93b..7788c58 100644
--- a/plc4go/pom.xml
+++ b/plc4go/pom.xml
@@ -380,6 +380,22 @@
               </packages>
             </configuration>
           </execution>
+          <execution>
+            <id>add-license2</id>
+            <goals>
+              <goal>custom</goal>
+            </goals>
+            <configuration>
+              <exec>go-licenser</exec>
+              <customCommand>-licensor</customCommand>
+              <buildFlags>
+                <flag>Apache Software Foundation (ASF)</flag>
+              </buildFlags>
+              <packages>
+                <package>internal/plc4go/spi/testutils/steptype_string.go</package>
+              </packages>
+            </configuration>
+          </execution>
         </executions>
         <configuration>
           <packages>