2019-08-03 09:19:32 +02:00
|
|
|
package v2
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2019-08-06 13:27:15 +02:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2019-08-06 18:00:14 +02:00
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
2019-08-03 09:19:32 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type eventA struct{}
|
|
|
|
type eventB struct{}
|
2019-08-08 15:53:02 +02:00
|
|
|
type errEvent struct{}
|
2019-08-03 09:19:32 +02:00
|
|
|
|
|
|
|
var done = fmt.Errorf("done")
|
|
|
|
|
|
|
|
func simpleHandler(event Event) (Events, error) {
|
|
|
|
switch event.(type) {
|
|
|
|
case eventA:
|
|
|
|
return Events{eventB{}}, nil
|
|
|
|
case eventB:
|
2019-08-08 15:12:11 +02:00
|
|
|
return Events{}, done
|
2019-08-03 09:19:32 +02:00
|
|
|
}
|
|
|
|
return Events{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRoutine(t *testing.T) {
|
2019-08-06 13:27:15 +02:00
|
|
|
routine := newRoutine("simpleRoutine", simpleHandler)
|
2019-08-03 09:19:32 +02:00
|
|
|
|
2019-08-06 13:27:15 +02:00
|
|
|
assert.False(t, routine.isRunning(),
|
|
|
|
"expected an initialized routine to not be running")
|
2019-08-08 15:12:11 +02:00
|
|
|
go routine.start()
|
2019-08-03 09:19:32 +02:00
|
|
|
go routine.feedback()
|
2019-08-08 15:12:11 +02:00
|
|
|
<-routine.ready()
|
2019-08-03 09:19:32 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.True(t, routine.trySend(eventA{}),
|
|
|
|
"expected sending to a ready routine to succeed")
|
2019-08-03 09:19:32 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.Equal(t, done, <-routine.final(),
|
|
|
|
"expected the final event to be done")
|
2019-08-06 13:27:15 +02:00
|
|
|
}
|
|
|
|
|
2019-08-08 17:42:46 +02:00
|
|
|
func TestRoutineSend(t *testing.T) {
|
2019-08-06 13:27:15 +02:00
|
|
|
routine := newRoutine("simpleRoutine", simpleHandler)
|
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.False(t, routine.trySend(eventA{}),
|
2019-08-06 13:27:15 +02:00
|
|
|
"expected sending to an unstarted routine to fail")
|
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
go routine.start()
|
2019-08-06 13:27:15 +02:00
|
|
|
|
|
|
|
go routine.feedback()
|
2019-08-08 15:12:11 +02:00
|
|
|
<-routine.ready()
|
2019-08-06 13:27:15 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.True(t, routine.trySend(eventA{}),
|
2019-08-06 13:27:15 +02:00
|
|
|
"expected sending to a running routine to succeed")
|
|
|
|
|
|
|
|
routine.stop()
|
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.False(t, routine.trySend(eventA{}),
|
2019-08-06 13:27:15 +02:00
|
|
|
"expected sending to a stopped routine to fail")
|
2019-08-03 09:19:32 +02:00
|
|
|
}
|
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
type finalCount struct {
|
|
|
|
count int
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f finalCount) Error() string {
|
|
|
|
return "end"
|
|
|
|
}
|
|
|
|
|
2019-08-03 09:19:32 +02:00
|
|
|
func genStatefulHandler(maxCount int) handleFunc {
|
|
|
|
counter := 0
|
|
|
|
return func(event Event) (Events, error) {
|
2019-08-08 15:12:11 +02:00
|
|
|
// golint fixme
|
2019-08-03 09:19:32 +02:00
|
|
|
switch event.(type) {
|
|
|
|
case eventA:
|
|
|
|
counter += 1
|
|
|
|
if counter >= maxCount {
|
2019-08-08 15:12:11 +02:00
|
|
|
return Events{}, finalCount{counter}
|
2019-08-03 09:19:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return Events{eventA{}}, nil
|
2019-08-08 17:42:46 +02:00
|
|
|
case eventB:
|
|
|
|
return Events{}, nil
|
2019-08-03 09:19:32 +02:00
|
|
|
}
|
|
|
|
return Events{}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStatefulRoutine(t *testing.T) {
|
2019-08-08 15:12:11 +02:00
|
|
|
count := 10
|
|
|
|
handler := genStatefulHandler(count)
|
2019-08-06 13:27:15 +02:00
|
|
|
routine := newRoutine("statefulRoutine", handler)
|
2019-08-06 18:00:14 +02:00
|
|
|
routine.setLogger(log.TestingLogger())
|
2019-08-03 09:19:32 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
go routine.start()
|
2019-08-03 09:19:32 +02:00
|
|
|
go routine.feedback()
|
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
<-routine.ready()
|
2019-08-06 13:27:15 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.True(t, routine.trySend(eventA{}),
|
|
|
|
"expected sending to a started routine to succeed")
|
2019-08-03 09:19:32 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
final := <-routine.final()
|
|
|
|
fnl, ok := final.(finalCount)
|
|
|
|
if ok {
|
|
|
|
assert.Equal(t, count, fnl.count,
|
|
|
|
"expected the routine to count to 10")
|
|
|
|
} else {
|
|
|
|
t.Fail()
|
|
|
|
}
|
2019-08-03 09:19:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func handleWithErrors(event Event) (Events, error) {
|
|
|
|
switch event.(type) {
|
|
|
|
case eventA:
|
|
|
|
return Events{}, nil
|
|
|
|
case errEvent:
|
|
|
|
return Events{}, done
|
|
|
|
}
|
|
|
|
return Events{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestErrorSaturation(t *testing.T) {
|
2019-08-06 13:27:15 +02:00
|
|
|
routine := newRoutine("errorRoutine", handleWithErrors)
|
2019-08-08 15:12:11 +02:00
|
|
|
go routine.start()
|
|
|
|
<-routine.ready()
|
2019-08-03 09:19:32 +02:00
|
|
|
go func() {
|
|
|
|
for {
|
2019-08-08 15:12:11 +02:00
|
|
|
routine.trySend(eventA{})
|
2019-08-03 09:19:32 +02:00
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}()
|
2019-08-06 13:27:15 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.True(t, routine.trySend(errEvent{}),
|
2019-08-06 13:27:15 +02:00
|
|
|
"expected send to succeed even when saturated")
|
2019-08-03 09:19:32 +02:00
|
|
|
|
2019-08-08 15:12:11 +02:00
|
|
|
assert.Equal(t, done, <-routine.final())
|
2019-08-03 09:19:32 +02:00
|
|
|
}
|