def test_tor_connection_fails(self): """ We fail to connect once, and then successfully connect -- testing whether we're retrying properly on each Bootstrapped line from stdout. """ config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 class Connector: count = 0 def __call__(self, proto, trans): self.count += 1 if self.count < 2: return defer.fail(error.CannotListenError(None, None, None)) proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') proto.outReceived('Bootstrapped 100%\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(Connector(), self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') d.addCallback(self.setup_complete_fails) return self.assertFailure(d, Exception)
def test_basic_launch(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap class OnProgress: def __init__(self, test, expected): self.test = test self.expected = expected def __call__(self, percent, tag, summary): self.test.assertEqual(self.expected[0], (percent, tag, summary)) self.expected = self.expected[1:] self.test.assertTrue('"' not in summary) self.test.assertTrue(percent >= 0 and percent <= 100) def on_protocol(proto): proto.outReceived('Bootstrapped 100%\n') proto.progress = OnProgress(self, [(90, 'circuit_create', 'Establishing a Tor circuit'), (100, 'done', 'Done')]) trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(connector, self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator) d.addCallback(self.setup_complete_no_errors, config) return d
def test_tor_connection_user_data_dir(self): """ Test that we don't delete a user-supplied data directory. """ config = TorConfig() config.OrPort = 1234 class Connector: def __call__(self, proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') my_dir = tempfile.mkdtemp(prefix='tortmp') config.DataDirectory = my_dir trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(Connector(), self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') def still_have_data_dir(proto, tester): proto.cleanup() # FIXME? not really unit-testy as this is sort of internal function tester.assertTrue(os.path.exists(my_dir)) delete_file_or_tree(my_dir) d.addCallback(still_have_data_dir, self) d.addErrback(self.fail) return d
def test_tor_connection_user_control_port(self): """ Confirm we use a user-supplied control-port properly """ config = TorConfig() config.OrPort = 1234 config.ControlPort = 4321 class Connector: def __call__(self, proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') proto.outReceived('Bootstrapped 100%\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(Connector(), self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') def check_control_port(proto, tester): ## we just want to ensure launch_tor() didn't mess with ## the controlport we set tester.assertEquals(config.ControlPort, 4321) d.addCallback(check_control_port, self) d.addErrback(self.fail) return d
def test_tor_connection_fails(self): """ We fail to connect once, and then successfully connect -- testing whether we're retrying properly on each Bootstrapped line from stdout. """ config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 class Connector: count = 0 def __call__(self, proto, trans): self.count += 1 if self.count < 2: return defer.fail(error.CannotListenError(None, None, None)) proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(Connector(), self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') d.addCallback(self.setup_complete_fails) return self.assertFailure(d, Exception)
def test_tor_produces_stderr_output(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.errReceived('Something went horribly wrong!\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans fakeout = StringIO() fakeerr = StringIO() creator = functools.partial(connector, self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo', stdout=fakeout, stderr=fakeerr) d.addCallback(self.fail) # should't get callback d.addErrback(self.setup_fails_stderr, fakeout, fakeerr) self.assertFalse(self.protocol.on_disconnect) return d
def test_tor_connection_user_data_dir(self): """ Test that we don't delete a user-supplied data directory. """ config = TorConfig() config.OrPort = 1234 class Connector: def __call__(self, proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') proto.outReceived('Bootstrapped 100%\n') my_dir = tempfile.mkdtemp(prefix='tortmp') config.DataDirectory = my_dir trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(Connector(), self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator) def still_have_data_dir(proto, tester): proto.cleanup() # FIXME? not really unit-testy as this is sort of internal function tester.assertTrue(os.path.exists(my_dir)) delete_file_or_tree(my_dir) d.addCallback(still_have_data_dir, self) d.addErrback(self.fail) return d
def test_tor_produces_stderr_output(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.errReceived('Something went horribly wrong!\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(connector, self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') d.addCallback(self.fail) # should't get callback d.addErrback(self.setup_fails_stderr) return d
def test_tor_connection_user_control_port(self): """ Confirm we use a user-supplied control-port properly """ config = TorConfig() config.OrPort = 1234 config.ControlPort = 4321 class Connector: def __call__(self, proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') proto.outReceived('Bootstrapped 100%\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(Connector(), self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator) def check_control_port(proto, tester): ## we just want to ensure launch_tor() didn't mess with ## the controlport we set tester.assertEquals(config.ControlPort, 4321) d.addCallback(check_control_port, self) d.addErrback(self.fail) return d
def test_multiple_orports(self): self.protocol.post_bootstrap = None self.protocol.answers.append('config/names=\nOrPort CommaList') self.protocol.answers.append({'OrPort': '1234'}) conf = TorConfig(self.protocol) conf.OrPort = ['1234', '4321'] conf.save() self.assertEqual(self.protocol.sets, [('OrPort', '1234'), ('OrPort', '4321')])
def test_multiple_orports(self): self.protocol.post_bootstrap = None self.protocol.answers.append('config/names=\nOrPort CommaList\nOK') self.protocol.answers.append({'OrPort': '1234'}) conf = TorConfig(self.protocol) conf.OrPort = ['1234', '4321'] conf.save() self.assertEqual(self.protocol.sets, [('OrPort', '1234'), ('OrPort', '4321')])
def test_launch_with_timeout(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 timeout = 5 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap class OnProgress: def __init__(self, test, expected): self.test = test self.expected = expected def __call__(self, percent, tag, summary): self.test.assertEqual(self.expected[0], (percent, tag, summary)) self.expected = self.expected[1:] self.test.assertTrue('"' not in summary) self.test.assertTrue(percent >= 0 and percent <= 100) def on_protocol(proto): proto.outReceived('Bootstrapped 100%\n') trans = FakeProcessTransportNeverBootstraps() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(connector, self.protocol, self.transport) react = FakeReactor(self, trans, on_protocol) d = launch_tor(config, react, connection_creator=creator, timeout=timeout, tor_binary='/bin/echo') rtn = self.assertFailure(d, RuntimeError, "Timed out waiting for Tor to launch.") # FakeReactor is a task.Clock subclass and +1 just to be sure react.advance(timeout + 1) return rtn
def test_tor_connection_user_data_dir(self): """ Test that we don't delete a user-supplied data directory. """ config = TorConfig() config.OrPort = 1234 class Connector: def __call__(self, proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived(b'Bootstrapped 90%\n') with TempDir() as tmp: my_dir = str(tmp) config.DataDirectory = my_dir trans = FakeProcessTransport() trans.protocol = self.protocol creator = functools.partial(Connector(), self.protocol, self.transport) d = launch( FakeReactor(self, trans, on_protocol, [1234, 9051]), connection_creator=creator, tor_binary='/bin/echo', data_directory=my_dir, control_port=0, ) def still_have_data_dir(tor, tester): tor._process_protocol.cleanup( ) # FIXME? not really unit-testy as this is sort of internal function tester.assertTrue(os.path.exists(my_dir)) d.addCallback(still_have_data_dir, self) d.addErrback(self.fail) return d
def test_launch_tor_fails(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 100%\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(connector, self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') d.addCallback(self.setup_complete_fails) return self.assertFailure(d, Exception)
def test_launch_with_timeout(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 timeout = 5 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap class OnProgress: def __init__(self, test, expected): self.test = test self.expected = expected def __call__(self, percent, tag, summary): self.test.assertEqual(self.expected[0], (percent, tag, summary)) self.expected = self.expected[1:] self.test.assertTrue('"' not in summary) self.test.assertTrue(percent >= 0 and percent <= 100) def on_protocol(proto): proto.outReceived('Bootstrapped 100%\n') trans = FakeProcessTransportNeverBootstraps() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(connector, self.protocol, self.transport) react = FakeReactor(self, trans, on_protocol) d = launch_tor(config, react, connection_creator=creator, timeout=timeout, tor_binary='/bin/echo') # FakeReactor is a task.Clock subclass and +1 just to be sure react.advance(timeout + 1) self.assertTrue(d.called) self.assertTrue(d.result.getErrorMessage().strip().endswith('Tor was killed (TERM).')) self.flushLoggedErrors(RuntimeError) return self.assertFailure(d, RuntimeError)
def test_basic_launch(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap class OnProgress: def __init__(self, test, expected): self.test = test self.expected = expected def __call__(self, percent, tag, summary): self.test.assertEqual(self.expected[0], (percent, tag, summary)) self.expected = self.expected[1:] self.test.assertTrue('"' not in summary) self.test.assertTrue(percent >= 0 and percent <= 100) def on_protocol(proto): proto.outReceived('Bootstrapped 100%\n') proto.progress = OnProgress( self, [(90, 'circuit_create', 'Establishing a Tor circuit'), (100, 'done', 'Done')]) trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans creator = functools.partial(connector, self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo') d.addCallback(self.setup_complete_no_errors, config) return d
def test_launch_tor_fails(self): config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def connector(proto, trans): proto._set_valid_events('STATUS_CLIENT') proto.makeConnection(trans) proto.post_bootstrap.callback(proto) return proto.post_bootstrap def on_protocol(proto): proto.outReceived('Bootstrapped 90%\n') trans = FakeProcessTransport() trans.protocol = self.protocol self.othertrans = trans fakeout = StringIO() fakeerr = StringIO() creator = functools.partial(connector, self.protocol, self.transport) d = launch_tor(config, FakeReactor(self, trans, on_protocol), connection_creator=creator, tor_binary='/bin/echo', stdout=fakeout, stderr=fakeerr) d.addCallback(self.setup_complete_fails, fakeout, fakeerr) self.flushLoggedErrors(RuntimeError) return d
print "setup complete:",proto print "Building a TorState" state = TorState(proto.tor_protocol) state.post_bootstrap.addCallback(state_complete) state.post_bootstrap.addErrback(setup_failed) def setup_failed(arg): print "SETUP FAILED",arg reactor.stop() def bootstrap(c): conf = TorConfig(c) conf.post_bootstrap.addCallback(setup_complete).addErrback(setup_failed) print "Connection is live, bootstrapping state..." ## FIXME need some way to make TorConfig slutty about accepting any ## unknown attribute into its config if it has no attached ## protocol...so we can set the config options we want config = TorConfig() config.OrPort = 1234 config.SocksPort = 9999 def updates(prog, tag, summary): print "%d%%: %s" % (prog, summary) d = launch_tor(config, reactor, progress_updates=updates) d.addCallback(setup_complete) d.addErrback(setup_failed) reactor.run()