Repository: qpid-dispatch
Updated Branches:
  refs/heads/master 279c1b4c6 -> ba8e158d6


DISPATCH-10 - Added configuration of inter-router cost up to the point of 
communicating
cost in LSU messages.  Cost is not yet used in computing routes.


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

Branch: refs/heads/master
Commit: 9f232923d120e2421214917268780b4c86cf959d
Parents: 279c1b4
Author: Ted Ross <[email protected]>
Authored: Wed Apr 20 15:08:23 2016 -0400
Committer: Ted Ross <[email protected]>
Committed: Fri Apr 22 17:49:43 2016 -0400

----------------------------------------------------------------------
 include/qpid/dispatch/router_core.h             |   4 +-
 include/qpid/dispatch/server.h                  |   7 +
 python/qpid_dispatch/management/qdrouter.json   |   7 +
 .../display_name/display_name.py                |   5 +-
 .../qpid_dispatch_internal/management/agent.py  |   4 +-
 python/qpid_dispatch_internal/router/data.py    |  14 +-
 python/qpid_dispatch_internal/router/engine.py  |   8 +-
 python/qpid_dispatch_internal/router/hello.py   |   4 +-
 python/qpid_dispatch_internal/router/node.py    |   8 +-
 src/connection_manager.c                        |   1 +
 src/python_embedded.c                           |   4 +-
 src/router_core/connections.c                   |   2 +
 src/router_core/forwarder.c                     |   3 +-
 src/router_core/management_agent.c              |   2 +-
 src/router_core/router_core_private.h           |   4 +-
 src/router_node.c                               |   7 +-
 tests/router_engine_test.py                     | 128 +++++++++----------
 17 files changed, 119 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/include/qpid/dispatch/router_core.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/router_core.h 
