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 <gmur...@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-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org