@@ -0,0 +1,2508 @@
+package hex.tree.drf;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.concurrent.Callable;%0Aimport java.util.concurrent.ExecutorService;%0Aimport java.util.concurrent.Executors;%0Aimport java.util.concurrent.Future;%0A%0Aimport hex.tree.drf.DRFModel.DRFParameters;%0Aimport org.junit.Assume;%0Aimport org.junit.BeforeClass;%0Aimport org.junit.Test;%0Aimport org.junit.runner.RunWith;%0Aimport org.junit.runners.Parameterized;%0Aimport water.*;%0Aimport water.fvec.Frame;%0Aimport water.parser.ParseSetup;%0A%0Aimport static org.junit.Assert.assertNotNull;%0A%0A/**%0A * Based on a reproducer of a bug PUBDEV-7193 kindly provided by https://github.com/SimonSchmid%0A */%0A@RunWith(Parameterized.class)%0Apublic class DRFConcurrent2Test extends TestUtil %7B%0A  %0A  private static final int REPEAT_N = 3;%0A  %0A  @Parameterized.Parameters%0A  public static Object%5B%5D repeated() %7B // emulating multiple runs%0A    return new Object%5BREPEAT_N%5D;%0A  %7D%0A  %0A  @Parameterized.Parameter%0A  public Object run; %0A  %0A  @BeforeClass%0A  public static void setup() %7B%0A    stall_till_cloudsize(1);%0A  %7D%0A%0A  @Test%0A  public void testConcurrent() throws Exception %7B%0A    Assume.assumeTrue(H2O.getCloudSize() == 1); // don't test in multi-node, not worth it - this tests already takes a long time%0A    Frame fr = null;%0A    try %7B%0A      fr = parse_test_file(%22./smalldata/jira/pubdev_7193.csv%22, new TestUtil.ParseSetupTransformer() %7B%0A        @Override%0A        public ParseSetup transformSetup(ParseSetup guessedSetup) %7B%0A          return guessedSetup.setCheckHeader(1);%0A        %7D%0A      %7D);%0A%0A      ExecutorService executor = Executors.newFixedThreadPool(2);%0A      List%3CCallable%3CDRFModel%3E%3E runnables = new ArrayList%3C%3E();%0A      for (int i = 0; i %3C 50; i++) %7B%0A        runnables.add(new DRFBuilder(fr));%0A      %7D%0A      for (Future%3CDRFModel%3E future : executor.invokeAll(runnables)) %7B%0A        assertNotNull(future.get());%0A      %7D%0A    %7D finally %7B%0A      if (fr != null)%0A        fr.delete();%0A    %7D%0A  %7D%0A%0A  private static class DRFBuilder implements Callable%3CDRFModel%3E %7B%0A%0A    private final Key%3CFrame%3E _train;%0A%0A    private DRFBuilder(Frame trainingFrame) %7B%0A      _train = trainingFrame._key;%0A    %7D%0A%0A    public DRFModel call() %7B%0A      DRFParameters params = new DRFParameters();%0A      params._response_column = %22C2%22;%0A      params._train = _train;%0A      DRF builder = new DRF(params);%0A      DRFModel model = null;%0A      try %7B%0A        model = builder.trainModel().get();%0A      %7D finally %7B%0A        if (model != null) %7B%0A          model.delete();%0A        %7D%0A      %7D%0A      return model;%0A    %7D%0A  %7D%0A%7D%0A

Add a test for race condition when DRF models are trained concurrently