github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/event/event_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:38</date>
    10  //</624450090769059840>
    11  
    12  
    13  package event
    14  
    15  import (
    16  	"math/rand"
    17  	"sync"
    18  	"testing"
    19  	"time"
    20  )
    21  
    22  type testEvent int
    23  
    24  func TestSubCloseUnsub(t *testing.T) {
    25  //这个测试的重点是**不要**恐慌。
    26  	var mux TypeMux
    27  	mux.Stop()
    28  	sub := mux.Subscribe(int(0))
    29  	sub.Unsubscribe()
    30  }
    31  
    32  func TestSub(t *testing.T) {
    33  	mux := new(TypeMux)
    34  	defer mux.Stop()
    35  
    36  	sub := mux.Subscribe(testEvent(0))
    37  	go func() {
    38  		if err := mux.Post(testEvent(5)); err != nil {
    39  			t.Errorf("Post returned unexpected error: %v", err)
    40  		}
    41  	}()
    42  	ev := <-sub.Chan()
    43  
    44  	if ev.Data.(testEvent) != testEvent(5) {
    45  		t.Errorf("Got %v (%T), expected event %v (%T)",
    46  			ev, ev, testEvent(5), testEvent(5))
    47  	}
    48  }
    49  
    50  func TestMuxErrorAfterStop(t *testing.T) {
    51  	mux := new(TypeMux)
    52  	mux.Stop()
    53  
    54  	sub := mux.Subscribe(testEvent(0))
    55  	if _, isopen := <-sub.Chan(); isopen {
    56  		t.Errorf("subscription channel was not closed")
    57  	}
    58  	if err := mux.Post(testEvent(0)); err != ErrMuxClosed {
    59  		t.Errorf("Post error mismatch, got: %s, expected: %s", err, ErrMuxClosed)
    60  	}
    61  }
    62  
    63  func TestUnsubscribeUnblockPost(t *testing.T) {
    64  	mux := new(TypeMux)
    65  	defer mux.Stop()
    66  
    67  	sub := mux.Subscribe(testEvent(0))
    68  	unblocked := make(chan bool)
    69  	go func() {
    70  		mux.Post(testEvent(5))
    71  		unblocked <- true
    72  	}()
    73  
    74  	select {
    75  	case <-unblocked:
    76  		t.Errorf("Post returned before Unsubscribe")
    77  	default:
    78  		sub.Unsubscribe()
    79  		<-unblocked
    80  	}
    81  }
    82  
    83  func TestSubscribeDuplicateType(t *testing.T) {
    84  	mux := new(TypeMux)
    85  	expected := "event: duplicate type event.testEvent in Subscribe"
    86  
    87  	defer func() {
    88  		err := recover()
    89  		if err == nil {
    90  			t.Errorf("Subscribe didn't panic for duplicate type")
    91  		} else if err != expected {
    92  			t.Errorf("panic mismatch: got %#v, expected %#v", err, expected)
    93  		}
    94  	}()
    95  	mux.Subscribe(testEvent(1), testEvent(2))
    96  }
    97  
    98  func TestMuxConcurrent(t *testing.T) {
    99  	rand.Seed(time.Now().Unix())
   100  	mux := new(TypeMux)
   101  	defer mux.Stop()
   102  
   103  	recv := make(chan int)
   104  	poster := func() {
   105  		for {
   106  			err := mux.Post(testEvent(0))
   107  			if err != nil {
   108  				return
   109  			}
   110  		}
   111  	}
   112  	sub := func(i int) {
   113  		time.Sleep(time.Duration(rand.Intn(99)) * time.Millisecond)
   114  		sub := mux.Subscribe(testEvent(0))
   115  		<-sub.Chan()
   116  		sub.Unsubscribe()
   117  		recv <- i
   118  	}
   119  
   120  	go poster()
   121  	go poster()
   122  	go poster()
   123  	nsubs := 1000
   124  	for i := 0; i < nsubs; i++ {
   125  		go sub(i)
   126  	}
   127  
   128  //等到所有人都被服务了
   129  	counts := make(map[int]int, nsubs)
   130  	for i := 0; i < nsubs; i++ {
   131  		counts[<-recv]++
   132  	}
   133  	for i, count := range counts {
   134  		if count != 1 {
   135  			t.Errorf("receiver %d called %d times, expected only 1 call", i, count)
   136  		}
   137  	}
   138  }
   139  
   140  func emptySubscriber(mux *TypeMux) {
   141  	s := mux.Subscribe(testEvent(0))
   142  	go func() {
   143  		for range s.Chan() {
   144  		}
   145  	}()
   146  }
   147  
   148  func BenchmarkPost1000(b *testing.B) {
   149  	var (
   150  		mux              = new(TypeMux)
   151  		subscribed, done sync.WaitGroup
   152  		nsubs            = 1000
   153  	)
   154  	subscribed.Add(nsubs)
   155  	done.Add(nsubs)
   156  	for i := 0; i < nsubs; i++ {
   157  		go func() {
   158  			s := mux.Subscribe(testEvent(0))
   159  			subscribed.Done()
   160  			for range s.Chan() {
   161  			}
   162  			done.Done()
   163  		}()
   164  	}
   165  	subscribed.Wait()
   166  
   167  //实际基准。
   168  	b.ResetTimer()
   169  	for i := 0; i < b.N; i++ {
   170  		mux.Post(testEvent(0))
   171  	}
   172  
   173  	b.StopTimer()
   174  	mux.Stop()
   175  	done.Wait()
   176  }
   177  
   178  func BenchmarkPostConcurrent(b *testing.B) {
   179  	var mux = new(TypeMux)
   180  	defer mux.Stop()
   181  	emptySubscriber(mux)
   182  	emptySubscriber(mux)
   183  	emptySubscriber(mux)
   184  
   185  	var wg sync.WaitGroup
   186  	poster := func() {
   187  		for i := 0; i < b.N; i++ {
   188  			mux.Post(testEvent(0))
   189  		}
   190  		wg.Done()
   191  	}
   192  	wg.Add(5)
   193  	for i := 0; i < 5; i++ {
   194  		go poster()
   195  	}
   196  	wg.Wait()
   197  }
   198  
   199  //为了比较
   200  func BenchmarkChanSend(b *testing.B) {
   201  	c := make(chan interface{})
   202  	closed := make(chan struct{})
   203  	go func() {
   204  		for range c {
   205  		}
   206  	}()
   207  
   208  	for i := 0; i < b.N; i++ {
   209  		select {
   210  		case c <- i:
   211  		case <-closed:
   212  		}
   213  	}
   214  }
   215