github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/p2p/test/testable_node_test.go (about)

     1  package p2ptest
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/qri-io/qri/auth/key"
     9  	"github.com/qri-io/qri/config"
    10  	"github.com/qri-io/qri/dsref"
    11  	"github.com/qri-io/qri/event"
    12  	"github.com/qri-io/qri/repo"
    13  
    14  	libp2p "github.com/libp2p/go-libp2p"
    15  	connmgr "github.com/libp2p/go-libp2p-connmgr"
    16  	host "github.com/libp2p/go-libp2p-core/host"
    17  	net "github.com/libp2p/go-libp2p-core/network"
    18  	peer "github.com/libp2p/go-libp2p-core/peer"
    19  	protocol "github.com/libp2p/go-libp2p-core/protocol"
    20  	pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem"
    21  )
    22  
    23  // TestableNode satisfies the TestablePeerNode interface
    24  // It is used for testing inside the p2ptest package
    25  type TestableNode struct {
    26  	host          host.Host
    27  	cfg           *config.P2P
    28  	Repo          repo.Repo
    29  	localResolver dsref.Resolver
    30  }
    31  
    32  // TestQriProtocolID is the key used to set the stream handler to our
    33  // testing protocol
    34  const TestQriProtocolID = protocol.ID("/qri/_testing")
    35  const TestQriSupportKey = "qri-support-test"
    36  const TestQriConnManagerTag = "qri_test"
    37  const TestQriConnManagerValue = 6
    38  
    39  var ErrTestQriProtocolNotSupported = fmt.Errorf("test qri protocol not supported")
    40  
    41  // Host returns the node's underlying host
    42  func (n *TestableNode) Host() host.Host {
    43  	return n.host
    44  }
    45  
    46  // SimpleAddrInfo returns the PeerInfo of the TestableNode
    47  func (n *TestableNode) SimpleAddrInfo() peer.AddrInfo {
    48  	return peer.AddrInfo{
    49  		ID:    n.host.ID(),
    50  		Addrs: n.host.Addrs(),
    51  	}
    52  }
    53  
    54  func (n *TestableNode) TestStreamHandler(s net.Stream) {
    55  	fmt.Println("stream handler called")
    56  }
    57  
    58  // GoOnline assumes the TestNode is not online, it will set
    59  // the StreamHandler and updates our profile with the underlying peerIDs
    60  func (n *TestableNode) GoOnline(ctx context.Context) error {
    61  	// add multistream handler for qri protocol to the host
    62  	// for more info on multistreams check github.com/multformats/go-multistream
    63  	// Setting the StreamHandler with the TestQriProtocol will let other peers
    64  	// know that we can speak the TestQriProtocol
    65  	n.Host().SetStreamHandler(TestQriProtocolID, n.TestStreamHandler)
    66  
    67  	p := n.Repo.Profiles().Owner(ctx)
    68  	p.PeerIDs = []peer.ID{n.host.ID()}
    69  
    70  	// update profile with our p2p addresses
    71  	if err := n.Repo.Profiles().SetOwner(ctx, p); err != nil {
    72  		return err
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  // NewTestableNode creates a testable node from a repo and a config.P2P
    79  // it creates a basic host
    80  func NewTestableNode(r repo.Repo, p2pconf *config.P2P, _ event.Publisher) (TestablePeerNode, error) {
    81  	ctx := context.Background()
    82  	ps := pstoremem.NewPeerstore()
    83  	// this is essentially what is located in the p2p.makeBasicHost function
    84  	pk, err := key.DecodeB64PrivKey(p2pconf.PrivKey)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	pid, err := p2pconf.DecodePeerID()
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	ps.AddPrivKey(pid, pk)
    94  	ps.AddPubKey(pid, pk.GetPublic())
    95  	opts := []libp2p.Option{
    96  		libp2p.ListenAddrs(p2pconf.Addrs...),
    97  		libp2p.Identity(pk),
    98  		libp2p.Peerstore(ps),
    99  		libp2p.ConnectionManager(connmgr.NewConnManager(1000, 0, time.Millisecond)),
   100  	}
   101  	basicHost, err := libp2p.New(ctx, opts...)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	localResolver := dsref.SequentialResolver(r.Dscache(), r)
   106  	return &TestableNode{
   107  		host:          basicHost,
   108  		Repo:          r,
   109  		cfg:           p2pconf,
   110  		localResolver: localResolver,
   111  	}, nil
   112  }
   113  
   114  var _ TestablePeerNode = (*TestableNode)(nil)
   115  var _ NodeMakerFunc = NewTestableNode