def test_get_mysql_password_peer_passwd_all(self, mock_leader_get, mock_get_disk_pw, mock_migrate_pw): helper = mysql.MySQLHelper('foo', 'bar', host='hostA') # Add * so we can identify that the new format key takes precedence # if found. store = {'mysql-userA.passwd': 'passwdA', 'userA.passwd': 'passwdA*'} mock_leader_get.side_effect = lambda key: store.get(key) mock_get_disk_pw.return_value = "disk-passwd" self.assertEqual(helper.get_mysql_password(username='******'), "passwdA") self.assertTrue(mock_migrate_pw.called)
def test_set_mysql_password(self, mock_connect, mock_get_passwd, mock_compare_releases, mock_leader_set, mock_leader_get, mock_is_leader): mock_connection = mock.MagicMock() mock_cursor = mock.MagicMock() mock_connection.cursor.return_value = mock_cursor mock_get_passwd.return_value = 'asdf' mock_is_leader.return_value = True mock_leader_get.return_value = '1234' mock_compare_releases.return_value = 'artful' helper = mysql.MySQLHelper('foo', 'bar', host='hostA') helper.connection = mock_connection helper.set_mysql_password(username='******', password='******') mock_connect.assert_has_calls( [mock.call(user='******', password='******'), # original password mock.call(user='******', password='******')]) # new password mock_leader_get.assert_has_calls([mock.call('mysql.passwd')]) mock_leader_set.assert_has_calls( [mock.call(settings={'mysql.passwd': '1234'})] ) SQL_UPDATE_PASSWD = ("UPDATE mysql.user SET password = "******"PASSWORD( %s ) WHERE user = %s;") mock_cursor.assert_has_calls( [mock.call.execute(SQL_UPDATE_PASSWD, ('1234', 'root')), mock.call.execute('FLUSH PRIVILEGES;'), mock.call.close(), mock.call.execute('select 1;'), mock.call.close()] ) # make sure for the non-leader leader-set is not called mock_is_leader.return_value = False mock_leader_set.reset_mock() helper.set_mysql_password(username='******', password='******') mock_leader_set.assert_not_called() mock_compare_releases.return_value = 'bionic' helper.set_mysql_password(username='******', password='******') SQL_UPDATE_PASSWD = ("UPDATE mysql.user SET " "authentication_string = " "PASSWORD( %s ) WHERE user = %s;") mock_cursor.assert_has_calls( [mock.call.execute(SQL_UPDATE_PASSWD, ('1234', 'root')), mock.call.execute('FLUSH PRIVILEGES;'), mock.call.close(), mock.call.execute('select 1;'), mock.call.close()] )
def test_set_mysql_password_fail_to_connect(self, mock_connect, mock_get_passwd, mock_leader_set, mock_leader_get): class FakeOperationalError(Exception): pass def fake_connect(*args, **kwargs): raise FakeOperationalError('foobar') mysql.MySQLdb.OperationalError = FakeOperationalError helper = mysql.MySQLHelper('foo', 'bar', host='hostA') mock_connect.side_effect = fake_connect self.assertRaises(mysql.MySQLSetPasswordError, helper.set_mysql_password, username='******', password='******')
def test_get_allowed_units(self, mock_log, mock_related_units, mock_relation_get, mock_grant_exists, mock_get_password, mock_normalize_address): # echo mock_normalize_address.side_effect = lambda addr: addr def mock_rel_get(unit, rid): if unit == 'unit/0': # Non-prefixed settings d = {'private-address': '10.0.0.1', 'hostname': 'hostA'} elif unit == 'unit/1': # Containing prefixed settings d = { 'private-address': '10.0.0.2', 'dbA_hostname': json.dumps(['10.0.0.2', '2001:db8:1::2']) } elif unit == 'unit/2': # No hostname d = {'private-address': '10.0.0.3'} return d mock_relation_get.side_effect = mock_rel_get mock_related_units.return_value = ['unit/0', 'unit/1', 'unit/2'] helper = mysql.MySQLHelper('foo', 'bar', host='hostA') units = helper.get_allowed_units('dbA', 'userA') calls = [ mock.call('dbA', 'userA', 'hostA'), mock.call().__nonzero__(), mock.call('dbA', 'userA', '10.0.0.2'), mock.call().__nonzero__(), mock.call('dbA', 'userA', '2001:db8:1::2'), mock.call().__nonzero__(), mock.call('dbA', 'userA', '10.0.0.3'), mock.call().__nonzero__() ] helper.grant_exists.assert_has_calls(calls) self.assertEqual(units, set(['unit/0', 'unit/1', 'unit/2']))
def test_migrate_passwords_to_leader_storage(self, mock_leader_set, mock_is_leader): files = { 'mysql.passwd': '1', 'userA.passwd': '2', 'mysql-userA.passwd': '3' } store = {} def _store(settings): store.update(settings) mock_is_leader.return_value = True tmpdir = tempfile.mkdtemp('charm-helpers-unit-tests') try: root_tmplt = "%s/mysql.passwd" % (tmpdir) helper = mysql.MySQLHelper(root_tmplt, None, host='hostA') for f in files: with open(os.path.join(tmpdir, f), 'w') as fd: fd.write(files[f]) mock_leader_set.side_effect = _store helper.migrate_passwords_to_leader_storage() calls = [ mock.call(settings={'mysql.passwd': '1'}), mock.call(settings={'userA.passwd': '2'}), mock.call(settings={'mysql-userA.passwd': '3'}) ] mock_leader_set.assert_has_calls(calls, any_order=True) finally: shutil.rmtree(tmpdir) # Note that legacy key/val is NOT overwritten self.assertEqual(store, { 'mysql.passwd': '1', 'userA.passwd': '2', 'mysql-userA.passwd': '3' })
def test_migrate_passwords_to_peer_relation(self, mock_peer_store): files = { 'mysql.passwd': '1', 'userA.passwd': '2', 'mysql-userA.passwd': '3' } store = {} def _store(key, val): store[key] = val tmpdir = tempfile.mkdtemp('charm-helpers-unit-tests') try: root_tmplt = "%s/mysql.passwd" % (tmpdir) helper = mysql.MySQLHelper(root_tmplt, None, host='hostA') for f in files: with open(os.path.join(tmpdir, f), 'w') as fd: fd.write(files[f]) mock_peer_store.side_effect = _store helper.migrate_passwords_to_peer_relation() calls = [ mock.call('mysql.passwd', '1'), mock.call('userA.passwd', '2'), mock.call('mysql-userA.passwd', '3') ] mock_peer_store.assert_has_calls(calls) finally: os.rmdir(tmpdir) # Note that legacy key/val is NOT overwritten self.assertEqual(store, { 'mysql.passwd': '1', 'userA.passwd': '2', 'mysql-userA.passwd': '3' })
def test_set_mysql_root_password(self, mock_set_passwd): helper = mysql.MySQLHelper('foo', 'bar', host='hostA') helper.set_mysql_root_password(password='******') mock_set_passwd.assert_called_with('root', '1234')
def test_passwd_keys(self): helper = mysql.MySQLHelper('foo', 'bar', host='hostA') self.assertEqual(list(helper.passwd_keys(None)), ['mysql.passwd']) self.assertEqual(list(helper.passwd_keys('auser')), ['mysql-auser.passwd', 'auser.passwd'])
def test_connect_host_not_defined(self): helper = mysql.MySQLHelper('foo', 'bar') with mock.patch.object(mysql, 'log'): helper.connect(user='******', password='******') mysql.MySQLdb.connect.assert_called_with( passwd='password', host='localhost', user='******')