You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gm...@apache.org on 2019/07/15 20:59:09 UTC

[qpid-dispatch] branch master updated: DISPATCH-1374 - Added qdstat options --all-routers and --all-entities. This closes #527.

This is an automated email from the ASF dual-hosted git repository.

gmurthy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 81da3d6  DISPATCH-1374 - Added qdstat options --all-routers and --all-entities. This closes #527.
81da3d6 is described below

commit 81da3d6da2d680e41527191c2a4b6eafc2bda3e8
Author: Ganesh Murthy <gm...@apache.org>
AuthorDate: Tue Jun 25 17:09:44 2019 -0400

    DISPATCH-1374 - Added qdstat options --all-routers and --all-entities. This closes #527.
---
 python/qpid_dispatch/management/client.py |   6 +
 tests/system_tests_edge_router.py         | 179 ++++++++++++++++++++++++++++++
 tools/qdstat.in                           |  82 ++++++++++++--
 3 files changed, 260 insertions(+), 7 deletions(-)

diff --git a/python/qpid_dispatch/management/client.py b/python/qpid_dispatch/management/client.py
index 28e8a80..b2a16f2 100644
--- a/python/qpid_dispatch/management/client.py
+++ b/python/qpid_dispatch/management/client.py
@@ -124,6 +124,12 @@ class Node(object):
         self.url = connection.url
         self.client = SyncRequestResponse(connection, self.url.path)
         self.reply_to = self.client.reply_to
+        self.connection = connection
+
+    def set_client(self, url_path):
+        if url_path:
+            self.url.path = u'%s'%url_path
+            self.client = SyncRequestResponse(self.connection, self.url.path)
 
     def close(self):
         """Shut down the node"""
diff --git a/tests/system_tests_edge_router.py b/tests/system_tests_edge_router.py
index 4c38316..b642ec6 100644
--- a/tests/system_tests_edge_router.py
+++ b/tests/system_tests_edge_router.py
@@ -1210,6 +1210,185 @@ class RouterTest(TestCase):
         test.run()
         self.assertEqual(None, test.error)
 
