/* * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.rt.execution.junit; import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.Vector; /** * Before rename or move * @see com.intellij.execution.junit.JUnitConfiguration#JUNIT_START_CLASS * @noinspection HardCodedStringLiteral */ public class JUnitStarter { public static final int VERSION = 5; public static final String IDE_VERSION = "-ideVersion"; public static final String JUNIT3_PARAMETER = "-junit3"; public static final String JUNIT4_PARAMETER = "-junit4"; public static final String JUNIT5_PARAMETER = "-junit5"; public static final String JUNIT5_KEY = "idea.is.junit5"; private static final String SOCKET = "-socket"; public static final String JUNIT3_RUNNER_NAME = "com.intellij.junit3.JUnit3IdeaTestRunner"; public static final String JUNIT4_RUNNER_NAME = "com.intellij.junit4.JUnit4IdeaTestRunner"; public static final String JUNIT5_RUNNER_NAME = "com.intellij.junit5.JUnit5IdeaTestRunner"; private static String ourForkMode; private static String ourCommandFileName; private static String ourWorkingDirs; protected static int ourCount = 1; public static String ourRepeatCount = null; public static void main(String[] args) throws IOException { Vector argList = new Vector(); for (int i = 0; i < args.length; i++) { String arg = args[i]; argList.addElement(arg); } final ArrayList listeners = new ArrayList(); final String[] name = new String[1]; String agentName = processParameters(argList, listeners, name); if (!JUNIT5_RUNNER_NAME.equals(agentName) && !canWorkWithJUnitVersion(System.err, agentName)) { System.exit(-3); } if (!checkVersion(args, System.err)) { System.exit(-3); } String[] array = new String[argList.size()]; argList.copyInto(array); int exitCode = prepareStreamsAndStart(array, agentName, listeners, name[0]); System.exit(exitCode); } private static String processParameters(Vector args, final List listeners, String[] params) { String agentName = isJUnit5Preferred() ? JUNIT5_RUNNER_NAME : JUNIT4_RUNNER_NAME; Vector result = new Vector(args.size()); for (int i = 0; i < args.size(); i++) { String arg = (String)args.get(i); if (arg.startsWith(IDE_VERSION)) { //ignore } else if (arg.equals(JUNIT3_PARAMETER)){ agentName = JUNIT3_RUNNER_NAME; } else if (arg.equals(JUNIT4_PARAMETER)) { agentName = JUNIT4_RUNNER_NAME; } else if (arg.equals(JUNIT5_PARAMETER)) { agentName = JUNIT5_RUNNER_NAME; } else { if (arg.startsWith("@name")) { params[0] = arg.substring("@name".length()); continue; } else if (arg.startsWith("@w@")) { ourWorkingDirs = arg.substring(3); continue; } else if (arg.startsWith("@@@")) { final int pos = arg.indexOf(','); ourForkMode = arg.substring(3, pos); ourCommandFileName = arg.substring(pos + 1); continue; } else if (arg.startsWith("@@")) { if (new File(arg.substring(2)).exists()) { try { final BufferedReader reader = new BufferedReader(new FileReader(arg.substring(2))); String line; while ((line = reader.readLine()) != null) { listeners.add(line); } } catch (Exception e) { e.printStackTrace(); } } continue; } else if (arg.startsWith(SOCKET)) { final int port = Integer.parseInt(arg.substring(SOCKET.length())); try { final Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), port); //start collecting tests final DataInputStream os = new DataInputStream(socket.getInputStream()); try { os.readBoolean();//wait for ready flag } finally { os.close(); } } catch (IOException e) { e.printStackTrace(); } continue; } final int count = RepeatCount.getCount(arg); if (count != 0) { ourRepeatCount = arg; ourCount = count; continue; } result.addElement(arg); } } args.removeAllElements(); for (int i = 0; i < result.size(); i++) { String arg = (String)result.get(i); args.addElement(arg); } if (JUNIT3_RUNNER_NAME.equals(agentName)) { try { Class.forName("org.junit.runner.Computer"); agentName = JUNIT4_RUNNER_NAME; } catch (ClassNotFoundException e) { return JUNIT3_RUNNER_NAME; } } if (JUNIT4_RUNNER_NAME.equals(agentName)) { try { Class.forName("org.junit.Test"); } catch (ClassNotFoundException e) { return JUNIT3_RUNNER_NAME; } } try { final String forceJUnit3 = System.getProperty("idea.force.junit3"); if (forceJUnit3 != null && Boolean.valueOf(forceJUnit3).booleanValue()) return JUNIT3_RUNNER_NAME; } catch (SecurityException ignored) {} return agentName; } public static boolean isJUnit5Preferred() { final String useJUnit5 = System.getProperty(JUNIT5_KEY); if (useJUnit5 == null) { return JUnit5EngineDetector.hasCustomEngine(); } else { final Boolean boolValue = Boolean.valueOf(useJUnit5); return boolValue != null && boolValue.booleanValue(); } } public static boolean checkVersion(String[] args, PrintStream printStream) { for (int i = 0; i < args.length; i++) { String arg = args[i]; if (arg.startsWith(IDE_VERSION)) { int ideVersion = Integer.parseInt(arg.substring(IDE_VERSION.length(), arg.length())); if (ideVersion != VERSION) { printStream.println("Wrong agent version: " + VERSION + ". IDE expects version: " + ideVersion); printStream.flush(); return false; } else return true; } } return false; } private static boolean canWorkWithJUnitVersion(PrintStream printStream, String agentName) { try { junitVersionChecks(agentName); } catch (Throwable e) { printStream.println("!!! JUnit version 3.8 or later expected:"); printStream.println(); e.printStackTrace(printStream); printStream.flush(); return false; } finally { printStream.flush(); } return true; } private static void junitVersionChecks(String agentName) throws ClassNotFoundException { Class.forName("junit.framework.ComparisonFailure"); getAgentClass(agentName); //noinspection UnnecessaryFullyQualifiedName new junit.textui.TestRunner().setPrinter(null); // } private static int prepareStreamsAndStart(String[] args, final String agentName, ArrayList listeners, String name) { try { IdeaTestRunner testRunner = (IdeaTestRunner)getAgentClass(agentName).newInstance(); if (ourCommandFileName != null) { if (!"none".equals(ourForkMode) || ourWorkingDirs != null && new File(ourWorkingDirs).length() > 0) { final List newArgs = new ArrayList(); newArgs.add(agentName); newArgs.addAll(listeners); return new JUnitForkedSplitter(ourWorkingDirs, ourForkMode, newArgs) .startSplitting(args, name, ourCommandFileName, ourRepeatCount); } } return IdeaTestRunner.Repeater.startRunnerWithArgs(testRunner, args, listeners, name, ourCount, true); } catch (Exception e) { e.printStackTrace(System.err); return -2; } } static Class getAgentClass(String agentName) throws ClassNotFoundException { return Class.forName(agentName); } public static void printClassesList(List classNames, String packageName, String category, String filters, File tempFile) throws IOException { final PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "UTF-8")); try { writer.println(packageName); //package name writer.println(category); //category writer.println(filters); //patterns for (int i = 0; i < classNames.size(); i++) { writer.println(classNames.get(i)); } } finally { writer.close(); } } }