github.com/decred/dcrlnd@v0.7.6/autopilot/top_centrality_test.go (about)

     1  package autopilot
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
     7  	"github.com/decred/dcrd/dcrutil/v4"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  // testTopCentrality is subtest helper to which given the passed graph and
    12  // channels creates the expected centrality score set and checks that the
    13  // calculated score set matches it.
    14  func testTopCentrality(t *testing.T, graph testGraph,
    15  	graphNodes map[int]*secp256k1.PublicKey, channelsWith []int) {
    16  
    17  	topCentrality := NewTopCentrality()
    18  
    19  	var channels []LocalChannel
    20  	for _, ch := range channelsWith {
    21  		channels = append(channels, LocalChannel{
    22  			Node: NewNodeID(graphNodes[ch]),
    23  		})
    24  	}
    25  
    26  	// Start iteration from -1 to also test the case where the node set
    27  	// is empty.
    28  	for i := -1; i < len(graphNodes); i++ {
    29  		nodes := make(map[NodeID]struct{})
    30  		expected := make(map[NodeID]*NodeScore)
    31  
    32  		for j := 0; j <= i; j++ {
    33  			// Add node to the interest set.
    34  			nodeID := NewNodeID(graphNodes[j])
    35  			nodes[nodeID] = struct{}{}
    36  
    37  			// Add to the expected set unless it's a node we have
    38  			// a channel with.
    39  			haveChannel := false
    40  			for _, ch := range channels {
    41  				if nodeID == ch.Node {
    42  					haveChannel = true
    43  					break
    44  				}
    45  			}
    46  
    47  			if !haveChannel {
    48  				score := normalizedTestGraphCentrality[j]
    49  				expected[nodeID] = &NodeScore{
    50  					NodeID: nodeID,
    51  					Score:  score,
    52  				}
    53  			}
    54  		}
    55  
    56  		const chanSize = dcrutil.AtomsPerCoin
    57  
    58  		// Attempt to get centrality scores and expect
    59  		// that the result equals with the expected set.
    60  		scores, err := topCentrality.NodeScores(
    61  			graph, channels, chanSize, nodes,
    62  		)
    63  
    64  		require.NoError(t, err)
    65  		require.Equal(t, expected, scores)
    66  	}
    67  }
    68  
    69  // TestTopCentrality tests that we return the correct normalized centralitiy
    70  // values given a non empty graph, and given our node has an increasing amount
    71  // of channels from 0 to N-1 simulating the whole range from non-connected to
    72  // fully connected.
    73  func TestTopCentrality(t *testing.T) {
    74  	// Generate channels: {}, {0}, {0, 1}, ... {0, 1, ..., N-1}
    75  	channelsWith := [][]int{nil}
    76  
    77  	for i := 0; i < centralityTestGraph.nodes; i++ {
    78  		channels := make([]int, i+1)
    79  		for j := 0; j <= i; j++ {
    80  			channels[j] = j
    81  		}
    82  		channelsWith = append(channelsWith, channels)
    83  	}
    84  
    85  	for _, chanGraph := range chanGraphs {
    86  		chanGraph := chanGraph
    87  
    88  		success := t.Run(chanGraph.name, func(t *testing.T) {
    89  			t.Parallel()
    90  
    91  			graph, cleanup, err := chanGraph.genFunc()
    92  			require.NoError(t, err, "unable to create graph")
    93  			if cleanup != nil {
    94  				defer cleanup()
    95  			}
    96  
    97  			// Build the test graph.
    98  			graphNodes := buildTestGraph(
    99  				t, graph, centralityTestGraph,
   100  			)
   101  
   102  			for _, chans := range channelsWith {
   103  				testTopCentrality(t, graph, graphNodes, chans)
   104  			}
   105  		})
   106  
   107  		require.True(t, success)
   108  	}
   109  }