github.com/MetalBlockchain/metalgo@v1.11.9/snow/networking/tracker/targeter_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package tracker
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  	"go.uber.org/mock/gomock"
    11  
    12  	"github.com/MetalBlockchain/metalgo/ids"
    13  	"github.com/MetalBlockchain/metalgo/snow/validators"
    14  	"github.com/MetalBlockchain/metalgo/utils/constants"
    15  	"github.com/MetalBlockchain/metalgo/utils/logging"
    16  )
    17  
    18  // Assert fields are set correctly.
    19  func TestNewTargeter(t *testing.T) {
    20  	require := require.New(t)
    21  	ctrl := gomock.NewController(t)
    22  
    23  	config := &TargeterConfig{
    24  		VdrAlloc:           10,
    25  		MaxNonVdrUsage:     10,
    26  		MaxNonVdrNodeUsage: 10,
    27  	}
    28  	vdrs := validators.NewManager()
    29  	tracker := NewMockTracker(ctrl)
    30  
    31  	targeterIntf := NewTargeter(
    32  		logging.NoLog{},
    33  		config,
    34  		vdrs,
    35  		tracker,
    36  	)
    37  	require.IsType(&targeter{}, targeterIntf)
    38  	targeter := targeterIntf.(*targeter)
    39  	require.Equal(vdrs, targeter.vdrs)
    40  	require.Equal(tracker, targeter.tracker)
    41  	require.Equal(config.MaxNonVdrUsage, targeter.maxNonVdrUsage)
    42  	require.Equal(config.MaxNonVdrNodeUsage, targeter.maxNonVdrNodeUsage)
    43  }
    44  
    45  func TestTarget(t *testing.T) {
    46  	ctrl := gomock.NewController(t)
    47  
    48  	vdr := ids.BuildTestNodeID([]byte{1})
    49  	vdrWeight := uint64(1)
    50  	totalVdrWeight := uint64(10)
    51  	nonVdr := ids.BuildTestNodeID([]byte{2})
    52  	vdrs := validators.NewManager()
    53  	require.NoError(t, vdrs.AddStaker(constants.PrimaryNetworkID, vdr, nil, ids.Empty, 1))
    54  	require.NoError(t, vdrs.AddStaker(constants.PrimaryNetworkID, ids.GenerateTestNodeID(), nil, ids.Empty, totalVdrWeight-vdrWeight))
    55  
    56  	tracker := NewMockTracker(ctrl)
    57  	config := &TargeterConfig{
    58  		VdrAlloc:           20,
    59  		MaxNonVdrUsage:     10,
    60  		MaxNonVdrNodeUsage: 5,
    61  	}
    62  
    63  	targeter := NewTargeter(
    64  		logging.NoLog{},
    65  		config,
    66  		vdrs,
    67  		tracker,
    68  	)
    69  
    70  	type test struct {
    71  		name           string
    72  		setup          func()
    73  		nodeID         ids.NodeID
    74  		expectedTarget float64
    75  	}
    76  	tests := []test{
    77  		{
    78  			name: "Vdr alloc and at-large alloc",
    79  			setup: func() {
    80  				// At large utilization is less than max
    81  				tracker.EXPECT().TotalUsage().Return(config.MaxNonVdrUsage - 1).Times(1)
    82  			},
    83  			nodeID:         vdr,
    84  			expectedTarget: 2 + 1, // 20 * (1/10) + min(max(0,10-9),5)
    85  		},
    86  		{
    87  			name: "no vdr alloc and at-large alloc",
    88  			setup: func() {
    89  				// At large utilization is less than max
    90  				tracker.EXPECT().TotalUsage().Return(config.MaxNonVdrUsage - 1).Times(1)
    91  			},
    92  			nodeID:         nonVdr,
    93  			expectedTarget: 0 + 1, // 0 * (1/10) + min(max(0,10-9), 5)
    94  		},
    95  		{
    96  			name: "at-large alloc maxed",
    97  			setup: func() {
    98  				tracker.EXPECT().TotalUsage().Return(float64(0)).Times(1)
    99  			},
   100  			nodeID:         nonVdr,
   101  			expectedTarget: 0 + 5, // 0 * (1/10) + min(max(0,10-0), 5)
   102  		},
   103  		{
   104  			name: "at-large alloc completely used",
   105  			setup: func() {
   106  				tracker.EXPECT().TotalUsage().Return(config.MaxNonVdrUsage).Times(1)
   107  			},
   108  			nodeID:         nonVdr,
   109  			expectedTarget: 0 + 0, // 0 * (1/10) + min(max(0,10-10), 5)
   110  		},
   111  		{
   112  			name: "at-large alloc exceeded used",
   113  			setup: func() {
   114  				tracker.EXPECT().TotalUsage().Return(config.MaxNonVdrUsage + 1).Times(1)
   115  			},
   116  			nodeID:         nonVdr,
   117  			expectedTarget: 0 + 0, // 0 * (1/10) + min(max(0,10-11), 5)
   118  		},
   119  	}
   120  
   121  	for _, tt := range tests {
   122  		t.Run(tt.name, func(t *testing.T) {
   123  			tt.setup()
   124  			target := targeter.TargetUsage(tt.nodeID)
   125  			require.Equal(t, tt.expectedTarget, target)
   126  		})
   127  	}
   128  }