In method blockCorruptionRecoveryPolicy(), 5 nodes are created, 3 with replicas of a certain block. Two of those replicas, in the nodes at index  and , are deliberately corrupted. Then it attempts to restart those two nodes so the corruption will be detected.
The loop that is intended to restart both datanodes starts with . But when it restarts , it is removed from the MiniCluster's arraylist and re-added to the end. As a result,  moves to . But the loop then restarts the new , which was the former , which doesn't contain a corrupt replica. As a result, the corrupt replica in the former  never gets detected.
In resolving the corruption, one of two errors can happen, with probability 50%: Since the namenode thinks it still has two good replicas, it may pick the corrupt replica as the source for re-replication. That will cause a checksum error at the receiving node.
Alternatively, it may pick the one valid replica as the source, and replicate it, and delete the bad replica from the original . However, since it doesn't know that the replica on the former  is corrupt, it never issues the delete request. This causes the test case to time out on the wait for corrupt replica deletion.
This problem is resolved by looping from high  to low , as is done in certain MiniDFSCluster methods.