package water; import hex.*; import hex.trees.TreeTestWithBalanceAndCrossVal; import org.apache.commons.lang.ArrayUtils; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import water.deploy.Node; import water.deploy.NodeVM; import water.fvec.ParseExceptionTest; import water.fvec.ParserTest2; import water.parser.ParseFolderTestBig; import water.util.Log; import water.util.Utils; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import java.net.ServerSocket; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class JUnitRunner { // TODO @Retention(RetentionPolicy.RUNTIME) public @interface Nightly { } private static void filter(List<Class> tests) { // Requires separate datasets project tests.remove(ParseFolderTestBig.class); // Too slow tests.remove(ConcurrentKeyTest.class); tests.remove(DeepLearningIrisTest.Long.class); tests.remove(DeepLearningProstateTest.Long.class); tests.remove(DeepLearningProstateTest.Mid.class); tests.remove(GLMRandomTest.Long.class); tests.remove(ParserTest2.ParseAllSmalldata.class); tests.remove(ParseExceptionTest.class); // Skip abstract test tests.remove(TreeTestWithBalanceAndCrossVal.class); // Pure JUnit test // tests.remove(CBSChunkTest.class); //tests.remove(GBMDomainTest.class); } public static void main(String[] args) throws Exception { // Can be necessary to run in parallel to other clouds, so find open ports int[] ports = new int[3]; int port = 54321; for( int i = 0; i < ports.length; i++ ) { for( ;; ) { if( isOpen(port) && isOpen(port + 1) ) { ports[i] = port; port += 2; break; } port++; } } String flat = ""; for( int i = 0; i < ports.length; i++ ) flat += "127.0.0.1:" + ports[i] + "\n"; // Force all IPs to local so that users can run with a firewall String[] a = new String[] { "-ip", "127.0.0.1", "-flatfile", Utils.writeFile(flat).getAbsolutePath() }; H2O.OPT_ARGS.ip = "127.0.0.1"; args = (String[]) ArrayUtils.addAll(a, args); ArrayList<Node> nodes = new ArrayList<Node>(); for( int i = 1; i < ports.length; i++ ) nodes.add(new NodeVM(Utils.append(args, "-port", "" + ports[i]))); args = Utils.append(new String[] { "-mainClass", Master.class.getName() }, args); Node master = new NodeVM(Utils.append(args, "-port", "" + ports[0])); nodes.add(master); File out = null, err = null, sandbox = new File("sandbox"); sandbox.mkdirs(); Utils.clearFolder(sandbox); for( int i = 0; i < nodes.size(); i++ ) { out = File.createTempFile("junit-" + i + "-out-", null, sandbox); err = File.createTempFile("junit-" + i + "-err-", null, sandbox); nodes.get(i).persistIO(out.getAbsolutePath(), err.getAbsolutePath()); nodes.get(i).start(); } int exit = master.waitFor(); if( exit != 0 ) { Log.log(out, System.out); Thread.sleep(100); // Or mixed (?) Log.log(err, System.err); } for( Node node : nodes ) node.kill(); if( exit == 0 ) System.out.println("OK"); System.exit(exit); } private static boolean isOpen(int port) throws Exception { ServerSocket s = null; try { s = new ServerSocket(port); return true; } catch( IOException ex ) { return false; } finally { if( s != null ) s.close(); } } static List<Class> all() { List<String> names = Boot.getClasses(); names.remove("water.Boot"); // In case called from Boot loader names.remove("water.Weaver"); Collections.sort(names); // For deterministic runs List<Class> tests = new ArrayList<Class>(); Log._dontDie = true; for( String name : names ) { try { Class c = Class.forName(name); if( isTest(c) ) tests.add(c); } catch( Throwable xe ) { } } if( tests.size() == 0 ) throw new RuntimeException("Failed to find tests"); filter(tests); return tests; } public static boolean isTest(Class c) { for( Annotation a : c.getAnnotations() ) if( a instanceof Ignore ) return false; for( Method m : c.getMethods() ) for( Annotation a : m.getAnnotations() ) if( a instanceof Test ) return true; return false; } public static class Master { public static void main(String[] args) { try { H2O.main(args); TestUtil.stall_till_cloudsize(3); List<Class> tests = JUnitRunner.all(); Result r = org.junit.runner.JUnitCore.runClasses(tests.toArray(new Class[0])); if( r.getFailureCount() == 0 ) { System.out.println("Successfully ran the following tests in " + (r.getRunTime() / 1000) + "s"); for( Class c : tests ) System.out.println(c.getName()); } else { for( Failure f : r.getFailures() ) { System.err.println(f.getDescription()); if( f.getException() != null ) f.getException().printStackTrace(); } } System.exit(r.getFailureCount()); } catch( Throwable t ) { t.printStackTrace(); System.exit(1); } } } }