func walk(tree recon.PrefixTree) { fmt.Println("[") var nodes []recon.PrefixNode root, err := tree.Root() if err != nil { die(err) } nodes = append(nodes, root) first := true for len(nodes) > 0 { if first { first = false } else { fmt.Println(",") } node := nodes[len(nodes)-1] nodes = nodes[:len(nodes)-1] visit(node) if !node.IsLeaf() { nodes = append(recon.MustChildren(node), nodes...) } } fmt.Println("]") }
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() }