| @@ -0,0 +1,132 @@ | |||
| import unittest | |||
| import aiosocks | |||
| import asyncio | |||
| from unittest import mock | |||
| try: | |||
| from asyncio import ensure_future | |||
| except ImportError: | |||
| ensure_future = asyncio.async | |||
| class TestCreateConnection(unittest.TestCase): | |||
| def setUp(self): | |||
| self.loop = asyncio.new_event_loop() | |||
| asyncio.set_event_loop(None) | |||
| def tearDown(self): | |||
| self.loop.close() | |||
| def _fake_coroutine(self, return_value): | |||
| def coro(*args, **kwargs): | |||
| if isinstance(return_value, Exception): | |||
| raise return_value | |||
| return return_value | |||
| return mock.Mock(side_effect=asyncio.coroutine(coro)) | |||
| def test_init(self): | |||
| addr = aiosocks.Socks5Addr('localhost') | |||
| auth = aiosocks.Socks5Auth('usr', 'pwd') | |||
| dst = ('python.org', 80) | |||
| # proxy argument | |||
| with self.assertRaises(AssertionError) as ct: | |||
| conn = aiosocks.create_connection(None, None, auth, dst) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertEqual(str(ct.exception), | |||
| 'proxy must be Socks4Addr() or Socks5Addr() tuple') | |||
| with self.assertRaises(AssertionError) as ct: | |||
| conn = aiosocks.create_connection(None, auth, auth, dst) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertEqual(str(ct.exception), | |||
| 'proxy must be Socks4Addr() or Socks5Addr() tuple') | |||
| # proxy_auth | |||
| with self.assertRaises(AssertionError) as ct: | |||
| conn = aiosocks.create_connection(None, addr, addr, dst) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertIn('proxy_auth must be None or Socks4Auth()', | |||
| str(ct.exception)) | |||
| # dst | |||
| with self.assertRaises(AssertionError) as ct: | |||
| conn = aiosocks.create_connection(None, addr, auth, None) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertIn('invalid dst format, tuple("dst_host", dst_port))', | |||
| str(ct.exception)) | |||
| # addr and auth compatibility | |||
| with self.assertRaises(ValueError) as ct: | |||
| conn = aiosocks.create_connection( | |||
| None, addr, aiosocks.Socks4Auth(''), dst | |||
| ) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertIn('proxy is Socks5Addr but proxy_auth is not Socks5Auth', | |||
| str(ct.exception)) | |||
| with self.assertRaises(ValueError) as ct: | |||
| conn = aiosocks.create_connection( | |||
| None, aiosocks.Socks4Addr(''), auth, dst | |||
| ) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertIn('proxy is Socks4Addr but proxy_auth is not Socks4Auth', | |||
| str(ct.exception)) | |||
| def test_connection_fail(self): | |||
| addr = aiosocks.Socks5Addr('localhost') | |||
| auth = aiosocks.Socks5Auth('usr', 'pwd') | |||
| dst = ('python.org', 80) | |||
| loop_mock = mock.Mock() | |||
| loop_mock.create_connection = self._fake_coroutine(OSError()) | |||
| with self.assertRaises(aiosocks.SocksConnectionError): | |||
| conn = aiosocks.create_connection( | |||
| None, addr, auth, dst, loop=loop_mock | |||
| ) | |||
| self.loop.run_until_complete(conn) | |||
| def test_negotiate_fail(self): | |||
| addr = aiosocks.Socks5Addr('localhost') | |||
| auth = aiosocks.Socks5Auth('usr', 'pwd') | |||
| dst = ('python.org', 80) | |||
| transp, proto = mock.Mock(), mock.Mock() | |||
| proto.negotiate_done = self._fake_coroutine(aiosocks.SocksError()) | |||
| loop_mock = mock.Mock() | |||
| loop_mock.create_connection = self._fake_coroutine((transp, proto)) | |||
| with self.assertRaises(aiosocks.SocksError) as ct: | |||
| conn = aiosocks.create_connection( | |||
| None, addr, auth, dst, loop=loop_mock | |||
| ) | |||
| self.loop.run_until_complete(conn) | |||
| self.assertIn('Can not connect to python.org:80', | |||
| str(ct.exception)) | |||
| def test_create_protocol(self): | |||
| addr = aiosocks.Socks5Addr('localhost') | |||
| auth = aiosocks.Socks5Auth('usr', 'pwd') | |||
| dst = ('python.org', 80) | |||
| transp, proto = mock.Mock(), mock.Mock() | |||
| proto.negotiate_done = self._fake_coroutine(True) | |||
| loop_mock = mock.Mock() | |||
| loop_mock.create_connection = self._fake_coroutine((transp, proto)) | |||
| user_proto = mock.Mock() | |||
| conn = aiosocks.create_connection( | |||
| lambda: user_proto, addr, auth, dst, loop=loop_mock | |||
| ) | |||
| fut = ensure_future(conn, loop=self.loop) | |||
| self.loop.run_until_complete(fut) | |||
| transport, protocol = fut.result() | |||
| self.assertIs(transport, transp) | |||
| self.assertIs(protocol, user_proto) | |||
| self.assertIs(transport._protocol, user_proto) | |||