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