Skip to content

Commit d652ddc

Browse files
committed
sort at the right place in the code
1 parent 6dd5609 commit d652ddc

2 files changed

Lines changed: 35 additions & 5 deletions

File tree

irods/data_object.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def __repr__(self):
4747

4848
def _DEFAULT_SORT_KEY_FN(row):
4949
repl_status = int(row[DataObject.replica_status])
50-
50+
5151
repl_status_rank = (
5252
_REPL_STATUSES.index(repl_status) if _REPL_STATUSES.count(repl_status)
5353
else sys.maxsize
@@ -61,6 +61,8 @@ def __init__(self, manager, parent=None, results=None, replica_sort_function=Non
6161
self.manager = manager
6262
if parent and results:
6363
self.collection = parent
64+
if results:
65+
results = sorted(results, key=(replica_sort_function or _DEFAULT_SORT_KEY_FN))
6466
for attr, value in DataObject.__dict__.items():
6567
if not attr.startswith("_"):
6668
try:
@@ -69,7 +71,6 @@ def __init__(self, manager, parent=None, results=None, replica_sort_function=Non
6971
# backward compatibility with older schema versions
7072
pass
7173
self.path = self.collection.path + "/" + self.name
72-
replicas = sorted(results, key=(replica_sort_function or _DEFAULT_SORT_KEY_FN))
7374

7475
# The status quo before iRODS 5
7576

@@ -90,13 +91,13 @@ def __init__(self, manager, parent=None, results=None, replica_sort_function=Non
9091
modify_time=r[DataObject.modify_time],
9192
),
9293
)
93-
for r in replicas
94+
for r in results
9495
]
9596

9697
# Adjust for adding access_time in the iRODS 5 case.
9798

9899
if self.manager.sess.server_version >= (5,):
99-
for n, r in enumerate(replicas):
100+
for n, r in enumerate(results):
100101
replica_args[n][1]['access_time'] = r[DataObject.access_time]
101102
self.replicas = [iRODSReplica(*a, **k) for a, k in replica_args]
102103

irods/test/data_obj_test.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ def test_replica_number(self):
12511251
# refresh object
12521252
obj = session.data_objects.get(obj_path)
12531253

1254-
# assertions on replicas
1254+
# assertions on replicas
12551255
self.assertEqual(len(obj.replicas), number_of_replicas)
12561256
self.assertEqual(
12571257
{repl.number for repl in obj.replicas},
@@ -2992,6 +2992,35 @@ def test_handling_of_termination_signals_during_multithread_put__issue_722(self)
29922992

29932993
test_put__issue_722(self)
29942994

2995+
def test_default_sorting_of_replicas__issue_647(self):
2996+
basename = unique_name(my_function_name(), datetime.now()) + '_dataobj_647'
2997+
with self.create_simple_resc() as newResc1, self.create_simple_resc() as newResc2:
2998+
data = helpers.make_object(self.sess, f'{helpers.home_collection(self.sess)}/{basename}')
2999+
3000+
# Precondition for an eventual total of 3 replicas: initial data replica is not on either of the new resources.
3001+
self.assertFalse({repl.resource_name for repl in data.replicas} & {newResc1, newResc2})
3002+
try:
3003+
data.replicate(resource=newResc1)
3004+
3005+
# Ensure that one of the replicas is stale, to test proper sorting.
3006+
with data.open('a',**{kw.RESC_NAME_KW:newResc1}) as f:
3007+
f.write(b'.')
3008+
time.sleep(2)
3009+
3010+
# Voting should ensure exactly two good replicas of the three.
3011+
data.replicate(resource=newResc2)
3012+
3013+
# refresh replicas
3014+
data = self.sess.data_objects.get(data.path)
3015+
3016+
# Test replica sorting.
3017+
self.assertEqual(data.replicas[0].status, '1')
3018+
self.assertEqual(data.replicas[0].modify_time, data.modify_time)
3019+
self.assertGreater(data.replicas[0].modify_time, data.replicas[1].modify_time)
3020+
finally:
3021+
if data:
3022+
data.unlink(force=True)
3023+
29953024

29963025
if __name__ == "__main__":
29973026
# let the tests find the parent irods lib

0 commit comments

Comments
 (0)