github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/cli/tests/test_network.py (about) 1 # Copyright 2017 Intel Corporation 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # ------------------------------------------------------------------------------ 15 import unittest 16 17 from sawtooth_cli.network_command.compare import build_fork_graph 18 from sawtooth_cli.network_command.compare import get_node_id_map 19 from sawtooth_cli.network_command.compare import get_tails 20 from sawtooth_cli.network_command.compare import print_summary 21 from sawtooth_cli.network_command.compare import print_table 22 from sawtooth_cli.network_command.compare import print_tree 23 from sawtooth_cli.network_command.fork_graph import SimpleBlock 24 25 26 def make_generator(collection): 27 for item in collection: 28 yield item 29 30 31 class TestNetworkCompare(unittest.TestCase): 32 def test_complex_graph(self): 33 """Test that building the fork graph works correctly for a complex 34 network state.""" 35 36 # -------PEER IDS------ 37 # NUM 0 1 2 3 4 38 chains_info = [ 39 (15, ['z', '', '', '', '']), 40 (14, ['y', '', '', '', '']), 41 (13, ['w', '', 'x', '', '']), 42 (12, ['t', '', 'u', '', 'v']), 43 (11, ['g', 'h', 'l', 'm', 's']), 44 (10, ['f', 'f', 'k', 'k', 'r']), 45 (9, ['e', 'e', 'j', 'j', 'q']), 46 (8, ['d', 'd', 'i', 'i', 'p']), 47 (7, ['c', 'c', 'c', 'c', 'o']), 48 (6, ['b', 'b', 'b', 'b', 'n']), 49 (5, ['a', 'a', 'a', 'a', 'a']), 50 (4, ['0', '0', '0', '0', '0']), 51 ] 52 53 chains = make_chains(chains_info) 54 55 tails, _ = get_tails(chains) 56 for tail in tails.values(): 57 self.assertEqual(tail[0].num, 11) 58 59 graph, _ = build_fork_graph(chains, tails) 60 self.assertEqual(graph.root.previous, '0') 61 self.assertEqual(graph.root.ident, 'a') 62 63 # How many checks should happen 64 expected_checks = sum(map( 65 lambda ci: sum(map( 66 lambda bi: 0 if (bi == '' or bi == '0') else 1, ci[1] 67 )), 68 chains_info)) 69 70 checks = [] 71 72 for block_num, _, siblings in graph.walk(): 73 expected = chains_info[-(block_num - 3)] 74 # Make sure we did the math right in this test 75 assert expected[0] == block_num 76 expected = expected[1] 77 78 # `expected` contains a list of block ids, where the index is the 79 # peer and the at that index is the block that peer should have 80 for block_id, nodes in siblings.items(): 81 # Make sure none of the null strings were added 82 self.assertNotEqual(block_id, '') 83 84 for node in nodes: 85 self.assertEqual(block_id, expected[node]) 86 checks.append(block_id) 87 88 self.assertEqual(len(checks), expected_checks) 89 90 node_id_map = get_node_id_map([], len(tails)) 91 tails = list(map(lambda item: item[1], sorted(tails.items()))) 92 93 print_table(graph, tails, node_id_map) 94 print() 95 96 print_tree(graph, tails, node_id_map) 97 print() 98 99 def test_simple_graph(self): 100 """Test that building the fork graph works correctly for a simple 101 network state.""" 102 103 chains = { 104 i: make_generator(chain) 105 for i, chain in enumerate(( 106 [SimpleBlock(19, '19', '18')], 107 [SimpleBlock(19, '19', '18')], 108 [SimpleBlock(19, '19', '18')], 109 )) 110 } 111 112 tails, _ = get_tails(chains) 113 graph, _ = build_fork_graph(chains, tails) 114 115 self.assertEqual(graph.root.previous, '18') 116 self.assertEqual(graph.root.ident, '19') 117 118 def test_tails_communication_error(self): 119 # -------PEER IDS------ 120 # NUM 0 1 2 3 4 121 chains_info = [ 122 (15, ['z', '', '', '', '']), 123 (14, ['y', '', '', '', '']), 124 (13, ['w', '', 'x', '', '']), 125 (12, ['t', '', 'u', '', 'v']), 126 (11, ['g', '', 'l', '', 's']), 127 ] 128 chains = make_chains(chains_info) 129 130 tails, errors = get_tails(chains) 131 for _, tail in tails.items(): 132 self.assertEqual(tail[0].num, 12) 133 self.assertEqual(errors, [1, 3]) 134 135 def test_graph_communication_error(self): 136 # -------PEER IDS------ 137 # NUM 0 1 2 3 4 138 good_chains_info = [ 139 (8, ['d', 'd', 'i', 'i', 'p']), 140 (7, ['c', 'c', 'c', 'c', 'o']), 141 ] 142 bad_chains_info = [ 143 (6, ['b', 'b', '', 'b', 'n']), 144 (5, ['a', 'a', '', 'a', '']), 145 (4, ['0', '0', '', '0', '']), 146 ] 147 good_chains = make_chains(good_chains_info) 148 bad_chains = make_chains(bad_chains_info) 149 150 tails, _ = get_tails(good_chains) 151 graph, errors = build_fork_graph(bad_chains, tails) 152 self.assertEqual(errors, [2, 4]) 153 154 node_id_map = get_node_id_map(errors, len(good_chains)) 155 tails = list(map( 156 lambda item: item[1], 157 filter( 158 lambda item: item[0] not in errors, 159 sorted(tails.items())))) 160 print_summary(graph, tails, node_id_map) 161 162 163 def make_chains(chains_info): 164 chains = [[] for _ in chains_info[0][1]] 165 for i, num_ids in enumerate(chains_info[:-1]): 166 num, ids = num_ids 167 for j, ident in enumerate(ids): 168 if ident != '': 169 next_chain_info = chains_info[i + 1] 170 previous = next_chain_info[1][j] 171 block = SimpleBlock(num, ident, previous) 172 chains[j].append(block) 173 chains = { 174 i: make_generator(chain) 175 for i, chain in enumerate(chains) 176 } 177 return chains