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 2023/06/13 12:17:24 UTC

[plc4x] 03/04: feat(plc4go/spi): added more Stringer implementations

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

commit caa9718473faa3ebb4fc71951fd3cf4ead000c17
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Jun 13 14:16:57 2023 +0200

    feat(plc4go/spi): added more Stringer implementations
---
 plc4go/spi/default/DefaultCodec.go                 |  17 ++++
 plc4go/spi/default/DefaultCodec_test.go            |  43 ++++++++
 plc4go/spi/default/DefaultConnection.go            |  15 +++
 plc4go/spi/default/DefaultConnection_test.go       |  40 ++++++++
 plc4go/spi/pool/dynamicExecutor.go                 |  13 +++
 plc4go/spi/pool/dynamicExecutor_test.go            |  43 ++++++++
 plc4go/spi/pool/executor.go                        |  19 ++++
 plc4go/spi/pool/executor_test.go                   |  66 ++++++++++++
 plc4go/spi/pool/workItem.go                        |  10 +-
 plc4go/spi/pool/workItem_test.go                   |   6 +-
 plc4go/spi/pool/worker.go                          |  17 ++++
 plc4go/spi/pool/worker_test.go                     |  26 +++++
 .../spi/transactions/RequestTransactionManager.go  |  33 ++++--
 .../transactions/RequestTransactionManager_test.go | 113 +++++++++++++++++----
 plc4go/spi/transactions/completedFuture.go         |   9 +-
 plc4go/spi/transactions/completedFuture_test.go    | 106 +++++++++++++++++++
 16 files changed, 549 insertions(+), 27 deletions(-)

diff --git a/plc4go/spi/default/DefaultCodec.go b/plc4go/spi/default/DefaultCodec.go
index 30b70557b6..afd3052c9c 100644
--- a/plc4go/spi/default/DefaultCodec.go
+++ b/plc4go/spi/default/DefaultCodec.go
@@ -244,6 +244,7 @@ func (m *defaultCodec) HandleMessages(message spi.Message) bool {
 	messageHandled := false
 	m.log.Trace().Msgf("Current number of expectations: %d", len(m.expectations))
 	for index, expectation := range m.expectations {
+		m.log.Trace().Msgf("Checking expectation %s", expectation)
 		// Check if the current message matches the expectations
 		// If it does, let it handle the message.
 		if accepts := expectation.GetAcceptsMessage()(message); accepts {
@@ -354,3 +355,19 @@ func (m *defaultCodec) passToDefaultIncomingMessageChannel(workerLog zerolog.Log
 		workerLog.Warn().Msgf("Message discarded\n%s", message)
 	}
 }
+
+func (m *defaultCodec) String() string {
+	return fmt.Sprintf("DefaultCodec{\n"+
+		"\tTransportInstance: %s,\n"+
+		"\tDefaultIncomingMessageChannel: %d elements,\n"+
+		"\tExpectations: %s,\n"+
+		"\trunning: %t,\n"+
+		"\tcustomMessageHandling: %t,\n"+
+		"}",
+		m.transportInstance,
+		len(m.defaultIncomingMessageChannel),
+		m.expectations,
+		m.running,
+		m.customMessageHandling != nil,
+	)
+}
diff --git a/plc4go/spi/default/DefaultCodec_test.go b/plc4go/spi/default/DefaultCodec_test.go
index 664b92c986..a186912b71 100644
--- a/plc4go/spi/default/DefaultCodec_test.go
+++ b/plc4go/spi/default/DefaultCodec_test.go
@@ -26,6 +26,7 @@ import (
 	"github.com/apache/plc4x/plc4go/spi/options"
 	"github.com/apache/plc4x/plc4go/spi/transports"
 	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 	"testing"
@@ -1194,3 +1195,45 @@ func Test_defaultCodec_Work(t *testing.T) {
 		})
 	}
 }
