@@ -58,6 +58,8 @@ func (s *WorkflowUnitTest) SetupSuite() {
5858 RegisterWorkflow (activityOptionsWorkflow )
5959 RegisterWorkflow (receiveAsync_CorruptSignalOnClosedChannelWorkflowTest )
6060 RegisterWorkflow (receive_CorruptSignalOnClosedChannelWorkflowTest )
61+ RegisterWorkflow (bufferedChanWorkflowTest )
62+ RegisterWorkflow (bufferedChanWithSelectorWorkflowTest )
6163
6264 s .activityOptions = ActivityOptions {
6365 ScheduleToStartTimeout : time .Minute ,
@@ -757,6 +759,83 @@ func (s *WorkflowUnitTest) Test_CorruptedSignalOnClosedChannelWorkflow_Receive_S
757759 s .EqualValues (0 , len (result ))
758760}
759761
762+ func bufferedChanWorkflowTest (ctx Context , bufferSize int ) error {
763+ bufferedCh := NewBufferedChannel (ctx , bufferSize )
764+
765+ Go (ctx , func (ctx Context ) {
766+ var dummy int
767+ for i := 0 ; i < bufferSize ; i ++ {
768+ bufferedCh .Receive (ctx , & dummy )
769+ }
770+ })
771+
772+ for i := 0 ; i < bufferSize + 1 ; i ++ {
773+ bufferedCh .Send (ctx , i )
774+ }
775+ return nil
776+ }
777+
778+ func (s * WorkflowUnitTest ) Test_BufferedChanWorkflow () {
779+ bufferSizeList := []int {1 , 5 }
780+ for _ , bufferSize := range bufferSizeList {
781+ env := s .NewTestWorkflowEnvironment ()
782+ env .ExecuteWorkflow (bufferedChanWorkflowTest , bufferSize )
783+ s .True (env .IsWorkflowCompleted ())
784+ s .NoError (env .GetWorkflowError ())
785+ }
786+ }
787+
788+ func bufferedChanWithSelectorWorkflowTest (ctx Context , bufferSize int ) error {
789+ bufferedCh := NewBufferedChannel (ctx , bufferSize )
790+ selectedCh := NewChannel (ctx )
791+ done := NewChannel (ctx )
792+ var dummy struct {}
793+
794+ // 1. First we need to fill the buffer
795+ for i := 0 ; i < bufferSize ; i ++ {
796+ bufferedCh .Send (ctx , dummy )
797+ }
798+
799+ // DO NOT change the order of these coroutines.
800+ Go (ctx , func (ctx Context ) {
801+ // 3. Add another send callback to bufferedCh's blockedSends.
802+ bufferedCh .Send (ctx , dummy )
803+ done .Send (ctx , dummy )
804+ })
805+
806+ Go (ctx , func (ctx Context ) {
807+ // 4. Make sure selectedCh is selected
808+ selectedCh .Receive (ctx , nil )
809+
810+ // 5. Get a value from channel buffer. Receive call will also check if there's any blocked sends.
811+ // The first blockedSends is added by Select(). Since bufferedCh is not selected, it's fn() will
812+ // return false. The Receive call should continue to check other blockedSends, until fn() returns
813+ // true or the list is empty. In this case, it will move the value sent in step 3 into buffer
814+ // and thus unblocks it.
815+ bufferedCh .Receive (ctx , nil )
816+ })
817+
818+ selector := NewSelector (ctx )
819+ selector .AddSend (selectedCh , dummy , func () {})
820+ selector .AddSend (bufferedCh , dummy , func () {})
821+ // 2. When select is called, callback for the second send will be added to bufferedCh's blockedSends
822+ selector .Select (ctx )
823+
824+ // Make sure no coroutine blocks
825+ done .Receive (ctx , nil )
826+ return nil
827+ }
828+
829+ func (s * WorkflowUnitTest ) Test_BufferedChanWithSelectorWorkflow () {
830+ bufferSizeList := []int {1 , 5 }
831+ for _ , bufferSize := range bufferSizeList {
832+ env := s .NewTestWorkflowEnvironment ()
833+ env .ExecuteWorkflow (bufferedChanWithSelectorWorkflowTest , bufferSize )
834+ s .True (env .IsWorkflowCompleted ())
835+ s .NoError (env .GetWorkflowError ())
836+ }
837+ }
838+
760839func activityOptionsWorkflow (ctx Context ) (result string , err error ) {
761840 ao1 := ActivityOptions {
762841 ActivityID : "id1" ,
0 commit comments