diff --git a/README.md b/README.md
index 14acc2e..4bed84a 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,9 @@ Name | Description
[ansible.utils.ipv6_ipv4_mapped](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv6_ipv4_mapped_test.rst)|Test if something appears to be a mapped IPv6 to IPv4 mapped address
[ansible.utils.ipv6_sixtofour](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv6_sixtofour_test.rst)|Test if something appears to be a 6to4 address
[ansible.utils.ipv6_teredo](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv6_teredo_test.rst)|Test if something appears to be an IPv6 teredo address
+[ansible.utils.loopback](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.loopback_test.rst)|Test if an IP address is a loopback
+[ansible.utils.mac](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.mac_test.rst)|Test if something appears to be a valid MAC address
+[ansible.utils.multicast](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.multicast_test.rst)|Test for a multicast IP address
[ansible.utils.validate](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.validate_test.rst)|Validate data with provided criteria
diff --git a/changelogs/fragments/add_netaddr_test_plugins_5.yml b/changelogs/fragments/add_netaddr_test_plugins_5.yml
new file mode 100644
index 0000000..40a2b30
--- /dev/null
+++ b/changelogs/fragments/add_netaddr_test_plugins_5.yml
@@ -0,0 +1,3 @@
+---
+minor_changes:
+ - Add loopback, mac, multicast test plugins
diff --git a/docs/ansible.utils.loopback_test.rst b/docs/ansible.utils.loopback_test.rst
new file mode 100644
index 0000000..c4927ee
--- /dev/null
+++ b/docs/ansible.utils.loopback_test.rst
@@ -0,0 +1,148 @@
+.. _ansible.utils.loopback_test:
+
+
+**********************
+ansible.utils.loopback
+**********************
+
+**Test if an IP address is a loopback**
+
+
+Version added: 2.2.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This plugin checks if the provided value is a valid loopback IP address
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ ip
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['127.0.0.1', '2002::c0a8:6301:1']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ - name: Check if 127.10.10.10 is a valid loopback address
+ ansible.builtin.set_fact:
+ data: "{{ '127.10.10.10' is ansible.utils.loopback }}"
+
+ # TASK [Check if 127.10.10.10 is a valid loopback address] *************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 10.1.1.1 is not a valid loopback address
+ ansible.builtin.set_fact:
+ data: "{{ '10.1.1.1' is not ansible.utils.loopback }}"
+
+ # TASK [Check if 10.1.1.1 is not a valid loopback address] *************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if ::1 is a valid loopback address
+ ansible.builtin.set_fact:
+ data: "{{ '::1' is ansible.utils.loopback }}"
+
+ # TASK [Check if ::1 is a valid loopback address] **********************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+
+
+Return Values
+-------------
+Common return values are documented `here `_, the following are the fields unique to this test:
+
+.. raw:: html
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ data
+
+
+ -
+
+ |
+ |
+
+ If jinja test satisfies plugin expression true
+ If jinja test does not satisfy plugin expression false
+
+ |
+
+
+
+
+
+Status
+------
+
+
+Authors
+~~~~~~~
+
+- Priyam Sahoo (@priyamsahoo)
+
+
+.. hint::
+ Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
diff --git a/docs/ansible.utils.mac_test.rst b/docs/ansible.utils.mac_test.rst
new file mode 100644
index 0000000..f0de524
--- /dev/null
+++ b/docs/ansible.utils.mac_test.rst
@@ -0,0 +1,172 @@
+.. _ansible.utils.mac_test:
+
+
+*****************
+ansible.utils.mac
+*****************
+
+**Test if something appears to be a valid MAC address**
+
+
+Version added: 2.2.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This plugin checks if the provided value is a valid MAC address that follows the industry level standards
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ mac
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['02:16:3e:e4:16:f3', '02-16-3e-e4-16-f3', '0216.3ee4.16f3', '02163ee416f3']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ - name: Check if 02:16:3e:e4:16:f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '02:16:3e:e4:16:f3' is ansible.utils.mac }}"
+
+ # TASK [Check if 02:16:3e:e4:16:f3 is a valid MAC address] ********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 02-16-3e-e4-16-f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '02-16-3e-e4-16-f3' is ansible.utils.mac }}"
+
+ # TASK [Check if 02-16-3e-e4-16-f3 is a valid MAC address] ********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 0216.3ee4.16f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '0216.3ee4.16f3' is ansible.utils.mac }}"
+
+ # TASK [Check if 0216.3ee4.16f3 is a valid MAC address] ***********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 02163ee416f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '02163ee416f3' is ansible.utils.mac }}"
+
+ # TASK [Check if 02163ee416f3 is a valid MAC address] *************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if helloworld is not a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ 'helloworld' is not ansible.utils.mac }}"
+
+ # TASK [Check if helloworld is not a valid MAC address] ***********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+
+
+Return Values
+-------------
+Common return values are documented `here `_, the following are the fields unique to this test:
+
+.. raw:: html
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ data
+
+
+ -
+
+ |
+ |
+
+ If jinja test satisfies plugin expression true
+ If jinja test does not satisfy plugin expression false
+
+ |
+
+
+
+
+
+Status
+------
+
+
+Authors
+~~~~~~~
+
+- Priyam Sahoo (@priyamsahoo)
+
+
+.. hint::
+ Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
diff --git a/docs/ansible.utils.multicast_test.rst b/docs/ansible.utils.multicast_test.rst
new file mode 100644
index 0000000..a84d051
--- /dev/null
+++ b/docs/ansible.utils.multicast_test.rst
@@ -0,0 +1,160 @@
+.. _ansible.utils.multicast_test:
+
+
+***********************
+ansible.utils.multicast
+***********************
+
+**Test for a multicast IP address**
+
+
+Version added: 2.2.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This plugin checks if the provided value is a valid multicast IP address
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ ip
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['224.0.0.1', '127.0.0.1']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ - name: Check if 224.0.0.1 is a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ '224.0.0.1' is ansible.utils.multicast }}"
+
+ # TASK [Check if 224.0.0.1 is a valid multicast IP address] **********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if ff02::1 is a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ 'ff02::1' is ansible.utils.multicast }}"
+
+ # TASK [Check if ff02::1 is a valid multicast IP address] ***************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 127.0.0.1 is not a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ '127.0.0.1' is not ansible.utils.multicast }}"
+
+ # TASK [Check if 127.0.0.1 is not a valid multicast IP address] *********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if helloworld is not a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ 'helloworld' is not ansible.utils.multicast }}"
+
+ # TASK [Check if helloworld is not a valid multicast IP address] ********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+
+
+Return Values
+-------------
+Common return values are documented `here `_, the following are the fields unique to this test:
+
+.. raw:: html
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ data
+
+
+ -
+
+ |
+ |
+
+ If jinja test satisfies plugin expression true
+ If jinja test does not satisfy plugin expression false
+
+ |
+
+
+
+
+
+Status
+------
+
+
+Authors
+~~~~~~~
+
+- Priyam Sahoo (@priyamsahoo)
+
+
+.. hint::
+ Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
diff --git a/plugins/test/loopback.py b/plugins/test/loopback.py
new file mode 100644
index 0000000..ccd193c
--- /dev/null
+++ b/plugins/test/loopback.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+Test plugin file for netaddr tests: loopback
+"""
+
+from __future__ import absolute_import, division, print_function
+from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import (
+ ip_address,
+ _need_ipaddress,
+ _validate_args,
+)
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+ name: loopback
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test if an IP address is a loopback
+ description:
+ - This plugin checks if the provided value is a valid loopback IP address
+ options:
+ ip:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "127.0.0.1"
+ - "2002::c0a8:6301:1"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+- name: Check if 127.10.10.10 is a valid loopback address
+ ansible.builtin.set_fact:
+ data: "{{ '127.10.10.10' is ansible.utils.loopback }}"
+
+# TASK [Check if 127.10.10.10 is a valid loopback address] *************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 10.1.1.1 is not a valid loopback address
+ ansible.builtin.set_fact:
+ data: "{{ '10.1.1.1' is not ansible.utils.loopback }}"
+
+# TASK [Check if 10.1.1.1 is not a valid loopback address] *************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if ::1 is a valid loopback address
+ ansible.builtin.set_fact:
+ data: "{{ '::1' is ansible.utils.loopback }}"
+
+# TASK [Check if ::1 is a valid loopback address] **********************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+"""
+
+RETURN = """
+ data:
+ description:
+ - If jinja test satisfies plugin expression C(true)
+ - If jinja test does not satisfy plugin expression C(false)
+"""
+
+
+@_need_ipaddress
+def _loopback(ip):
+ """ Test if an IP address is a loopback """
+
+ params = {"ip": ip}
+ _validate_args("loopback", DOCUMENTATION, params)
+
+ try:
+ return ip_address(ip).is_loopback
+ except Exception:
+ return False
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"loopback": _loopback}
+
+ def tests(self):
+ return self.test_map
diff --git a/plugins/test/mac.py b/plugins/test/mac.py
new file mode 100644
index 0000000..cb6fdbc
--- /dev/null
+++ b/plugins/test/mac.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+Test plugin file for netaddr tests: mac
+"""
+
+from __future__ import absolute_import, division, print_function
+from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import (
+ _validate_args,
+)
+import re
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+ name: mac
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test if something appears to be a valid MAC address
+ description:
+ - This plugin checks if the provided value is a valid MAC address that follows the industry level standards
+ options:
+ mac:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "02:16:3e:e4:16:f3"
+ - "02-16-3e-e4-16-f3"
+ - "0216.3ee4.16f3"
+ - "02163ee416f3"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+- name: Check if 02:16:3e:e4:16:f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '02:16:3e:e4:16:f3' is ansible.utils.mac }}"
+
+# TASK [Check if 02:16:3e:e4:16:f3 is a valid MAC address] ********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 02-16-3e-e4-16-f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '02-16-3e-e4-16-f3' is ansible.utils.mac }}"
+
+# TASK [Check if 02-16-3e-e4-16-f3 is a valid MAC address] ********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 0216.3ee4.16f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '0216.3ee4.16f3' is ansible.utils.mac }}"
+
+# TASK [Check if 0216.3ee4.16f3 is a valid MAC address] ***********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 02163ee416f3 is a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ '02163ee416f3' is ansible.utils.mac }}"
+
+# TASK [Check if 02163ee416f3 is a valid MAC address] *************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if helloworld is not a valid MAC address
+ ansible.builtin.set_fact:
+ data: "{{ 'helloworld' is not ansible.utils.mac }}"
+
+# TASK [Check if helloworld is not a valid MAC address] ***********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+"""
+
+RETURN = """
+ data:
+ description:
+ - If jinja test satisfies plugin expression C(true)
+ - If jinja test does not satisfy plugin expression C(false)
+"""
+
+
+def _mac(mac):
+ """ Test if something appears to be a valid mac address """
+
+ params = {"mac": mac}
+ _validate_args("mac", DOCUMENTATION, params)
+
+ # IEEE EUI-48 upper and lower, commom unix
+ re1 = r"^(?i)([0-9a-f]{2}[:-]){5}[0-9a-f]{2}$"
+ # Cisco triple hextex
+ re2 = r"^(?i)([0-9a-f]{4}\.[0-9a-f]{4}\.[0-9a-f]{4})$"
+ # Bare
+ re3 = r"^(?i)[0-9a-f]{12}$"
+ regex = "{re1}|{re2}|{re3}".format(re1=re1, re2=re2, re3=re3)
+ return bool(re.match(regex, mac))
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"mac": _mac}
+
+ def tests(self):
+ return self.test_map
diff --git a/plugins/test/multicast.py b/plugins/test/multicast.py
new file mode 100644
index 0000000..f2e3c97
--- /dev/null
+++ b/plugins/test/multicast.py
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+Test plugin file for netaddr tests: multicast
+"""
+
+from __future__ import absolute_import, division, print_function
+from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import (
+ ip_address,
+ _need_ipaddress,
+ _validate_args,
+)
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+ name: multicast
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test for a multicast IP address
+ description:
+ - This plugin checks if the provided value is a valid multicast IP address
+ options:
+ ip:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "224.0.0.1"
+ - "127.0.0.1"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+- name: Check if 224.0.0.1 is a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ '224.0.0.1' is ansible.utils.multicast }}"
+
+# TASK [Check if 224.0.0.1 is a valid multicast IP address] **********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if ff02::1 is a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ 'ff02::1' is ansible.utils.multicast }}"
+
+# TASK [Check if ff02::1 is a valid multicast IP address] ***************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 127.0.0.1 is not a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ '127.0.0.1' is not ansible.utils.multicast }}"
+
+# TASK [Check if 127.0.0.1 is not a valid multicast IP address] *********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if helloworld is not a valid multicast IP address
+ ansible.builtin.set_fact:
+ data: "{{ 'helloworld' is not ansible.utils.multicast }}"
+
+# TASK [Check if helloworld is not a valid multicast IP address] ********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+"""
+
+RETURN = """
+ data:
+ description:
+ - If jinja test satisfies plugin expression C(true)
+ - If jinja test does not satisfy plugin expression C(false)
+"""
+
+
+@_need_ipaddress
+def _multicast(ip):
+ """ Test for a multicast IP address """
+
+ params = {"ip": ip}
+ _validate_args("multicast", DOCUMENTATION, params)
+
+ try:
+ return ip_address(ip).is_multicast
+ except Exception:
+ return False
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"multicast": _multicast}
+
+ def tests(self):
+ return self.test_map
diff --git a/tests/integration/targets/netaddr_test/tasks/include/loopback.yml b/tests/integration/targets/netaddr_test/tasks/include/loopback.yml
new file mode 100644
index 0000000..40802a1
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/loopback.yml
@@ -0,0 +1,16 @@
+---
+- name: "loopback: Check if 127.10.10.10 is a valid loopback address"
+ assert:
+ that: "{{ '127.10.10.10' is ansible.utils.loopback }}"
+
+- name: "loopback: Check if ::1 is a valid loopback address"
+ assert:
+ that: "{{ '::1' is ansible.utils.loopback }}"
+
+- name: "loopback: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check: "{{ '10.1.1.1' is ansible.utils.loopback }}"
+
+- name: "loopback: Assert invalidness"
+ assert:
+ that: "{{ criteria_check == false }}"
diff --git a/tests/integration/targets/netaddr_test/tasks/include/mac.yml b/tests/integration/targets/netaddr_test/tasks/include/mac.yml
new file mode 100644
index 0000000..96f6da4
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/mac.yml
@@ -0,0 +1,24 @@
+---
+- name: "mac: Check if 02:16:3e:e4:16:f3 is a valid MAC address"
+ assert:
+ that: "{{ '02:16:3e:e4:16:f3' is ansible.utils.mac }}"
+
+- name: "mac: Check if 02-16-3e-e4-16-f3 is a valid MAC address"
+ assert:
+ that: "{{ '02-16-3e-e4-16-f3' is ansible.utils.mac }}"
+
+- name: "mac: Check if 0216.3ee4.16f3 is a valid MAC address"
+ assert:
+ that: "{{ '0216.3ee4.16f3' is ansible.utils.mac }}"
+
+- name: "mac: Check if 02163ee416f3 is a valid MAC address"
+ assert:
+ that: "{{ '02163ee416f3' is ansible.utils.mac }}"
+
+- name: "mac: Check invalidness"
+ ansible.builtin.set_fact:
+ criteria_check: "{{ 'string' is ansible.utils.mac }}"
+
+- name: "mac: Assert invalidness"
+ assert:
+ that: "{{ criteria_check == false }}"
diff --git a/tests/integration/targets/netaddr_test/tasks/include/multicast.yml b/tests/integration/targets/netaddr_test/tasks/include/multicast.yml
new file mode 100644
index 0000000..2b9a39b
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/multicast.yml
@@ -0,0 +1,24 @@
+---
+- name: "multicast: Check if 224.0.0.1 is a valid multicast IP address"
+ assert:
+ that: "{{ '224.0.0.1' is ansible.utils.multicast }}"
+
+- name: "multicast: Check if ff02::1 is a valid multicast IP address"
+ assert:
+ that: "{{ 'ff02::1' is ansible.utils.multicast }}"
+
+- name: "multicast: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check1: "{{ '127.0.0.1' is ansible.utils.multicast }}"
+
+- name: "multicast: Assert invalidness"
+ assert:
+ that: "{{ criteria_check1 == false }}"
+
+- name: "multicast: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check2: "{{ 'helloworld' is ansible.utils.multicast }}"
+
+- name: "multicast: Assert invalidness"
+ assert:
+ that: "{{ criteria_check2 == false }}"
diff --git a/tests/unit/plugins/test/test_loopback.py b/tests/unit/plugins/test/test_loopback.py
new file mode 100644
index 0000000..be3109e
--- /dev/null
+++ b/tests/unit/plugins/test/test_loopback.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+Unit test file for netaddr test plugin: loopback
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.loopback import _loopback
+
+
+class TestLoopback(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _loopback()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _loopback(ip="127.10.10.10")
+ self.assertEqual(result, True)
+
+ result = _loopback(ip="::1")
+ self.assertEqual(result, True)
+
+ result = _loopback(ip="10.1.1.1")
+ self.assertEqual(result, False)
diff --git a/tests/unit/plugins/test/test_mac.py b/tests/unit/plugins/test/test_mac.py
new file mode 100644
index 0000000..f7ac9a3
--- /dev/null
+++ b/tests/unit/plugins/test/test_mac.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+Unit test file for netaddr test plugin: mac
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.mac import _mac
+
+
+class TestMac(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _mac()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _mac(mac="02:16:3e:e4:16:f3")
+ self.assertEqual(result, True)
+
+ result = _mac(mac="02-16-3e-e4-16-f3")
+ self.assertEqual(result, True)
+
+ result = _mac(mac="0216.3ee4.16f3")
+ self.assertEqual(result, True)
+
+ result = _mac(mac="02163ee416f3")
+ self.assertEqual(result, True)
+
+ result = _mac(mac="string")
+ self.assertEqual(result, False)
diff --git a/tests/unit/plugins/test/test_multicast.py b/tests/unit/plugins/test/test_multicast.py
new file mode 100644
index 0000000..adbea68
--- /dev/null
+++ b/tests/unit/plugins/test/test_multicast.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+Unit test file for netaddr test plugin: multicast
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.multicast import _multicast
+
+
+class TestMulticast(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _multicast()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _multicast(ip="224.0.0.1")
+ self.assertEqual(result, True)
+
+ result = _multicast(ip="ff02::1")
+ self.assertEqual(result, True)
+
+ result = _multicast(ip="127.0.0.1")
+ self.assertEqual(result, False)
+
+ result = _multicast(ip="string")
+ self.assertEqual(result, False)