From 4ba82d6cc7d45fb9bb164de4b484267d17160ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20R=C3=BChl?= Date: Tue, 27 Aug 2024 13:02:01 +0200 Subject: [PATCH] fix(plc4go/bacnetip): task time calculation --- .../bacnetip/BACnetVirtualLinkLayerService.go | 10 ++++++- plc4go/internal/bacnetip/Task.go | 30 +++++++++++-------- plc4go/internal/bacnetip/comp.go | 2 +- .../test_max_apdu_length_accepted_test.go | 27 +---------------- .../test_max_segments_accepted_test.go | 22 ++++++++++++++ .../test_utilities/test_time_machine_test.go | 15 +++++----- plc4go/internal/bacnetip/tests/util.go | 2 +- 7 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 plc4go/internal/bacnetip/tests/test_apdu/test_max_segments_accepted_test.go diff --git a/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go b/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go index 3464a4151a5..ad5bf3dcb60 100644 --- a/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go +++ b/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go @@ -991,7 +991,15 @@ func (b *BIPForeign) registrationExpired(_ Args, _ KWArgs) error { } func (b *BIPForeign) String() string { - return fmt.Sprintf("BIPForeign(taskTime: %v, isScheduled: %t, registrationStatus: %d, bbmdAddress: %s, bbmdTimeToLive: %d)", b.taskTime, b.isScheduled, b.registrationStatus, b.bbmdAddress, b.bbmdTimeToLive) + taskTime := "unscheduled" + if b.taskTime != nil { + taskTime = b.taskTime.String() + } + bbmdTimeToLive := "unknown" + if b.bbmdTimeToLive != nil { + bbmdTimeToLive = fmt.Sprintf("%ds", *b.bbmdTimeToLive) + } + return fmt.Sprintf("BIPForeign(taskTime: %s, isScheduled: %t, registrationStatus: %d, bbmdAddress: %s, bbmdTimeToLive: %s)", taskTime, b.isScheduled, b.registrationStatus, b.bbmdAddress, bbmdTimeToLive) } type BIPBBMD struct { diff --git a/plc4go/internal/bacnetip/Task.go b/plc4go/internal/bacnetip/Task.go index 3efaa1bb57b..f34d59b43e7 100644 --- a/plc4go/internal/bacnetip/Task.go +++ b/plc4go/internal/bacnetip/Task.go @@ -98,8 +98,12 @@ type Task struct { isScheduled bool } -func NewTask(taskRequirements TaskRequirements) *Task { - return &Task{TaskRequirements: taskRequirements} +func NewTask(taskRequirements TaskRequirements, opts ...func(*Task)) *Task { + t := &Task{TaskRequirements: taskRequirements} + for _, opt := range opts { + opt(t) + } + return t } func (t *Task) InstallTask(options InstallTaskOptions) { @@ -155,10 +159,9 @@ type OneShotTask struct { func NewOneShotTask(taskRequirements TaskRequirements, when *time.Time) *OneShotTask { o := &OneShotTask{} - o.Task = NewTask(taskRequirements) - if when != nil { - o.taskTime = when - } + o.Task = NewTask(taskRequirements, func(task *Task) { + task.taskTime = when + }) return o } @@ -172,10 +175,9 @@ type OneShotDeleteTask struct { func NewOneShotDeleteTask(taskRequirements TaskRequirements, when *time.Time) *OneShotDeleteTask { o := &OneShotDeleteTask{} - o.Task = NewTask(taskRequirements) - if when != nil { - o.taskTime = when - } + o.Task = NewTask(taskRequirements, func(task *Task) { + task.taskTime = when + }) return o } @@ -379,11 +381,15 @@ func ClearTaskManager(localLog zerolog.Logger) { } type taskItem struct { - taskTime time.Time + taskTime *time.Time id int task TaskRequirements } +func (t taskItem) String() string { + return fmt.Sprintf("taskItem(taskTime:%v, id:%d, %v)", t.taskTime, t.id, t.task) +} + type taskManager struct { sync.Mutex @@ -455,7 +461,7 @@ func (m *taskManager) InstallTask(task TaskRequirements) { // save this in the task list m.count++ heap.Push(&m.tasks, &PriorityItem[int64, taskItem]{ - value: taskItem{taskTime: GetTaskManagerTime(), id: m.count, task: task}, + value: taskItem{taskTime: task.GetTaskTime(), id: m.count, task: task}, priority: task.GetTaskTime().UnixNano() - time.Time{}.UnixNano(), }) m.log.Debug().Stringer("tasks", m.tasks).Msg("tasks") diff --git a/plc4go/internal/bacnetip/comp.go b/plc4go/internal/bacnetip/comp.go index d9eadbb412c..cbd17fb0dc6 100644 --- a/plc4go/internal/bacnetip/comp.go +++ b/plc4go/internal/bacnetip/comp.go @@ -205,7 +205,7 @@ type PriorityItem[P cmp.Ordered, V any] struct { index int // The index of the item in the heap. } -func (p PriorityItem[P, V]) String() string { +func (p *PriorityItem[P, V]) String() string { return fmt.Sprintf("[%v: %v-%v], ", p.index, p.priority, p.value) } diff --git a/plc4go/internal/bacnetip/tests/test_apdu/test_max_apdu_length_accepted_test.go b/plc4go/internal/bacnetip/tests/test_apdu/test_max_apdu_length_accepted_test.go index dd6d87b3984..c6eac64311b 100644 --- a/plc4go/internal/bacnetip/tests/test_apdu/test_max_apdu_length_accepted_test.go +++ b/plc4go/internal/bacnetip/tests/test_apdu/test_max_apdu_length_accepted_test.go @@ -19,29 +19,4 @@ package test_apdu -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model" -) - -func TestMaxApduLengthAcceptedEncode(t *testing.T) { - t.Skip("Plc4x doesn't normalise at model level") - apdu := model.NewAPDU(50) - assert.Equal(t, 0, 50, apdu.ApduLength) -} - -func TestMaxApduLengthAcceptedDecode(t *testing.T) { - t.Skip("Plc4x doesn't normalise at model level") - apdu := model.NewAPDU(0) - serialize, err := apdu.Serialize() - require.NoError(t, err) - apduParse, err := model.APDUParse(context.Background(), serialize, 0) - require.NoError(t, err) - // TODO: no way to access the length - _ = apduParse -} +// TODO: implement diff --git a/plc4go/internal/bacnetip/tests/test_apdu/test_max_segments_accepted_test.go b/plc4go/internal/bacnetip/tests/test_apdu/test_max_segments_accepted_test.go new file mode 100644 index 00000000000..2ea37b65739 --- /dev/null +++ b/plc4go/internal/bacnetip/tests/test_apdu/test_max_segments_accepted_test.go @@ -0,0 +1,22 @@ +/* + * 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 test_apdu + +// TODO implement diff --git a/plc4go/internal/bacnetip/tests/test_utilities/test_time_machine_test.go b/plc4go/internal/bacnetip/tests/test_utilities/test_time_machine_test.go index 9ff9ce917e4..cce6f8d288e 100644 --- a/plc4go/internal/bacnetip/tests/test_utilities/test_time_machine_test.go +++ b/plc4go/internal/bacnetip/tests/test_utilities/test_time_machine_test.go @@ -251,17 +251,18 @@ func (suite *TimeMachineSuite) TestRecurringTask3() { ft := NewSampleRecurringTask(suite.log) // reset the time machine to midnight, install the task, let it run - tests.ResetTimeMachine(tests.StartTime) + startTime := time.Time{}.Add(1 * time.Hour) // We add an hour to avoid underflow + tests.ResetTimeMachine(startTime) ft.InstallTask(bacnetip.WithInstallTaskOptionsInterval(1000 * time.Millisecond).WithOffset(100 * time.Millisecond)) tests.RunTimeMachine(suite.log, 5*time.Second, time.Time{}) // function called, 60 seconds passed - suite.Equal(tests.StartTime.Add(100*time.Millisecond), ft.processTaskCalled[0]) - suite.Equal(tests.StartTime.Add(1100*time.Millisecond), ft.processTaskCalled[1]) - suite.Equal(tests.StartTime.Add(2100*time.Millisecond), ft.processTaskCalled[2]) - suite.Equal(tests.StartTime.Add(3100*time.Millisecond), ft.processTaskCalled[3]) - suite.Equal(tests.StartTime.Add(4100*time.Millisecond), ft.processTaskCalled[4]) - suite.InDelta(5*time.Second, tests.GlobalTimeMachineCurrentTime().Sub(tests.StartTime), float64(100*time.Millisecond)) + suite.Equal(startTime.Add(100*time.Millisecond), ft.processTaskCalled[0]) + suite.Equal(startTime.Add(1100*time.Millisecond), ft.processTaskCalled[1]) + suite.Equal(startTime.Add(2100*time.Millisecond), ft.processTaskCalled[2]) + suite.Equal(startTime.Add(3100*time.Millisecond), ft.processTaskCalled[3]) + suite.Equal(startTime.Add(4100*time.Millisecond), ft.processTaskCalled[4]) + suite.InDelta(5*time.Second, tests.GlobalTimeMachineCurrentTime().Sub(startTime), float64(100*time.Millisecond)) } func (suite *TimeMachineSuite) TestRecurringTask4() { diff --git a/plc4go/internal/bacnetip/tests/util.go b/plc4go/internal/bacnetip/tests/util.go index 56ad73dae4e..5f97ad9914a 100644 --- a/plc4go/internal/bacnetip/tests/util.go +++ b/plc4go/internal/bacnetip/tests/util.go @@ -26,7 +26,7 @@ import ( "github.com/apache/plc4x/plc4go/internal/bacnetip" ) -var StartTime = time.Time{}.Add(1 * time.Hour) +var StartTime = time.Time{} type DummyMessage struct { bacnetip.MessageBridge