diff --git a/swift/common/utils.py b/swift/common/utils.py index 5bd25a1b20..741aee07b2 100644 --- a/swift/common/utils.py +++ b/swift/common/utils.py @@ -5151,10 +5151,10 @@ class ShardName(object): /--- - Note: not all instances of :class:`~swift.common.utils.ShardRange` have - names that will parse as a :class:`~swift.common.utils.ShardName`; root - container own shard ranges, for example, have a simpler name format of - /. + Note: some instances of :class:`~swift.common.utils.ShardRange` have names + that will NOT parse as a :class:`~swift.common.utils.ShardName`; e.g. a + root container's own shard range will have a name format of + / which will raise ValueError if passed to parse. """ def __init__(self, account, root_container, parent_container_hash, @@ -5204,7 +5204,9 @@ class ShardName(object): container belongs. :param root_container: the name of the root container for the shard. :param parent_container: the name of the parent container for the - shard. + shard; for initial first generation shards this should be the same + as ``root_container``; for shards of shards this should be the name + of the sharding shard container. :param timestamp: an instance of :class:`~swift.common.utils.Timestamp` :param index: a unique index that will distinguish the path from any other path generated using the same combination of diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py index 7d10aa35e5..f351f94aed 100644 --- a/test/unit/common/test_utils.py +++ b/test/unit/common/test_utils.py @@ -7955,6 +7955,7 @@ class TestShardName(unittest.TestCase): actual = str(created) self.assertEqual(expected, actual) parsed = utils.ShardName.parse(actual) + # normally a ShardName will be in the .shards prefix self.assertEqual('a', parsed.account) self.assertEqual('root', parsed.root_container) self.assertEqual(parent_hash, parsed.parent_container_hash) @@ -7971,6 +7972,30 @@ class TestShardName(unittest.TestCase): self.assertEqual(utils.Timestamp(1234), parsed.timestamp) self.assertEqual(99, parsed.index) + def test_realistic_shard_range_names(self): + parsed = utils.ShardName.parse( + '.shards_a1/r1-' + '7c92cf1eee8d99cc85f8355a3d6e4b86-' + '1662475499.00000-1') + self.assertEqual('.shards_a1', parsed.account) + self.assertEqual('r1', parsed.root_container) + self.assertEqual('7c92cf1eee8d99cc85f8355a3d6e4b86', + parsed.parent_container_hash) + self.assertEqual(utils.Timestamp(1662475499), parsed.timestamp) + self.assertEqual(1, parsed.index) + + parsed = utils.ShardName('.shards_a', 'c', 'hash', + utils.Timestamp(1234), 42) + self.assertEqual( + '.shards_a/c-hash-0000001234.00000-42', + str(parsed)) + + parsed = utils.ShardName.create('.shards_a', 'c', 'c', + utils.Timestamp(1234), 42) + self.assertEqual( + '.shards_a/c-4a8a08f09d37b73795649038408b5f33-0000001234.00000-42', + str(parsed)) + def test_bad_parse(self): with self.assertRaises(ValueError) as cm: utils.ShardName.parse('a')