+
+func Test_defaultCodec_String(t *testing.T) {
+	type fields struct {
+		DefaultCodecRequirements      DefaultCodecRequirements
+		transportInstance             transports.TransportInstance
+		defaultIncomingMessageChannel chan spi.Message
+		expectations                  []spi.Expectation
+		running                       bool
+		customMessageHandling         func(codec DefaultCodecRequirements, message spi.Message) bool
+		log                           zerolog.Logger
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "string it",
+			want: "DefaultCodec{\n" +
+				"\tTransportInstance: %!s(<nil>),\n" +
+				"\tDefaultIncomingMessageChannel: 0 elements,\n" +
+				"\tExpectations: [],\n" +
+				"\trunning: false,\n" +
+				"\tcustomMessageHandling: false,\n" +
+				"}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			m := &defaultCodec{
+				DefaultCodecRequirements:      tt.fields.DefaultCodecRequirements,
+				transportInstance:             tt.fields.transportInstance,
+				defaultIncomingMessageChannel: tt.fields.defaultIncomingMessageChannel,
+				expectations:                  tt.fields.expectations,
+				running:                       tt.fields.running,
+				customMessageHandling:         tt.fields.customMessageHandling,
+				log:                           tt.fields.log,
+			}
+			assert.Equalf(t, tt.want, m.String(), "String()")
+		})
+	}
+}
diff --git a/plc4go/spi/default/DefaultConnection.go b/plc4go/spi/default/DefaultConnection.go
index 2d3a0f9fa5..67caedf5cd 100644
--- a/plc4go/spi/default/DefaultConnection.go
+++ b/plc4go/spi/default/DefaultConnection.go
@@ -21,6 +21,7 @@ package _default
 
 import (
 	"context"
+	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/tracer"
 	"github.com/rs/zerolog"
 	"runtime/debug"
@@ -359,6 +360,20 @@ func (d *defaultConnection) GetPlcValueHandler() spi.PlcValueHandler {
 	return d.valueHandler
 }
 
+func (d *defaultConnection) String() string {
+	return fmt.Sprintf("DefaultConnection{\n"+
+		"\tttl: %s,\n"+
+		"\tconnected: %t,\n"+
+		"\ttagHandler: %s,\n"+
+		"\tvalueHandler: %s,\n"+
+		"}",
+		d.defaultTtl,
+		d.connected,
+		d.tagHandler,
+		d.valueHandler,
+	)
+}
+
 func (m DefaultConnectionMetadata) GetConnectionAttributes() map[string]string {
 	return m.ConnectionAttributes
 }
diff --git a/plc4go/spi/default/DefaultConnection_test.go b/plc4go/spi/default/DefaultConnection_test.go
index c013b0690e..2e26883a1c 100644
--- a/plc4go/spi/default/DefaultConnection_test.go
+++ b/plc4go/spi/default/DefaultConnection_test.go
@@ -23,6 +23,7 @@ import (
 	"context"
 	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/tracer"
+	"github.com/rs/zerolog"
 	"testing"
 	"time"
 
@@ -1319,3 +1320,42 @@ func Test_plcConnectionPingResult_GetErr(t *testing.T) {
 		})
 	}
 }
+
+func Test_defaultConnection_String(t *testing.T) {
+	type fields struct {
+		DefaultConnectionRequirements DefaultConnectionRequirements
+		defaultTtl                    time.Duration
+		connected                     bool
+		tagHandler                    spi.PlcTagHandler
+		valueHandler                  spi.PlcValueHandler
+		log                           zerolog.Logger
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "string it",
+			want: "DefaultConnection{\n" +
+				"\tttl: 0s,\n" +
+				"\tconnected: false,\n" +
+				"\ttagHandler: %!s(<nil>),\n" +
+				"\tvalueHandler: %!s(<nil>),\n" +
+				"}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &defaultConnection{
+				DefaultConnectionRequirements: tt.fields.DefaultConnectionRequirements,
+				defaultTtl:                    tt.fields.defaultTtl,
+				connected:                     tt.fields.connected,
+				tagHandler:                    tt.fields.tagHandler,
+				valueHandler:                  tt.fields.valueHandler,
+				log:                           tt.fields.log,
+			}
+			assert.Equalf(t, tt.want, d.String(), "String()")
+		})
+	}
+}
diff --git a/plc4go/spi/pool/dynamicExecutor.go b/plc4go/spi/pool/dynamicExecutor.go
index 22f8d20e5b..ae4135d60a 100644
--- a/plc4go/spi/pool/dynamicExecutor.go
+++ b/plc4go/spi/pool/dynamicExecutor.go
@@ -20,6 +20,7 @@
 package pool
 
 import (
+	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/utils"
 	"github.com/rs/zerolog"
 	"runtime/debug"
@@ -171,3 +172,15 @@ func (e *dynamicExecutor) Stop() {
 	e.dynamicWorkers.Wait()
 	e.log.Trace().Msg("stopped")
 }
+
+func (e *dynamicExecutor) String() string {
+	return fmt.Sprintf("dynamicExecutor{\n"+
+		"\texecutor: %s\n"+
+		"\tmaxNumberOfWorkers: %d\n"+
+		"\tcurrentNumberOfWorkers: %d\n"+
+		"}",
+		e.executor,
+		e.maxNumberOfWorkers,
+		e.currentNumberOfWorkers.Load(),
+	)
+}
diff --git a/plc4go/spi/pool/dynamicExecutor_test.go b/plc4go/spi/pool/dynamicExecutor_test.go
index 1db92a5d7f..190fceb41d 100644
--- a/plc4go/spi/pool/dynamicExecutor_test.go
+++ b/plc4go/spi/pool/dynamicExecutor_test.go
@@ -20,6 +20,7 @@
 package pool
 
 import (
+	"github.com/stretchr/testify/assert"
 	"testing"
 	"time"
 )
@@ -168,3 +169,45 @@ func Test_dynamicExecutor_Stop(t *testing.T) {
 		})
 	}
 }
