Пример #1
0
// Test full node sync.
func (s *ReconSuite) TestFullSync(c *gc.C) {
	ptree1, cleanup, err := s.Factory()
	c.Assert(err, gc.IsNil)
	defer cleanup()

	ptree2, cleanup, err := s.Factory()
	c.Assert(err, gc.IsNil)
	defer cleanup()

	ptree1.Insert(cf.Zi(cf.P_SKS, 65537))
	ptree1.Insert(cf.Zi(cf.P_SKS, 65539))
	root, _ := ptree1.Root()
	c.Log("peer1:", recon.MustElements(root))

	ptree2.Insert(cf.Zi(cf.P_SKS, 65537))
	ptree2.Insert(cf.Zi(cf.P_SKS, 65541))
	root, _ = ptree2.Root()
	c.Log("peer2:", recon.MustElements(root))

	port1, port2 := portPair(c)
	peer1 := s.newPeer(port1, port2, recon.PeerModeGossipOnly, ptree1)
	peer2 := s.newPeer(port2, port1, recon.PeerModeServeOnly, ptree2)

	err = s.pollRootConvergence(c, peer1, peer2, ptree1, ptree2)
	c.Assert(err, gc.IsNil)
}
Пример #2
0
func (s *PtreeSuite) TestInsertNodeSplit(c *gc.C) {
	root, err := s.ptree.Root()
	for _, sv := range root.SValues() {
		c.Log("SV:", sv)
		c.Assert(sv.Cmp(cf.Zi(cf.P_SKS, 1)), gc.Equals, 0)
	}
	// Add a bunch of nodes, enough to cause splits
	for i := 0; i < s.config.SplitThreshold()*4; i++ {
		z := cf.Zi(cf.P_SKS, i+65536)
		c.Log("Insert:", z)
		s.ptree.Insert(z)
	}
	// Remove a bunch of nodes, enough to cause joins
	for i := 0; i < s.config.SplitThreshold()*4; i++ {
		z := cf.Zi(cf.P_SKS, i+65536)
		c.Log("Remove:", z)
		s.ptree.Remove(z)
	}
	root, err = s.ptree.Root()
	c.Assert(err, gc.IsNil)
	// Insert/Remove reversible after splitting & joining?
	for _, sv := range root.SValues() {
		c.Log("SV:", sv)
		c.Assert(sv.Cmp(cf.Zi(cf.P_SKS, 1)), gc.Equals, 0)
	}
	c.Assert(recon.MustChildren(root), gc.HasLen, 0)
	c.Assert(recon.MustElements(root), gc.HasLen, 0)
}
Пример #3
0
func visit(node recon.PrefixNode) {
	render := struct {
		SValues      []*conflux.Zp
		NumElements  int
		Key          string
		Leaf         bool
		Fingerprints []string
		Children     []string
	}{
		node.SValues(),
		node.Size(),
		node.Key().String(),
		node.IsLeaf(),
		[]string{},
		[]string{},
	}
	if node.IsLeaf() {
		for _, element := range recon.MustElements(node) {
			render.Fingerprints = append(render.Fingerprints, fmt.Sprintf("%x", element.Bytes()))
		}
	}
	for _, child := range recon.MustChildren(node) {
		render.Children = append(render.Children, child.Key().String())
	}
	out, err := json.MarshalIndent(render, "", "\t")
	if err != nil {
		die(err)
	}
	os.Stdout.Write(out)
	os.Stdout.Write([]byte("\n"))
}
Пример #4
0
func (s *PtreeSuite) TestInsertNodesNoSplit(c *gc.C) {
	s.ptree.Insert(cf.Zi(cf.P_SKS, 100))
	s.ptree.Insert(cf.Zi(cf.P_SKS, 300))
	s.ptree.Insert(cf.Zi(cf.P_SKS, 500))
	root, err := s.ptree.Root()
	c.Assert(err, gc.IsNil)
	c.Assert(recon.MustElements(root), gc.HasLen, 3)
	c.Assert(root.IsLeaf(), gc.Equals, true)
	s.ptree.Remove(cf.Zi(cf.P_SKS, 100))
	s.ptree.Remove(cf.Zi(cf.P_SKS, 300))
	s.ptree.Remove(cf.Zi(cf.P_SKS, 500))
	root, err = s.ptree.Root()
	c.Assert(recon.MustElements(root), gc.HasLen, 0)
	for _, sv := range root.SValues() {
		c.Assert(sv.Cmp(cf.Zi(cf.P_SKS, 1)), gc.Equals, 0)
	}
}
Пример #5
0
// Test sync with polynomial interpolation.
func (s *ReconSuite) TestPolySyncMBar(c *gc.C) {
	ptree1, cleanup, err := s.Factory()
	c.Assert(err, gc.IsNil)
	defer cleanup()

	ptree2, cleanup, err := s.Factory()
	c.Assert(err, gc.IsNil)
	defer cleanup()

	onlyInPeer1 := cf.NewZSet()
	// Load up peer 1 with items
	for i := 1; i < 100; i++ {
		ptree1.Insert(cf.Zi(cf.P_SKS, 65537*i))
	}
	// Four extra samples
	for i := 1; i < 5; i++ {
		z := cf.Zi(cf.P_SKS, 68111*i)
		ptree1.Insert(z)
		onlyInPeer1.Add(z)
	}
	root, _ := ptree1.Root()
	c.Log("peer1:", recon.MustElements(root))

	onlyInPeer2 := cf.NewZSet()
	// Load up peer 2 with items
	for i := 1; i < 100; i++ {
		ptree2.Insert(cf.Zi(cf.P_SKS, 65537*i))
	}
	// One extra sample
	for i := 1; i < 2; i++ {
		z := cf.Zi(cf.P_SKS, 70001*i)
		ptree2.Insert(z)
		onlyInPeer2.Add(z)
	}
	root, _ = ptree2.Root()
	c.Log("peer2:", recon.MustElements(root))

	port1, port2 := portPair(c)
	peer1 := s.newPeer(port1, port2, recon.PeerModeGossipOnly, ptree1)
	peer2 := s.newPeer(port2, port1, recon.PeerModeServeOnly, ptree2)

	err = s.pollConvergence(c, peer1, peer2, onlyInPeer2, onlyInPeer1, LongTimeout)
	c.Assert(err, gc.IsNil)
}
Пример #6
0
func (s *ReconSuite) pollRootConvergence(c *gc.C, peer1, peer2 *recon.Peer, ptree1, ptree2 recon.PrefixTree) error {
	var t tomb.Tomb
	t.Go(func() error {
		defer peer1.Stop()
		defer peer2.Stop()

		var mu sync.Mutex
		var zs1 *cf.ZSet = cf.NewZSet()
		var zs2 *cf.ZSet = cf.NewZSet()

		timer := time.NewTimer(LongTimeout)
		peer1.SetMutatedFunc(func() {
			mu.Lock()
			root1, err := ptree1.Root()
			c.Assert(err, gc.IsNil)
			zs1 = cf.NewZSet(recon.MustElements(root1)...)
			mu.Unlock()
		})
		peer2.SetMutatedFunc(func() {
			mu.Lock()
			root2, err := ptree2.Root()
			c.Assert(err, gc.IsNil)
			zs2 = cf.NewZSet(recon.MustElements(root2)...)
			mu.Unlock()
		})
	POLLING:
		for {
			select {
			case r1, ok := <-peer1.RecoverChan:
				if !ok {
					break POLLING
				}
				c.Logf("peer1 recover: %v", r1)
				for _, zp := range r1.RemoteElements {
					c.Assert(zp, gc.NotNil)
					peer1.Insert(zp)
				}
			case r2, ok := <-peer2.RecoverChan:
				if !ok {
					break POLLING
				}
				c.Logf("peer2 recover: %v", r2)
				for _, zp := range r2.RemoteElements {
					c.Assert(zp, gc.NotNil)
					peer2.Insert(zp)
				}
			case _ = <-timer.C:
				return fmt.Errorf("timeout waiting for convergence")
			default:
			}

			var done bool
			mu.Lock()
			done = zs1.Len() > 0 && zs1.Equal(zs2)
			mu.Unlock()
			if done {
				c.Logf("peer1 has %q, peer2 has %q", zs1, zs2)
				return nil
			}
		}
		return fmt.Errorf("set reconciliation did not converge")
	})
	return t.Wait()
}