diff --git a/swift/cli/manage_shard_ranges.py b/swift/cli/manage_shard_ranges.py index 63bc9bad61..7a43cd0267 100644 --- a/swift/cli/manage_shard_ranges.py +++ b/swift/cli/manage_shard_ranges.py @@ -654,6 +654,10 @@ def repair_shard_ranges(broker, args): def analyze_shard_ranges(args): shard_data = _load_and_validate_shard_data(args, require_index=False) + for data in shard_data: + # allow for incomplete shard range data that may have been scraped from + # swift-container-info output + data.setdefault('epoch', None) shard_ranges = [ShardRange.from_dict(data) for data in shard_data] whole_sr = ShardRange('whole/namespace', 0) try: diff --git a/test/unit/cli/test_manage_shard_ranges.py b/test/unit/cli/test_manage_shard_ranges.py index a7e2abbcea..d72ec5b482 100644 --- a/test/unit/cli/test_manage_shard_ranges.py +++ b/test/unit/cli/test_manage_shard_ranges.py @@ -1602,3 +1602,16 @@ class TestManageShardRanges(unittest.TestCase): self.assertEqual( ['Repairs necessary to remove overlapping shard ranges.'], out_lines[:1]) + + filtered_shard_json = [{k: v for k, v in sr.items() if k != 'epoch'} + for sr in shard_json] + with open(shard_file, 'w') as fd: + json.dump(filtered_shard_json, fd) + out = StringIO() + err = StringIO() + with mock.patch('sys.stdout', out), mock.patch('sys.stderr', err): + ret = main([shard_file, 'analyze']) + self.assertEqual(0, ret) + self.assertEqual('', err.getvalue()) + new_out_lines = out.getvalue().split('\n') + self.assertEqual(out_lines, new_out_lines)