test_mysql_database.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for the MySQL states
  4. """
  5. # Import python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. # Import salt libs
  8. import salt.utils.path
  9. from salt.ext import six
  10. # Import Salt Testing libs
  11. from tests.support.case import ModuleCase
  12. from tests.support.helpers import destructiveTest
  13. from tests.support.mixins import SaltReturnAssertsMixin
  14. from tests.support.unit import skipIf
  15. NO_MYSQL = False
  16. try:
  17. import MySQLdb # pylint: disable=import-error,unused-import
  18. except ImportError:
  19. NO_MYSQL = True
  20. if not salt.utils.path.which("mysqladmin"):
  21. NO_MYSQL = True
  22. @skipIf(
  23. NO_MYSQL,
  24. "Please install MySQL bindings and a MySQL Server before running"
  25. "MySQL integration tests.",
  26. )
  27. class MysqlDatabaseStateTest(ModuleCase, SaltReturnAssertsMixin):
  28. """
  29. Validate the mysql_database state
  30. """
  31. user = "root"
  32. password = "poney"
  33. @destructiveTest
  34. def setUp(self):
  35. """
  36. Test presence of MySQL server, enforce a root password
  37. """
  38. super(MysqlDatabaseStateTest, self).setUp()
  39. NO_MYSQL_SERVER = True
  40. # now ensure we know the mysql root password
  41. # one of theses two at least should work
  42. ret1 = self.run_state(
  43. "cmd.run",
  44. name='mysqladmin --host="localhost" -u '
  45. + self.user
  46. + ' flush-privileges password "'
  47. + self.password
  48. + '"',
  49. )
  50. ret2 = self.run_state(
  51. "cmd.run",
  52. name='mysqladmin --host="localhost" -u '
  53. + self.user
  54. + ' --password="'
  55. + self.password
  56. + '" flush-privileges password "'
  57. + self.password
  58. + '"',
  59. )
  60. key, value = ret2.popitem()
  61. if value["result"]:
  62. NO_MYSQL_SERVER = False
  63. else:
  64. self.skipTest("No MySQL Server running, or no root access on it.")
  65. def _test_database(self, db_name, second_db_name, test_conn, **kwargs):
  66. """
  67. Create db two times, test conn, remove it two times
  68. """
  69. # In case of...
  70. ret = self.run_state("mysql_database.absent", name=db_name, **kwargs)
  71. ret = self.run_state("mysql_database.present", name=db_name, **kwargs)
  72. self.assertSaltTrueReturn(ret)
  73. self.assertInSaltComment("The database " + db_name + " has been created", ret)
  74. # 2nd run
  75. ret = self.run_state("mysql_database.present", name=second_db_name, **kwargs)
  76. self.assertSaltTrueReturn(ret)
  77. self.assertInSaltComment("Database " + db_name + " is already present", ret)
  78. if test_conn:
  79. # test root connection
  80. ret = self.run_function(
  81. "mysql.query", database=db_name, query="SELECT 1", **kwargs
  82. )
  83. if not isinstance(ret, dict) or "results" not in ret:
  84. raise AssertionError(
  85. (
  86. "Unexpected result while testing connection" " on db '{0}': {1}"
  87. ).format(db_name, repr(ret))
  88. )
  89. self.assertEqual([["1"]], ret["results"])
  90. # Now removing databases
  91. kwargs.pop("character_set")
  92. kwargs.pop("collate")
  93. ret = self.run_state("mysql_database.absent", name=db_name, **kwargs)
  94. self.assertSaltTrueReturn(ret)
  95. self.assertInSaltComment("Database " + db_name + " has been removed", ret)
  96. # 2nd run
  97. ret = self.run_state("mysql_database.absent", name=second_db_name, **kwargs)
  98. self.assertSaltTrueReturn(ret)
  99. self.assertInSaltComment(
  100. "Database " + db_name + " is not present, so it cannot be removed", ret
  101. )
  102. self.assertSaltStateChangesEqual(ret, {})
  103. @destructiveTest
  104. def test_present_absent(self):
  105. """
  106. mysql_database.present
  107. """
  108. self._test_database(
  109. "testdb1",
  110. "testdb1",
  111. test_conn=True,
  112. character_set="utf8",
  113. collate="utf8_general_ci",
  114. connection_user=self.user,
  115. connection_pass=self.password,
  116. connection_charset="utf8",
  117. )
  118. # TODO: test with variations on collate and charset, check for db alter
  119. # once it will be done in mysql_database.present state
  120. @destructiveTest
  121. def test_present_absent_fuzzy(self):
  122. """
  123. mysql_database.present with utf-8 andf fuzzy db name
  124. """
  125. # this is : ":() ;,?@=`&'\
  126. dbname_fuzzy = "\":() ;,?@=`&/'\\"
  127. # \xe6\xa8\x99\ = \u6a19 = 標
  128. # this is : "();,?:@=`&/標'\
  129. dbname_utf8 = "\"();,?@=`&//\xe6\xa8\x99'\\"
  130. dbname_unicode = "\"();,?@=`&//\u6a19'\\"
  131. self._test_database(
  132. dbname_fuzzy,
  133. dbname_fuzzy,
  134. test_conn=True,
  135. character_set="utf8",
  136. collate="utf8_general_ci",
  137. connection_user=self.user,
  138. connection_pass=self.password,
  139. connection_charset="utf8",
  140. )
  141. # FIXME: MySQLdb bugs on dbnames with utf-8?
  142. self._test_database(
  143. dbname_utf8,
  144. dbname_unicode,
  145. test_conn=False,
  146. character_set="utf8",
  147. collate="utf8_general_ci",
  148. connection_user=self.user,
  149. connection_pass=self.password,
  150. connection_charset="utf8",
  151. # saltenv={"LC_ALL": "en_US.utf8"}
  152. )
  153. @destructiveTest
  154. @skipIf(True, "This tests needs issue #8947 to be fixed first")
  155. def test_utf8_from_sls_file(self):
  156. """
  157. Try to create/destroy an utf-8 database name from an sls file #8947
  158. """
  159. expected_result = {
  160. "mysql_database_|-A_|-foo \xe6\xba\x96`bar_|-present": {
  161. "__run_num__": 0,
  162. "comment": "The database foo \xe6\xba\x96`bar has been created",
  163. "result": True,
  164. },
  165. "mysql_database_|-B_|-foo \xe6\xba\x96`bar_|-absent": {
  166. "__run_num__": 1,
  167. "comment": "Database foo \xe6\xba\x96`bar has been removed",
  168. "result": True,
  169. },
  170. }
  171. result = {}
  172. ret = self.run_function("state.sls", mods="mysql_utf8")
  173. if not isinstance(ret, dict):
  174. raise AssertionError(
  175. (
  176. "Unexpected result while testing external mysql utf8 sls" ": {0}"
  177. ).format(repr(ret))
  178. )
  179. for item, descr in six.iteritems(ret):
  180. result[item] = {
  181. "__run_num__": descr["__run_num__"],
  182. "comment": descr["comment"],
  183. "result": descr["result"],
  184. }
  185. self.assertEqual(expected_result, result)