~joeborg/charm-helpers/charm-helpers

« back to all changes in this revision

Viewing changes to tests/contrib/database/test_mysql.py

[jamespage, r=thedac] Rework mysql helper to directly use leader storage.

Guard against passwd file migrations in following units.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
import json
4
4
import unittest
5
5
import sys
 
6
import shutil
6
7
import tempfile
7
8
 
8
9
sys.modules['MySQLdb'] = mock.Mock()
103
104
        self.assertEqual(list(helper.passwd_keys('auser')),
104
105
                         ['mysql-auser.passwd', 'auser.passwd'])
105
106
 
106
 
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_peer_relation')
 
107
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_leader_storage')
107
108
    @mock.patch.object(mysql.MySQLHelper, 'get_mysql_password_on_disk')
108
 
    @mock.patch.object(mysql, 'peer_retrieve')
109
 
    def test_get_mysql_password_no_peer_passwd(self, mock_peer_retrieve,
 
109
    @mock.patch.object(mysql, 'leader_get')
 
110
    def test_get_mysql_password_no_peer_passwd(self, mock_leader_get,
110
111
                                               mock_get_disk_pw,
111
112
                                               mock_migrate_pw):
112
113
        helper = mysql.MySQLHelper('foo', 'bar', host='hostA')
113
114
        store = {}
114
 
        mock_peer_retrieve.side_effect = lambda key: store.get(key)
 
115
        mock_leader_get.side_effect = lambda key: store.get(key)
115
116
        mock_get_disk_pw.return_value = "disk-passwd"
116
117
        self.assertEqual(helper.get_mysql_password(), "disk-passwd")
117
118
        self.assertTrue(mock_migrate_pw.called)
118
119
 
119
 
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_peer_relation')
 
120
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_leader_storage')
120
121
    @mock.patch.object(mysql.MySQLHelper, 'get_mysql_password_on_disk')
121
 
    @mock.patch.object(mysql, 'peer_retrieve')
122
 
    def test_get_mysql_password_peer_passwd(self, mock_peer_retrieve,
 
122
    @mock.patch.object(mysql, 'leader_get')
 
123
    def test_get_mysql_password_peer_passwd(self, mock_leader_get,
123
124
                                            mock_get_disk_pw, mock_migrate_pw):
124
125
        helper = mysql.MySQLHelper('foo', 'bar', host='hostA')
125
126
        store = {'mysql-userA.passwd': 'passwdA'}
126
 
        mock_peer_retrieve.side_effect = lambda key: store.get(key)
 
127
        mock_leader_get.side_effect = lambda key: store.get(key)
127
128
        mock_get_disk_pw.return_value = "disk-passwd"
128
129
        self.assertEqual(helper.get_mysql_password(username='userA'),
129
130
                         "passwdA")
130
131
        self.assertTrue(mock_migrate_pw.called)
131
132
 
132
 
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_peer_relation')
 
133
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_leader_storage')
133
134
    @mock.patch.object(mysql.MySQLHelper, 'get_mysql_password_on_disk')
134
 
    @mock.patch.object(mysql, 'peer_retrieve')
135
 
    def test_get_mysql_password_peer_passwd_legacy(self, mock_peer_retrieve,
 
135
    @mock.patch.object(mysql, 'leader_get')
 
136
    def test_get_mysql_password_peer_passwd_legacy(self, mock_leader_get,
136
137
                                                   mock_get_disk_pw,
137
138
                                                   mock_migrate_pw):
138
139
        helper = mysql.MySQLHelper('foo', 'bar', host='hostA')
139
140
        store = {'userA.passwd': 'passwdA'}
140
 
        mock_peer_retrieve.side_effect = lambda key: store.get(key)
 
141
        mock_leader_get.side_effect = lambda key: store.get(key)
141
142
        mock_get_disk_pw.return_value = "disk-passwd"
142
143
        self.assertEqual(helper.get_mysql_password(username='userA'),
143
144
                         "passwdA")
144
145
        self.assertTrue(mock_migrate_pw.called)
145
146
 
146
 
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_peer_relation')
 
147
    @mock.patch.object(mysql.MySQLHelper, 'migrate_passwords_to_leader_storage')
147
148
    @mock.patch.object(mysql.MySQLHelper, 'get_mysql_password_on_disk')
148
 
    @mock.patch.object(mysql, 'peer_retrieve')
149
 
    def test_get_mysql_password_peer_passwd_all(self, mock_peer_retrieve,
 
149
    @mock.patch.object(mysql, 'leader_get')
 
150
    def test_get_mysql_password_peer_passwd_all(self, mock_leader_get,
150
151
                                                mock_get_disk_pw,
151
152
                                                mock_migrate_pw):
152
153
        helper = mysql.MySQLHelper('foo', 'bar', host='hostA')
154
155
        # if found.
155
156
        store = {'mysql-userA.passwd': 'passwdA',
156
157
                 'userA.passwd': 'passwdA*'}
157
 
        mock_peer_retrieve.side_effect = lambda key: store.get(key)
 
158
        mock_leader_get.side_effect = lambda key: store.get(key)
158
159
        mock_get_disk_pw.return_value = "disk-passwd"
159
160
        self.assertEqual(helper.get_mysql_password(username='userA'),
160
161
                         "passwdA")
161
162
        self.assertTrue(mock_migrate_pw.called)
162
163
 
163
 
    @mock.patch.object(mysql, 'peer_store')
164
 
    def test_migrate_passwords_to_peer_relation(self, mock_peer_store):
 
164
    @mock.patch.object(mysql, 'is_leader')
 
165
    @mock.patch.object(mysql, 'leader_set')
 
166
    def test_migrate_passwords_to_leader_storage(self, mock_leader_set,
 
167
                                                 mock_is_leader):
165
168
        files = {'mysql.passwd': '1',
166
169
                 'userA.passwd': '2',
167
170
                 'mysql-userA.passwd': '3'}
168
171
        store = {}
169
172
 
170
 
        def _store(key, val):
171
 
            store[key] = val
 
173
        def _store(settings):
 
174
            store.update(settings)
 
175
 
 
176
        mock_is_leader.return_value = True
172
177
 
173
178
        tmpdir = tempfile.mkdtemp('charm-helpers-unit-tests')
174
179
        try:
178
183
                with open(os.path.join(tmpdir, f), 'w') as fd:
179
184
                    fd.write(files[f])
180
185
 
181
 
            mock_peer_store.side_effect = _store
182
 
            helper.migrate_passwords_to_peer_relation()
183
 
 
184
 
            calls = [mock.call('mysql.passwd', '1'),
185
 
                     mock.call('userA.passwd', '2'),
186
 
                     mock.call('mysql-userA.passwd', '3')]
187
 
 
188
 
            mock_peer_store.assert_has_calls(calls,
 
186
            mock_leader_set.side_effect = _store
 
187
            helper.migrate_passwords_to_leader_storage()
 
188
 
 
189
            calls = [mock.call(settings={'mysql.passwd': '1'}),
 
190
                     mock.call(settings={'userA.passwd': '2'}),
 
191
                     mock.call(settings={'mysql-userA.passwd': '3'})]
 
192
 
 
193
            mock_leader_set.assert_has_calls(calls,
189
194
                                             any_order=True)
190
195
        finally:
191
 
            os.rmdir(tmpdir)
 
196
            shutil.rmtree(tmpdir)
192
197
 
193
198
        # Note that legacy key/val is NOT overwritten
194
199
        self.assertEqual(store, {'mysql.passwd': '1',
195
200
                                 'userA.passwd': '2',
196
201
                                 'mysql-userA.passwd': '3'})
197
202
 
 
203
    @mock.patch.object(mysql, 'is_leader')
 
204
    @mock.patch.object(mysql, 'leader_set')
 
205
    def test_migrate_passwords_to_leader_storage_not_leader(self, mock_leader_set,
 
206
                                                            mock_is_leader):
 
207
        mock_is_leader.return_value = False
 
208
        tmpdir = tempfile.mkdtemp('charm-helpers-unit-tests')
 
209
        try:
 
210
            root_tmplt = "%s/mysql.passwd" % (tmpdir)
 
211
            helper = mysql.MySQLHelper(root_tmplt, None, host='hostA')
 
212
            helper.migrate_passwords_to_leader_storage()
 
213
        finally:
 
214
            shutil.rmtree(tmpdir)
 
215
        mock_leader_set.assert_not_called()
 
216
 
198
217
 
199
218
class PerconaTests(unittest.TestCase):
200
219