github.com/alwitt/goutils@v0.6.4/event_processing_test.go (about) 1 package goutils 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/apex/log" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestTaskParamProcessing(t *testing.T) { 16 assert := assert.New(t) 17 18 ctxt, cancel := context.WithCancel(context.Background()) 19 defer cancel() 20 uut, err := GetNewTaskProcessorInstance(ctxt, "testing", 4, log.Fields{"instance": "unit-tester"}) 21 assert.Nil(err) 22 defer func() { 23 assert.Nil(uut.StopEventLoop()) 24 }() 25 uutCast, ok := uut.(*taskProcessorImpl) 26 assert.True(ok) 27 28 // Case 1: no executor map 29 { 30 assert.NotNil(uutCast.processNewTaskParam("hello")) 31 } 32 33 type testStruct1 struct{} 34 type testStruct2 struct{} 35 type testStruct3 struct{} 36 37 executorMap := map[reflect.Type]TaskProcessorSupportHandler{ 38 reflect.TypeOf(testStruct1{}): func(p interface{}) error { 39 return nil 40 }, 41 } 42 43 // Case 2: define a executor map 44 { 45 assert.Nil(uut.SetTaskExecutionMap(executorMap)) 46 assert.Nil(uutCast.processNewTaskParam(testStruct1{})) 47 assert.NotNil(uutCast.processNewTaskParam(testStruct2{})) 48 assert.NotNil(uutCast.processNewTaskParam(&testStruct3{})) 49 } 50 51 executorMap = map[reflect.Type]TaskProcessorSupportHandler{ 52 reflect.TypeOf(testStruct1{}): func(p interface{}) error { return nil }, 53 reflect.TypeOf(testStruct3{}): func(p interface{}) error { return fmt.Errorf("Dummy error") }, 54 } 55 56 // Case 3: change executor map 57 { 58 assert.Nil(uut.SetTaskExecutionMap(executorMap)) 59 assert.Nil(uutCast.processNewTaskParam(testStruct1{})) 60 assert.NotNil(uutCast.processNewTaskParam(&testStruct2{})) 61 assert.NotNil(uutCast.processNewTaskParam(testStruct3{})) 62 } 63 64 // Case 4: append to existing map 65 { 66 assert.Nil(uut.AddToTaskExecutionMap( 67 reflect.TypeOf(&testStruct2{}), func(p interface{}) error { return nil }, 68 )) 69 assert.Nil(uutCast.processNewTaskParam(testStruct1{})) 70 assert.Nil(uutCast.processNewTaskParam(&testStruct2{})) 71 assert.NotNil(uutCast.processNewTaskParam(testStruct3{})) 72 } 73 } 74 75 func TestTaskDemuxProcessing(t *testing.T) { 76 assert := assert.New(t) 77 log.SetLevel(log.DebugLevel) 78 79 wg := sync.WaitGroup{} 80 defer wg.Wait() 81 ctxt, cancel := context.WithCancel(context.Background()) 82 defer cancel() 83 84 { 85 _, err := GetNewTaskDemuxProcessorInstance( 86 ctxt, "testing", 4, 0, log.Fields{"instance": "unit-tester"}, 87 ) 88 assert.NotNil(err) 89 } 90 91 uut, err := GetNewTaskDemuxProcessorInstance( 92 ctxt, "testing", 4, 3, log.Fields{"instance": "unit-tester"}, 93 ) 94 assert.Nil(err) 95 defer func() { 96 assert.Nil(uut.StopEventLoop()) 97 }() 98 99 // recast to source 100 uutc := uut.(*taskDemuxProcessorImpl) 101 assert.Equal(0, uutc.routeIdx) 102 103 // start the built in processes 104 assert.Nil(uut.StartEventLoop(&wg)) 105 106 path1 := 0 107 path2 := 0 108 path3 := 0 109 110 type testStruct1 struct{} 111 type testStruct2 struct{} 112 type testStruct3 struct{} 113 114 testWG := sync.WaitGroup{} 115 pathCB1 := func(p interface{}) error { 116 path1++ 117 testWG.Done() 118 return nil 119 } 120 pathCB2 := func(p interface{}) error { 121 path2++ 122 testWG.Done() 123 return nil 124 } 125 pathCB3 := func(p interface{}) error { 126 path3++ 127 testWG.Done() 128 return nil 129 } 130 131 executorMap := map[reflect.Type]TaskProcessorSupportHandler{ 132 reflect.TypeOf(testStruct1{}): pathCB1, 133 reflect.TypeOf(testStruct2{}): pathCB2, 134 reflect.TypeOf(testStruct3{}): pathCB3, 135 } 136 137 assert.Nil(uut.SetTaskExecutionMap(executorMap)) 138 139 // Case 1: trigger 140 { 141 testWG.Add(1) 142 useContext, cancel := context.WithTimeout(context.Background(), time.Second) 143 assert.Nil(uut.Submit(useContext, testStruct1{})) 144 cancel() 145 testWG.Wait() 146 assert.Equal(1, path1) 147 assert.Equal(1, uutc.routeIdx) 148 } 149 150 // Case 2: trigger 151 { 152 testWG.Add(1) 153 useContext, cancel := context.WithTimeout(context.Background(), time.Second) 154 assert.Nil(uut.Submit(useContext, testStruct1{})) 155 cancel() 156 testWG.Wait() 157 assert.Equal(2, path1) 158 assert.Equal(2, uutc.routeIdx) 159 } 160 161 // Case 3: trigger back to back 162 { 163 testWG.Add(2) 164 useContext, cancel := context.WithTimeout(context.Background(), time.Second) 165 assert.Nil(uut.Submit(useContext, testStruct2{})) 166 cancel() 167 useContext, cancel = context.WithTimeout(context.Background(), time.Second) 168 assert.Nil(uut.Submit(useContext, testStruct3{})) 169 cancel() 170 testWG.Wait() 171 assert.Equal(1, path2) 172 assert.Equal(1, path3) 173 assert.Equal(1, uutc.routeIdx) 174 } 175 }