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