From 88464d89612ae8150c73db52a4e3555961853fc1 Mon Sep 17 00:00:00 2001 From: Yang Youseok Date: Mon, 19 Mar 2018 16:23:15 +0900 Subject: [PATCH] Add check_process() for mysqldump Before, mysqldump had redirect parts for stderr but did not have any check logic for that. So redirect part was deleted to avoid reporting which is always success. But, mysqldump does not emit not only errors but also warnings like "Warning: ..." or "[Warning] ...". This warnings should not be considered to error, so add check_process for filtering that like other backup strategies. Also, change message log level to debug for the right purpose and change print location not to print None when the output file is empty. Change-Id: I27b1b0628e79ca1c7b0c1ab5f939b5960ec3177a Close-Bug: 1756806 --- .../strategies/backup/mysql_impl.py | 19 ++++++++++++++++++- .../unittests/backup/test_backupagent.py | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/trove/guestagent/strategies/backup/mysql_impl.py b/trove/guestagent/strategies/backup/mysql_impl.py index 8c51fc7a31..debae7bf09 100644 --- a/trove/guestagent/strategies/backup/mysql_impl.py +++ b/trove/guestagent/strategies/backup/mysql_impl.py @@ -44,6 +44,22 @@ class MySQLDump(base.BackupRunner): ' --opt' + user_and_pass) return cmd + self.zip_cmd + self.encrypt_cmd + def check_process(self): + """Check the output from mysqldump ignoring 'Warning'.""" + LOG.debug('Checking mysqldump process output.') + with open('/tmp/mysqldump.log', 'r') as backup_log: + output = backup_log.read() + if not output: + return True + + LOG.debug(output) + for line in output.splitlines(): + if not re.search('Warning', line.strip()): + LOG.error("Mysqldump did not complete successfully.") + return False + + return True + class InnoBackupEx(base.BackupRunner): """Implementation of Backup Strategy for InnoBackupEx.""" @@ -71,10 +87,11 @@ class InnoBackupEx(base.BackupRunner): LOG.debug('Checking innobackupex process output.') with open('/tmp/innobackupex.log', 'r') as backup_log: output = backup_log.read() - LOG.info(output) if not output: LOG.error("Innobackupex log file empty.") return False + + LOG.debug(output) last_line = output.splitlines()[-1].strip() if not re.search('completed OK!', last_line): LOG.error("Innobackupex did not complete successfully.") diff --git a/trove/tests/unittests/backup/test_backupagent.py b/trove/tests/unittests/backup/test_backupagent.py index 6f2526637d..9dada761fc 100644 --- a/trove/tests/unittests/backup/test_backupagent.py +++ b/trove/tests/unittests/backup/test_backupagent.py @@ -558,3 +558,21 @@ class BackupAgentTest(trove_testtools.TestCase): self.assertRaises( AttributeError, agent.execute_backup, TroveContext(), bkup_info, 'location') + + def test_backup_mysqldump_check_process(self): + mysql_dump = mysql_impl.MySQLDump( + 'abc', extra_opts='') + + str_will_be_true = 'Warning: Using a password ' \ + 'on the command line interface can be insecure.' + str_will_be_false = 'ERROR: mysqldump command did not succeed.' + + with mock.patch('trove.guestagent.strategies.backup.mysql_impl.open', + mock.mock_open(read_data='')): + self.assertTrue(mysql_dump.check_process()) + with mock.patch('trove.guestagent.strategies.backup.mysql_impl.open', + mock.mock_open(read_data=str_will_be_true)): + self.assertTrue(mysql_dump.check_process()) + with mock.patch('trove.guestagent.strategies.backup.mysql_impl.open', + mock.mock_open(read_data=str_will_be_false)): + self.assertFalse(mysql_dump.check_process())