gopkg.in/dedis/onet.v2@v2.0.0-20181115163211-c8f3724038a7/tree_test.go (about)

     1  package onet
     2  
     3  import (
     4  	"io/ioutil"
     5  	"math/rand"
     6  	"os"
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"gopkg.in/dedis/kyber.v2/util/key"
    14  	"gopkg.in/dedis/onet.v2/log"
    15  	"gopkg.in/dedis/onet.v2/network"
    16  )
    17  
    18  var prefix = "127.0.0.1:"
    19  
    20  func TestSubset(t *testing.T) {
    21  	// subset of 10 from roster of 1: degenerate case
    22  	names := genLocalhostPeerNames(1, 0)
    23  	ro := genRoster(tSuite, names)
    24  	r := ro.RandomSubset(ro.List[0], 10)
    25  	// (return just the root)
    26  	assert.Equal(t, len(r.List), 1)
    27  	assert.Equal(t, r.List[0], ro.List[0])
    28  	assert.NotContains(t, r.List[1:], ro.List[0])
    29  
    30  	// subset of 4 from a roster of 20: all returned should be in orig
    31  	// roster.
    32  	names = genLocalhostPeerNames(20, 0)
    33  	ro = genRoster(tSuite, names)
    34  	r = ro.RandomSubset(ro.List[0], 4)
    35  	assert.Equal(t, len(r.List), 5)
    36  	for _, x := range r.List {
    37  		assert.Contains(t, ro.List, x)
    38  	}
    39  	assert.NotContains(t, r.List[1:], ro.List[0])
    40  
    41  	// with two nodes, if the second is the root, the first should end up
    42  	// in r.List[0]
    43  	names = genLocalhostPeerNames(2, 0)
    44  	ro = genRoster(tSuite, names)
    45  	assert.Equal(t, len(ro.List), 2)
    46  	ro.List[1] = network.NewServerIdentity(ro.List[1].Public, ro.List[1].Address)
    47  	// The bug turned out to be about comparing, so let's give a root that is the same
    48  	// server id, but a different pointer.
    49  	r = ro.RandomSubset(network.NewServerIdentity(ro.List[1].Public, ro.List[1].Address), 1)
    50  	assert.Equal(t, len(r.List), 2)
    51  	assert.Equal(t, r.List[0], ro.List[1])
    52  	assert.Equal(t, r.List[1], ro.List[0])
    53  	// Check the "star" topology of these two guys
    54  	// is root==0 -> (len(child)==1) && child[0]==1
    55  	tr := r.GenerateStar()
    56  	assert.Equal(t, tr.Root.ServerIdentity, r.List[0])
    57  	assert.Equal(t, len(tr.Root.Children), 1)
    58  	assert.Equal(t, tr.Root.Children[0].ServerIdentity, r.List[1])
    59  }
    60  
    61  // test the ID generation
    62  func TestTreeId(t *testing.T) {
    63  	names := genLocalhostPeerNames(3, 0)
    64  	idsList := genRoster(tSuite, names)
    65  	// Generate two example topology
    66  	tree := idsList.GenerateBinaryTree()
    67  	/*
    68  			TODO: re-calculate the uuid
    69  		root, _ := ExampleGenerateTreeFromRoster(idsList)
    70  		tree := Tree{IdList: idsList, Root: root}
    71  		var h bytes.Buffer
    72  		h.Write(idsList.Id().Bytes())
    73  		h.Write(root.Id().Bytes())
    74  		genId := uuid.NewV5(uuid.NamespaceURL, h.String())
    75  		if !uuid.Equal(genId, tree.Id()) {
    76  				t.Fatal("Id generated is wrong")
    77  			}
    78  	*/
    79  	if len(tree.ID.String()) != 36 {
    80  		t.Fatal("Id generated is wrong")
    81  	}
    82  }
    83  
    84  // Test if topology correctly handles the "virtual" connections in the topology
    85  func TestTreeConnectedTo(t *testing.T) {
    86  	names := genLocalhostPeerNames(3, 0)
    87  	peerList := genRoster(tSuite, names)
    88  	// Generate two example topology
    89  	tree := peerList.GenerateBinaryTree()
    90  	// Generate the network
    91  	if !tree.Root.IsConnectedTo(peerList.List[1]) {
    92  		t.Fatal("Root should be connected to child (localhost:2001)")
    93  	}
    94  	if !tree.Root.IsConnectedTo(peerList.List[2]) {
    95  		t.Fatal("Root should be connected to child (localhost:2002)")
    96  	}
    97  }
    98  
    99  // Test initialisation of new peer-list
   100  func TestRosterNew(t *testing.T) {
   101  	adresses := genLocalhostPeerNames(2, 2000)
   102  	pl := genRoster(tSuite, adresses)
   103  	if len(pl.List) != 2 {
   104  		t.Fatalf("Expected two peers in PeerList. Instead got %d", len(pl.List))
   105  	}
   106  	if pl.ID.IsNil() {
   107  		t.Fatal("PeerList without ID is not allowed")
   108  	}
   109  	if len(pl.ID.String()) != 36 {
   110  		t.Fatal("PeerList ID does not seem to be a UUID.")
   111  	}
   112  }
   113  
   114  // Test initialisation of new peer-list from config-file
   115  func TestInitPeerListFromConfigFile(t *testing.T) {
   116  	names := genLocalhostPeerNames(3, 2000)
   117  	idsList := genRoster(tSuite, names)
   118  	// write it
   119  	tmpDir, err := ioutil.TempDir("", "tree_test")
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	defer os.RemoveAll(tmpDir)
   124  	WriteTomlConfig(idsList.Toml(tSuite), "identities.toml", tmpDir)
   125  	// decode it
   126  	var decoded RosterToml
   127  	if err := ReadTomlConfig(&decoded, "identities.toml", tmpDir); err != nil {
   128  		t.Fatal("Could not read from file the entityList")
   129  	}
   130  	decodedList := decoded.Roster(tSuite)
   131  	if len(decodedList.List) != 3 {
   132  		t.Fatalf("Expected two identities in Roster. Instead got %d", len(decodedList.List))
   133  	}
   134  	if decodedList.ID.IsNil() {
   135  		t.Fatal("PeerList without ID is not allowed")
   136  	}
   137  	if len(decodedList.ID.String()) != 36 {
   138  		t.Fatal("PeerList ID does not seem to be a UUID hash.")
   139  	}
   140  }
   141  
   142  // Test initialisation of new random tree from a peer-list
   143  
   144  // Test initialisation of new graph from config-file using a peer-list
   145  // XXX again this test might be obsolete/does more harm then it is useful:
   146  // It forces every field to be exported/made public
   147  // and we want to get away from config files (or not?)
   148  
   149  // Test initialisation of new graph when one peer is represented more than
   150  // once
   151  
   152  // Test access to tree:
   153  // - parent
   154  func TestTreeParent(t *testing.T) {
   155  	names := genLocalhostPeerNames(3, 2000)
   156  	peerList := genRoster(tSuite, names)
   157  	// Generate two example topology
   158  	tree := peerList.GenerateBinaryTree()
   159  	child := tree.Root.Children[0]
   160  	if !child.Parent.ID.Equal(tree.Root.ID) {
   161  		t.Fatal("Parent of child of root is not the root...")
   162  	}
   163  }
   164  
   165  // - children
   166  func TestTreeChildren(t *testing.T) {
   167  	names := genLocalhostPeerNames(2, 2000)
   168  	peerList := genRoster(tSuite, names)
   169  	// Generate two example topology
   170  	tree := peerList.GenerateBinaryTree()
   171  	child := tree.Root.Children[0]
   172  	if !child.ServerIdentity.ID.Equal(peerList.List[1].ID) {
   173  		t.Fatal("Parent of child of root is not the root...")
   174  	}
   175  }
   176  
   177  // Test marshal/unmarshaling of trees
   178  func TestUnMarshalTree(t *testing.T) {
   179  	names := genLocalhostPeerNames(10, 2000)
   180  	peerList := genRoster(tSuite, names)
   181  	// Generate two example topology
   182  	tree := peerList.GenerateBinaryTree()
   183  	treeBinary, err := tree.Marshal()
   184  
   185  	if err != nil {
   186  		t.Fatal("Error while marshaling:", err)
   187  	}
   188  	if len(treeBinary) == 0 {
   189  		t.Fatal("Marshaled tree is empty")
   190  	}
   191  
   192  	tree2, err := NewTreeFromMarshal(tSuite, treeBinary, peerList)
   193  	if err != nil {
   194  		t.Fatal("Error while unmarshaling:", err)
   195  	}
   196  	if !tree.Equal(tree2) {
   197  		log.Lvl3(tree, "\n", tree2)
   198  		t.Fatal("Tree and Tree2 are not identical")
   199  	}
   200  }
   201  
   202  func TestGetNode(t *testing.T) {
   203  	tree, _ := genLocalTree(10, 2000)
   204  	for _, tn := range tree.List() {
   205  		node := tree.Search(tn.ID)
   206  		if node == nil {
   207  			t.Fatal("Didn't find treeNode with id", tn.ID)
   208  		}
   209  	}
   210  }
   211  
   212  func TestBinaryTree(t *testing.T) {
   213  	tree, _ := genLocalTree(7, 2000)
   214  	root := tree.Root
   215  	if len(root.Children) != 2 {
   216  		t.Fatal("Not two children from root")
   217  	}
   218  	if len(root.Children[0].Children) != 2 {
   219  		t.Fatal("Not two children from first child")
   220  	}
   221  	if len(root.Children[1].Children) != 2 {
   222  		t.Fatal("Not two children from second child")
   223  	}
   224  	if !tree.IsBinary(root) {
   225  		t.Fatal("Tree should be binary")
   226  	}
   227  }
   228  
   229  func TestTreeNodeServerIdentityIndex(t *testing.T) {
   230  	names := genLocalhostPeerNames(13, 2000)
   231  	peerList := genRoster(tSuite, names)
   232  	tree := peerList.GenerateNaryTree(3)
   233  
   234  	ln := tree.List()
   235  	for _, node := range ln {
   236  		idx := -1
   237  		for i, e := range peerList.List {
   238  			if e.Equal(node.ServerIdentity) {
   239  				idx = i
   240  				break
   241  			}
   242  		}
   243  
   244  		if idx == -1 {
   245  			t.Fatal("Could not find the entity in the node")
   246  		}
   247  
   248  		if node.RosterIndex != idx {
   249  			t.Fatal("Index of entity do not correlate")
   250  		}
   251  	}
   252  }
   253  
   254  func TestNaryTree(t *testing.T) {
   255  	names := genLocalhostPeerNames(13, 2000)
   256  	peerList := genRoster(tSuite, names)
   257  	tree := peerList.GenerateNaryTree(3)
   258  	root := tree.Root
   259  	if len(root.Children) != 3 {
   260  		t.Fatal("Not three children from root")
   261  	}
   262  	if len(root.Children[0].Children) != 3 {
   263  		t.Fatal("Not three children from first child")
   264  	}
   265  	if len(root.Children[1].Children) != 3 {
   266  		t.Fatal("Not three children from second child")
   267  	}
   268  	if len(root.Children[2].Children) != 3 {
   269  		t.Fatal("Not three children from third child")
   270  	}
   271  	if !tree.IsNary(root, 3) {
   272  		t.Fatal("Tree should be 3-ary")
   273  	}
   274  
   275  	names = genLocalhostPeerNames(14, 0)
   276  	peerList = genRoster(tSuite, names)
   277  	tree = peerList.GenerateNaryTree(3)
   278  	root = tree.Root
   279  	if len(root.Children) != 3 {
   280  		t.Fatal("Not three children from root")
   281  	}
   282  	if len(root.Children[0].Children) != 3 {
   283  		t.Fatal("Not three children from first child")
   284  	}
   285  	if len(root.Children[1].Children) != 3 {
   286  		t.Fatal("Not three children from second child")
   287  	}
   288  	if len(root.Children[2].Children) != 3 {
   289  		t.Fatal("Not three children from third child")
   290  	}
   291  }
   292  
   293  func TestBigNaryTree(t *testing.T) {
   294  	names := genLocalDiffPeerNames(3, 2000)
   295  	peerList := genRoster(tSuite, names)
   296  	tree := peerList.GenerateBigNaryTree(3, 13)
   297  	root := tree.Root
   298  	log.Lvl2(tree.Dump())
   299  	if !tree.IsNary(root, 3) {
   300  		t.Fatal("Tree should be 3-ary")
   301  	}
   302  	for _, child := range root.Children {
   303  		if child.ServerIdentity.ID.Equal(root.ServerIdentity.ID) {
   304  			t.Fatal("Child should not have same identity as parent")
   305  		}
   306  		for _, c := range child.Children {
   307  			if c.ServerIdentity.ID.Equal(child.ServerIdentity.ID) {
   308  				t.Fatal("Child should not have same identity as parent")
   309  			}
   310  		}
   311  	}
   312  }
   313  
   314  func TestTreeIsColored(t *testing.T) {
   315  	names := genLocalPeerName(2, 2)
   316  	peerList := genRoster(tSuite, names)
   317  	tree := peerList.GenerateBigNaryTree(3, 13)
   318  	root := tree.Root
   319  	rootHost := root.ServerIdentity.Address.Host()
   320  	for _, child := range root.Children {
   321  		childHost := child.ServerIdentity.Address.NetworkAddress()
   322  		if rootHost == childHost {
   323  			t.Fatal("Child", childHost, "is the same as root", rootHost)
   324  		}
   325  	}
   326  }
   327  
   328  func TestBinaryTrees(t *testing.T) {
   329  	tree, _ := genLocalTree(1, 2000)
   330  	if !tree.IsBinary(tree.Root) {
   331  		t.Fatal("Tree with 1 node should be binary")
   332  	}
   333  	tree, _ = genLocalTree(2, 0)
   334  	if tree.IsBinary(tree.Root) {
   335  		t.Fatal("Tree with 2 nodes should NOT be binary")
   336  	}
   337  	tree, _ = genLocalTree(3, 0)
   338  	if !tree.IsBinary(tree.Root) {
   339  		t.Fatal("Tree with 3 nodes should be binary")
   340  	}
   341  	tree, _ = genLocalTree(4, 0)
   342  	if tree.IsBinary(tree.Root) {
   343  		t.Fatal("Tree with 4 nodes should NOT be binary")
   344  	}
   345  }
   346  
   347  func TestRosterIsUsed(t *testing.T) {
   348  	port := 2000
   349  	for hostExp := uint(2); hostExp < 8; hostExp++ {
   350  		hosts := (1 << hostExp) - 1
   351  		log.Lvl2("Trying tree with", hosts, "hosts")
   352  		names := make([]network.Address, hosts)
   353  		for i := 0; i < hosts; i++ {
   354  			add := "localhost" + strconv.Itoa(i/2) + ":" +
   355  				strconv.Itoa(port+i)
   356  			names[i] = network.NewAddress(network.Local, add)
   357  
   358  		}
   359  		peerList := genRoster(tSuite, names)
   360  		tree := peerList.GenerateBigNaryTree(2, hosts)
   361  		if !tree.UsesList() {
   362  			t.Fatal("Didn't find all ServerIdentities in tree", tree.Dump())
   363  		}
   364  	}
   365  }
   366  
   367  // Test whether the computation of the subtree aggregate public key is correct .
   368  func TestTreeComputeSubtreeAggregate(t *testing.T) {
   369  	names := genLocalDiffPeerNames(7, 2000)
   370  	entities := genRoster(tSuite, names)
   371  
   372  	// create tree
   373  	tree := entities.GenerateBinaryTree()
   374  
   375  	// manual check for 2nd level of tree (left part)
   376  	lchild := tree.Root.Children[0]
   377  	n2, n4, n5 := lchild.ServerIdentity, lchild.Children[0].ServerIdentity, lchild.Children[1].ServerIdentity
   378  	aggLeft := tSuite.Point().Add(n2.Public, n4.Public)
   379  	aggLeft = aggLeft.Add(aggLeft, n5.Public)
   380  	if !tree.Root.Children[0].PublicAggregateSubTree.Equal(aggLeft) {
   381  		t.Fatal("Aggregate is not correct for the left part")
   382  	}
   383  
   384  	// right part
   385  	rchild := tree.Root.Children[1]
   386  	n3, n4, n5 := rchild.ServerIdentity, rchild.Children[0].ServerIdentity, rchild.Children[1].ServerIdentity
   387  	aggRight := tSuite.Point().Add(n3.Public, n4.Public)
   388  	aggRight = aggRight.Add(aggRight, n5.Public)
   389  	if !tree.Root.Children[1].PublicAggregateSubTree.Equal(aggRight) {
   390  		t.Fatal("Aggregate is not correct for the right part")
   391  	}
   392  
   393  	// root part
   394  	agg := tSuite.Point().Add(aggRight, aggLeft)
   395  	agg = agg.Add(agg, tree.Root.ServerIdentity.Public)
   396  	if !tree.Root.PublicAggregateSubTree.Equal(agg) {
   397  		t.Fatal("Aggregate not correct for root")
   398  	}
   399  
   400  }
   401  
   402  func TestTree_BinaryMarshaler(t *testing.T) {
   403  	tree, _ := genLocalTree(5, 2000)
   404  	b, err := tree.BinaryMarshaler()
   405  	log.ErrFatal(err)
   406  	tree2 := &Tree{}
   407  	log.ErrFatal(tree2.BinaryUnmarshaler(tSuite, b))
   408  	if !tree.Equal(tree2) {
   409  		t.Fatal("Unmarshalled tree is not equal")
   410  	}
   411  	if tree.Root == tree2.Root {
   412  		t.Fatal("Address should not be equal")
   413  	}
   414  	log.Lvl1(tree.Dump())
   415  	log.Lvl1(tree2.Dump())
   416  }
   417  
   418  func TestTreeNode_SubtreeCount(t *testing.T) {
   419  	tree, _ := genLocalTree(15, 2000)
   420  	if tree.Root.SubtreeCount() != 14 {
   421  		t.Fatal("Not enough nodes in subtree-count")
   422  	}
   423  	if tree.Root.Children[0].SubtreeCount() != 6 {
   424  		t.Fatal("Not enough nodes in partial subtree")
   425  	}
   426  	if tree.Root.Children[0].Children[0].SubtreeCount() != 2 {
   427  		t.Fatal("Not enough nodes in partial subtree")
   428  	}
   429  	if tree.Root.Children[0].Children[0].Children[0].SubtreeCount() != 0 {
   430  		t.Fatal("Not enough nodes in partial subtree")
   431  	}
   432  }
   433  
   434  func TestRoster_GenerateNaryTree(t *testing.T) {
   435  	names := genLocalhostPeerNames(10, 2000)
   436  	peerList := genRoster(tSuite, names)
   437  	peerList.GenerateNaryTree(4)
   438  	for i := 0; i <= 9; i++ {
   439  		if !strings.Contains(peerList.List[i].Address.String(),
   440  			strconv.Itoa(2000+i)) {
   441  			t.Fatal("Missing port:", 2000+i, peerList.List)
   442  		}
   443  	}
   444  }
   445  
   446  func TestRoster_GenerateNaryTreeWithRoot_NewRoster(t *testing.T) {
   447  	names := genLocalhostPeerNames(10, 2000)
   448  	peerList := genRoster(tSuite, names)
   449  	tree := NewRoster(peerList.List[1:10]).GenerateNaryTreeWithRoot(2, peerList.List[0])
   450  	assert.Nil(t, tree)
   451  	for _, e := range peerList.List[1:len(peerList.List)] {
   452  		tree := peerList.NewRosterWithRoot(e).GenerateNaryTree(4)
   453  		for i := 0; i <= 9; i++ {
   454  			if !strings.Contains(peerList.List[i].Address.String(),
   455  				strconv.Itoa(2000+i)) {
   456  				t.Fatal("Missing port:", 2000+i, peerList.List)
   457  			}
   458  		}
   459  		if !tree.Root.ServerIdentity.ID.Equal(e.ID) {
   460  			t.Fatal("ServerIdentity", e, "is not root", tree.Dump())
   461  		}
   462  		if len(tree.List()) != 10 {
   463  			t.Fatal("Missing nodes")
   464  		}
   465  		if !tree.UsesList() {
   466  			t.Fatal("Not all elements are in the tree")
   467  		}
   468  		if tree.Roster.ID == peerList.ID {
   469  			t.Fatal("Generated tree should not be associated the receiver roster")
   470  		}
   471  	}
   472  }
   473  
   474  func TestRoster_GenerateNaryTreeWithRoot(t *testing.T) {
   475  	names := genLocalhostPeerNames(10, 2000)
   476  	peerList := genRoster(tSuite, names)
   477  	tree := NewRoster(peerList.List[1:10]).GenerateNaryTreeWithRoot(2, peerList.List[0])
   478  	assert.Nil(t, tree)
   479  	for _, e := range peerList.List {
   480  		tree := peerList.GenerateNaryTreeWithRoot(4, e)
   481  		for i := 0; i <= 9; i++ {
   482  			if !strings.Contains(peerList.List[i].Address.String(),
   483  				strconv.Itoa(2000+i)) {
   484  				t.Fatal("Missing port:", 2000+i, peerList.List)
   485  			}
   486  		}
   487  		if !tree.Root.ServerIdentity.ID.Equal(e.ID) {
   488  			t.Fatal("ServerIdentity", e, "is not root", tree.Dump())
   489  		}
   490  		if len(tree.List()) != 10 {
   491  			t.Fatal("Missing nodes")
   492  		}
   493  		if !tree.UsesList() {
   494  			t.Fatal("Not all elements are in the tree")
   495  		}
   496  		if tree.Roster.ID != peerList.ID {
   497  			t.Fatal("Generated tree should be associated with the receiver roster")
   498  		}
   499  	}
   500  }
   501  
   502  func TestRoster_Publics(t *testing.T) {
   503  	_, el := genLocalTree(1, 2000)
   504  	agg := el.Publics()
   505  	if !agg[0].Equal(el.List[0].Public) {
   506  		t.Fatal("Aggregate of 1 key is not correct")
   507  	}
   508  	_, el = genLocalTree(2, 0)
   509  	agg = el.Publics()
   510  	agg2 := el.List[0].Public.Add(el.List[0].Public,
   511  		el.List[1].Public)
   512  	if !agg[0].Equal(agg2) {
   513  		t.Fatal("Aggregate of 2 keys is not correct")
   514  	}
   515  }
   516  
   517  func TestRoster_IsRotation(t *testing.T) {
   518  	n := 5
   519  	_, tmpRoster := genLocalTree(n, 2000)
   520  	roster := NewRoster(tmpRoster.List)
   521  
   522  	// a roster that is missing an element is not a valid rotation
   523  	rosterShort := NewRoster(roster.List[1:])
   524  	// a roster with the final two elements swapped is not a valid rotation
   525  	rosterSwapped := NewRoster(append(roster.List[0:n-2], roster.List[n-1], roster.List[n-2]))
   526  	// the following are valid rotations
   527  	rosterRotated0 := NewRoster(append(roster.List[1:], roster.List[0]))
   528  	rosterRotated1 := NewRoster(append(rosterRotated0.List[1:], rosterRotated0.List[0]))
   529  
   530  	assert.False(t, roster.IsRotation(nil))
   531  	assert.False(t, roster.IsRotation(rosterShort))
   532  	assert.False(t, roster.IsRotation(rosterSwapped))
   533  	assert.True(t, roster.IsRotation(rosterRotated0))
   534  	assert.True(t, roster.IsRotation(rosterRotated1))
   535  }
   536  
   537  func TestRoster_Contains(t *testing.T) {
   538  	_, roster := genLocalTree(10, 2000)
   539  
   540  	pubs := roster.Publics()
   541  	require.True(t, roster.Contains(pubs))
   542  
   543  	for i := 0; i < 10; i++ {
   544  		rand.Shuffle(len(pubs), func(i, j int) {
   545  			pubs[i], pubs[j] = pubs[j], pubs[i]
   546  			require.True(t, roster.Contains(pubs))
   547  		})
   548  	}
   549  
   550  	require.False(t, roster.Contains(pubs[1:]))
   551  }
   552  
   553  // Checks that you can concatenate two rosters together
   554  // without duplicates
   555  func TestRoster_Concat(t *testing.T) {
   556  	_, roster := genLocalTree(10, 2000)
   557  
   558  	r1 := NewRoster(roster.List[:7])
   559  	r2 := NewRoster(roster.List[2:])
   560  
   561  	r := r1.Concat(r2.List...)
   562  	require.Equal(t, 10, len(r.List))
   563  	require.True(t, r.Contains(roster.Publics()))
   564  
   565  	r = r1.Concat()
   566  	require.Equal(t, len(r1.List), len(r.List))
   567  }
   568  
   569  func TestTreeNode_AggregatePublic(t *testing.T) {
   570  	tree, el := genLocalTree(7, 2000)
   571  	agg := el.Aggregate
   572  	root := tree.Root
   573  	aggRoot := root.AggregatePublic(tSuite)
   574  	assert.True(t, aggRoot.Equal(agg))
   575  
   576  	rootPub := tree.Root.ServerIdentity.Public
   577  	aggChild1 := tree.Root.Children[0].AggregatePublic(tSuite)
   578  	aggChild2 := tree.Root.Children[1].AggregatePublic(tSuite)
   579  
   580  	assert.True(t, aggChild1.Add(aggChild1, aggChild2).
   581  		Add(aggChild1, rootPub).Equal(aggRoot))
   582  
   583  	for i := 0; i < 4; i++ {
   584  		leaf := tree.Root.Children[i%2].Children[i/2]
   585  		assert.True(t, leaf.AggregatePublic(tSuite).Equal(leaf.ServerIdentity.Public))
   586  	}
   587  }
   588  
   589  // BenchmarkTreeMarshal will be the benchmark for the conversion between TreeMarshall and Tree
   590  func BenchmarkTreeMarshal(b *testing.B) {
   591  	tree, _ := genLocalTree(1000, 0)
   592  	t, _ := tree.BinaryMarshaler()
   593  	b.ResetTimer()
   594  	for i := 0; i < b.N; i++ {
   595  		tree.BinaryUnmarshaler(tSuite, t)
   596  	}
   597  }
   598  
   599  // BenchmarkMakeTree will time the amount of time it will take to make the tree
   600  func BenchmarkMakeTree(b *testing.B) {
   601  	tree, _ := genLocalTree(1000, 0)
   602  	el := tree.Roster
   603  	T := tree.MakeTreeMarshal()
   604  	b.ResetTimer()
   605  	for i := 0; i < b.N; i++ {
   606  		T.MakeTree(el)
   607  	}
   608  }
   609  
   610  // BenchmarkUnmarshalRegisteredType will time the amout it takes to perform the UnmarshalRegisteredType
   611  func BenchmarkUnmarshalRegisteredType(b *testing.B) {
   612  	tree, _ := genLocalTree(1000, 0)
   613  	buf, _ := tree.BinaryMarshaler()
   614  	b.ResetTimer()
   615  	for i := 0; i < b.N; i++ {
   616  		_, _, _ = network.Unmarshal(buf, tSuite)
   617  	}
   618  }
   619  
   620  // BenchmarkBinaryMarshaller will time the binary marshaler in order to compare MarshalerRegisteredType(used within BinaryMarshaler) to the UnmarshalRegisteredType
   621  func BenchmarkBinaryMarshaler(b *testing.B) {
   622  	tree, _ := genLocalTree(1000, 0)
   623  	b.ResetTimer()
   624  	for i := 0; i < b.N; i++ {
   625  		tree.BinaryMarshaler()
   626  	}
   627  }
   628  
   629  // genLocalhostPeerNames will generate n localhost names with port indices starting from p
   630  func genLocalhostPeerNames(n, p int) []network.Address {
   631  	names := make([]network.Address, n)
   632  	for i := range names {
   633  		names[i] = network.NewAddress(network.Local, prefix+strconv.Itoa(p+i))
   634  	}
   635  	return names
   636  }
   637  
   638  // genLocalDiffPeerNames will generate n local0..n-1 names with port indices starting from p
   639  func genLocalDiffPeerNames(n, p int) []network.Address {
   640  	names := make([]network.Address, n)
   641  	for i := range names {
   642  		names[i] = network.NewTCPAddress("127.0.0." + strconv.Itoa(i) + ":2000")
   643  	}
   644  	return names
   645  }
   646  
   647  // genLocalPeerName takes
   648  // nbrLocal: number of different local host address should it generate
   649  // nbrPort: for each different local host address, how many addresses with
   650  // different port should it generate
   651  // ex: genLocalPeerName(2,2) => local1:2000,local1:2001, local2:2000,local2:2001
   652  func genLocalPeerName(nbrLocal, nbrPort int) []network.Address {
   653  	names := make([]network.Address, nbrLocal)
   654  	for i := range names {
   655  		names[i] = network.NewAddress(network.Local, "127.0.0."+strconv.Itoa(i)+":2000")
   656  	}
   657  	return names
   658  
   659  }
   660  
   661  // genRoster generates a Roster out of names
   662  func genRoster(suite network.Suite, names []network.Address) *Roster {
   663  	var ids []*network.ServerIdentity
   664  	for _, n := range names {
   665  		kp := key.NewKeyPair(suite)
   666  		ids = append(ids, network.NewServerIdentity(kp.Public, n))
   667  	}
   668  	return NewRoster(ids)
   669  }
   670  
   671  func genLocalTree(count, port int) (*Tree, *Roster) {
   672  	names := genLocalhostPeerNames(count, port)
   673  	peerList := genRoster(tSuite, names)
   674  	tree := peerList.GenerateBinaryTree()
   675  	return tree, peerList
   676  }