github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/simulation/simulation_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:43</date>
    10  //</624450114856947712>
    11  
    12  
    13  package simulation
    14  
    15  import (
    16  	"context"
    17  	"errors"
    18  	"flag"
    19  	"sync"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/log"
    24  	"github.com/ethereum/go-ethereum/node"
    25  	"github.com/ethereum/go-ethereum/p2p/simulations"
    26  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    27  	"github.com/mattn/go-colorable"
    28  )
    29  
    30  var (
    31  	loglevel = flag.Int("loglevel", 2, "verbosity of logs")
    32  )
    33  
    34  func init() {
    35  	flag.Parse()
    36  	log.PrintOrigins(true)
    37  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true))))
    38  }
    39  
    40  //如果run方法调用runfunc并正确处理上下文,则测试run。
    41  func TestRun(t *testing.T) {
    42  	sim := New(noopServiceFuncMap)
    43  	defer sim.Close()
    44  
    45  	t.Run("call", func(t *testing.T) {
    46  		expect := "something"
    47  		var got string
    48  		r := sim.Run(context.Background(), func(ctx context.Context, sim *Simulation) error {
    49  			got = expect
    50  			return nil
    51  		})
    52  
    53  		if r.Error != nil {
    54  			t.Errorf("unexpected error: %v", r.Error)
    55  		}
    56  		if got != expect {
    57  			t.Errorf("expected %q, got %q", expect, got)
    58  		}
    59  	})
    60  
    61  	t.Run("cancellation", func(t *testing.T) {
    62  		ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
    63  		defer cancel()
    64  
    65  		r := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error {
    66  			time.Sleep(time.Second)
    67  			return nil
    68  		})
    69  
    70  		if r.Error != context.DeadlineExceeded {
    71  			t.Errorf("unexpected error: %v", r.Error)
    72  		}
    73  	})
    74  
    75  	t.Run("context value and duration", func(t *testing.T) {
    76  		ctx := context.WithValue(context.Background(), "hey", "there")
    77  		sleep := 50 * time.Millisecond
    78  
    79  		r := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error {
    80  			if ctx.Value("hey") != "there" {
    81  				return errors.New("expected context value not passed")
    82  			}
    83  			time.Sleep(sleep)
    84  			return nil
    85  		})
    86  
    87  		if r.Error != nil {
    88  			t.Errorf("unexpected error: %v", r.Error)
    89  		}
    90  		if r.Duration < sleep {
    91  			t.Errorf("reported run duration less then expected: %s", r.Duration)
    92  		}
    93  	})
    94  }
    95  
    96  //testclose测试是close方法,触发所有close函数,所有节点都不再是up。
    97  func TestClose(t *testing.T) {
    98  	var mu sync.Mutex
    99  	var cleanupCount int
   100  
   101  	sleep := 50 * time.Millisecond
   102  
   103  	sim := New(map[string]ServiceFunc{
   104  		"noop": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) {
   105  			return newNoopService(), func() {
   106  				time.Sleep(sleep)
   107  				mu.Lock()
   108  				defer mu.Unlock()
   109  				cleanupCount++
   110  			}, nil
   111  		},
   112  	})
   113  
   114  	nodeCount := 30
   115  
   116  	_, err := sim.AddNodes(nodeCount)
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  
   121  	var upNodeCount int
   122  	for _, n := range sim.Net.GetNodes() {
   123  		if n.Up {
   124  			upNodeCount++
   125  		}
   126  	}
   127  	if upNodeCount != nodeCount {
   128  		t.Errorf("all nodes should be up, insted only %v are up", upNodeCount)
   129  	}
   130  
   131  	sim.Close()
   132  
   133  	if cleanupCount != nodeCount {
   134  		t.Errorf("number of cleanups expected %v, got %v", nodeCount, cleanupCount)
   135  	}
   136  
   137  	upNodeCount = 0
   138  	for _, n := range sim.Net.GetNodes() {
   139  		if n.Up {
   140  			upNodeCount++
   141  		}
   142  	}
   143  	if upNodeCount != 0 {
   144  		t.Errorf("all nodes should be down, insted %v are up", upNodeCount)
   145  	}
   146  }
   147  
   148  //testdone检查close方法是否触发了done通道的关闭。
   149  func TestDone(t *testing.T) {
   150  	sim := New(noopServiceFuncMap)
   151  	sleep := 50 * time.Millisecond
   152  	timeout := 2 * time.Second
   153  
   154  	start := time.Now()
   155  	go func() {
   156  		time.Sleep(sleep)
   157  		sim.Close()
   158  	}()
   159  
   160  	select {
   161  	case <-time.After(timeout):
   162  		t.Error("done channel closing timed out")
   163  	case <-sim.Done():
   164  		if d := time.Since(start); d < sleep {
   165  			t.Errorf("done channel closed sooner then expected: %s", d)
   166  		}
   167  	}
   168  }
   169  
   170  //用于不执行任何操作的常规服务的帮助者映射
   171  var noopServiceFuncMap = map[string]ServiceFunc{
   172  	"noop": noopServiceFunc,
   173  }
   174  
   175  //最基本的noop服务的助手函数
   176  func noopServiceFunc(_ *adapters.ServiceContext, _ *sync.Map) (node.Service, func(), error) {
   177  	return newNoopService(), nil, nil
   178  }
   179  
   180  func newNoopService() node.Service {
   181  	return &noopService{}
   182  }
   183  
   184  //最基本的noop服务的助手函数
   185  //不同类型的,然后NoopService进行测试
   186  //一个节点上有多个服务。
   187  func noopService2Func(_ *adapters.ServiceContext, _ *sync.Map) (node.Service, func(), error) {
   188  	return new(noopService2), nil, nil
   189  }
   190  
   191  //NoopService2是不做任何事情的服务
   192  //但实现了node.service接口。
   193  type noopService2 struct {
   194  	simulations.NoopService
   195  }
   196  
   197  type noopService struct {
   198  	simulations.NoopService
   199  }
   200