b/include/qpid/dispatch/router_core.h
index 0291f64..81dd2f9 100644
--- a/include/qpid/dispatch/router_core.h
+++ b/include/qpid/dispatch/router_core.h
@@ -88,7 +88,7 @@ void qdr_core_route_table_handlers(qdr_core_t           *core,
  * In-process messaging functions
  ******************************************************************************
  */
-typedef void (*qdr_receive_t) (void *context, qd_message_t *msg, int 
link_maskbit);
+typedef void (*qdr_receive_t) (void *context, qd_message_t *msg, int 
link_maskbit, int inter_router_cost);
 
 qdr_subscription_t *qdr_core_subscribe(qdr_core_t             *core,
                                        const char             *address,
@@ -149,6 +149,7 @@ typedef enum {
  * @param core Pointer to the core object
  * @param incoming True iff this connection is associated with a listener, 
False if a connector
  * @param role The configured role of this connection
+ * @param cost If the role is inter_router, this is the configured cost for 
the connection.
  * @param label Optional label provided in the connection's configuration.  
This is used to 
  *        correlate the connection with waypoints and link-route destinations 
that use the connection.
  * @param strip_annotations_in True if configured to remove annotations on 
inbound messages.
@@ -159,6 +160,7 @@ typedef enum {
 qdr_connection_t *qdr_connection_opened(qdr_core_t            *core,
                                         bool                   incoming,
                                         qdr_connection_role_t  role,
+                                        int                    cost,
                                         const char            *label,
                                         const char            
*remote_container_id,
                                         bool                   
strip_annotations_in,

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/include/qpid/dispatch/server.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/server.h b/include/qpid/dispatch/server.h
index 5a85e63..4683288 100644
--- a/include/qpid/dispatch/server.h
+++ b/include/qpid/dispatch/server.h
@@ -400,6 +400,13 @@ typedef struct qd_server_config_t {
     char *role;
 
     /**
+     * If the role is "inter-router", the cost can be set to a number greater 
than
+     * or equal to one.  Inter-router cost is used to influence the routing 
algorithm
+     * such that it prefers lower-cost paths.
+     */
+    int inter_router_cost;
+
+    /**
      * The maximum size of an AMQP frame in octets.
      */
     uint32_t max_frame_size;

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch/management/qdrouter.json
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch/management/qdrouter.json 
b/python/qpid_dispatch/management/qdrouter.json
index 69d5192..f5cce7a 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -43,6 +43,13 @@
                     "default": "normal",
                     "description": "The role of an established connection. In 
the normal role, the connection is assumed to be used for AMQP clients that are 
doing normal message delivery over the connection.  In the inter-router role, 
the connection is assumed to be to another router in the network.  Inter-router 
discovery and routing protocols can only be used over inter-router connections. 
route-container role can be used for router-container connections, for example, 
a router-broker connection. on-demand role has been deprecated.",
                     "create": true
+                },
+                "cost": {
+                    "type": "integer",
+                    "default": "1",
+                    "required": false,
+                    "create": true,
+                    "description": "For the 'inter-router' role only.  This 
value assigns a cost metric to the inter-router connection.  The default (and 
minimum) value is one.  Higher values represent higher costs.  The cost is used 
to influence the routing algorithm as it attempts to use the path with the 
lowest total cost from ingress to egress."
                 }
             }
         },

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch_internal/display_name/display_name.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/display_name/display_name.py 
b/python/qpid_dispatch_internal/display_name/display_name.py
index 340e69d..5ecb867 100644
--- a/python/qpid_dispatch_internal/display_name/display_name.py
+++ b/python/qpid_dispatch_internal/display_name/display_name.py
@@ -95,14 +95,15 @@ class DisplayNameService(object):
 
         return body
 
-    def receive(self, message, link_id):
+    def receive(self, message, unused_link_id, unused_cost):
         """
         This is the IOAdapter's callback function. Will be invoked when the 
IOAdapter receives a request.
         Will only accept QUERY requests.
         Matches the passed in profilename and userid to user name. If a 
matching user name is not found, returns the
         passed in userid as the user name.
         :param message:
-        :param link_id:
+        :param unused_link_id:
+        :param unused_cost
         """
         body = {}
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch_internal/management/agent.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/management/agent.py 
b/python/qpid_dispatch_internal/management/agent.py
index 336ef86..b050b8a 100644
--- a/python/qpid_dispatch_internal/management/agent.py
+++ b/python/qpid_dispatch_internal/management/agent.py
@@ -751,7 +751,7 @@ class Agent(object):
         except:
             self.log(LOG_ERROR, "Can't respond to %s: %s"%(request, 
format_exc()))
 
-    def receive(self, request, link_id):
+    def receive(self, request, unused_link_id, unused_cost):
         """Called when a management request is received."""
         def error(e, trace):
             """Raise an error"""
@@ -766,7 +766,7 @@ class Agent(object):
         with self.request_lock:
             try:
                 self.entities.refresh_from_c()
-                self.log(LOG_DEBUG, "Agent request %s on link %s"%(request, 
link_id))
+                self.log(LOG_DEBUG, "Agent request %s"% request)
                 status, body = self.handle(request)
                 self.respond(request, status=status, body=body)
             except ManagementError, e:

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch_internal/router/data.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/router/data.py 
b/python/qpid_dispatch_internal/router/data.py
index 040f14b..5b739b8 100644
--- a/python/qpid_dispatch_internal/router/data.py
+++ b/python/qpid_dispatch_internal/router/data.py
@@ -52,7 +52,7 @@ class LinkState(object):
             self.id = getMandatory(body, 'id', str)
             self.area = '0'
             self.ls_seq = getMandatory(body, 'ls_seq', long)
-            self.peers = getMandatory(body, 'peers', list)
+            self.peers = getMandatory(body, 'peers', dict)
         else:
             self.id = _id
             self.area = '0'
@@ -68,20 +68,20 @@ class LinkState(object):
                 'ls_seq' : self.ls_seq,
                 'peers'  : self.peers}
 
-    def add_peer(self, _id):
-        if self.peers.count(_id) == 0:
-            self.peers.append(_id)
+    def add_peer(self, _id, _cost):
+        if _id not in self.peers:
+            self.peers[_id] = _cost
             return True
         return False
 
     def del_peer(self, _id):
-        if self.peers.count(_id) > 0:
-            self.peers.remove(_id)
+        if _id in self.peers:
+            self.peers.pop(_id)
             return True
         return False
 
     def del_all_peers(self):
-        self.peers = []
+        self.peers = {}
         self.ls_seq = 0
 
     def has_peers(self):

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch_internal/router/engine.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/router/engine.py 
b/python/qpid_dispatch_internal/router/engine.py
index 8905bac..5849d09 100644
--- a/python/qpid_dispatch_internal/router/engine.py
+++ b/python/qpid_dispatch_internal/router/engine.py
@@ -126,7 +126,7 @@ class RouterEngine:
         except Exception:
             self.log(LOG_ERROR, "Exception in timer processing\n%s" % 
format_exc(LOG_STACK_LIMIT))
 
-    def handleControlMessage(self, opcode, body, link_id):
+    def handleControlMessage(self, opcode, body, link_id, cost):
         """
         """
         try:
@@ -134,7 +134,7 @@ class RouterEngine:
             if   opcode == 'HELLO':
                 msg = MessageHELLO(body)
                 self.log_hello(LOG_TRACE, "RCVD: %r" % msg)
-                self.hello_protocol.handle_hello(msg, now, link_id)
+                self.hello_protocol.handle_hello(msg, now, link_id, cost)
 
             elif opcode == 'RA':
                 msg = MessageRA(body)
@@ -164,12 +164,12 @@ class RouterEngine:
         except Exception:
             self.log(LOG_ERROR, "Control message error: opcode=%s body=%r\n%s" 
% (opcode, body, format_exc(LOG_STACK_LIMIT)))
 
-    def receive(self, message, link_id):
+    def receive(self, message, link_id, cost):
         """
         This is the IoAdapter message-receive handler
         """
         try:
-            self.handleControlMessage(message.properties['opcode'], 
message.body, link_id)
+            self.handleControlMessage(message.properties['opcode'], 
message.body, link_id, cost)
         except Exception:
             self.log(LOG_ERROR, "Exception in raw message processing: 
properties=%r body=%r\n%s" %
                      (message.properties, message.body, 
format_exc(LOG_STACK_LIMIT)))

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch_internal/router/hello.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/router/hello.py 
b/python/qpid_dispatch_internal/router/hello.py
index 6dbed13..0b214a9 100644
--- a/python/qpid_dispatch_internal/router/hello.py
+++ b/python/qpid_dispatch_internal/router/hello.py
@@ -44,7 +44,7 @@ class HelloProtocol(object):
             self.container.log_hello(LOG_TRACE, "SENT: %r" % msg)
 
 
-    def handle_hello(self, msg, now, link_id):
+    def handle_hello(self, msg, now, link_id, cost):
         if msg.id == self.id:
             if not self.dup_reported and (msg.instance != 
self.container.instance):
                 self.dup_reported = True
@@ -52,7 +52,7 @@ class HelloProtocol(object):
             return
         self.hellos[msg.id] = now
         if msg.is_seen(self.id):
-            self.node_tracker.neighbor_refresh(msg.id, msg.instance, link_id, 
now)
+            self.node_tracker.neighbor_refresh(msg.id, msg.instance, link_id, 
cost, now)
 
 
     def _expire_hellos(self, now):

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/python/qpid_dispatch_internal/router/node.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/router/node.py 
b/python/qpid_dispatch_internal/router/node.py
index 0719898..7ae08fd 100644
--- a/python/qpid_dispatch_internal/router/node.py
+++ b/python/qpid_dispatch_internal/router/node.py
@@ -33,7 +33,7 @@ class NodeTracker(object):
         self.container             = container
         self.my_id                 = container.id
         self.max_routers           = max_routers
-        self.link_state            = LinkState(None, self.my_id, 0, [])
+        self.link_state            = LinkState(None, self.my_id, 0, {})
         self.link_state_changed    = False
         self.recompute_topology    = False
         self.last_topology_change  = 0
@@ -184,7 +184,7 @@ class NodeTracker(object):
             self.container.link_state_engine.send_ra(now)
 
 
-    def neighbor_refresh(self, node_id, instance, link_id, now):
+    def neighbor_refresh(self, node_id, instance, link_id, cost, now):
         """
         Invoked when the hello protocol has received positive confirmation
         of continued bi-directional connectivity with a neighbor router.
@@ -204,7 +204,7 @@ class NodeTracker(object):
         if node.set_link_id(link_id):
             self.nodes_by_link_id[link_id] = node
             node.request_link_state()
-            if self.link_state.add_peer(node_id):
+            if self.link_state.add_peer(node_id, cost):
                 self.link_state_changed = True
 
         ##
@@ -364,7 +364,7 @@ class RouterNode(object):
         self.maskbit                 = self.parent._allocate_maskbit()
         self.neighbor_refresh_time   = 0.0
         self.peer_link_id            = None
-        self.link_state              = LinkState(None, self.id, 0, [])
+        self.link_state              = LinkState(None, self.id, 0, {})
         self.next_hop_router         = None
         self.valid_origins           = None
         self.mobile_addresses        = []

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/connection_manager.c
----------------------------------------------------------------------
diff --git a/src/connection_manager.c b/src/connection_manager.c
index 44a22a9..66466f1 100644
--- a/src/connection_manager.c
+++ b/src/connection_manager.c
@@ -139,6 +139,7 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, 
qd_server_config_t *conf
     config->port                 = qd_entity_get_string(entity, "port"); 
CHECK();
     config->name                 = qd_entity_opt_string(entity, "name", 0); 
CHECK();
     config->role                 = qd_entity_get_string(entity, "role"); 
CHECK();
+    config->inter_router_cost    = qd_entity_opt_long(entity, "cost", 1); 
CHECK();
     config->protocol_family      = qd_entity_opt_string(entity, 
"protocolFamily", 0); CHECK();
     config->max_frame_size       = qd_entity_get_long(entity, "maxFrameSize"); 
CHECK();
     config->idle_timeout_seconds = qd_entity_get_long(entity, 
"idleTimeoutSeconds"); CHECK();

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/python_embedded.c
----------------------------------------------------------------------
diff --git a/src/python_embedded.c b/src/python_embedded.c
index 4946856..2d5d50b 100644
--- a/src/python_embedded.c
+++ b/src/python_embedded.c
@@ -488,7 +488,7 @@ static qd_error_t iter_to_py_attr(qd_field_iterator_t *iter,
     return qd_error_code();
 }
 
-static void qd_io_rx_handler(void *context, qd_message_t *msg, int link_id)
+static void qd_io_rx_handler(void *context, qd_message_t *msg, int link_id, 
int inter_router_cost)
 {
     IoAdapter *self = (IoAdapter*) context;
 
@@ -513,7 +513,7 @@ static void qd_io_rx_handler(void *context, qd_message_t 
*msg, int link_id)
     iter_to_py_attr(qd_message_field_iterator(msg, 
QD_FIELD_APPLICATION_PROPERTIES), py_iter_parse, py_msg, "properties");
     iter_to_py_attr(qd_message_field_iterator(msg, QD_FIELD_BODY), 
py_iter_parse, py_msg, "body");
 
-    PyObject *value = PyObject_CallFunction(self->handler, "Ol", py_msg, 
link_id);
+    PyObject *value = PyObject_CallFunction(self->handler, "Oll", py_msg, 
link_id, inter_router_cost);
 
     Py_DECREF(py_msg);
     Py_XDECREF(value);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/router_core/connections.c
----------------------------------------------------------------------
diff --git a/src/router_core/connections.c b/src/router_core/connections.c
index 88de922..0a4f1ed 100644
--- a/src/router_core/connections.c
+++ b/src/router_core/connections.c
@@ -58,6 +58,7 @@ qdr_terminus_t *qdr_terminus_router_data(void)
 qdr_connection_t *qdr_connection_opened(qdr_core_t            *core,
                                         bool                   incoming,
                                         qdr_connection_role_t  role,
+                                        int                    cost,
                                         const char            *label,
                                         const char            
*remote_container_id,
                                         bool                   
strip_annotations_in,
@@ -72,6 +73,7 @@ qdr_connection_t *qdr_connection_opened(qdr_core_t            
*core,
     conn->user_context          = 0;
     conn->incoming              = incoming;
     conn->role                  = role;
+    conn->inter_router_cost     = cost;
     conn->strip_annotations_in  = strip_annotations_in;
     conn->strip_annotations_out = strip_annotations_out;
     conn->link_capacity         = link_capacity;

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/router_core/forwarder.c
----------------------------------------------------------------------
diff --git a/src/router_core/forwarder.c b/src/router_core/forwarder.c
index a012875..274beb0 100644
--- a/src/router_core/forwarder.c
+++ b/src/router_core/forwarder.c
@@ -118,7 +118,7 @@ void qdr_forward_deliver_CT(qdr_core_t *core, qdr_link_t 
*link, qdr_delivery_t *
 
 void qdr_forward_on_message(qdr_core_t *core, qdr_general_work_t *work)
 {
-    work->on_message(work->on_message_context, work->msg, work->maskbit);
+    work->on_message(work->on_message_context, work->msg, work->maskbit, 
work->inter_router_cost);
     qd_message_free(work->msg);
 }
 
@@ -130,6 +130,7 @@ void qdr_forward_on_message_CT(qdr_core_t *core, 
qdr_subscription_t *sub, qdr_li
     work->on_message_context = sub->on_message_context;
     work->msg                = qd_message_copy(msg);
     work->maskbit            = link ? link->conn->mask_bit : 0;
+    work->inter_router_cost  = link ? link->conn->inter_router_cost : 1;
     qdr_post_general_work_CT(core, work);
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/router_core/management_agent.c
----------------------------------------------------------------------
diff --git a/src/router_core/management_agent.c 
b/src/router_core/management_agent.c
index e048c85..0eef56a 100644
--- a/src/router_core/management_agent.c
+++ b/src/router_core/management_agent.c
@@ -442,7 +442,7 @@ static bool qd_can_handle_request(qd_parsed_field_t         
  *properties_fld,
  * Handler for the management agent.
  *
  */
-void qdr_management_agent_on_message(void *context, qd_message_t *msg, int 
unused_link_id)
+void qdr_management_agent_on_message(void *context, qd_message_t *msg, int 
unused_link_id, int unused_cost)
 {
     qdr_core_t *core = (qdr_core_t*) context;
     qd_field_iterator_t *app_properties_iter = qd_message_field_iterator(msg, 
QD_FIELD_APPLICATION_PROPERTIES);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/router_core/router_core_private.h
----------------------------------------------------------------------
diff --git a/src/router_core/router_core_private.h 
b/src/router_core/router_core_private.h
index 62b8136..8abfba8 100644
--- a/src/router_core/router_core_private.h
+++ b/src/router_core/router_core_private.h
@@ -368,6 +368,7 @@ struct qdr_general_work_t {
     qdr_general_work_handler_t  handler;
     qdr_field_t                *field;
     int                         maskbit;
+    int                         inter_router_cost;
     qdr_receive_t               on_message;
     void                       *on_message_context;
     qd_message_t               *msg;
@@ -412,6 +413,7 @@ struct qdr_connection_t {
     void                       *user_context;
     bool                        incoming;
     qdr_connection_role_t       role;
+    int                         inter_router_cost;
     qdr_conn_identifier_t      *conn_id;
     bool                        strip_annotations_in;
     bool                        strip_annotations_out;
@@ -562,7 +564,7 @@ struct qdr_core_t {
 
 void *router_core_thread(void *arg);
 uint64_t qdr_identifier(qdr_core_t* core);
-void qdr_management_agent_on_message(void *context, qd_message_t *msg, int 
unused_link_id);
+void qdr_management_agent_on_message(void *context, qd_message_t *msg, int 
unused_link_id, int unused_cost);
 void  qdr_route_table_setup_CT(qdr_core_t *core);
 void  qdr_agent_setup_CT(qdr_core_t *core);
 void  qdr_forwarder_setup_CT(qdr_core_t *core);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/src/router_node.c
----------------------------------------------------------------------
diff --git a/src/router_node.c b/src/router_node.c
index af66278..8cba85e 100644
--- a/src/router_node.c
+++ b/src/router_node.c
@@ -43,6 +43,7 @@ static char *node_id;
  */
 static void qd_router_connection_get_config(const qd_connection_t  *conn,
                                             qdr_connection_role_t  *role,
+                                            int                    *cost,
                                             const char            **name,
                                             bool                   
*strip_annotations_in,
                                             bool                   
*strip_annotations_out,
@@ -59,6 +60,7 @@ static void qd_router_connection_get_config(const 
qd_connection_t  *conn,
             *strip_annotations_in  = false;
             *strip_annotations_out = false;
             *role = QDR_ROLE_INTER_ROUTER;
+            *cost = cf->inter_router_cost;
         } else if (cf && (strcmp(cf->role, container_role) == 0 ||
                           strcmp(cf->role, on_demand_role) == 0))  // backward 
compat
             *role = QDR_ROLE_ROUTE_CONTAINER;
@@ -497,16 +499,17 @@ static int AMQP_link_detach_handler(void* context, 
qd_link_t *link, qd_detach_ty
 static void AMQP_opened_handler(qd_router_t *router, qd_connection_t *conn, 
bool inbound)
 {
     qdr_connection_role_t  role = 0;
+    int                    cost = 1;
     bool                   strip_annotations_in = false;
     bool                   strip_annotations_out = false;
     int                    link_capacity = 1;
     const char            *name = 0;
     pn_connection_t       *pn_conn = qd_connection_pn(conn);
 
-    qd_router_connection_get_config(conn, &role, &name,
+    qd_router_connection_get_config(conn, &role, &cost, &name,
                                     &strip_annotations_in, 
&strip_annotations_out, &link_capacity);
 
-    qdr_connection_t *qdrc = qdr_connection_opened(router->router_core, 
inbound, role, name,
+    qdr_connection_t *qdrc = qdr_connection_opened(router->router_core, 
inbound, role, cost, name,
                                                    
pn_connection_remote_container(pn_conn),
                                                    strip_annotations_in, 
strip_annotations_out, link_capacity);
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/9f232923/tests/router_engine_test.py
----------------------------------------------------------------------
diff --git a/tests/router_engine_test.py b/tests/router_engine_test.py
index c78cfd9..76ae101 100644
--- a/tests/router_engine_test.py
+++ b/tests/router_engine_test.py
@@ -52,34 +52,34 @@ class Adapter(object):
 
 class DataTest(unittest.TestCase):
     def test_link_state(self):
-        ls = LinkState(None, 'R1', 1, ['R2', 'R3'])
+        ls = LinkState(None, 'R1', 1, {'R2':1, 'R3':1})
         self.assertEqual(ls.id, 'R1')
         self.assertEqual(ls.ls_seq, 1)
-        self.assertEqual(ls.peers, ['R2', 'R3'])
+        self.assertEqual(ls.peers, {'R2':1, 'R3':1})
         ls.bump_sequence()
         self.assertEqual(ls.id, 'R1')
         self.assertEqual(ls.ls_seq, 2)
-        self.assertEqual(ls.peers, ['R2', 'R3'])
+        self.assertEqual(ls.peers, {'R2':1, 'R3':1})
 
-        result = ls.add_peer('R4')
+        result = ls.add_peer('R4', 5)
         self.assertTrue(result)
-        self.assertEqual(ls.peers, ['R2', 'R3', 'R4'])
-        result = ls.add_peer('R2')
+        self.assertEqual(ls.peers, {'R2':1, 'R3':1, 'R4':5})
+        result = ls.add_peer('R2', 1)
         self.assertFalse(result)
-        self.assertEqual(ls.peers, ['R2', 'R3', 'R4'])
+        self.assertEqual(ls.peers, {'R2':1, 'R3':1, 'R4':5})
 
         result = ls.del_peer('R3')
         self.assertTrue(result)
-        self.assertEqual(ls.peers, ['R2', 'R4'])
+        self.assertEqual(ls.peers, {'R2':1, 'R4':5})
         result = ls.del_peer('R5')
         self.assertFalse(result)
-        self.assertEqual(ls.peers, ['R2', 'R4'])
+        self.assertEqual(ls.peers, {'R2':1, 'R4':5})
 
         encoded = ls.to_dict()
         new_ls = LinkState(encoded)
         self.assertEqual(new_ls.id, 'R1')
         self.assertEqual(new_ls.ls_seq, 2)
-        self.assertEqual(new_ls.peers, ['R2', 'R4'])
+        self.assertEqual(new_ls.peers, {'R2':1, 'R4':5})
 
 
     def test_hello_message(self):
@@ -141,8 +141,8 @@ class NeighborTest(unittest.TestCase):
     def send(self, dest, msg):
         self.sent.append((dest, msg))
 
-    def neighbor_refresh(self, node_id, instance, link_id, now):
-        self.neighbors[node_id] = (instance, link_id, now)
+    def neighbor_refresh(self, node_id, instance, link_id, cost, now):
+        self.neighbors[node_id] = (instance, link_id, cost, now)
 
     def setUp(self):
         self.sent = []
@@ -177,7 +177,7 @@ class NeighborTest(unittest.TestCase):
         self.sent = []
         self.neighbors = {}
         self.engine = HelloProtocol(self, self)
-        self.engine.handle_hello(MessageHELLO(None, 'R2', []), 2.0, 0)
+        self.engine.handle_hello(MessageHELLO(None, 'R2', []), 2.0, 0, 1)
         self.engine.tick(5.0)
         self.assertEqual(len(self.sent), 1)
         dest, msg = self.sent.pop(0)
@@ -187,7 +187,7 @@ class NeighborTest(unittest.TestCase):
         self.sent = []
         self.neighbors = {}
         self.engine = HelloProtocol(self, self)
-        self.engine.handle_hello(MessageHELLO(None, 'R2', ['R1']), 0.5, 0)
+        self.engine.handle_hello(MessageHELLO(None, 'R2', ['R1']), 0.5, 0, 1)
         self.engine.tick(1.0)
         self.engine.tick(2.0)
         self.engine.tick(3.0)
@@ -198,13 +198,13 @@ class NeighborTest(unittest.TestCase):
         self.sent = []
         self.neighbors = {}
         self.engine = HelloProtocol(self, self)
-        self.engine.handle_hello(MessageHELLO(None, 'R2', ['R1']), 0.5, 0)
+        self.engine.handle_hello(MessageHELLO(None, 'R2', ['R1']), 0.5, 0, 1)
         self.engine.tick(1.0)
-        self.engine.handle_hello(MessageHELLO(None, 'R3', ['R1', 'R2']), 1.5, 
0)
+        self.engine.handle_hello(MessageHELLO(None, 'R3', ['R1', 'R2']), 1.5, 
0, 1)
         self.engine.tick(2.0)
-        self.engine.handle_hello(MessageHELLO(None, 'R4', ['R1']), 2.5, 0)
-        self.engine.handle_hello(MessageHELLO(None, 'R5', ['R2']), 2.5, 0)
-        self.engine.handle_hello(MessageHELLO(None, 'R6', ['R1']), 2.5, 0)
+        self.engine.handle_hello(MessageHELLO(None, 'R4', ['R1']), 2.5, 0, 1)
+        self.engine.handle_hello(MessageHELLO(None, 'R5', ['R2']), 2.5, 0, 1)
+        self.engine.handle_hello(MessageHELLO(None, 'R6', ['R1']), 2.5, 0, 1)
         self.engine.tick(3.0)
         keys = self.neighbors.keys()
         keys.sort()
@@ -227,9 +227,9 @@ class PathTest(unittest.TestCase):
         +====+      +----+      +----+
 
         """
-        collection = { 'R1': LinkState(None, 'R1', 1, ['R2']),
-                       'R2': LinkState(None, 'R2', 1, ['R1', 'R3']),
-                       'R3': LinkState(None, 'R3', 1, ['R2']) }
+        collection = { 'R1': LinkState(None, 'R1', 1, {'R2':1}),
+                       'R2': LinkState(None, 'R2', 1, {'R1':1, 'R3':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R2':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 2)
         self.assertEqual(next_hops['R2'], 'R2')
@@ -252,12 +252,12 @@ class PathTest(unittest.TestCase):
                     +----+      +----+      +----+
 
         """
-        collection = { 'R1': LinkState(None, 'R1', 1, ['R2']),
-                       'R2': LinkState(None, 'R2', 1, ['R1', 'R3', 'R4']),
-                       'R3': LinkState(None, 'R3', 1, ['R2', 'R5']),
-                       'R4': LinkState(None, 'R4', 1, ['R2', 'R5']),
-                       'R5': LinkState(None, 'R5', 1, ['R3', 'R4', 'R6']),
-                       'R6': LinkState(None, 'R6', 1, ['R5']) }
+        collection = { 'R1': LinkState(None, 'R1', 1, {'R2':1}),
+                       'R2': LinkState(None, 'R2', 1, {'R1':1, 'R3':1, 
'R4':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R2':1, 'R5':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R2':1, 'R5':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R3':1, 'R4':1, 
'R6':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 5)
         self.assertEqual(next_hops['R2'], 'R2')
@@ -289,12 +289,12 @@ class PathTest(unittest.TestCase):
                     +====+      +----+      +----+
 
         """
-        collection = { 'R2': LinkState(None, 'R2', 1, ['R3']),
-                       'R3': LinkState(None, 'R3', 1, ['R1', 'R2', 'R4']),
-                       'R4': LinkState(None, 'R4', 1, ['R3', 'R5']),
-                       'R1': LinkState(None, 'R1', 1, ['R3', 'R5']),
-                       'R5': LinkState(None, 'R5', 1, ['R1', 'R4', 'R6']),
-                       'R6': LinkState(None, 'R6', 1, ['R5']) }
+        collection = { 'R2': LinkState(None, 'R2', 1, {'R3':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R1':1, 'R2':1, 
'R4':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R3':1, 'R5':1}),
+                       'R1': LinkState(None, 'R1', 1, {'R3':1, 'R5':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R1':1, 'R4':1, 
'R6':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 5)
         self.assertEqual(next_hops['R2'], 'R3')
@@ -326,12 +326,12 @@ class PathTest(unittest.TestCase):
                     +====+      +----+      +----+
 
         """
-        collection = { 'R2': LinkState(None, 'R2', 1, ['R3']),
-                       'R3': LinkState(None, 'R3', 1, ['R1', 'R2', 'R4']),
-                       'R4': LinkState(None, 'R4', 1, ['R3', 'R5']),
-                       'R1': LinkState(None, 'R1', 1, ['R3', 'R5']),
-                       'R5': LinkState(None, 'R5', 1, ['R1', 'R4', 'R6']),
-                       'R6': LinkState(None, 'R6', 1, ['R5', 'R7']) }
+        collection = { 'R2': LinkState(None, 'R2', 1, {'R3':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R1':1, 'R2':1, 
'R4':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R3':1, 'R5':1}),
+                       'R1': LinkState(None, 'R1', 1, {'R3':1, 'R5':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R1':1, 'R4':1, 
'R6':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1, 'R7':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 6)
         self.assertEqual(next_hops['R2'], 'R3')
@@ -366,12 +366,12 @@ class PathTest(unittest.TestCase):
                     +====+      +----+      +----+
 
         """
-        collection = { 'R2': LinkState(None, 'R2', 1, ['R3', 'R1']),
-                       'R3': LinkState(None, 'R3', 1, ['R1', 'R2', 'R4']),
-                       'R4': LinkState(None, 'R4', 1, ['R3', 'R5']),
-                       'R1': LinkState(None, 'R1', 1, ['R3', 'R5', 'R2']),
-                       'R5': LinkState(None, 'R5', 1, ['R1', 'R4', 'R6']),
-                       'R6': LinkState(None, 'R6', 1, ['R5', 'R7']) }
+        collection = { 'R2': LinkState(None, 'R2', 1, {'R3':1, 'R1':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R1':1, 'R2':1, 
'R4':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R3':1, 'R5':1}),
+                       'R1': LinkState(None, 'R1', 1, {'R3':1, 'R5':1, 
'R2':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R1':1, 'R4':1, 
'R6':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1, 'R7':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 6)
         self.assertEqual(next_hops['R2'], 'R2')
@@ -406,12 +406,12 @@ class PathTest(unittest.TestCase):
                     +====+      +----+      +----+
 
         """
-        collection = { 'R2': LinkState(None, 'R2', 1, ['R3']),
-                       'R3': LinkState(None, 'R3', 1, ['R1', 'R2', 'R4']),
-                       'R4': LinkState(None, 'R4', 1, ['R3', 'R5']),
-                       'R1': LinkState(None, 'R1', 1, ['R3', 'R5', 'R2']),
-                       'R5': LinkState(None, 'R5', 1, ['R1', 'R4', 'R6']),
-                       'R6': LinkState(None, 'R6', 1, ['R5', 'R7']) }
+        collection = { 'R2': LinkState(None, 'R2', 1, {'R3':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R1':1, 'R2':1, 
'R4':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R3':1, 'R5':1}),
+                       'R1': LinkState(None, 'R1', 1, {'R3':1, 'R5':1, 
'R2':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R1':1, 'R4':1, 
'R6':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1, 'R7':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 6)
         self.assertEqual(next_hops['R2'], 'R2')
@@ -446,12 +446,12 @@ class PathTest(unittest.TestCase):
                     +====+      +----+      +----+
 
         """
-        collection = { 'R2': LinkState(None, 'R2', 1, ['R3', 'R1']),
-                       'R3': LinkState(None, 'R3', 1, ['R1', 'R2', 'R4']),
-                       'R4': LinkState(None, 'R4', 1, ['R3', 'R5']),
-                       'R1': LinkState(None, 'R1', 1, ['R3', 'R5']),
-                       'R5': LinkState(None, 'R5', 1, ['R1', 'R4', 'R6']),
-                       'R6': LinkState(None, 'R6', 1, ['R5', 'R7']) }
+        collection = { 'R2': LinkState(None, 'R2', 1, {'R3':1, 'R1':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R1':1, 'R2':1, 
'R4':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R3':1, 'R5':1}),
+                       'R1': LinkState(None, 'R1', 1, {'R3':1, 'R5':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R1':1, 'R4':1, 
'R6':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1, 'R7':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 6)
         self.assertEqual(next_hops['R2'], 'R3')
@@ -486,12 +486,12 @@ class PathTest(unittest.TestCase):
                     +====+      +----+      +----+
 
         """
-        collection = { 'R2': LinkState(None, 'R2', 1, ['R3', 'R1']),
-                       'R3': LinkState(None, 'R3', 1, ['R1', 'R2', 'R4']),
-                       'R4': LinkState(None, 'R4', 1, ['R3', 'R5']),
-                       'R1': LinkState(None, 'R1', 1, ['R3', 'R5']),
-                       'R5': LinkState(None, 'R5', 1, ['R1', 'R4']),
-                       'R6': LinkState(None, 'R6', 1, ['R5', 'R7']) }
+        collection = { 'R2': LinkState(None, 'R2', 1, {'R3':1, 'R1':1}),
+                       'R3': LinkState(None, 'R3', 1, {'R1':1, 'R2':1, 
'R4':1}),
+                       'R4': LinkState(None, 'R4', 1, {'R3':1, 'R5':1}),
+                       'R1': LinkState(None, 'R1', 1, {'R3':1, 'R5':1}),
+                       'R5': LinkState(None, 'R5', 1, {'R1':1, 'R4':1}),
+                       'R6': LinkState(None, 'R6', 1, {'R5':1, 'R7':1}) }
         next_hops, valid_origins = self.engine.calculate_routes(collection)
         self.assertEqual(len(next_hops), 4)
         self.assertEqual(next_hops['R2'], 'R3')


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

Reply via email to