def test_get_printable_with_deep_changes_and_added_on_candidate(self): running_str = """ <vr> <interface> <switchportAllowedEthertypes> <ipv6>true</ipv6> <ipv4>true</ipv4> </switchportAllowedEthertypes> </interface> </vr> """ candidate_str = """ <vr> <interface> <switchportAllowedEthertypes> <ipv6>true</ipv6> <ipv4>true</ipv4> <arp>true</arp> </switchportAllowedEthertypes> </interface> </vr> """ running = etree.fromstring(running_str) candidate = etree.fromstring(candidate_str) block = Block(running, candidate) actual = block.get_printable_diff() expected = [ '[vr]', ' <interface>', ' <switchportAllowedEthertypes>', ' <ipv6>true</ipv6>', ' <ipv4>true</ipv4>', '+ <arp>true</arp>', ' </switchportAllowedEthertypes>', ' </interface>' ] self.assertEqual(expected, actual)
def test_when_root_elements_change(self): self.maxDiff = None running_str = """ <logginglevel> <name>foo</name> <logginglevel>5</logginglevel> <bar>1</bar> </logginglevel> """ candidate_str = """ <logginglevel> <name>foo</name> <logginglevel>2</logginglevel> <bar>1</bar> </logginglevel> """ running = etree.fromstring(running_str) candidate = etree.fromstring(candidate_str) block = Block(running, candidate) actual = block.get_printable_diff() expected = [ '[logginglevel]', ' <name>foo</name>', ' <bar>1</bar>', '- <logginglevel>5</logginglevel>', '+ <logginglevel>2</logginglevel>' ] self.assertEqual(expected, actual)
def test_when_deep_same_tags(self): running_str = """ <vr> <interface> <ifName>xe17</ifName> <loadInterval>30</loadInterval> <description>ecmem8-C914057</description> <isAutospeed>true</isAutospeed> <speed>1g</speed> </interface> </vr> """ candidate_str = """ <vr> <interface> <ifName>xe17</ifName> <loadInterval>30</loadInterval> <description>ecmem8-C914057</description> <speed>1g</speed> <isAutospeed>true</isAutospeed> </interface> </vr> """ running = etree.fromstring(running_str) candidate = etree.fromstring(candidate_str) block = Block(running, candidate) actual = block.get_printable_diff() self.assertEqual([], actual)
def test_get_printable_diff_whole_block_added(self): candidate = etree.fromstring('<vr>1234</vr>') block = Block(None, candidate) actual = block.get_printable_diff() expected = ['[vr]', '+ <vr>1234</vr>'] self.assertEqual(expected, actual)
def test_get_diff_when_root_have_no_children_and_added_candidate(self): running = etree.fromstring('<vr><vrId>1</vrId></vr>') candidate = etree.fromstring('<vr><vrId>1</vrId><vrId>2</vrId></vr>') block = Block(running, candidate) expected = b'<vr><same><vrId>1</vrId></same><added><vrId>2</vrId></added></vr>' actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_diff_when_elements_same(self): running = self._get_element('vr', 'vrId', '1') candidate = self._get_element('vr', 'vrId', '1') block = Block(running, candidate) self.assertEqual(b'<vr><same><vrId>1</vrId></same></vr>', etree.tostring(block.get_diff()))
def test_get_printable_diff_whole_block_removed(self): running = etree.fromstring('<vr>1234</vr>') block = Block(running, None) actual = block.get_printable_diff() expected = ['[vr]', '- <vr>1234</vr>'] self.assertEqual(expected, actual)
def test_get_printable_with_deep_changes(self): running_str = """ <vr> <interface> <ifName>po1</ifName> <loadInterval>30</loadInterval> <ipAddr>10.32.49.1/30</ipAddr> <description>to foo.net</description> <mtu>1600</mtu> <portChannelLoadBal>rtag7</portChannelLoadBal> <ospfInterface> <ifNetworkType>point-to-points</ifNetworkType> <ipOspfInterface> <ifCostAddr>100000</ifCostAddr> </ipOspfInterface> </ospfInterface> </interface> </vr> """ candidate_str = """ <vr> <interface> <ifName>po1</ifName> <loadInterval>30</loadInterval> <ipAddr>10.32.49.1/30</ipAddr> <description>to foo.net</description> <mtu>1600</mtu> <portChannelLoadBal>rtag7</portChannelLoadBal> <ospfInterface> <ifNetworkType>point-to-point</ifNetworkType> <ipOspfInterface> <ifCostAddr>10000</ifCostAddr> </ipOspfInterface> </ospfInterface> </interface> </vr> """ running = etree.fromstring(running_str) candidate = etree.fromstring(candidate_str) block = Block(running, candidate) actual = block.get_printable_diff() expected = [ '[vr]', ' <interface>', ' <ospfInterface>', ' <ipOspfInterface>', '- <ifCostAddr>100000</ifCostAddr>', '+ <ifCostAddr>10000</ifCostAddr>', ' </ipOspfInterface>', '- <ifNetworkType>point-to-points</ifNetworkType>', '+ <ifNetworkType>point-to-point</ifNetworkType>', ' </ospfInterface>', ' <ifName>po1</ifName>', ' <loadInterval>30</loadInterval>', ' <ipAddr>10.32.49.1/30</ipAddr>', ' <description>to foo.net</description>', ' <mtu>1600</mtu>', ' <portChannelLoadBal>rtag7</portChannelLoadBal>', ' </interface>' ] self.assertEqual(expected, actual)
def test_get_diff_when_elements_moved(self): running = etree.fromstring('<vr><vrId>1</vrId><vrId>2</vrId></vr>') candidate = etree.fromstring('<vr><vrId>2</vrId><vrId>1</vrId></vr>') block = Block(running, candidate) self.assertEqual( b'<vr><moved><vrId>1</vrId></moved><moved><vrId>2</vrId></moved></vr>', etree.tostring(block.get_diff()))
def test_get_diff_when_running_is_none(self): candidate = self._get_element('vr', 'Interface', 'Interface text') block = Block(None, candidate) added_element = etree.Element('added') added_element.append(candidate) expected = etree.tostring(added_element) self.assertEqual(expected, etree.tostring(block.get_diff()))
def test_get_diff_when_root_have_no_children_and_new_ele_in_candidate( self): running = etree.fromstring('<vr><vrId>1</vrId></vr>') candidate = etree.fromstring('<vr><vrId>1</vrId><vrId>2</vrId></vr>') block = Block(running, candidate) self.assertEqual( b'<vr><same><vrId>1</vrId></same><added><vrId>2</vrId></added></vr>', etree.tostring(block.get_diff()))
def test_get_printable_diff_for_removed_tags(self): running = etree.fromstring('<vr><vrId>1</vrId><vrId>2</vrId></vr>') candidate = etree.fromstring('<vr><vrId>1</vrId></vr>') block = Block(running, candidate) actual = block.get_printable_diff() expected = ['[vr]', '- <vrId>2</vrId>'] self.assertEqual(expected, actual)
def test_get_diff_when_candidate_is_none(self): running = self._get_element('vr', 'Interface', 'Interface text') block = Block(running, None) added_element = etree.Element('removed') added_element.append(running) expected = etree.tostring(added_element) self.assertEqual(expected, etree.tostring(block.get_diff()))
def test_get_diff_when_candidate_has_deep_new_elements(self): running = etree.fromstring('<vr><vrId><mac>1</mac></vrId></vr>') candidate = etree.fromstring( '<vr><vrId><mac>1</mac></vrId><vrId><mac>3</mac></vrId></vr>') block = Block(running, candidate) expected = b'<vr><same><vrId><mac>1</mac></vrId></same><added><vrId><mac>3</mac></vrId></added></vr>' actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_diff_element_with_two_children_and_moved(self): running = etree.fromstring( '<a><b><n>r1</n><c>true</c></b><b><n>r2</n><c>true</c></b></a>') candidate = etree.fromstring( '<a><b><n>r2</n><c>true</c></b><b><n>r1</n><c>true</c></b></a>') block = Block(running, candidate) expected = b'<a><moved><b><n>r1</n><c>true</c></b></moved><moved><b><n>r2</n><c>true</c></b></moved></a>' actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_diff_when_text_changed(self): running = etree.fromstring( '<logging_cli><logging>false</logging></logging_cli>') candidate = etree.fromstring( '<logging_cli><logging>true</logging></logging_cli>') block = Block(running, candidate) expected = (b'<logging_cli><removed><logging>false</logging></removed>' b'<added><logging>true</logging></added></logging_cli>') actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_printable_diff_for_removed_and_added_tags(self): running = etree.fromstring( '<vr><vrId>1</vrId><vrId>2</vrId><foo>1</foo></vr>') candidate = etree.fromstring('<vr><vrId>1</vrId></vr>') block = Block(running, candidate) actual = block.get_printable_diff() self.assertTrue('[vr]' in actual) self.assertTrue('- <vrId>2</vrId>' in actual) self.assertTrue('- <foo>1</foo>' in actual)
def test_get_diff_when_root_have_no_children(self): running = etree.fromstring( '<vr><vrId><name>1</name></vrId><vrId><name>3</name></vrId></vr>') candidate = etree.fromstring( '<vr><vrId><name>2</name></vrId><vrId><name>4</name></vrId></vr>') block = Block(running, candidate) expected = ( b'<vr><vrId><removed><name>1</name></removed><added><name>2</name></added></vrId>' b'<vrId><removed><name>3</name></removed><added><name>4</name></added></vrId></vr>' ) actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_diff_with_multiple_children_changed(self): running_string = """ <vr> <interface> <ifName>lo.management</ifName> <vrfName>management</vrfName> <ipAddr>127.0.0.1/9</ipAddr> <mtu>1501</mtu> <ipv6Addr> <ipv6Addr>::1/128</ipv6Addr> </ipv6Addr> </interface> </vr> """ candidate_string = """ <vr> <interface> <ifName>lo.management</ifName> <vrfName>management</vrfName> <ipAddr>127.0.0.1/10</ipAddr> <mtu>1500</mtu> <ipv6Addr> <ipv6Addr>::1/129</ipv6Addr> </ipv6Addr> </interface> </vr> """ running = etree.fromstring(running_string) candidate = etree.fromstring(candidate_string) block = Block(running, candidate) expected = (b'<vr>' b'<interface>' b'<ipv6Addr>' b'<removed><ipv6Addr>::1/128</ipv6Addr></removed>' b'<added><ipv6Addr>::1/129</ipv6Addr></added>' b'</ipv6Addr>' b'<same><ifName>lo.management</ifName></same>' b'<same><vrfName>management</vrfName></same>' b'<removed><ipAddr>127.0.0.1/9</ipAddr></removed>' b'<added><ipAddr>127.0.0.1/10</ipAddr></added>' b'<removed><mtu>1501</mtu></removed>' b'<added><mtu>1500</mtu></added>' b'</interface>' b'</vr>') actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_diff_when_text_changed_but_have_other_children(self): running = etree.fromstring( '<nsmsnmp><enabled>false</enabled><vrfName>management</vrfName></nsmsnmp>' ) candidate = etree.fromstring( '<nsmsnmp><enabled>true</enabled><vrfName>management</vrfName></nsmsnmp>' ) block = Block(running, candidate) expected = (b'<nsmsnmp>' b'<same><vrfName>management</vrfName></same>' b'<removed><enabled>false</enabled></removed>' b'<added><enabled>true</enabled></added>' b'</nsmsnmp>') actual = etree.tostring(block.get_diff()) self.assertEqual(expected, actual)
def test_get_diff_with_deep_children_and_formatted(self): running_string = """ <vr> <vrId>0</vrId> <vrId>1</vrId> <vrId>2</vrId> <vrf> <vrfName>FOO_THREE</vrfName> <macVrf>true</macVrf> </vrf> <vrf> <vrfName>FOO_TWO</vrfName> <macVrf>true</macVrf> </vrf> </vr>""" candidate_string = """ <vr> <vrId>0</vrId> <vrId>1</vrId> <vrf> <vrfName>FOO_TWO</vrfName> <macVrf>true</macVrf> </vrf> <vrf> <vrfName>FOO_THREE</vrfName> <macVrf>true</macVrf> </vrf> </vr>""" running = etree.fromstring(running_string) candidate = etree.fromstring(candidate_string) block = Block(running, candidate) actual = block.get_diff() self.assertEqual(actual.tag, 'vr') actual_as_string = etree.tostring(actual).decode('utf-8') self.assertTrue('<same><vrId>0</vrId></same>' in actual_as_string) self.assertTrue('<same><vrId>1</vrId></same>' in actual_as_string) self.assertTrue( '<moved><vrf><vrfName>FOO_THREE</vrfName><macVrf>true</macVrf></vrf></moved>' in actual_as_string) self.assertTrue( '<moved><vrf><vrfName>FOO_TWO</vrfName><macVrf>true</macVrf></vrf></moved>' in actual_as_string) self.assertTrue( '<removed><vrId>2</vrId></removed>' in actual_as_string)
def test_get_diff_on_children_when_sub_element_same(self): actual = Block._get_diff_on_children( etree.fromstring('<vrId><name>1</name></vrId>'), etree.fromstring('<vrId><name>1</name></vrId>')) self.assertEqual(actual.tag, 'vrId') actual_as_string = etree.tostring(actual).decode('utf-8') self.assertTrue('<same><name>1</name></same>' in actual_as_string, actual_as_string)
def test_get_diff_on_children_when_candidate_child_not_present(self): actual = Block._get_diff_on_children( etree.fromstring('<vrId><name>2</name><foo>text</foo></vrId>'), etree.fromstring('<vrId><name>2</name></vrId>')) self.assertEqual(actual.tag, 'vrId') actual_as_string = etree.tostring(actual).decode('utf-8') self.assertTrue('<same><name>2</name></same>' in actual_as_string) self.assertTrue( '<removed><foo>text</foo></removed>' in actual_as_string)
def test_get_diff_on_children_when_single_child_changed(self): actual = Block._get_diff_on_children( etree.fromstring('<vrId><name>2</name></vrId>'), etree.fromstring('<vrId><name>1</name></vrId>')) self.assertEqual(actual.tag, 'vrId') actual_as_string = etree.tostring(actual).decode('utf-8') self.assertTrue( '<removed><name>2</name></removed>' in actual_as_string) self.assertTrue('<added><name>1</name></added>' in actual_as_string)
def test_surround_element_with_tag(self): element = etree.fromstring( '<vrf><vrfName>COMPANY_ONE</vrfName><macVrf>true</macVrf></vrf>') tag = 'added' actual = Block._surround_element_with_tag(element=element, tag=tag) expected = '<{0}>{1}</{0}>'.format( tag, etree.tostring(element).decode('utf-8')) self.assertEqual(expected, etree.tostring(actual).decode('utf-8'))
def test_get_diff_on_children_when_candidate_has_extract_elements(self): actual = Block._get_diff_on_children( etree.fromstring('<vrId><name>2</name></vrId>'), etree.fromstring('<vrId><name>2</name><foo>text</foo></vrId>')) self.assertEqual(actual.tag, 'vrId') actual_as_string = etree.tostring(actual).decode('utf-8') self.assertTrue('<same><name>2</name></same>' in actual_as_string, actual_as_string) self.assertTrue('<added><foo>text</foo></added>' in actual_as_string, actual_as_string)
def test_append_symbol_when_element_has_children_spaces_are_ignored(self): actual = Block._append_symbol(element=etree.fromstring( '<vrf><vrfName>COMPANY_ONE</vrfName><macVrf>true</macVrf></vrf>'), symbol='+', spaces=8) expected = [ '+ <vrf>', '+ <vrfName>COMPANY_ONE</vrfName>', '+ <macVrf>true</macVrf>', '+ </vrf>' ] self.assertEqual(expected, actual)
def test_get_printable_with_whole_tag_missing(self): self.maxDiff = None running_str = """ <vr> <interface> <switchportAllowedEthertypes> <ipv6>true</ipv6> <ipv4>true</ipv4> </switchportAllowedEthertypes> </interface> <bgp> <name>has</name> </bgp> </vr> """ candidate_str = """ <vr> <interface> <switchportAllowedEthertypes> <ipv6>true</ipv6> <ipv4>true</ipv4> <arp>true</arp> </switchportAllowedEthertypes> </interface> </vr> """ running = etree.fromstring(running_str) candidate = etree.fromstring(candidate_str) block = Block(running, candidate) actual = block.get_printable_diff() self.assertTrue('[vr]' in actual) self.assertTrue(' <interface>' in actual) self.assertTrue(' <switchportAllowedEthertypes>' in actual) self.assertTrue(' <ipv6>true</ipv6>' in actual) self.assertTrue(' <ipv4>true</ipv4>' in actual) self.assertTrue('+ <arp>true</arp>' in actual) self.assertTrue(' </switchportAllowedEthertypes>' in actual) self.assertTrue(' </interface>' in actual) self.assertTrue('- <bgp>' in actual) self.assertTrue('- <name>has</name>' in actual) self.assertTrue('- </bgp>' in actual)
def _get_elements_blocks(self): """ Loop over candidate and running children and create blocks and do a diff one each block Returns: (List of Blocks) For example if we have running xml as <vr><vrId>1</vrId><vrId>2</vrId></vr><ssh>foo</ssh> and candidate xml as <vr><vrId>1</vrId><vrId>3</vrId></vr><ssh>foo</ssh> Two blocks will be created one for VR and one for SSH """ blocks = [] running_paths = [] for running_child in self.running_xml: running_paths.append(get_element_path(running_child)) blocks.append( Block(running=deepcopy(running_child), candidate=deepcopy( self._get_candidate_element(running_child)))) for candidate_child in self.candidate_xml: candidate_child_path = get_element_path(candidate_child) if candidate_child_path not in running_paths: blocks.append( Block(running=None, candidate=deepcopy(candidate_child))) return blocks
def test_get_diff_on_children_when_running_has_extract_elements(self): actual = Block._get_diff_on_children( etree.fromstring( '<vrfT><dns><ser>1233</ser><ser>1244</ser><ser>1245</ser></dns></vrfT>' ), etree.fromstring('<vrfT><dns><ser>2</ser></dns></vrfT>'), ) self.assertEqual(actual.tag, 'vrfT') actual_as_string = etree.tostring(actual).decode('utf-8') self.assertTrue( '<removed><ser>1244</ser></removed>' in actual_as_string, actual_as_string) self.assertTrue( '<removed><ser>1233</ser></removed>' in actual_as_string, actual_as_string) self.assertTrue('<added><ser>2</ser></added>' in actual_as_string, actual_as_string)