You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/11/15 21:05:36 UTC

[12/31] qpid-proton git commit: PROTON-1176: Core dump if reactor creation fails

PROTON-1176: Core dump if reactor creation fails

Fixed wrapper construct bug that leaves fields uninitialized if the reactor
fails to create. Added test to verify that BlockingConnection raises a
ProtonException if there are not enough FDs, and does not crash.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/da7f5056
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/da7f5056
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/da7f5056

Branch: refs/heads/go1
Commit: da7f5056a45528196be6733fc56a1f41bda58ded
Parents: bdfe982
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 23 19:57:07 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 23 20:21:18 2017 +0100

----------------------------------------------------------------------
 proton-c/bindings/python/proton/wrapper.py |  3 ++
 tests/python/proton_tests/utils.py         | 40 +++++++++++++++++++++----
 2 files changed, 38 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da7f5056/proton-c/bindings/python/proton/wrapper.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/wrapper.py b/proton-c/bindings/python/proton/wrapper.py
index 8519646..f009de5 100644
--- a/proton-c/bindings/python/proton/wrapper.py
+++ b/proton-c/bindings/python/proton/wrapper.py
@@ -39,6 +39,9 @@ class Wrapper(object):
             # we are constructing a new object
             impl = impl_or_constructor()
             if impl is None:
+                self.__dict__["_impl"] = impl
+                self.__dict__["_attrs"] = EMPTY_ATTRS
+                self.__dict__["_record"] = None
                 from proton import ProtonException
                 raise ProtonException("Wrapper failed to create wrapped object. Check for file descriptor or memory exhaustion.")
             init = True

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da7f5056/tests/python/proton_tests/utils.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/utils.py b/tests/python/proton_tests/utils.py
index 52d0dc2..72711c7 100644
--- a/tests/python/proton_tests/utils.py
+++ b/tests/python/proton_tests/utils.py
@@ -22,7 +22,7 @@ from threading import Thread, Event
 from unittest import TestCase
 from proton_tests.common import Test, free_tcp_port
 from copy import copy
-from proton import Message, Url, generate_uuid, Array, UNDESCRIBED, Data, symbol, ConnectionException
+from proton import Message, Url, generate_uuid, Array, UNDESCRIBED, Data, symbol, ConnectionException, ProtonException
 from proton.handlers import MessagingHandler
 from proton.reactor import Container
 from proton.utils import SyncRequestResponse, BlockingConnection
@@ -53,7 +53,7 @@ class EchoServer(MessagingHandler, Thread):
         self.acceptor = event.container.listen(self.url)
         self.container = event.container
         self.event.set()
-        
+
     def on_link_opening(self, event):
         if event.link.is_sender:
             if event.link.remote_source and event.link.remote_source.dynamic:
@@ -89,14 +89,14 @@ class ConnPropertiesServer(EchoServer):
 
      def on_connection_opening(self, event):
         conn = event.connection
-                   
+
         if conn.remote_properties == CONNECTION_PROPERTIES:
             self.properties_received = True
         if conn.remote_offered_capabilities == OFFERED_CAPABILITIES:
             self.offered_capabilities_received = True
         if conn.remote_desired_capabilities == DESIRED_CAPABILITIES:
             self.desired_capabilities_received = True
-        
+
 class SyncRequestResponseTest(Test):
     """Test SyncRequestResponse"""
 
@@ -135,7 +135,7 @@ class SyncRequestResponseTest(Test):
         self.assertEquals(server.desired_capabilities_received, True)
 
     def test_allowed_mechs_external(self):
-        # All this test does it make sure that if we pass allowed_mechs to BlockingConnection, it is actually used. 
+        # All this test does it make sure that if we pass allowed_mechs to BlockingConnection, it is actually used.
         port = free_tcp_port()
         server = ConnPropertiesServer(Url(host="127.0.0.1", port=port), timeout=self.timeout)
         server.start()
@@ -162,3 +162,33 @@ class SyncRequestResponseTest(Test):
         self.assertEquals(server.offered_capabilities_received, True)
         self.assertEquals(server.desired_capabilities_received, True)
 
+class OutOfFdsTest(Test):
+
+    def test_out_of_fds(self):
+        """Create BlockingConnections until we run out of FDs, make sure we get an exception
+        and not a crash"""
+
+        server = EchoServer(Url(host="127.0.0.1", port=free_tcp_port()), self.timeout)
+        server.start()
+        server.wait()
+
+        # Use up all the FDs
+        dummy = os.tmpfile()
+        fds = []
+        try:
+            while True: fds.append(os.dup(dummy.fileno()));
+        except OSError, e:
+            pass
+
+        for i in [0, 1]:        # Check the odd and even case
+            try:
+                BlockingConnection(server.url)
+                fail("Expected ProtonException")
+            except ProtonException, e:
+                pass
+            os.close(fds.pop())
+
+        for f in fds: os.close(f)
+        c = BlockingConnection(server.url, timeout=self.timeout)
+        c.close()
+        server.join(timeout=self.timeout)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org