}
public void testUpdateAvailableWithBlockRecovery() throws Exception {
// Fail the test if any node is added to dead nodes.
final AtomicBoolean needFail = new AtomicBoolean(false);
InjectionHandler.set(new InjectionHandler() {
@Override
protected void _processEvent(InjectionEventI event, Object... args) {
if (event == InjectionEvent.DFSCLIENT_BEFORE_ADD_DEADNODES) {
needFail.set(true);
try {
throw new Exception("for call stack");
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
final Path p = new Path("/testUpdateAvailableWithBlockRecovery");
System.out.println("p=" + p);
final int len1 = (int) BLOCK_SIZE / 4 - 3;
FSDataOutputStream out = fs.create(p, false, buffersize, REPLICATION,
BLOCK_SIZE);
FSDataInputStream in = fs.open(p);
AppendTestUtil.write(out, 0, len1);
out.sync();
// Make sure the input stream select the first datanode to read.
final DatanodeInfo targetNode = ((DFSOutputStream) (out.getWrappedStream())).nodes[0];
InjectionHandler.set(new InjectionHandler() {
@Override
protected void _processEventIO(InjectionEventI event, Object... args)
throws IOException {
if (event == InjectionEvent.DFSCLIENT_BEFORE_BEST_NODE) {
DatanodeInfo[] nodes = (DatanodeInfo[]) args[0];
int index = 0;
for (;index < nodes.length; index++) {
if (nodes[index].equals(targetNode)) {
break;
}
}
if (index > 0 && index < nodes.length) {
DatanodeInfo tempInfo = nodes[0];
nodes[0] = nodes[index];
nodes[index] = tempInfo;
}
}
}
});
int available = in.available();
TestCase.assertEquals(len1, available);
int i = 0;
for(; i < len1; i++) {
TestCase.assertEquals((byte)i, (byte)in.read());
}
// Remove the first datanode out of the pipelinebbccbc
InjectionHandler.set(new InjectionHandler() {
int thrownCount = 0;
@Override
protected void _processEventIO(InjectionEventI event, Object... args)
throws IOException {
if (event == InjectionEvent.DFSCLIENT_DATASTREAM_BEFORE_WRITE