def test_the_little_relay_that_could(self): def tutorial_example(): from stem.control import Controller with Controller.from_port(control_port = 9051) as controller: controller.authenticate() # provide the password here if you set one bytes_read = controller.get_info("traffic/read") bytes_written = controller.get_info("traffic/written") print "My Tor relay has read %s bytes and written %s." % (bytes_read, bytes_written) controller = mocking.get_object(Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_info': mocking.return_for_args({ ('traffic/read',): '33406', ('traffic/written',): '29649', }, is_method = True), }) mocking.mock( Controller.from_port, mocking.return_value(controller), target_module = Controller, is_static = True, ) tutorial_example() self.assertEqual("My Tor relay has read 33406 bytes and written 29649.\n", self.stdout.getvalue())
def test_example(self): """ Exercises the add_event_listener() pydoc example, but without the sleep(). """ import time from stem.control import Controller, EventType def print_bw(event): msg = "sent: %i, received: %i" % (event.written, event.read) self.assertEqual("sent: 25, received: 15", msg) def event_sender(): for index in xrange(3): print_bw(_get_event("650 BW 15 25")) time.sleep(0.05) controller = mocking.get_object( Controller, {"authenticate": mocking.no_op(), "add_event_listener": mocking.no_op()} ) controller.authenticate() controller.add_event_listener(print_bw, EventType.BW) events_thread = threading.Thread(target=event_sender) events_thread.start() time.sleep(0.2) events_thread.join()
def test_event_listening(self): """ Exercises the add_event_listener and remove_event_listener methods. """ # set up for failure to create any events mocking.mock_method(Controller, "is_authenticated", mocking.return_true()) mocking.mock_method(Controller, "_attach_listeners", mocking.return_value(([], []))) mocking.mock_method( Controller, "get_version", mocking.return_value(stem.version.Version('0.1.0.14'))) self.assertRaises(InvalidRequest, self.controller.add_event_listener, mocking.no_op(), EventType.BW) # set up to only fail newer events mocking.mock_method( Controller, "get_version", mocking.return_value(stem.version.Version('0.2.0.35'))) # EventType.BW is one of the earliest events self.controller.add_event_listener(mocking.no_op(), EventType.BW) # EventType.SIGNAL was added in tor version 0.2.3.1-alpha self.assertRaises(InvalidRequest, self.controller.add_event_listener, mocking.no_op(), EventType.SIGNAL)
def test_example(self): """ Exercises the add_event_listener() pydoc example, but without the sleep(). """ import time from stem.control import Controller, EventType def print_bw(event): msg = "sent: %i, received: %i" % (event.written, event.read) self.assertEqual("sent: 25, received: 15", msg) def event_sender(): for index in xrange(3): print_bw(_get_event("650 BW 15 25")) time.sleep(0.05) controller = mocking.get_object( Controller, { 'authenticate': mocking.no_op(), 'add_event_listener': mocking.no_op(), }) controller.authenticate() controller.add_event_listener(print_bw, EventType.BW) events_thread = threading.Thread(target=event_sender) events_thread.start() time.sleep(0.2) events_thread.join()
def test_mirror_mirror_on_the_wall_1(self): def tutorial_example(): from stem.control import Controller with Controller.from_port(control_port=9051) as controller: controller.authenticate() for desc in controller.get_network_statuses(): print "found relay %s (%s)" % (desc.nickname, desc.fingerprint) controller = mocking.get_object( Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_network_statuses': mocking.return_value([mocking.get_router_status_entry_v2()], ), }) mocking.mock( Controller.from_port, mocking.return_value(controller), target_module=Controller, is_static=True, ) tutorial_example() self.assertEqual( "found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", self.stdout.getvalue())
def test_mirror_mirror_on_the_wall_1(self): def tutorial_example(): from stem.control import Controller with Controller.from_port(control_port = 9051) as controller: controller.authenticate() for desc in controller.get_network_statuses(): print "found relay %s (%s)" % (desc.nickname, desc.fingerprint) controller = mocking.get_object(Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_network_statuses': mocking.return_value( [mocking.get_router_status_entry_v2()], ), }) mocking.mock( Controller.from_port, mocking.return_value(controller), target_module = Controller, is_static = True, ) tutorial_example() self.assertEqual("found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", self.stdout.getvalue())
def test_mirror_mirror_on_the_wall_4(self): def tutorial_example(): from stem.control import Controller from stem.util import str_tools # provides a mapping of observed bandwidth to the relay nicknames def get_bw_to_relay(): bw_to_relay = {} with Controller.from_port(control_port = 9051) as controller: controller.authenticate() for desc in controller.get_server_descriptors(): if desc.exit_policy.is_exiting_allowed(): bw_to_relay.setdefault(desc.observed_bandwidth, []).append(desc.nickname) return bw_to_relay # prints the top fifteen relays bw_to_relay = get_bw_to_relay() count = 1 for bw_value in sorted(bw_to_relay.keys(), reverse = True): for nickname in bw_to_relay[bw_value]: print "%i. %s (%s/s)" % (count, nickname, str_tools.get_size_label(bw_value, 2)) count += 1 if count > 15: return exit_descriptor = mocking.get_relay_server_descriptor({ 'router': 'speedyexit 149.255.97.109 9001 0 0' }, content = True).replace(b'reject *:*', b'accept *:*') exit_descriptor = mocking.sign_descriptor_content(exit_descriptor) exit_descriptor = RelayDescriptor(exit_descriptor) controller = mocking.get_object(Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_server_descriptors': mocking.return_value([ exit_descriptor, mocking.get_relay_server_descriptor(), # non-exit exit_descriptor, exit_descriptor, ]) }) mocking.mock( Controller.from_port, mocking.return_value(controller), target_module = Controller, is_static = True, ) tutorial_example() self.assertEqual(MIRROR_MIRROR_OUTPUT, self.stdout.getvalue())
def test_event_listening(self): """ Exercises the add_event_listener and remove_event_listener methods. """ # set up for failure to create any events mocking.mock_method(Controller, "get_version", mocking.return_value(stem.version.Version('0.1.0.14'))) self.assertRaises(InvalidRequest, self.controller.add_event_listener, mocking.no_op(), EventType.BW) # set up to only fail newer events mocking.mock_method(Controller, "get_version", mocking.return_value(stem.version.Version('0.2.0.35'))) # EventType.BW is one of the earliest events self.controller.add_event_listener(mocking.no_op(), EventType.BW) # EventType.SIGNAL was added in tor version 0.2.3.1-alpha self.assertRaises(InvalidRequest, self.controller.add_event_listener, mocking.no_op(), EventType.SIGNAL)
def test_the_little_relay_that_could(self): def tutorial_example(): from stem.control import Controller with Controller.from_port(control_port=9051) as controller: controller.authenticate( ) # provide the password here if you set one bytes_read = controller.get_info("traffic/read") bytes_written = controller.get_info("traffic/written") print "My Tor relay has read %s bytes and written %s." % ( bytes_read, bytes_written) controller = mocking.get_object( Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_info': mocking.return_for_args( { ('traffic/read', ): '33406', ('traffic/written', ): '29649', }, is_method=True), }) mocking.mock( Controller.from_port, mocking.return_value(controller), target_module=Controller, is_static=True, ) tutorial_example() self.assertEqual( "My Tor relay has read 33406 bytes and written 29649.\n", self.stdout.getvalue())
def test_the_little_relay_that_could(self): from stem.control import Controller controller = mocking.get_object(Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_info': mocking.return_for_args({ 'traffic/read': '1234', 'traffic/written': '5678', }), }) controller.authenticate() bytes_read = controller.get_info("traffic/read") bytes_written = controller.get_info("traffic/written") expected_line = "My Tor relay has read 1234 bytes and written 5678." printed_line = "My Tor relay has read %s bytes and written %s." % (bytes_read, bytes_written) self.assertEqual(expected_line, printed_line) controller.close()
def test_the_little_relay_that_could(self): from stem.control import Controller controller = mocking.get_object(Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_info': mocking.return_for_args({ ('traffic/read',): '1234', ('traffic/written',): '5678', }, is_method = True), }) controller.authenticate() bytes_read = controller.get_info("traffic/read") bytes_written = controller.get_info("traffic/written") expected_line = "My Tor relay has read 1234 bytes and written 5678." printed_line = "My Tor relay has read %s bytes and written %s." % (bytes_read, bytes_written) self.assertEqual(expected_line, printed_line) controller.close()
def test_mirror_mirror_on_the_wall(self): from stem.descriptor.server_descriptor import RelayDescriptor from stem.descriptor.reader import DescriptorReader from stem.util import str_tools exit_descriptor = mocking.get_relay_server_descriptor({ 'router': 'speedyexit 149.255.97.109 9001 0 0' }, content = True).replace('reject *:*', 'accept *:*') exit_descriptor = mocking.sign_descriptor_content(exit_descriptor) exit_descriptor = RelayDescriptor(exit_descriptor) reader_wrapper = mocking.get_object(DescriptorReader, { '__enter__': lambda x: x, '__exit__': mocking.no_op(), '__iter__': mocking.return_value(iter(( exit_descriptor, mocking.get_relay_server_descriptor(), # non-exit exit_descriptor, exit_descriptor, ))) }) # provides a mapping of observed bandwidth to the relay nicknames def get_bw_to_relay(): bw_to_relay = {} with reader_wrapper as reader: for desc in reader: if desc.exit_policy.is_exiting_allowed(): bw_to_relay.setdefault(desc.observed_bandwidth, []).append(desc.nickname) return bw_to_relay # prints the top fifteen relays bw_to_relay = get_bw_to_relay() count = 1 for bw_value in sorted(bw_to_relay.keys(), reverse = True): for nickname in bw_to_relay[bw_value]: expected_line = "%i. speedyexit (102.13 KB/s)" % count printed_line = "%i. %s (%s/s)" % (count, nickname, str_tools.get_size_label(bw_value, 2)) self.assertEqual(expected_line, printed_line) count += 1 if count > 15: return self.assertEqual(4, count)
def setUp(self): self.stdout, self.stdout_real = StringIO.StringIO(), sys.stdout sys.stdout = self.stdout mocking.mock_method(RelayDescriptor, '_verify_digest', mocking.no_op())
def setUp(self): mock_method(RelayDescriptor, '_verify_digest', no_op())
def test_all_use_cases(self): """ Does basic validation that all valid use cases for the PROTOCOLINFO input and dependent functions result in either success or a AuthenticationFailed subclass being raised. """ # mute the logger for this test since otherwise the output is overwhelming stem_logger = log.get_logger() stem_logger.setLevel(log.logging_level(None)) # exceptions that the authentication functions are documented to raise all_auth_none_exc = (None, stem.connection.OpenAuthRejected(None)) all_auth_password_exc = (None, stem.connection.PasswordAuthRejected(None), stem.connection.IncorrectPassword(None)) all_auth_cookie_exc = (None, stem.connection.IncorrectCookieSize(None, None), stem.connection.UnreadableCookieFile(None, None), stem.connection.CookieAuthRejected(None, None), stem.connection.IncorrectCookieValue(None, None)) # authentication functions might raise a controller error when # 'suppress_ctl_errors' is False, so including those control_exc = ( stem.socket.ProtocolError(None), stem.socket.SocketError(None), stem.socket.SocketClosed(None)) all_auth_none_exc += control_exc all_auth_password_exc += control_exc all_auth_cookie_exc += control_exc for protocolinfo_auth_methods in _get_all_auth_method_combinations(): # protocolinfo input for the authenticate() call we'll be making protocolinfo_arg = mocking.get_protocolinfo_response( auth_methods = protocolinfo_auth_methods, cookie_path = "/tmp/blah", ) for auth_none_exc in all_auth_none_exc: for auth_password_exc in all_auth_password_exc: for auth_cookie_exc in all_auth_cookie_exc: # determine if the authenticate() call will succeed and mock each # of the authenticate_* function to raise its given exception expect_success = False auth_mocks = { stem.connection.AuthMethod.NONE: (stem.connection.authenticate_none, auth_none_exc), stem.connection.AuthMethod.PASSWORD: (stem.connection.authenticate_password, auth_password_exc), stem.connection.AuthMethod.COOKIE: (stem.connection.authenticate_cookie, auth_cookie_exc), } for auth_method in auth_mocks: auth_function, raised_exc = auth_mocks[auth_method] if not raised_exc: # Mocking this authentication method so it will succeed. If # it's among the protocolinfo methods then expect success. mocking.mock(auth_function, mocking.no_op()) expect_success |= auth_method in protocolinfo_auth_methods else: mocking.mock(auth_function, mocking.raise_exception(raised_exc)) if expect_success: stem.connection.authenticate(None, "blah", None, protocolinfo_arg) else: self.assertRaises(stem.connection.AuthenticationFailure, stem.connection.authenticate, None, "blah", None, protocolinfo_arg) # revert logging back to normal stem_logger.setLevel(log.logging_level(log.TRACE))
def setUp(self): mocking.mock(stem.connection.get_protocolinfo, mocking.no_op()) mocking.mock(stem.connection.authenticate_none, mocking.no_op()) mocking.mock(stem.connection.authenticate_password, mocking.no_op()) mocking.mock(stem.connection.authenticate_cookie, mocking.no_op())
def test_all_use_cases(self): """ Does basic validation that all valid use cases for the PROTOCOLINFO input and dependent functions result in either success or a AuthenticationFailed subclass being raised. """ # mute the logger for this test since otherwise the output is overwhelming stem_logger = log.get_logger() stem_logger.setLevel(log.logging_level(None)) # exceptions that the authentication functions are documented to raise all_auth_none_exc = (None, stem.connection.OpenAuthRejected(None)) all_auth_password_exc = ( None, stem.connection.PasswordAuthRejected(None), stem.connection.IncorrectPassword(None)) all_auth_cookie_exc = ( None, stem.connection.IncorrectCookieSize(None, False, None), stem.connection.UnreadableCookieFile(None, False, None), stem.connection.CookieAuthRejected(None, False, None), stem.connection.IncorrectCookieValue(None, False, None), stem.connection.UnrecognizedAuthChallengeMethod(None, None, None), stem.connection.AuthChallengeFailed(None, None), stem.connection.AuthSecurityFailure(None, None), stem.connection.InvalidClientNonce(None, None)) # authentication functions might raise a controller error when # 'suppress_ctl_errors' is False, so including those control_exc = ( stem.ProtocolError(None), stem.SocketError(None), stem.SocketClosed(None)) all_auth_none_exc += control_exc all_auth_password_exc += control_exc all_auth_cookie_exc += control_exc auth_method_combinations = mocking.get_all_combinations([ stem.connection.AuthMethod.NONE, stem.connection.AuthMethod.PASSWORD, stem.connection.AuthMethod.COOKIE, stem.connection.AuthMethod.SAFECOOKIE, stem.connection.AuthMethod.UNKNOWN, ], include_empty = True) for protocolinfo_auth_methods in auth_method_combinations: # protocolinfo input for the authenticate() call we'll be making protocolinfo_arg = mocking.get_protocolinfo_response( auth_methods = protocolinfo_auth_methods, cookie_path = "/tmp/blah", ) for auth_none_exc in all_auth_none_exc: for auth_password_exc in all_auth_password_exc: for auth_cookie_exc in all_auth_cookie_exc: # Determine if the authenticate() call will succeed and mock each # of the authenticate_* function to raise its given exception. # # This implementation is slightly inaccurate in a couple regards... # a. it raises safecookie exceptions from authenticate_cookie() # b. exceptions raised by authenticate_cookie() and # authenticate_safecookie() are always the same # # However, adding another loop for safe_cookie exceptions means # multiplying our runtime many fold. This exercises everything that # matters so the above inaccuracies seem fine. expect_success = False auth_mocks = { stem.connection.AuthMethod.NONE: (stem.connection.authenticate_none, auth_none_exc), stem.connection.AuthMethod.PASSWORD: (stem.connection.authenticate_password, auth_password_exc), stem.connection.AuthMethod.COOKIE: (stem.connection.authenticate_cookie, auth_cookie_exc), stem.connection.AuthMethod.SAFECOOKIE: (stem.connection.authenticate_safecookie, auth_cookie_exc), } for auth_method in auth_mocks: auth_function, raised_exc = auth_mocks[auth_method] if not raised_exc: # Mocking this authentication method so it will succeed. If # it's among the protocolinfo methods then expect success. mocking.mock(auth_function, mocking.no_op()) expect_success |= auth_method in protocolinfo_auth_methods else: mocking.mock(auth_function, mocking.raise_exception(raised_exc)) if expect_success: stem.connection.authenticate(None, "blah", None, protocolinfo_arg) else: self.assertRaises(stem.connection.AuthenticationFailure, stem.connection.authenticate, None, "blah", None, protocolinfo_arg) # revert logging back to normal stem_logger.setLevel(log.logging_level(log.TRACE))
def setUp(self): socket = stem.socket.ControlSocket() mocking.mock_method(Controller, "add_event_listener", mocking.no_op()) self.controller = Controller(socket) mocking.revert_mocking()
def test_mirror_mirror_on_the_wall_4(self): def tutorial_example(): from stem.control import Controller from stem.util import str_tools # provides a mapping of observed bandwidth to the relay nicknames def get_bw_to_relay(): bw_to_relay = {} with Controller.from_port(control_port=9051) as controller: controller.authenticate() for desc in controller.get_server_descriptors(): if desc.exit_policy.is_exiting_allowed(): bw_to_relay.setdefault(desc.observed_bandwidth, []).append(desc.nickname) return bw_to_relay # prints the top fifteen relays bw_to_relay = get_bw_to_relay() count = 1 for bw_value in sorted(bw_to_relay.keys(), reverse=True): for nickname in bw_to_relay[bw_value]: print "%i. %s (%s/s)" % ( count, nickname, str_tools.get_size_label(bw_value, 2)) count += 1 if count > 15: return exit_descriptor = mocking.get_relay_server_descriptor( { 'router': 'speedyexit 149.255.97.109 9001 0 0' }, content=True).replace(b'reject *:*', b'accept *:*') exit_descriptor = mocking.sign_descriptor_content(exit_descriptor) exit_descriptor = RelayDescriptor(exit_descriptor) controller = mocking.get_object( Controller, { 'authenticate': mocking.no_op(), 'close': mocking.no_op(), 'get_server_descriptors': mocking.return_value([ exit_descriptor, mocking.get_relay_server_descriptor(), # non-exit exit_descriptor, exit_descriptor, ]) }) mocking.mock( Controller.from_port, mocking.return_value(controller), target_module=Controller, is_static=True, ) tutorial_example() self.assertEqual(MIRROR_MIRROR_OUTPUT, self.stdout.getvalue())
def setUp(self): mocking.mock(stem.connection.get_protocolinfo, mocking.no_op()) mocking.mock(stem.connection.authenticate_none, mocking.no_op()) mocking.mock(stem.connection.authenticate_password, mocking.no_op()) mocking.mock(stem.connection.authenticate_cookie, mocking.no_op()) mocking.mock(stem.connection.authenticate_safecookie, mocking.no_op())
def test_all_use_cases(self): """ Does basic validation that all valid use cases for the PROTOCOLINFO input and dependent functions result in either success or a AuthenticationFailed subclass being raised. """ # mute the logger for this test since otherwise the output is overwhelming stem_logger = log.get_logger() stem_logger.setLevel(log.logging_level(None)) # exceptions that the authentication functions are documented to raise all_auth_none_exc = (None, stem.connection.OpenAuthRejected(None)) all_auth_password_exc = (None, stem.connection.PasswordAuthRejected(None), stem.connection.IncorrectPassword(None)) all_auth_cookie_exc = ( None, stem.connection.IncorrectCookieSize(None, False, None), stem.connection.UnreadableCookieFile(None, False, None), stem.connection.CookieAuthRejected(None, False, None), stem.connection.IncorrectCookieValue(None, False, None), stem.connection.UnrecognizedAuthChallengeMethod(None, None, None), stem.connection.AuthChallengeFailed(None, None), stem.connection.AuthSecurityFailure(None, None), stem.connection.InvalidClientNonce(None, None)) # authentication functions might raise a controller error when # 'suppress_ctl_errors' is False, so including those control_exc = (stem.ProtocolError(None), stem.SocketError(None), stem.SocketClosed(None)) all_auth_none_exc += control_exc all_auth_password_exc += control_exc all_auth_cookie_exc += control_exc auth_method_combinations = mocking.get_all_combinations( [ stem.connection.AuthMethod.NONE, stem.connection.AuthMethod.PASSWORD, stem.connection.AuthMethod.COOKIE, stem.connection.AuthMethod.SAFECOOKIE, stem.connection.AuthMethod.UNKNOWN, ], include_empty=True) for protocolinfo_auth_methods in auth_method_combinations: # protocolinfo input for the authenticate() call we'll be making protocolinfo_arg = mocking.get_protocolinfo_response( auth_methods=protocolinfo_auth_methods, cookie_path="/tmp/blah", ) for auth_none_exc in all_auth_none_exc: for auth_password_exc in all_auth_password_exc: for auth_cookie_exc in all_auth_cookie_exc: # Determine if the authenticate() call will succeed and mock each # of the authenticate_* function to raise its given exception. # # This implementation is slightly inaccurate in a couple regards... # a. it raises safecookie exceptions from authenticate_cookie() # b. exceptions raised by authenticate_cookie() and # authenticate_safecookie() are always the same # # However, adding another loop for safe_cookie exceptions means # multiplying our runtime many fold. This exercises everything that # matters so the above inaccuracies seem fine. expect_success = False auth_mocks = { stem.connection.AuthMethod.NONE: (stem.connection.authenticate_none, auth_none_exc), stem.connection.AuthMethod.PASSWORD: (stem.connection.authenticate_password, auth_password_exc), stem.connection.AuthMethod.COOKIE: (stem.connection.authenticate_cookie, auth_cookie_exc), stem.connection.AuthMethod.SAFECOOKIE: (stem.connection.authenticate_safecookie, auth_cookie_exc), } for auth_method in auth_mocks: auth_function, raised_exc = auth_mocks[auth_method] if not raised_exc: # Mocking this authentication method so it will succeed. If # it's among the protocolinfo methods then expect success. mocking.mock(auth_function, mocking.no_op()) expect_success |= auth_method in protocolinfo_auth_methods else: mocking.mock( auth_function, mocking.raise_exception(raised_exc)) if expect_success: stem.connection.authenticate( None, "blah", None, protocolinfo_arg) else: self.assertRaises( stem.connection.AuthenticationFailure, stem.connection.authenticate, None, "blah", None, protocolinfo_arg) # revert logging back to normal stem_logger.setLevel(log.logging_level(log.TRACE))
def setUp(self): socket = stem.socket.ControlSocket() mocking.mock_method(Controller, "add_event_listener", mocking.no_op()) self.controller = Controller(socket, enable_caching = True) mocking.revert_mocking()