Migrate mysql execution and state tests to functional tests.

-----

As an added bonus, running mysql module integration tests:
```
=== 195 passed, 2 warnings in 2067.57s (0:34:27) ===
```
as functional tests:
```
=== 195 passed, 5 warnings in 222.23s (0:03:42) ===
```

-----

As an added bonus, running mysql state integration tests:
```
=== 62 passed, 3 skipped, 2 warnings in 576.79s (0:09:36) ===
```
as functional tests:
```
=== 62 passed, 3 skipped, 5 warnings in 253.27s (0:04:13) ===
```

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>
This commit is contained in:
Pedro Algarvio 2022-07-04 15:09:19 +01:00 committed by Gareth J. Greenaway
parent 837160019a
commit 81d3112046
6 changed files with 727 additions and 785 deletions

View file

@ -323,8 +323,8 @@ tests/support/mock.py:
- unit.test_mock
tests/support/pytest/mysql.py:
- pytests.integration.states.test_mysql
- pytests.integration.modules.test_mysql
- pytests.functional.states.test_mysql
- pytests.functional.modules.test_mysql
tests/pytests/scenarios/multimaster:
- pytests.scenarios.multimaster.test_multimaster

View file

@ -0,0 +1,466 @@
"""
Test Salt MySQL module across various MySQL variants
"""
import logging
import pytest
import salt.modules.mysql as mysqlmod
from tests.support.pytest.mysql import * # pylint: disable=wildcard-import,unused-wildcard-import
log = logging.getLogger(__name__)
pytestmark = [
pytest.mark.slow_test,
pytest.mark.skip_if_binaries_missing("dockerd"),
pytest.mark.skipif(
mysqlmod.MySQLdb is None, reason="No python mysql client installed."
),
]
class CallWrapper:
def __init__(self, func, container):
self.func = func
self.container = container
def __call__(self, *args, **kwargs):
kwargs.update(self.container.get_credentials(**kwargs))
return self.func(*args, **kwargs)
@pytest.fixture(scope="module")
def mysql(modules, mysql_container):
for name in list(modules):
if not name.startswith("mysql."):
continue
modules._dict[name] = CallWrapper(
modules._dict[name],
mysql_container,
)
return modules.mysql
def test_query(mysql):
ret = mysql.query("mysql", "SELECT 1")
assert ret
assert ret["results"] == (("1",),)
def test_version(mysql, mysql_container):
ret = mysql.version()
assert ret
assert mysql_container.mysql_version in ret
def test_status(mysql):
ret = mysql.status()
assert ret
def test_db_list(mysql):
ret = mysql.db_list()
assert ret
assert "mysql" in ret
def test_db_create_alter_remove(mysql):
ret = mysql.db_create("salt")
assert ret
ret = mysql.alter_db(
name="salt",
character_set="latin1",
collate="latin1_general_ci",
)
assert ret
ret = mysql.db_remove(name="salt")
assert ret
def test_user_list(mysql, mysql_combo):
ret = mysql.user_list()
assert ret
assert {
"User": mysql_combo.mysql_root_user,
"Host": mysql_combo.mysql_host,
} in ret
def test_user_exists(mysql, mysql_combo):
ret = mysql.user_exists(
mysql_combo.mysql_root_user,
host=mysql_combo.mysql_host,
password=mysql_combo.mysql_passwd,
)
assert ret
ret = mysql.user_exists(
"george",
"hostname",
"badpassword",
)
assert not ret
def test_user_info(mysql, mysql_combo):
ret = mysql.user_info(mysql_combo.mysql_root_user, host=mysql_combo.mysql_host)
assert ret
# Check that a subset of the information
# is available in the returned user information.
expected = {
"Host": mysql_combo.mysql_host,
"User": mysql_combo.mysql_root_user,
"Select_priv": "Y",
"Insert_priv": "Y",
"Update_priv": "Y",
"Delete_priv": "Y",
"Create_priv": "Y",
"Drop_priv": "Y",
"Reload_priv": "Y",
"Shutdown_priv": "Y",
"Process_priv": "Y",
"File_priv": "Y",
"Grant_priv": "Y",
"References_priv": "Y",
"Index_priv": "Y",
"Alter_priv": "Y",
"Show_db_priv": "Y",
"Super_priv": "Y",
"Create_tmp_table_priv": "Y",
"Lock_tables_priv": "Y",
"Execute_priv": "Y",
"Repl_slave_priv": "Y",
"Repl_client_priv": "Y",
"Create_view_priv": "Y",
"Show_view_priv": "Y",
"Create_routine_priv": "Y",
"Alter_routine_priv": "Y",
"Create_user_priv": "Y",
"Event_priv": "Y",
"Trigger_priv": "Y",
"Create_tablespace_priv": "Y",
}
data = ret.copy()
for key in list(data):
if key not in expected:
data.pop(key)
assert data == expected
def test_user_create_chpass_delete(mysql):
ret = mysql.user_create(
"george",
host="localhost",
password="badpassword",
)
assert ret
ret = mysql.user_chpass(
"george",
host="localhost",
password="different_password",
)
assert ret
ret = mysql.user_remove("george", host="localhost")
assert ret
def test_user_grants(mysql, mysql_combo):
ret = mysql.user_grants(mysql_combo.mysql_root_user, host=mysql_combo.mysql_host)
assert ret
def test_grant_add_revoke(mysql):
# Create the database
ret = mysql.db_create("salt")
assert ret
# Create a user
ret = mysql.user_create(
"george",
host="localhost",
password="badpassword",
)
assert ret
# Grant privileges to user to specific table
ret = mysql.grant_add(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert ret
# Check the grant exists
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert ret
# Revoke the grant
ret = mysql.grant_revoke(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert ret
# Check the grant does not exist
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert not ret
# Grant privileges to user globally
ret = mysql.grant_add(
grant="ALL PRIVILEGES",
database="*.*",
user="george",
host="localhost",
)
assert ret
# Check the global exists
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="*.*",
user="george",
host="localhost",
)
assert ret
# Revoke the global grant
ret = mysql.grant_revoke(
grant="ALL PRIVILEGES",
database="*.*",
user="george",
host="localhost",
)
assert ret
# Check the grant does not exist
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert not ret
# Remove the user
ret = mysql.user_remove("george", host="localhost")
assert ret
# Remove the database
ret = mysql.db_remove("salt")
assert ret
def test_plugin_add_status_remove(mysql, mysql_combo):
if "mariadb" in mysql_combo.mysql_name:
plugin = "simple_password_check"
else:
plugin = "auth_socket"
ret = mysql.plugin_status(plugin, host=mysql_combo.mysql_host)
assert not ret
ret = mysql.plugin_add(plugin)
assert ret
ret = mysql.plugin_status(plugin, host=mysql_combo.mysql_host)
assert ret
assert ret == "ACTIVE"
ret = mysql.plugin_remove(plugin)
assert ret
ret = mysql.plugin_status(plugin, host=mysql_combo.mysql_host)
assert not ret
def test_plugin_list(mysql, mysql_container):
if "mariadb" in mysql_container.mysql_name:
plugin = "simple_password_check"
else:
plugin = "auth_socket"
ret = mysql.plugins_list()
assert {"name": plugin, "status": "ACTIVE"} not in ret
assert ret
ret = mysql.plugin_add(plugin)
assert ret
ret = mysql.plugins_list()
assert ret
assert {"name": plugin, "status": "ACTIVE"} in ret
ret = mysql.plugin_remove(plugin)
assert ret
def test_grant_add_revoke_password_hash(mysql):
# Create the database
ret = mysql.db_create("salt")
assert ret
# Create a user
ret = mysql.user_create(
"george",
host="%",
password_hash="*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19",
)
assert ret
# Grant privileges to user to specific table
ret = mysql.grant_add(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret
# Check the grant exists
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret
# Check the grant exists via a query
ret = mysql.query(
database="salt",
query="SELECT 1",
connection_user="george",
connection_pass="password",
connection_db="salt",
)
assert ret
# Revoke the grant
ret = mysql.grant_revoke(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret
# Check the grant does not exist
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert not ret
# Remove the user
ret = mysql.user_remove("george", host="%")
assert ret
# Remove the database
ret = mysql.db_remove("salt")
assert ret
def test_create_alter_password_hash(mysql):
# Create the database
ret = mysql.db_create("salt")
assert ret
# Create a user
ret = mysql.user_create(
"george",
host="%",
password_hash="*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19",
)
assert ret
# Grant privileges to user to specific table
ret = mysql.grant_add(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret
# Check the grant exists
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret
# Check we can query as the new user
ret = mysql.query(
database="salt",
query="SELECT 1",
connection_user="george",
connection_pass="password",
connection_db="salt",
)
assert ret
# Change the user password
ret = mysql.user_chpass(
"george",
host="%",
password_hash="*F4A5147613F01DEC0C5226BF24CD1D5762E6AAF2",
)
assert ret
# Check we can query with the new password
ret = mysql.query(
database="salt",
query="SELECT 1",
connection_user="george",
connection_pass="badpassword",
connection_db="salt",
)
assert ret
# Revoke the grant
ret = mysql.grant_revoke(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret
# Check the grant does not exist
ret = mysql.grant_exists(
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert not ret
# Remove the user
ret = mysql.user_remove("george", host="%")
assert ret
# Remove the database
ret = mysql.db_remove("salt")
assert ret

View file

@ -0,0 +1,251 @@
"""
Test Salt MySQL state module across various MySQL variants
"""
import logging
import pytest
import salt.modules.mysql as mysqlmod
from saltfactories.utils.functional import StateResult
from tests.support.pytest.mysql import * # pylint: disable=wildcard-import,unused-wildcard-import
log = logging.getLogger(__name__)
pytestmark = [
pytest.mark.slow_test,
pytest.mark.skip_if_binaries_missing("dockerd"),
pytest.mark.skipif(
mysqlmod.MySQLdb is None, reason="No python mysql client installed."
),
]
class CallWrapper:
def __init__(self, func, container):
self.func = func
self.container = container
def __call__(self, *args, **kwargs):
kwargs.update(self.container.get_credentials(**kwargs))
return self.func(*args, **kwargs)
class StateSingleWrapper:
def __init__(self, func, container):
self.func = func
self.container = container
def __call__(self, statefunc, *args, **kwargs):
if statefunc.startswith("mysql_"):
kwargs.update(self.container.get_credentials(**kwargs))
ret = self.func(statefunc, *args, **kwargs)
if isinstance(ret, StateResult):
# Sadly, because we're wrapping, we need to return the raw
# attribute for a StateResult class to be recreated.
return ret.raw
return ret
@pytest.fixture(scope="module")
def mysql(modules, mysql_container):
for name in list(modules):
if name.startswith("mysql."):
modules._dict[name] = CallWrapper(
modules._dict[name],
mysql_container,
)
if name == "state.single":
modules._dict[name] = StateSingleWrapper(
modules._dict[name],
mysql_container,
)
return modules.mysql
@pytest.fixture(scope="module")
def mysql_states(mysql, states, mysql_container):
# Just so we also have the container running
return states
@pytest.fixture(scope="module")
def mysql_user(mysql_states):
return mysql_states.mysql_user
@pytest.fixture(scope="module")
def mysql_query(mysql_states):
return mysql_states.mysql_query
@pytest.fixture(scope="module")
def mysql_grants(mysql_states):
return mysql_states.mysql_grants
@pytest.fixture(scope="module")
def mysql_database(mysql_states):
return mysql_states.mysql_database
def test_database_present_absent(mysql_database):
ret = mysql_database.present(name="test_database")
assert ret.changes
assert ret.changes == {"test_database": "Present"}
assert ret.comment
assert ret.comment == "The database test_database has been created"
ret = mysql_database.absent(name="test_database")
assert ret.changes
assert ret.changes == {"test_database": "Absent"}
assert ret.comment
assert ret.comment == "Database test_database has been removed"
def test_grants_present_absent(mysql, mysql_grants):
# Create the database
ret = mysql.db_create("salt")
assert ret
# Create a user
ret = mysql.user_create(
"george",
host="localhost",
password="badpassword",
)
assert ret
try:
ret = mysql_grants.present(
name="add_salt_grants",
grant="select,insert,update",
database="salt.*",
user="george",
host="localhost",
)
assert ret.changes
assert ret.changes == {"add_salt_grants": "Present"}
assert ret.comment
assert (
ret.comment
== "Grant select,insert,update on salt.* to george@localhost has been added"
)
ret = mysql_grants.absent(
name="delete_salt_grants",
grant="select,insert,update",
database="salt.*",
user="george",
host="localhost",
)
assert ret.changes
assert ret.changes == {"delete_salt_grants": "Absent"}
assert ret.comment
assert (
ret.comment
== "Grant select,insert,update on salt.* for george@localhost has been revoked"
)
finally:
# Remove the user
ret = mysql.user_remove("george", host="localhost")
assert ret
# Remove the database
ret = mysql.db_remove("salt")
assert ret
def test_user_present_absent(mysql_user):
ret = mysql_user.present(
name="george",
host="localhost",
password="password",
)
assert ret.changes
assert ret.changes == {"george": "Present"}
assert ret.comment
assert ret.comment == "The user george@localhost has been added"
ret = mysql_user.absent(
name="george",
host="localhost",
)
assert ret.changes
assert ret.changes == {"george": "Absent"}
assert ret.comment
assert ret.comment == "User george@localhost has been removed"
def test_user_present_absent_passwordless(mysql_user):
ret = mysql_user.present(
name="george",
host="localhost",
allow_passwordless=True,
)
assert ret.changes
assert ret.changes == {"george": "Present"}
assert ret.comment
assert (
ret.comment
== "The user george@localhost has been added with passwordless login"
)
ret = mysql_user.absent(
name="george",
host="localhost",
)
assert ret.changes
assert ret.changes == {"george": "Absent"}
assert ret.comment
assert ret.comment == "User george@localhost has been removed"
def test_user_present_absent_unixsocket(mysql, mysql_user, mysql_container):
# The auth_socket plugin on MariaDB is unavailable
# on versions 10.1 - 10.3
if "mariadb" in mysql_container.mysql_name:
if mysql_container.mysql_version in ("10.1", "10.2", "10.3"):
pytest.skip(
"The auth_socket plugin is unavaiable "
"for the {}:{} docker image.".format(
mysql_container.mysql_name, mysql_container.mysql_version
)
)
# enable the auth_socket plugin on MySQL
# already enabled on MariaDB > 10.3
try:
if "mariadb" not in mysql_container.mysql_name:
ret = mysql.plugin_add("auth_socket")
assert ret
ret = mysql_user.present(
name="george",
host="localhost",
unix_socket=True,
allow_passwordless=False,
)
assert ret.changes
assert ret.changes == {"george": "Present"}
assert ret.comment
assert (
ret.comment == "The user george@localhost has been added using unix_socket"
)
ret = mysql_user.absent(
name="george",
host="localhost",
)
assert ret.changes
assert ret.changes == {"george": "Absent"}
assert ret.comment
assert ret.comment == "User george@localhost has been removed"
finally:
if "mariadb" not in mysql_container.mysql_name:
ret = mysql.plugin_remove("auth_socket")
assert ret

View file

@ -1,507 +0,0 @@
"""
Test Salt MySQL module across various MySQL variants
"""
import logging
import pytest
import salt.modules.mysql as mysql
from tests.support.pytest.mysql import * # pylint: disable=wildcard-import,unused-wildcard-import
log = logging.getLogger(__name__)
pytestmark = [
pytest.mark.slow_test,
pytest.mark.skip_if_binaries_missing("dockerd"),
pytest.mark.skipif(
mysql.MySQLdb is None, reason="No python mysql client installed."
),
]
@pytest.fixture(scope="module")
def salt_call_cli_wrapper(salt_call_cli, mysql_container):
def run_command(*command, **kwargs):
connection_user = kwargs.pop("connection_user", mysql_container.mysql_root_user)
connection_pass = kwargs.pop(
"connection_pass", mysql_container.mysql_root_passwd
)
connection_db = kwargs.pop("connection_db", "mysql")
connection_port = kwargs.pop("connection_port", mysql_container.mysql_port)
return salt_call_cli.run(
*command,
connection_user=connection_user,
connection_pass=connection_pass,
connection_db=connection_db,
connection_port=connection_port,
**kwargs
)
return run_command
def test_query(salt_call_cli_wrapper):
ret = salt_call_cli_wrapper("mysql.query", "mysql", "SELECT 1")
assert ret.data
assert ret.data["results"] == [["1"]]
def test_version(salt_call_cli_wrapper, mysql_container):
ret = salt_call_cli_wrapper("mysql.version")
assert ret.data
assert mysql_container.mysql_version in ret.data
def test_status(salt_call_cli_wrapper):
ret = salt_call_cli_wrapper("mysql.status")
assert ret.data
def test_db_list(salt_call_cli_wrapper):
ret = salt_call_cli_wrapper("mysql.db_list")
assert ret.data
assert "mysql" in ret.data
def test_db_create_alter_remove(salt_call_cli_wrapper):
ret = salt_call_cli_wrapper("mysql.db_create", "salt")
assert ret.data
ret = salt_call_cli_wrapper(
"mysql.alter_db",
name="salt",
character_set="latin1",
collate="latin1_general_ci",
)
assert ret.data
ret = salt_call_cli_wrapper("mysql.db_remove", name="salt")
assert ret.data
def test_user_list(salt_call_cli_wrapper, mysql_combo):
ret = salt_call_cli_wrapper("mysql.user_list")
assert ret.data
assert {
"User": mysql_combo.mysql_root_user,
"Host": mysql_combo.mysql_host,
} in ret.data
def test_user_exists(salt_call_cli_wrapper, mysql_combo):
ret = salt_call_cli_wrapper(
"mysql.user_exists",
mysql_combo.mysql_root_user,
host=mysql_combo.mysql_host,
password=mysql_combo.mysql_passwd,
)
assert ret.data
ret = salt_call_cli_wrapper(
"mysql.user_exists",
"george",
"hostname",
"badpassword",
)
assert not ret.data
def test_user_info(salt_call_cli_wrapper, mysql_combo):
ret = salt_call_cli_wrapper(
"mysql.user_info", mysql_combo.mysql_root_user, host=mysql_combo.mysql_host
)
assert ret.data
# Check that a subset of the information
# is available in the returned user information.
expected = {
"Host": mysql_combo.mysql_host,
"User": mysql_combo.mysql_root_user,
"Select_priv": "Y",
"Insert_priv": "Y",
"Update_priv": "Y",
"Delete_priv": "Y",
"Create_priv": "Y",
"Drop_priv": "Y",
"Reload_priv": "Y",
"Shutdown_priv": "Y",
"Process_priv": "Y",
"File_priv": "Y",
"Grant_priv": "Y",
"References_priv": "Y",
"Index_priv": "Y",
"Alter_priv": "Y",
"Show_db_priv": "Y",
"Super_priv": "Y",
"Create_tmp_table_priv": "Y",
"Lock_tables_priv": "Y",
"Execute_priv": "Y",
"Repl_slave_priv": "Y",
"Repl_client_priv": "Y",
"Create_view_priv": "Y",
"Show_view_priv": "Y",
"Create_routine_priv": "Y",
"Alter_routine_priv": "Y",
"Create_user_priv": "Y",
"Event_priv": "Y",
"Trigger_priv": "Y",
"Create_tablespace_priv": "Y",
}
data = ret.data.copy()
for key in list(data):
if key not in expected:
data.pop(key)
assert data == expected
# assert all(ret.data.get(key, None) == val for key, val in expected.items())
def test_user_create_chpass_delete(salt_call_cli_wrapper):
ret = salt_call_cli_wrapper(
"mysql.user_create",
"george",
host="localhost",
password="badpassword",
)
assert ret.data
ret = salt_call_cli_wrapper(
"mysql.user_chpass",
"george",
host="localhost",
password="different_password",
)
assert ret.data
ret = salt_call_cli_wrapper("mysql.user_remove", "george", host="localhost")
assert ret.data
def test_user_grants(salt_call_cli_wrapper, mysql_combo):
ret = salt_call_cli_wrapper(
"mysql.user_grants", mysql_combo.mysql_root_user, host=mysql_combo.mysql_host
)
assert ret.data
def test_grant_add_revoke(salt_call_cli_wrapper):
# Create the database
ret = salt_call_cli_wrapper("mysql.db_create", "salt")
assert ret.data
# Create a user
ret = salt_call_cli_wrapper(
"mysql.user_create",
"george",
host="localhost",
password="badpassword",
)
assert ret.data
# Grant privileges to user to specific table
ret = salt_call_cli_wrapper(
"mysql.grant_add",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert ret.data
# Check the grant exists
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert ret.data
# Revoke the grant
ret = salt_call_cli_wrapper(
"mysql.grant_revoke",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert ret.data
# Check the grant does not exist
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert not ret.data
# Grant privileges to user globally
ret = salt_call_cli_wrapper(
"mysql.grant_add",
grant="ALL PRIVILEGES",
database="*.*",
user="george",
host="localhost",
)
assert ret.data
# Check the global exists
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="*.*",
user="george",
host="localhost",
)
assert ret.data
# Revoke the global grant
ret = salt_call_cli_wrapper(
"mysql.grant_revoke",
grant="ALL PRIVILEGES",
database="*.*",
user="george",
host="localhost",
)
assert ret.data
# Check the grant does not exist
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="localhost",
)
assert not ret.data
# Remove the user
ret = salt_call_cli_wrapper("mysql.user_remove", "george", host="localhost")
assert ret.data
# Remove the database
ret = salt_call_cli_wrapper("mysql.db_remove", "salt")
assert ret.data
def test_plugin_add_status_remove(salt_call_cli_wrapper, mysql_combo):
if "mariadb" in mysql_combo.mysql_name:
plugin = "simple_password_check"
else:
plugin = "auth_socket"
ret = salt_call_cli_wrapper(
"mysql.plugin_status", plugin, host=mysql_combo.mysql_host
)
assert not ret.data
ret = salt_call_cli_wrapper("mysql.plugin_add", plugin)
assert ret.data
ret = salt_call_cli_wrapper(
"mysql.plugin_status", plugin, host=mysql_combo.mysql_host
)
assert ret.data
assert ret.data == "ACTIVE"
ret = salt_call_cli_wrapper("mysql.plugin_remove", plugin)
assert ret.data
ret = salt_call_cli_wrapper(
"mysql.plugin_status", plugin, host=mysql_combo.mysql_host
)
assert not ret.data
def test_plugin_list(salt_call_cli_wrapper, mysql_container):
if "mariadb" in mysql_container.mysql_name:
plugin = "simple_password_check"
else:
plugin = "auth_socket"
ret = salt_call_cli_wrapper("mysql.plugins_list")
assert {"name": plugin, "status": "ACTIVE"} not in ret.data
assert ret.data
ret = salt_call_cli_wrapper("mysql.plugin_add", plugin)
assert ret.data
ret = salt_call_cli_wrapper("mysql.plugins_list")
assert ret.data
assert {"name": plugin, "status": "ACTIVE"} in ret.data
ret = salt_call_cli_wrapper("mysql.plugin_remove", plugin)
assert ret.data
def test_grant_add_revoke_password_hash(salt_call_cli_wrapper):
# Create the database
ret = salt_call_cli_wrapper("mysql.db_create", "salt")
assert ret.data
# Create a user
ret = salt_call_cli_wrapper(
"mysql.user_create",
"george",
host="%",
password_hash="*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19",
)
assert ret.data
# Grant privileges to user to specific table
ret = salt_call_cli_wrapper(
"mysql.grant_add",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret.data
# Check the grant exists
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret.data
# Check the grant exists via a query
ret = salt_call_cli_wrapper(
"mysql.query",
database="salt",
query="SELECT 1",
connection_user="george",
connection_pass="password",
connection_db="salt",
)
assert ret.data
# Revoke the grant
ret = salt_call_cli_wrapper(
"mysql.grant_revoke",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret.data
# Check the grant does not exist
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert not ret.data
# Remove the user
ret = salt_call_cli_wrapper("mysql.user_remove", "george", host="%")
assert ret.data
# Remove the database
ret = salt_call_cli_wrapper("mysql.db_remove", "salt")
assert ret.data
def test_create_alter_password_hash(salt_call_cli_wrapper):
# Create the database
ret = salt_call_cli_wrapper("mysql.db_create", "salt")
assert ret.data
# Create a user
ret = salt_call_cli_wrapper(
"mysql.user_create",
"george",
host="%",
password_hash="*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19",
)
assert ret.data
# Grant privileges to user to specific table
ret = salt_call_cli_wrapper(
"mysql.grant_add",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret.data
# Check the grant exists
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret.data
# Check we can query as the new user
ret = salt_call_cli_wrapper(
"mysql.query",
database="salt",
query="SELECT 1",
connection_user="george",
connection_pass="password",
connection_db="salt",
)
assert ret.data
# Change the user password
ret = salt_call_cli_wrapper(
"mysql.user_chpass",
"george",
host="%",
password_hash="*F4A5147613F01DEC0C5226BF24CD1D5762E6AAF2",
)
assert ret.data
# Check we can query with the new password
ret = salt_call_cli_wrapper(
"mysql.query",
database="salt",
query="SELECT 1",
connection_user="george",
connection_pass="badpassword",
connection_db="salt",
)
assert ret.data
# Revoke the grant
ret = salt_call_cli_wrapper(
"mysql.grant_revoke",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert ret.data
# Check the grant does not exist
ret = salt_call_cli_wrapper(
"mysql.grant_exists",
grant="ALL PRIVILEGES",
database="salt.*",
user="george",
host="%",
)
assert not ret.data
# Remove the user
ret = salt_call_cli_wrapper("mysql.user_remove", "george", host="%")
assert ret.data
# Remove the database
ret = salt_call_cli_wrapper("mysql.db_remove", "salt")
assert ret.data

View file

@ -1,276 +0,0 @@
"""
Test Salt MySQL state module across various MySQL variants
"""
import logging
import pytest
import salt.modules.mysql as mysql
from tests.support.pytest.mysql import * # pylint: disable=wildcard-import,unused-wildcard-import
log = logging.getLogger(__name__)
pytestmark = [
pytest.mark.slow_test,
pytest.mark.skip_if_binaries_missing("dockerd"),
pytest.mark.skipif(
mysql.MySQLdb is None, reason="No python mysql client installed."
),
]
@pytest.fixture(scope="module")
def salt_cli_wrapper(salt_minion, salt_cli, mysql_container):
def run_command(*command, **kwargs):
return salt_cli.run(
*command,
minion_tgt=salt_minion.id,
connection_user=mysql_container.mysql_root_user,
connection_pass=mysql_container.mysql_root_passwd,
connection_db="mysql",
connection_port=mysql_container.mysql_port,
**kwargs
)
return run_command
@pytest.fixture(scope="module")
def salt_call_cli_wrapper(salt_call_cli, mysql_container):
def run_command(*command, **kwargs):
return salt_call_cli.run(
*command,
connection_user=mysql_container.mysql_root_user,
connection_pass=mysql_container.mysql_root_passwd,
connection_db="mysql",
connection_port=mysql_container.mysql_port,
**kwargs
)
return run_command
def test_database_present_absent(salt_cli_wrapper):
ret = salt_cli_wrapper(
"state.single",
"mysql_database.present",
name="test_database",
)
state = ret.data["mysql_database_|-test_database_|-test_database_|-present"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"test_database": "Present"}
assert "comment" in state
assert state["comment"] == "The database test_database has been created"
ret = salt_cli_wrapper(
"state.single",
"mysql_database.absent",
name="test_database",
)
state = ret.data["mysql_database_|-test_database_|-test_database_|-absent"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"test_database": "Absent"}
assert "comment" in state
assert state["comment"] == "Database test_database has been removed"
def test_grants_present_absent(salt_cli_wrapper, salt_call_cli_wrapper):
# Create the database
ret = salt_call_cli_wrapper("mysql.db_create", "salt")
assert ret.data
# Create a user
ret = salt_call_cli_wrapper(
"mysql.user_create",
"george",
host="localhost",
password="badpassword",
)
assert ret.data
ret = salt_cli_wrapper(
"state.single",
"mysql_grants.present",
name="add_salt_grants",
grant="select,insert,update",
database="salt.*",
user="george",
host="localhost",
)
state = ret.data["mysql_grants_|-add_salt_grants_|-add_salt_grants_|-present"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"add_salt_grants": "Present"}
assert "comment" in state
assert (
state["comment"]
== "Grant select,insert,update on salt.* to george@localhost has been added"
)
ret = salt_cli_wrapper(
"state.single",
"mysql_grants.absent",
name="delete_salt_grants",
grant="select,insert,update",
database="salt.*",
user="george",
host="localhost",
)
state = ret.data["mysql_grants_|-delete_salt_grants_|-delete_salt_grants_|-absent"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"delete_salt_grants": "Absent"}
assert "comment" in state
assert (
state["comment"]
== "Grant select,insert,update on salt.* for george@localhost has been revoked"
)
# Remove the user
ret = salt_call_cli_wrapper("mysql.user_remove", "george", host="localhost")
assert ret.data
# Remove the database
ret = salt_call_cli_wrapper("mysql.db_remove", "salt")
assert ret.data
def test_user_present_absent(salt_cli_wrapper):
ret = salt_cli_wrapper(
"state.single",
"mysql_user.present",
name="george",
host="localhost",
password="password",
)
state = ret.data["mysql_user_|-george_|-george_|-present"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"george": "Present"}
assert "comment" in state
assert state["comment"] == "The user george@localhost has been added"
ret = salt_cli_wrapper(
"state.single",
"mysql_user.absent",
name="george",
host="localhost",
)
state = ret.data["mysql_user_|-george_|-george_|-absent"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"george": "Absent"}
assert "comment" in state
assert state["comment"] == "User george@localhost has been removed"
def test_user_present_absent_passwordless(salt_cli_wrapper):
ret = salt_cli_wrapper(
"state.single",
"mysql_user.present",
name="george",
host="localhost",
allow_passwordless=True,
)
state = ret.data["mysql_user_|-george_|-george_|-present"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"george": "Present"}
assert "comment" in state
log.debug("=== comment %s ===", state["comment"])
assert (
state["comment"]
== "The user george@localhost has been added with passwordless login"
)
ret = salt_cli_wrapper(
"state.single",
"mysql_user.absent",
name="george",
host="localhost",
)
state = ret.data["mysql_user_|-george_|-george_|-absent"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"george": "Absent"}
assert "comment" in state
assert state["comment"] == "User george@localhost has been removed"
def test_user_present_absent_unixsocket(salt_cli_wrapper, mysql_container):
# The auth_socket plugin on MariaDB is unavailable
# on versions 10.1 - 10.3
if "mariadb" in mysql_container.mysql_name:
if mysql_container.mysql_version in ("10.1", "10.2", "10.3"):
pytest.skip(
"The auth_socket plugin is unavaiable "
"for the {}:{} docker image.".format(
mysql_container.mysql_name, mysql_container.mysql_version
)
)
# enable the auth_socket plugin on MySQL
# already enabled on MariaDB > 10.3
if "mariadb" not in mysql_container.mysql_name:
ret = salt_cli_wrapper("mysql.plugin_add", "auth_socket")
assert ret.data
ret = salt_cli_wrapper(
"state.single",
"mysql_user.present",
name="george",
host="localhost",
unix_socket=True,
allow_passwordless=False,
)
state = ret.data["mysql_user_|-george_|-george_|-present"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"george": "Present"}
assert "comment" in state
assert (
state["comment"] == "The user george@localhost has been added using unix_socket"
)
ret = salt_cli_wrapper(
"state.single",
"mysql_user.absent",
name="george",
host="localhost",
)
state = ret.data["mysql_user_|-george_|-george_|-absent"]
assert ret.returncode == 0, ret
assert "changes" in state
assert state["changes"] == {"george": "Absent"}
assert "comment" in state
assert state["comment"] == "User george@localhost has been removed"
if "mariadb" not in mysql_container.mysql_name:
ret = salt_cli_wrapper("mysql.plugin_remove", "auth_socket")
assert ret.data

View file

@ -50,6 +50,14 @@ class MySQLCombo:
def _default_mysql_root_user_passwd(self):
return self.mysql_passwd
def get_credentials(self, **kwargs):
return {
"connection_user": kwargs.get("connection_user") or self.mysql_root_user,
"connection_pass": kwargs.get("connection_pass") or self.mysql_root_passwd,
"connection_db": kwargs.get("connection_db") or "mysql",
"connection_port": kwargs.get("connection_port") or self.mysql_port,
}
def get_test_versions():
test_versions = []