sharder: report perfectly overlapping shard ranges
Previously, shard ranges that overlapped perfectly (i.e. their bounds were equal) were erroneously excluded from overlapping shard reports. With this patch they will be reported in logs and cause shard audit failures. Also, the format of the audit log line is simplified to avoid unnecessary duplication of information. Change-Id: Ie15c9f40a132374c89337f0009fb5cf5a8e62c51 Closes-Bug: #1928459 Related-Bug: #1913332
This commit is contained in:
parent
9edcfad22f
commit
1b183f221d
@ -108,12 +108,13 @@ def find_overlapping_ranges(shard_ranges):
|
||||
each other.
|
||||
"""
|
||||
result = set()
|
||||
for shard_range in shard_ranges:
|
||||
overlapping = [sr for sr in shard_ranges
|
||||
if shard_range != sr and shard_range.overlaps(sr)]
|
||||
for i, shard_range in enumerate(shard_ranges):
|
||||
overlapping = [
|
||||
sr for sr in shard_ranges[i + 1:]
|
||||
if shard_range.name != sr.name and shard_range.overlaps(sr)]
|
||||
if overlapping:
|
||||
overlapping.append(shard_range)
|
||||
overlapping.sort()
|
||||
overlapping.sort(key=ShardRange.sort_key)
|
||||
result.add(tuple(overlapping))
|
||||
|
||||
return result
|
||||
@ -994,12 +995,14 @@ class ContainerSharder(ContainerReplicator):
|
||||
continue
|
||||
shard_ranges = broker.get_shard_ranges(states=state)
|
||||
overlaps = find_overlapping_ranges(shard_ranges)
|
||||
for overlapping_ranges in overlaps:
|
||||
if overlaps:
|
||||
all_overlaps = ', '.join(
|
||||
[' '.join(['%s-%s' % (sr.lower, sr.upper)
|
||||
for sr in overlapping_ranges])
|
||||
for overlapping_ranges in sorted(list(overlaps))])
|
||||
warnings.append(
|
||||
'overlapping ranges in state %s: %s' %
|
||||
(ShardRange.STATES[state],
|
||||
' '.join(['%s-%s' % (sr.lower, sr.upper)
|
||||
for sr in overlapping_ranges])))
|
||||
'overlapping ranges in state %r: %s' %
|
||||
(ShardRange.STATES[state], all_overlaps))
|
||||
|
||||
if warnings:
|
||||
self.logger.warning(
|
||||
|
@ -117,10 +117,10 @@ class BaseTestSharder(unittest.TestCase):
|
||||
if not isinstance(state, (tuple, list)):
|
||||
state = [state] * len(bounds)
|
||||
state_iter = iter(state)
|
||||
return [ShardRange('.shards_a/c_%s' % upper, timestamp,
|
||||
return [ShardRange('.shards_a/c_%s_%s' % (upper, index), timestamp,
|
||||
lower, upper, state=next(state_iter),
|
||||
object_count=object_count, **kwargs)
|
||||
for lower, upper in bounds]
|
||||
for index, (lower, upper) in enumerate(bounds)]
|
||||
|
||||
def ts_encoded(self):
|
||||
# make a unique timestamp string with multiple timestamps encoded;
|
||||
@ -4859,11 +4859,14 @@ class TestSharder(BaseTestSharder):
|
||||
self.assertIn(
|
||||
'Audit failed for root %s' % broker.db_file, line)
|
||||
self.assertIn(
|
||||
'overlapping ranges in state %s: k-t s-z' % state_text,
|
||||
line)
|
||||
'overlapping ranges in state %r: k-t s-y, y-z y-z'
|
||||
% state_text, line)
|
||||
# check for no duplicates in reversed order
|
||||
self.assertNotIn('s-z k-t', line)
|
||||
|
||||
expected_stats = {'attempted': 1, 'success': 0, 'failure': 1}
|
||||
shard_bounds = (('a', 'j'), ('k', 't'), ('s', 'z'))
|
||||
shard_bounds = (('a', 'j'), ('k', 't'), ('s', 'y'),
|
||||
('y', 'z'), ('y', 'z'))
|
||||
for state, state_text in ShardRange.STATES.items():
|
||||
if state in (ShardRange.SHRINKING,
|
||||
ShardRange.SHARDED,
|
||||
|
Loading…
Reference in New Issue
Block a user