diff --git a/swift/obj/auditor.py b/swift/obj/auditor.py index 28f39f89da..78ab123474 100644 --- a/swift/obj/auditor.py +++ b/swift/obj/auditor.py @@ -78,7 +78,7 @@ class AuditorWorker(object): logger=self.logger) for path, device, partition in all_locs: loop_time = time.time() - self.object_audit(path, device, partition) + self.failsafe_object_audit(path, device, partition) self.logger.timing_since('timing', loop_time) self.files_running_time = ratelimit_sleep( self.files_running_time, self.max_files_per_second) @@ -151,6 +151,17 @@ class AuditorWorker(object): else: self.stats_buckets["OVER"] += 1 + def failsafe_object_audit(self, path, device, partition): + """ + Entrypoint to object_audit, with a failsafe generic exception handler. + """ + try: + self.object_audit(path, device, partition) + except (Exception, Timeout): + self.logger.increment('errors') + self.errors += 1 + self.logger.exception(_('ERROR Trying to audit %s'), path) + def object_audit(self, path, device, partition): """ Audits the given object path. @@ -204,11 +215,6 @@ class AuditorWorker(object): diskfile.quarantine_renamer( os.path.join(self.devices, device), path) return - except (Exception, Timeout): - self.logger.increment('errors') - self.errors += 1 - self.logger.exception(_('ERROR Trying to audit %s'), path) - return self.passes += 1 diff --git a/test/unit/obj/test_auditor.py b/test/unit/obj/test_auditor.py index 83b6e27f33..94a6c5b57b 100644 --- a/test/unit/obj/test_auditor.py +++ b/test/unit/obj/test_auditor.py @@ -141,6 +141,36 @@ class TestAuditor(unittest.TestCase): 'sda', '0') self.assertEquals(self.auditor.quarantines, pre_quarantines + 1) + def test_object_audit_will_not_swallow_errors_in_tests(self): + timestamp = str(normalize_timestamp(time.time())) + path = os.path.join(self.disk_file.datadir, timestamp + '.data') + mkdirs(self.disk_file.datadir) + with open(path, 'w') as f: + write_metadata(f, {'name': '/a/c/o'}) + self.auditor = auditor.AuditorWorker(self.conf, self.logger) + + def blowup(*args): + raise NameError('tpyo') + with mock.patch('swift.obj.diskfile.DiskFile', + blowup): + self.assertRaises(NameError, self.auditor.object_audit, + path, 'sda', '0') + + def test_failsafe_object_audit_will_swallow_errors_in_tests(self): + timestamp = str(normalize_timestamp(time.time())) + path = os.path.join(self.disk_file.datadir, timestamp + '.data') + mkdirs(self.disk_file.datadir) + with open(path, 'w') as f: + write_metadata(f, {'name': '/a/c/o'}) + self.auditor = auditor.AuditorWorker(self.conf, self.logger) + + def blowup(*args): + raise NameError('tpyo') + with mock.patch('swift.obj.diskfile.DiskFile', + blowup): + self.auditor.failsafe_object_audit(path, 'sda', '0') + self.assertEquals(self.auditor.errors, 1) + def test_generic_exception_handling(self): self.auditor = auditor.AuditorWorker(self.conf, self.logger) timestamp = str(normalize_timestamp(time.time()))