Index: asyncore.py =================================================================== --- asyncore.py (revision 74184) +++ asyncore.py (working copy) @@ -415,6 +415,10 @@ # sockets that are connected self.handle_accept() elif not self.connected: + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + raise socket.error(err, _strerror(err)) + self.handle_connect_event() self.handle_read() else: @@ -431,12 +435,12 @@ return if not self.connected: - #check for errors err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if err != 0: raise socket.error(err, _strerror(err)) - + self.handle_connect_event() + self.handle_write() def handle_expt_event(self): Index: test/test_asyncore.py =================================================================== --- test/test_asyncore.py (revision 74184) +++ test/test_asyncore.py (working copy) @@ -1,8 +1,10 @@ import asyncore +import asynchat import unittest import select import os import socket +import errno import threading import sys import time @@ -302,7 +304,57 @@ self.assertEquals(lines, expected) +class testing_channel(asynchat.async_chat): + def __init__(self, *a, **kw): + asynchat.async_chat.__init__(self, *a, **kw) + self.exceptions = [] + self.close_count = 0 + def collect_incoming_data(self, data): + pass + + def found_terminator(self): + pass + + def handle_connect(self): + self.push("connected") + + def handle_error(self): + self.exceptions.append(sys.exc_info()[1]) + self.handle_close() + + def handle_close(self): + self.close_count += 1 + self.close() + + +class ConnectionRefusedTests(unittest.TestCase): + + def setUp(self): + s = socket.socket() + self.channel = testing_channel(s) + + # Assumes that noone is listeing here + self.channel.connect(('localhost', 65535)) + + # give time for socket to connect + time.sleep(0.1) + + asyncore.poll() + + def tearDown(self): + asyncore.close_all() + + def test_single_exception(self): + self.assertEqual(len(self.channel.exceptions), 1) + + def test_connection_refused(self): + self.assertEqual(self.channel.exceptions[0].args[0], errno.ECONNREFUSED) + + def test_close_once(self): + self.assertEqual(self.channel.close_count, 1) + + class dispatcherwithsend_noread(asyncore.dispatcher_with_send): def readable(self): return False @@ -393,8 +445,8 @@ def test_main(): - tests = [HelperFunctionTests, DispatcherTests, DispatcherWithSendTests, - DispatcherWithSendTests_UsePoll] + tests = [HelperFunctionTests, DispatcherTests, ConnectionRefusedTests, + DispatcherWithSendTests, DispatcherWithSendTests_UsePoll] if hasattr(asyncore, 'file_wrapper'): tests.append(FileWrapperTest)