test_mysql_database.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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 Testing libs
  8. from tests.support.case import ModuleCase
  9. from tests.support.unit import skipIf
  10. from tests.support.mixins import SaltReturnAssertsMixin
  11. # Import salt libs
  12. import salt.utils.path
  13. from salt.ext import six
  14. import pytest
  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. @pytest.mark.destructive_test
  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',
  71. name=db_name,
  72. **kwargs
  73. )
  74. ret = self.run_state('mysql_database.present',
  75. name=db_name,
  76. **kwargs
  77. )
  78. self.assertSaltTrueReturn(ret)
  79. self.assertInSaltComment(
  80. 'The database ' + db_name + ' has been created',
  81. ret
  82. )
  83. #2nd run
  84. ret = self.run_state('mysql_database.present',
  85. name=second_db_name,
  86. **kwargs
  87. )
  88. self.assertSaltTrueReturn(ret)
  89. self.assertInSaltComment(
  90. 'Database ' + db_name + ' is already present',
  91. ret
  92. )
  93. if test_conn:
  94. # test root connection
  95. ret = self.run_function(
  96. 'mysql.query',
  97. database=db_name,
  98. query='SELECT 1',
  99. **kwargs
  100. )
  101. if not isinstance(ret, dict) or 'results' not in ret:
  102. raise AssertionError(
  103. ('Unexpected result while testing connection'
  104. ' on db \'{0}\': {1}').format(
  105. db_name,
  106. repr(ret)
  107. )
  108. )
  109. self.assertEqual([['1']], ret['results'])
  110. # Now removing databases
  111. kwargs.pop('character_set')
  112. kwargs.pop('collate')
  113. ret = self.run_state('mysql_database.absent',
  114. name=db_name,
  115. **kwargs
  116. )
  117. self.assertSaltTrueReturn(ret)
  118. self.assertInSaltComment(
  119. 'Database ' + db_name + ' has been removed',
  120. ret
  121. )
  122. #2nd run
  123. ret = self.run_state('mysql_database.absent',
  124. name=second_db_name,
  125. ** kwargs
  126. )
  127. self.assertSaltTrueReturn(ret)
  128. self.assertInSaltComment(
  129. 'Database ' + db_name + ' is not present, so it cannot be removed',
  130. ret
  131. )
  132. self.assertSaltStateChangesEqual(ret, {})
  133. @pytest.mark.destructive_test
  134. def test_present_absent(self):
  135. '''
  136. mysql_database.present
  137. '''
  138. self._test_database(
  139. 'testdb1',
  140. 'testdb1',
  141. test_conn=True,
  142. character_set='utf8',
  143. collate='utf8_general_ci',
  144. connection_user=self.user,
  145. connection_pass=self.password,
  146. connection_charset='utf8'
  147. )
  148. # TODO: test with variations on collate and charset, check for db alter
  149. # once it will be done in mysql_database.present state
  150. @pytest.mark.destructive_test
  151. def test_present_absent_fuzzy(self):
  152. '''
  153. mysql_database.present with utf-8 andf fuzzy db name
  154. '''
  155. # this is : ":() ;,?@=`&'\
  156. dbname_fuzzy = '":() ;,?@=`&/\'\\'
  157. # \xe6\xa8\x99\ = \u6a19 = 標
  158. # this is : "();,?:@=`&/標'\
  159. dbname_utf8 = '"();,?@=`&//\xe6\xa8\x99\'\\'
  160. dbname_unicode = u'"();,?@=`&//\u6a19\'\\'
  161. self._test_database(
  162. dbname_fuzzy,
  163. dbname_fuzzy,
  164. test_conn=True,
  165. character_set='utf8',
  166. collate='utf8_general_ci',
  167. connection_user=self.user,
  168. connection_pass=self.password,
  169. connection_charset='utf8'
  170. )
  171. # FIXME: MySQLdb bugs on dbnames with utf-8?
  172. self._test_database(
  173. dbname_utf8,
  174. dbname_unicode,
  175. test_conn=False,
  176. character_set='utf8',
  177. collate='utf8_general_ci',
  178. connection_user=self.user,
  179. connection_pass=self.password,
  180. connection_charset='utf8',
  181. #saltenv={"LC_ALL": "en_US.utf8"}
  182. )
  183. @pytest.mark.destructive_test
  184. @skipIf(True, 'This tests needs issue #8947 to be fixed first')
  185. def test_utf8_from_sls_file(self):
  186. '''
  187. Try to create/destroy an utf-8 database name from an sls file #8947
  188. '''
  189. expected_result = {
  190. 'mysql_database_|-A_|-foo \xe6\xba\x96`bar_|-present': {
  191. '__run_num__': 0,
  192. 'comment': 'The database foo \xe6\xba\x96`bar has been created',
  193. 'result': True},
  194. 'mysql_database_|-B_|-foo \xe6\xba\x96`bar_|-absent': {
  195. '__run_num__': 1,
  196. 'comment': 'Database foo \xe6\xba\x96`bar has been removed',
  197. 'result': True},
  198. }
  199. result = {}
  200. ret = self.run_function('state.sls', mods='mysql_utf8')
  201. if not isinstance(ret, dict):
  202. raise AssertionError(
  203. ('Unexpected result while testing external mysql utf8 sls'
  204. ': {0}').format(
  205. repr(ret)
  206. )
  207. )
  208. for item, descr in six.iteritems(ret):
  209. result[item] = {
  210. '__run_num__': descr['__run_num__'],
  211. 'comment': descr['comment'],
  212. 'result': descr['result']
  213. }
  214. self.assertEqual(expected_result, result)