github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/protocols/dag/dagstream/dagstreamleecher/leecher_test.go (about)

     1  package dagstreamleecher
     2  
     3  import (
     4  	"math/rand"
     5  	"strconv"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/unicornultrafoundation/go-helios/hash"
    12  	"github.com/unicornultrafoundation/go-helios/native/idx"
    13  
    14  	"github.com/unicornultrafoundation/go-u2u/gossip/protocols/dag/dagstream"
    15  )
    16  
    17  func TestLeecherNoDeadlocks(t *testing.T) {
    18  	for try := 0; try < 10; try++ {
    19  		testLeecherNoDeadlocks(t, 1+rand.Intn(500))
    20  	}
    21  }
    22  
    23  type peerRequest struct {
    24  	peer    string
    25  	request dagstream.Request
    26  }
    27  
    28  func testLeecherNoDeadlocks(t *testing.T, maxPeers int) {
    29  	requests := make(chan peerRequest, 1000)
    30  	config := LiteConfig()
    31  	config.RecheckInterval = time.Millisecond * 5
    32  	config.MinSessionRestart = 2 * time.Millisecond * 5
    33  	config.MaxSessionRestart = 5 * time.Millisecond * 5
    34  	config.BaseProgressWatchdog = 3 * time.Millisecond * 5
    35  	config.Session.RecheckInterval = time.Millisecond
    36  	epoch := idx.Epoch(1)
    37  	leecher := New(epoch, rand.Intn(2) == 0, config, Callbacks{
    38  		IsProcessed: func(id hash.Event) bool {
    39  			return rand.Intn(2) == 0
    40  		},
    41  		RequestChunk: func(peer string, r dagstream.Request) error {
    42  			requests <- peerRequest{peer, r}
    43  			return nil
    44  		},
    45  		Suspend: func(peer string) bool {
    46  			return rand.Intn(10) == 0
    47  		},
    48  		PeerEpoch: func(peer string) idx.Epoch {
    49  			return 1 + epoch/2 + idx.Epoch(rand.Intn(int(epoch*2)))
    50  		},
    51  	})
    52  	terminated := false
    53  	for i := 0; i < maxPeers*2; i++ {
    54  		peer := strconv.Itoa(rand.Intn(maxPeers))
    55  		coin := rand.Intn(100)
    56  		if coin <= 50 {
    57  			err := leecher.RegisterPeer(peer)
    58  			if !terminated {
    59  				require.NoError(t, err)
    60  			}
    61  		} else if coin <= 60 {
    62  			err := leecher.UnregisterPeer(peer)
    63  			if !terminated {
    64  				require.NoError(t, err)
    65  			}
    66  		} else if coin <= 65 {
    67  			epoch++
    68  			leecher.OnNewEpoch(epoch)
    69  		} else if coin <= 70 {
    70  			leecher.ForceSyncing()
    71  		} else {
    72  			time.Sleep(time.Millisecond)
    73  		}
    74  		select {
    75  		case req := <-requests:
    76  			if rand.Intn(10) != 0 {
    77  				err := leecher.NotifyChunkReceived(req.request.Session.ID, hash.FakeEvent(), rand.Intn(5) == 0)
    78  				if !terminated {
    79  					require.NoError(t, err)
    80  				}
    81  			}
    82  		default:
    83  		}
    84  		if !terminated && rand.Intn(maxPeers*2) == 0 {
    85  			terminated = true
    86  			leecher.Terminate()
    87  		}
    88  	}
    89  	if !terminated {
    90  		leecher.Stop()
    91  	} else {
    92  		leecher.Wg.Wait()
    93  	}
    94  }