package testing import ( "context" "testing" csms "github.com/libp2p/go-conn-security-multistream" metrics "github.com/libp2p/go-libp2p-metrics" inet "github.com/libp2p/go-libp2p-net" pstore "github.com/libp2p/go-libp2p-peerstore" pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" secio "github.com/libp2p/go-libp2p-secio" tptu "github.com/libp2p/go-libp2p-transport-upgrader" tcp "github.com/libp2p/go-tcp-transport" tu "github.com/libp2p/go-testutil" msmux "github.com/whyrusleeping/go-smux-multistream" yamux "github.com/whyrusleeping/go-smux-yamux" swarm "github.com/libp2p/go-libp2p-swarm" ) type config struct { disableReuseport bool dialOnly bool } // Option is an option that can be passed when constructing a test swarm. type Option func(*testing.T, *config) // OptDisableReuseport disables reuseport in this test swarm. var OptDisableReuseport Option = func(_ *testing.T, c *config) { c.disableReuseport = true } // OptDialOnly prevents the test swarm from listening. var OptDialOnly Option = func(_ *testing.T, c *config) { c.dialOnly = true } // GenUpgrader creates a new connection upgrader for use with this swarm. func GenUpgrader(n *swarm.Swarm) *tptu.Upgrader { id := n.LocalPeer() pk := n.Peerstore().PrivKey(id) secMuxer := new(csms.SSMuxer) secMuxer.AddTransport(secio.ID, &secio.Transport{ LocalID: id, PrivateKey: pk, }) stMuxer := msmux.NewBlankTransport() stMuxer.AddTransport("/yamux/1.0.0", yamux.DefaultTransport) return &tptu.Upgrader{ Secure: secMuxer, Muxer: stMuxer, Filters: n.Filters, } } // GenSwarm generates a new test swarm. func GenSwarm(t *testing.T, ctx context.Context, opts ...Option) *swarm.Swarm { var cfg config for _, o := range opts { o(t, &cfg) } p := tu.RandPeerNetParamsOrFatal(t) ps := pstoremem.NewPeerstore() ps.AddPubKey(p.ID, p.PubKey) ps.AddPrivKey(p.ID, p.PrivKey) s := swarm.NewSwarm(ctx, p.ID, ps, metrics.NewBandwidthCounter()) tcpTransport := tcp.NewTCPTransport(GenUpgrader(s)) tcpTransport.DisableReuseport = cfg.disableReuseport if err := s.AddTransport(tcpTransport); err != nil { t.Fatal(err) } if !cfg.dialOnly { if err := s.Listen(p.Addr); err != nil { t.Fatal(err) } s.Peerstore().AddAddrs(p.ID, s.ListenAddresses(), pstore.PermanentAddrTTL) } return s } // DivulgeAddresses adds swarm a's addresses to swarm b's peerstore. func DivulgeAddresses(a, b inet.Network) { id := a.LocalPeer() addrs := a.Peerstore().Addrs(id) b.Peerstore().AddAddrs(id, addrs, pstore.PermanentAddrTTL) }