github.com/igggame/nebulas-go@v2.1.0+incompatible/core/event_test.go (about) 1 // Copyright (C) 2017 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // the go-nebulas library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with the go-nebulas library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 19 package core 20 21 import ( 22 "fmt" 23 "math/rand" 24 "sync" 25 "testing" 26 "time" 27 28 "github.com/nebulasio/go-nebulas/core/state" 29 30 "github.com/stretchr/testify/assert" 31 ) 32 33 func register(emitter *EventEmitter, topic string) *EventSubscriber { 34 eventSub := NewEventSubscriber(128, []string{topic}) 35 emitter.Register(eventSub) 36 return eventSub 37 } 38 39 func TestEventEmitter(t *testing.T) { 40 // create emitter. 41 emitter := NewEventEmitter(1024) 42 emitter.Start() 43 44 // topic & categories 45 topics := []string{"chain.topic.01", "chain.topic.02", "chain.topic.03", "node.topic.11", "node.topic.12"} 46 47 // prepare chan. 48 t1ch := register(emitter, topics[0]) 49 t2ch := register(emitter, topics[1]) 50 t3ch := register(emitter, topics[2]) 51 52 wg := new(sync.WaitGroup) 53 wg.Add(2) 54 55 totalEventCount := 1000 56 eventCountDist := make(map[string]int) 57 go func() { 58 // send message. 59 defer wg.Done() 60 rand.Seed(time.Now().UnixNano()) 61 62 for i := 0; i < totalEventCount; i++ { 63 64 topic := topics[rand.Intn(len(topics))] 65 66 eventCountDist[topic] = eventCountDist[topic] + 1 67 68 e := &state.Event{ 69 Topic: topic, 70 Data: fmt.Sprintf("%d", i), 71 } 72 emitter.Trigger(e) 73 } 74 }() 75 76 t1c, t2c, t3c := 0, 0, 0 77 for len(t1ch.eventCh) > 0 { 78 e := <-t1ch.eventCh 79 assert.Equal(t, topics[0], e.Topic) 80 t1c++ 81 } 82 for len(t2ch.eventCh) > 0 { 83 e := <-t2ch.eventCh 84 assert.Equal(t, topics[1], e.Topic) 85 t2c++ 86 } 87 for len(t3ch.eventCh) > 0 { 88 e := <-t3ch.eventCh 89 assert.Equal(t, topics[2], e.Topic) 90 t3c++ 91 } 92 93 at1c, at2c, at3c := eventCountDist[topics[0]], eventCountDist[topics[1]], eventCountDist[topics[2]] 94 assert.Equal(t, at1c, t1c) 95 assert.Equal(t, at2c, t2c) 96 assert.Equal(t, at3c, t3c) 97 98 emitter.Stop() 99 time.Sleep(time.Second) 100 } 101 102 func TestEventEmitterWithRunningRegDereg(t *testing.T) { 103 // create emitter. 104 emitter := NewEventEmitter(1024) 105 emitter.Start() 106 107 // topic 108 topics := []string{"chain.topic.01", "chain.topic.02", "node.topic.11"} 109 110 wg := new(sync.WaitGroup) 111 wg.Add(2) 112 113 totalEventCount := 1000 114 eventCountDist := make(map[string]int) 115 116 // prepare chan. 117 t1ch := register(emitter, topics[0]) 118 t2ch := register(emitter, topics[1]) 119 t3ch := register(emitter, topics[2]) 120 121 go func() { 122 // send message. 123 defer wg.Done() 124 rand.Seed(time.Now().UnixNano()) 125 126 for i := 0; i < totalEventCount; i++ { 127 if i%100 == 99 { 128 time.Sleep(time.Millisecond * 500) 129 } 130 131 topic := topics[rand.Intn(len(topics))] 132 133 eventCountDist[topic] = eventCountDist[topic] + 1 134 135 e := &state.Event{ 136 Topic: topic, 137 Data: fmt.Sprintf("%d", i), 138 } 139 emitter.Trigger(e) 140 } 141 }() 142 143 t1c, t2c, t3c := 0, 0, 0 144 go func() { 145 defer wg.Done() 146 147 for { 148 select { 149 case <-time.After(time.Second * 1): 150 return 151 case e := <-t1ch.eventCh: 152 assert.Equal(t, topics[0], e.Topic) 153 t1c++ 154 155 if t1c%13 == 2 { 156 emitter.Deregister(t2ch) 157 } else if t1c%13 == 9 { 158 emitter.Register(t2ch) 159 } 160 161 case e := <-t2ch.eventCh: 162 assert.Equal(t, topics[1], e.Topic) 163 t2c++ 164 165 if t2c%13 == 4 { 166 emitter.Deregister(t3ch) 167 } else if t2c%13 == 12 { 168 emitter.Register(t3ch) 169 } 170 171 case e := <-t3ch.eventCh: 172 assert.Equal(t, topics[2], e.Topic) 173 t3c++ 174 } 175 } 176 }() 177 178 wg.Wait() 179 180 emitter.Stop() 181 time.Sleep(time.Millisecond * 100) 182 }