github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/event/event_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package event 26 27 import ( 28 "math/rand" 29 "sync" 30 "testing" 31 "time" 32 ) 33 34 type testEvent int 35 36 func TestSubCloseUnsub(t *testing.T) { 37 //这个测试的重点是**不要**恐慌。 38 var mux TypeMux 39 mux.Stop() 40 sub := mux.Subscribe(int(0)) 41 sub.Unsubscribe() 42 } 43 44 func TestSub(t *testing.T) { 45 mux := new(TypeMux) 46 defer mux.Stop() 47 48 sub := mux.Subscribe(testEvent(0)) 49 go func() { 50 if err := mux.Post(testEvent(5)); err != nil { 51 t.Errorf("Post returned unexpected error: %v", err) 52 } 53 }() 54 ev := <-sub.Chan() 55 56 if ev.Data.(testEvent) != testEvent(5) { 57 t.Errorf("Got %v (%T), expected event %v (%T)", 58 ev, ev, testEvent(5), testEvent(5)) 59 } 60 } 61 62 func TestMuxErrorAfterStop(t *testing.T) { 63 mux := new(TypeMux) 64 mux.Stop() 65 66 sub := mux.Subscribe(testEvent(0)) 67 if _, isopen := <-sub.Chan(); isopen { 68 t.Errorf("subscription channel was not closed") 69 } 70 if err := mux.Post(testEvent(0)); err != ErrMuxClosed { 71 t.Errorf("Post error mismatch, got: %s, expected: %s", err, ErrMuxClosed) 72 } 73 } 74 75 func TestUnsubscribeUnblockPost(t *testing.T) { 76 mux := new(TypeMux) 77 defer mux.Stop() 78 79 sub := mux.Subscribe(testEvent(0)) 80 unblocked := make(chan bool) 81 go func() { 82 mux.Post(testEvent(5)) 83 unblocked <- true 84 }() 85 86 select { 87 case <-unblocked: 88 t.Errorf("Post returned before Unsubscribe") 89 default: 90 sub.Unsubscribe() 91 <-unblocked 92 } 93 } 94 95 func TestSubscribeDuplicateType(t *testing.T) { 96 mux := new(TypeMux) 97 expected := "event: duplicate type event.testEvent in Subscribe" 98 99 defer func() { 100 err := recover() 101 if err == nil { 102 t.Errorf("Subscribe didn't panic for duplicate type") 103 } else if err != expected { 104 t.Errorf("panic mismatch: got %#v, expected %#v", err, expected) 105 } 106 }() 107 mux.Subscribe(testEvent(1), testEvent(2)) 108 } 109 110 func TestMuxConcurrent(t *testing.T) { 111 rand.Seed(time.Now().Unix()) 112 mux := new(TypeMux) 113 defer mux.Stop() 114 115 recv := make(chan int) 116 poster := func() { 117 for { 118 err := mux.Post(testEvent(0)) 119 if err != nil { 120 return 121 } 122 } 123 } 124 sub := func(i int) { 125 time.Sleep(time.Duration(rand.Intn(99)) * time.Millisecond) 126 sub := mux.Subscribe(testEvent(0)) 127 <-sub.Chan() 128 sub.Unsubscribe() 129 recv <- i 130 } 131 132 go poster() 133 go poster() 134 go poster() 135 nsubs := 1000 136 for i := 0; i < nsubs; i++ { 137 go sub(i) 138 } 139 140 //等到所有人都被服务了 141 counts := make(map[int]int, nsubs) 142 for i := 0; i < nsubs; i++ { 143 counts[<-recv]++ 144 } 145 for i, count := range counts { 146 if count != 1 { 147 t.Errorf("receiver %d called %d times, expected only 1 call", i, count) 148 } 149 } 150 } 151 152 func emptySubscriber(mux *TypeMux, types ...interface{}) { 153 s := mux.Subscribe(testEvent(0)) 154 go func() { 155 for range s.Chan() { 156 } 157 }() 158 } 159 160 func BenchmarkPost1000(b *testing.B) { 161 var ( 162 mux = new(TypeMux) 163 subscribed, done sync.WaitGroup 164 nsubs = 1000 165 ) 166 subscribed.Add(nsubs) 167 done.Add(nsubs) 168 for i := 0; i < nsubs; i++ { 169 go func() { 170 s := mux.Subscribe(testEvent(0)) 171 subscribed.Done() 172 for range s.Chan() { 173 } 174 done.Done() 175 }() 176 } 177 subscribed.Wait() 178 179 //实际基准。 180 b.ResetTimer() 181 for i := 0; i < b.N; i++ { 182 mux.Post(testEvent(0)) 183 } 184 185 b.StopTimer() 186 mux.Stop() 187 done.Wait() 188 } 189 190 func BenchmarkPostConcurrent(b *testing.B) { 191 var mux = new(TypeMux) 192 defer mux.Stop() 193 emptySubscriber(mux, testEvent(0)) 194 emptySubscriber(mux, testEvent(0)) 195 emptySubscriber(mux, testEvent(0)) 196 197 var wg sync.WaitGroup 198 poster := func() { 199 for i := 0; i < b.N; i++ { 200 mux.Post(testEvent(0)) 201 } 202 wg.Done() 203 } 204 wg.Add(5) 205 for i := 0; i < 5; i++ { 206 go poster() 207 } 208 wg.Wait() 209 } 210 211 //为了比较 212 func BenchmarkChanSend(b *testing.B) { 213 c := make(chan interface{}) 214 closed := make(chan struct{}) 215 go func() { 216 for range c { 217 } 218 }() 219 220 for i := 0; i < b.N; i++ { 221 select { 222 case c <- i: 223 case <-closed: 224 } 225 } 226 }