1# -*- coding: utf-8 -*-
2
3#
4# Dell EMC OpenManage Ansible Modules
5# Version 3.5.0
6# Copyright (C) 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
7
8# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
9#
10
11from __future__ import (absolute_import, division, print_function)
12
13__metaclass__ = type
14
15import pytest
16import json
17from ssl import SSLError
18from io import StringIO
19from ansible_collections.dellemc.openmanage.plugins.modules import ome_device_group
20from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants, \
21    AnsibleFailJSonException
22from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
23from ansible.module_utils.urls import ConnectionError, SSLValidationError
24from ansible.module_utils._text import to_text
25
26netaddr = pytest.importorskip("netaddr")
27
28MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.ome_device_group.'
29ADD_STATIC_GROUP_MESSAGE = "Devices can be added only to the static device groups created using OpenManage Enterprise."
30INVALID_IP_FORMAT = "The format {0} of the IP address provided is not supported or invalid."
31IP_NOT_EXISTS = "The IP addresses provided do not exist in OpenManage Enterprise."
32try:
33    from netaddr import IPAddress, IPNetwork, IPRange
34    from netaddr.core import AddrFormatError
35
36    HAS_NETADDR = True
37except ImportError:
38    HAS_NETADDR = False
39
40
41@pytest.fixture
42def ome_connection_mock_for_device_group(mocker, ome_response_mock):
43    connection_class_mock = mocker.patch(MODULE_PATH + 'RestOME')
44    ome_connection_mock_obj = connection_class_mock.return_value.__enter__.return_value
45    ome_connection_mock_obj.invoke_request.return_value = ome_response_mock
46    ome_connection_mock_obj.get_all_report_details.return_value = {"report_list": []}
47    return ome_connection_mock_obj
48
49
50class TestOMEDeviceGroup(FakeAnsibleModule):
51    module = ome_device_group
52
53    def test_ome_device_group_get_group_id_case01(self, ome_connection_mock_for_device_group, ome_response_mock):
54        f_module = self.get_module_mock(params={"name": "Storage Services",
55                                                "device_ids": [25011], "device_service_tags": []})
56        ome_response_mock.json_data = {"value": []}
57        with pytest.raises(Exception) as exc:
58            self.module.get_group_id(ome_connection_mock_for_device_group, f_module)
59        assert exc.value.args[0] == "Unable to complete the operation because the entered " \
60                                    "target group name 'Storage Services' is invalid."
61        ome_response_mock.json_data = {"value": [{"Id": 25011, "CreatedBy": "user",
62                                                  "TypeId": 3000, "MembershipTypeId": 12}]}
63        resp = self.module.get_group_id(ome_connection_mock_for_device_group, f_module)
64        assert resp == 25011
65
66    def test_ome_device_group_get_group_id_case02(self, ome_connection_mock_for_device_group, ome_response_mock):
67        f_module = self.get_module_mock(params={"group_id": 1234,
68                                                "device_ids": [25011], "device_service_tags": []})
69        ome_connection_mock_for_device_group.invoke_request.side_effect = HTTPError('http://testhost.com', 400,
70                                                                                    'http error message',
71                                                                                    {"accept-type": "application/json"},
72                                                                                    StringIO(to_text(json.dumps(
73                                                                                        {"info": "error_details"}))))
74        with pytest.raises(Exception) as exc1:
75            self.module.get_group_id(ome_connection_mock_for_device_group, f_module)
76        assert exc1.value.args[0] == "Unable to complete the operation because the entered " \
77                                     "target group Id '1234' is invalid."
78
79    def test_ome_device_group_get_group_id_case03(self, ome_connection_mock_for_device_group, ome_response_mock):
80        f_module = self.get_module_mock(params={"group_id": 1234,
81                                                "device_ids": [25011], "device_service_tags": []})
82        ome_response_mock.json_data = {"Id": 1234, "CreatedBy": "user",
83                                       "TypeId": 3000, "MembershipTypeId": 12}
84        resp = self.module.get_group_id(ome_connection_mock_for_device_group, f_module)
85        assert resp == 1234
86
87    def test_ome_device_group_get_device_id(self, ome_connection_mock_for_device_group):
88        report_list = [{"Id": 25011, "DeviceServiceTag": "SEFRG2"}, {"Id": 25012, "DeviceServiceTag": "SEFRG3"}]
89        ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
90        f_module = self.get_module_mock(params={"name": "Storage Services",
91                                                "device_ids": [25011, 25012]})
92        device_list, key = self.module.get_device_id(ome_connection_mock_for_device_group, f_module)
93        assert device_list == [25011, 25012]
94        assert key == "Id"
95        f_module = self.get_module_mock(params={"name": "Storage Services",
96                                                "device_service_tags": ["SEFRG2", "SEFRG3"]})
97        device_list, key = self.module.get_device_id(ome_connection_mock_for_device_group, f_module)
98        assert device_list == [25011, 25012]
99        assert key == "DeviceServiceTag"
100
101        f_module = self.get_module_mock(params={"name": "Storage Services",
102                                                "device_ids": [25011, 25000]})
103        with pytest.raises(Exception) as exc:
104            self.module.get_device_id(ome_connection_mock_for_device_group, f_module)
105        assert exc.value.args[0] == "Unable to complete the operation because the entered target " \
106                                    "device id(s) '25000' are invalid."
107
108    def test_ome_device_group_add_member_to_group(self, ome_connection_mock_for_device_group, ome_response_mock):
109        report_list = [{"Id": 25011, "DeviceServiceTag": "SEFRG2"}]
110        ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
111        f_module = self.get_module_mock(params={"name": "Storage Services",
112                                                "device_ids": [25011]})
113        ome_response_mock.status_code = 204
114        ome_response_mock.success = True
115        with pytest.raises(Exception) as exc:
116            self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group,
117                                            1, [25011], "Id")
118        assert exc.value.args[0] == "No changes found to be applied."
119
120        f_module.check_mode = True
121        with pytest.raises(Exception) as exc:
122            self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group,
123                                            1, [25011], "Id")
124        assert exc.value.args[0] == "No changes found to be applied."
125
126        f_module.check_mode = False
127        report_list = [{"Id": 25013, "DeviceServiceTag": "SEFRG4"}, {"Id": 25014, "DeviceServiceTag": "SEFRG5"}]
128        ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
129        resp, [] = self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group,
130                                                   1, [25011, 25012], "Id")
131        assert resp.status_code == 204
132
133        f_module.check_mode = True
134        with pytest.raises(Exception) as exc:
135            self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group,
136                                            1, [25011, 25012], "Id")
137        assert exc.value.args[0] == "Changes found to be applied."
138
139    def test_ome_device_group_main_exception(self, ome_connection_mock_for_device_group, mocker,
140                                             ome_response_mock, ome_default_args):
141        ome_default_args.update({"name": "Storage Services", "device_ids": [25011, 25012]})
142        ome_response_mock.status_code = 204
143        ome_response_mock.success = True
144        mocker.patch(MODULE_PATH + 'get_group_id', return_value=1)
145        mocker.patch(MODULE_PATH + 'get_device_id', return_value=[25011, 25012])
146        mocker.patch(MODULE_PATH + 'add_member_to_group', return_value=(ome_response_mock, []))
147        result = self._run_module(ome_default_args)
148        assert result['msg'] == "Successfully added member(s) to the device group."
149
150    def test_ome_device_group_argument_exception_case1(self, ome_default_args):
151        ome_default_args.update({"name": "Storage Services", "device_ids": [25011, 25012], "group_id": 1234})
152        result = self._run_module_with_fail_json(ome_default_args)
153        assert result["msg"] == "parameters are mutually exclusive: name|group_id"
154
155    def test_ome_device_group_argument_exception_case2(self, ome_default_args):
156        ome_default_args.update(
157            {"device_ids": [25011, 25012], "group_id": 1234, "device_service_tags": [Constants.service_tag1]})
158        result = self._run_module_with_fail_json(ome_default_args)
159        assert result["msg"] == "parameters are mutually exclusive: device_ids|device_service_tags|ip_addresses"
160
161    def test_ome_device_group_argument_exception_case3(self, ome_default_args):
162        ome_default_args.update({"device_ids": [25011, 25012]})
163        result = self._run_module_with_fail_json(ome_default_args)
164        assert result["msg"] == "one of the following is required: name, group_id"
165
166    def test_ome_device_group_argument_exception_case4(self, ome_default_args):
167        ome_default_args.update(
168            {"group_id": 1234})
169        result = self._run_module_with_fail_json(ome_default_args)
170        assert result["msg"] == "one of the following is required: device_ids, device_service_tags, ip_addresses"
171
172    def test_ome_device_group_argument_exception_case5(self, ome_default_args):
173        ome_default_args.update(
174            {"device_ids": None, "group_id": 1234, "device_service_tags": None})
175        result = self._run_module_with_fail_json(ome_default_args)
176        assert result["msg"] == "parameters are mutually exclusive: device_ids|device_service_tags|ip_addresses"
177
178    @pytest.mark.parametrize("exc_type",
179                             [IOError, ValueError, SSLError, TypeError, ConnectionError, HTTPError, URLError])
180    def test_ome_device_group_argument_main_exception_failure_case(self, exc_type, mocker, ome_default_args,
181                                                                   ome_connection_mock_for_device_group,
182                                                                   ome_response_mock):
183        ome_default_args.update({"name": "Storage Services", "device_ids": [25011, 25012]})
184        ome_response_mock.status_code = 400
185        ome_response_mock.success = False
186        json_str = to_text(json.dumps({"info": "error_details"}))
187        if exc_type == URLError:
188            mocker.patch(MODULE_PATH + 'get_group_id', side_effect=exc_type("url open error"))
189            result = self._run_module(ome_default_args)
190            assert result["unreachable"] is True
191        elif exc_type not in [HTTPError, SSLValidationError]:
192            mocker.patch(MODULE_PATH + 'get_group_id', side_effect=exc_type("exception message"))
193            result = self._run_module_with_fail_json(ome_default_args)
194            assert result['failed'] is True
195        else:
196            mocker.patch(MODULE_PATH + 'get_group_id',
197                         side_effect=exc_type('http://testhost.com', 400, 'http error message',
198                                              {"accept-type": "application/json"}, StringIO(json_str)))
199            result = self._run_module_with_fail_json(ome_default_args)
200            assert result['failed'] is True
201        assert 'msg' in result
202
203    @pytest.mark.parametrize("inp", [{"TypeId": 3000, "MembershipTypeId": 24},
204                                     {"TypeId": 1000, "MembershipTypeId": 24},
205                                     {"TypeId": 2000, "MembershipTypeId": 12}])
206    def test_validate_group_case01(self, inp, ome_response_mock):
207        group_resp = {"Id": 25011, "CreatedBy": "user", "TypeId": inp["TypeId"],
208                      "MembershipTypeId": inp["MembershipTypeId"]}
209        f_module = self.get_module_mock(params={"name": "group1",
210                                                "device_ids": [25011]})
211        with pytest.raises(Exception) as exc:
212            self.module.validate_group(group_resp, f_module, "name", "group1")
213        assert exc.value.args[0] == ADD_STATIC_GROUP_MESSAGE
214
215    @pytest.mark.parametrize("inp,out", [(['192.168.2.0'], [IPAddress('192.168.2.0')]),
216                                         (['fe80::ffff:ffff:ffff:ffff'], [IPAddress('fe80::ffff:ffff:ffff:ffff')]),
217                                         (['192.168.2.0/24'], [IPNetwork('192.168.2.0/24')]),
218                                         (['fe80::ffff:ffff:ffff:1111-fe80::ffff:ffff:ffff:ffff'],
219                                          [IPRange('fe80::ffff:ffff:ffff:1111', 'fe80::ffff:ffff:ffff:ffff')]),
220                                         (['192.168.2.0', 'fe80::ffff:ffff:ffff:ffff',
221                                           '192.168.2.0/24', 'fe80::ffff:ffff:ffff:1111-fe80::ffff:ffff:ffff:ffff',
222                                           '2002:c000:02e6::1/48'], [IPAddress('192.168.2.0'),
223                                                                     IPAddress('fe80::ffff:ffff:ffff:ffff'),
224                                                                     IPNetwork('192.168.2.0/24'),
225                                                                     IPRange('fe80::ffff:ffff:ffff:1111',
226                                                                             'fe80::ffff:ffff:ffff:ffff'),
227                                                                     IPNetwork(
228                                                                         '2002:c000:02e6::1/48')])])
229    def test_get_all_ips_success_case(self, inp, out):
230        f_module = self.get_module_mock(params={"name": "group1",
231                                                "ip_addresses": inp})
232        res = self.module.get_all_ips(inp, f_module)
233        assert res == out
234
235    @pytest.mark.parametrize("inp", [["abc"], [""], ["266.128"], ["100:1bcd:xyz"], ["192.168.0.0--192.168.0.1"],
236                                     ["-192.168.0.0-192.168.0.1"], ["-192.168.0.0192.168.0.1"],
237                                     ["192.168.0.0-192.168.0.1-"], ["192.168.0.0192.168.0.1-"],
238                                     ["192.168.0.1//24"],
239                                     ["\192.168.0.1//24"],
240                                     ["192.168.0.1/\24"],
241                                     ["/192.168.0.1/24"],
242                                     ["1.12.1.36/255.255.255.88"]],
243                             ids=["abc", "", "266.128", "100:1bcd:xyz", "192.168.0.0--192.168.0.1",
244                                  "-192.168.0.0-192.168.0.1", "-192.168.0.0192.168.0.1", "192.168.0.0-192.168.0.1-",
245                                  "192.168.0.0192.168.0.1-", "192.168.0.1//24", "\192.168.0.1//24",
246                                  "192.168.0.1/\24", "/192.168.0.1/24", "1.12.1.36/255.255.255.88"])
247    def test_get_all_ips_failure_case(self, inp):
248        f_module = self.get_module_mock(params={"name": "group1",
249                                                "ip_addresses": inp})
250        with pytest.raises(Exception, match=INVALID_IP_FORMAT.format(inp[0])) as err:
251            self.module.get_all_ips(inp, f_module)
252
253    def test_get_device_id_from_ip_success_case(self):
254        device_list = [
255            {
256                "Id": 1111,
257                "Identifier": "device1",
258                "DeviceServiceTag": "device1",
259                "DeviceManagement": [
260                    {
261                        "NetworkAddress": "192.168.2.255",
262                    }
263                ],
264            },
265            {
266                "Id": 2222,
267                "Identifier": "device2",
268                "DeviceServiceTag": "device2",
269                "DeviceManagement": [
270                    {
271                        "NetworkAddress": "192.168.4.10",
272                    }
273                ],
274            },
275            {
276                "Id": 3333,
277                "Identifier": "device3",
278                "DeviceServiceTag": "device3",
279                "DeviceManagement": [
280                    {
281                        "NetworkAddress": "192.168.2.10",
282                    }
283                ],
284            },
285            {
286                "Id": 4444,
287                "Identifier": "device4",
288                "DeviceServiceTag": "device4",
289                "DeviceManagement": [
290                    {
291                        "NetworkAddress": "192.168.3.10",
292                    }
293                ],
294            },
295            {
296                "Id": 5555,
297                "Identifier": "device5",
298                "DeviceServiceTag": "device5",
299                "DeviceManagement": [
300                    {
301                        "NetworkAddress": "192.168.4.3",
302                    }
303                ],
304            },
305            {
306                "Id": 6666,
307                "Identifier": "device6",
308                "DeviceServiceTag": "device6",
309                "DeviceManagement": [
310                    {
311                        "NetworkAddress": "192.168.3.11",
312                    }
313                ],
314            },
315            {
316                "Id": 7777,
317                "Identifier": "device7",
318                "DeviceServiceTag": "device7",
319                "DeviceManagement": [
320                    {
321                        "NetworkAddress": "192.168.3.0",
322                    }
323                ],
324            },
325            {
326                "Id": 8888,
327                "Identifier": "device8",
328                "DeviceServiceTag": "device8",
329                "DeviceManagement": [
330                    {
331                        "NetworkAddress": "192.168.4.1",
332                    }
333                ],
334            },
335            {
336                "Id": 9999,
337                "Identifier": "device9",
338                "DeviceServiceTag": "device9",
339                "DeviceManagement": [
340                    {
341                        "NetworkAddress": "192.168.4.5",
342                    }
343                ],
344            },
345            {
346                "Id": 1010,
347                "Identifier": "device10",
348                "DeviceServiceTag": "device10",
349                "DeviceManagement": [
350                    {
351                        "NetworkAddress": "192.168.4.9",
352                    }
353                ],
354            },
355            {
356                "Id": 1011,
357                "Identifier": "device11",
358                "DeviceServiceTag": "device11",
359                "DeviceManagement": [
360                    {
361                        "NetworkAddress": "[fe80::de0:b6b3:a764:0]",
362                    }
363                ],
364            },
365            {
366                "Id": 1012,
367                "Identifier": "device11",
368                "DeviceServiceTag": "device11",
369                "DeviceManagement": [
370                    {
371                        "NetworkAddress": "[fe90::de0:b6b3:a764:0]",
372                    }
373                ],
374            }
375        ]
376        output = {3333: "192.168.2.10", 4444: "192.168.3.10",
377                  5555: "192.168.4.3", 6666: "192.168.3.11", 7777: "192.168.3.0",
378                  8888: "192.168.4.1", 9999: "192.168.4.5", 1010: "192.168.4.9",
379                  1011: "fe80::de0:b6b3:a764:0"}
380        ip_addresses = [IPNetwork("::ffff:192.168.2.0/125"), IPAddress("192.168.2.10"),
381                        IPAddress('fe80::ffff:ffff:ffff:ffff'),
382                        IPNetwork('fe80::ffff:ffff:ffff:ffff/24'),
383                        IPNetwork('192.168.3.0/24'), IPRange('192.168.4.1', '192.168.4.9')]
384        f_module = self.get_module_mock(params={"name": "group1",
385                                                "ip_addresses": ["::ffff:192.168.2.0/125",
386                                                                 "192.168.2.10",
387                                                                 'fe80::ffff:ffff:ffff:ffff',
388                                                                 '192.168.3.0/24',
389                                                                 '192.168.4.1-192.168.4.9',
390                                                                 'fe80::ffff:ffff:ffff:ffff/24']})
391        res = self.module.get_device_id_from_ip(ip_addresses, device_list, f_module)
392        assert res == output
393
394    def test_get_device_id_from_ip_failure_case(self):
395        device_list = [
396            {
397                "Id": 1111,
398                "Identifier": "device1",
399                "DeviceServiceTag": "device1",
400                "DeviceManagement": [
401                    {
402                        "NetworkAddress": "192.168.2.255",
403                    }
404                ],
405            },
406        ]
407        ip_addresses = [IPNetwork("::ffff:192.168.2.0/125"), IPAddress("192.168.2.10"),
408                        IPAddress('fe80::ffff:ffff:ffff:ffff'),
409                        IPNetwork('fe80::ffff:ffff:ffff:ffff/24'),
410                        IPNetwork('192.168.3.0/24'), IPRange('192.168.4.1', '192.168.4.9')]
411        with pytest.raises(Exception, match=IP_NOT_EXISTS):
412            f_module = self.get_module_mock(params={"name": "group1",
413                                                    "ip_addresses": ["::ffff:192.168.2.0/125",
414                                                                     "192.168.2.10",
415                                                                     'fe80::ffff:ffff:ffff:ffff',
416                                                                     '192.168.3.0/24',
417                                                                     '192.168.4.1-192.168.4.9',
418                                                                     'fe80::ffff:ffff:ffff:ffff/24']})
419            self.module.get_device_id_from_ip(ip_addresses, device_list, f_module)
420
421    # def test_add_member_to_group_case01(self, ome_connection_mock_for_device_group, ome_response_mock):
422    #     report_list = [{"Id": 3333, "DeviceServiceTag": "device1",
423    #                     "DeviceManagement": [{"NetworkAddress": "192.168.2.10"},
424    #                                          ]},
425    #                    {"Id": 1013, "DeviceServiceTag": "device1",
426    #                     "DeviceManagement": [{"NetworkAddress": "192.168.5.10"},
427    #                                          ]}
428    #                    ]
429    #     ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
430    #     f_module = self.get_module_mock(params={"name": "group1",
431    #                                             "ip_addresses": ["::ffff:192.168.2.0/125",
432    #                                                              "192.168.2.10",
433    #                                                              'fe80::ffff:ffff:ffff:ffff',
434    #                                                              '192.168.3.0/24',
435    #                                                              '192.168.4.1-192.168.4.9',
436    #                                                              'fe80::ffff:ffff:ffff:ffff/24']})
437    #     device_id = {3333: "192.168.2.10", 4444: "192.168.3.10",
438    #                  5555: "192.168.4.3",
439    #                  1011: "fe80::de0:b6b3:a764:0"}
440    #     ome_response_mock.status_code = 204
441    #     added_ips_out = ["192.168.3.10", "192.168.4.3", "fe80::de0:b6b3:a764:0"]
442    #     resp, added_ips = self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group, 1, device_id,
443    #                                                       "IPAddresses")
444    #     assert resp.status_code == 204
445    #     assert added_ips == added_ips_out
446
447    def test_add_member_to_group_checkmode_case01(self, ome_connection_mock_for_device_group, ome_response_mock):
448        report_list = [{"Id": 3333, "DeviceServiceTag": "device1",
449                        "DeviceManagement": [{"NetworkAddress": "192.168.2.10"},
450                                             ]},
451                       {"Id": 1013, "DeviceServiceTag": "device1",
452                        "DeviceManagement": [{"NetworkAddress": "192.168.5.10"},
453                                             ]}
454                       ]
455        ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
456        f_module = self.get_module_mock(params={"name": "group1",
457                                                "ip_addresses": ["::ffff:192.168.2.0/125",
458                                                                 "192.168.2.10",
459                                                                 'fe80::ffff:ffff:ffff:ffff',
460                                                                 '192.168.3.0/24',
461                                                                 '192.168.4.1-192.168.4.9',
462                                                                 'fe80::ffff:ffff:ffff:ffff/24']}, check_mode=True)
463        device_id = {3333: "192.168.2.10", 4444: "192.168.3.10",
464                     5555: "192.168.4.3",
465                     1011: "fe80::de0:b6b3:a764:0"}
466        with pytest.raises(Exception, match="Changes found to be applied."):
467            self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group, 1, device_id, "IPAddresses")
468
469    def test_add_member_to_group_checkmode_case02(self, ome_connection_mock_for_device_group, ome_response_mock):
470        report_list = [{"Id": 3333, "DeviceServiceTag": "device1",
471                        "DeviceManagement": [{"NetworkAddress": "192.168.2.10"},
472                                             ]},
473                       {"Id": 1013, "DeviceServiceTag": "device1",
474                        "DeviceManagement": [{"NetworkAddress": "192.168.5.10"},
475                                             ]}
476                       ]
477        ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
478        f_module = self.get_module_mock(params={"name": "group1",
479                                                "ip_addresses": ["192.168.2.10"]}, check_mode=True)
480        device_id = {3333: "192.168.2.10"}
481        with pytest.raises(Exception, match="No changes found to be applied."):
482            self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group, 1, device_id, "IPAddresses")
483
484    def test_add_member_to_group_idempotency_case(self, ome_connection_mock_for_device_group, ome_response_mock):
485        report_list = [{"Id": 3333, "DeviceServiceTag": "device1",
486                        "DeviceManagement": [{"NetworkAddress": "192.168.2.10"},
487                                             ]},
488                       {"Id": 1013, "DeviceServiceTag": "device1",
489                        "DeviceManagement": [{"NetworkAddress": "192.168.5.10"},
490                                             ]}
491                       ]
492        ome_connection_mock_for_device_group.get_all_report_details.return_value = {"report_list": report_list}
493        f_module = self.get_module_mock(params={"name": "group1",
494                                                "ip_addresses": ["192.168.2.10"]})
495        device_id = {3333: "192.168.2.10"}
496        with pytest.raises(Exception) as exc:
497            self.module.add_member_to_group(f_module, ome_connection_mock_for_device_group, 1, device_id, "IPAddresses")
498
499        assert exc.value.args[0] == "No changes found to be applied."
500
501    def test_ome_device_group_main_ip_address_case(self, ome_connection_mock_for_device_group, mocker,
502                                                   ome_response_mock, ome_default_args):
503        ome_default_args.update({"name": "Storage Services", "ip_addresses": ["192.168.2.10"]})
504        ome_response_mock.status_code = 204
505        ome_response_mock.success = True
506        mocker.patch(MODULE_PATH + 'get_group_id', return_value=1)
507        mocker.patch(MODULE_PATH + 'get_device_id', return_value=[25011, 25012])
508        mocker.patch(MODULE_PATH + 'add_member_to_group', return_value=(ome_response_mock, ["192.168.2.10"]))
509        result = self._run_module(ome_default_args)
510        assert result['msg'] == "Successfully added member(s) to the device group."
511        assert result['ip_addresses_added'] == ["192.168.2.10"]
512
513    def test_get_device_id_ip_address_case(self, ome_connection_mock_for_device_group, mocker):
514        f_module = self.get_module_mock(params={"name": "group1",
515                                                "ip_addresses": ["192.168.2.10"]})
516        mocker.patch(MODULE_PATH + 'get_all_ips', return_value=[IPAddress("192.168.2.10")])
517        mocker.patch(MODULE_PATH + 'get_device_id_from_ip', return_value={1111: "192.168.2.10"})
518        each_device_list, key = self.module.get_device_id(ome_connection_mock_for_device_group, f_module)
519        assert key == "IPAddresses"
520        assert each_device_list == {1111: "192.168.2.10"}
521