package water;
import static org.junit.Assert.*;
import org.junit.*;
import java.util.concurrent.ExecutionException;
import jsr166y.CountedCompleter;
import water.fvec.Chunk;
import water.fvec.FileVec;
import water.fvec.Vec;
public class MRThrow extends TestUtil {
@BeforeClass static public void setup() { stall_till_cloudsize(5);}
@Test public void testLots() {
for( int i=0; i<10; i++ )
testInvokeThrow();
}
// ---
// Map in h2o.jar - a multi-megabyte file - into Arraylets.
// Run a distributed byte histogram. Throw an exception in *some* map call,
// and make sure it's forwarded to the invoke.
@Test public void testInvokeThrow() {
int sz = H2O.CLOUD.size();
Vec vec = Vec.makeZero((sz+1)*FileVec.DFLT_CHUNK_SIZE+1);
try {
for(int i = 0; i < sz; ++i) {
ByteHistoThrow bh = new ByteHistoThrow(H2O.CLOUD._memary[i]);
Throwable ex=null;
try {
bh.doAll(vec); // invoke should throw DistributedException wrapped up in RunTimeException
} catch( RuntimeException e ) {
ex = e;
assertTrue(e.getMessage().contains("test") || e.getCause().getMessage().contains("test"));
} catch( Throwable e2 ) {
(ex=e2).printStackTrace();
fail("Expected RuntimeException, got " + ex.toString());
}
if( ex == null ) fail("should've thrown");
}
} finally {
if( vec != null ) vec.remove(); // remove from DKV
}
}
@Test public void testContinuationThrow() throws InterruptedException, ExecutionException {
int sz = H2O.CLOUD.size();
Vec vec = Vec.makeZero((sz+1)*FileVec.DFLT_CHUNK_SIZE+1);
try {
for(int i = 0; i < H2O.CLOUD._memary.length; ++i){
final ByteHistoThrow bh = new ByteHistoThrow(H2O.CLOUD._memary[i]);
final boolean [] ok = new boolean[]{false};
try {
CountedCompleter cc = new CountedCompleter() {
@Override public void compute() { tryComplete(); }
@Override public boolean onExceptionalCompletion(Throwable ex, CountedCompleter cc){
ok[0] = ex.getMessage().contains("test");
return super.onExceptionalCompletion(ex,cc);
}
};
bh.setCompleter(cc);
bh.dfork(vec);
// If the chosen file is too small for the cluster, some nodes will have *no* work
// and so no exception is thrown.
cc.join();
} catch( RuntimeException re ) {
assertTrue(re.getMessage().contains("test") || re.getCause().getMessage().contains("test"));
// } catch( ExecutionException e ) { // caught on self
// assertTrue(e.getMessage().contains("test"));
} catch( java.lang.AssertionError ae ) {
throw ae; // Standard junit failure reporting assertion
} catch(Throwable ex) {
ex.printStackTrace();
fail("Unexpected exception" + ex.toString());
}
}
} finally {
if( vec != null ) vec.remove(); // remove from DKV
}
}
// Byte-wise histogram
public static class ByteHistoThrow extends MRTask<ByteHistoThrow> {
final H2ONode _throwAt;
int[] _x;
ByteHistoThrow( H2ONode h2o ) { _throwAt = h2o; }
// Count occurrences of bytes
@Override public void map( Chunk chk ) {
_x = new int[256]; // One-time set histogram array
byte[] bits = chk.getBytes(); // Raw file bytes
for( byte b : bits ) // Compute local histogram
_x[b&0xFF]++;
if( H2O.SELF.equals(_throwAt) )
throw new RuntimeException("test");
}
// ADD together all results
@Override public void reduce( ByteHistoThrow bh ) { water.util.ArrayUtils.add(_x,bh._x); }
}
}