+
+func Test_dynamicExecutor_String(t *testing.T) {
+	type fields struct {
+		executor           *executor
+		maxNumberOfWorkers int
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "string it",
+			fields: fields{
+				executor:           &executor{},
+				maxNumberOfWorkers: 3,
+			},
+			want: "dynamicExecutor{\n" +
+				"\texecutor: executor{\n" +
+				"\trunning: false,\n" +
+				"\tshutdown: false,\n" +
+				"\tworker: [],\n" +
+				"\tqueueDepth: 0,\n" +
+				"\tworkItems: 0 elements,\n" +
+				"\ttraceWorkers: false,\n" +
+				"\n" +
+				"}\n" +
+				"\tmaxNumberOfWorkers: 3\n" +
+				"\tcurrentNumberOfWorkers: 0\n" +
+				"}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := &dynamicExecutor{
+				executor:           tt.fields.executor,
+				maxNumberOfWorkers: tt.fields.maxNumberOfWorkers,
+			}
+			assert.Equalf(t, tt.want, e.String(), "String()")
+		})
+	}
+}
diff --git a/plc4go/spi/pool/executor.go b/plc4go/spi/pool/executor.go
index 79bddb6dc0..0e8e458903 100644
--- a/plc4go/spi/pool/executor.go
+++ b/plc4go/spi/pool/executor.go
@@ -21,6 +21,7 @@ package pool
 
 import (
 	"context"
+	"fmt"
 	"sync"
 	"sync/atomic"
 
@@ -127,3 +128,21 @@ func (e *executor) Close() error {
 func (e *executor) IsRunning() bool {
 	return e.running && !e.shutdown
 }
+
+func (e *executor) String() string {
+	return fmt.Sprintf("executor{\n"+
+		"\trunning: %t,\n"+
+		"\tshutdown: %t,\n"+
+		"\tworker: %s,\n"+
+		"\tqueueDepth: %d,\n"+
+		"\tworkItems: %d elements,\n"+
+		"\ttraceWorkers: %t,\n"+
+		"\n}",
+		e.running,
+		e.shutdown,
+		e.worker,
+		e.queueDepth,
+		len(e.workItems),
+		e.traceWorkers,
+	)
+}
diff --git a/plc4go/spi/pool/executor_test.go b/plc4go/spi/pool/executor_test.go
index 2a43b1366e..577ce986c0 100644
--- a/plc4go/spi/pool/executor_test.go
+++ b/plc4go/spi/pool/executor_test.go
@@ -25,6 +25,7 @@ import (
 	"github.com/rs/zerolog"
 	"github.com/stretchr/testify/assert"
 	"sync"
+	"sync/atomic"
 	"testing"
 	"time"
 )
@@ -411,3 +412,68 @@ func Test_executor_isTraceWorkers(t *testing.T) {
 		})
 	}
 }
