content: """Testing framework."""
  
  import functools
  from itertools import zip_longest
  import inspect
  import json
  
  import pytest
  from napalm.base.test import helpers
  from napalm.base import models
  from napalm.base import NetworkDriver
  from napalm.base.test import conftest
  
  
  def list_dicts_diff(prv, nxt):
      """Compare two lists of dicts."""
      result = []
      for prv_element, nxt_element in zip_longest(prv, nxt, fillvalue={}):
          intermediate_result = dict_diff(prv_element, nxt_element)
          if intermediate_result:
              result.append(intermediate_result)
      return result
  
  
  def dict_diff(prv, nxt):
      """Return a dict of keys that differ with another config object."""
      keys = set(list(prv.keys()) + list(nxt.keys()))
      result = {}
  
      for k in keys:
          if isinstance(prv.get(k), dict):
              if isinstance(nxt.get(k), dict):
                  "If both are dicts we do a recursive call."
                  diff = dict_diff(prv.get(k), nxt.get(k))
                  if diff:
                      result[k] = diff
              else:
                  "If only one is a dict they are clearly different"
                  result[k] = {"result": prv.get(k), "expected": nxt.get(k)}
          else:
              "Ellipsis is a wildcard." ""
              if prv.get(k) != nxt.get(k) and nxt.get(k) != "...":
                  result[k] = {"result": prv.get(k), "expected": nxt.get(k)}
      return result
  
  
  def wrap_test_cases(func):
      """Wrap test cases."""
      func.__dict__["build_test_cases"] = True
  
      @functools.wraps(func)
      def mock_wrapper(cls, test_case):
          for patched_attr in cls.device.patched_attrs:
              attr = getattr(cls.device, patched_attr)
              attr.current_test = func.__name__
              attr.current_test_case = test_case
  
          try:
              # This is an ugly, ugly, ugly hack because some python objects don't load
              # as expected. For example, dicts where integers are strings
              result = json.loads(json.dumps(func(cls, test_case)))
          except IOError:
              if test_case == "no_test_case_found":
                  pytest.fail("No test case for '{}' found".format(func.__name__))
              else:
                  raise
          except NotImplementedError:
              pytest.skip("Method not implemented")
              return
  
          # This is an ugly, ugly, ugly hack because some python objects don't load
          # as expected. For example, dicts where integers are strings
  
          try:
              expected_result = attr.expected_result
          except IOError as e:
              raise Exception("{}. Actual result was: {}".format(e, json.dumps(result)))
          if isinstance(result, list):
              diff = list_dicts_diff(result, expected_result)
          else:
              diff = dict_diff(result, expected_result)
          if diff:
              print("Resulting JSON object was: {}".format(json.dumps(result)))
              raise AssertionError(
                  "Expected result varies on some keys {}".format(json.dumps(diff))
              )
  
          for patched_attr in cls.device.patched_attrs:
              attr = getattr(cls.device, patched_attr)
              attr.current_test = ""  # Empty them to avoid side effects
              attr.current_test_case = ""  # Empty them to avoid side effects
  
          return None
  
      @functools.wraps(func)
      def real_wrapper(cls, test_case):
          try:
              return func(cls, test_case)
          except NotImplementedError:
              pytest.skip("Method not implemented")
              return
  
      if conftest.NAPALM_TEST_MOCK:
          return mock_wrapper
      else:
          return real_wrapper
  
  
  class BaseTestGetters(object):
      """Base class for testing drivers."""
  
      def test_method_signatures(self):
          """
          Test that all methods have the same signature.
  
          The type hint annotations are ignored here because the import paths might differ.
          """
          errors = {}
          cls = self.driver
          # Create fictional driver instance (py3 needs bound methods)
          tmp_obj = cls(hostname="test", username="admin", password="pwd")
          attrs = [m for m, v in inspect.getmembers(tmp_obj)]
          for attr in attrs:
              func = getattr(tmp_obj, attr)
              if attr.startswith("_") or not inspect.ismethod(func):
                  continue
              try:
                  orig = getattr(NetworkDriver, attr)
                  orig_spec = inspect.getfullargspec(orig)[:4]
              except AttributeError:
                  orig_spec = "Method does not exist in napalm.base"
              func_spec = inspect.getfullargspec(func)[:4]
              if orig_spec != func_spec:
                  errors[attr] = (orig_spec, func_spec)
  
          EXTRA_METHODS = ["__init__"]
          for method in EXTRA_METHODS:
              orig_spec = inspect.getfullargspec(getattr(NetworkDriver, method))[:4]
              func_spec = inspect.getfullargspec(getattr(cls, method))[:4]
              if orig_spec != func_spec:
                  errors[attr] = (orig_spec, func_spec)
  
          assert not errors, "Some methods vary. \n{}".format(errors.keys())
  
      @wrap_test_cases
      def test_is_alive(self, test_case):
          """Test is_alive method."""
          alive = self.device.is_alive()
          assert helpers.test_model(models.AliveDict, alive)
          return alive
  
      @wrap_test_cases
      def test_get_facts(self, test_case):
          """Test get_facts method."""
          facts = self.device.get_facts()
          assert helpers.test_model(models.FactsDict, facts)
          return facts
  
      @wrap_test_cases
      def test_get_interfaces(self, test_case):
          """Test get_interfaces."""
          get_interfaces = self.device.get_interfaces()
          assert len(get_interfaces) > 0
  
          for interface, interface_data in get_interfaces.items():
              assert helpers.test_model(models.InterfaceDict, interface_data)
  
          return get_interfaces
  
      @wrap_test_cases
      def test_get_lldp_neighbors(self, test_case):
          """Test get_lldp_neighbors."""
          get_lldp_neighbors = self.device.get_lldp_neighbors()
          assert len(get_lldp_neighbors) > 0
  
          for interface, neighbor_list in get_lldp_neighbors.items():
              for neighbor in neighbor_list:
                  assert helpers.test_model(models.LLDPNeighborDict, neighbor)
  
          return get_lldp_neighbors
  
      @wrap_test_cases
      def test_get_interfaces_counters(self, test_case):
          """Test get_interfaces_counters."""
          get_interfaces_counters = self.device.get_interfaces_counters()
          assert len(self.device.get_interfaces_counters()) > 0
  
          for interface, interface_data in get_interfaces_counters.items():
              assert helpers.test_model(models.InterfaceCounterDict, interface_data)
  
          return get_interfaces_counters
  
      @wrap_test_cases
      def test_get_environment(self, test_case):
          """Test get_environment."""
          environment = self.device.get_environment()
          assert len(environment) > 0
  
          for fan, fan_data in environment["fans"].items():
              assert helpers.test_model(models.FanDict, fan_data)
  
          for power, power_data in environment["power"].items():
              assert helpers.test_model(models.PowerDict, power_data)
  
          for temperature, temperature_data in environment["temperature"].items():
              assert helpers.test_model(models.TemperatureDict, temperature_data)
  
          for cpu, cpu_data in environment["cpu"].items():
              assert helpers.test_model(models.CPUDict, cpu_data)
  
          assert helpers.test_model(models.MemoryDict, environment["memory"])
  
          return environment
  
      @wrap_test_cases
      def test_get_bgp_neighbors(self, test_case):
          """Test get_bgp_neighbors."""
          get_bgp_neighbors = self.device.get_bgp_neighbors()
          if len(get_bgp_neighbors) > 0:
              assert "global" in get_bgp_neighbors.keys()
  
          for vrf, vrf_data in get_bgp_neighbors.items():
              assert isinstance(vrf_data["router_id"], str)
  
              for peer, peer_data in vrf_data["peers"].items():
                  assert helpers.test_model(models.PeerDict, peer_data)
  
                  for af, af_data in peer_data["address_family"].items():
                      assert helpers.test_model(models.AFDict, af_data)
  
          return get_bgp_neighbors
  
      @wrap_test_cases
      def test_get_lldp_neighbors_detail(self, test_case):
          """Test get_lldp_neighbors_detail."""
          get_lldp_neighbors_detail = self.device.get_lldp_neighbors_detail()
          assert len(get_lldp_neighbors_detail) > 0
  
          for interface, neighbor_list in get_lldp_neighbors_detail.items():
              for neighbor in neighbor_list:
                  assert helpers.test_model(models.LLDPNeighborDetailDict, neighbor)
  
          return get_lldp_neighbors_detail
  
      @wrap_test_cases
      def test_get_bgp_config(self, test_case):
          """Test get_bgp_config."""
          get_bgp_config = self.device.get_bgp_config()
          assert get_bgp_config == {} or len(get_bgp_config) > 0
  
          for bgp_group in get_bgp_config.values():
              assert helpers.test_model(models.BGPConfigGroupDict, bgp_group)
              for bgp_neighbor in bgp_group.get("neighbors", {}).values():
                  assert helpers.test_model(models.BGPConfigNeighborDict, bgp_neighbor)
  
          return get_bgp_config
  
      @wrap_test_cases
      def test_get_bgp_neighbors_detail(self, test_case):
          """Test get_bgp_neighbors_detail."""
          get_bgp_neighbors_detail = self.device.get_bgp_neighbors_detail()
  
          assert len(get_bgp_neighbors_detail) > 0
  
          for vrf, vrf_ases in get_bgp_neighbors_detail.items():
              assert isinstance(vrf, str)
              for remote_as, neighbor_list in vrf_ases.items():
                  assert isinstance(remote_as, int)
                  for neighbor in neighbor_list:
                      assert helpers.test_model(models.PeerDetailsDict, neighbor)
  
          return get_bgp_neighbors_detail
  
      @wrap_test_cases
      def test_get_arp_table(self, test_case):
          """Test get_arp_table."""
          get_arp_table = self.device.get_arp_table()
          assert len(get_arp_table) > 0
  
          for arp_entry in get_arp_table:
              assert helpers.test_model(models.ARPTableDict, arp_entry)
  
          return get_arp_table
  
      @wrap_test_cases
      def test_get_arp_table_with_vrf(self, test_case):
          """Test get_arp_table."""
          get_arp_table = self.device.get_arp_table(vrf="TEST")
          assert len(get_arp_table) > 0
  
          for arp_entry in get_arp_table:
              assert helpers.test_model(models.ARPTableDict, arp_entry)
  
          return get_arp_table
  
      @wrap_test_cases
      def test_get_ipv6_neighbors_table(self, test_case):
          """Test get_ipv6_neighbors_table."""
          get_ipv6_neighbors_table = self.device.get_ipv6_neighbors_table()
  
          for entry in get_ipv6_neighbors_table:
              assert helpers.test_model(models.IPV6NeighborDict, entry)
  
          return get_ipv6_neighbors_table
  
      @wrap_test_cases
      def test_get_ntp_peers(self, test_case):
          """Test get_ntp_peers."""
          get_ntp_peers = self.device.get_ntp_peers()
          assert len(get_ntp_peers) > 0
  
          for peer, peer_details in get_ntp_peers.items():
              assert isinstance(peer, str)
              assert helpers.test_model(
                  models.NTPPeerDict, peer_details, allow_subset=True
              )
  
          return get_ntp_peers
  
      @wrap_test_cases
      def test_get_ntp_servers(self, test_case):
          """Test get_ntp_servers."""
          get_ntp_servers = self.device.get_ntp_servers()
          assert len(get_ntp_servers) > 0
  
          for server, server_details in get_ntp_servers.items():
              assert isinstance(server, str)
              assert helpers.test_model(
                  models.NTPServerDict, server_details, allow_subset=True
              )
  
          return get_ntp_servers
  
      @wrap_test_cases
      def test_get_ntp_stats(self, test_case):
          """Test get_ntp_stats."""
          get_ntp_stats = self.device.get_ntp_stats()
          assert len(get_ntp_stats) > 0
  
          for ntp_peer_details in get_ntp_stats:
              assert helpers.test_model(models.NTPStats, ntp_peer_details)
  
          return get_ntp_stats
  
      @wrap_test_cases
      def test_get_interfaces_ip(self, test_case):
          """Test get_interfaces_ip."""
          get_interfaces_ip = self.device.get_interfaces_ip()
          assert len(get_interfaces_ip) > 0
  
          for interface, interface_details in get_interfaces_ip.items():
              ipv4 = interface_details.get("ipv4", {})
              ipv6 = interface_details.get("ipv6", {})
              for ip, ip_details in ipv4.items():
                  assert helpers.test_model(models.InterfacesIPDictEntry, ip_details)
              for ip, ip_details in ipv6.items():
                  assert helpers.test_model(models.InterfacesIPDictEntry, ip_details)
  
          return get_interfaces_ip
  
      @wrap_test_cases
      def test_get_mac_address_table(self, test_case):
          """Test get_mac_address_table."""
          get_mac_address_table = self.device.get_mac_address_table()
          assert len(get_mac_address_table) > 0
  
          for mac_table_entry in get_mac_address_table:
              assert helpers.test_model(models.MACAdressTable, mac_table_entry)
  
          return get_mac_address_table
  
      @wrap_test_cases
      def test_get_route_to(self, test_case):
          """Test get_route_to."""
          destination = "1.0.4.0/24"
          protocol = "bgp"
          get_route_to = self.device.get_route_to(
              destination=destination, protocol=protocol
          )
  
          assert len(get_route_to) > 0
  
          for prefix, routes in get_route_to.items():
              for route in routes:
                  assert helpers.test_model(models.RouteDict, route)
  
          return get_route_to
  
      @wrap_test_cases
      def test_get_route_to_longer(self, test_case):
          """Test get_route_to with longer=True"""
          destination = "1.0.4.0/24"
          protocol = "bgp"
  
          get_route_to = self.device.get_route_to(
              destination=destination, protocol=protocol, longer=True
          )
  
          assert len(get_route_to) > 0
  
          for prefix, routes in get_route_to.items():
              for route in routes:
                  assert helpers.test_model(models.RouteDict, route)
  
          return get_route_to
  
      @wrap_test_cases
      def test_get_snmp_information(self, test_case):
          """Test get_snmp_information."""
          get_snmp_information = self.device.get_snmp_information()
  
          assert len(get_snmp_information) > 0
  
          for snmp_entry in get_snmp_information:
              assert helpers.test_model(models.SNMPDict, get_snmp_information)
  
          for community, community_data in get_snmp_information["community"].items():
              assert helpers.test_model(models.SNMPCommunityDict, community_data)
  
          return get_snmp_information
  
      @wrap_test_cases
      def test_get_probes_config(self, test_case):
          """Test get_probes_config."""
          get_probes_config = self.device.get_probes_config()
  
          assert len(get_probes_config) > 0
  
          for probe_name, probe_tests in get_probes_config.items():
              for test_name, test_config in probe_tests.items():
                  assert helpers.test_model(models.ProbeTestDict, test_config)
  
          return get_probes_config
  
      @wrap_test_cases
      def test_get_probes_results(self, test_case):
          """Test get_probes_results."""
          get_probes_results = self.device.get_probes_results()
          assert len(get_probes_results) > 0
  
          for probe_name, probe_tests in get_probes_results.items():
              for test_name, test_results in probe_tests.items():
                  assert helpers.test_model(models.ProbeTestResultDict, test_results)
  
          return get_probes_results
  
      @wrap_test_cases
      def test_ping(self, test_case):
          """Test ping."""
          destination = "8.8.8.8"
          get_ping = self.device.ping(destination)
          assert isinstance(get_ping.get("success"), dict)
          ping_results = get_ping.get("success", {})
  
          assert helpers.test_model(models.PingDict, ping_results)
  
          for ping_result in ping_results.get("results", []):
              assert helpers.test_model(models.PingResultDictEntry, ping_result)
  
          return get_ping
  
      @wrap_test_cases
      def test_traceroute(self, test_case):
          """Test traceroute."""
          destination = "8.8.8.8"
          get_traceroute = self.device.traceroute(destination)
          assert isinstance(get_traceroute.get("success"), dict)
          traceroute_results = get_traceroute.get("success", {})
  
          for hope_id, hop_result in traceroute_results.items():
              for probe_id, probe_result in hop_result.get("probes", {}).items():
                  assert helpers.test_model(models.TracerouteDict, probe_result)
  
          return get_traceroute
  
      @wrap_test_cases
      def test_get_users(self, test_case):
          """Test get_users."""
          get_users = self.device.get_users()
          assert len(get_users)
  
          for user, user_details in get_users.items():
              assert helpers.test_model(models.UsersDict, user_details)
              assert (0 <= user_details.get("level") <= 15) or (
                  user_details.get("level") == 20
              )
  
          return get_users
  
      @wrap_test_cases
      def test_get_optics(self, test_case):
          """Test get_optics."""
          get_optics = self.device.get_optics()
          assert isinstance(get_optics, dict)
  
          for iface, iface_data in get_optics.items():
              assert isinstance(iface, str)
              for channel in iface_data["physical_channels"]["channel"]:
                  assert len(channel) == 2
                  assert isinstance(channel["index"], int)
                  for field in ["input_power", "output_power", "laser_bias_current"]:
                      assert len(channel["state"][field]) == 4
                      assert isinstance(channel["state"][field]["instant"], float)
                      assert isinstance(channel["state"][field]["avg"], float)
                      assert isinstance(channel["state"][field]["min"], float)
                      assert isinstance(channel["state"][field]["max"], float)
  
          return get_optics
  
      @wrap_test_cases
      def test_get_config(self, test_case):
          """Test get_config method."""
          get_config = self.device.get_config()
  
          assert isinstance(get_config, dict)
          assert helpers.test_model(models.ConfigDict, get_config)
  
          return get_config
  
      @wrap_test_cases
      def test_get_config_filtered(self, test_case):
          """Test get_config method."""
          if self.device.platform == "iosxr_netconf":
              pytest.skip("This test is not implemented on {self.device.platform}")
          for config in ["running", "startup", "candidate"]:
              get_config = self.device.get_config(retrieve=config)
  
              assert get_config["candidate"] == "" if config != "candidate" else True
              assert get_config["startup"] == "" if config != "startup" else True
              assert get_config["running"] == "" if config != "running" else True
  
          return get_config
  
      @wrap_test_cases
      def test_get_config_sanitized(self, test_case):
          """Test get_config method."""
          get_config = self.device.get_config(sanitized=True)
  
          assert isinstance(get_config, dict)
          assert helpers.test_model(models.ConfigDict, get_config)
  
          return get_config
  
      @wrap_test_cases
      def test_get_config_sanitized_filtered(self, test_case):
          """Test get_config with both sanitized=True and retrieve parameter."""
          return_config = {}
          get_config = self.device.get_config(retrieve="running", sanitized=True)
          assert isinstance(get_config, dict)
          assert helpers.test_model(models.ConfigDict, get_config)
          assert get_config["startup"] == ""
          assert get_config["candidate"] == ""
          assert get_config["running"] != ""
          return_config["running"] = get_config["running"]
  
          get_config = self.device.get_config(retrieve="startup", sanitized=True)
          assert isinstance(get_config, dict)
          assert helpers.test_model(models.ConfigDict, get_config)
          assert get_config["running"] == ""
          assert get_config["candidate"] == ""
  
          return_config["startup"] = get_config["startup"]
  
          return_config["candidate"] = ""
  
          return return_config
  
      @wrap_test_cases
      def test_get_network_instances(self, test_case):
          """Test get_network_instances method."""
          get_network_instances = self.device.get_network_instances()
  
          assert isinstance(get_network_instances, dict)
          for network_instance_name, network_instance in get_network_instances.items():
              assert helpers.test_model(models.NetworkInstanceDict, network_instance)
              assert helpers.test_model(
                  models.NetworkInstanceStateDict, network_instance["state"]
              )
              assert helpers.test_model(
                  models.NetworkInstanceInterfacesDict, network_instance["interfaces"]
              )
  
          return get_network_instances
  
      @wrap_test_cases
      def test_get_firewall_policies(self, test_case):
          """Test get_firewall_policies method."""
          get_firewall_policies = self.device.get_firewall_policies()
          assert len(get_firewall_policies) > 0
          for policy_name, policy_details in get_firewall_policies.items():
              for policy_term in policy_details:
                  assert helpers.test_model(models.FirewallPolicyDict, policy_term)
          return get_firewall_policies
  
      @wrap_test_cases
      def test_get_vlans(self, test_case):
          """Test get_vlans."""
          get_vlans = self.device.get_vlans()
  
          assert len(get_vlans) > 0
  
          for vlan, vlan_data in get_vlans.items():
              assert helpers.test_model(models.VlanDict, vlan_data)
  
          return get_vlans
  