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/05/17 12:05:12 UTC

[plc4x] 01/04: fix(plc4go/spi): gracefully handle tag names not found on SubscriptionEvent

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 1f16e0f7beb8605e71284765bc22891bd915cd8d
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed May 17 13:55:20 2023 +0200

    fix(plc4go/spi): gracefully handle tag names not found on SubscriptionEvent
---
 plc4go/spi/model/DefaultPlcSubscriptionEvent.go    |  37 +-
 .../spi/model/DefaultPlcSubscriptionEvent_test.go  | 414 +++++++++++++++++++++
 2 files changed, 446 insertions(+), 5 deletions(-)

diff --git a/plc4go/spi/model/DefaultPlcSubscriptionEvent.go b/plc4go/spi/model/DefaultPlcSubscriptionEvent.go
index a9d8aab0f7..b4f91f4cb0 100644
--- a/plc4go/spi/model/DefaultPlcSubscriptionEvent.go
+++ b/plc4go/spi/model/DefaultPlcSubscriptionEvent.go
@@ -25,6 +25,9 @@ import (
 	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
 	apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
 	"github.com/apache/plc4x/plc4go/spi/utils"
+	spiValues "github.com/apache/plc4x/plc4go/spi/values"
+
+	"github.com/rs/zerolog/log"
 )
 
 //go:generate go run ../../tools/plc4xgenerator/gen.go -type=DefaultPlcSubscriptionEvent
