# test code for the mysql_variables module
# (c) 2014,  Wayne Rosario <wrosario@ansible.com>

# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

# ============================================================
# Verify mysql_variable successfully queries a variable
#
- set_fact: set_name='version'

- name: read mysql variables (expect changed=false)
  mysql_variables:
    variable: '{{set_name}}'
    login_unix_socket: '{{ mysql_socket }}'
  register: result

- include: assert_var_output.yml changed=false output={{result}} var_name={{set_name}}

# ============================================================
# Verify mysql_variable successfully updates a variable (issue:4568)
#
- set_fact:
     set_name: 'delay_key_write'
     set_value: 'ON'

- name: set mysql variable
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_unix_socket: '{{ mysql_socket }}'

- name: update mysql variable to same value (expect changed=false)
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_unix_socket: '{{ mysql_socket }}'
  register: result

- include: assert_var.yml changed=false output={{result}} var_name={{set_name}} var_value={{set_value}}

# ============================================================
# Verify mysql_variable successfully updates a variable using single quotes
#
- set_fact:
     set_name: 'wait_timeout'
     set_value: '300'

- name: set mysql variable to a temp value
  mysql_variables:
    variable: '{{set_name}}'
    value: '200'
    login_unix_socket: '{{ mysql_socket }}'

- name: update mysql variable value (expect changed=true)
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_unix_socket: '{{ mysql_socket }}'
  register: result

- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}'

# ============================================================
# Verify mysql_variable successfully updates a variable using double quotes
#
- set_fact:
     set_name: "wait_timeout"
     set_value: "400"

- name: set mysql variable to a temp value
  mysql_variables:
    variable: '{{set_name}}'
    value: "200"
    login_unix_socket: '{{ mysql_socket }}'

- name: update mysql variable value (expect changed=true)
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_unix_socket: '{{ mysql_socket }}'
  register: result

- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}'

# ============================================================
# Verify mysql_variable successfully updates a variable using no quotes
#
- set_fact:
     set_name: wait_timeout
     set_value: 500

- name: set mysql variable to a temp value
  mysql_variables:
    variable: '{{set_name}}'
    value: 200
    login_unix_socket: '{{ mysql_socket }}'

- name: update mysql variable value (expect changed=true)
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_unix_socket: '{{ mysql_socket }}'
  register: result

- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}'

# ============================================================
# Verify mysql_variable successfully updates a variable using an expression (e.g. 1024*4)
#
- name: set mysql variable value to an expression
  mysql_variables:
    variable: max_tmp_tables
    value: "1024*4"
    login_unix_socket: '{{ mysql_socket }}'
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='Incorrect argument type to variable'

# ============================================================
# Verify mysql_variable fails when setting an incorrect value (out of range)
#
# This test started failing on RHEL 8 randomly, even though no packages saw an
# update and nothing else seems to have changed. Several of us were unable to
# pinpoint the root cause of the issue, so for now we just skip RHEL 8 for this
# particular check.
- name: set mysql variable value to a number out of range
  mysql_variables:
    variable: max_tmp_tables
    value: -1
    login_unix_socket: '{{ mysql_socket }}'
  register: result
  ignore_errors: true
  when:
    - not (ansible_facts.os_family == 'RedHat' and ansible_distribution_major_version is version('8', '=='))

- include: assert_fail_msg.yml output={{result}}  msg='Truncated incorrect'
  when:
    - not (ansible_facts.os_family == 'RedHat' and ansible_distribution_major_version is version('8', '=='))

# ============================================================
# Verify mysql_variable fails when setting an incorrect value (incorrect type)
#
- name: set mysql variable value to a non-valid value number
  mysql_variables:
    variable: max_tmp_tables
    value: TEST
    login_unix_socket: '{{ mysql_socket }}'
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='Incorrect argument type to variable'

# ============================================================
# Verify mysql_variable fails when setting an unknown variable
#
- name: set a non mysql variable
  mysql_variables:
    variable: my_sql_variable
    value: ON
    login_unix_socket: '{{ mysql_socket }}'
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='Variable not available'

# ============================================================
# Verify mysql_variable fails when setting a read-only variable
#
- name: set value of a read only mysql variable
  mysql_variables:
    variable: character_set_system
    value: utf16
    login_unix_socket: '{{ mysql_socket }}'
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='read only variable'

#=============================================================
# Verify mysql_variable works with the login_user and login_password parameters
#
- name: create mysql user
  mysql_user:
    name: '{{user}}'
    password: '{{password}}'
    state: present
    priv: '*.*:ALL'
    login_unix_socket: '{{ mysql_socket }}'

- set_fact:
     set_name: wait_timeout
     set_value: 77

- name: query mysql_variable using login_user and password_password
  mysql_variables:
    variable: '{{set_name}}'
    login_user: '{{user}}'
    login_password: '{{password}}'
  register: result

- include: assert_var_output.yml changed=false output={{result}} var_name={{set_name}}

- name: set mysql variable to temp value using user login and password (expect changed=true)
  mysql_variables:
    variable: '{{set_name}}'
    value: 20
    login_user: '{{user}}'
    login_password: '{{password}}'
  register: result

- name: update mysql variable value using user login and password (expect changed=true)
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_user: '{{user}}'
    login_password: '{{password}}'
  register: result

- include: assert_var.yml changed=true output={{result}} var_name={{set_name}} var_value='{{set_value}}'

#============================================================
# Verify mysql_variable fails with an incorrect login_password parameter
#
- set_fact:
     set_name: connect_timeout
     set_value: 10

- name: query mysql_variable using incorrect login_password
  mysql_variables:
    variable: '{{set_name}}'
    login_user: '{{user}}'
    login_password: 'wrongpassword'
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='unable to connect to database'

- name: update mysql variable value using incorrect login_password (expect failed=true)
  mysql_variables:
    variable: '{{set_name}}'
    value: '{{set_value}}'
    login_user: '{{user}}'
    login_password: 'this is an incorrect password'
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='unable to connect to database'

#============================================================
# Verify mysql_variable fails with an incorrect login_host parameter
#
- name: query mysql_variable using incorrect login_host
  mysql_variables:
    variable: wait_timeout
    login_host: '12.0.0.9'
    login_user: '{{user}}'
    login_password: '{{password}}'
    connect_timeout: 5
  register: result
  ignore_errors: true

- include: assert_fail_msg.yml output={{result}}  msg='unable to connect to database'

- name: remove mysql_user {{user}}
  mysql_user:
    name: '{{user}}'
    state: absent
    login_unix_socket: '{{ mysql_socket }}'