+
+func Test_executor_String(t *testing.T) {
+	type fields struct {
+		running      bool
+		shutdown     bool
+		worker       []*worker
+		queueDepth   int
+		workItems    chan workItem
+		traceWorkers bool
+		log          zerolog.Logger
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "string it",
+			fields: fields{
+				running:  true,
+				shutdown: true,
+				worker: []*worker{
+					{
+						id:           1,
+						shutdown:     atomic.Bool{},
+						interrupted:  atomic.Bool{},
+						hasEnded:     atomic.Bool{},
+						lastReceived: time.Time{},
+					},
+				},
+				queueDepth:   2,
+				traceWorkers: true,
+			},
+			want: "executor{\n" +
+				"\trunning: true,\n" +
+				"\tshutdown: true,\n" +
+				"\tworker: [worker{\n" +
+				"\tid: 1,\n" +
+				"\tshutdown: false,\n" +
+				"\tinterrupted: false,\n" +
+				"\thasEnded: false,\n" +
+				"\tlastReceived: 0001-01-01 00:00:00 +0000 UTC,\n" +
+				"}],\n" +
+				"\tqueueDepth: 2,\n" +
+				"\tworkItems: 0 elements,\n" +
+				"\ttraceWorkers: true,\n" +
+				"\n" +
+				"}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := &executor{
+				running:      tt.fields.running,
+				shutdown:     tt.fields.shutdown,
+				worker:       tt.fields.worker,
+				queueDepth:   tt.fields.queueDepth,
+				workItems:    tt.fields.workItems,
+				traceWorkers: tt.fields.traceWorkers,
+				log:          tt.fields.log,
+			}
+			assert.Equalf(t, tt.want, e.String(), "String()")
+		})
+	}
+}
diff --git a/plc4go/spi/pool/workItem.go b/plc4go/spi/pool/workItem.go
index 942480bc1a..233df1315d 100644
--- a/plc4go/spi/pool/workItem.go
+++ b/plc4go/spi/pool/workItem.go
@@ -28,5 +28,13 @@ type workItem struct {
 }
 
 func (w workItem) String() string {
-	return fmt.Sprintf("Workitem{wid:%d, runnable(%t)}, completionFuture(%v)}", w.workItemId, w.runnable != nil, w.completionFuture)
+	return fmt.Sprintf("workItem{\n"+
+		"\twid: %d,\n"+
+		"\trunnable: %t,\n"+
+		"\tcompletionFuture: %s,\n"+
+		"}",
+		w.workItemId,
+		w.runnable != nil,
+		w.completionFuture,
+	)
 }
diff --git a/plc4go/spi/pool/workItem_test.go b/plc4go/spi/pool/workItem_test.go
index ebc4b30c5c..1477f69012 100644
--- a/plc4go/spi/pool/workItem_test.go
+++ b/plc4go/spi/pool/workItem_test.go
@@ -37,7 +37,11 @@ func Test_workItem_String(t *testing.T) {
 	}{
 		{
 			name: "Simple test",
-			want: "Workitem{wid:0, runnable(false)}, completionFuture(<nil>)}",
+			want: "workItem{\n" +
+				"\twid: 0,\n" +
+				"\trunnable: false,\n" +
+				"\tcompletionFuture: <nil>,\n" +
+				"}",
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/pool/worker.go b/plc4go/spi/pool/worker.go
index 7530ed0ad9..77909cd1b6 100644
--- a/plc4go/spi/pool/worker.go
+++ b/plc4go/spi/pool/worker.go
@@ -20,6 +20,7 @@
 package pool
 
 import (
+	"fmt"
 	"runtime/debug"
 	"sync"
 	"sync/atomic"
@@ -94,3 +95,19 @@ func (w *worker) work() {
 	w.hasEnded.Store(true)
 	workerLog.Debug().Msg("setting to ended")
 }
+
+func (w *worker) String() string {
+	return fmt.Sprintf("worker{\n"+
+		"\tid: %d,\n"+
+		"\tshutdown: %v,\n"+
+		"\tinterrupted: %t,\n"+
+		"\thasEnded: %t,\n"+
+		"\tlastReceived: %s,\n"+
+		"}",
+		w.id,
+		w.shutdown.Load(),
+		w.interrupted.Load(),
+		w.hasEnded.Load(),
+		w.lastReceived,
+	)
+}
diff --git a/plc4go/spi/pool/worker_test.go b/plc4go/spi/pool/worker_test.go
index 4f604d2efb..31c0ece2c0 100644
--- a/plc4go/spi/pool/worker_test.go
+++ b/plc4go/spi/pool/worker_test.go
@@ -225,3 +225,29 @@ func Test_worker_work(t *testing.T) {
 		})
 	}
 }