@@ -75,23 +78,47 @@ func (d *DefaultPlcSubscriptionEvent) GetTagNames() []string {
 }
 
 func (d *DefaultPlcSubscriptionEvent) GetResponseCode(name string) apiModel.PlcResponseCode {
-	return d.values[name].GetCode()
+	item, ok := d.values[name]
+	if !ok {
+		return apiModel.PlcResponseCode_NOT_FOUND
+	}
+	return item.GetCode()
 }
 
 func (d *DefaultPlcSubscriptionEvent) GetTag(name string) apiModel.PlcTag {
-	return d.values[name].GetTag()
+	item := d.values[name]
+	if item == nil {
+		log.Warn().Msgf("field for %s not found", name)
+		return nil
+	}
+	return item.GetTag()
 }
 
 func (d *DefaultPlcSubscriptionEvent) GetType(name string) SubscriptionType {
-	return d.values[name].GetSubscriptionType()
+	item := d.values[name]
+	if item == nil {
+		log.Warn().Msgf("field for %s not found", name)
+		return 0
+	}
+	return item.GetSubscriptionType()
 }
 
 func (d *DefaultPlcSubscriptionEvent) GetInterval(name string) time.Duration {
-	return d.values[name].GetInterval()
+	item := d.values[name]
+	if item == nil {
+		log.Warn().Msgf("field for %s not found", name)
+		return -1
+	}
+	return item.GetInterval()
 }
 
 func (d *DefaultPlcSubscriptionEvent) GetValue(name string) apiValues.PlcValue {
-	return d.values[name].GetValue()
+	item := d.values[name]
+	if item == nil {
+		log.Warn().Msgf("field for %s not found", name)
+		return spiValues.PlcNull{}
+	}
+	return item.GetValue()
 }
 
 func (d *DefaultPlcSubscriptionEvent) GetAddress(name string) string {
diff --git a/plc4go/spi/model/DefaultPlcSubscriptionEvent_test.go b/plc4go/spi/model/DefaultPlcSubscriptionEvent_test.go
new file mode 100644
index 0000000000..dc8432dc09
--- /dev/null
+++ b/plc4go/spi/model/DefaultPlcSubscriptionEvent_test.go
@@ -0,0 +1,414 @@
+/*
+ * 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 model
+
+import (
+	"github.com/stretchr/testify/mock"
+	"testing"
+	"time"
+
+	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
+	apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
+	spiValues "github.com/apache/plc4x/plc4go/spi/values"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDefaultPlcSubscriptionEvent_GetAddress(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   string
+	}{
+		{
+			fields: fields{
+				DefaultPlcSubscriptionEventRequirements: func() DefaultPlcSubscriptionEventRequirements {
+					requirements := NewMockDefaultPlcSubscriptionEventRequirements(t)
+					requirements.EXPECT().GetAddress(mock.Anything).Return("anything")
+					return requirements
+				}(),
+			},
+			name: "get it",
+			want: "anything",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetAddress(tt.args.name), "GetAddress(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetInterval(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   time.Duration
+	}{
+		{
+			name: "get it (not found)",
+			want: -1,
+		},
+		{
+			name: "get it",
+			fields: fields{
+				values: map[string]*DefaultPlcSubscriptionEventItem{
+					"da field": {interval: 70},
+				},
+			},
+			args: args{
+				name: "da field",
+			},
+			want: 70,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetInterval(tt.args.name), "GetInterval(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetResponseCode(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   apiModel.PlcResponseCode
+	}{
+		{
+			name: "get it (not found)",
+			want: apiModel.PlcResponseCode_NOT_FOUND,
+		},
+		{
+			name: "get it",
+			fields: fields{
+				values: map[string]*DefaultPlcSubscriptionEventItem{
+					"da field": {code: apiModel.PlcResponseCode_NOT_FOUND},
+				},
+			},
+			args: args{
+				name: "da field",
+			},
+			want: apiModel.PlcResponseCode_NOT_FOUND,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetResponseCode(tt.args.name), "GetResponseCode(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetSource(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   string
+	}{
+		{
+			name: "get it (not found)",
+			fields: fields{
+				DefaultPlcSubscriptionEventRequirements: func() DefaultPlcSubscriptionEventRequirements {
+					requirements := NewMockDefaultPlcSubscriptionEventRequirements(t)
+					requirements.EXPECT().GetAddress(mock.Anything).Return("")
+					return requirements
+				}(),
+			},
+			want: "",
+		},
+		{
+			name: "get it",
+			fields: fields{
+				DefaultPlcSubscriptionEventRequirements: func() DefaultPlcSubscriptionEventRequirements {
+					requirements := NewMockDefaultPlcSubscriptionEventRequirements(t)
+					requirements.EXPECT().GetAddress(mock.Anything).Return("something")
+					return requirements
+				}(),
+			},
+			args: args{
+				name: "da field",
+			},
+			want: "something",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetSource(tt.args.name), "GetSource(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetTag(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   apiModel.PlcTag
+	}{
+		{
+			name: "get it (not found)",
+			want: nil,
+		},
+		{
+			name: "get it",
+			fields: fields{
+				values: map[string]*DefaultPlcSubscriptionEventItem{
+					"da field": {tag: nil},
+				},
+			},
+			args: args{
+				name: "da field",
+			},
+			want: nil,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetTag(tt.args.name), "GetTag(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetTagNames(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   []string
+	}{
+		{
+			name: "get it (not found)",
+			want: nil,
+		},
+		{
+			name: "get it",
+			fields: fields{
+				values: map[string]*DefaultPlcSubscriptionEventItem{
+					"da field":  {tag: nil},
+					"da field2": {tag: nil},
+				},
+			},
+			want: []string{"da field", "da field2"},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetTagNames(), "GetTagNames()")
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetType(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   SubscriptionType
+	}{
+		{
+			name: "get it (not found)",
+			want: 0,
+		},
+		{
+			name: "get it",
+			fields: fields{
+				values: map[string]*DefaultPlcSubscriptionEventItem{
+					"da field": {subscriptionType: SubscriptionChangeOfState},
+				},
+			},
+			args: args{name: "da field"},
+			want: SubscriptionChangeOfState,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetType(tt.args.name), "GetType(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_GetValue(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   apiValues.PlcValue
+	}{
+		{
+			name: "get it (not found)",
+			want: spiValues.PlcNull{},
+		},
+		{
+			name: "get it",
+			fields: fields{
+				values: map[string]*DefaultPlcSubscriptionEventItem{
+					"da field": {value: spiValues.NewPlcSTRING("yeah")},
+				},
+			},
+			args: args{name: "da field"},
+			want: spiValues.NewPlcSTRING("yeah"),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.GetValue(tt.args.name), "GetValue(%v)", tt.args.name)
+		})
+	}
+}
+
+func TestDefaultPlcSubscriptionEvent_IsAPlcMessage(t *testing.T) {
+	type fields struct {
+		DefaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		values                                  map[string]*DefaultPlcSubscriptionEventItem
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   bool
+	}{
+		{
+			name: "it is",
+			want: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &DefaultPlcSubscriptionEvent{
+				DefaultPlcSubscriptionEventRequirements: tt.fields.DefaultPlcSubscriptionEventRequirements,
+				values:                                  tt.fields.values,
+			}
+			assert.Equalf(t, tt.want, d.IsAPlcMessage(), "IsAPlcMessage()")
+		})
+	}
+}
+
+func TestNewDefaultPlcSubscriptionEvent(t *testing.T) {
+	type args struct {
+		defaultPlcSubscriptionEventRequirements DefaultPlcSubscriptionEventRequirements
+		tags                                    map[string]apiModel.PlcTag
+		types                                   map[string]SubscriptionType
+		intervals                               map[string]time.Duration
+		responseCodes                           map[string]apiModel.PlcResponseCode
+		values                                  map[string]apiValues.PlcValue
+	}
+	tests := []struct {
+		name string
+		args args
+		want apiModel.PlcSubscriptionEvent
+	}{
+		{
+			name: "create it",
+			want: &DefaultPlcSubscriptionEvent{values: map[string]*DefaultPlcSubscriptionEventItem{}},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			assert.Equalf(t, tt.want, NewDefaultPlcSubscriptionEvent(tt.args.defaultPlcSubscriptionEventRequirements, tt.args.tags, tt.args.types, tt.args.intervals, tt.args.responseCodes, tt.args.values), "NewDefaultPlcSubscriptionEvent(%v, %v, %v, %v, %v, %v)", tt.args.defaultPlcSubscriptionEventRequirements, tt.args.tags, tt.args.types, tt.args.intervals, tt.args.responseCodes, tt.args.values)
+		})
+	}
+}