1# -*- coding: utf-8 -*-
2#
3# Copyright: (c) 2017, F5 Networks Inc.
4# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
6from __future__ import (absolute_import, division, print_function)
7__metaclass__ = type
8
9import os
10import json
11import pytest
12import sys
13
14if sys.version_info < (2, 7):
15    pytestmark = pytest.mark.skip("F5 Ansible modules require Python >= 2.7")
16
17from ansible.module_utils.basic import AnsibleModule
18
19from ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_fastl4_udp import (
20    ModuleParameters, ModuleManager, ArgumentSpec
21)
22from ansible_collections.f5networks.f5_modules.plugins.module_utils.common import F5ModuleError
23from ansible_collections.f5networks.f5_modules.tests.unit.compat import unittest
24from ansible_collections.f5networks.f5_modules.tests.unit.compat.mock import Mock, patch
25from ansible_collections.f5networks.f5_modules.tests.unit.modules.utils import set_module_args
26
27
28fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
29fixture_data = {}
30
31
32def load_fixture(name):
33    path = os.path.join(fixture_path, name)
34
35    if path in fixture_data:
36        return fixture_data[path]
37
38    with open(path) as f:
39        data = f.read()
40
41    try:
42        data = json.loads(data)
43    except Exception:
44        pass
45
46    fixture_data[path] = data
47    return data
48
49
50class TestParameters(unittest.TestCase):
51    def test_module_parameters(self):
52        args = dict(
53            name='foo',
54            description='my description',
55            service_environment='bar',
56            servers=[
57                dict(
58                    address='1.2.3.4',
59                    port=8080
60                ),
61                dict(
62                    address='5.6.7.8',
63                    port=8000
64                )
65            ],
66            inbound_virtual=dict(
67                address='2.2.2.2',
68                netmask='255.255.255.255',
69                port=80
70            )
71        )
72
73        p = ModuleParameters(params=args)
74        assert p.name == 'foo'
75        assert p.config_set_name == 'foo'
76        assert p.sub_path == 'foo'
77        assert p.http_profile == 'profile_http'
78        assert p.service_environment == 'bar'
79        assert len(p.servers) == 2
80        assert 'address' in p.servers[0]
81        assert 'port' in p.servers[0]
82        assert 'address' in p.servers[1]
83        assert 'port' in p.servers[1]
84        assert p.servers[0]['address'] == '1.2.3.4'
85        assert p.servers[0]['port'] == 8080
86        assert p.servers[1]['address'] == '5.6.7.8'
87        assert p.servers[1]['port'] == 8000
88        assert 'address' in p.inbound_virtual
89        assert 'netmask' in p.inbound_virtual
90        assert 'port' in p.inbound_virtual
91        assert p.inbound_virtual['address'] == '2.2.2.2'
92        assert p.inbound_virtual['netmask'] == '255.255.255.255'
93        assert p.inbound_virtual['port'] == 80
94
95
96class TestManager(unittest.TestCase):
97    def setUp(self):
98        self.spec = ArgumentSpec()
99        self.patcher1 = patch('time.sleep')
100        self.patcher1.start()
101
102        self.p1 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_fastl4_udp.bigiq_version')
103        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_fastl4_udp.ModuleParameters.template_reference')
104        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_fastl4_udp.ModuleParameters.default_device_reference')
105
106        self.m1 = self.p1.start()
107        self.m2 = self.p2.start()
108        self.m3 = self.p3.start()
109
110        self.m1.return_value = '6.1.0'
111        self.m2.return_value = Mock(return_value='https://localhost/mgmt/foobar1')
112        self.m3.return_value = Mock(return_value='https://localhost/mgmt/foobar3')
113        self.p5 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_fastl4_udp.send_teem')
114        self.m5 = self.p5.start()
115        self.m5.return_value = True
116
117    def tearDown(self):
118        self.patcher1.stop()
119        self.p1.stop()
120        self.p2.stop()
121        self.p3.stop()
122        self.p5.stop()
123
124    def test_create(self, *args):
125        set_module_args(dict(
126            name='foo',
127            description='my description',
128            service_environment='bar',
129            servers=[
130                dict(
131                    address='1.2.3.4',
132                    port=8080
133                ),
134                dict(
135                    address='5.6.7.8',
136                    port=8000
137                )
138            ],
139            inbound_virtual=dict(
140                address='2.2.2.2',
141                netmask='255.255.255.255',
142                port=80
143            ),
144            provider=dict(
145                server='localhost',
146                password='password',
147                user='admin'
148            )
149        ))
150
151        module = AnsibleModule(
152            argument_spec=self.spec.argument_spec,
153            supports_check_mode=self.spec.supports_check_mode
154        )
155
156        # Override methods to force specific logic in the module to happen
157        mm = ModuleManager(module=module)
158        mm.check_bigiq_version = Mock(return_value=True)
159        mm.has_no_service_environment = Mock(return_value=False)
160        mm.wait_for_apply_template_task = Mock(return_value=True)
161
162        mm.create_on_device = Mock(return_value=True)
163        mm.exists = Mock(side_effect=[False, True])
164
165        results = mm.exec_module()
166
167        assert results['changed'] is True
168        assert results['description'] == 'my description'
169
170    def test_bigiq_version_raises(self):
171        set_module_args(dict(
172            name='foo',
173            description='my description',
174            service_environment='bar',
175            servers=[
176                dict(
177                    address='1.2.3.4',
178                    port=8080
179                ),
180                dict(
181                    address='5.6.7.8',
182                    port=8000
183                )
184            ],
185            inbound_virtual=dict(
186                address='2.2.2.2',
187                netmask='255.255.255.255',
188                port=80
189            ),
190            provider=dict(
191                server='localhost',
192                password='password',
193                user='admin'
194            )
195        ))
196
197        module = AnsibleModule(
198            argument_spec=self.spec.argument_spec,
199            supports_check_mode=self.spec.supports_check_mode
200        )
201
202        msg = 'Module supports only BIGIQ version 6.0.x or lower.'
203        # Override methods to force specific logic in the module to happen
204        mm = ModuleManager(module=module)
205
206        with pytest.raises(F5ModuleError) as err:
207            mm.exec_module()
208        assert str(err.value) == msg
209