github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/bloombits/scheduler_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  //版权所有2017 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 bloombits
    26  
    27  import (
    28  	"bytes"
    29  	"math/big"
    30  	"math/rand"
    31  	"sync"
    32  	"sync/atomic"
    33  	"testing"
    34  	"time"
    35  )
    36  
    37  //测试调度程序可以对检索请求进行重复数据消除和转发
    38  //底层的获取器和服务响应返回,与并发无关
    39  //请求客户机或服务数据获取程序。
    40  func TestSchedulerSingleClientSingleFetcher(t *testing.T) { testScheduler(t, 1, 1, 5000) }
    41  func TestSchedulerSingleClientMultiFetcher(t *testing.T)  { testScheduler(t, 1, 10, 5000) }
    42  func TestSchedulerMultiClientSingleFetcher(t *testing.T)  { testScheduler(t, 10, 1, 5000) }
    43  func TestSchedulerMultiClientMultiFetcher(t *testing.T)   { testScheduler(t, 10, 10, 5000) }
    44  
    45  func testScheduler(t *testing.T, clients int, fetchers int, requests int) {
    46  	f := newScheduler(0)
    47  
    48  //创建一批处理程序goroutine,以响应bloom位请求和
    49  //把它们交给调度。
    50  	var fetchPend sync.WaitGroup
    51  	fetchPend.Add(fetchers)
    52  	defer fetchPend.Wait()
    53  
    54  	fetch := make(chan *request, 16)
    55  	defer close(fetch)
    56  
    57  	var delivered uint32
    58  	for i := 0; i < fetchers; i++ {
    59  		go func() {
    60  			defer fetchPend.Done()
    61  
    62  			for req := range fetch {
    63  				time.Sleep(time.Duration(rand.Intn(int(100 * time.Microsecond))))
    64  				atomic.AddUint32(&delivered, 1)
    65  
    66  				f.deliver([]uint64{
    67  req.section + uint64(requests), //未请求的数据(确保不超出界限)
    68  req.section,                    //请求数据
    69  req.section,                    //重复的数据(确保不会双重关闭任何内容)
    70  				}, [][]byte{
    71  					{},
    72  					new(big.Int).SetUint64(req.section).Bytes(),
    73  					new(big.Int).SetUint64(req.section).Bytes(),
    74  				})
    75  			}
    76  		}()
    77  	}
    78  //启动一批goroutine以同时运行计划任务
    79  	quit := make(chan struct{})
    80  
    81  	var pend sync.WaitGroup
    82  	pend.Add(clients)
    83  
    84  	for i := 0; i < clients; i++ {
    85  		go func() {
    86  			defer pend.Done()
    87  
    88  			in := make(chan uint64, 16)
    89  			out := make(chan []byte, 16)
    90  
    91  			f.run(in, fetch, out, quit, &pend)
    92  
    93  			go func() {
    94  				for j := 0; j < requests; j++ {
    95  					in <- uint64(j)
    96  				}
    97  				close(in)
    98  			}()
    99  
   100  			for j := 0; j < requests; j++ {
   101  				bits := <-out
   102  				if want := new(big.Int).SetUint64(uint64(j)).Bytes(); !bytes.Equal(bits, want) {
   103  					t.Errorf("vector %d: delivered content mismatch: have %x, want %x", j, bits, want)
   104  				}
   105  			}
   106  		}()
   107  	}
   108  	pend.Wait()
   109  
   110  	if have := atomic.LoadUint32(&delivered); int(have) != requests {
   111  		t.Errorf("request count mismatch: have %v, want %v", have, requests)
   112  	}
   113  }