<NME> test_channel.py
<BEF> ADDFILE
<MSG> Added pants.channel unit tests.

<DFF> @@ -0,0 +1,629 @@
+###############################################################################
+#
+# Copyright 2011 Chris Davis
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+###############################################################################
+
+###############################################################################
+# Imports
+###############################################################################
+
+import errno
+import socket
+
+import pants.channel
+from pants.channel import Channel
+from pants.engine import Engine
+
+
+###############################################################################
+# Constants
+###############################################################################
+
+NO_ERROR = 0
+AN_ERROR = 1
+# This is an error that cannot possibly be raised by a socket. It can
+# be used in tests to mock a socket.error that absolutely won't match
+# a "real" error.
+IMPOSSIBLE_ERROR = errno.ENOTTY
+
+EXAMPLE_ADDRESS = ('example.com', 80)
+
+EXAMPLE_STRING = "foobarbaz"
+EXAMPLE_STRING_LENGTH = 9
+
+
+
+###############################################################################
+# Mock Objects
+###############################################################################
+
+class MockSocket(object):
+    def __init__(self, err=NO_ERROR, exc=socket.error):
+        self._socket = socket.socket()
+        self._exc = exc
+        self._err = err
+        
+        self.connect_ex_called = False
+        self.connect_ex_addr = None
+        
+        self.listen_called = False
+        self.listen_backlog = None
+        
+        self.close_called = False
+        
+        self.accept_called = False
+        
+        self.recv_called = False
+        
+        self.recvfrom_called = False
+        
+        self.send_called = False
+        self.send_buffer = ""
+        
+        self.sendto_called = False
+        self.sendto_addr = None
+        
+        self._initted = True
+    
+    def __getattr__(self, key):
+        return getattr(self._socket, key)
+    
+    def __setattr__(self, key, value):
+        if not hasattr(self, "_initted") or hasattr(self, key):
+            return object.__setattr__(self, key, value)
+        else:
+            return setattr(self._socket, key, value)
+    
+    def _raise_exc(self):
+        raise self._exc(self._err)
+    
+    def connect_ex(self, addr):
+        self.connect_ex_called = True
+        self.connect_ex_addr = addr
+        
+        if self._err == NO_ERROR:
+            return 0
+        else:
+            self._raise_exc()
+    
+    def listen(self, backlog):
+        self.listen_backlog = backlog
+        
+        if self._err != NO_ERROR:
+            self._raise_exc()
+    
+    def close(self):
+        self.close_called = True
+        
+        if self._err != NO_ERROR:
+            self._raise_exc()
+    
+    def accept(self):
+        self.accept_called = True
+        
+        if self._err == NO_ERROR:
+            return None, EXAMPLE_ADDRESS
+        else:
+            self._raise_exc()
+    
+    def recv(self, recv_amount):
+        self.recv_called = True
+        
+        if self._err == NO_ERROR:
+            return EXAMPLE_STRING
+        else:
+            self._raise_exc()
+    
+    def recvfrom(self, recv_amount):
+        self.recvfrom_called = True
+        
+        if self._err == NO_ERROR:
+            return EXAMPLE_STRING, EXAMPLE_ADDRESS
+        else:
+            self._raise_exc()
+    
+    def send(self, data):
+        self.send_called = True
+        self.send_buffer += data
+        
+        if self._err == NO_ERROR:
+            return len(data)
+        else:
+            self._raise_exc()
+    
+    def sendto(self, data, addr):
+        self.sendto_called = True
+        self.sendto_addr = addr
+        self.send_buffer += data
+        
+        if self._err == NO_ERROR:
+            return len(data)
+        else:
+            self._raise_exc()
+
+class MockChannel(Channel):
+    def __init__(self, **kwargs):
+        Channel.__init__(self, **kwargs)
+        
+        self.close_called = False
+        self.handle_read_event_called = False
+        self.handle_write_event_called = False
+    
+    def close(self):    
+        self.close_called = True
+        
+        self._socket = None
+        self.fileno = None
+    
+    def closed(self):
+        return False
+    
+    def _handle_read_event(self):
+        self.handle_read_event_called = True
+    
+    def _handle_write_event(self):
+        self.handle_write_event_called = True
+
+
+###############################################################################
+# __init__() Tests
+###############################################################################
+
+def test_init():
+    chan = Channel()
+    
+    assert isinstance(chan._socket, socket.socket)
+    assert chan._socket.family == socket.AF_INET
+    assert chan._socket.type == socket.SOCK_STREAM
+
+def test_init_with_socket():
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    chan = Channel(socket=sock)
+    
+    assert chan._socket is sock
+
+def test_init_with_type():
+    chan = Channel(type=socket.SOCK_DGRAM)
+    
+    assert chan._socket.type == socket.SOCK_DGRAM
+
+def test_init_with_socket_and_type():
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    chan = Channel(socket=sock, type=socket.SOCK_DGRAM)
+    
+    assert chan._socket is sock
+
+def test_init_adds_channel_to_Engine():
+    engn = Engine.instance()
+    chan = Channel()
+    
+    assert chan.fileno in engn._channels
+    assert engn._channels[chan.fileno] is chan
+
+
+###############################################################################
+# _handle_events() tests
+###############################################################################
+
+def test_handle_events_with_no_events():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.NONE)
+    
+    assert not chan.handle_read_event_called
+    assert not chan.handle_write_event_called
+    assert not chan.close_called
+
+def test_handle_events_with_read_event():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.READ)
+    
+    assert chan.handle_read_event_called
+    assert not chan.handle_write_event_called
+    assert not chan.close_called
+
+def test_handle_events_with_write_event():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.WRITE)
+    
+    assert not chan.handle_read_event_called
+    assert chan.handle_write_event_called
+    assert not chan.close_called
+
+def test_handle_events_with_error_event():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.ERROR)
+    
+    assert not chan.handle_read_event_called
+    assert not chan.handle_write_event_called
+    assert chan.close_called
+
+def test_handle_events_with_read_and_write_events():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.READ | Engine.WRITE)
+    
+    assert chan.handle_read_event_called
+    assert chan.handle_write_event_called
+    assert not chan.close_called
+
+def test_handle_events_with_read_and_error_events():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.READ | Engine.ERROR)
+    
+    assert chan.handle_read_event_called
+    assert not chan.handle_write_event_called
+    assert chan.close_called
+
+def test_handle_events_with_write_and_error_events():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.WRITE | Engine.ERROR)
+    
+    assert not chan.handle_read_event_called
+    assert chan.handle_write_event_called
+    assert chan.close_called
+
+def test_handle_events_with_read_write_and_error_events():
+    chan = MockChannel()
+    
+    chan._handle_events(Engine.READ | Engine.WRITE | Engine.ERROR)
+    
+    assert chan.handle_read_event_called
+    assert chan.handle_write_event_called
+    assert chan.close_called
+
+# TODO Improve coverage of final block in _handle_events()
+
+
+###############################################################################
+# _socket_set() tests
+###############################################################################
+
+def test_socket_set_with_default_socket():
+    chan = MockChannel()
+    chan.close()
+    sock = socket.socket()
+    sock.setblocking(True)
+    
+    chan._socket_set(sock)
+    
+    assert chan._socket is sock
+    assert chan.fileno == sock.fileno()
+    assert chan._socket.gettimeout() == 0, "Socket should be non-blocking."
+
+def test_socket_set_when_channel_has_a_preexisting_socket():
+    chan = MockChannel()
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    
+    try:
+        chan._socket_set(sock)
+        assert False, "RuntimeError should be raised."
+    except RuntimeError:
+        assert True
+
+def test_socket_set_with_socket_with_unsupported_family():
+    chan = MockChannel()
+    chan.close()
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    
+    # A little trickery is required here to get around actual OS
+    # constraints on socket families.
+    old_supported_families = pants.channel.SUPPORTED_FAMILIES
+    try:
+        pants.channel.SUPPORTED_FAMILIES = ()
+        try:
+            chan._socket_set(sock)
+            assert False, "ValueError should be raised."
+        except ValueError:
+            assert True
+    finally:
+        pants.channel.SUPPORTED_FAMILIES = old_supported_families
+
+def test_socket_set_with_socket_with_unsupported_type():
+    chan = MockChannel()
+    chan.close()
+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    
+    # A little trickery is required here to get around actual OS
+    # constraints on socket types.
+    old_supported_types = pants.channel.SUPPORTED_TYPES
+    try:
+        pants.channel.SUPPORTED_TYPES = ()
+        try:
+            chan._socket_set(sock)
+            assert False, "ValueError should be raised."
+        except ValueError:
+            assert True
+    finally:
+        pants.channel.SUPPORTED_TYPES = old_supported_types
+
+
+###############################################################################
+# _socket_connect() tests
+###############################################################################
+
+def test_socket_connect():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_connect(EXAMPLE_ADDRESS)
+    
+    assert ret
+    assert sock.connect_ex_addr == EXAMPLE_ADDRESS
+
+def test_socket_connect_when_channel_is_already_connected():
+    sock = MockSocket(errno.EISCONN)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_connect(EXAMPLE_ADDRESS)
+    
+    assert ret
+
+def test_socket_connect_when_connection_is_already_in_progress():
+    sock = MockSocket(errno.EINPROGRESS)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_connect(EXAMPLE_ADDRESS)
+    
+    assert not ret
+
+def test_socket_connect_when_uncaught_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        chan._socket_connect(EXAMPLE_ADDRESS)
+        assert False, "socket.error should be raised."
+    except socket.error as e:
+        assert e[0] == IMPOSSIBLE_ERROR
+
+
+###############################################################################
+# _socket_listen() tests
+###############################################################################
+
+def test_socket_listen():
+    chan = MockChannel()
+    
+    chan._readable = True
+    chan._socket_listen(1024)
+    
+    assert not chan._readable
+
+# TODO Should we test the backlog adjustment here?
+
+
+###############################################################################
+# _socket_close() tests
+###############################################################################
+
+def test_socket_close():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    chan._socket_close()
+    
+    assert sock.close_called
+    assert chan._socket is None
+    assert chan.fileno is None
+
+def test_socket_close_when_AttributeError_is_raised():
+    sock = MockSocket(AN_ERROR, AttributeError)
+    chan = MockChannel(socket=sock)
+    
+    chan._socket_close()
+    
+    assert sock.close_called
+    assert chan._socket is None
+    assert chan.fileno is None
+
+def test_socket_close_when_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR, socket.error)
+    chan = MockChannel(socket=sock)
+    
+    chan._socket_close()
+    
+    assert sock.close_called
+    assert chan._socket is None
+    assert chan.fileno is None
+
+def test_socket_close_when_Exception_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR, Exception)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        chan._socket_close()
+        assert False, "Exception should be raised."
+    except Exception:
+        assert True
+    
+    assert sock.close_called
+    assert chan._socket is None
+    assert chan.fileno is None
+
+
+###############################################################################
+# _socket_accept() tests
+###############################################################################
+
+def test_socket_accept():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_accept()
+    
+    assert sock.accept_called
+    assert ret == (None, EXAMPLE_ADDRESS)
+
+def test_socket_accept_when_accept_blocks():
+    sock = MockSocket(errno.EAGAIN)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_accept()
+    
+    assert sock.accept_called
+    assert ret == (None, ())
+    assert not chan._readable
+
+def test_socket_accept_when_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        ret = chan._socket_accept()
+        assert False, "socket.error should be raised."
+    except socket.error as e:
+        assert e[0] == IMPOSSIBLE_ERROR
+
+
+###############################################################################
+# _socket_recv() tests
+###############################################################################
+
+def test_socket_recv():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_recv()
+    
+    assert ret == EXAMPLE_STRING
+
+# TODO Test None return value?
+
+def test_socket_recv_when_recv_blocks():
+    sock = MockSocket(errno.EAGAIN)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_recv()
+    
+    assert ret == ''
+    assert not chan._readable
+
+def test_socket_recv_when_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        chan._socket_recv()
+        assert False, "socket.error should be raised."
+    except socket.error as e:
+        assert e[0] == IMPOSSIBLE_ERROR
+
+
+###############################################################################
+# _socket_recvfrom() tests
+###############################################################################
+
+def test_socket_recvfrom():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_recvfrom()
+    
+    assert ret == (EXAMPLE_STRING, EXAMPLE_ADDRESS)
+
+# TODO Test None return value?
+
+def test_socket_recvfrom_when_recvfrom_blocks():
+    sock = MockSocket(errno.EAGAIN)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_recvfrom()
+    
+    assert ret == ('', None)
+    assert not chan._readable
+
+def test_socket_recvfrom_when_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        chan._socket_recvfrom()
+        assert False, "socket.error should be raised."
+    except socket.error as e:
+        assert e[0] == IMPOSSIBLE_ERROR
+
+
+###############################################################################
+# _socket_send() tests
+###############################################################################
+
+def test_socket_send():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_send(EXAMPLE_STRING)
+    
+    assert ret == EXAMPLE_STRING_LENGTH
+    assert sock.send_buffer == EXAMPLE_STRING
+
+def test_socket_send_when_send_blocks():
+    sock = MockSocket(errno.EAGAIN)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_send(EXAMPLE_STRING)
+    
+    assert ret == 0
+    assert not chan._writable
+
+def test_socket_send_when_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        chan._socket_send(EXAMPLE_STRING)
+        assert False, "socket.error should be raised."
+    except socket.error as e:
+        assert e[0] == IMPOSSIBLE_ERROR
+
+
+###############################################################################
+# _socket_sendto() tests
+###############################################################################
+
+def test_socket_sendto():
+    sock = MockSocket()
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)
+    
+    assert ret == EXAMPLE_STRING_LENGTH
+    assert sock.send_buffer == EXAMPLE_STRING
+    assert sock.sendto_addr == EXAMPLE_ADDRESS
+
+def test_socket_sendto_when_sendto_blocks():
+    sock = MockSocket(errno.EAGAIN)
+    chan = MockChannel(socket=sock)
+    
+    ret = chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)
+    
+    assert ret == 0
+    assert not chan._writable
+
+def test_socket_sendto_when_socket_error_is_raised():
+    sock = MockSocket(IMPOSSIBLE_ERROR)
+    chan = MockChannel(socket=sock)
+    
+    try:
+        chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)
+        assert False, "socket.error should be raised."
+    except socket.error as e:
+        assert e[0] == IMPOSSIBLE_ERROR

