def test_persisting_a_consensus(self, query_mock, open_mock, parse_file_mock, stdout_mock): def tutorial_example_2(): from stem.descriptor import DocumentHandler, parse_file consensus = next( parse_file( '/tmp/descriptor_dump', descriptor_type='network-status-consensus-3 1.0', document_handler=DocumentHandler.DOCUMENT, )) for fingerprint, relay in consensus.routers.items(): print('%s: %s' % (fingerprint, relay.nickname)) network_status = get_network_status_document_v3( routers=(get_router_status_entry_v3(), )) query_mock().run.return_value = [network_status] parse_file_mock.return_value = itertools.cycle([network_status]) exec_documentation_example('persisting_a_consensus.py') exec_documentation_example('persisting_a_consensus_with_parse_file.py') self.assertEqual(PERSISTING_A_CONSENSUS_OUTPUT, stdout_mock.getvalue()) if os.path.exists('/tmp/descriptor_dump'): os.remove('/tmp/descriptor_dump')
def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock): downloader_mock().get_consensus.return_value = [RouterStatusEntryV2.create({ 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', })] exec_documentation_example('current_descriptors.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock): downloader_mock().get_consensus().run.return_value = [RouterStatusEntryV2.create({ 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', })] exec_documentation_example('current_descriptors.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_list_circuits(self, from_port_mock, stdout_mock): path_1 = ('B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C', 'ByTORAndTheSnowDog') path_2 = ('0DD9935C5E939CFA1E07B8DDA6D91C1A2A9D9338', 'afo02') path_3 = ('DB3B1CFBD3E4D97B84B548ADD5B9A31451EEC4CC', 'edwardsnowden3') path_4 = ('EC01CB4766BADC1611678555CE793F2A7EB2D723', 'sprockets') path_5 = ('9EA317EECA56BDF30CAEB208A253FB456EDAB1A0', 'bolobolo1') path_6 = ('00C2C2A16AEDB51D5E5FB7D6168FC66B343D822F', 'ph3x') path_7 = ('65242C91BFF30F165DA4D132C81A9EBA94B71D62', 'torexit16') circuit_4 = _get_circ_event(4, 'BUILT', path_1, path_2, path_3, 'GENERAL') circuit_6 = _get_circ_event(6, 'BUILT', path_1, path_4, path_5, 'GENERAL') circuit_10 = _get_circ_event(10, 'BUILT', path_1, path_6, path_7, 'GENERAL') controller = from_port_mock().__enter__() controller.get_circuits.return_value = [circuit_4, circuit_6, circuit_10] controller.get_network_status.side_effect = lambda fingerprint, *args: { path_1[0]: _get_router_status('173.209.180.61'), path_2[0]: _get_router_status('87.238.194.176'), path_3[0]: _get_router_status('109.163.234.10'), path_4[0]: _get_router_status('46.165.197.96'), path_5[0]: _get_router_status('96.47.226.20'), path_6[0]: _get_router_status('86.59.119.83'), path_7[0]: _get_router_status('176.67.169.171') }[fingerprint] exec_documentation_example('list_circuits.py') self.assert_equal_unordered(LIST_CIRCUITS_OUTPUT, stdout_mock.getvalue())
def test_list_circuits(self, from_port_mock, stdout_mock): path_1 = ('B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C', 'ByTORAndTheSnowDog') path_2 = ('0DD9935C5E939CFA1E07B8DDA6D91C1A2A9D9338', 'afo02') path_3 = ('DB3B1CFBD3E4D97B84B548ADD5B9A31451EEC4CC', 'edwardsnowden3') path_4 = ('EC01CB4766BADC1611678555CE793F2A7EB2D723', 'sprockets') path_5 = ('9EA317EECA56BDF30CAEB208A253FB456EDAB1A0', 'bolobolo1') path_6 = ('00C2C2A16AEDB51D5E5FB7D6168FC66B343D822F', 'ph3x') path_7 = ('65242C91BFF30F165DA4D132C81A9EBA94B71D62', 'torexit16') circuit_4 = _get_circ_event(4, 'BUILT', path_1, path_2, path_3, 'GENERAL') circuit_6 = _get_circ_event(6, 'BUILT', path_1, path_4, path_5, 'GENERAL') circuit_10 = _get_circ_event(10, 'BUILT', path_1, path_6, path_7, 'GENERAL') controller = from_port_mock().__enter__() controller.get_circuits.return_value = [ circuit_4, circuit_6, circuit_10 ] controller.get_network_status.side_effect = lambda fingerprint, *args: { path_1[0]: _get_router_status('173.209.180.61'), path_2[0]: _get_router_status('87.238.194.176'), path_3[0]: _get_router_status('109.163.234.10'), path_4[0]: _get_router_status('46.165.197.96'), path_5[0]: _get_router_status('96.47.226.20'), path_6[0]: _get_router_status('86.59.119.83'), path_7[0]: _get_router_status('176.67.169.171') }[fingerprint] exec_documentation_example('list_circuits.py') self.assertCountEqual(LIST_CIRCUITS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
def test_persisting_a_consensus(self, query_mock, parse_file_mock, stdout_mock): def tutorial_example_2(): from stem.descriptor import DocumentHandler, parse_file consensus = next( parse_file( '/tmp/descriptor_dump', descriptor_type='network-status-consensus-3 1.0', document_handler=DocumentHandler.DOCUMENT, )) for fingerprint, relay in consensus.routers.items(): print('%s: %s' % (fingerprint, relay.nickname)) network_status = NetworkStatusDocumentV3.create( routers=(RouterStatusEntryV3.create({ 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', }), )) query_mock().run.return_value = [network_status] parse_file_mock.return_value = itertools.cycle([network_status]) exec_documentation_example('persisting_a_consensus.py') exec_documentation_example('persisting_a_consensus_with_parse_file.py') self.assertEqual(PERSISTING_A_CONSENSUS_OUTPUT, stdout_mock.getvalue()) if os.path.exists('/tmp/descriptor_dump'): os.remove('/tmp/descriptor_dump')
def test_votes_by_bandwidth_authorities(self, query_mock, get_authorities_mock, stdout_mock): directory_values = [ DIRECTORY_AUTHORITIES['gabelmoo'], DIRECTORY_AUTHORITIES['tor26'], DIRECTORY_AUTHORITIES['moria1'], DIRECTORY_AUTHORITIES['maatuska'], ] directory_values[0].address = '131.188.40.189' get_authorities_mock().values.return_value = directory_values entry_with_measurement = get_router_status_entry_v3({'w': 'Bandwidth=1 Measured=1'}) entry_without_measurement = get_router_status_entry_v3() query1 = Mock() query1.download_url = 'http://131.188.40.189:80/tor/status-vote/current/authority' query1.run.return_value = [entry_with_measurement] * 5935 + [entry_without_measurement] * 1332 query2 = Mock() query2.download_url = 'http://86.59.21.38:80/tor/status-vote/current/authority' query2.run.return_value = [entry_with_measurement] * 5735 + [entry_without_measurement] * 1690 query3 = Mock() query3.download_url = 'http://128.31.0.39:9131/tor/status-vote/current/authority' query3.run.return_value = [entry_with_measurement] * 6647 + [entry_without_measurement] * 625 query4 = Mock() query4.download_url = 'http://171.25.193.9:443/tor/status-vote/current/authority' query4.run.return_value = [entry_with_measurement] * 6313 + [entry_without_measurement] * 1112 query_mock.side_effect = [query1, query2, query3, query4] exec_documentation_example('votes_by_bandwidth_authorities.py') self.assert_equal_unordered(VOTES_BY_BANDWIDTH_AUTHORITIES_OUTPUT, stdout_mock.getvalue())
def test_votes_by_bandwidth_authorities(self, query_mock, authorities_mock, stdout_mock): directory_values = [ DIRECTORY_AUTHORITIES['gabelmoo'], DIRECTORY_AUTHORITIES['moria1'], DIRECTORY_AUTHORITIES['maatuska'], ] directory_values[0].address = '131.188.40.189' authorities_mock().values.return_value = directory_values entry_with_measurement = RouterStatusEntryV3.create({'w': 'Bandwidth=1 Measured=1'}) entry_without_measurement = RouterStatusEntryV3.create() query1 = Mock() query1.download_url = 'http://131.188.40.189:80/tor/status-vote/current/authority' query1.run.return_value = [entry_with_measurement] * 5935 + [entry_without_measurement] * 1332 query2 = Mock() query2.download_url = 'http://128.31.0.39:9131/tor/status-vote/current/authority' query2.run.return_value = [entry_with_measurement] * 6647 + [entry_without_measurement] * 625 query3 = Mock() query3.download_url = 'http://171.25.193.9:443/tor/status-vote/current/authority' query3.run.return_value = [entry_with_measurement] * 6313 + [entry_without_measurement] * 1112 query_mock.side_effect = [query1, query2, query3] exec_documentation_example('votes_by_bandwidth_authorities.py') self.assertCountEqual(VOTES_BY_BANDWIDTH_AUTHORITIES_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
def test_mirror_mirror_on_the_wall_4(self, reader_mock, stdout_mock): reader = reader_mock().__enter__() reader.__iter__.return_value = iter( [mocking.get_relay_server_descriptor()]) exec_documentation_example('past_descriptors.py') self.assertEqual('found relay caerSidi (None)\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_2(self, from_port_mock, stdout_mock): controller = from_port_mock().__enter__() controller.get_network_statuses.return_value = [RouterStatusEntryV2.create({ 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', })] exec_documentation_example('descriptor_from_tor_control_socket.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_4(self, get_desc_mock, stdout_mock): get_desc_mock.return_value = iter([RelayDescriptor.create({ 'router': 'caerSidi 71.35.133.197 9001 0 0', 'fingerprint': '2C3C 4662 5698 B6D6 7DF3 2BC1 918A D3EE 1F99 06B1', }, exit_policy = ExitPolicy('accept *:*'), validate = False)]) exec_documentation_example('collector_reading.py') self.assertEqual(' caerSidi (2C3C46625698B6D67DF32BC1918AD3EE1F9906B1)\n', stdout_mock.getvalue())
def test_the_little_relay_that_could(self, from_port_mock, stdout_mock): controller = from_port_mock().__enter__() controller.get_info.side_effect = lambda arg: { 'traffic/read': '33406', 'traffic/written': '29649', }[arg] exec_documentation_example('hello_world.py') self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock): downloader_mock().get_consensus().run.return_value = [ mocking.get_router_status_entry_v2() ] exec_documentation_example('current_descriptors.py') self.assertEqual( 'found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_compare_flags(self, authorities_mock, query_mock, stdout_mock): authorities_mock().items.return_value = [ ('moria1', DIRECTORY_AUTHORITIES['moria1']), ('maatuska', DIRECTORY_AUTHORITIES['maatuska']) ] fingerprint = [ ('92FCB6748A40E6088E22FBAB943AB2DD743EA818', 'kvy2dIpA5giOIvurlDqy3XQ+qBg='), ('6871F682350BA931838C0EC1E4A23044DAE06A73', 'aHH2gjULqTGDjA7B5KIwRNrganM='), ('E2BB13AA2F6960CD93ABE5257A825687F3973C62', '4rsTqi9pYM2Tq+UleoJWh/OXPGI='), ('546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE', 'VGxU4qidiOB5TQSuy/Gsisnagd4='), ('DCAEC3D069DC39AAE43D13C8AF31B5645E05ED61', '3K7D0GncOarkPRPIrzG1ZF4F7WE='), ] entry = [ # entries for moria1 _get_router_status(fingerprint_base64=fingerprint[0][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[1][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[2][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[3][1]), _get_router_status(fingerprint_base64=fingerprint[4][1]), # entries for maatuska _get_router_status(fingerprint_base64=fingerprint[0][1]), _get_router_status(fingerprint_base64=fingerprint[1][1]), _get_router_status(fingerprint_base64=fingerprint[2][1]), _get_router_status(fingerprint_base64=fingerprint[3][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[4][1], s_line=' '), ] query_mock().run.side_effect = [ [ NetworkStatusDocumentV3.create(routers=(entry[0], entry[1], entry[2], entry[3], entry[4])) ], [ NetworkStatusDocumentV3.create(routers=(entry[5], entry[6], entry[7], entry[8], entry[9])) ], ] exec_documentation_example('compare_flags.py') self.assertCountEqual(COMPARE_FLAGS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
def test_mirror_mirror_on_the_wall_4(self, reader_mock, stdout_mock): reader = reader_mock().__enter__() reader.__iter__.return_value = iter([ RelayDescriptor.create( {'router': 'caerSidi 71.35.133.197 9001 0 0'}) ]) exec_documentation_example('past_descriptors.py') self.assertEqual('found relay caerSidi (None)\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_2(self, from_port_mock, stdout_mock): controller = from_port_mock().__enter__() controller.get_network_statuses.return_value = [ mocking.get_router_status_entry_v2() ] exec_documentation_example('descriptor_from_tor_control_socket.py') self.assertEqual( 'found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_outdated_relays(self, downloader_mock, stdout_mock): downloader_mock().get_server_descriptors.return_value = [ get_relay_server_descriptor({'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}), get_relay_server_descriptor({'platform': 'node-Tor 0.1.0 on Linux x86_64'}), get_relay_server_descriptor({'opt': 'contact Random Person [email protected]', 'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}), get_relay_server_descriptor({'opt': 'contact Sambuddha Basu', 'platform': 'node-Tor 0.1.0 on Linux x86_64'}), ] exec_documentation_example('outdated_relays.py') self.assert_equal_unordered(OUTDATED_RELAYS_OUTPUT, stdout_mock.getvalue())
def test_outdated_relays(self, downloader_mock, stdout_mock): downloader_mock().get_server_descriptors.return_value = [ RelayDescriptor.create({'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}), RelayDescriptor.create({'platform': 'node-Tor 0.1.0 on Linux x86_64'}), RelayDescriptor.create({'opt': 'contact Random Person [email protected]', 'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}), RelayDescriptor.create({'opt': 'contact Sambuddha Basu', 'platform': 'node-Tor 0.1.0 on Linux x86_64'}), ] exec_documentation_example('outdated_relays.py') self.assertCountEqual(OUTDATED_RELAYS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
def test_compare_flags(self, get_authorities_mock, query_mock, stdout_mock): if stem.prereq._is_python_26(): # example imports OrderedDict from collections which doesn't work under # python 2.6 test.runner.skip(self, "(example doesn't support python 2.6)") return get_authorities_mock().items.return_value = [('moria1', DIRECTORY_AUTHORITIES['moria1']), ('maatuska', DIRECTORY_AUTHORITIES['maatuska'])] fingerprint = [ ('92FCB6748A40E6088E22FBAB943AB2DD743EA818', 'kvy2dIpA5giOIvurlDqy3XQ+qBg='), ('6871F682350BA931838C0EC1E4A23044DAE06A73', 'aHH2gjULqTGDjA7B5KIwRNrganM='), ('E2BB13AA2F6960CD93ABE5257A825687F3973C62', '4rsTqi9pYM2Tq+UleoJWh/OXPGI='), ('546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE', 'VGxU4qidiOB5TQSuy/Gsisnagd4='), ('DCAEC3D069DC39AAE43D13C8AF31B5645E05ED61', '3K7D0GncOarkPRPIrzG1ZF4F7WE='), ] entry = [ # entries for moria1 _get_router_status(fingerprint_base64 = fingerprint[0][1], s_line = ' '), _get_router_status(fingerprint_base64 = fingerprint[1][1], s_line = ' '), _get_router_status(fingerprint_base64 = fingerprint[2][1], s_line = ' '), _get_router_status(fingerprint_base64 = fingerprint[3][1]), _get_router_status(fingerprint_base64 = fingerprint[4][1]), # entries for maatuska _get_router_status(fingerprint_base64 = fingerprint[0][1]), _get_router_status(fingerprint_base64 = fingerprint[1][1]), _get_router_status(fingerprint_base64 = fingerprint[2][1]), _get_router_status(fingerprint_base64 = fingerprint[3][1], s_line = ' '), _get_router_status(fingerprint_base64 = fingerprint[4][1], s_line = ' '), ] query_mock().run.side_effect = [ [get_network_status_document_v3(routers = (entry[0], entry[1], entry[2], entry[3], entry[4]))], [get_network_status_document_v3(routers = (entry[5], entry[6], entry[7], entry[8], entry[9]))], ] exec_documentation_example('compare_flags.py') self.assert_equal_unordered(COMPARE_FLAGS_OUTPUT, stdout_mock.getvalue())
def test_persisting_a_consensus(self, query_mock, open_mock, parse_file_mock, stdout_mock): def tutorial_example_2(): from stem.descriptor import DocumentHandler, parse_file consensus = next(parse_file( '/tmp/descriptor_dump', descriptor_type = 'network-status-consensus-3 1.0', document_handler = DocumentHandler.DOCUMENT, )) for fingerprint, relay in consensus.routers.items(): print('%s: %s' % (fingerprint, relay.nickname)) network_status = get_network_status_document_v3(routers = (get_router_status_entry_v3(),)) query_mock().run.return_value = [network_status] parse_file_mock.return_value = itertools.cycle([network_status]) exec_documentation_example('persisting_a_consensus.py') exec_documentation_example('persisting_a_consensus_with_parse_file.py') self.assertEqual(PERSISTING_A_CONSENSUS_OUTPUT, stdout_mock.getvalue())
def test_outdated_relays(self, downloader_mock, stdout_mock): downloader_mock().get_server_descriptors.return_value = [ get_relay_server_descriptor( {'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}), get_relay_server_descriptor( {'platform': 'node-Tor 0.1.0 on Linux x86_64'}), get_relay_server_descriptor({ 'opt': 'contact Random Person [email protected]', 'platform': 'node-Tor 0.2.3.0 on Linux x86_64' }), get_relay_server_descriptor({ 'opt': 'contact Sambuddha Basu', 'platform': 'node-Tor 0.1.0 on Linux x86_64' }), ] exec_documentation_example('outdated_relays.py') self.assert_equal_unordered(OUTDATED_RELAYS_OUTPUT, stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock): downloader_mock().get_consensus().run.return_value = [mocking.get_router_status_entry_v2()] exec_documentation_example('current_descriptors.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_2(self, from_port_mock, stdout_mock): controller = from_port_mock().__enter__() controller.get_network_statuses.return_value = [mocking.get_router_status_entry_v2()] exec_documentation_example('descriptor_from_tor_control_socket.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_4(self, reader_mock, stdout_mock): reader = reader_mock().__enter__() reader.__iter__.return_value = iter([mocking.get_relay_server_descriptor()]) exec_documentation_example('past_descriptors.py') self.assertEqual('found relay caerSidi (None)\n', stdout_mock.getvalue())
def test_compare_flags(self, get_authorities_mock, query_mock, stdout_mock): if stem.prereq._is_python_26(): # example imports OrderedDict from collections which doesn't work under # python 2.6 test.runner.skip(self, "(example doesn't support python 2.6)") return get_authorities_mock().items.return_value = [ ('moria1', DIRECTORY_AUTHORITIES['moria1']), ('maatuska', DIRECTORY_AUTHORITIES['maatuska']) ] fingerprint = [ ('92FCB6748A40E6088E22FBAB943AB2DD743EA818', 'kvy2dIpA5giOIvurlDqy3XQ+qBg='), ('6871F682350BA931838C0EC1E4A23044DAE06A73', 'aHH2gjULqTGDjA7B5KIwRNrganM='), ('E2BB13AA2F6960CD93ABE5257A825687F3973C62', '4rsTqi9pYM2Tq+UleoJWh/OXPGI='), ('546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE', 'VGxU4qidiOB5TQSuy/Gsisnagd4='), ('DCAEC3D069DC39AAE43D13C8AF31B5645E05ED61', '3K7D0GncOarkPRPIrzG1ZF4F7WE='), ] entry = [ # entries for moria1 _get_router_status(fingerprint_base64=fingerprint[0][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[1][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[2][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[3][1]), _get_router_status(fingerprint_base64=fingerprint[4][1]), # entries for maatuska _get_router_status(fingerprint_base64=fingerprint[0][1]), _get_router_status(fingerprint_base64=fingerprint[1][1]), _get_router_status(fingerprint_base64=fingerprint[2][1]), _get_router_status(fingerprint_base64=fingerprint[3][1], s_line=' '), _get_router_status(fingerprint_base64=fingerprint[4][1], s_line=' '), ] query_mock().run.side_effect = [ [ get_network_status_document_v3(routers=(entry[0], entry[1], entry[2], entry[3], entry[4])) ], [ get_network_status_document_v3(routers=(entry[5], entry[6], entry[7], entry[8], entry[9])) ], ] exec_documentation_example('compare_flags.py') self.assert_equal_unordered(COMPARE_FLAGS_OUTPUT, stdout_mock.getvalue())
def test_mirror_mirror_on_the_wall_4(self, reader_mock, stdout_mock): reader = reader_mock().__enter__() reader.__iter__.return_value = iter([RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 9001 0 0'})]) exec_documentation_example('past_descriptors.py') self.assertEqual('found relay caerSidi (None)\n', stdout_mock.getvalue())