def test_no_orphaned_process(tor_cmd): """ Check that when an exception arises in the middle of spawning tor that we don't leave a lingering process. """ if not stem.util.system.is_available('sleep'): skip('(sleep unavailable)') with patch('re.compile', Mock(side_effect=KeyboardInterrupt('nope'))): # We don't need to actually run tor for this test. Rather, any process will # do the trick. Picking sleep so this'll clean itself up if our test fails. mock_tor_process = subprocess.Popen(['sleep', '60']) with patch('subprocess.Popen', Mock(return_value=mock_tor_process)): try: stem.process.launch_tor(tor_cmd) raise AssertionError("tor shoudn't have started") except KeyboardInterrupt as exc: if os.path.exists('/proc/%s' % mock_tor_process.pid): raise AssertionError( 'launch_tor() left a lingering tor process') assert_equal('nope', str(exc))
def test_torrc_arguments_via_stdin(tor_cmd): """ Pass configuration options via stdin. """ if test.tor_version() < stem.version.Requirement.TORRC_VIA_STDIN: skip('(requires )' % stem.version.Requirement.TORRC_VIA_STDIN) with tmp_directory() as data_directory: torrc = BASIC_RELAY_TORRC % data_directory output = run_tor(tor_cmd, '-f', '-', '--dump-config', 'short', stdin = torrc) assert_equal(sorted(torrc.splitlines()), sorted(output.splitlines()))
def test_take_ownership_via_pid(tor_cmd): """ Checks that the tor process quits after we do if we set take_ownership. To test this we spawn a process and trick tor into thinking that it is us. """ if not stem.util.system.is_available('sleep'): skip('(sleep unavailable)') with tempfile.TemporaryDirectory() as data_directory: sleep_process = subprocess.Popen(['sleep', '60']) tor_process = stem.process.launch_tor_with_config( tor_cmd=tor_cmd, config={ 'SocksPort': random_port(), 'ControlPort': random_port(), 'DataDirectory': data_directory, '__OwningControllerProcess': str(sleep_process.pid), }, completion_percent=0, ) # Kill the sleep command. Tor should quit shortly after. sleep_process.kill() sleep_process.communicate() # tor polls for the process every fifteen seconds so this may take a # while... # # https://trac.torproject.org/projects/tor/ticket/21281 start_time = time.time() while time.time() - start_time < 30: if tor_process.poll() is not None: if tor_process.returncode != 0: raise AssertionError( 'Tor exited with a non-zero exit status: %i' % tor_process.returncode) else: return # tor exited successfully time.sleep(0.01) raise AssertionError( "tor didn't quit after the process that owned it terminated")
def test_torrc_arguments_via_stdin(tor_cmd): """ Pass configuration options via stdin. """ if test.tor_version() < stem.version.Requirement.TORRC_VIA_STDIN: skip('(requires %s)' % stem.version.Requirement.TORRC_VIA_STDIN) with tmp_directory() as data_directory: torrc = BASIC_RELAY_TORRC % data_directory output = run_tor(tor_cmd, '-f', '-', '--dump-config', 'short', stdin=torrc) assert_equal(sorted(torrc.splitlines()), sorted(output.splitlines()))
def test_take_ownership_via_pid(tor_cmd): """ Checks that the tor process quits after we do if we set take_ownership. To test this we spawn a process and trick tor into thinking that it is us. """ if not stem.util.system.is_available('sleep'): skip('(sleep unavailable)') elif test.tor_version() < stem.version.Requirement.TAKEOWNERSHIP: skip('(requires )' % stem.version.Requirement.TAKEOWNERSHIP) with tmp_directory() as data_directory: sleep_process = subprocess.Popen(['sleep', '60']) tor_process = stem.process.launch_tor_with_config( tor_cmd = tor_cmd, config = { 'SocksPort': random_port(), 'ControlPort': random_port(), 'DataDirectory': data_directory, '__OwningControllerProcess': str(sleep_process.pid), }, completion_percent = 5, ) # Kill the sleep command. Tor should quit shortly after. sleep_process.kill() sleep_process.communicate() # tor polls for the process every fifteen seconds so this may take a # while... # # https://trac.torproject.org/projects/tor/ticket/21281 start_time = time.time() while time.time() - start_time < 30: if tor_process.poll() == 0: return # tor exited time.sleep(0.01) raise AssertionError("tor didn't quit after the process that owned it terminated")
def test_take_ownership_via_controller(tor_cmd): """ Checks that the tor process quits after the controller that owns it connects, then disconnects.. """ if test.tor_version() < stem.version.Requirement.TAKEOWNERSHIP: skip('(requires %s)' % stem.version.Requirement.TAKEOWNERSHIP) with tmp_directory() as data_directory: control_port = random_port() tor_process = stem.process.launch_tor_with_config( tor_cmd=tor_cmd, config={ 'SocksPort': random_port(), 'ControlPort': control_port, 'DataDirectory': data_directory, }, completion_percent=0, take_ownership=True, ) # We're the controlling process. Just need to connect then disconnect. controller = stem.control.Controller.from_port( port=int(control_port)) controller.authenticate() controller.close() # give tor a few seconds to quit start_time = time.time() while time.time() - start_time < 5: if tor_process.poll() == 0: return # tor exited time.sleep(0.01) raise AssertionError( "tor didn't quit after the controller that owned it disconnected" )
def test_launch_tor_with_config_via_stdin(tor_cmd): """ Exercises launch_tor_with_config when we provide our torrc via stdin. """ if test.tor_version() < stem.version.Requirement.TORRC_VIA_STDIN: skip('(requires %s)' % stem.version.Requirement.TORRC_VIA_STDIN) with tmp_directory() as data_directory: control_port = random_port() control_socket, tor_process = None, None try: tor_process = stem.process.launch_tor_with_config( tor_cmd=tor_cmd, config={ 'SocksPort': random_port(), 'ControlPort': control_port, 'DataDirectory': data_directory, }, completion_percent=0) control_socket = stem.socket.ControlPort( port=int(control_port)) stem.connection.authenticate(control_socket) # exercises the socket control_socket.send('GETCONF ControlPort') getconf_response = control_socket.recv() assert_equal('ControlPort=%s' % control_port, str(getconf_response)) finally: if control_socket: control_socket.close() if tor_process: tor_process.kill() tor_process.wait()
def test_take_ownership_via_controller(tor_cmd): """ Checks that the tor process quits after the controller that owns it connects, then disconnects.. """ if test.tor_version() < stem.version.Requirement.TAKEOWNERSHIP: skip('(requires )' % stem.version.Requirement.TAKEOWNERSHIP) with tmp_directory() as data_directory: control_port = random_port() tor_process = stem.process.launch_tor_with_config( tor_cmd = tor_cmd, config = { 'SocksPort': random_port(), 'ControlPort': control_port, 'DataDirectory': data_directory, }, completion_percent = 5, take_ownership = True, ) # We're the controlling process. Just need to connect then disconnect. controller = stem.control.Controller.from_port(port = int(control_port)) controller.authenticate() controller.close() # give tor a few seconds to quit start_time = time.time() while time.time() - start_time < 5: if tor_process.poll() == 0: return # tor exited time.sleep(0.01) raise AssertionError("tor didn't quit after the controller that owned it disconnected")
def test_launch_tor_with_config_via_stdin(tor_cmd): """ Exercises launch_tor_with_config when we provide our torrc via stdin. """ if test.tor_version() < stem.version.Requirement.TORRC_VIA_STDIN: skip('(requires )' % stem.version.Requirement.TORRC_VIA_STDIN) with tmp_directory() as data_directory: control_port = random_port() control_socket, tor_process = None, None try: tor_process = stem.process.launch_tor_with_config( tor_cmd = tor_cmd, config = { 'SocksPort': random_port(), 'ControlPort': control_port, 'DataDirectory': data_directory, }, completion_percent = 5 ) control_socket = stem.socket.ControlPort(port = int(control_port)) stem.connection.authenticate(control_socket) # exercises the socket control_socket.send('GETCONF ControlPort') getconf_response = control_socket.recv() assert_equal('ControlPort=%s' % control_port, str(getconf_response)) finally: if control_socket: control_socket.close() if tor_process: tor_process.kill() tor_process.wait()
def test_no_orphaned_process(tor_cmd): """ Check that when an exception arises in the middle of spawning tor that we don't leave a lingering process. """ if not stem.util.system.is_available('sleep'): skip('(sleep unavailable)') with patch('re.compile', Mock(side_effect = KeyboardInterrupt('nope'))): # We don't need to actually run tor for this test. Rather, any process will # do the trick. Picking sleep so this'll clean itself up if our test fails. mock_tor_process = subprocess.Popen(['sleep', '60']) with patch('subprocess.Popen', Mock(return_value = mock_tor_process)): try: stem.process.launch_tor(tor_cmd) raise AssertionError("tor shoudn't have started") except KeyboardInterrupt as exc: if os.path.exists('/proc/%s' % mock_tor_process.pid): raise AssertionError('launch_tor() left a lingering tor process') assert_equal('nope', str(exc))