github.com/vipernet-xyz/tm@v0.34.24/blockchain/v2/routine_test.go (about)

     1  package v2
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  type eventA struct {
    12  	priorityNormal
    13  }
    14  
    15  var errDone = fmt.Errorf("done")
    16  
    17  func simpleHandler(event Event) (Event, error) {
    18  	if _, ok := event.(eventA); ok {
    19  		return noOp, errDone
    20  	}
    21  	return noOp, nil
    22  }
    23  
    24  func TestRoutineFinal(t *testing.T) {
    25  	var (
    26  		bufferSize = 10
    27  		routine    = newRoutine("simpleRoutine", simpleHandler, bufferSize)
    28  	)
    29  
    30  	assert.False(t, routine.isRunning(),
    31  		"expected an initialized routine to not be running")
    32  	go routine.start()
    33  	<-routine.ready()
    34  	assert.True(t, routine.isRunning(),
    35  		"expected an started routine")
    36  
    37  	assert.True(t, routine.send(eventA{}),
    38  		"expected sending to a ready routine to succeed")
    39  
    40  	assert.Equal(t, errDone, <-routine.final(),
    41  		"expected the final event to be done")
    42  
    43  	assert.False(t, routine.isRunning(),
    44  		"expected an completed routine to no longer be running")
    45  }
    46  
    47  func TestRoutineStop(t *testing.T) {
    48  	var (
    49  		bufferSize = 10
    50  		routine    = newRoutine("simpleRoutine", simpleHandler, bufferSize)
    51  	)
    52  
    53  	assert.False(t, routine.send(eventA{}),
    54  		"expected sending to an unstarted routine to fail")
    55  
    56  	go routine.start()
    57  	<-routine.ready()
    58  
    59  	assert.True(t, routine.send(eventA{}),
    60  		"expected sending to a running routine to succeed")
    61  
    62  	routine.stop()
    63  
    64  	assert.False(t, routine.send(eventA{}),
    65  		"expected sending to a stopped routine to fail")
    66  }
    67  
    68  type finalCount struct {
    69  	count int
    70  }
    71  
    72  func (f finalCount) Error() string {
    73  	return "end"
    74  }
    75  
    76  func genStatefulHandler(maxCount int) handleFunc {
    77  	counter := 0
    78  	return func(event Event) (Event, error) {
    79  		if _, ok := event.(eventA); ok {
    80  			counter++
    81  			if counter >= maxCount {
    82  				return noOp, finalCount{counter}
    83  			}
    84  
    85  			return eventA{}, nil
    86  		}
    87  		return noOp, nil
    88  	}
    89  }
    90  
    91  func feedback(r *Routine) {
    92  	for event := range r.next() {
    93  		r.send(event)
    94  	}
    95  }
    96  
    97  func TestStatefulRoutine(t *testing.T) {
    98  	var (
    99  		count      = 10
   100  		handler    = genStatefulHandler(count)
   101  		bufferSize = 20
   102  		routine    = newRoutine("statefulRoutine", handler, bufferSize)
   103  	)
   104  
   105  	go routine.start()
   106  	go feedback(routine)
   107  	<-routine.ready()
   108  
   109  	assert.True(t, routine.send(eventA{}),
   110  		"expected sending to a started routine to succeed")
   111  
   112  	final := <-routine.final()
   113  	if fnl, ok := final.(finalCount); ok {
   114  		assert.Equal(t, count, fnl.count,
   115  			"expected the routine to count to 10")
   116  	} else {
   117  		t.Fail()
   118  	}
   119  }
   120  
   121  type lowPriorityEvent struct {
   122  	priorityLow
   123  }
   124  
   125  type highPriorityEvent struct {
   126  	priorityHigh
   127  }
   128  
   129  func handleWithPriority(event Event) (Event, error) {
   130  	switch event.(type) {
   131  	case lowPriorityEvent:
   132  		return noOp, nil
   133  	case highPriorityEvent:
   134  		return noOp, errDone
   135  	}
   136  	return noOp, nil
   137  }
   138  
   139  func TestPriority(t *testing.T) {
   140  	var (
   141  		bufferSize = 20
   142  		routine    = newRoutine("priorityRoutine", handleWithPriority, bufferSize)
   143  	)
   144  
   145  	go routine.start()
   146  	<-routine.ready()
   147  	go func() {
   148  		for {
   149  			routine.send(lowPriorityEvent{})
   150  			time.Sleep(1 * time.Millisecond)
   151  		}
   152  	}()
   153  	time.Sleep(10 * time.Millisecond)
   154  
   155  	assert.True(t, routine.isRunning(),
   156  		"expected an started routine")
   157  	assert.True(t, routine.send(highPriorityEvent{}),
   158  		"expected send to succeed even when saturated")
   159  
   160  	assert.Equal(t, errDone, <-routine.final())
   161  	assert.False(t, routine.isRunning(),
   162  		"expected an started routine")
   163  }