@@ -47,6 +47,11 @@ func simpleStepError(_ context.Context) (string, error) {
4747 return "" , fmt .Errorf ("step failure" )
4848}
4949
50+ func stepWithSleep (_ context.Context , duration time.Duration ) (string , error ) {
51+ time .Sleep (duration )
52+ return fmt .Sprintf ("from step that slept for %s" , duration ), nil
53+ }
54+
5055func simpleWorkflowWithStepError (dbosCtx DBOSContext , input string ) (string , error ) {
5156 return RunAsStep (dbosCtx , func (ctx context.Context ) (string , error ) {
5257 return simpleStepError (ctx )
@@ -860,6 +865,85 @@ func TestSteps(t *testing.T) {
860865 })
861866}
862867
868+ func TestGoRunningStepsInsideGoRoutines (t * testing.T ) {
869+ dbosCtx := setupDBOS (t , true , true )
870+ t .Run ("Go must run steps inside a workflow" , func (t * testing.T ) {
871+ _ , err := Go (dbosCtx , func (ctx context.Context ) (string , error ) {
872+ return stepWithSleep (ctx , 1 * time .Second )
873+ })
874+ require .Error (t , err , "expected error when running step outside of workflow context, but got none" )
875+
876+ dbosErr , ok := err .(* DBOSError )
877+ require .True (t , ok , "expected error to be of type *DBOSError, got %T" , err )
878+ require .Equal (t , StepExecutionError , dbosErr .Code )
879+ expectedMessagePart := "workflow state not found in context: are you running this step within a workflow?"
880+ require .Contains (t , err .Error (), expectedMessagePart , "expected error message to contain %q, but got %q" , expectedMessagePart , err .Error ())
881+ })
882+
883+ t .Run ("Go must return step error correctly" , func (t * testing.T ) {
884+ goWorkflow := func (dbosCtx DBOSContext , input string ) (string , error ) {
885+ result , _ := Go (dbosCtx , func (ctx context.Context ) (string , error ) {
886+ return "" , fmt .Errorf ("step error" )
887+ })
888+
889+ resultChan := <- result
890+ if resultChan .err != nil {
891+ return "" , resultChan .err
892+ }
893+ return resultChan .result , nil
894+ }
895+
896+ RegisterWorkflow (dbosCtx , goWorkflow )
897+
898+ handle , err := RunWorkflow (dbosCtx , goWorkflow , "test-input" )
899+ require .NoError (t , err , "failed to run go workflow" )
900+ _ , err = handle .GetResult ()
901+ require .Error (t , err , "expected error when running step, but got none" )
902+ require .Equal (t , "step error" , err .Error ())
903+ })
904+
905+ t .Run ("Go must execute 100 steps simultaneously" , func (t * testing.T ) {
906+ // run 100 steps simultaneously
907+ const numSteps = 100
908+ results := make (chan string , numSteps )
909+ errors := make (chan error , numSteps )
910+ var resultChans []<- chan stepOutcome [string ]
911+
912+ goWorkflow := func (dbosCtx DBOSContext , input string ) (string , error ) {
913+ for range numSteps {
914+ resultChan , err := Go (dbosCtx , func (ctx context.Context ) (string , error ) {
915+ return stepWithSleep (ctx , 20 * time .Millisecond )
916+ })
917+
918+ if err != nil {
919+ return "" , err
920+ }
921+ resultChans = append (resultChans , resultChan )
922+ }
923+
924+ for _ , resultChan := range resultChans {
925+ result1 := <- resultChan
926+ if result1 .err != nil {
927+ errors <- result1 .err
928+ }
929+ results <- result1 .result
930+ }
931+ return "" , nil
932+ }
933+ close (results )
934+ close (errors )
935+
936+ RegisterWorkflow (dbosCtx , goWorkflow )
937+ handle , err := RunWorkflow (dbosCtx , goWorkflow , "test-input" )
938+ require .NoError (t , err , "failed to run go workflow" )
939+ _ , err = handle .GetResult ()
940+ require .NoError (t , err , "failed to get result from go workflow" )
941+
942+ assert .Equal (t , numSteps , len (results ), "expected %d results, got %d" , numSteps , len (results ))
943+ assert .Equal (t , 0 , len (errors ), "expected no errors, got %d" , len (errors ))
944+ })
945+ }
946+
863947func TestChildWorkflow (t * testing.T ) {
864948 dbosCtx := setupDBOS (t , true , true )
865949
0 commit comments