+    def run_qdstat(self, args, regexp=None, address=None):
+        if args:
+            popen_arg = ['qdstat', '--bus', str(address or self.router.addresses[0]),
+                 '--timeout', str(TIMEOUT)] + args
+        else:
+            popen_arg = ['qdstat', '--bus',
+                         str(address or self.router.addresses[0]),
+                         '--timeout', str(TIMEOUT)]
+
+        p = self.popen(popen_arg,
+                       name='qdstat-' + self.id(), stdout=PIPE, expect=None,
+            universal_newlines=True)
+
+        out = p.communicate()[0]
+        assert p.returncode == 0, \
+            "qdstat exit status %s, output:\n%s" % (p.returncode, out)
+        if regexp: assert re.search(regexp, out,
+                                    re.I), "Can't find '%s' in '%s'" % (
+        regexp, out)
+        return out
+
+    def test_68_edge_qdstat_all_routers(self):
+        # Connects to an edge router and runs "qdstat --all-routers"
+        # "qdstat --all-routers" is same as "qdstat --all-routers --all-entities"
+        # Connecting to an edge router and running "qdstat --all-routers""will only yield the
+        # summary statostics of the edge router. It will not show statistics of the interior routers.
+        outs = self.run_qdstat(['--all-routers'],
+                               address=self.routers[2].addresses[0])
+        # Check if each entity  section is showing
+        self.assertEqual(outs.count("Router Links"), 1)
+        self.assertEqual(outs.count("Router Addresses"), 1)
+        self.assertEqual(outs.count("AutoLinks"), 1)
+        self.assertEqual(outs.count("Auto Links"), 1)
+        self.assertEqual(outs.count("Router Statistics"), 1)
+        self.assertEqual(outs.count("Link Routes"), 2)
+        self.assertEqual(outs.count("Types"), 1)
+        self.assertTrue("Router Id                        EA1" in outs)
+
+        self.assertTrue("Types" in outs)
+
+        outs = self.run_qdstat(['--all-routers', '--all-entities'],
+                               address=self.routers[2].addresses[0])
+        # Check if each entity  section is showing
+        self.assertTrue("Router Links" in outs)
+        self.assertTrue("Router Addresses" in outs)
+        self.assertTrue("Connections" in outs)
+        self.assertTrue("AutoLinks" in outs)
+        self.assertTrue("Auto Links" in outs)
+        self.assertEqual(outs.count("Link Routes"), 2)
+        self.assertTrue("Router Statistics" in outs)
+        self.assertTrue("Router Id                        EA1" in outs)
+
+        self.assertTrue("Types" in outs)
+
+        outs = self.run_qdstat(['-c', '--all-routers'],
+                               address=self.routers[2].addresses[0])
+
+        # Verify that the the edhe uplink connection is showing
+        self.assertTrue("INT.A" in outs)
+        self.assertTrue("inter-router" not in outs)
+
+        outs = self.run_qdstat(['--all-entities'],
+                               address=self.routers[2].addresses[0])
+        # Check if each entity  section is showing
+        self.assertTrue("Router Links" in outs)
+        self.assertTrue("Router Addresses" in outs)
+        self.assertTrue("Connections" in outs)
+        self.assertTrue("AutoLinks" in outs)
+        self.assertTrue("Auto Links" in outs)
+        self.assertEqual(outs.count("Link Routes"), 2)
+        self.assertTrue("Router Statistics" in outs)
+        self.assertTrue("Router Id                        EA1" in outs)
+
+        self.assertTrue("Types" in outs)
+
+
+        # Run qdstat with no prarameters and make sure it executes qdstat --all-entities
+        outs = self.run_qdstat(None,
+                               address=self.routers[2].addresses[0])
+        # Check if each entity  section is showing
+        self.assertTrue("Router Links" in outs)
+        self.assertTrue("Router Addresses" in outs)
+        self.assertTrue("Connections" in outs)
+        self.assertTrue("AutoLinks" in outs)
+        self.assertTrue("Auto Links" in outs)
+        self.assertEqual(outs.count("Link Routes"), 2)
+        self.assertTrue("Router Statistics" in outs)
+        self.assertTrue("Router Id                        EA1" in outs)
+
+        self.assertTrue("Types" in outs)
+
+    def test_69_interior_qdstat_all_routers(self):
+        # Connects to an interior router and runs "qdstat --all-routers"
+        # "qdstat --all-routers" is same as "qdstat --all-routers --all-entities"
+        # Connecting to an interior router and running "qdstat --all-routers""will yield the
+        # summary statostics of all the interior routers.
+        outs = self.run_qdstat(['--all-routers'],
+                               address=self.routers[0].addresses[0])
+        self.assertEqual(outs.count("Router Links"), 2)
+        self.assertEqual(outs.count("Router Addresses"), 2)
+        self.assertEqual(outs.count("Connections"), 4)
+        self.assertEqual(outs.count("AutoLinks"), 2)
+        self.assertEqual(outs.count("Auto Links"), 2)
+        self.assertEqual(outs.count("Link Routes"), 4)
+        self.assertEqual(outs.count("Router Statistics"), 2)
+        self.assertEqual(outs.count("Types"), 2)
+
+        outs = self.run_qdstat(['--all-routers', '-nv'],
+                               address=self.routers[0].addresses[0])
+        # 5 occurences including section headers
+        self.assertEqual(outs.count("INT.A"), 5)
+        self.assertEqual(outs.count("INT.B"), 5)
+
+        outs = self.run_qdstat(['--all-routers', '--all-entities'],
+                               address=self.routers[0].addresses[0])
+        self.assertEqual(outs.count("Router Links"), 2)
+        self.assertEqual(outs.count("Router Addresses"), 2)
+        self.assertEqual(outs.count("Connections"), 4)
+        self.assertEqual(outs.count("AutoLinks"), 2)
+        self.assertEqual(outs.count("Auto Links"), 2)
+        self.assertEqual(outs.count("Link Routes"), 4)
+        self.assertEqual(outs.count("Router Statistics"), 2)
+        self.assertEqual(outs.count("Types"), 2)
+
+        outs = self.run_qdstat(['--all-routers', '-nv'],
+                               address=self.routers[0].addresses[0])
+        # 5 occurences including section headers
+        self.assertEqual(outs.count("INT.A"), 5)
+        self.assertEqual(outs.count("INT.B"), 5)
+
+        has_error = False
+        try:
+            # You cannot combine --all-entities  with -c
+            outs = self.run_qdstat(['-c', '--all-entities'],
+                               address=self.routers[0].addresses[0])
+        except Exception as e:
+            if "--all-entities cannot be combined with specific entity option -c" in str(e):
+                has_error=True
+
+        self.assertTrue(has_error)
+
+        outs = self.run_qdstat(['-c', '--all-routers'],
+                               address=self.routers[0].addresses[0])
+        self.assertEqual(outs.count("INT.A"), 2)
+        self.assertEqual(outs.count("INT.B"), 2)
+
+        outs = self.run_qdstat(['-l', '--all-routers'],
+                               address=self.routers[0].addresses[0])
+
+        # Two edge-downlinks from each interior to the two edges, 4 in total.
+        self.assertEqual(outs.count("edge-downlink"), 4)
+
+        has_error = False
+        try:
+            outs = self.run_qdstat(['-r', 'INT.A', '--all-routers'],
+                                   address=self.routers[0].addresses[0])
+        except Exception as e:
+            if "--all-routers cannot be combined with single router option" in str(e):
+                has_error=True
+
+        self.assertTrue(has_error)
+
+        # Gets all entity information of the interior router
+        outs = self.run_qdstat(['--all-entities'],
+                       address=self.routers[0].addresses[0])
+        self.assertEqual(outs.count("Router Links"), 1)
+        self.assertEqual(outs.count("Router Addresses"), 1)
+        self.assertEqual(outs.count("AutoLinks"), 1)
+        self.assertEqual(outs.count("Auto Links"), 1)
+        self.assertEqual(outs.count("Router Statistics"), 1)
+        self.assertEqual(outs.count("Link Routes"), 2)
+
+        #self.assertTrue("Router Addresses" in outs)
+        #self.assertTrue("Connections" in outs)
+        #self.assertTrue("AutoLinks" in outs)
+        #self.assertTrue("Auto Links" in outs)
+        #self.assertEqual(outs.count("Link Routes"), 2)
+        #self.assertTrue("Router Statistics" in outs)
+
 
 class LinkRouteProxyTest(TestCase):
     """
diff --git a/tools/qdstat.in b/tools/qdstat.in
index 73a1dea..196243d 100755
--- a/tools/qdstat.in
+++ b/tools/qdstat.in
@@ -30,6 +30,7 @@ import sys
 import locale
 import socket
 import re
+from datetime import datetime
 from time import ctime, strftime, gmtime
 import  qpid_dispatch_site
 from qpid_dispatch.management.client import Url, Node, Entity
@@ -43,7 +44,6 @@ def parse_args(argv):
     """ Set global variables for options, return arguments """
 
     usage = "%prog [options]"
-
     parser = OptionParser(usage=usage)
 
     parser.add_option_group(connection_options(parser))
@@ -57,6 +57,10 @@ def parse_args(argv):
     parser.add_option("-m", "--memory", help="Show Router Memory Stats",    action="store_const", const="m",   dest="show")
     parser.add_option("--autolinks", help="Show Auto Links",                action="store_const", const="autolinks",  dest="show")
     parser.add_option("--linkroutes", help="Show Link Routes",              action="store_const", const="linkroutes", dest="show")
+
+    parser.add_option("--all-routers", help="Show entities for all routers in network. Can also be used in combination with other options",  action="store_const", const="all_routers",  dest="all_routers")
+    parser.add_option("--all-entities", help="Show all router entities. Can be combined with --all-routers option", action="store_const", const="all_entities", dest="all_entities")
+
     parser.add_option("-v", "--verbose", help="Show maximum detail",        action="store_true", dest="verbose")
     parser.add_option("--log", help="Show recent log entries", action="store_const", const="log", dest="show")
 
@@ -64,16 +68,20 @@ def parse_args(argv):
     # can be used in conjunction with options
     # like -c, -l, -a, --autolinks, --linkroutes and --log.
     # By default, the limit is not set, which means the limit is unlimited.
-
     parser.add_option("--limit", help="Limit number of output rows", type="int", default=None)
 
     opts, args = parser.parse_args(args=argv)
 
-    if not opts.show:
-        parser.error("You must specify one of these options: -g, -c, -l, -n, -a, -m, -h, --autolinks, --linkroutes, or --log.")
+    if opts.router and opts.all_routers:
+        parser.error("--all-routers cannot be combined with single router option -r " + opts.router)
 
-    return opts, args
+    if opts.all_entities and opts.show:
+           parser.error("--all-entities cannot be combined with specific entity option -" + opts.show)
+
+    if not opts.all_routers and not opts.all_entities and not opts.show:
+        opts.all_entities = u'all_entities'
 
+    return opts, args
 
 def get(obj, attr):
     if attr in obj.__dict__:
@@ -656,7 +664,27 @@ class BusManager(Node):
         for line in log:
             print("%s %s (%s) %s" % (ctime(line[5]), line[0], line[1], line[2]))
 
-    def displayMain(self, identitys, main):
+    def show_all(self):
+        self.displayRouterLinks()
+        self.displayAddresses()
+        self.displayConnections()
+        self.displayAutolinks()
+        self.displayLinkRoutes()
+        self.displayGeneral()
+        self.displayMemory()
+
+    def has_nodes(self):
+        all_nodes = super(BusManager, self).get_mgmt_nodes()
+        has_nodes = True
+        if all_nodes:
+            if len(all_nodes) < 2:
+                has_nodes = False
+        else:
+           has_nodes = False
+
+        return has_nodes, all_nodes
+
+    def show_entity(self, main):
         if   main == 'l': self.displayRouterLinks()
         elif main == 'n': self.displayRouterNodes()
         elif main == 'a': self.displayAddresses()
@@ -668,8 +696,48 @@ class BusManager(Node):
         elif main == 'linkroutes': self.displayLinkRoutes()
         elif main == 'log': self.displayLog()
 
+    def all_routers_entities(self):
+        has_nodes, nodes = self.has_nodes()
+        if has_nodes:
+            for node in nodes:
+                super(BusManager, self).set_client(node[6:])
+                parts = node.split("/")
+                print ("Router ", parts[3])
+                self.show_all()
+                print("")
+        else:
+            self.show_all()
+
+    def displayMain(self, identitys, opts):
+        main = opts.show
+        if opts.all_routers and main:
+            print (str(datetime.now()))
+            has_nodes, nodes = self.has_nodes()
+            if has_nodes:
+                for node in nodes:
+                    super(BusManager, self).set_client(node[6:])
+                    parts = node.split("/")
+                    print ("Router ", parts[3])
+                    self.show_entity(main)
+                    print("")
+            else:
+                self.show_entity(main)
+        elif opts.all_routers and opts.all_entities:
+            print (str(datetime.now()))
+            self.all_routers_entities()
+        elif opts.all_routers:
+            print (str(datetime.now()))
+            self.all_routers_entities()
+        elif opts.all_entities:
+            print (str(datetime.now()))
+            # Display all the relevant entities from the one router that
+            # qdstat is connecting to.
+            self.show_all()
+        elif main:
+            self.show_entity(main)
+
     def display(self, identitys):
-        self.displayMain(identitys, self.opts.show)
+        self.displayMain(identitys, self.opts)
 
 def run(argv):
     opts, args = parse_args(argv)


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