DISPATCH-451: Incorporate review comments; add self tests

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

Branch: refs/heads/master
Commit: f1dbfbf6dd73b4068440f235be38906944c35b59
Parents: c248a34
Author: Chuck Rolke <[email protected]>
Authored: Fri Oct 7 17:23:31 2016 -0400
Committer: Chuck Rolke <[email protected]>
Committed: Fri Oct 7 17:23:31 2016 -0400

----------------------------------------------------------------------
 include/qpid/dispatch/amqp.h                    |   7 +
 include/qpid/dispatch/server.h                  |  13 +-
 python/qpid_dispatch/management/qdrouter.json   |  22 +-
 .../qdrouter.policyRuleset.settings.txt         |   4 +-
 src/connection_manager.c                        |  32 +-
 src/container.c                                 |   3 +-
 src/policy.c                                    |   3 +-
 tests/CMakeLists.txt                            |   1 +
 tests/system_tests_protocol_settings.py         | 316 +++++++++++++++++++
 9 files changed, 372 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/include/qpid/dispatch/amqp.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/amqp.h b/include/qpid/dispatch/amqp.h
index 3f9c778..bda1300 100644
--- a/include/qpid/dispatch/amqp.h
+++ b/include/qpid/dispatch/amqp.h
@@ -30,6 +30,13 @@
 
 
 /**
+ * AMQP Constants
+ */
+typedef enum {
+    QD_AMQP_MIN_MAX_FRAME_SIZE = 512
+} qd_amqp_constants_t;
+
+/**
  * AMQP Performative Tags
  */
 typedef enum {

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/include/qpid/dispatch/server.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/server.h b/include/qpid/dispatch/server.h
index 6e6f503..de20385 100644
--- a/include/qpid/dispatch/server.h
+++ b/include/qpid/dispatch/server.h
@@ -419,19 +419,16 @@ typedef struct qd_server_config_t {
 
     /**
      * The max_sessions value is the number of sessions allowed on the 
Connection. 
-     * This value minus one is the Open performative channel-max setting.
      */
     uint32_t max_sessions;
 
     /**
-     * The max_session_window value is the maximum number of outstanding 
octets that are
-     * allowed to be in flight on a session. This value is used to calculate 
the number of
-     * outstanding transfers that are allowed by the formula:
-     *   incoming_window = max_session_window / max_frame_size
-     * If max_session_window=1000000 and max_frame_size=32768 then 30 
transfers may
-     * be outstanding before session flow control begins.
+     * The incoming capacity value is calculated to be (sessionMaxFrames * 
maxFrameSize).
+     * In a round about way the calculation forces the AMQP 
Begin/incoming-capacity value
+     * to equal the specified sessionMaxFrames value measured in units of 
transfer frames.
+     * This calculation is done to satisfy proton 
pn_session_set_incoming_capacity().
      */
-    uint32_t max_session_window;
+    uint32_t incoming_capacity;
 
     /**
      * The idle timeout, in seconds.  If the peer sends no data frames in this 
many seconds, the

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/python/qpid_dispatch/management/qdrouter.json
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch/management/qdrouter.json 
b/python/qpid_dispatch/management/qdrouter.json
index 8113140..c57a3c1 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -609,19 +609,19 @@
                 "maxFrameSize": {
                     "type": "integer",
                     "default": 16384,
-                    "description": "Defaults to 16384.  If specified, it is 
the maximum frame size in octets that will be used in the connection-open 
negotiation with a connected peer.  The frame size is the largest contiguous 
set of uninterrupted data that can be sent for a message delivery over the 
connection. Interleaving of messages on different links is done at frame 
granularity. Policy settings, if specified, will overwrite this value.",
+                    "description": "The maximum frame size in octets that will 
be used in the connection-open negotiation with a connected peer.  The frame 
size is the largest contiguous set of uninterrupted data that can be sent for a 
message delivery over the connection. Interleaving of messages on different 
links is done at frame granularity. Policy settings, if specified, will 
overwrite this value. Defaults to 16384.",
                     "create": true
                 },
                 "maxSessions": {
                     "type": "integer",
                     "default": 32768,
-                    "description": "Defaults to 32768.  The maximum number of 
sessions that can be simultaneously active on the connection. Setting this 
value to zero selects the default number of sessions. Policy settings, if 
specified, will overwrite this value.",
+                    "description": "The maximum number of sessions that can be 
simultaneously active on the connection. Setting this value to zero selects the 
default number of sessions. Policy settings, if specified, will overwrite this 
value. Defaults to 32768.",
                     "create": true
                 },
-                "maxSessionWindow": {
+                "maxSessionFrames": {
                     "type": "integer",
-                    "description": "Incoming window measured in octets for 
sessions created on this connection. The AMQP negotiated session incoming 
window, measured in transfers, is calculated to be (maxSessionWindow / 
maxFrameSize). Setting this value to zero selects the default session window 
size. Policy settings, if specified, will overwrite this value.",
-                    "default": 1000000,
+                    "description": "Session incoming window measured in 
transfer frames for sessions created on this connection. This is the number of 
transfer frames that may simultaneously be in flight for all links in the 
session. Setting this value to zero selects the default session window size. 
Policy settings, if specified, will overwrite this value. Defaults to 100.",
+                    "default": 100,
                     "required": false,
                     "create": true
                 },
@@ -734,20 +734,20 @@
                 },
                 "maxFrameSize": {
                     "type": "integer",
-                    "default": 65536,
-                    "description": "Maximum frame size in octets that will be 
used in the connection-open negotiation with a connected peer.  The frame size 
is the largest contiguous set of uninterrupted data that can be sent for a 
message delivery over the connection. Interleaving of messages on different 
links is done at frame granularity. Policy settings, if specified, will 
overwrite this value.",
+                    "default": 16384,
+                    "description": "The maximum frame size in octets that will 
be used in the connection-open negotiation with a connected peer.  The frame 
size is the largest contiguous set of uninterrupted data that can be sent for a 
message delivery over the connection. Interleaving of messages on different 
links is done at frame granularity. Policy settings will not overwrite this 
value. Defaults to 16384.",
                     "create": true
                 },
                 "maxSessions": {
                     "type": "integer",
                     "default": 32768,
-                    "description": "Defaults to 32768.  The maximum number of 
sessions that can be simultaneously active on the connection. Setting this 
value to zero selects the default number of sessions. Policy settings, if 
specified, will overwrite this value.",
+                    "description": "The maximum number of sessions that can be 
simultaneously active on the connection. Setting this value to zero selects the 
default number of sessions. Policy settings will not overwrite this value. 
Defaults to 32768.",
                     "create": true
                 },
-                "maxSessionWindow": {
+                "maxSessionFrames": {
                     "type": "integer",
-                    "description": "Incoming window measured in octets for 
sessions created on this connection. The AMQP negotiated session incoming 
window, measured in transfers, is calculated to be (maxSessionWindow / 
maxFrameSize). Setting this value to zero selects the default session window 
size. Policy settings, if specified, will overwrite this value.",
-                    "default": 1000000,
+                    "description": "Session incoming window measured in 
transfer frames for sessions created on this connection. This is the number of 
transfer frames that may simultaneously be in flight for all links in the 
session. Setting this value to zero selects the default session window size. 
Policy settings will not overwrite this value. Defaults to 100.",
+                    "default": 100,
                     "required": false,
                     "create": true
                 },

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/python/qpid_dispatch/management/qdrouter.policyRuleset.settings.txt
----------------------------------------------------------------------
diff --git 
a/python/qpid_dispatch/management/qdrouter.policyRuleset.settings.txt 
b/python/qpid_dispatch/management/qdrouter.policyRuleset.settings.txt
index db85f47..fe2a6f2 100644
--- a/python/qpid_dispatch/management/qdrouter.policyRuleset.settings.txt
+++ b/python/qpid_dispatch/management/qdrouter.policyRuleset.settings.txt
@@ -42,7 +42,7 @@ Until the schema is extended specify embedded maps this 
document describes the v
           "maxFrameSize": {
               "type": "integer",
               "description": "Largest frame that may be sent on this 
connection. Zero implies system default. Policy setting overwrites values 
specified for a listener or connector. (AMQP Open, max-frame-size)",
-              "default": 65536,
+              "default": 16384,
               "required": false,
               "create": true
           },
@@ -56,7 +56,7 @@ Until the schema is extended specify embedded maps this 
document describes the v
           "maxSessionWindow": {
               "type": "integer",
               "description": "Largest incoming window in octets for sessions 
created on this connection. Zero implies system default. Policy setting 
overwrites values specified for a listener or connector. (AMQP Begin, 
incoming-window)",
-              "default": 1000000,
+              "default": 1638400,
               "required": false,
               "create": true
           },

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/src/connection_manager.c
----------------------------------------------------------------------
diff --git a/src/connection_manager.c b/src/connection_manager.c
index 96b85f1..2c9d549 100644
--- a/src/connection_manager.c
+++ b/src/connection_manager.c
@@ -184,7 +184,7 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, 
qd_server_config_t *conf
     config->protocol_family      = qd_entity_opt_string(entity, 
"protocolFamily", 0); CHECK();
     config->max_frame_size       = qd_entity_get_long(entity, "maxFrameSize"); 
       CHECK();
     config->max_sessions         = qd_entity_get_long(entity, "maxSessions");  
       CHECK();
-    config->max_session_window   = qd_entity_get_long(entity, 
"maxSessionWindow");    CHECK();
+    uint64_t ssn_frames          = qd_entity_get_long(entity, 
"maxSessionFrames");    CHECK();
     config->idle_timeout_seconds = qd_entity_get_long(entity, 
"idleTimeoutSeconds");  CHECK();
     config->sasl_username        = qd_entity_opt_string(entity, 
"saslUsername", 0);   CHECK();
     config->sasl_password        = qd_entity_opt_string(entity, 
"saslPassword", 0);   CHECK();
@@ -199,11 +199,35 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, 
qd_server_config_t *conf
     if (config->link_capacity == 0)
         config->link_capacity = 250;
 
-    if (config->max_sessions == 0)
+    if (config->max_sessions == 0 || config->max_sessions > 32768)
+        // Proton disallows > 32768
         config->max_sessions = 32768;
 
-    if (config->max_session_window == 0)
-        config->max_session_window = 1000000;
+    if (config->max_frame_size < QD_AMQP_MIN_MAX_FRAME_SIZE)
+        // Silently promote the minimum max-frame-size
+        // Proton will do this but the number is needed for the
+        // incoming capacity calculation.
+        config->max_frame_size = QD_AMQP_MIN_MAX_FRAME_SIZE;
+
+    //
+    // Given session frame count and max frame size compute session 
incoming_capacity
+    // Limit total capacity to 2^31-1.
+    // 
+    uint64_t mfs      = (uint64_t)config->max_frame_size;
+    uint64_t trial_ic = ssn_frames * mfs;
+    uint64_t limit    = (1ll << 31) - 1;
+    if (trial_ic < limit) {
+        // Silently promote incoming capacity of zero to one
+        config->incoming_capacity = 
+            (trial_ic < QD_AMQP_MIN_MAX_FRAME_SIZE ? 
QD_AMQP_MIN_MAX_FRAME_SIZE : trial_ic);
+    } else {
+        config->incoming_capacity = limit;
+        uint64_t computed_ssn_frames = limit / mfs;
+        qd_log(qd->connection_manager->log_source, QD_LOG_WARNING,
+               "Server configuation for I/O adapter entity name:'%s', 
host:'%s', port:'%s', "
+               "requested maxSessionFrames truncated from %llu to %llu",
+               config->name, config->host, config->port, ssn_frames, 
computed_ssn_frames);
+    }
 
     //
     // For now we are hardwiring this attribute to true.  If there's an outcry 
from the

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/src/container.c
----------------------------------------------------------------------
diff --git a/src/container.c b/src/container.c
index f9cc64b..e3f181a 100644
--- a/src/container.c
+++ b/src/container.c
@@ -764,10 +764,9 @@ qd_link_t *qd_link(qd_node_t *node, qd_connection_t *conn, 
qd_direction_t dir, c
 {
     qd_link_t *link = new_qd_link_t();
     const qd_server_config_t * cf = qd_connection_config(conn);
-    assert(cf);
 
     link->pn_sess = pn_session(qd_connection_pn(conn));
-    pn_session_set_incoming_capacity(link->pn_sess, cf->max_session_window);
+    pn_session_set_incoming_capacity(link->pn_sess, cf->incoming_capacity);
 
     if (dir == QD_OUTGOING)
         link->pn_link = pn_sender(link->pn_sess, name);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/src/policy.c
----------------------------------------------------------------------
diff --git a/src/policy.c b/src/policy.c
index a90a796..ad6bb1f 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -438,8 +438,7 @@ void qd_policy_apply_session_settings(pn_session_t *ssn, 
qd_connection_t *qd_con
         capacity = qd_conn->policy_settings->maxSessionWindow;
     } else {
         const qd_server_config_t * cf = qd_connection_config(qd_conn);
-        assert(cf);
-        capacity = cf->max_session_window;
+        capacity = cf->incoming_capacity;
     }
     pn_session_set_incoming_capacity(ssn, capacity);
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index eb04e82..6bc0e74 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -78,6 +78,7 @@ foreach(py_test_module
     system_tests_one_router
     system_tests_policy
     system_tests_protocol_family
+    system_tests_protocol_settings
     system_tests_qdmanage
     system_tests_qdstat
     system_tests_sasl_plain

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f1dbfbf6/tests/system_tests_protocol_settings.py
----------------------------------------------------------------------
diff --git a/tests/system_tests_protocol_settings.py 
b/tests/system_tests_protocol_settings.py
new file mode 100644
index 0000000..79f2f03
--- /dev/null
+++ b/tests/system_tests_protocol_settings.py
@@ -0,0 +1,316 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+import unittest
+from proton import Message, Delivery, PENDING, ACCEPTED, REJECTED
+from system_test import TestCase, Qdrouterd, main_module
+from proton.handlers import MessagingHandler
+from proton.reactor import Container, AtMostOnce, AtLeastOnce
+from proton.utils import BlockingConnection, SyncRequestResponse
+from qpid_dispatch.management.client import Node
+from proton import ConnectionException
+
+class MaxFrameMaxSessionFramesTest(TestCase):
+    """System tests setting proton negotiated size max-frame-size and 
incoming-window"""
+    @classmethod
+    def setUpClass(cls):
+        '''Start a router'''
+        super(MaxFrameMaxSessionFramesTest, cls).setUpClass()
+        name = "MaxFrameMaxSessionFrames"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxFrameSize': '2048', 'maxSessionFrames': '10'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_frame_max_session_frames__max_sessions_default(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxFrameMaxSessionFrames.log', 'r') as 
router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # max-frame is from the config
+            self.assertTrue(' max-frame-size=2048,' in open_lines[0])
+            # channel-max is default
+            self.assertTrue(" channel-max=32767" in open_lines[0])
+            begin_lines = [s for s in log_lines if "-> @begin" in s]
+            # incoming-window is from the config
+            self.assertTrue(" incoming-window=10," in begin_lines[0] )
+
+
+class MaxSessionsTest(TestCase):
+    """System tests setting proton channel-max"""
+    @classmethod
+    def setUpClass(cls):
+        """Start a router and a messenger"""
+        super(MaxSessionsTest, cls).setUpClass()
+        name = "MaxSessions"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxSessions': '10'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_sessions(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxSessions.log', 'r') as router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # channel-max is 10
+            self.assertTrue(" channel-max=9" in open_lines[0])
+
+
+class MaxSessionsZeroTest(TestCase):
+    """System tests setting proton channel-max"""
+    @classmethod
+    def setUpClass(cls):
+        """Start a router and a messenger"""
+        super(MaxSessionsZeroTest, cls).setUpClass()
+        name = "MaxSessionsZero"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxSessions': '0'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_sessions_zero(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxSessionsZero.log', 'r') as router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # channel-max is 0. Should get proton default 32767
+            self.assertTrue(" channel-max=32767" in open_lines[0])
+
+
+class MaxSessionsLargeTest(TestCase):
+    """System tests setting proton channel-max"""
+    @classmethod
+    def setUpClass(cls):
+        """Start a router and a messenger"""
+        super(MaxSessionsLargeTest, cls).setUpClass()
+        name = "MaxSessionsLarge"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxSessions': '500000'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_sessions_large(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxSessionsLarge.log', 'r') as router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # channel-max is 0. Should get proton default 32767
+            self.assertTrue(" channel-max=32767" in open_lines[0])
+
+
+class MaxFrameSmallTest(TestCase):
+    """System tests setting proton max-frame-size"""
+    @classmethod
+    def setUpClass(cls):
+        """Start a router and a messenger"""
+        super(MaxFrameSmallTest, cls).setUpClass()
+        name = "MaxFrameSmall"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxFrameSize': '2'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_frame_small(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxFrameSmall.log', 'r') as router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # if frame size <= 512 proton set min of 512
+            self.assertTrue(" max-frame-size=512" in open_lines[0])
+
+
+class MaxFrameDefaultTest(TestCase):
+    """System tests setting proton max-frame-size"""
+    @classmethod
+    def setUpClass(cls):
+        """Start a router and a messenger"""
+        super(MaxFrameDefaultTest, cls).setUpClass()
+        name = "MaxFrameDefault"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port()}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_frame_default(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxFrameDefault.log', 'r') as router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # if frame size not set then a default is used
+            self.assertTrue(" max-frame-size=16384" in open_lines[0])
+
+
+class MaxSessionFramesDefaultTest(TestCase):
+    """System tests setting proton max-frame-size"""
+    @classmethod
+    def setUpClass(cls):
+        """Start a router and a messenger"""
+        super(MaxSessionFramesDefaultTest, cls).setUpClass()
+        name = "MaxSessionFramesDefault"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port()}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_session_frames_default(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxSessionFramesDefault.log', 'r') as 
router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # if frame size not set then a default is used
+            self.assertTrue(" max-frame-size=16384" in open_lines[0])
+            begin_lines = [s for s in log_lines if "-> @begin" in s]
+            # incoming-window is from the config
+            self.assertTrue(" incoming-window=100," in begin_lines[0])
+
+
+class MaxFrameMaxSessionFramesTooBigTest(TestCase):
+    """
+    System tests setting proton negotiated size max-frame-size and 
incoming-window
+    when the product of the two is > 2^31-1. There must be a warning and the 
incoming
+    window will be reduced to 2^31-1 / max-frame-size
+    """
+    @classmethod
+    def setUpClass(cls):
+        '''Start a router'''
+        super(MaxFrameMaxSessionFramesTooBigTest, cls).setUpClass()
+        name = "MaxFrameMaxSessionFramesTooBig"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxFrameSize': '1000000', 'maxSessionFrames': '5000000'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_frame_max_session_too_big(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxFrameMaxSessionFramesTooBig.log', 'r') as 
router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # max-frame is from the config
+            self.assertTrue(' max-frame-size=1000000,' in open_lines[0])
+            begin_lines = [s for s in log_lines if "-> @begin" in s]
+            # incoming-window is truncated
+            self.assertTrue(" incoming-window=2147," in begin_lines[0])
+            warning_lines = [s for s in log_lines if "(warning)" in s]
+            self.assertTrue(len(warning_lines) == 1)
+            self.assertTrue("requested maxSessionFrames truncated from 5000000 
to 2147" in warning_lines[0])
+
+
+class MaxFrameMaxSessionFramesZeroTest(TestCase):
+    """
+    System tests setting proton negotiated size max-frame-size and 
incoming-window
+    when they are both zero. Frame size is bumped up to the minimum and 
capacity is
+    bumped up to have an incoming window of 1
+    """
+    @classmethod
+    def setUpClass(cls):
+        '''Start a router'''
+        super(MaxFrameMaxSessionFramesZeroTest, cls).setUpClass()
+        name = "MaxFrameMaxSessionFramesZero"
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR'}),
+
+            ('listener', {'host': '0.0.0.0', 'port': cls.tester.get_port(), 
'maxFrameSize': '0', 'maxSessionFrames': '0'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_max_frame_max_session_zero(self):
+        # Set up a connection to get the Open and a receiver to get a Begin 
frame in the log
+        bc = BlockingConnection(self.router.addresses[0])
+        bc.create_receiver("xxx")
+        bc.close()
+
+        with  open('../setUpClass/MaxFrameMaxSessionFramesZero.log', 'r') as 
router_log:
+            log_lines = router_log.read().split("\n")
+            open_lines = [s for s in log_lines if "-> @open" in s]
+            # max-frame gets set to protocol min
+            self.assertTrue(' max-frame-size=512,' in open_lines[0])
+            begin_lines = [s for s in log_lines if "-> @begin" in s]
+            # incoming-window is promoted to 1
+            self.assertTrue(" incoming-window=1," in begin_lines[0])
+
+
+if __name__ == '__main__':
+    unittest.main(main_module())


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to