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.bigip_iapp_template import ( 20 Parameters, ArgumentSpec, ModuleManager 21) 22from ansible_collections.f5networks.f5_modules.tests.unit.compat import unittest 23from ansible_collections.f5networks.f5_modules.tests.unit.compat.mock import Mock, patch 24from ansible_collections.f5networks.f5_modules.tests.unit.modules.utils import set_module_args 25 26 27fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') 28fixture_data = {} 29 30 31def load_fixture(name): 32 path = os.path.join(fixture_path, name) 33 34 if path in fixture_data: 35 return fixture_data[path] 36 37 with open(path) as f: 38 data = f.read() 39 40 try: 41 data = json.loads(data) 42 except Exception: 43 pass 44 45 fixture_data[path] = data 46 return data 47 48 49class TestParameters(unittest.TestCase): 50 def test_module_parameters(self): 51 iapp = load_fixture('create_iapp_template.iapp') 52 args = dict( 53 content=iapp 54 ) 55 p = Parameters(params=args) 56 assert p.name == 'foo.iapp' 57 58 def test_module_parameters_custom_name(self): 59 iapp = load_fixture('create_iapp_template.iapp') 60 args = dict( 61 content=iapp, 62 name='foobar' 63 ) 64 p = Parameters(params=args) 65 assert p.name == 'foobar' 66 assert 'sys application template /Common/foobar' in p.content 67 68 def test_module_parameters_custom_partition(self): 69 iapp = load_fixture('create_iapp_template.iapp') 70 args = dict( 71 content=iapp, 72 partition='foobar' 73 ) 74 p = Parameters(params=args) 75 assert p.name == 'foo.iapp' 76 assert 'sys application template /foobar/foo.iapp' in p.content 77 78 79class TestManager(unittest.TestCase): 80 def setUp(self): 81 self.spec = ArgumentSpec() 82 self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_iapp_template.tmos_version') 83 self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_iapp_template.send_teem') 84 self.m2 = self.p2.start() 85 self.m2.return_value = '14.1.0' 86 self.m3 = self.p3.start() 87 self.m3.return_value = True 88 89 def tearDown(self): 90 self.p2.stop() 91 self.p3.stop() 92 93 def test_create_iapp_template(self, *args): 94 # Configure the arguments that would be sent to the Ansible module 95 set_module_args(dict( 96 content=load_fixture('basic-iapp.tmpl'), 97 provider=dict( 98 server='localhost', 99 password='password', 100 user='admin' 101 ) 102 )) 103 104 module = AnsibleModule( 105 argument_spec=self.spec.argument_spec, 106 supports_check_mode=self.spec.supports_check_mode 107 ) 108 mm = ModuleManager(module=module) 109 110 # Override methods to force specific logic in the module to happen 111 mm.exists = Mock(side_effect=[False, True]) 112 mm.create_on_device = Mock(return_value=True) 113 114 results = mm.exec_module() 115 116 assert results['changed'] is True 117 118 def test_update_iapp_template(self, *args): 119 # Configure the arguments that would be sent to the Ansible module 120 set_module_args(dict( 121 content=load_fixture('basic-iapp.tmpl'), 122 provider=dict( 123 server='localhost', 124 password='password', 125 user='admin' 126 ) 127 )) 128 129 current1 = Parameters(params=load_fixture('load_sys_application_template_w_new_checksum.json')) 130 current2 = Parameters(params=load_fixture('load_sys_application_template_w_old_checksum.json')) 131 module = AnsibleModule( 132 argument_spec=self.spec.argument_spec, 133 supports_check_mode=self.spec.supports_check_mode 134 ) 135 mm = ModuleManager(module=module) 136 137 # Override methods to force specific logic in the module to happen 138 mm.exists = Mock(side_effect=[True, True]) 139 mm.create_on_device = Mock(return_value=True) 140 mm.read_current_from_device = Mock(return_value=current1) 141 mm.template_in_use = Mock(return_value=False) 142 mm._get_temporary_template = Mock(return_value=current2) 143 mm._remove_iapp_checksum = Mock(return_value=None) 144 mm._generate_template_checksum_on_device = Mock(return_value=None) 145 146 results = mm.exec_module() 147 148 assert results['changed'] is True 149 150 def test_delete_iapp_template(self, *args): 151 set_module_args(dict( 152 content=load_fixture('basic-iapp.tmpl'), 153 state='absent', 154 provider=dict( 155 server='localhost', 156 password='password', 157 user='admin' 158 ) 159 )) 160 161 module = AnsibleModule( 162 argument_spec=self.spec.argument_spec, 163 supports_check_mode=self.spec.supports_check_mode 164 ) 165 mm = ModuleManager(module=module) 166 167 # Override methods to force specific logic in the module to happen 168 mm.exists = Mock(side_effect=[True, False]) 169 mm.remove_from_device = Mock(return_value=True) 170 171 results = mm.exec_module() 172 173 assert results['changed'] is True 174 175 def test_delete_iapp_template_idempotent(self, *args): 176 set_module_args(dict( 177 content=load_fixture('basic-iapp.tmpl'), 178 state='absent', 179 provider=dict( 180 server='localhost', 181 password='password', 182 user='admin' 183 ) 184 )) 185 186 module = AnsibleModule( 187 argument_spec=self.spec.argument_spec, 188 supports_check_mode=self.spec.supports_check_mode 189 ) 190 mm = ModuleManager(module=module) 191 192 # Override methods to force specific logic in the module to happen 193 mm.exists = Mock(side_effect=[False, False]) 194 195 results = mm.exec_module() 196 197 assert results['changed'] is False 198