Repository: napalm-automation-community/napalm-arubaos-switch (language: python)

Issue:
Interfaces
# Add get_interfaces

## Description
I couldn't find an endpoint to get information about interfaces, but used the cli endpoint to get the output of the cli.

It will be parsed for interfaces and is doing another calls on all interfaces to get more specific information about the interfaces as we need this to fill the expected template by napalm.
Needed to implement the asynchronous call into the method as all other calls are synchronous and this would take much longer to process on all interfaces.
Maybe a good idea to implement only asynchronous calls instead of synchronous calls for all methods!?

I don't know right now if there could be another naming format for interfaces too. On the test device I could only see integers for the interfaces (I guess 1-10). Are there maybe also other formats like ge0/0/0???


Discussion / hints:
Yes, the `cli()` method is the only option. How fast was to get all the interface information on the 2530-8G?

On my tests, API calls turned out to be very expensive. Aruba switches showed to have some sort of CPU protection where they rate-limit API calls to 1 call/5sec, so it may take  `(num_interfaces * 5) + 5` seconds for `get_interfaces()` to return something.

I think we'd better off doing a single `cli("display interface")` and parsing it with textfsm as we did with `get_arp_table()` or `get_route_to()`. 

@hupebln  What do you think?
@gcotone synchronous it was around 55 seconds and asynchronous around 25 when I timed it.

"display interface" is actually way better. I'll look into it to parse it.
But still the question if the name of the interfaces is always an integer. Have you seen another formats on these devices?
It's not always an `int`. Interface name is platform dependant and also user-configurable (can be renamed), so potentially it could be any word `\w` including dashes, dots and slashes.  
I've rebuilt the method and use **display interface** + **show interfaces brief** asynchronously.
textfsm is used now as well, instead of manually regex'ing

But there are still values missing:
* last_flapped
* mtu
@hupebln interface MTU is displayed as `The Maximum Frame Length`, e.g.:

```
switch# display interface 
 IP Packet Frame Type: n/a, Hardware Address: 3821c7-b93f0f
 Description: 1 interface
 Loopback is n/a
 Media type is twisted Pair
 Port hardware type is 100/1000T
 1000Mbps-speed mode,  full-duplex mode
 Link speed type is autonegotiation, link duplex type is autonegotiation
 Flow-control is not enabled
 The Maximum Frame Length is 9216
...
```

Additionally, if the interface is admin disabled, it can be extracted directly from `display interface`:
``` 
switch# display interface | beg Administratively
 8 current state: DOWN ( Administratively )
 IP Packet Frame Type: n/a, Hardware Address: 3821c7-b93f08
 Description: 8 interface
...
```
`last_flapped` seems to be not available
I'll implement it like discussed, but will close it here and take care of the async beforehand.

Fix patch:
diff --git a/README.md b/README.md
index 6a3f011..3b39faf 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ Driver implementation for Aruba OS Switch. Tested in AOS > WC.16.09.0004, some m
     * commit_config()                 ✅
     * compare_config()                ✅
     * compliance_report()             ✅
+    * confirm_commit()                ✅
     * discard_config()                ✅  
     * get_arp_table()                 ✅
     * get_bgp_config()                ❌*
@@ -20,7 +21,7 @@ Driver implementation for Aruba OS Switch. Tested in AOS > WC.16.09.0004, some m
     * get_facts()                     ✅
     * get_firewall_policies()         ❌*
     * get_interfaces_counters()       ❌***
-    * get_interfaces()                ✅
+    * get_interfaces()                ❌
     * get_interfaces_ip()             ✅
     * get_ipv6_neighbors_table()      ❌*
     * get_lldp_neighbors()            ✅
@@ -35,6 +36,7 @@ Driver implementation for Aruba OS Switch. Tested in AOS > WC.16.09.0004, some m
     * get_route_to()                  ✅
     * get_snmp_information()          ❌  - Planned
     * get_users()                     ❌  - Planned
+    * has_pending_commit()            ✅
     * is_alive()                      ✅
     * load_merge_candidate()          ✅**
     * load_replace_candidate()        ✅
diff --git a/napalm_arubaoss/ArubaOS.py b/napalm_arubaoss/ArubaOS.py
index df8a421..30e14f9 100644
--- a/napalm_arubaoss/ArubaOS.py
+++ b/napalm_arubaoss/ArubaOS.py
@@ -7,6 +7,7 @@
     backup_config,
     commit_config,
     compare_config,
+    confirm_commit,
     get_mac_address_table,
     get_facts,
     get_arp_table,
@@ -17,22 +18,23 @@
     get_ntp_stats,
     get_ntp_servers,
     get_route_to,
+    has_pending_commit,
     is_alive,
     load_merge_candidate,
     load_replace_candidate,
     ping,
     rollback,
-    traceroute
+    traceroute,
 )
 
 from napalm.base.base import NetworkDriver
 
-logger = logging.getLogger('arubaoss')
+logger = logging.getLogger("arubaoss")
 logger.setLevel(logging.INFO)
 
 stream_formatter = logging.Formatter(
-        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
-    )
+    "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
+)
 
 streamhandler = logging.StreamHandler()
 streamhandler.setFormatter(stream_formatter)
@@ -47,17 +49,28 @@ class ArubaOSS(NetworkDriver):
     def __init__(
             self,
             hostname,
-            username='',
-            password='',
-            timeout=10,
+            username,
+            password,
+            timeout=60,
             optional_args=None
     ):
-        """Instantiate the module."""
-        if optional_args.get('debugging', False):
+        """
+        Initialize Class ArubaOSS.
+
+        :param hostname: Hostname of the device
+        :param username: Username for the login
+        :param password: Password for the login
+        :param timeout: timeout to be passed to Request-Futures
+        :param optional_args: Optional Args to be passed to Request-Futures
+        """
+        if not optional_args:
+            optional_args = {}
+
+        if optional_args.get("debugging", False):
             logger.setLevel(logging.DEBUG)
             streamhandler.setLevel(logging.DEBUG)
 
-        if optional_args.get('disable_ssl_warnings', False):
+        if optional_args.get("disable_ssl_warnings", False):
             urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 
         self.hostname = hostname
@@ -91,15 +104,15 @@ def close(self):
 
         return ret
 
-    def commit_config(self, message=None, confirm=0):
+    def commit_config(self, message="", revert_in=None):
         """
         Backups and commit the configuration, and handles commit confirm.
 
         :param message:
-        :param confirm:
+        :param revert_in:
         :return:
         """
-        ret = commit_config(confirm=confirm)
+        ret = commit_config(self=self, revert_in=revert_in)
 
         return ret
 
@@ -109,7 +122,7 @@ def compare_config(self):
 
         :return:
         """
-        ret = compare_config()
+        ret = compare_config(self=self)
 
         return ret
 
@@ -123,6 +136,15 @@ def compliance_report(self, validation_file=None, validation_source=None):
         """
         return super(ArubaOSS, self).compliance_report()
 
+    def confirm_commit(self):
+        """
+        Confirm the changes requested via commit_config when commit_confirm=True.
+
+        Should cause self.has_pending_commit to return False when done.
+        :return: None
+        """
+        return confirm_commit(self=self)
+
     def connection_tests(self):
         """
         Show connection tests - NOT IMPLEMENTED.
@@ -137,21 +159,23 @@ def discard_config(self):
 
         :return:
         """
-        backup_config(destination='REST_Payload_Backup')
+        if self.has_pending_commit():
+            self.load_merge_candidate(config="no job ROLLBACK")
 
-    def get_arp_table(self, *args, **kwargs):
+        backup_config(self=self, destination="REST_Payload_Backup")
+
+    def get_arp_table(self, vrf=""):
         """
         Get device's ARP table.
 
-        :param args:
-        :param kwargs:
+        :param vrf:
         :return:
         """
-        ret = get_arp_table(self_obj=self)
+        ret = get_arp_table(self=self, vrf=vrf)
 
         return ret
 
-    def get_bgp_config(self, group='', neighbor=''):
+    def get_bgp_config(self, group="", neighbor=""):
         """
         Get BGP config - NOT IMPLEMENTED.
 
@@ -169,7 +193,7 @@ def get_bgp_neighbors(self):
         """
         return super(ArubaOSS, self).get_bgp_neighbors()
 
-    def get_bgp_neighbors_detail(self, neighbor_address=''):
+    def get_bgp_neighbors_detail(self, neighbor_address=""):
         """
         Get BGP Neighbors detail - NOT IMPLEMENTED.
 
@@ -178,15 +202,17 @@ def get_bgp_neighbors_detail(self, neighbor_address=''):
         """
         return super(ArubaOSS, self).get_bgp_neighbors_detail()
 
-    def get_config(self, retrieve='all', full=False):
+    def get_config(self, retrieve="all", full=False, sanitized=False):
         """
         Get configuration stored on the device.
 
         :param retrieve:
         :param full:
+        :param sanitized:
         :return:
         """
-        ret = get_config(retrieve=retrieve)
+        # TODO check why "full" exists
+        ret = get_config(self=self, retrieve=retrieve)
 
         return ret
 
@@ -220,7 +246,7 @@ def get_facts(self):
 
         :return:
         """
-        ret = get_facts()
+        ret = get_facts(self=self)
 
         return ret
 
@@ -256,7 +282,7 @@ def get_interfaces_ip(self):
 
         :return:
         """
-        ret = get_interfaces_ip()
+        ret = get_interfaces_ip(self=self)
 
         return ret
 
@@ -274,19 +300,21 @@ def get_lldp_neighbors(self):
 
         :return:
         """
-        ret = get_lldp_neighbors()
+        ret = get_lldp_neighbors(self=self)
 
         return ret
 
-    def get_lldp_neighbors_detail(self, *args, **kwargs):
+    def get_lldp_neighbors_detail(self, interface=""):
         """
         Get LLDP neighbor information.
 
-        :param args:
-        :param kwargs:
+        NOTE: Parent Interface is always empty,
+        as the information isn't available.
+
+        :param interface:
         :return:
         """
-        ret = get_lldp_neighbors_detail(*args, **kwargs)
+        ret = get_lldp_neighbors_detail(self=self, interface=interface)
 
         return ret
 
@@ -294,13 +322,20 @@ def get_mac_address_table(self):
         """
         Get the mac-address table of the device.
 
+        "static", "moves" and "last_move" have always default values,
+        as there is no helpful information from the device.
+
+        static: False,  # not supported
+        moves: 0,  # not supported
+        last_move: 0.0  # not supported
+
         :return:
         """
-        ret = get_mac_address_table()
+        ret = get_mac_address_table(self=self)
 
         return ret
 
-    def get_network_instances(self, name=''):
+    def get_network_instances(self, name=""):
         """
         Get network instances - NOT IMPLEMENTED.
 
@@ -318,7 +353,7 @@ def get_ntp_peers(self):
 
         :return:
         """
-        ret = get_ntp_servers()
+        ret = get_ntp_servers(self=self)
 
         return ret
 
@@ -330,7 +365,7 @@ def get_ntp_servers(self):
 
         :return:
         """
-        ret = get_ntp_servers()
+        ret = get_ntp_servers(self=self)
 
         return ret
 
@@ -340,7 +375,7 @@ def get_ntp_stats(self):
 
         :return:
         """
-        ret = get_ntp_stats()
+        ret = get_ntp_stats(self=self)
 
         return ret
 
@@ -371,18 +406,19 @@ def get_probes_results(self):
         """
         return super(ArubaOSS, self).get_probes_results()
 
-    def get_route_to(self, destination='', protocol=''):
+    def get_route_to(self, destination="", protocol="", longer=False):
         """
         Get route to destination.
 
         :param destination:
         :param protocol:
+        :param longer:
         :return:
         """
         ret = get_route_to(
+            self=self,
             destination=destination,
-            protocol=protocol,
-            self_obj=self
+            protocol=protocol
         )
 
         return ret
@@ -403,13 +439,21 @@ def get_users(self):
         """
         return super(ArubaOSS, self).get_users()
 
+    def has_pending_commit(self):
+        """
+        Boolean indicates if a commit_config that needs confirmed is in process.
+
+        :return Boolean
+        """
+        return has_pending_commit(self=self)
+
     def is_alive(self):
         """
         Is alive method.
 
         :return:
         """
-        ret = is_alive()
+        ret = is_alive(self=self)
 
         return ret
 
@@ -426,7 +470,9 @@ def load_merge_candidate(self, filename=None, config=None):
         :param config:
         :return:
         """
-        ret = load_merge_candidate(filename=filename, config=config)
+        ret = load_merge_candidate(
+            self=self, filename=filename, config=config
+        )
 
         return ret
 
@@ -446,16 +492,14 @@ def load_replace_candidate(self, filename=None, config=None):
         :param config:
         :return:
         """
-        ret = load_replace_candidate(filename=filename, config=config)
+        ret = load_replace_candidate(
+            self=self, filename=filename, config=config
+        )
 
         return ret
 
     def load_template(
-            self,
-            template_name,
-            template_source=None,
-            template_path=None,
-            **template_vars
+        self, template_name, template_source=None, template_path=None, **template_vars
     ):
         """
         Load template - NOT IMPLEMENTED.
@@ -479,20 +523,21 @@ def open(self):
             username=self.username,
             password=self.password,
             timeout=self.timeout,
-            optional_args=self.optional_args
+            optional_args=self.optional_args,
         )
 
         return True
 
     def ping(
-            self,
-            destination,
-            source='',
-            timeout=2,
-            ttl=255,
-            size=100,
-            count=5,
-            vrf=''
+        self,
+        destination,
+        source="",
+        ttl=255,
+        timeout=2,
+        size=100,
+        count=5,
+        vrf="",
+        source_interface=""
     ):
         """
         Execute ping on the device and returns a dictionary with the result.
@@ -500,13 +545,14 @@ def ping(
         :param destination: needed argument
         :param source: not implemented as not available from device
         :param ttl: not implemented as not available from device
-        :param timeout: not implemented as not available from device
+        :param timeout: Maximum seconds to wait after sending final packet
         :param vrf: not implemented as not available from device
         :param size: not implemented as not available from device
         :param count: not implemented as not available from device
+        :param source_interface: not  implemented as not available from device
         :return: returns a dictionary containing the hops and probes
         """
-        ret = ping(destination=destination, timeout=timeout)
+        ret = ping(self=self, destination=destination, timeout=timeout)
         return ret
 
     def post_connection_tests(self):
@@ -531,18 +577,11 @@ def rollback(self):
 
         :return:
         """
-        ret = rollback()
+        ret = rollback(self=self)
 
         return ret
 
-    def traceroute(
-            self,
-            destination,
-            source='',
-            ttl=255,
-            timeout=2,
-            vrf=''
-    ):
+    def traceroute(self, destination, source="", ttl=255, timeout=2, vrf=""):
         """
         Execute traceroute on the device.
 
