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  }