@@ -5,11 +5,13 @@ import (
5
5
"fmt"
6
6
"reflect"
7
7
"sort"
8
+ "sync"
8
9
"sync/atomic"
9
10
"testing"
10
11
"time"
11
12
12
13
"github.com/benbjohnson/clock"
14
+ "github.com/cschleiden/go-workflows/backend"
13
15
"github.com/cschleiden/go-workflows/internal/activity"
14
16
margs "github.com/cschleiden/go-workflows/internal/args"
15
17
"github.com/cschleiden/go-workflows/internal/command"
@@ -50,7 +52,7 @@ type WorkflowTester[TResult any] interface {
50
52
51
53
SignalWorkflow (signalName string , value interface {})
52
54
53
- SignalWorkflowInstance (wfi * core.WorkflowInstance , signalName string , value interface {})
55
+ SignalWorkflowInstance (wfi * core.WorkflowInstance , signalName string , value interface {}) error
54
56
55
57
WorkflowFinished () bool
56
58
@@ -95,7 +97,9 @@ type workflowTester[TResult any] struct {
95
97
wfi * core.WorkflowInstance
96
98
97
99
// Workflows
98
- testWorkflows []* testWorkflow
100
+ mtw sync.RWMutex
101
+ testWorkflowsByInstanceID map [string ]* testWorkflow
102
+ testWorkflows []* testWorkflow
99
103
100
104
workflowFinished bool
101
105
workflowResult payload.Payload
@@ -167,7 +171,8 @@ func NewWorkflowTester[TResult any](wf interface{}, opts ...WorkflowTesterOption
167
171
wfi : wfi ,
168
172
registry : registry ,
169
173
170
- testWorkflows : make ([]* testWorkflow , 0 ),
174
+ testWorkflows : make ([]* testWorkflow , 0 ),
175
+ testWorkflowsByInstanceID : make (map [string ]* testWorkflow ),
171
176
172
177
ma : & mock.Mock {},
173
178
mockedActivities : make (map [string ]bool ),
@@ -236,11 +241,8 @@ func (wt *workflowTester[TResult]) OnSubWorkflow(workflow interface{}, args ...i
236
241
237
242
func (wt * workflowTester [TResult ]) Execute (args ... interface {}) {
238
243
// Start workflow under test
239
- wt .testWorkflows = append (wt .testWorkflows , & testWorkflow {
240
- instance : wt .wfi ,
241
- pendingEvents : []history.Event {wt .getInitialEvent (wt .wf , args )},
242
- history : make ([]history.Event , 0 ),
243
- })
244
+ initialEvent := wt .getInitialEvent (wt .wf , args )
245
+ wt .addWorkflow (wt .wfi , initialEvent )
244
246
245
247
for ! wt .workflowFinished {
246
248
// Execute all workflows until no more events?
@@ -356,23 +358,10 @@ func (wt *workflowTester[TResult]) Execute(args ...interface{}) {
356
358
}
357
359
358
360
func (wt * workflowTester [TResult ]) sendEvent (wfi * core.WorkflowInstance , event history.Event ) {
359
- var w * testWorkflow
360
- for _ , tw := range wt .testWorkflows {
361
- if tw .instance .InstanceID == wfi .InstanceID {
362
- w = tw
363
- break
364
- }
365
- }
361
+ w := wt .getWorkflow (wfi )
366
362
367
363
if w == nil {
368
- // Workflow not mocked, create new instance
369
- w = & testWorkflow {
370
- instance : wfi ,
371
- history : []history.Event {},
372
- pendingEvents : []history.Event {},
373
- }
374
-
375
- wt .testWorkflows = append (wt .testWorkflows , w )
364
+ panic (fmt .Sprintf ("tried to send event to instance %s which does not exist" , wfi .InstanceID ))
376
365
}
377
366
378
367
w .pendingEvents = append (w .pendingEvents , event )
@@ -382,7 +371,11 @@ func (wt *workflowTester[TResult]) SignalWorkflow(name string, value interface{}
382
371
wt .SignalWorkflowInstance (wt .wfi , name , value )
383
372
}
384
373
385
- func (wt * workflowTester [TResult ]) SignalWorkflowInstance (wfi * core.WorkflowInstance , name string , value interface {}) {
374
+ func (wt * workflowTester [TResult ]) SignalWorkflowInstance (wfi * core.WorkflowInstance , name string , value interface {}) error {
375
+ if wt .getWorkflow (wfi ) == nil {
376
+ return backend .ErrInstanceNotFound
377
+ }
378
+
386
379
arg , err := converter .DefaultConverter .To (value )
387
380
if err != nil {
388
381
panic ("Could not convert signal value to string" + err .Error ())
@@ -403,6 +396,8 @@ func (wt *workflowTester[TResult]) SignalWorkflowInstance(wfi *core.WorkflowInst
403
396
HistoryEvent : e ,
404
397
}
405
398
}
399
+
400
+ return nil
406
401
}
407
402
408
403
func (wt * workflowTester [TResult ]) WorkflowFinished () bool {
@@ -538,6 +533,28 @@ func (wt *workflowTester[TResult]) scheduleTimer(instance *core.WorkflowInstance
538
533
})
539
534
}
540
535
536
+ func (wt * workflowTester [TResult ]) getWorkflow (instance * core.WorkflowInstance ) * testWorkflow {
537
+ wt .mtw .RLock ()
538
+ defer wt .mtw .RUnlock ()
539
+
540
+ return wt .testWorkflowsByInstanceID [instance .InstanceID ]
541
+ }
542
+
543
+ func (wt * workflowTester [TResult ]) addWorkflow (instance * core.WorkflowInstance , initialEvent history.Event ) * testWorkflow {
544
+ wt .mtw .Lock ()
545
+ defer wt .mtw .Unlock ()
546
+
547
+ tw := & testWorkflow {
548
+ instance : instance ,
549
+ pendingEvents : []history.Event {initialEvent },
550
+ history : make ([]history.Event , 0 ),
551
+ }
552
+ wt .testWorkflows = append (wt .testWorkflows , tw )
553
+ wt .testWorkflowsByInstanceID [instance .InstanceID ] = tw
554
+
555
+ return tw
556
+ }
557
+
541
558
func (wt * workflowTester [TResult ]) scheduleSubWorkflow (event history.WorkflowEvent ) {
542
559
a := event .HistoryEvent .Attributes .(* history.ExecutionStartedAttributes )
543
560
@@ -568,7 +585,7 @@ func (wt *workflowTester[TResult]) scheduleSubWorkflow(event history.WorkflowEve
568
585
569
586
if ! wt .mockedWorkflows [a .Name ] {
570
587
// Workflow not mocked, allow event to be processed
571
- wt .sendEvent (event .WorkflowInstance , event .HistoryEvent )
588
+ wt .addWorkflow (event .WorkflowInstance , event .HistoryEvent )
572
589
return
573
590
}
574
591
@@ -646,7 +663,7 @@ type signaler[T any] struct {
646
663
}
647
664
648
665
func (s * signaler [T ]) SignalWorkflow (ctx context.Context , instanceID string , name string , arg interface {}) error {
649
- return nil
666
+ return s . wt . SignalWorkflowInstance ( core . NewWorkflowInstance ( instanceID , "" ), name , arg )
650
667
}
651
668
652
669
var _ signals.Signaler = (* signaler [any ])(nil )
0 commit comments