func TestValueGetSet(t *testing.T) { u.Debug = false addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1235") if err != nil { t.Fatal(err) } addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5679") if err != nil { t.Fatal(err) } peerA := makePeer(addrA) peerB := makePeer(addrB) neta := swarm.NewSwarm(peerA) err = neta.Listen() if err != nil { t.Fatal(err) } dhtA := NewDHT(peerA, neta, ds.NewMapDatastore()) netb := swarm.NewSwarm(peerB) err = netb.Listen() if err != nil { t.Fatal(err) } dhtB := NewDHT(peerB, netb, ds.NewMapDatastore()) dhtA.Start() dhtB.Start() errsa := dhtA.network.GetErrChan() errsb := dhtB.network.GetErrChan() go func() { select { case err := <-errsa: t.Fatal(err) case err := <-errsb: t.Fatal(err) } }() _, err = dhtA.Connect(addrB) if err != nil { t.Fatal(err) } dhtA.PutValue("hello", []byte("world")) val, err := dhtA.GetValue("hello", time.Second*2) if err != nil { t.Fatal(err) } if string(val) != "world" { t.Fatalf("Expected 'world' got '%s'", string(val)) } }
func TestPing(t *testing.T) { u.Debug = true addrA, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/2222") if err != nil { t.Fatal(err) } addrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/5678") if err != nil { t.Fatal(err) } peerA := makePeer(addrA) peerB := makePeer(addrB) neta := swarm.NewSwarm(peerA) err = neta.Listen() if err != nil { t.Fatal(err) } dhtA := NewDHT(peerA, neta, ds.NewMapDatastore()) netb := swarm.NewSwarm(peerB) err = netb.Listen() if err != nil { t.Fatal(err) } dhtB := NewDHT(peerB, netb, ds.NewMapDatastore()) dhtA.Start() dhtB.Start() _, err = dhtA.Connect(addrB) if err != nil { t.Fatal(err) } //Test that we can ping the node err = dhtA.Ping(peerB, time.Second*2) if err != nil { t.Fatal(err) } dhtA.Halt() dhtB.Halt() }
// If less than K nodes are in the entire network, it should fail when we make // a GET rpc and nobody has the value func TestLessThanKResponses(t *testing.T) { u.Debug = false fn := newFauxNet() fn.Listen() local := new(peer.Peer) local.ID = peer.ID("test_peer") d := NewDHT(local, fn, ds.NewMapDatastore()) d.Start() var ps []*peer.Peer for i := 0; i < 5; i++ { ps = append(ps, _randPeer()) d.Update(ps[i]) } other := _randPeer() // Reply with random peers to every message fn.AddHandler(func(mes *swarm.Message) *swarm.Message { pmes := new(PBDHTMessage) err := proto.Unmarshal(mes.Data, pmes) if err != nil { t.Fatal(err) } switch pmes.GetType() { case PBDHTMessage_GET_VALUE: resp := Message{ Type: pmes.GetType(), ID: pmes.GetId(), Response: true, Success: false, Peers: []*peer.Peer{other}, } return swarm.NewMessage(mes.Peer, resp.ToProtobuf()) default: panic("Shouldnt recieve this.") } }) _, err := d.GetValue(u.Key("hello"), time.Second*30) if err != nil { switch err { case u.ErrNotFound: //Success! return case u.ErrTimeout: t.Fatal("Should not have gotten timeout!") default: t.Fatalf("Got unexpected error: %s", err) } } t.Fatal("Expected to recieve an error.") }
func TestBlocks(t *testing.T) { d := ds.NewMapDatastore() bs, err := NewBlockService(d, nil) if err != nil { t.Error("failed to construct block service", err) return } b, err := blocks.NewBlock([]byte("beep boop")) if err != nil { t.Error("failed to construct block", err) return } h, err := u.Hash([]byte("beep boop")) if err != nil { t.Error("failed to hash data", err) return } if !bytes.Equal(b.Multihash, h) { t.Error("Block Multihash and data multihash not equal") } if b.Key() != u.Key(h) { t.Error("Block key and data multihash key not equal") } k, err := bs.AddBlock(b) if err != nil { t.Error("failed to add block to BlockService", err) return } if k != b.Key() { t.Error("returned key is not equal to block key", err) } b2, err := bs.GetBlock(b.Key()) if err != nil { t.Error("failed to retrieve block from BlockService", err) return } if b.Key() != b2.Key() { t.Error("Block keys not equal.") } if !bytes.Equal(b.Data, b2.Data) { t.Error("Block data is not equal.") } }
func makeDatastore(cfg config.Datastore) (ds.Datastore, error) { if len(cfg.Type) == 0 { return nil, fmt.Errorf("config datastore.type required") } switch cfg.Type { case "leveldb": return makeLevelDBDatastore(cfg) case "memory": return ds.NewMapDatastore(), nil } return nil, fmt.Errorf("Unknown datastore type: %s", cfg.Type) }
func setupDHTS(n int, t *testing.T) ([]*ma.Multiaddr, []*peer.Peer, []*IpfsDHT) { var addrs []*ma.Multiaddr for i := 0; i < 4; i++ { a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 5000+i)) if err != nil { t.Fatal(err) } addrs = append(addrs, a) } var peers []*peer.Peer for i := 0; i < 4; i++ { p := new(peer.Peer) p.AddAddress(addrs[i]) sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512) if err != nil { panic(err) } p.PubKey = pk p.PrivKey = sk id, err := identify.IDFromPubKey(pk) if err != nil { panic(err) } p.ID = id peers = append(peers, p) } var dhts []*IpfsDHT for i := 0; i < 4; i++ { net := swarm.NewSwarm(peers[i]) err := net.Listen() if err != nil { t.Fatal(err) } d := NewDHT(peers[i], net, ds.NewMapDatastore()) dhts = append(dhts, d) d.Start() } return addrs, peers, dhts }
func TestGetFailures(t *testing.T) { fn := newFauxNet() fn.Listen() local := new(peer.Peer) local.ID = peer.ID("test_peer") d := NewDHT(local, fn, ds.NewMapDatastore()) other := &peer.Peer{ID: peer.ID("other_peer")} d.Start() d.Update(other) // This one should time out _, err := d.GetValue(u.Key("test"), time.Millisecond*10) if err != nil { if err != u.ErrTimeout { t.Fatal("Got different error than we expected.") } } else { t.Fatal("Did not get expected error!") } // Reply with failures to every message fn.AddHandler(func(mes *swarm.Message) *swarm.Message { pmes := new(PBDHTMessage) err := proto.Unmarshal(mes.Data, pmes) if err != nil { t.Fatal(err) } resp := Message{ Type: pmes.GetType(), ID: pmes.GetId(), Response: true, Success: false, } return swarm.NewMessage(mes.Peer, resp.ToProtobuf()) }) // This one should fail with NotFound _, err = d.GetValue(u.Key("test"), time.Millisecond*1000) if err != nil { if err != u.ErrNotFound { t.Fatalf("Expected ErrNotFound, got: %s", err) } } else { t.Fatal("expected error, got none.") } success := make(chan struct{}) fn.handlers = nil fn.AddHandler(func(mes *swarm.Message) *swarm.Message { resp := new(PBDHTMessage) err := proto.Unmarshal(mes.Data, resp) if err != nil { t.Fatal(err) } if resp.GetSuccess() { t.Fatal("Get returned success when it shouldnt have.") } success <- struct{}{} return nil }) // Now we test this DHT's handleGetValue failure req := Message{ Type: PBDHTMessage_GET_VALUE, Key: "hello", ID: swarm.GenerateMessageID(), Value: []byte{0}, } fn.Chan.Incoming <- swarm.NewMessage(other, req.ToProtobuf()) <-success }