@@ -553,6 +592,6 @@ def traceroute(
         :param vrf: not implemented as not available from device
         :return: returns a dictionary containing the hops and probes
         """
-        ret = traceroute(destination=destination)
+        ret = traceroute(self=self, destination=destination)
 
         return ret
diff --git a/napalm_arubaoss/helper/__init__.py b/napalm_arubaoss/helper/__init__.py
index bd73ee2..0edbf8c 100644
--- a/napalm_arubaoss/helper/__init__.py
+++ b/napalm_arubaoss/helper/__init__.py
@@ -3,6 +3,7 @@
 from napalm_arubaoss.helper.base import Connection
 from napalm_arubaoss.helper.commit_config import commit_config
 from napalm_arubaoss.helper.compare_config import compare_config
+from napalm_arubaoss.helper.confirm_commit import confirm_commit
 from napalm_arubaoss.helper.get_arp_table import get_arp_table
 from napalm_arubaoss.helper.get_config import get_config
 from napalm_arubaoss.helper.get_facts import get_facts
@@ -13,6 +14,7 @@
 from napalm_arubaoss.helper.get_ntp_servers import get_ntp_servers
 from napalm_arubaoss.helper.get_ntp_stats import get_ntp_stats
 from napalm_arubaoss.helper.get_route_to import get_route_to
+from napalm_arubaoss.helper.has_pending_commit import has_pending_commit
 from napalm_arubaoss.helper.is_alive import is_alive
 from napalm_arubaoss.helper.load_merge_candidate import load_merge_candidate
 from napalm_arubaoss.helper.load_replace_candidate import load_replace_candidate
@@ -26,34 +28,36 @@
     config_batch,
     read_candidate,
     str_to_b64,
-    transaction_status
+    transaction_status,
 )
 
 __all__ = (
-    'Connection',
-    'backup_config',
-    'commit_candidate',
-    'commit_config',
-    'compare_config',
-    'config_batch',
-    'get_mac_address_table',
-    'get_facts',
-    'get_arp_table',
-    'get_config',
-    'get_interfaces_ip',
-    'get_lldp_neighbors',
-    'get_lldp_neighbors_detail',
-    'get_ntp_stats',
-    'get_ntp_servers',
-    'get_route_to',
-    'is_alive',
-    'load_merge_candidate',
-    'load_replace_candidate',
-    'mac_reformat',
-    'ping',
-    'read_candidate',
-    'rollback',
-    'str_to_b64',
-    'traceroute',
-    'transaction_status'
+    "Connection",
+    "backup_config",
+    "commit_candidate",
+    "commit_config",
+    "compare_config",
+    "config_batch",
+    "confirm_commit",
+    "get_mac_address_table",
+    "get_facts",
+    "get_arp_table",
+    "get_config",
+    "get_interfaces_ip",
+    "get_lldp_neighbors",
+    "get_lldp_neighbors_detail",
+    "get_ntp_stats",
+    "get_ntp_servers",
+    "get_route_to",
+    "has_pending_commit",
+    "is_alive",
+    "load_merge_candidate",
+    "load_replace_candidate",
+    "mac_reformat",
+    "ping",
+    "read_candidate",
+    "rollback",
+    "str_to_b64",
+    "traceroute",
+    "transaction_status",
 )
diff --git a/napalm_arubaoss/helper/base.py b/napalm_arubaoss/helper/base.py
index 609c669..b82681b 100644
--- a/napalm_arubaoss/helper/base.py
+++ b/napalm_arubaoss/helper/base.py
@@ -1,4 +1,6 @@
 """Create the Session."""
+
+
 from requests_futures.sessions import FuturesSession
 from requests.models import Response
 from concurrent.futures import as_completed
@@ -9,34 +11,28 @@
 from napalm.base.exceptions import ConnectAuthError
 
 
-logger = logging.getLogger('arubaoss.helper.base')
+logger = logging.getLogger("arubaoss.helper.base")
 
 
 class Connection:
     """Connection class."""
 
-    _apisession = FuturesSession()
-    config = {'api_url': ''}
+    config = {"api_url": ""}
 
     def __init__(self):
         """Initialize the class."""
-        self.hostname = ''
-        self.username = ''
-        self.password = ''
+        self._apisession = None
+
+        self.hostname = ""
+        self.username = ""
+        self.password = ""
         self.timeout = 10
-        self.api = 'v6'
-        self.proto = 'https'
+        self.api = "v6"
+        self.proto = "https"
 
         self.cli_output = {}
 
-    def login(
-            self,
-            hostname,
-            username='',
-            password='',
-            timeout=10,
-            optional_args=None
-    ):
+    def login(self, hostname, username="", password="", timeout=10, optional_args=None):
         """
         Login to the Rest-API.
 
@@ -47,54 +43,49 @@ def login(
         :param optional_args:
         :return:
         """
-        logger.debug('logging in')
+        logger.debug("logging in")
         self.hostname = hostname
         self.username = username
         self.password = password
         self.timeout = timeout
 
-        self.api = optional_args.get('api', 'v6')
+        self.api = optional_args.get("api", "v6")
 
         if not optional_args:
             optional_args = {}
 
-        self.proto = 'https' if optional_args.get("ssl", True) else 'http'
+        self.proto = "https" if optional_args.get("ssl", True) else "http"
 
-        self.config['api_url'] = '{}://{}/rest/{}/'.format(
-            self.proto,
-            self.hostname,
-            self.api
+        self.config["api_url"] = "{}://{}/rest/{}/".format(
+            self.proto, self.hostname, self.api
         )
 
-        url = self.config['api_url'] + 'login-sessions'
+        url = self.config["api_url"] + "login-sessions"
 
+        self._apisession = FuturesSession()
         self._apisession.verify = optional_args.get("ssl_verify", True)
-        self._apisession.headers = {'Content-Type': 'application/json'}
+        self._apisession.headers = {
+            "Content-Type": "application/json",
+            # "Connection": "close"
+        }
         self._apisession.keep_alive = optional_args.get("keepalive", True)
 
-        params = {
-            'userName': self.username,
-            'password': self.password
-        }
+        params = {"userName": self.username, "password": self.password}
 
-        rest_login = self.post(
-            url,
-            json=params,
-            timeout=self.timeout
-        )
+        rest_login = self.post(url, json=params, timeout=self.timeout)
 
         if not rest_login.status_code == 201:
             raise ConnectAuthError("Login failed")
 
         session = rest_login.json()
-        self._apisession.headers['cookie'] = session['cookie']
+        self._apisession.headers["cookie"] = session["cookie"]
 
     def logout(self):
         """Close device connection and delete sessioncookie."""
-        url = self.config['api_url'] + 'login-sessions'
+        url = self.config["api_url"] + "login-sessions"
 
         rest_logout = self.delete(url, timeout=self.timeout)
-        self._apisession.headers['cookie'] = ''
+        self._apisession.headers["cookie"] = ""
 
         if not rest_logout.status_code == 204:
             logger.debug("Logout Failed")
@@ -151,30 +142,33 @@ def delete(self, *args, **kwargs) -> Response:
         return ret.result()
 
     def cli(self, commands):
-        """Run CLI commands through the REST API."""
+        """
+        Run CLI commands through the REST API.
+
+        :param commands:
+        :return:
+        """
         self.cli_output = {}
 
-        url = self.config['api_url'] + 'cli'
+        url = self.config["api_url"] + "cli"
 
         if not isinstance(commands, list):
-            self.cli_output['error'] = 'Provide a list of commands'
+            self.cli_output["error"] = "Provide a list of commands"
             return self.cli_output
 
         async_calls = (
             self._apisession.post(
                 url=url,
-                json={'cmd': command},
+                json={"cmd": command},
                 timeout=self.timeout,
                 # bug #4 - random delay while re-using TCP connection - workaround:
                 # always close the TCP connection
-                headers={'Content-Type': 'application/json', 'Connection': 'close'},
+                headers={"Content-Type": "application/json", "Connection": "close"},
                 hooks={
-                    'response': self._callback(
-                        output=self.cli_output,
-                        command=command
-                    )
-                }
-            ) for command in commands
+                    "response": self._callback(output=self.cli_output, command=command)
+                },
+            )
+            for command in commands
         )
 
         [call.result() for call in as_completed(async_calls)]
@@ -191,26 +185,27 @@ def _callback(self, *args, **kwargs):
         :param kwargs:
         :return: callback function
         """
+
         def callback(call, *cargs, **ckwargs):
-            cli_output = kwargs.get('output')
-            passed_cmd = kwargs.get('command')
+            cli_output = kwargs.get("output")
+            passed_cmd = kwargs.get("command")
             try:
                 json_ret = call.json()
             except JSONDecodeError:
                 json_ret = {}
 
-            cmd = json_ret.get('cmd')
-            result_base64 = json_ret.get('result_base64_encoded', '')
+            cmd = json_ret.get("cmd")
+            result_base64 = json_ret.get("result_base64_encoded", "")
 
             if not cmd == passed_cmd:
-                cli_output[passed_cmd] = 'cmd not found in output'
+                cli_output[passed_cmd] = "cmd not found in output"
                 return
 
             if not result_base64:
-                cli_output[passed_cmd] = 'no result found in output'
+                cli_output[passed_cmd] = "no result found in output"
                 return
 
-            result = base64.b64decode(result_base64).decode('utf-8')
+            result = base64.b64decode(result_base64).decode("utf-8")
             cli_output[passed_cmd] = result
 
         return callback
diff --git a/napalm_arubaoss/helper/commit_config.py b/napalm_arubaoss/helper/commit_config.py
index e425385..73e3b86 100644
--- a/napalm_arubaoss/helper/commit_config.py
+++ b/napalm_arubaoss/helper/commit_config.py
@@ -2,23 +2,59 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+from napalm.base.exceptions import CommitError
+
 from napalm_arubaoss.helper.utils import backup_config, commit_candidate
 from napalm_arubaoss.helper.get_config import get_config
 from napalm_arubaoss.helper.load_replace_candidate import load_replace_candidate
+from napalm_arubaoss.helper.has_pending_commit import has_pending_commit
+
+logger = logging.getLogger("arubaoss.helper.commit_config")
+
+
+def commit_config(self, message="", revert_in=None):
+    """
+    Backups and commit the configuration, and handles commit confirm.
+
+    :param self: object from class
+    :param message: Optional - configuration session commit message
+    :type message: str
+    :param revert_in: Optional - number of seconds before the configuration
+    will be rolled back using a commit confirm mechanism.
+    :type revert_in: int|None
+    """
+    if message:
+        msg = "\"message\" support has not been added " \
+              "for this getter on this platform."
+        raise NotImplementedError(msg)
+
+    if not revert_in:
+        revert_in = 0
+
+    if not type(revert_in) == int:
+        err_msg = "Invalid \"revert_in\" value, "\
+                  "commit confirn cannot be carried out"
+        logger.error(err_msg)
+        raise TypeError(err_msg)
+
+    if has_pending_commit(self=self):
+        raise CommitError("Pending commit confirm already in process!")
 
-logger = logging.getLogger('arubaoss.helper.commit_config')
+    backup_config(self=self)
 
-connection = Connection()
+    logger.debug('Confirm rollback time is {}'.format(str(revert_in)))
+    if revert_in > 0:
+        candidate = get_config(
+            self=self,
+            retrieve='candidate'
+        )['candidate']
+        candidate = candidate[:-2]  # remove unneeded chars
 
+        candidate_confirm = (
+            f"{candidate}"
+            f"job ROLLBACK delay {str(revert_in)} "
+            "\"cfg-restore flash backup_running\"\n"
+        )
+        load_replace_candidate(self=self, config=candidate_confirm)
 
-def commit_config(confirm=0):
-    """Backups and commit the configuration, and handles commit confirm."""
-    backup_config()
-    logger.debug('Confirm rollback time is {}'.format(str(confirm)))
-    if confirm > 0:
-        candidate = get_config(retrieve='candidate')['candidate'][:-2]
-        candidate_confirm = candidate + 'job ROLLBACK delay {} \
-            "cfg-restore flash backup_running"\n'.format(str(confirm))
-        load_replace_candidate(config=candidate_confirm)
-    commit_candidate(config='REST_Payload_Backup')
+    commit_candidate(self=self, config="REST_Payload_Backup")
diff --git a/napalm_arubaoss/helper/compare_config.py b/napalm_arubaoss/helper/compare_config.py
index 9555e35..b2b3dd0 100644
--- a/napalm_arubaoss/helper/compare_config.py
+++ b/napalm_arubaoss/helper/compare_config.py
@@ -3,38 +3,41 @@
 import logging
 from napalm.base.exceptions import CommandErrorException
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.compare_config")
 
-logger = logging.getLogger('arubaoss.helper.compare_config')
 
-connection = Connection()
+def compare_config(self):
+    """
+    Compare the running config with the candidate one.
 
-
-def compare_config():
-    """Compare the running config with the candidate one."""
-    url = connection.config['api_url'] + 'system/config/cfg_restore/latest_diff'
-    check_url = url + '/status'
+    :param self: object from class
+    :return:
+    """
+    url = self.connection.config["api_url"] + "system/config/cfg_restore/latest_diff"
+    check_url = url + "/status"
     data = {
         "server_type": "ST_FLASH",
         "file_name": "REST_Payload_Backup",
-        "is_oobm": False
+        "is_oobm": False,
     }
     # trigger configuration comparison
-    diff = connection.post(url, json=data)
+    diff = self.connection.post(url, json=data)
 
     if not diff.ok:
         raise CommandErrorException("diff generation failed, raise status")
 
-    diff_output = connection.get(check_url)
+    diff_output = self.connection.get(check_url)
 
     if not diff_output.status_code == 200:
         raise CommandErrorException("diff generation failed, raise status")
 
-    if not diff_output.json()['diff_add_list'] and \
-            not diff_output.json()['diff_remove_list']:
+    if (
+        not diff_output.json()["diff_add_list"]
+        and not diff_output.json()["diff_remove_list"]
+    ):
         # return empty string to signal the candidate
         # and running configs are the same
 
-        return ''
+        return ""
     else:
         return diff_output.json()
diff --git a/napalm_arubaoss/helper/confirm_commit.py b/napalm_arubaoss/helper/confirm_commit.py
new file mode 100644
index 0000000..2862203
--- /dev/null
+++ b/napalm_arubaoss/helper/confirm_commit.py
@@ -0,0 +1,23 @@
+"""Confirm the changes requested via commit_config when `type(revert_in)=int`."""
+
+import logging
+
+from napalm_arubaoss.helper.commit_config import commit_config
+from napalm_arubaoss.helper.has_pending_commit import has_pending_commit
+from napalm_arubaoss.helper.load_merge_candidate import load_merge_candidate
+
+logger = logging.getLogger('arubaoss.helper.confirm_commit')
+
+
+def confirm_commit(self):
+    """
+    Confirm the changes requested via commit_config when `type(revert_in)=int`.
+
+    :param self: object from class
+    :return:
+    """
+    if has_pending_commit(self=self):
+        load_merge_candidate(self=self, config="no job ROLLBACK")
+        ret = commit_config(self=self)
+
+        return ret
diff --git a/napalm_arubaoss/helper/get_arp_table.py b/napalm_arubaoss/helper/get_arp_table.py
index 465715f..f86d265 100644
--- a/napalm_arubaoss/helper/get_arp_table.py
+++ b/napalm_arubaoss/helper/get_arp_table.py
@@ -3,23 +3,30 @@
 from napalm.base.helpers import textfsm_extractor
 import logging
 
-from napalm_arubaoss.helper.base import Connection
 from napalm_arubaoss.helper.utils import mac_reformat
 
-logger = logging.getLogger('arubaoss.helper.get_arp_table')
+logger = logging.getLogger("arubaoss.helper.get_arp_table")
 
-connection = Connection()
 
+def get_arp_table(self, vrf):
+    """
+    Get device's ARP table.
 
-def get_arp_table(self_obj=None, *args, **kwargs):
-    """Get device's ARP table."""
-    if not self_obj:
-        return []
-    raw_arp = connection.run_cmd("show arp")
-    arp_table = textfsm_extractor(self_obj, "show_arp", raw_arp)
+    :param self: object from class
+    :param vrf: not supported
+    :return:
+    """
+    if vrf:
+        msg = "VRF support has not been added " \
+              "for this getter on this platform."
+        raise NotImplementedError(msg)
+
+    raw_arp = self.connection.run_cmd("show arp")
+    arp_table = textfsm_extractor(self, "show_arp", raw_arp)
     for arp in arp_table:
-        arp['interface'] = arp.pop('port')
-        arp['mac'] = mac_reformat(arp['mac'])
-        arp['age'] = 'N/A'
+        arp["interface"] = arp.pop("port")
+        arp["mac"] = mac_reformat(arp["mac"])
+        arp["age"] = -1.00  # needs to be a float - -1.00 to signal "N/A"
+        arp.pop("type")  # pop because it is not present in the napalm model
 
     return arp_table
diff --git a/napalm_arubaoss/helper/get_config.py b/napalm_arubaoss/helper/get_config.py
index 969a079..e4dc113 100644
--- a/napalm_arubaoss/helper/get_config.py
+++ b/napalm_arubaoss/helper/get_config.py
@@ -2,27 +2,42 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.get_config")
 
-logger = logging.getLogger('arubaoss.helper.get_config')
 
-connection = Connection()
+def get_config(self, retrieve="all", full=False):
+    """
+    Get configuration stored on the device.
 
+    :param self: object from class
+    :param retrieve:
+    :param full:
 
-def get_config(retrieve='all'):
-    """Get configuration stored on the device."""
-    out = {'startup': '', 'candidate': '', 'running': ''}
+    :return:
+    """
+    if full:
+        msg = "\"full\" is not available " \
+              "for this getter on this platform."
+        raise NotImplementedError(msg)
+
+    out = {"startup": "", "candidate": "", "running": ""}
 
     cmd_mapping = {
-        'display saved-configuration': 'startup',
-        'show config REST_Payload_Backup': 'candidate',
-        'show running-config': 'running'
+        "display saved-configuration": "startup",
+        "show config REST_Payload_Backup": "candidate",
+        "show running-config": "running",
     }
-    cmd_mapping = {
-        key: value for key, value in cmd_mapping.items() if retrieve == value
-    } if not retrieve == 'all' else cmd_mapping
-
-    outputs = connection.cli([cmd for cmd, config in cmd_mapping.items()])
+    cmd_mapping = (
+        {key: value for key, value in cmd_mapping.items() if retrieve == value}
+        if not retrieve == "all"
+        else cmd_mapping
+    )
+
+    outputs = self.connection.cli(
+        [
+            cmd for cmd, config in cmd_mapping.items()
+        ]
+    )
 
     for okey, ovalue in outputs.items():
         out[cmd_mapping[okey]] = ovalue
diff --git a/napalm_arubaoss/helper/get_facts.py b/napalm_arubaoss/helper/get_facts.py
index 110e137..3635234 100644
--- a/napalm_arubaoss/helper/get_facts.py
+++ b/napalm_arubaoss/helper/get_facts.py
@@ -2,58 +2,91 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.get_facts")
 
-logger = logging.getLogger('arubaoss.helper.get_facts')
 
-connection = Connection()
+def get_facts(self):
+    """
+    Get general device information.
 
+    :param self: object from class
+    :return:
+    """
+    url = "{base_url}{endpoint}"
+
+    system_status_url = url.format(
+        base_url=self.connection.config["api_url"],
+        endpoint="system/status"
+    )
+    switch_status_url = url.format(
+        base_url=self.connection.config["api_url"],
+        endpoint="system/status/switch"
+    )
+    dns_url = url.format(
+        base_url=self.connection.config["api_url"],
+        endpoint="dns"
+    )
 
-def get_facts():
-    """Get general device information."""
-    system_status_url = connection.config['api_url'] + 'system/status'
-    switch_status_url = connection.config['api_url'] + 'system/status/switch'
-    dns_url = connection.config['api_url'] + 'dns'
     out = {
-        'vendor': 'HPE Aruba',
-        'interface_list': []
+        "uptime": -1,
+        "vendor": "HPE Aruba",
+        "model": "",
+        "hostname": "",
+        "fqdn": "",
+        "os_version": "",
+        "serial_number": "",
+        "interface_list": [],
+
     }
 
-    call = connection.get(system_status_url)
+    call = self.connection.get(system_status_url)
 
     # If it's a Stack, use `/system/status/global_info`
     if call.status_code == 404:
-        system_status_url = connection.config['api_url'] +\
-            'system/status/global_info'
-        call = connection.get(system_status_url)
+        system_status_url = url.format(
+            base_url=self.connection.config["api_url"],
+            endpoint="system/status/global_info"
+        )
+        call = self.connection.get(system_status_url)
+
     if call.ok:
         rest_out = call.json()
-        out['hostname'] = rest_out['name']
-        out['os_version'] = rest_out['firmware_version']
-        out['serial_number'] = rest_out.get('serial_number', '')
-        out['model'] = rest_out.get('product_model', '')
+        out["hostname"] = rest_out.get("name", "")
+        out["os_version"] = rest_out.get("firmware_version", "")
+        out["serial_number"] = rest_out.get("serial_number", "")
+        out["model"] = rest_out.get("product_model", "")
 
         # get domain name to generate the FQDN
-        call = connection.get(dns_url)
+        call = self.connection.get(dns_url)
         if call.ok:
             rest_out = call.json()
             # return "{{hostname}}." if no domain is configured
-            out['fqdn'] = out['hostname'] + "." +\
-                rest_out.get('dns_domain_names', '.')[0]
+            domain_names = rest_out.get("dns_domain_names")
+            domain = ".{}".format(domain_names[0]) if domain_names else "."
+            out["fqdn"] = "{hostname}{domain}".format(
+                hostname=out["hostname"],
+                domain=domain
+            )
 
     # Get interface list
-    call = connection.get(switch_status_url)
+    call = self.connection.get(switch_status_url)
     if call.ok:
         rest_out = call.json()
-        if rest_out.get('switch_type', 'ST_STANDALONE') == 'ST_STACKED':
-            serial_url = connection.config['api_url'] +\
-                'system/status/members/1'
-            call = connection.get(serial_url)
+        if rest_out.get("switch_type", "ST_STANDALONE") == "ST_STACKED":
+            serial_url = url.format(
+                base_url=self.connection.config["api_url"],
+                endpoint="system/status/members/1"
+            )
+            call = self.connection.get(serial_url)
+
             if call.ok:
-                out['serial_number'] = call.json().get('serial_number')
-                out['model'] = call.json().get('product_model')
-        for blade in rest_out['blades']:
-            for ports in blade['data_ports']:
-                out['interface_list'].append(ports['port_name'])
+                out["serial_number"] = call.json().get("serial_number", "")
+                out["model"] = call.json().get("product_model", "")
+
+        for blade in rest_out.get("blades", []):
+            for ports in blade.get("data_ports", []):
+                out["interface_list"].append(
+                    ports.get("port_name", "")
+                )
 
     return out
diff --git a/napalm_arubaoss/helper/get_interfaces_ip.py b/napalm_arubaoss/helper/get_interfaces_ip.py
index a802ece..94d15b6 100644
--- a/napalm_arubaoss/helper/get_interfaces_ip.py
+++ b/napalm_arubaoss/helper/get_interfaces_ip.py
@@ -3,32 +3,46 @@
 from netaddr import IPNetwork
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.get_interfaces_ip")
 
-logger = logging.getLogger('arubaoss.helper.get_interfaces_ip')
 
-connection = Connection()
+def get_interfaces_ip(self):
+    """
+    Get IP interface IP addresses.
 
+    !!! Looks like there's a bug n ArubaOS and is not returning IPv6
 
-def get_interfaces_ip():
-    """Get IP interface IP addresses."""
-    "Looks like there's a bug n ArubaOS and is not returning IPv6"
-
-    url = connection.config['api_url'] + 'ipaddresses'
+    :param self: object from class
+    :return:
+    """
+    url = self.connection.config["api_url"] + "ipaddresses"
     output = {}
-    resp = connection.get(url)
+    resp = self.connection.get(url)
     if resp.status_code == 200:
-        for address in resp.json().get('ip_address_subnet_element'):
-            iface_name = "VLAN" + str(address['vlan_id'])
+        for address in resp.json().get("ip_address_subnet_element", []):
+            vlan_id = address.get("vlan_id", "")
+            iface_name = "VLAN{vlan_id}".format(vlan_id=str(vlan_id))
+
             if iface_name not in output.keys():
                 output[iface_name] = {}
-            ip = IPNetwork("{}/{}".format(
-                address['ip_address']['octets'],
-                address['ip_mask']['octets']))
-            version = 'ipv' + str(ip.version)
-            if version not in output[iface_name].keys():
-                output[iface_name][version] = {}
-            output[iface_name][version][str(ip.ip)] = {
-                'prefix_length': ip.prefixlen}
+
+            ip_address = address.get("ip_address", {}).get("octets")
+            ip_mask = address.get("ip_mask", {}).get("octets")
+
+            if ip_address and ip_mask:
+                ip = IPNetwork(
+                    "{ip_address}/{ip_mask}".format(
+                        ip_address=ip_address,
+                        ip_mask=ip_mask
+                    )
+                )
+
+                version = "ipv{ip_version}".format(ip_version=str(ip.version))
+
+                if version not in output[iface_name].keys():
+                    output[iface_name][version] = {}
+                output[iface_name][version][str(ip.ip)] = {
+                    "prefix_length": ip.prefixlen
+                }
 
     return output
diff --git a/napalm_arubaoss/helper/get_lldp_neighbors.py b/napalm_arubaoss/helper/get_lldp_neighbors.py
index 4cabe9f..9a3f622 100644
--- a/napalm_arubaoss/helper/get_lldp_neighbors.py
+++ b/napalm_arubaoss/helper/get_lldp_neighbors.py
@@ -2,28 +2,29 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.get_lldp_neighbors")
 
-logger = logging.getLogger('arubaoss.helper.get_lldp_neighbors')
 
-connection = Connection()
+def get_lldp_neighbors(self):
+    """
+    Get a list of LLDP neighbors.
 
-
-def get_lldp_neighbors():
-    """Get a list of LLDP neighbors."""
-    url = connection.config['api_url'] + '/lldp/remote-device'
-    resp = connection.get(url)
+    :param self: object from class
+    :return:
+    """
+    url = self.connection.config["api_url"] + "lldp/remote-device"
+    resp = self.connection.get(url)
     logger.debug("API returned {}".format(resp.status_code))
 
     if resp.ok:
         neighbor_table = {}
-        for neighbor in resp.json()['lldp_remote_device_element']:
-            port = neighbor['local_port']
+        for neighbor in resp.json()["lldp_remote_device_element"]:
+            port = neighbor["local_port"]
             if not neighbor_table.get(port):
                 neighbor_table[port] = []
             remote_device = {
-                'hostname': neighbor.get('system_name'),
-                'port': neighbor.get('port_id')
+                "hostname": neighbor.get("system_name"),
+                "port": neighbor.get("port_id"),
             }
             neighbor_table[port].append(remote_device)
 
diff --git a/napalm_arubaoss/helper/get_lldp_neighbors_detail.py b/napalm_arubaoss/helper/get_lldp_neighbors_detail.py
index 1433ac7..e4b399e 100644
--- a/napalm_arubaoss/helper/get_lldp_neighbors_detail.py
+++ b/napalm_arubaoss/helper/get_lldp_neighbors_detail.py
@@ -2,39 +2,47 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.get_lldp_neighbors_detail")
 
-logger = logging.getLogger('arubaoss.helper.get_lldp_neighbors_detail')
 
-connection = Connection()
+def get_lldp_neighbors_detail(self, *args, **kwargs):
+    """
+    Get LLDP neighbor information.
 
-
-def get_lldp_neighbors_detail(*args, **kwargs):
-    """Get LLDP neighbor information."""
-    url = connection.config['api_url'] + '/lldp/remote-device'
-    resp = connection.get(url)
-    logger.debug('API returned {}'.format(resp.status_code))
+    :param self: object from class
+    :param args:
+    :param kwargs:
+    :return:
+    """
+    url = self.connection.config["api_url"] + "lldp/remote-device"
+    resp = self.connection.get(url)
+    logger.debug("API returned {}".format(resp.status_code))
 
     if resp.ok:
         neighbor_table = {}
-        for neighbor in resp.json()['lldp_remote_device_element']:
-            port = neighbor['local_port']
+        for neighbor in resp.json()["lldp_remote_device_element"]:
+            port = neighbor["local_port"]
             if not neighbor_table.get(port):
                 neighbor_table[port] = []
             remote_device = {
-                'remote_system_name': neighbor.get('system_name'),
-                'remote_chassis_id': neighbor.get('chassis_id'),
-                'remote_port': neighbor.get('port_id'),
-                'remote_port_description':
-                    neighbor.get('port_description'),
-                'remote_system_description':
-                    ''.join(neighbor.get('system_description')),
-                'remote_system_capab':
-                    [k for k, v in neighbor.get(
-                        'capabilities_supported').items() if v is True],
-                'remote_system_enable_capab':
-                    [k for k, v in neighbor.get(
-                        'capabilities_enabled').items() if v is True]
+                "parent_interface": "",
+                "remote_system_name": neighbor.get("system_name"),
+                "remote_chassis_id": neighbor.get("chassis_id"),
+                "remote_port": neighbor.get("port_id"),
+                "remote_port_description": neighbor.get("port_description"),
+                "remote_system_description": "".join(
+                    neighbor.get("system_description")
+                ),
+                "remote_system_capab": [
+                    k
+                    for k, v in neighbor.get("capabilities_supported").items()
+                    if v is True
+                ],
+                "remote_system_enable_capab": [
+                    k
+                    for k, v in neighbor.get("capabilities_enabled").items()
+                    if v is True
+                ],
             }
             neighbor_table[port].append(remote_device)
 
diff --git a/napalm_arubaoss/helper/get_mac_address_table.py b/napalm_arubaoss/helper/get_mac_address_table.py
index 99f2313..131540b 100644
--- a/napalm_arubaoss/helper/get_mac_address_table.py
+++ b/napalm_arubaoss/helper/get_mac_address_table.py
@@ -2,29 +2,31 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
 from napalm_arubaoss.helper.utils import mac_reformat
 
-logger = logging.getLogger('arubaoss.helper.get_mac_address_table')
+logger = logging.getLogger("arubaoss.helper.get_mac_address_table")
 
-connection = Connection()
 
+def get_mac_address_table(self):
+    """
+    Get the mac-address table of the device.
 
-def get_mac_address_table():
-    """Get the mac-address table of the device."""
-    url = connection.config['api_url'] + 'mac-table'
-    resp = connection.get(url)
+    :param self: object from class
+    :return:
+    """
+    url = self.connection.config["api_url"] + "mac-table"
+    resp = self.connection.get(url)
     if resp.status_code == 200:
         table = []
-        for entry in resp.json().get('mac_table_entry_element'):
+        for entry in resp.json().get("mac_table_entry_element"):
             item = {
-                'mac': mac_reformat(entry['mac_address']),
-                'interface': entry['port_id'],
-                'vlan': entry['vlan_id'],
-                'active': True,
-                # 'static': False,  # not supported
-                # 'moves': 0,  # not supported
-                # 'last_move': 0.0  # not supported
+                "mac": mac_reformat(entry["mac_address"]),
+                "interface": entry["port_id"],
+                "vlan": entry["vlan_id"],
+                "active": True,
+                "static": False,  # not supported
+                "moves": 0,  # not supported
+                "last_move": 0.0  # not supported
             }
             table.append(item)
 
diff --git a/napalm_arubaoss/helper/get_ntp_servers.py b/napalm_arubaoss/helper/get_ntp_servers.py
index 2bf8e2c..334448e 100644
--- a/napalm_arubaoss/helper/get_ntp_servers.py
+++ b/napalm_arubaoss/helper/get_ntp_servers.py
@@ -2,20 +2,33 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.get_ntp_servers")
 
-logger = logging.getLogger('arubaoss.helper.get_ntp_servers')
 
-connection = Connection()
+def get_ntp_servers(self):
+    """
+    Get NTP servers.
 
+    # TODO: add IPv6 support, currently getting 404 from the API
+
+    :param self: object from class
+    :return:
+    """
+    base_url = self.connection.config["api_url"]
+    ipv4_url = f"{base_url}config/ntp/server/ip4addr"
+    name_url = f"{base_url}config/ntp/server-name/ASCII-STR"
+
+    ipv4_resp = self.connection.get(ipv4_url)
+    name_resp = self.connection.get(name_url)
+
+    output = {}
+
+    if ipv4_resp.status_code == 200:
+        for server in ipv4_resp.json().get("ntpServerIp4addr_element"):
+            output[server["ip4addr"]["ip4addr_value"]] = {}
+
+    if name_resp.status_code == 200:
+        for server in name_resp.json().get("ntpServerNameASCIISTR_element"):
+            output[server["ASCII-STR"]["ASCII-STR_value"]] = {}
 
-def get_ntp_servers():
-    """Get NTP servers."""
-    " TO-DO: add IPv6 support, currently getting 404 from the API"
-    url = connection.config['api_url'] + 'config/ntp/server/ip4addr'
-    resp = connection.get(url)
-    if resp.status_code == 200:
-        output = {}
-        for server in resp.json().get('ntpServerIp4addr_element'):
-            output[server['ip4addr']['ip4addr_value']] = {}
         return output
diff --git a/napalm_arubaoss/helper/get_ntp_stats.py b/napalm_arubaoss/helper/get_ntp_stats.py
index 4157159..576f760 100644
--- a/napalm_arubaoss/helper/get_ntp_stats.py
+++ b/napalm_arubaoss/helper/get_ntp_stats.py
@@ -2,45 +2,77 @@
 
 import logging
 
-from napalm_arubaoss.helper.base import Connection
-from napalm_arubaoss.helper.get_ntp_servers import get_ntp_servers
+logger = logging.getLogger("arubaoss.helper.get_ntp_stats")
 
-logger = logging.getLogger('arubaoss.helper.get_ntp_stats')
 
-connection = Connection()
+def get_ntp_stats(self):
+    """
+    Get NTP peer statistics.
 
-
-def get_ntp_stats():
-    """Get NTP peer statistics."""
+    :param self: object from class
+    :return:
+    """
     out = []
-    associations = get_ntp_servers()
+    base_url = self.connection.config["api_url"]
+    ret = self.connection.get(
+        f"{base_url}monitoring/ntp/servers"
+    )
+
+    ret_json = ret.json() if hasattr(ret, "json") else {}
+
+    ntp_ips = [
+        address.get("Server address")
+        for address in ret_json.get("NTP_Server_Address_Information", [])
+    ]
+
+    for association in ntp_ips:
+        url = f"{base_url}monitoring/ntp/associations/detail/{association}"
+
+        resp = self.connection.get(url)
+        if resp.status_code == 200:
+            data = resp.json() if hasattr(resp, "json") else {}
+
+            ntp_entry = _create_ntp_entry(data)
+
+            if ntp_entry:
+                out.append(ntp_entry)
 
-    for association in associations.keys():
-        url = '{api_url}monitoring/ntp/associations/detail/{association}'.format(
-            api_url=connection.config['api_url'],
-            association=association
-        )
+    if not ntp_ips:
+        # assumes no IPs have been configured but a name
+        url = f"{base_url}monitoring/ntp/associations/detail"
+        resp = self.connection.get(url)
 
-        resp = connection.get(url)
         if resp.status_code == 200:
-            ntp_entry = {
-                'remote': resp.json()['IP Address'],
-                'referenceid': resp.json()['Reference ID'],
-                'stratum': int(resp.json()['Stratum']),
-                'type': resp.json()['Peer Mode'],
-                'when': resp.json()['Origin Time'],
-                'hostpoll': int(resp.json()['Peer Poll Intvl']),
-                'reachability': int(resp.json()['Reach']),
-                'delay': float(resp.json()['Root Delay'].split(' ')[0]),
-                'offset': float(resp.json()['Offset'].split(' ')[0]),
-                'jitter': float(resp.json()['Root Dispersion'].split(' ')[0])
-            }
-
-            if resp.json()['Status'].find("Master") == -1:
-                ntp_entry['synchronized'] = False
-            else:
-                ntp_entry['synchronized'] = True
-
-            out.append(ntp_entry)
+            data = resp.json() if hasattr(resp, "json") else {}
+
+            ntp_entry = _create_ntp_entry(data)
+
+            if ntp_entry:
+                out.append(ntp_entry)
 
     return out
+
+
+def _create_ntp_entry(data):
+    if not data:
+        return None
+
+    ntp_entry = {
+        "remote": data.get("IP Address", ""),
+        "referenceid": data.get("Reference ID", ""),
+        "stratum": int(data.get("Stratum", 0)),
+        "type": data.get("Peer Mode", ""),
+        "when": data.get("Origin Time", ""),
+        "hostpoll": int(data.get("Peer Poll Intvl", 0)),
+        "reachability": int(data.get("Reach", 0)),
+        "delay": float(data.get("Root Delay", "").split(" ")[0]),
+        "offset": float(data.get("Offset", "").split(" ")[0]),
+        "jitter": float(data.get("Root Dispersion", "").split(" ")[0]),
+    }
+
+    if data.get("Status").find("Master") == -1:
+        ntp_entry["synchronized"] = False
+    else:
+        ntp_entry["synchronized"] = True
+
+    return ntp_entry
diff --git a/napalm_arubaoss/helper/get_route_to.py b/napalm_arubaoss/helper/get_route_to.py
index 343059f..2547022 100644
--- a/napalm_arubaoss/helper/get_route_to.py
+++ b/napalm_arubaoss/helper/get_route_to.py
@@ -4,66 +4,103 @@
 from netaddr import IPNetwork
 import logging
 
-from napalm_arubaoss.helper.base import Connection
 
-logger = logging.getLogger('arubaoss.helper.get_route_to')
+logger = logging.getLogger("arubaoss.helper.get_route_to")
 
-connection = Connection()
 
-
-def get_route_to(destination='', protocol='', self_obj=None):
+def get_route_to(self, destination="", protocol=""):
     """
     Get route to destination.
 
+    :param self: object from class
     :param destination:
     :param protocol:
     :return:
     """
-    if not self_obj:
-        return {}
+    inner_dictionary = {
+        "protocol": "",
+        "current_active": True,
+        "last_active": True,
+        "age": -1,
+        "next_hop": "",
+        "outgoing_interface": "",
+        "selected_next_hop": True,
+        "preference": -1,
+        "inactive_reason": "",
+        "routing_table": "",
+        "protocol_attributes": {}
+    }
+
+    bgp_dictionary = {
+        "local_as": -1,
+        "remote_as": -1,
+        "peer_id": "",
+        "as_path": "",
+        "communities": -1,
+        "local_preference": -1,
+        "preference2": -1,
+        "metric": -1,
+        "metric2": -1
+    }
+
+    isis_dictionary = {
+        "level": -1
+    }
+
     if destination:
         ip_address = IPNetwork(destination)
 
         cmds = {
             4: {
-                'template': 'show_ip_route',
-                'command': 'show ip route {} {}'.format(ip_address.ip, protocol)
+                "template": "show_ip_route",
+                "command": "show ip route {} {}".format(ip_address.ip, protocol),
             },
             6: {
-                'template': 'show_ipv6_route',
-                'command': 'show ipv6 route {} {}'.format(ip_address.ip, protocol)
-            }
+                "template": "show_ipv6_route",
+                "command": "show ipv6 route {} {}".format(ip_address.ip, protocol),
+            },
         }
         cmd_dict = cmds[ip_address.version]
-        ret = connection.run_cmd(cmd_dict['command'])
+        ret = self.connection.run_cmd(cmd_dict["command"])
 
-        route_table = textfsm_extractor(self_obj, cmd_dict['template'], ret)
+        route_table = textfsm_extractor(self, cmd_dict["template"], ret)
     else:
         cmds = [
             {
-                'template': 'show_ip_route',
-                'command': 'show ip route {} {}'.format(destination, protocol)
+                "template": "show_ip_route",
+                "command": "show ip route {} {}".format(destination, protocol),
             },
             {
-                'template': 'show_ipv6_route',
-                'command': 'show ipv6 route {} {}'.format(destination, protocol)
-            }
+                "template": "show_ipv6_route",
+                "command": "show ipv6 route {} {}".format(destination, protocol),
+            },
         ]
 
-        ret = connection.cli([cmd['command'] for cmd in cmds])
+        ret = self.connection.cli([cmd["command"] for cmd in cmds])
 
         route_table = []
         for cmd in cmds:
-            route_table.extend(textfsm_extractor(self_obj, cmd['template'], ret[cmd['command']]))
+            route_table.extend(
+                textfsm_extractor(self, cmd["template"], ret[cmd["command"]])
+            )
 
     out = {}
     for route in route_table:
-        if not out.get(route['destination']):
-            out[route['destination']] = []
-        new_path = {
-            'protocol': route['type'],
-            'preference': int(route['distance']),
-            'next_hop': route['gateway']
-        }
-        out[route['destination']].append(new_path)
+        if not out.get(route["destination"]):
+            out[route["destination"]] = []
+
+        new_path = inner_dictionary.copy()
+        new_path["protocol"] = route["type"]
+        new_path["preference"] = int(route["distance"])
+        new_path["next_hop"] = route["gateway"]
+
+        # doesn't exist, but will be handled to be compliant with the tests
+        if route["type"] == "bgp":
+            new_path["protocol_attributes"] = bgp_dictionary.copy()
+
+        # doesn't exist, but will be handled to be compliant with the tests
+        if route["type"] == "isis":
+            new_path["protocol_attributes"] = isis_dictionary.copy()
+
+        out[route["destination"]].append(new_path)
     return out
diff --git a/napalm_arubaoss/helper/has_pending_commit.py b/napalm_arubaoss/helper/has_pending_commit.py
new file mode 100644
index 0000000..e1f1b66
--- /dev/null
+++ b/napalm_arubaoss/helper/has_pending_commit.py
@@ -0,0 +1,24 @@
+"""Confirm the changes requested via commit_config when `type(revert_in)=int`."""
+
+import logging
+
+from napalm_arubaoss.helper.get_config import get_config
+
+
+logger = logging.getLogger('arubaoss.helper.has_pending_commit')
+
+
+def has_pending_commit(self):
+    """
+    Boolean indicates if a commit_config that needs confirmed is in process.
+
+    :param self: object from class
+    :return Boolean
+    """
+    running = get_config(self=self, retrieve='running')['running'][:-2]
+
+    for line in running.split("\n"):
+        if line.find("ROLLBACK") > 0:
+            return True
+
+    return False
diff --git a/napalm_arubaoss/helper/is_alive.py b/napalm_arubaoss/helper/is_alive.py
index 33edb3e..ee23a40 100644
--- a/napalm_arubaoss/helper/is_alive.py
+++ b/napalm_arubaoss/helper/is_alive.py
@@ -1,23 +1,20 @@
 """Check if device connection is alive."""
 
-from napalm_arubaoss.helper.base import Connection
 from napalm.base.exceptions import ConnectionClosedException
 import logging
 
-logger = logging.getLogger('arubaoss.helper.is_alive')
+logger = logging.getLogger("arubaoss.helper.is_alive")
 
-connection = Connection()
 
+def is_alive(self):
+    """
+    Check if device connection is alive.
 
-def is_alive():
-    """Check if device connection is alive."""
-    """check if session cookie is still valid
-    Returns:
-        True - Session cookie is still valid
-        None - There's an error
+    :param self: object from class
+    :return:
     """
-    url = connection.config['api_url'] + 'system'
-    endpoint = connection.get(url)
+    url = self.connection.config["api_url"] + "system"
+    endpoint = self.connection.get(url)
     if endpoint.status_code == 200:
         "Session cookie is still valid"
         return {"is_alive": True}
diff --git a/napalm_arubaoss/helper/load_merge_candidate.py b/napalm_arubaoss/helper/load_merge_candidate.py
index 2ecdfc1..846d55f 100644
--- a/napalm_arubaoss/helper/load_merge_candidate.py
+++ b/napalm_arubaoss/helper/load_merge_candidate.py
@@ -3,32 +3,34 @@
 from napalm.base.exceptions import MergeConfigException
 import logging
 
-from napalm_arubaoss.helper.base import Connection
 from napalm_arubaoss.helper.utils import read_candidate, config_batch, backup_config
 
-logger = logging.getLogger('arubaoss.helper.load_merge_candidate')
+logger = logging.getLogger("arubaoss.helper.load_merge_candidate")
 
-connection = Connection()
 
-
-def load_merge_candidate(filename=None, config=None):
-    """Merge candidate configuration with the running one."""
+def load_merge_candidate(self, filename=None, config=None):
     """
+    Merge candidate configuration with the running one.
+
     Imperative config change:
      Merge new config with existing one. There's no config validation
      nor atomic commit!. Only configuration commands are supported,
      "configure terminal" is not required. Use with caution.
 
+    :param self: object from class
+    :param filename:
+    :param config:
+    :return:
     """
     if filename:
-        config = read_candidate(filename)
+        config = read_candidate(candidate=filename)
 
     if config is not None:
         if isinstance(config, str):
-            config = config.split('\n')
-        if not config_batch(cmd_list=config):
+            config = config.split("\n")
+        if not config_batch(self=self, cmd_list=config):
             raise MergeConfigException("Configuration merge failed")
 
     # mimic load_replace_candidate behaviour, by making sure candidate
     # config exactly matches our merged configuration
-    backup_config(destination='REST_Payload_Backup')
+    backup_config(self=self, destination="REST_Payload_Backup")
diff --git a/napalm_arubaoss/helper/load_replace_candidate.py b/napalm_arubaoss/helper/load_replace_candidate.py
index 610c315..188e57a 100644
--- a/napalm_arubaoss/helper/load_replace_candidate.py
+++ b/napalm_arubaoss/helper/load_replace_candidate.py
@@ -1,33 +1,39 @@
 """Replace running config with the candidate."""
 
-from napalm_arubaoss.helper.base import Connection
 from napalm.base.exceptions import ReplaceConfigException
 import logging
 
 from napalm_arubaoss.helper.utils import str_to_b64, read_candidate
 
-logger = logging.getLogger('arubaoss.helper.load_replace_candidate')
+logger = logging.getLogger("arubaoss.helper.load_replace_candidate")
 
-connection = Connection()
 
+def load_replace_candidate(self, filename=None, config=None):
+    """
+    Replace running config with the candidate.
 
-def load_replace_candidate(filename=None, config=None):
-    """Replace running config with the candidate."""
-    """ Implentation of napalm module load_replace_candidate()
+    Implentation of napalm module load_replace_candidate()
     ArubaOS-Switch supports payload_type options:
         - "RPT_PATCH_FILE" -> not implemented
         - "RPT_BACKUP_FILE" -> Implemented
 
     Note: the maximum content_length = 16072,
     "HTTP/1.1 413 Request Entity Too Large" is returned above that!!!
+
+    :param self: object from class
+    :param filename:
+    :param config:
+    :return:
     """
-    url = connection.config['api_url'] + 'system/config/payload'
+    url = self.connection.config["api_url"] + "system/config/payload"
     payload = {"payload_type": "RPT_BACKUP_FILE"}
     if filename is not None:
-        config = read_candidate(filename)
+        config = read_candidate(candidate=filename)
 
     if config is not None:
-        payload['config_base64_encoded'] = str_to_b64(config)
-        load = connection.post(url, json=payload)
+        payload["config_base64_encoded"] = str_to_b64(config)
+        load = self.connection.post(url, json=payload)
         if load.status_code != 200:
-            raise ReplaceConfigException("Load configuration failed")
+            raise ReplaceConfigException(
+                f"Load configuration failed - Reason: {load.text}"
+            )
diff --git a/napalm_arubaoss/helper/ping.py b/napalm_arubaoss/helper/ping.py
index 9a07758..62a4c40 100644
--- a/napalm_arubaoss/helper/ping.py
+++ b/napalm_arubaoss/helper/ping.py
@@ -1,50 +1,49 @@
 """Execute ping on the device and returns a dictionary with the result."""
 
-from napalm_arubaoss.helper.base import Connection
 import logging
 
-logger = logging.getLogger('arubaoss.helper.ping')
+logger = logging.getLogger("arubaoss.helper.ping")
 
-connection = Connection()
 
-
-def ping(destination, timeout=2):
+def ping(self, destination, timeout=2):
     """
     Execute ping on the device and returns a dictionary with the result.
 
+    :param self: object from class
     :param destination: needed argument
     :param timeout: not implemented as not available from device
     :return: returns a dictionary containing the hops and probes
     """
-    url = connection.config['api_url'] + 'ping'
+    url = self.connection.config["api_url"] + "ping"
     data = {
-        'destination': {
-            'ip_address': {
-                'version': 'IAV_IP_V4',
-                "octets": destination
-            }
-        },
-        "timeout_in_seconds": timeout
+        "destination": {"ip_address": {"version": "IAV_IP_V4", "octets": destination}},
+        "timeout_in_seconds": timeout,
     }
-    data_post = connection.post(url, json=data)
+    data_post = self.connection.post(url, json=data)
 
     if not data_post.status_code == 200:
-        return {'error': 'unknown host {}'.format(destination)}
+        return {"error": "unknown host {}".format(destination)}
 
-    if 'PR_OK' in data_post.json().get('result'):
+    return_post = data_post.json() if hasattr(data_post, "json") else {}
+    result_post = return_post.get("result", "")
+    rtt = return_post.get("rtt_in_milliseconds", 0)
+    rtt_float = float(rtt)
+
+    if "PR_OK" in result_post:
         result = {
-            'success': {
-                'probes_sent': 1,
-                'packet_loss': 0,
-                'rtt_min': data_post.json().get('rtt_in_milliseconds'),
-                'rtt_max': data_post.json().get('rtt_in_milliseconds'),
-                'rtt_avg': data_post.json().get('rtt_in_milliseconds'),
-                'rtt_stddev': 0,
-                'results': {
-                    'ip_address': destination,
-                    'rtt': data_post.json().get('rtt_in_milliseconds')
-                }
+            "success": {
+                "probes_sent": 1,
+                "packet_loss": 0,
+                "rtt_min": rtt_float,
+                "rtt_max": rtt_float,
+                "rtt_avg": rtt_float,
+                "rtt_stddev": 0.0,
+                "results": [
+                    {
+                        "ip_address": destination,
+                        "rtt": rtt_float
+                    }
+                ]
             }
         }
-
         return result
diff --git a/napalm_arubaoss/helper/rollback.py b/napalm_arubaoss/helper/rollback.py
index a63305b..fbd6c15 100644
--- a/napalm_arubaoss/helper/rollback.py
+++ b/napalm_arubaoss/helper/rollback.py
@@ -5,18 +5,20 @@
 from napalm_arubaoss.helper.utils import commit_candidate
 from napalm_arubaoss.helper.compare_config import compare_config
 
-logger = logging.getLogger('arubaoss.helper.rollback')
+logger = logging.getLogger("arubaoss.helper.rollback")
 
 
-def rollback():
-    """Rollback configuration."""
-    diff = compare_config()
+def rollback(self):
+    """
+    Rollback configuration.
+
+    :param self: object from class
+    :return:
+    """
+    diff = compare_config(self=self)
     if diff and isinstance(diff, dict):
-        if not (
-                len(diff.get('diff_add_list')) and
-                len(diff.get('diff_remove_list'))
-        ):
-            commit_candidate(config='backup_running')
+        if not (len(diff.get("diff_add_list")) and len(diff.get("diff_remove_list"))):
+            commit_candidate(self=self, config="backup_running")
 
             return True
         else:
diff --git a/napalm_arubaoss/helper/traceroute.py b/napalm_arubaoss/helper/traceroute.py
index f8a5d9e..e72fbd5 100644
--- a/napalm_arubaoss/helper/traceroute.py
+++ b/napalm_arubaoss/helper/traceroute.py
@@ -3,55 +3,53 @@
 import socket
 import logging
 
-from napalm_arubaoss.helper.base import Connection
+logger = logging.getLogger("arubaoss.helper.traceroute")
 
-logger = logging.getLogger('arubaoss.helper.traceroute')
 
-connection = Connection()
-
-
-def traceroute(
-        destination
-):
+def traceroute(self, destination):
     """
     Execute traceroute on the device and returns a dictionary with the result.
 
+    :param self: object from class
     :param destination: needed argument
-    :param source: not implemented as not available from device
-    :param ttl: not implemented as not available from device
-    :param timeout: not implemented as not available from device
-    :param vrf: not implemented as not available from device
     :return: returns a dictionary containing the hops and probes
     """
-    url = connection.config['api_url'] + 'trace-route'
-    data = {"destination": {"ip_address": {"version": "IAV_IP_V4", "octets": destination}}}
-    data_post = connection.post(url, json=data)
+    url = self.connection.config["api_url"] + "trace-route"
+    data = {
+        "destination": {"ip_address": {"version": "IAV_IP_V4", "octets": destination}}
+    }
+    data_post = self.connection.post(url, json=data)
 
     if not data_post.status_code == 200:
-        return {'error': 'unknown host {}'.format(destination)}
+        return {"error": "unknown host {}".format(destination)}
 
-    ret = {'success': {}}
-    ttl_data = data_post.json().get('ttl_data', [])
+    ret = {"success": {}}
+    ttl_data = data_post.json().get("ttl_data", [])
 
     for hop_count in range(len(ttl_data)):
-        ret['success'][hop_count + 1] = {'probes': {}}
-        ttl_probe_data = ttl_data[hop_count].get('ttl_probe_data', [])
+        ret["success"][hop_count + 1] = {"probes": {}}
+        ttl_probe_data = ttl_data[hop_count].get("ttl_probe_data", [])
         for probe_count in range(len(ttl_probe_data)):
             try:
                 hostname, _, _ = socket.gethostbyaddr(
-                    ttl_probe_data[probe_count].get('gateway', {}).get('ip_address', {}).get('octets', '')
+                    ttl_probe_data[probe_count]
+                    .get("gateway", {})
+                    .get("ip_address", {})
+                    .get("octets", "")
                 )
             except socket.herror:  # fetch if nothing can be found
-                hostname = ''
+                hostname = ""
 
             probe = {
-                'rtt': float(ttl_probe_data[probe_count]['probe_time_in_millis']),
-                'ip_address':
-                    ttl_probe_data[probe_count].get('gateway', {}).get('ip_address', {}).get('octets', ''),
-                'hostname': hostname
+                "rtt": float(ttl_probe_data[probe_count]["probe_time_in_millis"]),
+                "ip_address": ttl_probe_data[probe_count]
+                .get("gateway", {})
+                .get("ip_address", {})
+                .get("octets", ""),
+                "host_name": hostname,
             }
 
-            ret['success'][hop_count + 1]['probes'][probe_count + 1] = probe
+            ret["success"][hop_count + 1]["probes"][probe_count + 1] = probe
             del probe
 
     return ret
diff --git a/napalm_arubaoss/helper/utils.py b/napalm_arubaoss/helper/utils.py
index 0528b15..dc3d2f8 100644
--- a/napalm_arubaoss/helper/utils.py
+++ b/napalm_arubaoss/helper/utils.py
@@ -6,11 +6,7 @@
 from itertools import zip_longest
 from napalm.base.exceptions import CommandTimeoutException
 
-from napalm_arubaoss.helper.base import Connection
-
-logger = logging.getLogger('arubaoss.helper.utils')
-
-connection = Connection()
+logger = logging.getLogger("arubaoss.helper.utils")
 
 
 def read_candidate(candidate):
@@ -21,71 +17,83 @@ def read_candidate(candidate):
     :return:
     """
     with open(candidate) as candidate_config:
-        return ''.join(candidate_config.readlines())
+        return "".join(candidate_config.readlines())
 
 
 def str_to_b64(spayload):
-    """Convert from str to b64 for aoss API."""
+    """
+    Convert from str to b64 for aoss API.
+
+    :param spayload:
+    :return:
+    """
     payload_b64 = base64.b64encode(spayload.encode())
 
-    return payload_b64.decode('utf-8')
+    return payload_b64.decode("utf-8")
 
 
-def config_batch(cmd_list):
+def config_batch(self, cmd_list):
     """
     Load a batch of configuration commands into the running-config.
 
+    :param self: object from class
     :param cmd_list:
     :return:
     """
-    url = connection.config['api_url'] + 'cli_batch'
-    data = {
-        'cli_batch_base64_encoded': str_to_b64('\n'.join(cmd_list))
-    }
-    batch_run = connection.post(url, json=data)
+    url = self.connection.config["api_url"] + "cli_batch"
+    data = {"cli_batch_base64_encoded": str_to_b64("\n".join(cmd_list))}
+    batch_run = self.connection.post(url, json=data)
 
     if not batch_run.status_code == 202:
         logger.debug("Failed to paste commands")
 
         return False
 
-    check_status = connection.get(url + "/status")
+    check_status = self.connection.get(url + "/status")
     if check_status.status_code == 200:
-        for cmd_status in check_status.json()['cmd_exec_logs']:
-            if cmd_status['status'] != "CCS_SUCCESS":
-                logger.debug("command failed to execute with error {}".format(cmd_status['result']))
+        for cmd_status in check_status.json()["cmd_exec_logs"]:
+            if not cmd_status["status"] == "CCS_SUCCESS":
+                logger.warning(
+                    "command failed to execute with error {}".format(
+                        cmd_status["result"]
+                    )
+                )
                 return False
-            else:
-                return True
         return True
 
 
-def backup_config(config='running', destination='backup'):
-    """Backup config."""
-    """Supported configs
+def backup_config(self, config="running", destination="backup"):
+    """
+    Backup config.
+
+    Supported configs
     API:
         - "CT_RUNNING_CONFIG",
         - "CT_STARTUP_CONFIG"
+
+    :param self: object from class
+    :param config:
+    :param destination:
+    :return:
     """
-    url = connection.config['api_url'] + 'system/config/cfg_backup_files'
+    url = self.connection.config["api_url"] + "system/config/cfg_backup_files"
     payload = {}
     dest_map = {
-        'backup': 'backup_{}'.format(config),
-        'REST_Payload_Backup': 'REST_Payload_Backup'
-
+        "backup": "backup_{}".format(config),
+        "REST_Payload_Backup": "REST_Payload_Backup",
     }
     conf_map = {
-        'running': 'CT_RUNNING_CONFIG',
-        'startup': 'CT_STARTUP_CONFIG'
+        "running": "CT_RUNNING_CONFIG",
+        "startup": "CT_STARTUP_CONFIG"
     }
-    payload['file_name'] = dest_map.get(destination)
-    payload['config_type'] = conf_map.get(config, False)
+    payload["file_name"] = dest_map.get(destination)
+    payload["config_type"] = conf_map.get(config, False)
 
-    if not payload['config_type']:
+    if not payload["config_type"]:
         "unsupported argument; raise error"
         return False
 
-    cmd_post = connection.post(url, json=payload)
+    cmd_post = self.connection.post(url, json=payload)
     if not cmd_post.ok:
         "raise error"
         pass
@@ -93,40 +101,43 @@ def backup_config(config='running', destination='backup'):
         return cmd_post.json()
 
 
-def transaction_status(url):
+def transaction_status(self, url):
     """
     Wait for the requested transaction to finish within the specified timeout.
 
+    :param self: object from class
     :param url:
     :return:
     """
-    status = 'CRS_IN_PROGRESS'
+    status = "CRS_IN_PROGRESS"
     elapsed = 0
-    while status == 'CRS_IN_PROGRESS' and elapsed < connection.timeout:
-        call = connection.get(url)
+    while status == "CRS_IN_PROGRESS" and elapsed < self.connection.timeout:
+        call = self.connection.get(url)
         if call.status_code in range(200, 300):
             status = call.json()
             return status
         elapsed += 1
         sleep(1)
-    if elapsed == (int(connection.timeout) - 1) and status == 'CRS_IN_PROGRESS':
+    if elapsed == (int(self.connection.timeout) - 1) and status == "CRS_IN_PROGRESS":
         raise CommandTimeoutException("Transaction timed out")
 
 
-def commit_candidate(config):
-    """Commit the candidate configuration."""
-    url = connection.config['api_url'] + 'system/config/cfg_restore'
-    data = {
-            "server_type": "ST_FLASH",
-            "file_name": config,
-            "is_oobm": False
-            }
-    cmd_post = connection.post(url, json=data)
+def commit_candidate(self, config):
+    """
+    Commit the candidate configuration.
+
+    :param self: object from class
+    :param config:
+    :return:
+    """
+    url = self.connection.config["api_url"] + "system/config/cfg_restore"
+    data = {"server_type": "ST_FLASH", "file_name": config, "is_oobm": False}
+    cmd_post = self.connection.post(url, json=data)
 
-    if not cmd_post.json()['failure_reason']:
-        check_url = url + '/status'
+    if not cmd_post.json()["failure_reason"]:
+        check_url = url + "/status"
 
-        return transaction_status(check_url)
+        return transaction_status(self=self, url=check_url)
 
 
 def mac_reformat(mac):
@@ -138,4 +149,4 @@ def mac_reformat(mac):
     """
     t = iter(mac.replace("-", ""))
 
-    return ':'.join(a+b for a, b in zip_longest(t, t, fillvalue=""))
+    return ":".join(a + b for a, b in zip_longest(t, t, fillvalue=""))
diff --git a/requirements.txt b/requirements.txt
index 4b532b2..55dd39f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-napalm>=2.0.0
+napalm>=3.3.0
 netaddr
 requests
 requests-futures
diff --git a/setup.cfg b/setup.cfg
index a42a367..23a7705 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -11,9 +11,11 @@ addopts =
     --cov=napalm_arubaoss
     --cov-report term-missing
     -vs
-    --pylama
+#     --pylama
 json_report = report.json
 jsonapi = true
+testpaths =
+    test
 
 [coverage:run]
 source = napalm_arubaoss
diff --git a/setup.py b/setup.py
index afe915c..44bb06c 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@
 
 setup(
     name="napalm-arubaos-switch",
-    version="0.1.1",
+    version="0.2.0",
     packages=find_packages(),
     author="Guillermo Cotone",
     author_email="15230109+gcotone@users.noreply.github.com",
@@ -26,6 +26,8 @@
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
         "Operating System :: POSIX :: Linux",
     ],
     url="https://github.com/napalm-automation-community/napalm-arubaos-switch/",


Test patch:
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/test/unit/conftest.py b/test/unit/conftest.py
new file mode 100644
index 0000000..edfe782
--- /dev/null
+++ b/test/unit/conftest.py
@@ -0,0 +1,130 @@
+"""Test fixtures."""
+
+from re import search
+
+import pytest
+from napalm.base.test import conftest as parent_conftest
+
+from napalm.base.test.double import BaseTestDouble
+
+from napalm_arubaoss import ArubaOS
+
+
+@pytest.fixture(scope='class')
+def set_device_parameters(request):
+    """Set up the class."""
+    def fin():
+        request.cls.device.close()
+    request.addfinalizer(fin)
+
+    request.cls.driver = ArubaOS.ArubaOSS
+    request.cls.patched_driver = PatchedArubaOSDriver
+    request.cls.vendor = 'napalm_arubaoss'
+    parent_conftest.set_device_parameters(request)
+
+
+def pytest_generate_tests(metafunc):
+    """Generate test cases dynamically."""
+    parent_conftest.pytest_generate_tests(metafunc, __file__)
+
+
+class PatchedArubaOSDriver(ArubaOS.ArubaOSS):
+    """Patched ArubaOS Driver."""
+
+    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
+        super().__init__(hostname, username, password, timeout, optional_args)
+
+        self.patched_attrs = ['connection']
+        self.connection = FakeArubaOSDevice()
+        self.platform = "arubaos"
+
+    def disconnect(self):
+        pass
+
+    def is_alive(self):
+        return {
+            'is_alive': True  # In testing everything works..
+        }
+
+    def open(self):
+        pass
+
+
+class FakeArubaOSDevice(BaseTestDouble):
+    """ArubaOS device test double."""
+    def __init__(self):
+        super().__init__()
+        self.config = {'api_url': ''}
+
+    def get(self, url: str):
+        full_path = self.find_file('facts.json')
+        facts = self.read_json_file(full_path)
+
+        facts = facts.get(url)
+        resp = Response(
+            facts.get('data', {}),
+            status=facts.get('status', 204),
+            ok=facts.get('ok', True)
+        )
+        return resp
+
+    def post(self, url: str, json=None):
+        full_path = self.find_file('facts.json')
+        facts = self.read_json_file(full_path)
+
+        facts = facts.get(url)
+        resp = Response(
+            facts.get('data', {}),
+            status=facts.get('status', 204),
+            ok=facts.get('ok', True)
+        )
+        return resp
+
+    def cli(self, commands):
+        full_path = self.find_file('cli_mapping.json')
+        cli_mapping = self.read_json_file(full_path)
+
+        fake_return = {}
+
+        for cmd in commands:
+            cli_match = cli_mapping.get(cmd)
+            if not cli_match:
+                return
+            fake_return[cmd] = cli_match
+
+        return fake_return
+
+    def run_cmd(self, cmd):
+        return self.cli([cmd])[cmd]
+
+    def show(self, command, raw_text=False):
+        """Fake show."""
+        filename = '{}.json'.format(command.replace(' ', '_'))
+        full_path = self.find_file(filename)
+
+        if raw_text:
+            result = self.read_txt_file(full_path)
+        else:
+            result = self.read_json_file(full_path)
+
+        return result
+
+    def login(self):
+        pass
+
+    def logout(self):
+        pass
+
+    def config_list(self, command):
+        """Fake config_list."""
+        pass
+
+
+class Response:
+    def __init__(self, data, status=204, ok=True):
+        self.status_code = status
+        self.ok = ok
+        self.data = data
+
+    def json(self):
+        return self.data
diff --git a/test/unit/mocked_data/test_get_arp_table/normal/cli_mapping.json b/test/unit/mocked_data/test_get_arp_table/normal/cli_mapping.json
new file mode 100644
index 0000000..553bcac
--- /dev/null
+++ b/test/unit/mocked_data/test_get_arp_table/normal/cli_mapping.json
@@ -0,0 +1,3 @@
+{
+  "show arp": "\n IP ARP table\n\n  IP Address       MAC Address       Type    Port\n  ---------------  ----------------- ------- ----\n  10.0.4.55        1a2b3c-4d5e6f     dynamic Trk1\n  10.0.65.1       abcdef-123456     dynamic 1/15\n  10.2.3.2       123456-abcdef     dynamic 1/3 \n"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_arp_table/normal/expected_result.json b/test/unit/mocked_data/test_get_arp_table/normal/expected_result.json
new file mode 100644
index 0000000..218006f
--- /dev/null
+++ b/test/unit/mocked_data/test_get_arp_table/normal/expected_result.json
@@ -0,0 +1,20 @@
+[
+  {
+    "interface": "Trk1",
+    "mac": "1a:2b:3c:4d:5e:6f",
+    "ip": "10.0.4.55",
+    "age": -1.00
+  },
+  {
+    "interface": "1/15",
+    "mac": "ab:cd:ef:12:34:56",
+    "ip": "10.0.65.1",
+    "age": -1.00
+  },
+  {
+    "interface": "1/3",
+    "mac": "12:34:56:ab:cd:ef",
+    "ip": "10.2.3.2",
+    "age": -1.00
+  }
+]
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_arp_table/stack/cli_mapping.json b/test/unit/mocked_data/test_get_arp_table/stack/cli_mapping.json
new file mode 100644
index 0000000..553bcac
--- /dev/null
+++ b/test/unit/mocked_data/test_get_arp_table/stack/cli_mapping.json
@@ -0,0 +1,3 @@
+{
+  "show arp": "\n IP ARP table\n\n  IP Address       MAC Address       Type    Port\n  ---------------  ----------------- ------- ----\n  10.0.4.55        1a2b3c-4d5e6f     dynamic Trk1\n  10.0.65.1       abcdef-123456     dynamic 1/15\n  10.2.3.2       123456-abcdef     dynamic 1/3 \n"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_arp_table/stack/expected_result.json b/test/unit/mocked_data/test_get_arp_table/stack/expected_result.json
new file mode 100644
index 0000000..218006f
--- /dev/null
+++ b/test/unit/mocked_data/test_get_arp_table/stack/expected_result.json
@@ -0,0 +1,20 @@
+[
+  {
+    "interface": "Trk1",
+    "mac": "1a:2b:3c:4d:5e:6f",
+    "ip": "10.0.4.55",
+    "age": -1.00
+  },
+  {
+    "interface": "1/15",
+    "mac": "ab:cd:ef:12:34:56",
+    "ip": "10.0.65.1",
+    "age": -1.00
+  },
+  {
+    "interface": "1/3",
+    "mac": "12:34:56:ab:cd:ef",
+    "ip": "10.2.3.2",
+    "age": -1.00
+  }
+]
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config/normal/cli_mapping.json b/test/unit/mocked_data/test_get_config/normal/cli_mapping.json
new file mode 100644
index 0000000..2dccc53
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config/normal/cli_mapping.json
@@ -0,0 +1,5 @@
+{
+  "display saved-configuration": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show config REST_Payload_Backup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show running-config": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config/normal/expected_result.json b/test/unit/mocked_data/test_get_config/normal/expected_result.json
new file mode 100644
index 0000000..b92be02
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config/normal/expected_result.json
@@ -0,0 +1,5 @@
+{
+  "startup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "candidate": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "running": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config/stack/cli_mapping.json b/test/unit/mocked_data/test_get_config/stack/cli_mapping.json
new file mode 100644
index 0000000..2dccc53
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config/stack/cli_mapping.json
@@ -0,0 +1,5 @@
+{
+  "display saved-configuration": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show config REST_Payload_Backup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show running-config": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config/stack/expected_result.json b/test/unit/mocked_data/test_get_config/stack/expected_result.json
new file mode 100644
index 0000000..b92be02
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config/stack/expected_result.json
@@ -0,0 +1,5 @@
+{
+  "startup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "candidate": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "running": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_filtered/normal/cli_mapping.json b/test/unit/mocked_data/test_get_config_filtered/normal/cli_mapping.json
new file mode 100644
index 0000000..2dccc53
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_filtered/normal/cli_mapping.json
@@ -0,0 +1,5 @@
+{
+  "display saved-configuration": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show config REST_Payload_Backup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show running-config": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_filtered/normal/expected_result.json b/test/unit/mocked_data/test_get_config_filtered/normal/expected_result.json
new file mode 100644
index 0000000..8dc7869
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_filtered/normal/expected_result.json
@@ -0,0 +1,5 @@
+{
+  "startup": "",
+  "candidate": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "running": ""
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_filtered/stack/cli_mapping.json b/test/unit/mocked_data/test_get_config_filtered/stack/cli_mapping.json
new file mode 100644
index 0000000..2dccc53
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_filtered/stack/cli_mapping.json
@@ -0,0 +1,5 @@
+{
+  "display saved-configuration": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show config REST_Payload_Backup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show running-config": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_filtered/stack/expected_result.json b/test/unit/mocked_data/test_get_config_filtered/stack/expected_result.json
new file mode 100644
index 0000000..8dc7869
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_filtered/stack/expected_result.json
@@ -0,0 +1,5 @@
+{
+  "startup": "",
+  "candidate": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "running": ""
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_sanitized/normal/cli_mapping.json b/test/unit/mocked_data/test_get_config_sanitized/normal/cli_mapping.json
new file mode 100644
index 0000000..2dccc53
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_sanitized/normal/cli_mapping.json
@@ -0,0 +1,5 @@
+{
+  "display saved-configuration": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show config REST_Payload_Backup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show running-config": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_sanitized/normal/expected_result.json b/test/unit/mocked_data/test_get_config_sanitized/normal/expected_result.json
new file mode 100644
index 0000000..b92be02
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_sanitized/normal/expected_result.json
@@ -0,0 +1,5 @@
+{
+  "startup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "candidate": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "running": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_sanitized/stack/cli_mapping.json b/test/unit/mocked_data/test_get_config_sanitized/stack/cli_mapping.json
new file mode 100644
index 0000000..2dccc53
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_sanitized/stack/cli_mapping.json
@@ -0,0 +1,5 @@
+{
+  "display saved-configuration": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show config REST_Payload_Backup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "show running-config": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_config_sanitized/stack/expected_result.json b/test/unit/mocked_data/test_get_config_sanitized/stack/expected_result.json
new file mode 100644
index 0000000..b92be02
--- /dev/null
+++ b/test/unit/mocked_data/test_get_config_sanitized/stack/expected_result.json
@@ -0,0 +1,5 @@
+{
+  "startup": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "candidate": "; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000",
+  "running": "\nRunning configuration:\n\n; hpStack_WC Configuration Editor; Created on release #WC.16.10.0009\n; Ver #14:67.6f.f8.1d.9b.3f.bf.bb.ef.7c.59.fc.6b.fb.9f.fc.ff.ff.37.ef:44\n\nstacking\n   member 1 type \"JL322A\" mac-address 000000-000000\n   exit\nhostname \"Aruba-Stack-2930M\"\nrest-interface session-idle-timeout 120\nweb-management ssl\nip default-gateway 172.16.6.1\nip dns domain-name \"arubaos.napalm\"\nip dns server-address priority 1 8.8.8.8\nip dns server-address priority 2 1.1.1.1\ninterface 1/10\n   name \"test\"\n   exit\ninterface 1/12\n   name \"blubdf\"\n   exit\ninterface 1/48\n   name \"test\"\n   exit\nsnmp-server community \"public\" unrestricted\noobm\n   ip address 172.16.7.3 255.255.254.0\n   ip default-gateway 172.16.6.1\n   ipv6 enable\n   ipv6 address dhcp full\n   member 1\n      ip address dhcp-bootp\n      exit\n   exit\nvlan 1\n   name \"DEFAULT_VLAN\"\n   untagged 1/1-1/48\n   ip address 172.16.7.3 255.255.254.0\n   ipv6 enable\n   ipv6 address dhcp full\n   exit\npassword password\n\n\u0000"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_facts/normal/expected_result.json b/test/unit/mocked_data/test_get_facts/normal/expected_result.json
new file mode 100644
index 0000000..8e757fc
--- /dev/null
+++ b/test/unit/mocked_data/test_get_facts/normal/expected_result.json
@@ -0,0 +1,63 @@
+{
+  "vendor": "HPE Aruba",
+  "interface_list": [
+    "1",
+    "2",
+    "3",
+    "4",
+    "5",
+    "6",
+    "7",
+    "8",
+    "9",
+    "10",
+    "11",
+    "12",
+    "13",
+    "14",
+    "15",
+    "16",
+    "17",
+    "18",
+    "19",
+    "20",
+    "21",
+    "22",
+    "23",
+    "24",
+    "25",
+    "26",
+    "27",
+    "28",
+    "29",
+    "30",
+    "31",
+    "32",
+    "33",
+    "34",
+    "35",
+    "36",
+    "37",
+    "38",
+    "39",
+    "40",
+    "41",
+    "42",
+    "43",
+    "44",
+    "45T",
+    "46T",
+    "47T",
+    "48T",
+    "45S",
+    "46S",
+    "47S",
+    "48S"
+  ],
+  "uptime": -1,
+  "hostname": "Aruba-2930M-48G-PoEP",
+  "os_version": "WC.16.10.0009",
+  "serial_number": "ABC123456",
+  "model": "Aruba2930M-48G-PoE+ Switch(JL322A)",
+  "fqdn": "Aruba-2930M-48G-PoEP.arubaos.napalm"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_facts/normal/facts.json b/test/unit/mocked_data/test_get_facts/normal/facts.json
new file mode 100644
index 0000000..b08bcf7
--- /dev/null
+++ b/test/unit/mocked_data/test_get_facts/normal/facts.json
@@ -0,0 +1,832 @@
+{
+  "system/status/global_info": {
+    "status": 404,
+    "ok": false,
+    "data": {}
+  },
+  "system/status": {
+    "status": 200,
+    "data": {
+      "uri": "/system/status",
+      "name": "Aruba-2930M-48G-PoEP",
+      "serial_number": "ABC123456",
+      "firmware_version": "WC.16.10.0009",
+      "hardware_revision": "JL322A",
+      "product_model": "Aruba2930M-48G-PoE+ Switch(JL322A)",
+      "base_ethernet_address": {
+        "version": "MAV_EUI_48",
+        "octets": "000000-000000"
+      },
+      "current_ip_address": {
+        "version": "IAV_IP_V4",
+        "octets": "172.16.7.3"
+      },
+      "total_memory_in_bytes": 339329536,
+      "total_poe_consumption": 0,
+      "sys_temp": 22,
+      "sys_temp_threshold": 55,
+      "sys_fan_status": true
+    }
+  },
+  "system/status/members/1": {
+    "status": 404,
+    "ok": false,
+    "data": {}
+  },
+  "system/status/switch": {
+    "status": 200,
+    "data": {
+      "uri": "/system/status/switch",
+      "switch_type": "ST_STANDALONE",
+      "product_name": "Aruba2930M-48G-PoE+ Switch(JL322A)",
+      "product_number": "JL322A",
+      "hardware_info": [
+        {
+          "hardware_type": "SHT_FAN",
+          "status": "SHS_OK"
+        },
+        {
+          "hardware_type": "SHT_TEMP",
+          "status": "SHS_OK"
+        },
+        {
+          "hardware_type": "SHT_PS",
+          "status": "SHS_OK"
+        },
+        {
+          "hardware_type": "SHT_PS",
+          "status": "SHS_OK"
+        }
+      ],
+      "oobm_ports": [
+        {
+          "port_id": 4883,
+          "port_name": "OOBM",
+          "type": "PT_RJ45",
+          "sub_type": "10/100TX",
+          "adminStatus": "ADMIN_UP",
+          "operStatus": "OPER_UP",
+          "mode": "PCM_AUTO",
+          "alignment": "PA_TOP"
+        }
+      ],
+      "is_poe_supported": true,
+      "blades": [
+        {
+          "product_number": "JL322A",
+          "data_ports": [
+            {
+              "port_id": 1,
+              "port_name": "1",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 2,
+              "port_name": "2",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 3,
+              "port_name": "3",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 4,
+              "port_name": "4",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 5,
+              "port_name": "5",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 6,
+              "port_name": "6",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 7,
+              "port_name": "7",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 8,
+              "port_name": "8",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 9,
+              "port_name": "9",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 10,
+              "port_name": "10",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 11,
+              "port_name": "11",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 12,
+              "port_name": "12",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 13,
+              "port_name": "13",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 14,
+              "port_name": "14",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 15,
+              "port_name": "15",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 16,
+              "port_name": "16",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 17,
+              "port_name": "17",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 18,
+              "port_name": "18",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 19,
+              "port_name": "19",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 20,
+              "port_name": "20",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 21,
+              "port_name": "21",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 22,
+              "port_name": "22",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 23,
+              "port_name": "23",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 24,
+              "port_name": "24",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 25,
+              "port_name": "25",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 26,
+              "port_name": "26",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 27,
+              "port_name": "27",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 28,
+              "port_name": "28",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 29,
+              "port_name": "29",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 30,
+              "port_name": "30",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 31,
+              "port_name": "31",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 32,
+              "port_name": "32",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 33,
+              "port_name": "33",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 34,
+              "port_name": "34",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 35,
+              "port_name": "35",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 36,
+              "port_name": "36",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 37,
+              "port_name": "37",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 38,
+              "port_name": "38",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 39,
+              "port_name": "39",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 40,
+              "port_name": "40",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 41,
+              "port_name": "41",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 42,
+              "port_name": "42",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 43,
+              "port_name": "43",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 44,
+              "port_name": "44",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 45,
+              "port_name": "45T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 46,
+              "port_name": "46T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 47,
+              "port_name": "47T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 48,
+              "port_name": "48T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 45,
+              "port_name": "45S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 46,
+              "port_name": "46S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 47,
+              "port_name": "47S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 48,
+              "port_name": "48S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            }
+          ],
+          "expansion_modules": []
+        }
+      ]
+    }
+  },
+  "dns": {
+    "status": 200,
+    "data": {
+      "uri": "/dns",
+      "dns_config_mode": "DCM_MANUAL",
+      "server_1": {
+        "version": "IAV_IP_V4",
+        "octets": "8.8.8.8"
+      },
+      "server_2": {
+        "version": "IAV_IP_V4",
+        "octets": "1.1.1.1"
+      },
+      "dns_domain_names": [
+        "arubaos.napalm"
+      ],
+      "server_3": null,
+      "server_4": null
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_facts/stack/expected_result.json b/test/unit/mocked_data/test_get_facts/stack/expected_result.json
new file mode 100644
index 0000000..b9b00d3
--- /dev/null
+++ b/test/unit/mocked_data/test_get_facts/stack/expected_result.json
@@ -0,0 +1,63 @@
+{
+  "vendor": "HPE Aruba",
+  "interface_list": [
+    "1/1",
+    "1/2",
+    "1/3",
+    "1/4",
+    "1/5",
+    "1/6",
+    "1/7",
+    "1/8",
+    "1/9",
+    "1/10",
+    "1/11",
+    "1/12",
+    "1/13",
+    "1/14",
+    "1/15",
+    "1/16",
+    "1/17",
+    "1/18",
+    "1/19",
+    "1/20",
+    "1/21",
+    "1/22",
+    "1/23",
+    "1/24",
+    "1/25",
+    "1/26",
+    "1/27",
+    "1/28",
+    "1/29",
+    "1/30",
+    "1/31",
+    "1/32",
+    "1/33",
+    "1/34",
+    "1/35",
+    "1/36",
+    "1/37",
+    "1/38",
+    "1/39",
+    "1/40",
+    "1/41",
+    "1/42",
+    "1/43",
+    "1/44",
+    "1/45T",
+    "1/46T",
+    "1/47T",
+    "1/48T",
+    "1/45S",
+    "1/46S",
+    "1/47S",
+    "1/48S"
+  ],
+  "uptime": -1,
+  "hostname": "Aruba-Stack-2930M",
+  "os_version": "WC.16.10.0009",
+  "serial_number": "ABC123456",
+  "model": "Aruba2930M-48G-PoE+ Swit(JL322A)",
+  "fqdn": "Aruba-Stack-2930M.arubaos.napalm"
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_facts/stack/facts.json b/test/unit/mocked_data/test_get_facts/stack/facts.json
new file mode 100644
index 0000000..2a4e741
--- /dev/null
+++ b/test/unit/mocked_data/test_get_facts/stack/facts.json
@@ -0,0 +1,837 @@
+{
+  "system/status/global_info": {
+    "status": 200,
+    "data": {
+      "name": "Aruba-Stack-2930M",
+      "firmware_version": "WC.16.10.0009",
+      "base_ethernet_address": {
+        "version": "MAV_EUI_48",
+        "octets": "000000-000000"
+      },
+      "current_ip_address": {
+        "version": "IAV_IP_V4",
+        "octets": "172.16.7.3"
+      }
+    }
+  },
+  "system/status": {
+    "status": 404,
+    "ok": false,
+    "data": {}
+  },
+  "system/status/members/1": {
+    "status": 200,
+    "data": {
+      "uri": "/system/status/members/1",
+      "member_id": 1,
+      "serial_number": "ABC123456",
+      "hardware_revision": "JL322A",
+      "product_model": "Aruba2930M-48G-PoE+ Swit(JL322A)",
+      "mac_address": {
+        "version": "MAV_EUI_48",
+        "octets": "000000-000000"
+      },
+      "total_memory_in_bytes": 339329536,
+      "total_poe_consumption": 0,
+      "sys_temp": "22C",
+      "sys_temp_threshold": "55C",
+      "sys_fan_status": false
+    }
+  },
+  "system/status/switch": {
+    "status": 200,
+    "data": {
+      "uri": "/system/status/switch",
+      "switch_type": "ST_STACKED",
+      "blades": [
+        {
+          "stack_member": 1,
+          "product_name": "Aruba2930M-48G-PoE+ Swit(JL322A)",
+          "product_number": "JL322A",
+          "hardware_info": [
+            {
+              "hardware_type": "SHT_FAN",
+              "status": "SHS_OK"
+            },
+            {
+              "hardware_type": "SHT_TEMP",
+              "status": "SHS_OK"
+            },
+            {
+              "hardware_type": "SHT_PS",
+              "status": "SHS_OK"
+            },
+            {
+              "hardware_type": "SHT_PS",
+              "status": "SHS_ERROR"
+            }
+          ],
+          "oobm_ports": [
+            {
+              "port_id": 4884,
+              "port_name": "OOBM",
+              "type": "PT_RJ45",
+              "sub_type": "10/100TX",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_UP",
+              "mode": "PCM_AUTO",
+              "alignment": "PA_TOP"
+            }
+          ],
+          "is_poe_supported": true,
+          "data_ports": [
+            {
+              "port_id": 1,
+              "port_name": "1/1",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 2,
+              "port_name": "1/2",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 3,
+              "port_name": "1/3",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 4,
+              "port_name": "1/4",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 5,
+              "port_name": "1/5",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 6,
+              "port_name": "1/6",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 7,
+              "port_name": "1/7",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 8,
+              "port_name": "1/8",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 9,
+              "port_name": "1/9",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 10,
+              "port_name": "1/10",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 11,
+              "port_name": "1/11",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 12,
+              "port_name": "1/12",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 13,
+              "port_name": "1/13",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 14,
+              "port_name": "1/14",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 15,
+              "port_name": "1/15",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 16,
+              "port_name": "1/16",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 17,
+              "port_name": "1/17",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 18,
+              "port_name": "1/18",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 19,
+              "port_name": "1/19",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 20,
+              "port_name": "1/20",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 21,
+              "port_name": "1/21",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 22,
+              "port_name": "1/22",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 23,
+              "port_name": "1/23",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 24,
+              "port_name": "1/24",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 25,
+              "port_name": "1/25",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 26,
+              "port_name": "1/26",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 27,
+              "port_name": "1/27",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 28,
+              "port_name": "1/28",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 29,
+              "port_name": "1/29",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 30,
+              "port_name": "1/30",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 31,
+              "port_name": "1/31",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 32,
+              "port_name": "1/32",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 33,
+              "port_name": "1/33",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 34,
+              "port_name": "1/34",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 35,
+              "port_name": "1/35",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 36,
+              "port_name": "1/36",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 37,
+              "port_name": "1/37",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 38,
+              "port_name": "1/38",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 39,
+              "port_name": "1/39",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 40,
+              "port_name": "1/40",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 41,
+              "port_name": "1/41",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 42,
+              "port_name": "1/42",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 43,
+              "port_name": "1/43",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 44,
+              "port_name": "1/44",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 45,
+              "port_name": "1/45T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 46,
+              "port_name": "1/46T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 47,
+              "port_name": "1/47T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 48,
+              "port_name": "1/48T",
+              "type": "PT_RJ45",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 45,
+              "port_name": "1/45S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 46,
+              "port_name": "1/46S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 47,
+              "port_name": "1/47S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_TOP",
+              "is_smartrate": false
+            },
+            {
+              "port_id": 48,
+              "port_name": "1/48S",
+              "type": "PT_GBIC",
+              "adminStatus": "ADMIN_UP",
+              "operStatus": "OPER_DOWN",
+              "sub_type": "100/1000T",
+              "mode": "PCM_AUTO",
+              "is_internal": false,
+              "oper_mode": "OM_1000_FDX",
+              "poe_status": "POES_SEARCHING",
+              "alignment": "PA_BOTTOM",
+              "is_smartrate": false
+            }
+          ],
+          "expansion_modules": []
+        }
+      ]
+    }
+  },
+  "dns": {
+    "status": 200,
+    "data": {
+      "uri": "/dns",
+      "dns_config_mode": "DCM_MANUAL",
+      "server_1": {
+        "version": "IAV_IP_V4",
+        "octets": "8.8.8.8"
+      },
+      "server_2": {
+        "version": "IAV_IP_V4",
+        "octets": "1.1.1.1"
+      },
+      "dns_domain_names": [
+        "arubaos.napalm"
+      ],
+      "server_3": null,
+      "server_4": null
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_interfaces_ip/normal/expected_result.json b/test/unit/mocked_data/test_get_interfaces_ip/normal/expected_result.json
new file mode 100644
index 0000000..a4ed18e
--- /dev/null
+++ b/test/unit/mocked_data/test_get_interfaces_ip/normal/expected_result.json
@@ -0,0 +1,9 @@
+{
+  "VLAN1": {
+    "ipv4": {
+      "172.16.7.3": {
+        "prefix_length": 23
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_interfaces_ip/normal/facts.json b/test/unit/mocked_data/test_get_interfaces_ip/normal/facts.json
new file mode 100644
index 0000000..408ab4f
--- /dev/null
+++ b/test/unit/mocked_data/test_get_interfaces_ip/normal/facts.json
@@ -0,0 +1,26 @@
+{
+  "ipaddresses": {
+    "status": 200,
+    "data": {
+      "collection_result": {
+        "total_elements_count": 1,
+        "filtered_elements_count": 1
+      },
+      "ip_address_subnet_element": [
+        {
+          "uri": "/vlans/1/ipaddresses/IAAM_STATIC-172.16.7.3",
+          "ip_address_mode": "IAAM_STATIC",
+          "vlan_id": 1,
+          "ip_address": {
+            "version": "IAV_IP_V4",
+            "octets": "172.16.7.3"
+          },
+          "ip_mask": {
+            "version": "IAV_IP_V4",
+            "octets": "255.255.254.0"
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_interfaces_ip/stack/expected_result.json b/test/unit/mocked_data/test_get_interfaces_ip/stack/expected_result.json
new file mode 100644
index 0000000..a4ed18e
--- /dev/null
+++ b/test/unit/mocked_data/test_get_interfaces_ip/stack/expected_result.json
@@ -0,0 +1,9 @@
+{
+  "VLAN1": {
+    "ipv4": {
+      "172.16.7.3": {
+        "prefix_length": 23
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_interfaces_ip/stack/facts.json b/test/unit/mocked_data/test_get_interfaces_ip/stack/facts.json
new file mode 100644
index 0000000..408ab4f
--- /dev/null
+++ b/test/unit/mocked_data/test_get_interfaces_ip/stack/facts.json
@@ -0,0 +1,26 @@
+{
+  "ipaddresses": {
+    "status": 200,
+    "data": {
+      "collection_result": {
+        "total_elements_count": 1,
+        "filtered_elements_count": 1
+      },
+      "ip_address_subnet_element": [
+        {
+          "uri": "/vlans/1/ipaddresses/IAAM_STATIC-172.16.7.3",
+          "ip_address_mode": "IAAM_STATIC",
+          "vlan_id": 1,
+          "ip_address": {
+            "version": "IAV_IP_V4",
+            "octets": "172.16.7.3"
+          },
+          "ip_mask": {
+            "version": "IAV_IP_V4",
+            "octets": "255.255.254.0"
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_lldp_neighbors/normal/expected_result.json b/test/unit/mocked_data/test_get_lldp_neighbors/normal/expected_result.json
new file mode 100644
index 0000000..d06d053
--- /dev/null
+++ b/test/unit/mocked_data/test_get_lldp_neighbors/normal/expected_result.json
@@ -0,0 +1,8 @@
+{
+  "oobm": [
+    {
+      "hostname": "LAB-EDGE-SWITCH01",
+      "port": "GigabitEthernet1/0/8"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_lldp_neighbors/normal/facts.json b/test/unit/mocked_data/test_get_lldp_neighbors/normal/facts.json
new file mode 100644
index 0000000..08abafe
--- /dev/null
+++ b/test/unit/mocked_data/test_get_lldp_neighbors/normal/facts.json
@@ -0,0 +1,48 @@
+{
+  "lldp/remote-device": {
+    "status": 200,
+    "data": {
+      "collection_result": {
+        "total_elements_count": 1,
+        "filtered_elements_count": 1
+      },
+      "lldp_remote_device_element": [
+        {
+          "local_port": "oobm",
+          "chassis_type": "RCT_MAC_ADDRESS",
+          "chassis_id": "00 00 00 00 00 00",
+          "port_type": "LPT_INTERFACE_NAME",
+          "port_id": "GigabitEthernet1/0/8",
+          "port_description": "ARUBA-MGMT",
+          "system_name": "LAB-EDGE-SWITCH01",
+          "system_description": "HP Comware Platform Software, Software Version 5.20.99 Release 2222P01",
+          "pvid": null,
+          "capabilities_supported": {
+            "repeater": false,
+            "bridge": true,
+            "wlan_access_point": false,
+            "router": true,
+            "telephone": false,
+            "cable_device": false,
+            "station_only": false
+          },
+          "capabilities_enabled": {
+            "repeater": false,
+            "bridge": true,
+            "wlan_access_point": false,
+            "router": true,
+            "telephone": false,
+            "cable_device": false,
+            "station_only": false
+          },
+          "remote_management_address": [
+            {
+              "type": "AFM_IP4",
+              "address": "192.168.6.6"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_lldp_neighbors_detail/normal/expected_result.json b/test/unit/mocked_data/test_get_lldp_neighbors_detail/normal/expected_result.json
new file mode 100644
index 0000000..1479369
--- /dev/null
+++ b/test/unit/mocked_data/test_get_lldp_neighbors_detail/normal/expected_result.json
@@ -0,0 +1,20 @@
+{
+  "oobm": [
+    {
+      "parent_interface": "",
+      "remote_system_name": "LAB-EDGE-SWITCH01",
+      "remote_chassis_id": "00 00 00 00 00 00",
+      "remote_port": "GigabitEthernet1/0/8",
+      "remote_port_description": "ARUBA-MGMT",
+      "remote_system_description": "HP Comware Platform Software, Software Version 5.20.99 Release 2222P01",
+      "remote_system_capab": [
+        "bridge",
+        "router"
+      ],
+      "remote_system_enable_capab": [
+        "bridge",
+        "router"
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_lldp_neighbors_detail/normal/facts.json b/test/unit/mocked_data/test_get_lldp_neighbors_detail/normal/facts.json
new file mode 100644
index 0000000..dd4a8e1
--- /dev/null
+++ b/test/unit/mocked_data/test_get_lldp_neighbors_detail/normal/facts.json
@@ -0,0 +1,48 @@
+{
+  "lldp/remote-device": {
+    "status": 200,
+    "data": {
+      "collection_result": {
+        "total_elements_count": 1,
+        "filtered_elements_count": 1
+      },
+      "lldp_remote_device_element": [
+        {
+          "local_port": "oobm",
+          "chassis_type": "RCT_MAC_ADDRESS",
+          "chassis_id": "00 00 00 00 00 00",
+          "port_type": "LPT_INTERFACE_NAME",
+          "port_id": "GigabitEthernet1/0/8",
+          "port_description": "ARUBA-MGMT",
+          "system_name": "LAB-EDGE-SWITCH01",
+          "system_description": "HP Comware Platform Software, Software Version 5.20.99 Release 2222P01",
+          "pvid": null,
+          "capabilities_supported": {
+            "repeater": false,
+            "bridge": true,
+            "wlan_access_point": false,
+            "router": true,
+            "telephone": false,
+            "cable_device": false,
+            "station_only": false
+          },
+          "capabilities_enabled": {
+            "repeater": false,
+            "bridge": true,
+            "wlan_access_point": false,
+            "router": true,
+            "telephone": false,
+            "cable_device": false,
+            "station_only": false
+          },
+          "remote_management_address": [
+            {
+              "type": "AFM_IP4",
+              "address": "192.168.6.6"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
diff --git a/test/unit/mocked_data/test_get_mac_address_table/normal/expected_result.json b/test/unit/mocked_data/test_get_mac_address_table/normal/expected_result.json
new file mode 100644
index 0000000..4507923
--- /dev/null
+++ b/test/unit/mocked_data/test_get_mac_address_table/normal/expected_result.json
@@ -0,0 +1,56 @@
+[
+  {
+    "mac": "ec:00:8b:f7:00:e5",
+    "interface": "Trk1",
+    "vlan": 1,
+    "active": true,
+    "static": false,
+    "moves": 0,
+    "last_move": 0.0
+  },
+  {
+    "mac": "4e:11:14:b1:11:3c",
+    "interface": "Trk1",
+    "vlan": 48,
+    "active": true,
+    "static": false,
+    "moves": 0,
+    "last_move": 0.0
+  },
+  {
+    "mac": "78:22:77:60:22:3f",
+    "interface": "3/44",
+    "vlan": 64,
+    "active": true,
+    "static": false,
+    "moves": 0,
+    "last_move": 0.0
+  },
+  {
+    "mac": "00:33:98:16:33:85",
+    "interface": "2/32",
+    "vlan": 64,
+    "active": true,
+    "static": false,
+    "moves": 0,
+    "last_move": 0.0
+  },
+  {
+    "mac": "e0:44:43:5d:44:b3",
+    "interface": "Trk1",
+    "vlan": 104,
+    "active": true,
+    "static": false,
+    "moves": 0,
+    "last_move": 0.0
+  },
+  {
+    "mac": "00:55:98:17:55:78",
+    "interface": "4/25",
+    "vlan": 64,
+    "active": true,
+    "static": false,
+    "moves": 0,
+    "last_move": 0.0
+  }
+]
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_mac_address_table/normal/facts.json b/test/unit/mocked_data/test_get_mac_address_table/normal/facts.json
new file mode 100644
index 0000000..312b900
--- /dev/null
+++ b/test/unit/mocked_data/test_get_mac_address_table/normal/facts.json
@@ -0,0 +1,49 @@
+{
+  "mac-table": {
+    "status": 200,
+    "data": {
+      "collection_result": {
+        "total_elements_count": 400,
+        "filtered_elements_count": 400
+      },
+      "mac_table_entry_element": [
+        {
+          "uri": "/mac-table/ec008b-f700e5",
+          "mac_address": "ec008b-f700e5",
+          "port_id": "Trk1",
+          "vlan_id": 1
+        },
+        {
+          "uri": "/mac-table/4e1114-b1113c",
+          "mac_address": "4e1114-b1113c",
+          "port_id": "Trk1",
+          "vlan_id": 48
+        },
+        {
+          "uri": "/mac-table/782277-60223f",
+          "mac_address": "782277-60223f",
+          "port_id": "3/44",
+          "vlan_id": 64
+        },
+        {
+          "uri": "/mac-table/003398-163385",
+          "mac_address": "003398-163385",
+          "port_id": "2/32",
+          "vlan_id": 64
+        },
+        {
+          "uri": "/mac-table/e04443-5d44b3",
+          "mac_address": "e04443-5d44b3",
+          "port_id": "Trk1",
+          "vlan_id": 104
+        },
+        {
+          "uri": "/mac-table/005598-175578",
+          "mac_address": "005598-175578",
+          "port_id": "4/25",
+          "vlan_id": 64
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_ntp_peers/normal/expected_result.json b/test/unit/mocked_data/test_get_ntp_peers/normal/expected_result.json
new file mode 100644
index 0000000..6813943
--- /dev/null
+++ b/test/unit/mocked_data/test_get_ntp_peers/normal/expected_result.json
@@ -0,0 +1,4 @@
+{
+  "116.203.116.168": {},
+  "\"de.pool.ntp.org\"": {}
+}
diff --git a/test/unit/mocked_data/test_get_ntp_peers/normal/facts.json b/test/unit/mocked_data/test_get_ntp_peers/normal/facts.json
new file mode 100644
index 0000000..2061a36
--- /dev/null
+++ b/test/unit/mocked_data/test_get_ntp_peers/normal/facts.json
@@ -0,0 +1,46 @@
+{
+  "config/ntp/server/ip4addr": {
+    "status": 200,
+    "data": {
+      "ntpServerIp4addr_element": [
+        {
+          "ip4addr": {
+            "ip4addr_value": "116.203.116.168",
+            "ip4addr_reference": {
+              "min-poll": {
+                "min-poll_value": 6
+              },
+              "max-poll": {
+                "max-poll_value": 10
+              },
+              "oobm": true
+            }
+          },
+          "uri": "/config/ntp/server/ip4addr/116.203.116.168"
+        }
+      ]
+    }
+  },
+  "config/ntp/server-name/ASCII-STR": {
+    "status": 200,
+    "data": {
+      "ntpServerNameASCIISTR_element": [
+        {
+          "ASCII-STR": {
+            "ASCII-STR_value": "\"de.pool.ntp.org\"",
+            "ASCII-STR_reference": {
+              "min-poll": {
+                "min-poll_value": 6
+              },
+              "max-poll": {
+                "max-poll_value": 10
+              },
+              "oobm": true
+            }
+          },
+          "uri": "/config/ntp/server-name/ASCII-STR/%22de.pool.ntp.org%22"
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_ntp_servers/normal/expected_result.json b/test/unit/mocked_data/test_get_ntp_servers/normal/expected_result.json
new file mode 100644
index 0000000..6813943
--- /dev/null
+++ b/test/unit/mocked_data/test_get_ntp_servers/normal/expected_result.json
@@ -0,0 +1,4 @@
+{
+  "116.203.116.168": {},
+  "\"de.pool.ntp.org\"": {}
+}
diff --git a/test/unit/mocked_data/test_get_ntp_servers/normal/facts.json b/test/unit/mocked_data/test_get_ntp_servers/normal/facts.json
new file mode 100644
index 0000000..2061a36
--- /dev/null
+++ b/test/unit/mocked_data/test_get_ntp_servers/normal/facts.json
@@ -0,0 +1,46 @@
+{
+  "config/ntp/server/ip4addr": {
+    "status": 200,
+    "data": {
+      "ntpServerIp4addr_element": [
+        {
+          "ip4addr": {
+            "ip4addr_value": "116.203.116.168",
+            "ip4addr_reference": {
+              "min-poll": {
+                "min-poll_value": 6
+              },
+              "max-poll": {
+                "max-poll_value": 10
+              },
+              "oobm": true
+            }
+          },
+          "uri": "/config/ntp/server/ip4addr/116.203.116.168"
+        }
+      ]
+    }
+  },
+  "config/ntp/server-name/ASCII-STR": {
+    "status": 200,
+    "data": {
+      "ntpServerNameASCIISTR_element": [
+        {
+          "ASCII-STR": {
+            "ASCII-STR_value": "\"de.pool.ntp.org\"",
+            "ASCII-STR_reference": {
+              "min-poll": {
+                "min-poll_value": 6
+              },
+              "max-poll": {
+                "max-poll_value": 10
+              },
+              "oobm": true
+            }
+          },
+          "uri": "/config/ntp/server-name/ASCII-STR/%22de.pool.ntp.org%22"
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_ntp_stats/server-name/expected_result.json b/test/unit/mocked_data/test_get_ntp_stats/server-name/expected_result.json
new file mode 100644
index 0000000..4f871e4
--- /dev/null
+++ b/test/unit/mocked_data/test_get_ntp_stats/server-name/expected_result.json
@@ -0,0 +1,15 @@
+[
+  {
+    "remote": "173.249.33.207",
+    "referenceid": "205.46.178.169",
+    "stratum": 2,
+    "type": "Server",
+    "when": "Wed Nov 10 18:01:18 2021",
+    "hostpoll": 7,
+    "reachability": 17,
+    "delay": 0.01628,
+    "offset": 0.0,
+    "jitter": 0.00075,
+    "synchronized": true
+  }
+]
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_ntp_stats/server-name/facts.json b/test/unit/mocked_data/test_get_ntp_stats/server-name/facts.json
new file mode 100644
index 0000000..5e2201c
--- /dev/null
+++ b/test/unit/mocked_data/test_get_ntp_stats/server-name/facts.json
@@ -0,0 +1,47 @@
+{
+  "monitoring/ntp/servers": {
+    "status": 200,
+    "data": {
+      "NTP_Server_Name_Information": [
+        {
+          "Server Name": "de.pool.ntp.org",
+          "Resolved Address": "173.249.33.207",
+          "Server Status": "Success: NTP server active"
+        },
+        {
+          "Server Name": "0.de.pool.ntp.org",
+          "Resolved Address": "",
+          "Server Status": "Failed: NTP server not active"
+        }
+      ]
+    }
+  },
+  "monitoring/ntp/associations/detail": {
+    "status": 200,
+    "data": {
+      "IP Address": "173.249.33.207",
+      "Peer Mode": "Server",
+      "Status": "Config,Sane,Master",
+      "Peer Poll Intvl": 7,
+      "Stratum": 2,
+      "Root Delay": "0.01628 sec",
+      "Ref Assoc ID": 1,
+      "Root Dispersion": "0.00075 sec",
+      "Assoc Name": "NTP Association 1",
+      "Reach": 17,
+      "Reference ID": "205.46.178.169",
+      "Delay": "0.00000 sec",
+      "Our Mode": "Client",
+      "Offset": "0.00000 sec",
+      "Our Poll Intvl": 7,
+      "Precision": "2**-25",
+      "Dispersion": "15.53054 sec",
+      "Association In Packets": 11,
+      "Association Out Packets": 11,
+      "Association Error Packets": 0,
+      "Origin Time": "Wed Nov 10 18:01:18 2021",
+      "Receive Time": "Wed Nov 10 18:01:18 2021",
+      "Transmit Time": "Wed Nov 10 18:01:18 2021"
+    }
+  }
+}
diff --git a/test/unit/mocked_data/test_get_route_to/normal/cli_mapping.json b/test/unit/mocked_data/test_get_route_to/normal/cli_mapping.json
new file mode 100644
index 0000000..25f16c6
--- /dev/null
+++ b/test/unit/mocked_data/test_get_route_to/normal/cli_mapping.json
@@ -0,0 +1,1 @@
+{"show ip route 1.0.4.0 bgp": "\n                         IP Route Entries to 1.0.4.0\n\n  Destination        Gateway         VLAN Type      Sub-Type   Metric     Dist.\n  ------------------ --------------- ---- --------- ---------- ---------- -----\n  1.0.4.0/24       NET_MGMT        4    bgp            1          0    \n \n\n\u0000"}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_route_to/normal/expected_result.json b/test/unit/mocked_data/test_get_route_to/normal/expected_result.json
new file mode 100644
index 0000000..18aca65
--- /dev/null
+++ b/test/unit/mocked_data/test_get_route_to/normal/expected_result.json
@@ -0,0 +1,27 @@
+{
+  "1.0.4.0/24": [
+    {
+      "protocol": "bgp",
+      "current_active": true,
+      "last_active": true,
+      "age": -1,
+      "next_hop": "NET_MGMT",
+      "outgoing_interface": "",
+      "selected_next_hop": true,
+      "preference": 0,
+      "inactive_reason": "",
+      "routing_table": "",
+      "protocol_attributes": {
+        "local_as": -1,
+        "remote_as": -1,
+        "peer_id": "",
+        "as_path": "",
+        "communities": -1,
+        "local_preference": -1,
+        "preference2": -1,
+        "metric": -1,
+        "metric2": -1
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_route_to_longer/normal/cli_mapping.json b/test/unit/mocked_data/test_get_route_to_longer/normal/cli_mapping.json
new file mode 100644
index 0000000..25f16c6
--- /dev/null
+++ b/test/unit/mocked_data/test_get_route_to_longer/normal/cli_mapping.json
@@ -0,0 +1,1 @@
+{"show ip route 1.0.4.0 bgp": "\n                         IP Route Entries to 1.0.4.0\n\n  Destination        Gateway         VLAN Type      Sub-Type   Metric     Dist.\n  ------------------ --------------- ---- --------- ---------- ---------- -----\n  1.0.4.0/24       NET_MGMT        4    bgp            1          0    \n \n\n\u0000"}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_get_route_to_longer/normal/expected_result.json b/test/unit/mocked_data/test_get_route_to_longer/normal/expected_result.json
new file mode 100644
index 0000000..18aca65
--- /dev/null
+++ b/test/unit/mocked_data/test_get_route_to_longer/normal/expected_result.json
@@ -0,0 +1,27 @@
+{
+  "1.0.4.0/24": [
+    {
+      "protocol": "bgp",
+      "current_active": true,
+      "last_active": true,
+      "age": -1,
+      "next_hop": "NET_MGMT",
+      "outgoing_interface": "",
+      "selected_next_hop": true,
+      "preference": 0,
+      "inactive_reason": "",
+      "routing_table": "",
+      "protocol_attributes": {
+        "local_as": -1,
+        "remote_as": -1,
+        "peer_id": "",
+        "as_path": "",
+        "communities": -1,
+        "local_preference": -1,
+        "preference2": -1,
+        "metric": -1,
+        "metric2": -1
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_is_alive/normal/expected_result.json b/test/unit/mocked_data/test_is_alive/normal/expected_result.json
new file mode 100644
index 0000000..fd599e5
--- /dev/null
+++ b/test/unit/mocked_data/test_is_alive/normal/expected_result.json
@@ -0,0 +1,1 @@
+{"is_alive":  true}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_ping/normal/expected_result.json b/test/unit/mocked_data/test_ping/normal/expected_result.json
new file mode 100644
index 0000000..28fece2
--- /dev/null
+++ b/test/unit/mocked_data/test_ping/normal/expected_result.json
@@ -0,0 +1,16 @@
+{
+  "success": {
+    "probes_sent": 1,
+    "packet_loss": 0,
+    "rtt_min": 21,
+    "rtt_max": 21,
+    "rtt_avg": 21,
+    "rtt_stddev": 0,
+    "results": [
+      {
+        "ip_address": "8.8.8.8",
+        "rtt": 21
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_ping/normal/facts.json b/test/unit/mocked_data/test_ping/normal/facts.json
new file mode 100644
index 0000000..2a518ea
--- /dev/null
+++ b/test/unit/mocked_data/test_ping/normal/facts.json
@@ -0,0 +1,10 @@
+{
+  "ping": {
+    "status": 200,
+    "data": {
+      "uri": "/ping",
+      "result": "PR_OK",
+      "rtt_in_milliseconds": 21
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_traceroute/normal/expected_result.json b/test/unit/mocked_data/test_traceroute/normal/expected_result.json
new file mode 100644
index 0000000..c480013
--- /dev/null
+++ b/test/unit/mocked_data/test_traceroute/normal/expected_result.json
@@ -0,0 +1,99 @@
+{
+  "success": {
+    "1": {
+      "probes": {
+        "1": {
+          "rtt": 2.0,
+          "ip_address": "10.20.4.1",
+          "host_name": ""
+        },
+        "2": {
+          "rtt": 1.0,
+          "ip_address": "10.20.4.1",
+          "host_name": ""
+        },
+        "3": {
+          "rtt": 2.0,
+          "ip_address": "10.20.4.1",
+          "host_name": ""
+        }
+      }
+    },
+    "2": {
+      "probes": {
+        "1": {
+          "rtt": 0.0,
+          "ip_address": "10.191.253.109",
+          "host_name": ""
+        },
+        "2": {
+          "rtt": 1.0,
+          "ip_address": "10.191.253.109",
+          "host_name": ""
+        },
+        "3": {
+          "rtt": 1.0,
+          "ip_address": "10.191.253.109",
+          "host_name": ""
+        }
+      }
+    },
+    "3": {
+      "probes": {
+        "1": {
+          "rtt": 6.0,
+          "ip_address": "10.191.250.69",
+          "host_name": ""
+        },
+        "2": {
+          "rtt": 5.0,
+          "ip_address": "10.191.250.69",
+          "host_name": ""
+        },
+        "3": {
+          "rtt": 5.0,
+          "ip_address": "10.191.250.69",
+          "host_name": ""
+        }
+      }
+    },
+    "4": {
+      "probes": {
+        "1": {
+          "rtt": 20.0,
+          "ip_address": "142.251.225.135",
+          "host_name": ""
+        },
+        "2": {
+          "rtt": 21.0,
+          "ip_address": "142.251.48.177",
+          "host_name": ""
+        },
+        "3": {
+          "rtt": 22.0,
+          "ip_address": "142.250.224.133",
+          "host_name": ""
+        }
+      }
+    },
+    "5": {
+      "probes": {
+        "1": {
+          "rtt": 20.0,
+          "ip_address": "8.8.8.8",
+          "host_name": "dns.google"
+        },
+        "2": {
+          "rtt": 20.0,
+          "ip_address": "8.8.8.8",
+          "host_name": "dns.google"
+        },
+        "3": {
+          "rtt": 21.0,
+          "ip_address": "8.8.8.8",
+          "host_name": "dns.google"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/mocked_data/test_traceroute/normal/facts.json b/test/unit/mocked_data/test_traceroute/normal/facts.json
new file mode 100644
index 0000000..c6b7b43
--- /dev/null
+++ b/test/unit/mocked_data/test_traceroute/normal/facts.json
@@ -0,0 +1,166 @@
+{
+  "trace-route": {
+    "status": 200,
+    "data": {
+      "ttl_data": [
+        {
+          "ttl_probe_data": [
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.20.4.1"
+                }
+              },
+              "probe_time_in_millis": 2
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.20.4.1"
+                }
+              },
+              "probe_time_in_millis": 1
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.20.4.1"
+                }
+              },
+              "probe_time_in_millis": 2
+            }
+          ]
+        },
+        {
+          "ttl_probe_data": [
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.191.253.109"
+                }
+              },
+              "probe_time_in_millis": 0
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.191.253.109"
+                }
+              },
+              "probe_time_in_millis": 1
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.191.253.109"
+                }
+              },
+              "probe_time_in_millis": 1
+            }
+          ]
+        },
+        {
+          "ttl_probe_data": [
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.191.250.69"
+                }
+              },
+              "probe_time_in_millis": 6
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.191.250.69"
+                }
+              },
+              "probe_time_in_millis": 5
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "10.191.250.69"
+                }
+              },
+              "probe_time_in_millis": 5
+            }
+          ]
+        },
+        {
+          "ttl_probe_data": [
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "142.251.225.135"
+                }
+              },
+              "probe_time_in_millis": 20
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "142.251.48.177"
+                }
+              },
+              "probe_time_in_millis": 21
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "142.250.224.133"
+                }
+              },
+              "probe_time_in_millis": 22
+            }
+          ]
+        },
+        {
+          "ttl_probe_data": [
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "8.8.8.8"
+                }
+              },
+              "probe_time_in_millis": 20
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "8.8.8.8"
+                }
+              },
+              "probe_time_in_millis": 20
+            },
+            {
+              "gateway": {
+                "ip_address": {
+                  "version": "IAV_IP_V4",
+                  "octets": "8.8.8.8"
+                }
+              },
+              "probe_time_in_millis": 21
+            }
+          ]
+        }
+      ],
+      "result": "TRR_OK",
+      "uri": "/trace-route"
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/unit/test_getters.py b/test/unit/test_getters.py
new file mode 100644
index 0000000..6a16ea5
--- /dev/null
+++ b/test/unit/test_getters.py
@@ -0,0 +1,10 @@
+"""Tests for getters."""
+
+from napalm.base.test.getters import BaseTestGetters
+
+import pytest
+
+
+@pytest.mark.usefixtures("set_device_parameters")
+class TestGetter(BaseTestGetters):
+    """Test get_* methods."""
diff --git a/test/unit/utils/textfsm_templates/show_arp.tpl b/test/unit/utils/textfsm_templates/show_arp.tpl
new file mode 100644
index 0000000..4dd9c4d
--- /dev/null
+++ b/test/unit/utils/textfsm_templates/show_arp.tpl
@@ -0,0 +1,10 @@
+Value IP (\S+)
+Value MAC ([0-9a-fA-F]{6}-[0-9a-fA-F]{6})
+Value TYPE (\S+)
+Value PORT (\S+)
+
+Start
+  ^.*IP ARP table -> ARP
+
+ARP
+  ^\s+${IP}\s+${MAC}\s+${TYPE}\s+${PORT} -> Record
diff --git a/test/unit/utils/textfsm_templates/show_ip_route.tpl b/test/unit/utils/textfsm_templates/show_ip_route.tpl
new file mode 100644
index 0000000..69ef9a5
--- /dev/null
+++ b/test/unit/utils/textfsm_templates/show_ip_route.tpl
@@ -0,0 +1,15 @@
+Value Required DESTINATION (\S+)
+Value GATEWAY (\S+)
+Value VLAN ([0-9]*)
+Value TYPE (\w+)
+Value SUBTYPE (\S*)
+Value METRIC ([0-9]+)
+Value DISTANCE ([0-9]+)
+
+
+Start
+  ^.*IP Route Entries -> Routes
+
+Routes
+  ^\s+${DESTINATION}\s+${GATEWAY}\s+${VLAN}\s+${TYPE}\s+${SUBTYPE}\s+${METRIC}\s+${DISTANCE} -> Record
+
diff --git a/test/unit/utils/textfsm_templates/show_ipv6_route.tpl b/test/unit/utils/textfsm_templates/show_ipv6_route.tpl
new file mode 100644
index 0000000..5745f71
--- /dev/null
+++ b/test/unit/utils/textfsm_templates/show_ipv6_route.tpl
@@ -0,0 +1,15 @@
+Value DESTINATION ([0-9a-z:/%]+)
+Value GATEWAY (\w+)
+Value VLAN (\w+)
+Value TYPE ([SCOR])
+Value SUBTYPE ([A-Z0-9][A-Z0-9])
+Value METRIC ([0-9]+)
+Value DISTANCE ([0-9]+)
+
+
+Start
+  ^.*IPv6 Route Entries -> Routes
+
+Routes
+  ^\s${DESTINATION}\s+
+  ^\s+${GATEWAY}\s(\(${VLAN}\))?\s+${TYPE}\s+${SUBTYPE}\s+${DISTANCE}\s+${METRIC} -> Record