github.com/jimmyx0x/go-ethereum@v1.10.28/les/vflux/client/fillset_test.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package client 18 19 import ( 20 "math/rand" 21 "testing" 22 "time" 23 24 "github.com/ethereum/go-ethereum/common/mclock" 25 "github.com/ethereum/go-ethereum/p2p/enode" 26 "github.com/ethereum/go-ethereum/p2p/enr" 27 "github.com/ethereum/go-ethereum/p2p/nodestate" 28 ) 29 30 type testIter struct { 31 waitCh chan struct{} 32 nodeCh chan *enode.Node 33 node *enode.Node 34 } 35 36 func (i *testIter) Next() bool { 37 if _, ok := <-i.waitCh; !ok { 38 return false 39 } 40 i.node = <-i.nodeCh 41 return true 42 } 43 44 func (i *testIter) Node() *enode.Node { 45 return i.node 46 } 47 48 func (i *testIter) Close() { 49 close(i.waitCh) 50 } 51 52 func (i *testIter) push() { 53 var id enode.ID 54 rand.Read(id[:]) 55 i.nodeCh <- enode.SignNull(new(enr.Record), id) 56 } 57 58 func (i *testIter) waiting(timeout time.Duration) bool { 59 select { 60 case i.waitCh <- struct{}{}: 61 return true 62 case <-time.After(timeout): 63 return false 64 } 65 } 66 67 func TestFillSet(t *testing.T) { 68 ns := nodestate.NewNodeStateMachine(nil, nil, &mclock.Simulated{}, testSetup) 69 iter := &testIter{ 70 waitCh: make(chan struct{}), 71 nodeCh: make(chan *enode.Node), 72 } 73 fs := NewFillSet(ns, iter, sfTest1) 74 ns.Start() 75 76 expWaiting := func(i int, push bool) { 77 for ; i > 0; i-- { 78 if !iter.waiting(time.Second * 10) { 79 t.Fatalf("FillSet not waiting for new nodes") 80 } 81 if push { 82 iter.push() 83 } 84 } 85 } 86 87 expNotWaiting := func() { 88 if iter.waiting(time.Millisecond * 100) { 89 t.Fatalf("FillSet unexpectedly waiting for new nodes") 90 } 91 } 92 93 expNotWaiting() 94 fs.SetTarget(3) 95 expWaiting(3, true) 96 expNotWaiting() 97 fs.SetTarget(100) 98 expWaiting(2, true) 99 expWaiting(1, false) 100 // lower the target before the previous one has been filled up 101 fs.SetTarget(0) 102 iter.push() 103 expNotWaiting() 104 fs.SetTarget(10) 105 expWaiting(4, true) 106 expNotWaiting() 107 // remove all previously set flags 108 ns.ForEach(sfTest1, nodestate.Flags{}, func(node *enode.Node, state nodestate.Flags) { 109 ns.SetState(node, nodestate.Flags{}, sfTest1, 0) 110 }) 111 // now expect FillSet to fill the set up again with 10 new nodes 112 expWaiting(10, true) 113 expNotWaiting() 114 115 fs.Close() 116 ns.Stop() 117 }