diff --git a/swift/container/sharder.py b/swift/container/sharder.py index 106c3bc1f0..cb6ac22a05 100644 --- a/swift/container/sharder.py +++ b/swift/container/sharder.py @@ -835,7 +835,7 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator): ('created', default_stats), ('cleaved', default_stats + ('min_time', 'max_time',)), ('misplaced', default_stats + ('found', 'placed', 'unplaced')), - ('audit_root', default_stats), + ('audit_root', default_stats + ('has_overlap', 'num_overlap')), ('audit_shard', default_stats), ) @@ -1038,6 +1038,9 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator): shard_ranges = broker.get_shard_ranges(states=state) overlaps = find_overlapping_ranges(shard_ranges) if overlaps: + self._increment_stat('audit_root', 'has_overlap') + self._increment_stat('audit_root', 'num_overlap', + step=len(overlaps)) all_overlaps = ', '.join( [' '.join(['%s-%s' % (sr.lower, sr.upper) for sr in overlapping_ranges]) diff --git a/test/unit/container/test_sharder.py b/test/unit/container/test_sharder.py index 85f4ea64e3..d06c516f7f 100644 --- a/test/unit/container/test_sharder.py +++ b/test/unit/container/test_sharder.py @@ -451,7 +451,8 @@ class TestSharder(BaseTestSharder): 'min_time': 0.01, 'max_time': 1.3}, 'misplaced': {'attempted': 1, 'success': 1, 'failure': 0, 'found': 1, 'placed': 1, 'unplaced': 0}, - 'audit_root': {'attempted': 5, 'success': 4, 'failure': 1}, + 'audit_root': {'attempted': 5, 'success': 4, 'failure': 1, + 'num_overlap': 0, "has_overlap": 0}, 'audit_shard': {'attempted': 2, 'success': 2, 'failure': 0}, } # NB these are time increments not absolute times... @@ -5010,7 +5011,8 @@ class TestSharder(BaseTestSharder): def test_audit_root_container(self): broker = self._make_broker() - expected_stats = {'attempted': 1, 'success': 1, 'failure': 0} + expected_stats = {'attempted': 1, 'success': 1, 'failure': 0, + 'has_overlap': 0, 'num_overlap': 0} with self._mock_sharder() as sharder: with mock.patch.object( sharder, '_audit_shard_container') as mocked: @@ -5029,7 +5031,8 @@ class TestSharder(BaseTestSharder): # check for no duplicates in reversed order self.assertNotIn('s-z k-t', line) - expected_stats = {'attempted': 1, 'success': 0, 'failure': 1} + expected_stats = {'attempted': 1, 'success': 0, 'failure': 1, + 'has_overlap': 1, 'num_overlap': 2} shard_bounds = (('a', 'j'), ('k', 't'), ('s', 'y'), ('y', 'z'), ('y', 'z')) for state, state_text in ShardRange.STATES.items(): @@ -5061,7 +5064,8 @@ class TestSharder(BaseTestSharder): sharder._audit_container(broker) self.assertFalse(sharder.logger.get_lines_for_level('warning')) self.assertFalse(sharder.logger.get_lines_for_level('error')) - self._assert_stats({'attempted': 1, 'success': 1, 'failure': 0}, + self._assert_stats({'attempted': 1, 'success': 1, 'failure': 0, + 'has_overlap': 0, 'num_overlap': 0}, sharder, 'audit_root') mocked.assert_not_called() @@ -5077,7 +5081,8 @@ class TestSharder(BaseTestSharder): sharder._audit_container(broker) self.assertFalse(sharder.logger.get_lines_for_level('warning')) self.assertFalse(sharder.logger.get_lines_for_level('error')) - self._assert_stats({'attempted': 1, 'success': 1, 'failure': 0}, + self._assert_stats({'attempted': 1, 'success': 1, 'failure': 0, + 'has_overlap': 0, 'num_overlap': 0}, sharder, 'audit_root') mocked.assert_not_called()