From c11747ae0639d229bcfaed3c97f494055a389945 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 24 Oct 2019 12:44:29 +0530 Subject: [PATCH 1/2] handle different cases for SAX filter generation --- lib/jnpr/junos/factory/optable.py | 16 ++++-- tests/unit/factory/test_optable.py | 86 ++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/lib/jnpr/junos/factory/optable.py b/lib/jnpr/junos/factory/optable.py index e66077e62..d237da021 100644 --- a/lib/jnpr/junos/factory/optable.py +++ b/lib/jnpr/junos/factory/optable.py @@ -78,7 +78,6 @@ def get(self, *vargs, **kvargs): rpc_args.update(kvargs.pop('args')) rpc_args.update(kvargs) # copy caller provided args - if hasattr(self, 'GET_KEY') and argkey is not None: rpc_args.update({self.GET_KEY: argkey}) @@ -98,11 +97,10 @@ def generate_sax_parser_input(obj): Returns: lxml etree object to be used as sax parser input """ + item_tags = [] if '/' in obj.ITEM_XPATH: - tags = obj.ITEM_XPATH.split('/') - parser_ingest = E(tags.pop(-1), E(obj.ITEM_NAME_XPATH)) - for tag in tags[::-1]: - parser_ingest = E(tag, parser_ingest) + item_tags = obj.ITEM_XPATH.split('/') + parser_ingest = E(item_tags.pop(-1), E(obj.ITEM_NAME_XPATH)) else: parser_ingest = E(obj.ITEM_XPATH, E(obj.ITEM_NAME_XPATH)) local_field_dict = deepcopy(obj.VIEW.FIELDS) @@ -150,4 +148,12 @@ def generate_sax_parser_input(obj): parser_ingest.insert(i + 1, obj) else: parser_ingest.insert(i + 1, E(xpath)) + # cases where item is something like + # item: task-memory-malloc-usage-report/task-malloc-list/task-malloc + # created filter from last item task-malloc + # Now add all the tags if present + for item_tag in item_tags[::-1]: + parser_ingest = E(item_tag, parser_ingest) + logger.debug("Generated filter XML is: %s" % etree.tostring(parser_ingest)) + return parser_ingest diff --git a/tests/unit/factory/test_optable.py b/tests/unit/factory/test_optable.py index 0f283635b..4deb57e92 100644 --- a/tests/unit/factory/test_optable.py +++ b/tests/unit/factory/test_optable.py @@ -3,16 +3,21 @@ import unittest import os +import yaml from nose.plugins.attrib import attr from jnpr.junos import Device from jnpr.junos.op.phyport import PhyPortStatsTable from jnpr.junos.op.ethport import EthPortTable +from jnpr.junos.factory.factory_loader import FactoryLoader +from jnpr.junos.factory.optable import generate_sax_parser_input from ncclient.manager import Manager, make_device_handler from ncclient.transport import SSHSession from ncclient.operations.rpc import RPCReply +from lxml import etree + from mock import patch @@ -89,6 +94,87 @@ def bad(key): self.assertRaises(ValueError, bad, 'bunk') + def test_generate_sax_parser_item_with_many_slash(self): + yaml_data = """ +--- +taskmallocdetail: + rpc: get-task-memory-information + args: + level: detail + item: task-memory-malloc-usage-report/task-malloc-list/task-malloc + key: tm-name + view: taskmallocview + +taskmallocview: + fields: + tmallocs: tm-allocs + tmallocbytes: tm-alloc-bytes + tmmaxallocs: tm-max-allocs + tmmaxallocbytes: tm-max-alloc-bytes + tmfunctioncalls: tm-function-calls +""" + globals().update(FactoryLoader().load(yaml.load(yaml_data, + Loader=yaml.Loader))) + tbl = taskmallocdetail(self.dev) + data = generate_sax_parser_input(tbl) + self.assertEqual( + etree.tostring(data), + b'') + + def test_generate_sax_parser_same_parents_with_diff_fields(self): + yaml_data = """ +--- +VtepTable: + rpc: get-interface-information + args: + interface-name: "vtep" + extensive: True + item: physical-interface + key: name + view: VtepView + +VtepView: + fields: + admin-status: admin-status + oper-status: oper-status + link-level-type: link-level-type + input-bytes: traffic-statistics/input-bytes + output-bytes: traffic-statistics/output-bytes + input-errors: input-error-list/input-errors + output-errors: output-error-list/output-errors + carrier-transitions: output-error-list/carrier-transitions + vtep-tunnel-stats: VtepTunnelTable + +VtepTunnelTable: + item: logical-interface + key: name + view: VtepTunnelView + +VtepTunnelView: + fields: + vtep-type: vtep-info/vtep-type + vtep-address: vtep-info/vtep-address + tunnel-input-bytes: traffic-statistics/input-bytes + tunnel-output-bytes: traffic-statistics/output-bytes + """ + globals().update(FactoryLoader().load(yaml.load(yaml_data, + Loader=yaml.Loader))) + tbl = VtepTable(self.dev) + data = generate_sax_parser_input(tbl) + self.assertEqual( + etree.tostring(data), + b'' + b'' + b'' + b'' + b'' + b'' + b'' + b'' + ) + def _read_file(self, fname): from ncclient.xml_ import NCElement From 5ab241c17a6e54c9085fca130876eb7c2a0e1dcf Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 24 Oct 2019 13:53:40 +0530 Subject: [PATCH 2/2] tag can be anywhere so just validate len of filter xml --- tests/unit/factory/test_optable.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/factory/test_optable.py b/tests/unit/factory/test_optable.py index 4deb57e92..b81e7a517 100644 --- a/tests/unit/factory/test_optable.py +++ b/tests/unit/factory/test_optable.py @@ -117,11 +117,11 @@ def test_generate_sax_parser_item_with_many_slash(self): Loader=yaml.Loader))) tbl = taskmallocdetail(self.dev) data = generate_sax_parser_input(tbl) - self.assertEqual( - etree.tostring(data), + self.assertEqual(data.tag, 'task-memory-malloc-usage-report') + self.assertEqual(len(etree.tostring(data)), len( b'') + b'-calls/>')) def test_generate_sax_parser_same_parents_with_diff_fields(self): yaml_data = """ @@ -163,8 +163,8 @@ def test_generate_sax_parser_same_parents_with_diff_fields(self): Loader=yaml.Loader))) tbl = VtepTable(self.dev) data = generate_sax_parser_input(tbl) - self.assertEqual( - etree.tostring(data), + self.assertEqual(data.tag, 'physical-interface') + self.assertEqual(len(etree.tostring(data)),len( b'' b'' b'' @@ -172,7 +172,7 @@ def test_generate_sax_parser_same_parents_with_diff_fields(self): b'' b'' b'' - b'' + b'') ) def _read_file(self, fname):