@@ -41,6 +41,11 @@ func simpleStepError(_ context.Context) (string, error) {
4141 return "" , fmt .Errorf ("step failure" )
4242}
4343
44+ func stepWithSleep (_ context.Context , duration time.Duration ) (string , error ) {
45+ time .Sleep (duration )
46+ return fmt .Sprintf ("from step that slept for %s" , duration ), nil
47+ }
48+
4449func simpleWorkflowWithStepError (dbosCtx DBOSContext , input string ) (string , error ) {
4550 return RunAsStep (dbosCtx , func (ctx context.Context ) (string , error ) {
4651 return simpleStepError (ctx )
@@ -569,6 +574,85 @@ func TestSteps(t *testing.T) {
569574 })
570575}
571576
577+ func TestGoRunningStepsInsideGoRoutines (t * testing.T ) {
578+ dbosCtx := setupDBOS (t , true , true )
579+ t .Run ("Go must run steps inside a workflow" , func (t * testing.T ) {
580+ _ , err := Go (dbosCtx , func (ctx context.Context ) (string , error ) {
581+ return stepWithSleep (ctx , 1 * time .Second )
582+ })
583+ require .Error (t , err , "expected error when running step outside of workflow context, but got none" )
584+
585+ dbosErr , ok := err .(* DBOSError )
586+ require .True (t , ok , "expected error to be of type *DBOSError, got %T" , err )
587+ require .Equal (t , StepExecutionError , dbosErr .Code )
588+ expectedMessagePart := "workflow state not found in context: are you running this step within a workflow?"
589+ require .Contains (t , err .Error (), expectedMessagePart , "expected error message to contain %q, but got %q" , expectedMessagePart , err .Error ())
590+ })
591+
592+ t .Run ("Go must return step error correctly" , func (t * testing.T ) {
593+ goWorkflow := func (dbosCtx DBOSContext , input string ) (string , error ) {
594+ result , _ := Go (dbosCtx , func (ctx context.Context ) (string , error ) {
595+ return "" , fmt .Errorf ("step error" )
596+ })
597+
598+ resultChan := <- result
599+ if resultChan .err != nil {
600+ return "" , resultChan .err
601+ }
602+ return resultChan .result , nil
603+ }
604+
605+ RegisterWorkflow (dbosCtx , goWorkflow )
606+
607+ handle , err := RunWorkflow (dbosCtx , goWorkflow , "test-input" )
608+ require .NoError (t , err , "failed to run go workflow" )
609+ _ , err = handle .GetResult ()
610+ require .Error (t , err , "expected error when running step, but got none" )
611+ require .Equal (t , "step error" , err .Error ())
612+ })
613+
614+ t .Run ("Go must execute 100 steps simultaneously" , func (t * testing.T ) {
615+ // run 100 steps simultaneously
616+ const numSteps = 100
617+ results := make (chan string , numSteps )
618+ errors := make (chan error , numSteps )
619+ var resultChans []<- chan stepOutcome [string ]
620+
621+ goWorkflow := func (dbosCtx DBOSContext , input string ) (string , error ) {
622+ for range numSteps {
623+ resultChan , err := Go (dbosCtx , func (ctx context.Context ) (string , error ) {
624+ return stepWithSleep (ctx , 20 * time .Millisecond )
625+ })
626+
627+ if err != nil {
628+ return "" , err
629+ }
630+ resultChans = append (resultChans , resultChan )
631+ }
632+
633+ for _ , resultChan := range resultChans {
634+ result1 := <- resultChan
635+ if result1 .err != nil {
636+ errors <- result1 .err
637+ }
638+ results <- result1 .result
639+ }
640+ return "" , nil
641+ }
642+ close (results )
643+ close (errors )
644+
645+ RegisterWorkflow (dbosCtx , goWorkflow )
646+ handle , err := RunWorkflow (dbosCtx , goWorkflow , "test-input" )
647+ require .NoError (t , err , "failed to run go workflow" )
648+ _ , err = handle .GetResult ()
649+ require .NoError (t , err , "failed to get result from go workflow" )
650+
651+ assert .Equal (t , numSteps , len (results ), "expected %d results, got %d" , numSteps , len (results ))
652+ assert .Equal (t , 0 , len (errors ), "expected no errors, got %d" , len (errors ))
653+ })
654+ }
655+
572656func TestChildWorkflow (t * testing.T ) {
573657 dbosCtx := setupDBOS (t , true , true )
574658
0 commit comments