+
+func Test_worker_String(t *testing.T) {
+	type fields struct {
+		id           int
+		lastReceived time.Time
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "string it",
+			want: "worker{\n\tid: 0,\n\tshutdown: false,\n\tinterrupted: false,\n\thasEnded: false,\n\tlastReceived: 0001-01-01 00:00:00 +0000 UTC,\n}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			w := &worker{
+				id:           tt.fields.id,
+				lastReceived: tt.fields.lastReceived,
+			}
+			assert.Equalf(t, tt.want, w.String(), "String()")
+		})
+	}
+}
diff --git a/plc4go/spi/transactions/RequestTransactionManager.go b/plc4go/spi/transactions/RequestTransactionManager.go
index 8a93dc6f87..fe63035ebd 100644
--- a/plc4go/spi/transactions/RequestTransactionManager.go
+++ b/plc4go/spi/transactions/RequestTransactionManager.go
@@ -22,6 +22,7 @@ package transactions
 import (
 	"container/list"
 	"context"
+	"fmt"
 	"github.com/apache/plc4x/plc4go/spi/options"
 	"github.com/apache/plc4x/plc4go/spi/pool"
 	"io"
@@ -60,7 +61,7 @@ type RequestTransactionManager interface {
 func NewRequestTransactionManager(numberOfConcurrentRequests int, _options ...options.WithOption) RequestTransactionManager {
 	_requestTransactionManager := &requestTransactionManager{
 		numberOfConcurrentRequests: numberOfConcurrentRequests,
-		transactionId:              0,
+		currentTransactionId:       0,
 		workLog:                    *list.New(),
 		executor:                   sharedExecutorInstance,
 
@@ -98,8 +99,8 @@ type requestTransactionManager struct {
 	// How many transactions are allowed to run at the same time?
 	numberOfConcurrentRequests int
 	// Assigns each request a Unique Transaction Id, especially important for failure handling
-	transactionId    int32
-	transactionMutex sync.RWMutex
+	currentTransactionId int32
+	transactionMutex     sync.RWMutex
 	// Important, this is a FIFO Queue for Fairness!
 	workLog      list.List
 	workLogMutex sync.RWMutex
@@ -162,9 +163,9 @@ func (r *requestTransactionManager) processWorklog() {
 func (r *requestTransactionManager) StartTransaction() RequestTransaction {
 	r.transactionMutex.Lock()
 	defer r.transactionMutex.Unlock()
-	currentTransactionId := r.transactionId
-	r.transactionId += 1
-	transactionLogger := r.log.With().Int32("transactionId", currentTransactionId).Logger()
+	currentTransactionId := r.currentTransactionId
+	r.currentTransactionId += 1
+	transactionLogger := r.log.With().Int32("currentTransactionId", currentTransactionId).Logger()
 	if !r.traceTransactionManagerTransactions {
 		transactionLogger = zerolog.Nop()
 	}
@@ -246,3 +247,23 @@ func (r *requestTransactionManager) CloseGraceful(timeout time.Duration) error {
 	r.runningRequests = nil
 	return r.executor.Close()
 }
+
+func (r *requestTransactionManager) String() string {
+	return fmt.Sprintf("RequestTransactionManager{\n"+
+		"\trunningRequests: %s,\n"+
+		"\tnumberOfConcurrentRequests: %d,\n"+
+		"\tcurrentTransactionId: %d,\n"+
+		"\tworkLog: %d elements,\n"+
+		"\texecutor: %s,\n"+
+		"\tshutdown: %t,\n"+
+		"\ttraceTransactionManagerTransactions: %t,\n"+
+		"}",
+		r.runningRequests,
+		r.numberOfConcurrentRequests,
+		r.currentTransactionId,
+		r.workLog.Len(),
+		r.executor,
+		r.shutdown,
+		r.traceTransactionManagerTransactions,
+	)
+}
diff --git a/plc4go/spi/transactions/RequestTransactionManager_test.go b/plc4go/spi/transactions/RequestTransactionManager_test.go
index 4445edad1e..4925ce7790 100644
--- a/plc4go/spi/transactions/RequestTransactionManager_test.go
+++ b/plc4go/spi/transactions/RequestTransactionManager_test.go
@@ -106,7 +106,7 @@ func Test_requestTransactionManager_SetNumberOfConcurrentRequests(t *testing.T)
 	type fields struct {
 		runningRequests            []*requestTransaction
 		numberOfConcurrentRequests int
-		transactionId              int32
+		currentTransactionId       int32
 		workLog                    list.List
 		executor                   pool.Executor
 	}
@@ -135,7 +135,7 @@ func Test_requestTransactionManager_SetNumberOfConcurrentRequests(t *testing.T)
 			r := &requestTransactionManager{
 				runningRequests:            tt.fields.runningRequests,
 				numberOfConcurrentRequests: tt.fields.numberOfConcurrentRequests,
-				transactionId:              tt.fields.transactionId,
+				currentTransactionId:       tt.fields.currentTransactionId,
 				workLog:                    tt.fields.workLog,
 				executor:                   tt.fields.executor,
 			}
@@ -148,7 +148,7 @@ func Test_requestTransactionManager_StartTransaction(t *testing.T) {
 	type fields struct {
 		runningRequests                     []*requestTransaction
 		numberOfConcurrentRequests          int
-		transactionId                       int32
+		currentTransactionId                int32
 		workLog                             list.List
 		executor                            pool.Executor
 		shutdown                            bool
@@ -194,7 +194,7 @@ func Test_requestTransactionManager_StartTransaction(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:                     tt.fields.runningRequests,
 				numberOfConcurrentRequests:          tt.fields.numberOfConcurrentRequests,
-				transactionId:                       tt.fields.transactionId,
+				currentTransactionId:                tt.fields.currentTransactionId,
 				workLog:                             tt.fields.workLog,
 				executor:                            tt.fields.executor,
 				shutdown:                            tt.fields.shutdown,
@@ -212,7 +212,7 @@ func Test_requestTransactionManager_endRequest(t *testing.T) {
 	type fields struct {
 		runningRequests            []*requestTransaction
 		numberOfConcurrentRequests int
-		transactionId              int32
+		currentTransactionId       int32
 		workLog                    list.List
 		executor                   pool.Executor
 	}
@@ -249,7 +249,7 @@ func Test_requestTransactionManager_endRequest(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:            tt.fields.runningRequests,
 				numberOfConcurrentRequests: tt.fields.numberOfConcurrentRequests,
-				transactionId:              tt.fields.transactionId,
+				currentTransactionId:       tt.fields.currentTransactionId,
 				workLog:                    tt.fields.workLog,
 				executor:                   tt.fields.executor,
 			}
@@ -264,7 +264,7 @@ func Test_requestTransactionManager_failRequest(t *testing.T) {
 	type fields struct {
 		runningRequests            []*requestTransaction
 		numberOfConcurrentRequests int
-		transactionId              int32
+		currentTransactionId       int32
 		workLog                    list.List
 		executor                   pool.Executor
 		log                        zerolog.Logger
@@ -304,7 +304,7 @@ func Test_requestTransactionManager_failRequest(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:            tt.fields.runningRequests,
 				numberOfConcurrentRequests: tt.fields.numberOfConcurrentRequests,
-				transactionId:              tt.fields.transactionId,
+				currentTransactionId:       tt.fields.currentTransactionId,
 				workLog:                    tt.fields.workLog,
 				executor:                   tt.fields.executor,
 				log:                        tt.fields.log,
@@ -320,7 +320,7 @@ func Test_requestTransactionManager_getNumberOfActiveRequests(t *testing.T) {
 	type fields struct {
 		runningRequests            []*requestTransaction
 		numberOfConcurrentRequests int
-		transactionId              int32
+		currentTransactionId       int32
 		workLog                    list.List
 		executor                   pool.Executor
 	}
@@ -338,7 +338,7 @@ func Test_requestTransactionManager_getNumberOfActiveRequests(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:            tt.fields.runningRequests,
 				numberOfConcurrentRequests: tt.fields.numberOfConcurrentRequests,
-				transactionId:              tt.fields.transactionId,
+				currentTransactionId:       tt.fields.currentTransactionId,
 				workLog:                    tt.fields.workLog,
 				executor:                   tt.fields.executor,
 			}
@@ -353,7 +353,7 @@ func Test_requestTransactionManager_processWorklog(t *testing.T) {
 	type fields struct {
 		runningRequests            []*requestTransaction
 		numberOfConcurrentRequests int
-		transactionId              int32
+		currentTransactionId       int32
 		workLog                    list.List
 		executor                   pool.Executor
 	}
@@ -401,7 +401,7 @@ func Test_requestTransactionManager_processWorklog(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:            tt.fields.runningRequests,
 				numberOfConcurrentRequests: tt.fields.numberOfConcurrentRequests,
-				transactionId:              tt.fields.transactionId,
+				currentTransactionId:       tt.fields.currentTransactionId,
 				workLog:                    tt.fields.workLog,
 				executor:                   tt.fields.executor,
 			}
@@ -414,7 +414,7 @@ func Test_requestTransactionManager_submitTransaction(t *testing.T) {
 	type fields struct {
 		runningRequests            []*requestTransaction
 		numberOfConcurrentRequests int
-		transactionId              int32
+		currentTransactionId       int32
 		workLog                    list.List
 		executor                   pool.Executor
 	}
@@ -442,7 +442,7 @@ func Test_requestTransactionManager_submitTransaction(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:            tt.fields.runningRequests,
 				numberOfConcurrentRequests: tt.fields.numberOfConcurrentRequests,
-				transactionId:              tt.fields.transactionId,
+				currentTransactionId:       tt.fields.currentTransactionId,
 				workLog:                    tt.fields.workLog,
 				executor:                   tt.fields.executor,
 			}
@@ -455,7 +455,7 @@ func Test_requestTransactionManager_Close(t *testing.T) {
 	type fields struct {
 		runningRequests                     []*requestTransaction
 		numberOfConcurrentRequests          int
-		transactionId                       int32
+		currentTransactionId                int32
 		workLog                             list.List
 		executor                            pool.Executor
 		shutdown                            bool
@@ -486,7 +486,7 @@ func Test_requestTransactionManager_Close(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:                     tt.fields.runningRequests,
 				numberOfConcurrentRequests:          tt.fields.numberOfConcurrentRequests,
-				transactionId:                       tt.fields.transactionId,
+				currentTransactionId:                tt.fields.currentTransactionId,
 				workLog:                             tt.fields.workLog,
 				executor:                            tt.fields.executor,
 				shutdown:                            tt.fields.shutdown,
@@ -502,7 +502,7 @@ func Test_requestTransactionManager_CloseGraceful(t *testing.T) {
 	type fields struct {
 		runningRequests                     []*requestTransaction
 		numberOfConcurrentRequests          int
-		transactionId                       int32
+		currentTransactionId                int32
 		workLog                             list.List
 		executor                            pool.Executor
 		shutdown                            bool
@@ -566,7 +566,7 @@ func Test_requestTransactionManager_CloseGraceful(t *testing.T) {
 			r := &requestTransactionManager{
 				runningRequests:                     tt.fields.runningRequests,
 				numberOfConcurrentRequests:          tt.fields.numberOfConcurrentRequests,
-				transactionId:                       tt.fields.transactionId,
+				currentTransactionId:                tt.fields.currentTransactionId,
 				workLog:                             tt.fields.workLog,
 				executor:                            tt.fields.executor,
 				shutdown:                            tt.fields.shutdown,
@@ -577,3 +577,80 @@ func Test_requestTransactionManager_CloseGraceful(t *testing.T) {
 		})
 	}
 }
+
+func Test_requestTransactionManager_String(t *testing.T) {
+	type fields struct {
+		runningRequests                     []*requestTransaction
+		numberOfConcurrentRequests          int
+		currentTransactionId                int32
+		workLog                             list.List
+		executor                            pool.Executor
+		shutdown                            bool
+		traceTransactionManagerTransactions bool
+		log                                 zerolog.Logger
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "string it",
+			fields: fields{
+				runningRequests: []*requestTransaction{
+					{
+						transactionId: 2,
+					},
+				},
+				numberOfConcurrentRequests: 3,
+				currentTransactionId:       4,
+				workLog: func() list.List {
+					v := list.List{}
+					v.PushBack(nil)
+					return v
+				}(),
+				executor:                            pool.NewFixedSizeExecutor(1, 1),
+				shutdown:                            true,
+				traceTransactionManagerTransactions: true,
+			},
+			want: "RequestTransactionManager{\n" +
+				"\trunningRequests: [Transaction{tid:2}],\n" +
+				"\tnumberOfConcurrentRequests: 3,\n" +
+				"\tcurrentTransactionId: 4,\n" +
+				"\tworkLog: 1 elements,\n" +
+				"\texecutor: executor{\n" +
+				"\trunning: false,\n" +
+				"\tshutdown: false,\n" +
+				"\tworker: [worker{\n" +
+				"\tid: 0,\n" +
+				"\tshutdown: false,\n" +
+				"\tinterrupted: false,\n" +
+				"\thasEnded: false,\n" +
+				"\tlastReceived: 0001-01-01 00:00:00 +0000 UTC,\n" +
+				"}],\n" +
+				"\tqueueDepth: 1,\n" +
+				"\tworkItems: 0 elements,\n" +
+				"\ttraceWorkers: false,\n" +
+				"\n" +
+				"},\n" +
+				"\tshutdown: true,\n" +
+				"\ttraceTransactionManagerTransactions: true,\n" +
+				"}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := &requestTransactionManager{
+				runningRequests:                     tt.fields.runningRequests,
+				numberOfConcurrentRequests:          tt.fields.numberOfConcurrentRequests,
+				currentTransactionId:                tt.fields.currentTransactionId,
+				workLog:                             tt.fields.workLog,
+				executor:                            tt.fields.executor,
+				shutdown:                            tt.fields.shutdown,
+				traceTransactionManagerTransactions: tt.fields.traceTransactionManagerTransactions,
+				log:                                 tt.fields.log,
+			}
+			assert.Equalf(t, tt.want, r.String(), "String()")
+		})
+	}
+}
diff --git a/plc4go/spi/transactions/completedFuture.go b/plc4go/spi/transactions/completedFuture.go
index ac8227f579..9d5ef8d9ab 100644
--- a/plc4go/spi/transactions/completedFuture.go
+++ b/plc4go/spi/transactions/completedFuture.go
@@ -19,7 +19,10 @@
 
 package transactions
 
-import "context"
+import (
+	"context"
+	"fmt"
+)
 
 type completedFuture struct {
 	err error
@@ -32,3 +35,7 @@ func (c completedFuture) AwaitCompletion(_ context.Context) error {
 func (completedFuture) Cancel(_ bool, _ error) {
 	// No op
 }
+
+func (c completedFuture) String() string {
+	return fmt.Sprintf("completedFuture{\n\terr: %v,\n}", c.err)
+}
diff --git a/plc4go/spi/transactions/completedFuture_test.go b/plc4go/spi/transactions/completedFuture_test.go
new file mode 100644
index 0000000000..c875decec7
--- /dev/null
+++ b/plc4go/spi/transactions/completedFuture_test.go
@@ -0,0 +1,106 @@
+/*
+ * 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 transactions
+
+import (
+	"context"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func Test_completedFuture_AwaitCompletion(t *testing.T) {
+	type fields struct {
+		err error
+	}
+	type args struct {
+		in0 context.Context
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr assert.ErrorAssertionFunc
+	}{
+		{
+			name:    "does nothing",
+			wantErr: assert.NoError,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			c := completedFuture{
+				err: tt.fields.err,
+			}
+			tt.wantErr(t, c.AwaitCompletion(tt.args.in0), fmt.Sprintf("AwaitCompletion(%v)", tt.args.in0))
+		})
+	}
+}
+
+func Test_completedFuture_Cancel(t *testing.T) {
+	type fields struct {
+		err error
+	}
+	type args struct {
+		in0 bool
+		in1 error
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		{
+			name: "does nothing",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			co := completedFuture{
+				err: tt.fields.err,
+			}
+			co.Cancel(tt.args.in0, tt.args.in1)
+		})
+	}
+}
+
+func Test_completedFuture_String(t *testing.T) {
+	type fields struct {
+		err error
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{
+			name: "gives the error",
+			want: "completedFuture{\n\terr: <nil>,\n}",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			c := completedFuture{
+				err: tt.fields.err,
+			}
+			assert.Equalf(t, tt.want, c.String(), "String()")
+		})
+	}
+}