{'commit': 'diff --git a/pants/test/__init__.py b/pants/test/__init__.py\nnew file mode 100644\nindex 0000000..e69de29\ndiff --git a/pants/test/test_channel.py b/pants/test/test_channel.py\nnew file mode 100644\nindex 0000000..4b60f66\n--- /dev/null\n+++ b/pants/test/test_channel.py\n@@ -0,0 +1,629 @@\n+###############################################################################\n+#\n+# Copyright 2011 Chris Davis\n+#\n+# Licensed under the Apache License, Version 2.0 (the "License");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an "AS IS" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+#\n+###############################################################################\n+\n+###############################################################################\n+# Imports\n+###############################################################################\n+\n+import errno\n+import socket\n+\n+import pants.channel\n+from pants.channel import Channel\n+from pants.engine import Engine\n+\n+\n+###############################################################################\n+# Constants\n+###############################################################################\n+\n+NO_ERROR = 0\n+AN_ERROR = 1\n+# This is an error that cannot possibly be raised by a socket. It can\n+# be used in tests to mock a socket.error that absolutely won\'t match\n+# a "real" error.\n+IMPOSSIBLE_ERROR = errno.ENOTTY\n+\n+EXAMPLE_ADDRESS = (\'example.com\', 80)\n+\n+EXAMPLE_STRING = "foobarbaz"\n+EXAMPLE_STRING_LENGTH = 9\n+\n+\n+\n+###############################################################################\n+# Mock Objects\n+###############################################################################\n+\n+class MockSocket(object):\n+    def __init__(self, err=NO_ERROR, exc=socket.error):\n+        self._socket = socket.socket()\n+        self._exc = exc\n+        self._err = err\n+        \n+        self.connect_ex_called = False\n+        self.connect_ex_addr = None\n+        \n+        self.listen_called = False\n+        self.listen_backlog = None\n+        \n+        self.close_called = False\n+        \n+        self.accept_called = False\n+        \n+        self.recv_called = False\n+        \n+        self.recvfrom_called = False\n+        \n+        self.send_called = False\n+        self.send_buffer = ""\n+        \n+        self.sendto_called = False\n+        self.sendto_addr = None\n+        \n+        self._initted = True\n+    \n+    def __getattr__(self, key):\n+        return getattr(self._socket, key)\n+    \n+    def __setattr__(self, key, value):\n+        if not hasattr(self, "_initted") or hasattr(self, key):\n+            return object.__setattr__(self, key, value)\n+        else:\n+            return setattr(self._socket, key, value)\n+    \n+    def _raise_exc(self):\n+        raise self._exc(self._err)\n+    \n+    def connect_ex(self, addr):\n+        self.connect_ex_called = True\n+        self.connect_ex_addr = addr\n+        \n+        if self._err == NO_ERROR:\n+            return 0\n+        else:\n+            self._raise_exc()\n+    \n+    def listen(self, backlog):\n+        self.listen_backlog = backlog\n+        \n+        if self._err != NO_ERROR:\n+            self._raise_exc()\n+    \n+    def close(self):\n+        self.close_called = True\n+        \n+        if self._err != NO_ERROR:\n+            self._raise_exc()\n+    \n+    def accept(self):\n+        self.accept_called = True\n+        \n+        if self._err == NO_ERROR:\n+            return None, EXAMPLE_ADDRESS\n+        else:\n+            self._raise_exc()\n+    \n+    def recv(self, recv_amount):\n+        self.recv_called = True\n+        \n+        if self._err == NO_ERROR:\n+            return EXAMPLE_STRING\n+        else:\n+            self._raise_exc()\n+    \n+    def recvfrom(self, recv_amount):\n+        self.recvfrom_called = True\n+        \n+        if self._err == NO_ERROR:\n+            return EXAMPLE_STRING, EXAMPLE_ADDRESS\n+        else:\n+            self._raise_exc()\n+    \n+    def send(self, data):\n+        self.send_called = True\n+        self.send_buffer += data\n+        \n+        if self._err == NO_ERROR:\n+            return len(data)\n+        else:\n+            self._raise_exc()\n+    \n+    def sendto(self, data, addr):\n+        self.sendto_called = True\n+        self.sendto_addr = addr\n+        self.send_buffer += data\n+        \n+        if self._err == NO_ERROR:\n+            return len(data)\n+        else:\n+            self._raise_exc()\n+\n+class MockChannel(Channel):\n+    def __init__(self, **kwargs):\n+        Channel.__init__(self, **kwargs)\n+        \n+        self.close_called = False\n+        self.handle_read_event_called = False\n+        self.handle_write_event_called = False\n+    \n+    def close(self):    \n+        self.close_called = True\n+        \n+        self._socket = None\n+        self.fileno = None\n+    \n+    def closed(self):\n+        return False\n+    \n+    def _handle_read_event(self):\n+        self.handle_read_event_called = True\n+    \n+    def _handle_write_event(self):\n+        self.handle_write_event_called = True\n+\n+\n+###############################################################################\n+# __init__() Tests\n+###############################################################################\n+\n+def test_init():\n+    chan = Channel()\n+    \n+    assert isinstance(chan._socket, socket.socket)\n+    assert chan._socket.family == socket.AF_INET\n+    assert chan._socket.type == socket.SOCK_STREAM\n+\n+def test_init_with_socket():\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    chan = Channel(socket=sock)\n+    \n+    assert chan._socket is sock\n+\n+def test_init_with_type():\n+    chan = Channel(type=socket.SOCK_DGRAM)\n+    \n+    assert chan._socket.type == socket.SOCK_DGRAM\n+\n+def test_init_with_socket_and_type():\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    chan = Channel(socket=sock, type=socket.SOCK_DGRAM)\n+    \n+    assert chan._socket is sock\n+\n+def test_init_adds_channel_to_Engine():\n+    engn = Engine.instance()\n+    chan = Channel()\n+    \n+    assert chan.fileno in engn._channels\n+    assert engn._channels[chan.fileno] is chan\n+\n+\n+###############################################################################\n+# _handle_events() tests\n+###############################################################################\n+\n+def test_handle_events_with_no_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.NONE)\n+    \n+    assert not chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_read_event():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ)\n+    \n+    assert chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_write_event():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.WRITE)\n+    \n+    assert not chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_error_event():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.ERROR)\n+    \n+    assert not chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert chan.close_called\n+\n+def test_handle_events_with_read_and_write_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ | Engine.WRITE)\n+    \n+    assert chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_read_and_error_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ | Engine.ERROR)\n+    \n+    assert chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert chan.close_called\n+\n+def test_handle_events_with_write_and_error_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.WRITE | Engine.ERROR)\n+    \n+    assert not chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert chan.close_called\n+\n+def test_handle_events_with_read_write_and_error_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ | Engine.WRITE | Engine.ERROR)\n+    \n+    assert chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert chan.close_called\n+\n+# TODO Improve coverage of final block in _handle_events()\n+\n+\n+###############################################################################\n+# _socket_set() tests\n+###############################################################################\n+\n+def test_socket_set_with_default_socket():\n+    chan = MockChannel()\n+    chan.close()\n+    sock = socket.socket()\n+    sock.setblocking(True)\n+    \n+    chan._socket_set(sock)\n+    \n+    assert chan._socket is sock\n+    assert chan.fileno == sock.fileno()\n+    assert chan._socket.gettimeout() == 0, "Socket should be non-blocking."\n+\n+def test_socket_set_when_channel_has_a_preexisting_socket():\n+    chan = MockChannel()\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    \n+    try:\n+        chan._socket_set(sock)\n+        assert False, "RuntimeError should be raised."\n+    except RuntimeError:\n+        assert True\n+\n+def test_socket_set_with_socket_with_unsupported_family():\n+    chan = MockChannel()\n+    chan.close()\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    \n+    # A little trickery is required here to get around actual OS\n+    # constraints on socket families.\n+    old_supported_families = pants.channel.SUPPORTED_FAMILIES\n+    try:\n+        pants.channel.SUPPORTED_FAMILIES = ()\n+        try:\n+            chan._socket_set(sock)\n+            assert False, "ValueError should be raised."\n+        except ValueError:\n+            assert True\n+    finally:\n+        pants.channel.SUPPORTED_FAMILIES = old_supported_families\n+\n+def test_socket_set_with_socket_with_unsupported_type():\n+    chan = MockChannel()\n+    chan.close()\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    \n+    # A little trickery is required here to get around actual OS\n+    # constraints on socket types.\n+    old_supported_types = pants.channel.SUPPORTED_TYPES\n+    try:\n+        pants.channel.SUPPORTED_TYPES = ()\n+        try:\n+            chan._socket_set(sock)\n+            assert False, "ValueError should be raised."\n+        except ValueError:\n+            assert True\n+    finally:\n+        pants.channel.SUPPORTED_TYPES = old_supported_types\n+\n+\n+###############################################################################\n+# _socket_connect() tests\n+###############################################################################\n+\n+def test_socket_connect():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_connect(EXAMPLE_ADDRESS)\n+    \n+    assert ret\n+    assert sock.connect_ex_addr == EXAMPLE_ADDRESS\n+\n+def test_socket_connect_when_channel_is_already_connected():\n+    sock = MockSocket(errno.EISCONN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_connect(EXAMPLE_ADDRESS)\n+    \n+    assert ret\n+\n+def test_socket_connect_when_connection_is_already_in_progress():\n+    sock = MockSocket(errno.EINPROGRESS)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_connect(EXAMPLE_ADDRESS)\n+    \n+    assert not ret\n+\n+def test_socket_connect_when_uncaught_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_connect(EXAMPLE_ADDRESS)\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_listen() tests\n+###############################################################################\n+\n+def test_socket_listen():\n+    chan = MockChannel()\n+    \n+    chan._readable = True\n+    chan._socket_listen(1024)\n+    \n+    assert not chan._readable\n+\n+# TODO Should we test the backlog adjustment here?\n+\n+\n+###############################################################################\n+# _socket_close() tests\n+###############################################################################\n+\n+def test_socket_close():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    chan._socket_close()\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+def test_socket_close_when_AttributeError_is_raised():\n+    sock = MockSocket(AN_ERROR, AttributeError)\n+    chan = MockChannel(socket=sock)\n+    \n+    chan._socket_close()\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+def test_socket_close_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR, socket.error)\n+    chan = MockChannel(socket=sock)\n+    \n+    chan._socket_close()\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+def test_socket_close_when_Exception_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR, Exception)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_close()\n+        assert False, "Exception should be raised."\n+    except Exception:\n+        assert True\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+\n+###############################################################################\n+# _socket_accept() tests\n+###############################################################################\n+\n+def test_socket_accept():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_accept()\n+    \n+    assert sock.accept_called\n+    assert ret == (None, EXAMPLE_ADDRESS)\n+\n+def test_socket_accept_when_accept_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_accept()\n+    \n+    assert sock.accept_called\n+    assert ret == (None, ())\n+    assert not chan._readable\n+\n+def test_socket_accept_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        ret = chan._socket_accept()\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_recv() tests\n+###############################################################################\n+\n+def test_socket_recv():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recv()\n+    \n+    assert ret == EXAMPLE_STRING\n+\n+# TODO Test None return value?\n+\n+def test_socket_recv_when_recv_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recv()\n+    \n+    assert ret == \'\'\n+    assert not chan._readable\n+\n+def test_socket_recv_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_recv()\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_recvfrom() tests\n+###############################################################################\n+\n+def test_socket_recvfrom():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recvfrom()\n+    \n+    assert ret == (EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+\n+# TODO Test None return value?\n+\n+def test_socket_recvfrom_when_recvfrom_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recvfrom()\n+    \n+    assert ret == (\'\', None)\n+    assert not chan._readable\n+\n+def test_socket_recvfrom_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_recvfrom()\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_send() tests\n+###############################################################################\n+\n+def test_socket_send():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_send(EXAMPLE_STRING)\n+    \n+    assert ret == EXAMPLE_STRING_LENGTH\n+    assert sock.send_buffer == EXAMPLE_STRING\n+\n+def test_socket_send_when_send_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_send(EXAMPLE_STRING)\n+    \n+    assert ret == 0\n+    assert not chan._writable\n+\n+def test_socket_send_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_send(EXAMPLE_STRING)\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_sendto() tests\n+###############################################################################\n+\n+def test_socket_sendto():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+    \n+    assert ret == EXAMPLE_STRING_LENGTH\n+    assert sock.send_buffer == EXAMPLE_STRING\n+    assert sock.sendto_addr == EXAMPLE_ADDRESS\n+\n+def test_socket_sendto_when_sendto_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+    \n+    assert ret == 0\n+    assert not chan._writable\n+\n+def test_socket_sendto_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n', 'commit_subject': 'Added pants.channel unit tests.', 'repo_name': 'ecdavis/pants', 'committer': {'name': 'Chris Davis', 'email': '0e382076ebf46bc5ba91ab2c5b2bbaf7733c2005@wtfrak.com', 'time_sec': '1303828660', 'tz_offset': '600', 'date': {'seconds': '1303828660'}}, 'commit_tree': '19bd2c8f7574f3339eb9f1a2e03d57b60bf89dd9', 'commit_message': 'Added pants.channel unit tests.\n', 'language_name': 'HTML', 'license': 'apache-2.0', 'hunks': '@@ -0,0 +1,629 @@\n+###############################################################################\n+#\n+# Copyright 2011 Chris Davis\n+#\n+# Licensed under the Apache License, Version 2.0 (the "License");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an "AS IS" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+#\n+###############################################################################\n+\n+###############################################################################\n+# Imports\n+###############################################################################\n+\n+import errno\n+import socket\n+\n+import pants.channel\n+from pants.channel import Channel\n+from pants.engine import Engine\n+\n+\n+###############################################################################\n+# Constants\n+###############################################################################\n+\n+NO_ERROR = 0\n+AN_ERROR = 1\n+# This is an error that cannot possibly be raised by a socket. It can\n+# be used in tests to mock a socket.error that absolutely won\'t match\n+# a "real" error.\n+IMPOSSIBLE_ERROR = errno.ENOTTY\n+\n+EXAMPLE_ADDRESS = (\'example.com\', 80)\n+\n+EXAMPLE_STRING = "foobarbaz"\n+EXAMPLE_STRING_LENGTH = 9\n+\n+\n+\n+###############################################################################\n+# Mock Objects\n+###############################################################################\n+\n+class MockSocket(object):\n+    def __init__(self, err=NO_ERROR, exc=socket.error):\n+        self._socket = socket.socket()\n+        self._exc = exc\n+        self._err = err\n+        \n+        self.connect_ex_called = False\n+        self.connect_ex_addr = None\n+        \n+        self.listen_called = False\n+        self.listen_backlog = None\n+        \n+        self.close_called = False\n+        \n+        self.accept_called = False\n+        \n+        self.recv_called = False\n+        \n+        self.recvfrom_called = False\n+        \n+        self.send_called = False\n+        self.send_buffer = ""\n+        \n+        self.sendto_called = False\n+        self.sendto_addr = None\n+        \n+        self._initted = True\n+    \n+    def __getattr__(self, key):\n+        return getattr(self._socket, key)\n+    \n+    def __setattr__(self, key, value):\n+        if not hasattr(self, "_initted") or hasattr(self, key):\n+            return object.__setattr__(self, key, value)\n+        else:\n+            return setattr(self._socket, key, value)\n+    \n+    def _raise_exc(self):\n+        raise self._exc(self._err)\n+    \n+    def connect_ex(self, addr):\n+        self.connect_ex_called = True\n+        self.connect_ex_addr = addr\n+        \n+        if self._err == NO_ERROR:\n+            return 0\n+        else:\n+            self._raise_exc()\n+    \n+    def listen(self, backlog):\n+        self.listen_backlog = backlog\n+        \n+        if self._err != NO_ERROR:\n+            self._raise_exc()\n+    \n+    def close(self):\n+        self.close_called = True\n+        \n+        if self._err != NO_ERROR:\n+            self._raise_exc()\n+    \n+    def accept(self):\n+        self.accept_called = True\n+        \n+        if self._err == NO_ERROR:\n+            return None, EXAMPLE_ADDRESS\n+        else:\n+            self._raise_exc()\n+    \n+    def recv(self, recv_amount):\n+        self.recv_called = True\n+        \n+        if self._err == NO_ERROR:\n+            return EXAMPLE_STRING\n+        else:\n+            self._raise_exc()\n+    \n+    def recvfrom(self, recv_amount):\n+        self.recvfrom_called = True\n+        \n+        if self._err == NO_ERROR:\n+            return EXAMPLE_STRING, EXAMPLE_ADDRESS\n+        else:\n+            self._raise_exc()\n+    \n+    def send(self, data):\n+        self.send_called = True\n+        self.send_buffer += data\n+        \n+        if self._err == NO_ERROR:\n+            return len(data)\n+        else:\n+            self._raise_exc()\n+    \n+    def sendto(self, data, addr):\n+        self.sendto_called = True\n+        self.sendto_addr = addr\n+        self.send_buffer += data\n+        \n+        if self._err == NO_ERROR:\n+            return len(data)\n+        else:\n+            self._raise_exc()\n+\n+class MockChannel(Channel):\n+    def __init__(self, **kwargs):\n+        Channel.__init__(self, **kwargs)\n+        \n+        self.close_called = False\n+        self.handle_read_event_called = False\n+        self.handle_write_event_called = False\n+    \n+    def close(self):    \n+        self.close_called = True\n+        \n+        self._socket = None\n+        self.fileno = None\n+    \n+    def closed(self):\n+        return False\n+    \n+    def _handle_read_event(self):\n+        self.handle_read_event_called = True\n+    \n+    def _handle_write_event(self):\n+        self.handle_write_event_called = True\n+\n+\n+###############################################################################\n+# __init__() Tests\n+###############################################################################\n+\n+def test_init():\n+    chan = Channel()\n+    \n+    assert isinstance(chan._socket, socket.socket)\n+    assert chan._socket.family == socket.AF_INET\n+    assert chan._socket.type == socket.SOCK_STREAM\n+\n+def test_init_with_socket():\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    chan = Channel(socket=sock)\n+    \n+    assert chan._socket is sock\n+\n+def test_init_with_type():\n+    chan = Channel(type=socket.SOCK_DGRAM)\n+    \n+    assert chan._socket.type == socket.SOCK_DGRAM\n+\n+def test_init_with_socket_and_type():\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    chan = Channel(socket=sock, type=socket.SOCK_DGRAM)\n+    \n+    assert chan._socket is sock\n+\n+def test_init_adds_channel_to_Engine():\n+    engn = Engine.instance()\n+    chan = Channel()\n+    \n+    assert chan.fileno in engn._channels\n+    assert engn._channels[chan.fileno] is chan\n+\n+\n+###############################################################################\n+# _handle_events() tests\n+###############################################################################\n+\n+def test_handle_events_with_no_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.NONE)\n+    \n+    assert not chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_read_event():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ)\n+    \n+    assert chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_write_event():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.WRITE)\n+    \n+    assert not chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_error_event():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.ERROR)\n+    \n+    assert not chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert chan.close_called\n+\n+def test_handle_events_with_read_and_write_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ | Engine.WRITE)\n+    \n+    assert chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert not chan.close_called\n+\n+def test_handle_events_with_read_and_error_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ | Engine.ERROR)\n+    \n+    assert chan.handle_read_event_called\n+    assert not chan.handle_write_event_called\n+    assert chan.close_called\n+\n+def test_handle_events_with_write_and_error_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.WRITE | Engine.ERROR)\n+    \n+    assert not chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert chan.close_called\n+\n+def test_handle_events_with_read_write_and_error_events():\n+    chan = MockChannel()\n+    \n+    chan._handle_events(Engine.READ | Engine.WRITE | Engine.ERROR)\n+    \n+    assert chan.handle_read_event_called\n+    assert chan.handle_write_event_called\n+    assert chan.close_called\n+\n+# TODO Improve coverage of final block in _handle_events()\n+\n+\n+###############################################################################\n+# _socket_set() tests\n+###############################################################################\n+\n+def test_socket_set_with_default_socket():\n+    chan = MockChannel()\n+    chan.close()\n+    sock = socket.socket()\n+    sock.setblocking(True)\n+    \n+    chan._socket_set(sock)\n+    \n+    assert chan._socket is sock\n+    assert chan.fileno == sock.fileno()\n+    assert chan._socket.gettimeout() == 0, "Socket should be non-blocking."\n+\n+def test_socket_set_when_channel_has_a_preexisting_socket():\n+    chan = MockChannel()\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    \n+    try:\n+        chan._socket_set(sock)\n+        assert False, "RuntimeError should be raised."\n+    except RuntimeError:\n+        assert True\n+\n+def test_socket_set_with_socket_with_unsupported_family():\n+    chan = MockChannel()\n+    chan.close()\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    \n+    # A little trickery is required here to get around actual OS\n+    # constraints on socket families.\n+    old_supported_families = pants.channel.SUPPORTED_FAMILIES\n+    try:\n+        pants.channel.SUPPORTED_FAMILIES = ()\n+        try:\n+            chan._socket_set(sock)\n+            assert False, "ValueError should be raised."\n+        except ValueError:\n+            assert True\n+    finally:\n+        pants.channel.SUPPORTED_FAMILIES = old_supported_families\n+\n+def test_socket_set_with_socket_with_unsupported_type():\n+    chan = MockChannel()\n+    chan.close()\n+    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+    \n+    # A little trickery is required here to get around actual OS\n+    # constraints on socket types.\n+    old_supported_types = pants.channel.SUPPORTED_TYPES\n+    try:\n+        pants.channel.SUPPORTED_TYPES = ()\n+        try:\n+            chan._socket_set(sock)\n+            assert False, "ValueError should be raised."\n+        except ValueError:\n+            assert True\n+    finally:\n+        pants.channel.SUPPORTED_TYPES = old_supported_types\n+\n+\n+###############################################################################\n+# _socket_connect() tests\n+###############################################################################\n+\n+def test_socket_connect():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_connect(EXAMPLE_ADDRESS)\n+    \n+    assert ret\n+    assert sock.connect_ex_addr == EXAMPLE_ADDRESS\n+\n+def test_socket_connect_when_channel_is_already_connected():\n+    sock = MockSocket(errno.EISCONN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_connect(EXAMPLE_ADDRESS)\n+    \n+    assert ret\n+\n+def test_socket_connect_when_connection_is_already_in_progress():\n+    sock = MockSocket(errno.EINPROGRESS)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_connect(EXAMPLE_ADDRESS)\n+    \n+    assert not ret\n+\n+def test_socket_connect_when_uncaught_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_connect(EXAMPLE_ADDRESS)\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_listen() tests\n+###############################################################################\n+\n+def test_socket_listen():\n+    chan = MockChannel()\n+    \n+    chan._readable = True\n+    chan._socket_listen(1024)\n+    \n+    assert not chan._readable\n+\n+# TODO Should we test the backlog adjustment here?\n+\n+\n+###############################################################################\n+# _socket_close() tests\n+###############################################################################\n+\n+def test_socket_close():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    chan._socket_close()\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+def test_socket_close_when_AttributeError_is_raised():\n+    sock = MockSocket(AN_ERROR, AttributeError)\n+    chan = MockChannel(socket=sock)\n+    \n+    chan._socket_close()\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+def test_socket_close_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR, socket.error)\n+    chan = MockChannel(socket=sock)\n+    \n+    chan._socket_close()\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+def test_socket_close_when_Exception_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR, Exception)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_close()\n+        assert False, "Exception should be raised."\n+    except Exception:\n+        assert True\n+    \n+    assert sock.close_called\n+    assert chan._socket is None\n+    assert chan.fileno is None\n+\n+\n+###############################################################################\n+# _socket_accept() tests\n+###############################################################################\n+\n+def test_socket_accept():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_accept()\n+    \n+    assert sock.accept_called\n+    assert ret == (None, EXAMPLE_ADDRESS)\n+\n+def test_socket_accept_when_accept_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_accept()\n+    \n+    assert sock.accept_called\n+    assert ret == (None, ())\n+    assert not chan._readable\n+\n+def test_socket_accept_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        ret = chan._socket_accept()\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_recv() tests\n+###############################################################################\n+\n+def test_socket_recv():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recv()\n+    \n+    assert ret == EXAMPLE_STRING\n+\n+# TODO Test None return value?\n+\n+def test_socket_recv_when_recv_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recv()\n+    \n+    assert ret == \'\'\n+    assert not chan._readable\n+\n+def test_socket_recv_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_recv()\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_recvfrom() tests\n+###############################################################################\n+\n+def test_socket_recvfrom():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recvfrom()\n+    \n+    assert ret == (EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+\n+# TODO Test None return value?\n+\n+def test_socket_recvfrom_when_recvfrom_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_recvfrom()\n+    \n+    assert ret == (\'\', None)\n+    assert not chan._readable\n+\n+def test_socket_recvfrom_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_recvfrom()\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_send() tests\n+###############################################################################\n+\n+def test_socket_send():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_send(EXAMPLE_STRING)\n+    \n+    assert ret == EXAMPLE_STRING_LENGTH\n+    assert sock.send_buffer == EXAMPLE_STRING\n+\n+def test_socket_send_when_send_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_send(EXAMPLE_STRING)\n+    \n+    assert ret == 0\n+    assert not chan._writable\n+\n+def test_socket_send_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_send(EXAMPLE_STRING)\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n+\n+\n+###############################################################################\n+# _socket_sendto() tests\n+###############################################################################\n+\n+def test_socket_sendto():\n+    sock = MockSocket()\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+    \n+    assert ret == EXAMPLE_STRING_LENGTH\n+    assert sock.send_buffer == EXAMPLE_STRING\n+    assert sock.sendto_addr == EXAMPLE_ADDRESS\n+\n+def test_socket_sendto_when_sendto_blocks():\n+    sock = MockSocket(errno.EAGAIN)\n+    chan = MockChannel(socket=sock)\n+    \n+    ret = chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+    \n+    assert ret == 0\n+    assert not chan._writable\n+\n+def test_socket_sendto_when_socket_error_is_raised():\n+    sock = MockSocket(IMPOSSIBLE_ERROR)\n+    chan = MockChannel(socket=sock)\n+    \n+    try:\n+        chan._socket_sendto(EXAMPLE_STRING, EXAMPLE_ADDRESS)\n+        assert False, "socket.error should be raised."\n+    except socket.error as e:\n+        assert e[0] == IMPOSSIBLE_ERROR\n', 'addition_count': 629, 'deletion_count': 0, 'src_file': '/dev/null', 'tgt_file': 'b/pants/test/test_channel.py', 'file_extension': '.py', 'before_file': 'ADDFILE', 'message': 'Added pants.channel unit tests.\n', 'author_name': 'Chris Davis', 'lang': 'py'}