def test_wait_ssh_ready(self, *args):
        """ Wait till tenant accepts ssh connections. """
        set_module_args(dict(name='defaultbip', state='ssh-ready'))

        module = AnsibleModule(
            argument_spec=self.spec.argument_spec,
            supports_check_mode=self.spec.supports_check_mode)

        # Override methods to force specific logic in the module to happen
        mm = ModuleManager(module=module)
        mm.tenant_exists = Mock(side_effect=[True, True])
        deployed_state = load_fixture('load_tenant_state_deployed.json')
        mm.read_tenant_from_device = Mock(return_value=deployed_state)

        # Simulate the first ssh connection attempt raises an SSHExecption
        # indicating ssh is not ready, followed by a second connection which
        # raises AuthenticationException, indicating ssh server is up.
        with patch.object(paramiko, 'SSHClient', autospec=True) as mock_ssh:
            mocked_client = MagicMock()
            attrs = {
                'connect.side_effect': [
                    paramiko.ssh_exception.SSHException,
                    paramiko.ssh_exception.AuthenticationException
                ]
            }
            mocked_client.configure_mock(**attrs)
            mock_ssh.return_value = mocked_client

            results = mm.exec_module()
            assert results['changed'] is False
            assert mm.tenant_exists.call_count == 2
            assert mocked_client.connect.call_count == 2
    def test_timeout_elapsed(self, *args):
        set_module_args(dict(name='defaultbip', state='configured', timeout=2))

        module = AnsibleModule(
            argument_spec=self.spec.argument_spec,
            supports_check_mode=self.spec.supports_check_mode)

        # Override methods to force specific logic in the module to happen
        mm = ModuleManager(module=module)
        mm.tenant_exists = Mock(side_effect=[False, False, False])

        with self.assertRaises(AnsibleFailJson):
            mm.exec_module()
    def test_invalid_timeout(self, *args):
        set_module_args(
            dict(name='defaultbip',
                 state='configured',
                 delay=1,
                 sleep=3,
                 timeout=2))

        module = AnsibleModule(
            argument_spec=self.spec.argument_spec,
            supports_check_mode=self.spec.supports_check_mode)

        # Override methods to force specific logic in the module to happen
        mm = ModuleManager(module=module)
        mm.tenant_exists = Mock(side_effect=[False, False, False])

        with self.assertRaises(F5ModuleError):
            # exception: The combined delay and sleep should not be greater than or equal to the timeout.
            mm.exec_module()
    def test_wait_provisioned(self, *args):
        """ Transition from configured to provisioned state. """
        set_module_args(dict(name='defaultbip', state='provisioned'))

        module = AnsibleModule(
            argument_spec=self.spec.argument_spec,
            supports_check_mode=self.spec.supports_check_mode)

        # Override methods to force specific logic in the module to happen
        mm = ModuleManager(module=module)
        mm.tenant_exists = Mock(side_effect=[True, True])
        configured_state = load_fixture('load_tenant_state_configured.json')
        provisioned_state = load_fixture('load_tenant_state_provisioned.json')
        mm.read_tenant_from_device = Mock(
            side_effect=[configured_state, provisioned_state])

        results = mm.exec_module()
        assert results['changed'] is False
        assert mm.tenant_exists.call_count == 2
        assert mm.read_tenant_from_device.call_count == 2
    def test_wait_configured(self, *args):
        """ Transition from configured to provisioned state. """
        set_module_args(dict(name='defaultbip', state='configured'))

        module = AnsibleModule(
            argument_spec=self.spec.argument_spec,
            supports_check_mode=self.spec.supports_check_mode)

        # Override methods to force specific logic in the module to happen
        mm = ModuleManager(module=module)
        # Simulate the tenant is not present until the 3rd loop iteration at
        # which time it is present and in the configured state.
        mm.tenant_exists = Mock(side_effect=[False, False, True])
        configured_state = load_fixture('load_tenant_state_configured.json')
        mm.read_tenant_from_device = Mock(return_value=configured_state)

        results = mm.exec_module()
        assert results['changed'] is False
        assert results['elapsed'] >= 2
        assert mm.tenant_exists.called
        assert mm.read_tenant_from_device.called