Browse Source

[1428] Accumulating incoming data

Michal 'vorner' Vaner 13 years ago
parent
commit
024808d2a4
2 changed files with 38 additions and 2 deletions
  1. 15 1
      src/bin/bind10/bind10_src.py.in
  2. 23 1
      src/bin/bind10/tests/bind10_test.py.in

+ 15 - 1
src/bin/bind10/bind10_src.py.in

@@ -883,12 +883,26 @@ class BoB:
         """
         (sock, previous) = self._unix_sockets[socket_fileno]
         while True:
-            data = sock.recv(1, socket.MSG_DONTWAIT)
+            try:
+                data = sock.recv(1, socket.MSG_DONTWAIT)
+            except socket.error as se:
+                # These two might be different on some systems
+                if se.errno == errno.EAGAIN or se.errno == errno.EWOULDBLOCK:
+                    # No more data now. Oh, well, just store what we have.
+                    self._unix_sockets[socket_fileno] = (sock, previous)
+                    return
+                else:
+                    pass # TODO What now? Drop the socket?
             if len(data) == 0: # The socket got to it's end
                 del self._unix_sockets[socket_fileno]
                 self.socket_consumer_dead(sock)
                 sock.close()
                 return
+            else:
+                if data == b"\n":
+                    pass
+                else:
+                    previous += data
 
     def run(self, wakeup_fd):
         """

+ 23 - 1
src/bin/bind10/tests/bind10_test.py.in

@@ -29,6 +29,7 @@ from isc.net.addr import IPAddr
 import time
 import isc
 import isc.log
+import errno
 
 from isc.testutils.parse_args import TestOptParser, OptsError
 
@@ -943,6 +944,7 @@ class SocketSrvTest(unittest.TestCase):
         self.__select_called = None
         self.__socket_data_called = None
         self.__consumer_dead_called = None
+        self.__socket_request_handler_called = None
 
     def tearDown(self):
         """
@@ -970,7 +972,12 @@ class SocketSrvTest(unittest.TestCase):
             self.__owner.assertEqual(1, bufsize)
             self.__owner.assertEqual(socket.MSG_DONTWAIT, flags)
             if self.data is not None:
-                pass # TODO
+                if len(self.data):
+                    result = self.data[0:1]
+                    self.data = self.data[1:]
+                    return result
+                else:
+                    raise socket.error(errno.EAGAIN, "Would block")
             else:
                 return b''
 
@@ -1061,6 +1068,9 @@ class SocketSrvTest(unittest.TestCase):
     def __consumer_dead(self, socket):
         self.__consumer_dead_called = socket
 
+    def __socket_request_handler(self, token, socket):
+        self.__socket_request_handler_called = (token, socket)
+
     def test_socket_closed(self):
         """
         Test that a socket is removed and the socket_consumer_dead is called
@@ -1072,6 +1082,18 @@ class SocketSrvTest(unittest.TestCase):
         self.assertEqual({}, self.__boss._unix_sockets)
         self.assertTrue(socket.closed)
 
+    def test_socket_short(self):
+        """
+        Test that if there's not enough data to get the whole socket, it is
+        kept there, but nothing is called.
+        """
+        socket = self.__prepare_data(b'tok')
+        self.__boss._socket_data(13)
+        self.assertEqual({13: (socket, b'tok')}, self.__boss._unix_sockets)
+        self.assertFalse(socket.closed)
+        self.assertIsNone(self.__consumer_dead_called)
+        self.assertIsNone(self.__socket_request_handler_called)
+
 if __name__ == '__main__':
     # store os.environ for test_unchanged_environment
     original_os_environ = copy.deepcopy(os.environ)