diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 7f5c4e10a1d0..0c17f2fa2038 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -203,10 +203,15 @@ + + + testrunfactory + org.testng.DruidTestRunnerFactory + + -Duser.timezone=UTC -Dfile.encoding=UTF-8 - -Dtestrunfactory=org.testng.DruidTestRunnerFactory -Ddruid.test.config.dockerIp=${env.DOCKER_IP} -Ddruid.test.config.hadoopDir=${env.HADOOP_DIR} -Ddruid.zk.service.host=${env.DOCKER_IP} @@ -248,10 +253,15 @@ + + + testrunfactory + org.testng.DruidTestRunnerFactory + + -Duser.timezone=UTC -Dfile.encoding=UTF-8 - -Dtestrunfactory=org.testng.DruidTestRunnerFactory -Ddruid.test.config.type=configFile -Ddruid.test.config.configFile=${env.CONFIG_FILE} diff --git a/integration-tests/src/main/java/org/testng/TestNG.java b/integration-tests/src/main/java/org/testng/TestNG.java deleted file mode 100644 index 0586a81519bc..000000000000 --- a/integration-tests/src/main/java/org/testng/TestNG.java +++ /dev/null @@ -1,2207 +0,0 @@ -/* - * Licensed to Metamarkets Group Inc. (Metamarkets) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. Metamarkets licenses this file - * to you 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 org.testng; - -import com.beust.jcommander.JCommander; -import com.beust.jcommander.ParameterException; -import org.testng.annotations.ITestAnnotation; -import org.testng.collections.Lists; -import org.testng.collections.Maps; -import org.testng.internal.ClassHelper; -import org.testng.internal.Configuration; -import org.testng.internal.DynamicGraph; -import org.testng.internal.IConfiguration; -import org.testng.internal.IResultListener2; -import org.testng.internal.OverrideProcessor; -import org.testng.internal.SuiteRunnerMap; -import org.testng.internal.Utils; -import org.testng.internal.Version; -import org.testng.internal.annotations.DefaultAnnotationTransformer; -import org.testng.internal.annotations.IAnnotationFinder; -import org.testng.internal.annotations.JDK15AnnotationFinder; -import org.testng.internal.annotations.Sets; -import org.testng.internal.thread.graph.GraphThreadPoolExecutor; -import org.testng.internal.thread.graph.IThreadWorkerFactory; -import org.testng.internal.thread.graph.SuiteWorkerFactory; -import org.testng.junit.JUnitTestFinder; -import org.testng.log4testng.Logger; -import org.testng.remote.SuiteDispatcher; -import org.testng.remote.SuiteSlave; -import org.testng.reporters.EmailableReporter; -import org.testng.reporters.EmailableReporter2; -import org.testng.reporters.FailedReporter; -import org.testng.reporters.JUnitReportReporter; -import org.testng.reporters.SuiteHTMLReporter; -import org.testng.reporters.VerboseReporter; -import org.testng.reporters.XMLReporter; -import org.testng.reporters.jq.Main; -import org.testng.xml.Parser; -import org.testng.xml.XmlClass; -import org.testng.xml.XmlInclude; -import org.testng.xml.XmlMethodSelector; -import org.testng.xml.XmlSuite; -import org.testng.xml.XmlTest; -import org.xml.sax.SAXException; - -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import static org.testng.internal.Utils.defaultIfStringEmpty; -import static org.testng.internal.Utils.isStringEmpty; -import static org.testng.internal.Utils.isStringNotEmpty; - -/** - * Class copied from TestNG library ver 6.8.7 to apply a workaround for http://jira.codehaus.org/browse/SUREFIRE-622 - * To Locate the PATCHED AREA search for keyword "PATCH" in this class file - *

- *

- * This class is the main entry point for running tests in the TestNG framework. - * Users can create their own TestNG object and invoke it in many different - * ways: - *

    - *
  • On an existing testng.xml - *
  • On a synthetic testng.xml, created entirely from Java - *
  • By directly setting the test classes - *
- * You can also define which groups to include or exclude, assign parameters, etc... - *

- * The command line parameters are: - *

    - *
  • -d outputdir: specify the output directory
  • - *
  • -testclass class_name: specifies one or several class names
  • - *
  • -testjar jar_name: specifies the jar containing the tests
  • - *
  • -sourcedir src1;src2: ; separated list of source directories - * (used only when javadoc annotations are used)
  • - *
  • -target
  • - *
  • -groups
  • - *
  • -testrunfactory
  • - *
  • -listener
  • - *
- *

- * Please consult documentation for more details. - *

- * FIXME: should support more than simple paths for suite xmls - * - * @author Cedric Beust - * @author Alex Popescu - * @see #usage() - */ -public class TestNG -{ - - /** - * This class' log4testng Logger. - */ - private static final Logger LOGGER = Logger.getLogger(TestNG.class); - - /** - * The default name for a suite launched from the command line - */ - public static final String DEFAULT_COMMAND_LINE_SUITE_NAME = "Command line suite"; - - /** - * The default name for a test launched from the command line - */ - public static final String DEFAULT_COMMAND_LINE_TEST_NAME = "Command line test"; - - /** - * The default name of the result's output directory (keep public, used by Eclipse). - */ - public static final String DEFAULT_OUTPUTDIR = "test-output"; - - /** - * System properties - */ - public static final String SHOW_TESTNG_STACK_FRAMES = "testng.show.stack.frames"; - public static final String TEST_CLASSPATH = "testng.test.classpath"; - - private static TestNG m_instance; - - protected static JCommander m_jCommander; - - private List m_commandLineMethods; - protected List m_suites = Lists.newArrayList(); - private List m_cmdlineSuites; - private String m_outputDir = DEFAULT_OUTPUTDIR; - - private String[] m_includedGroups; - private String[] m_excludedGroups; - - private Boolean m_isJUnit = XmlSuite.DEFAULT_JUNIT; - private Boolean m_isMixed = XmlSuite.DEFAULT_MIXED; - protected boolean m_useDefaultListeners = true; - - private ITestRunnerFactory m_testRunnerFactory; - - // These listeners can be overridden from the command line - private List m_testListeners = Lists.newArrayList(); - private List m_suiteListeners = Lists.newArrayList(); - private Set m_reporters = Sets.newHashSet(); - - protected static final int HAS_FAILURE = 1; - protected static final int HAS_SKIPPED = 2; - protected static final int HAS_FSP = 4; - protected static final int HAS_NO_TEST = 8; - - public static final Integer DEFAULT_VERBOSE = 1; - - private int m_status; - private boolean m_hasTests = false; - - private String m_slavefileName = null; - private String m_masterfileName = null; - - // Command line suite parameters - private int m_threadCount; - private boolean m_useThreadCount; - private String m_parallelMode; - private boolean m_useParallelMode; - private String m_configFailurePolicy; - private Class[] m_commandLineTestClasses; - - private String m_defaultSuiteName = DEFAULT_COMMAND_LINE_SUITE_NAME; - private String m_defaultTestName = DEFAULT_COMMAND_LINE_TEST_NAME; - - private Map m_methodDescriptors = Maps.newHashMap(); - - private ITestObjectFactory m_objectFactory; - - private List m_invokedMethodListeners = Lists.newArrayList(); - - private Integer m_dataProviderThreadCount = null; - - private String m_jarPath; - /** - * The path of the testng.xml file inside the jar file - */ - private String m_xmlPathInJar = CommandLineArgs.XML_PATH_IN_JAR_DEFAULT; - - private List m_stringSuites = Lists.newArrayList(); - - private IHookable m_hookable; - private IConfigurable m_configurable; - - protected long m_end; - protected long m_start; - - private List m_executionListeners = Lists.newArrayList(); - - private boolean m_isInitialized = false; - - /** - * Default constructor. Setting also usage of default listeners/reporters. - */ - public TestNG() - { - init(true); - } - - /** - * Used by maven2 to have 0 output of any kind come out - * of testng. - * - * @param useDefaultListeners Whether or not any default reports - * should be added to tests. - */ - public TestNG(boolean useDefaultListeners) - { - init(useDefaultListeners); - } - - private void init(boolean useDefaultListeners) - { - m_instance = this; - - m_useDefaultListeners = useDefaultListeners; - m_configuration = new Configuration(); - } - - public int getStatus() - { - return m_status; - } - - private void setStatus(int status) - { - m_status |= status; - } - - /** - * Sets the output directory where the reports will be created. - * - * @param outputdir The directory. - */ - public void setOutputDirectory(final String outputdir) - { - if (isStringNotEmpty(outputdir)) { - m_outputDir = outputdir; - } - } - - /** - * If this method is passed true before run(), the default listeners - * will not be used. - *

    - *
  • org.testng.reporters.TestHTMLReporter - *
  • org.testng.reporters.JUnitXMLReporter - *
  • org.testng.reporters.XMLReporter - *
- * - * @see org.testng.reporters.TestHTMLReporter - * @see org.testng.reporters.JUnitXMLReporter - * @see XMLReporter - */ - public void setUseDefaultListeners(boolean useDefaultListeners) - { - m_useDefaultListeners = useDefaultListeners; - } - - /** - * Sets a jar containing a testng.xml file. - * - * @param jarPath - */ - public void setTestJar(String jarPath) - { - m_jarPath = jarPath; - } - - /** - * Sets the path to the XML file in the test jar file. - */ - public void setXmlPathInJar(String xmlPathInJar) - { - m_xmlPathInJar = xmlPathInJar; - } - - public void initializeSuitesAndJarFile() - { - // The Eclipse plug-in (RemoteTestNG) might have invoked this method already - // so don't initialize suites twice. - if (m_isInitialized) { - return; - } - - m_isInitialized = true; - if (m_suites.size() > 0) { - //to parse the suite files (), if any - for (XmlSuite s : m_suites) { - - for (String suiteFile : s.getSuiteFiles()) { - try { - Collection childSuites = getParser(suiteFile).parse(); - for (XmlSuite cSuite : childSuites) { - cSuite.setParentSuite(s); - s.getChildSuites().add(cSuite); - } - } - catch (ParserConfigurationException | SAXException | IOException e) { - LOGGER.error("", e); - } - } - - } - return; - } - - // - // Parse the suites that were passed on the command line - // - for (String suitePath : m_stringSuites) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("suiteXmlPath: \"" + suitePath + "\""); - } - try { - Collection allSuites = getParser(suitePath).parse(); - - for (XmlSuite s : allSuites) { - // If test names were specified, only run these test names - if (m_testNames != null) { - m_suites.add(extractTestNames(s, m_testNames)); - } else { - m_suites.add(s); - } - } - } - catch (IOException | SAXException | ParserConfigurationException e) { - LOGGER.error("", e); - } - catch (Exception ex) { - // Probably a Yaml exception, unnest it - Throwable t = ex; - while (t.getCause() != null) { - t = t.getCause(); - } - if (t instanceof TestNGException) { - throw (TestNGException) t; - } else { - throw new TestNGException(t); - } - } - } - - // - // jar path - // - // If suites were passed on the command line, they take precedence over the suite file - // inside that jar path - if (m_jarPath != null && m_stringSuites.size() > 0) { - StringBuilder suites = new StringBuilder(); - for (String s : m_stringSuites) { - suites.append(s); - } - Utils.log( - "TestNG", 2, "Ignoring the XML file inside " + m_jarPath + " and using " - + suites + " instead" - ); - return; - } - if (isStringEmpty(m_jarPath)) { - return; - } - - // We have a jar file and no XML file was specified: try to find an XML file inside the jar - File jarFile = new File(m_jarPath); - - try { - - Utils.log("TestNG", 2, "Trying to open jar file:" + jarFile); - - JarFile jf = new JarFile(jarFile); - Enumeration entries = jf.entries(); - List classes = Lists.newArrayList(); - boolean foundTestngXml = false; - while (entries.hasMoreElements()) { - JarEntry je = entries.nextElement(); - if (je.getName().equals(m_xmlPathInJar)) { - Parser parser = getParser(jf.getInputStream(je)); - m_suites.addAll(parser.parse()); - foundTestngXml = true; - break; - } else if (je.getName().endsWith(".class")) { - int n = je.getName().length() - ".class".length(); - classes.add(je.getName().replace("/", ".").substring(0, n)); - } - } - if (!foundTestngXml) { - Utils.log( - "TestNG", 1, - "Couldn't find the " + m_xmlPathInJar + " in the jar file, running all the classes" - ); - XmlSuite xmlSuite = new XmlSuite(); - xmlSuite.setVerbose(0); - xmlSuite.setName("Jar suite"); - XmlTest xmlTest = new XmlTest(xmlSuite); - List xmlClasses = Lists.newArrayList(); - for (String cls : classes) { - XmlClass xmlClass = new XmlClass(cls); - xmlClasses.add(xmlClass); - } - xmlTest.setXmlClasses(xmlClasses); - m_suites.add(xmlSuite); - } - } - catch (ParserConfigurationException | SAXException | IOException ex) { - LOGGER.error("", ex); - } - } - - private Parser getParser(String path) - { - Parser result = new Parser(path); - initProcessor(result); - return result; - } - - private Parser getParser(InputStream is) - { - Parser result = new Parser(is); - initProcessor(result); - return result; - } - - private void initProcessor(Parser result) - { - result.setPostProcessor(new OverrideProcessor(m_includedGroups, m_excludedGroups)); - } - - /** - * If the XmlSuite contains at least one test named as testNames, return - * an XmlSuite that's made only of these tests, otherwise, return the - * original suite. - */ - private static XmlSuite extractTestNames(XmlSuite s, List testNames) - { - List tests = Lists.newArrayList(); - for (XmlTest xt : s.getTests()) { - for (String tn : testNames) { - if (xt.getName().equals(tn)) { - tests.add(xt); - } - } - } - - if (tests.size() == 0) { - return s; - } else { - XmlSuite result = (XmlSuite) s.clone(); - result.getTests().clear(); - result.getTests().addAll(tests); - return result; - } - } - - /** - * Define the number of threads in the thread pool. - */ - public void setThreadCount(int threadCount) - { - if (threadCount < 1) { - exitWithError("Cannot use a threadCount parameter less than 1; 1 > " + threadCount); - } - - m_threadCount = threadCount; - m_useThreadCount = true; - } - - /** - * Define whether this run will be run in parallel mode. - */ - public void setParallel(String parallel) - { - m_parallelMode = parallel; - m_useParallelMode = true; - } - - public void setCommandLineSuite(XmlSuite suite) - { - m_cmdlineSuites = Lists.newArrayList(); - m_cmdlineSuites.add(suite); - m_suites.add(suite); - } - - /** - * Set the test classes to be run by this TestNG object. This method - * will create a dummy suite that will wrap these classes called - * "Command Line Test". - *

- * If used together with threadCount, parallel, groups, excludedGroups than this one must be set first. - * - * @param classes An array of classes that contain TestNG annotations. - */ - public void setTestClasses(Class[] classes) - { - m_suites.clear(); - m_commandLineTestClasses = classes; - } - - /** - * Given a string com.example.Foo.f1, return an array where [0] is the class and [1] - * is the method. - */ - private String[] splitMethod(String m) - { - int index = m.lastIndexOf("."); - if (index < 0) { - throw new TestNGException( - "Bad format for command line method:" + m - + ", expected ." - ); - } - - return new String[]{m.substring(0, index), m.substring(index + 1).replaceAll("\\*", "\\.\\*")}; - } - - /** - * @param commandLineMethods a string with the form "com.example.Foo.f1,com.example.Bar.f2" - * - * @return a list of XmlSuite objects that represent the list of classes and methods passed - * in parameter. - */ - private List createCommandLineSuitesForMethods(List commandLineMethods) - { - // - // Create the tag - // - Set classes = Sets.newHashSet(); - for (String m : commandLineMethods) { - Class c = ClassHelper.forName(splitMethod(m)[0]); - if (c != null) { - classes.add(c); - } - } - - List result = createCommandLineSuitesForClasses(classes.toArray(new Class[0])); - - // - // Add the method tags - // - List xmlClasses = Lists.newArrayList(); - for (XmlSuite s : result) { - for (XmlTest t : s.getTests()) { - xmlClasses.addAll(t.getClasses()); - } - } - - for (XmlClass xc : xmlClasses) { - for (String m : commandLineMethods) { - String[] split = splitMethod(m); - String className = split[0]; - if (xc.getName().equals(className)) { - XmlInclude includedMethod = new XmlInclude(split[1]); - xc.getIncludedMethods().add(includedMethod); - } - } - } - - return result; - } - - private List createCommandLineSuitesForClasses(Class[] classes) - { - // - // See if any of the classes has an xmlSuite or xmlTest attribute. - // If it does, create the appropriate XmlSuite, otherwise, create - // the default one - // - XmlClass[] xmlClasses = Utils.classesToXmlClasses(classes); - Map suites = Maps.newHashMap(); - IAnnotationFinder finder = m_configuration.getAnnotationFinder(); - - for (int i = 0; i < classes.length; i++) { - Class c = classes[i]; - ITestAnnotation test = finder.findAnnotation(c, ITestAnnotation.class); - String suiteName = getDefaultSuiteName(); - String testName = getDefaultTestName(); - boolean isJUnit = false; - if (test != null) { - suiteName = defaultIfStringEmpty(test.getSuiteName(), suiteName); - testName = defaultIfStringEmpty(test.getTestName(), testName); - } else { - if (m_isMixed && JUnitTestFinder.isJUnitTest(c)) { - isJUnit = true; - testName = c.getName(); - } - } - XmlSuite xmlSuite = suites.get(suiteName); - if (xmlSuite == null) { - xmlSuite = new XmlSuite(); - xmlSuite.setName(suiteName); - suites.put(suiteName, xmlSuite); - } - - if (m_dataProviderThreadCount != null) { - xmlSuite.setDataProviderThreadCount(m_dataProviderThreadCount); - } - XmlTest xmlTest = null; - for (XmlTest xt : xmlSuite.getTests()) { - if (xt.getName().equals(testName)) { - xmlTest = xt; - break; - } - } - - if (xmlTest == null) { - xmlTest = new XmlTest(xmlSuite); - xmlTest.setName(testName); - xmlTest.setJUnit(isJUnit); - } - - xmlTest.getXmlClasses().add(xmlClasses[i]); - } - - return new ArrayList(suites.values()); - } - - public void addMethodSelector(String className, int priority) - { - m_methodDescriptors.put(className, priority); - } - - /** - * Set the suites file names to be run by this TestNG object. This method tries to load and - * parse the specified TestNG suite xml files. If a file is missing, it is ignored. - * - * @param suites A list of paths to one more XML files defining the tests. For example: - *

- *

-   *                             TestNG tng = new TestNG();
-   *                             List suites = Lists.newArrayList();
-   *                             suites.add("c:/tests/testng1.xml");
-   *                             suites.add("c:/tests/testng2.xml");
-   *                             tng.setTestSuites(suites);
-   *                             tng.run();
-   *                             
- */ - public void setTestSuites(List suites) - { - m_stringSuites = suites; - } - - /** - * Specifies the XmlSuite objects to run. - * - * @param suites - * - * @see XmlSuite - */ - public void setXmlSuites(List suites) - { - m_suites = suites; - } - - /** - * Define which groups will be excluded from this run. - * - * @param groups A list of group names separated by a comma. - */ - public void setExcludedGroups(String groups) - { - m_excludedGroups = Utils.split(groups, ","); - } - - - /** - * Define which groups will be included from this run. - * - * @param groups A list of group names separated by a comma. - */ - public void setGroups(String groups) - { - m_includedGroups = Utils.split(groups, ","); - } - - - private void setTestRunnerFactoryClass(Class testRunnerFactoryClass) - { - setTestRunnerFactory((ITestRunnerFactory) ClassHelper.newInstance(testRunnerFactoryClass)); - } - - - protected void setTestRunnerFactory(ITestRunnerFactory itrf) - { - m_testRunnerFactory = itrf; - } - - public void setObjectFactory(Class c) - { - m_objectFactory = (ITestObjectFactory) ClassHelper.newInstance(c); - } - - public void setObjectFactory(ITestObjectFactory factory) - { - m_objectFactory = factory; - } - - /** - * Define which listeners to user for this run. - * - * @param classes A list of classes, which must be either ISuiteListener, - * ITestListener or IReporter - */ - public void setListenerClasses(List classes) - { - for (Class cls : classes) { - addListener(ClassHelper.newInstance(cls)); - } - } - - public void addListener(Object listener) - { - if (!(listener instanceof ITestNGListener)) { - exitWithError( - "Listener " + listener - + " must be one of ITestListener, ISuiteListener, IReporter, " - + " IAnnotationTransformer, IMethodInterceptor or IInvokedMethodListener" - ); - } else { - if (listener instanceof ISuiteListener) { - addListener((ISuiteListener) listener); - } - if (listener instanceof ITestListener) { - addListener((ITestListener) listener); - } - if (listener instanceof IReporter) { - addListener((IReporter) listener); - } - if (listener instanceof IAnnotationTransformer) { - setAnnotationTransformer((IAnnotationTransformer) listener); - } - if (listener instanceof IMethodInterceptor) { - setMethodInterceptor((IMethodInterceptor) listener); - } - if (listener instanceof IInvokedMethodListener) { - addInvokedMethodListener((IInvokedMethodListener) listener); - } - if (listener instanceof IHookable) { - setHookable((IHookable) listener); - } - if (listener instanceof IConfigurable) { - setConfigurable((IConfigurable) listener); - } - if (listener instanceof IExecutionListener) { - addExecutionListener((IExecutionListener) listener); - } - if (listener instanceof IConfigurationListener) { - getConfiguration().addConfigurationListener((IConfigurationListener) listener); - } - } - } - - public void addListener(IInvokedMethodListener listener) - { - m_invokedMethodListeners.add(listener); - } - - public void addListener(ISuiteListener listener) - { - if (null != listener) { - m_suiteListeners.add(listener); - } - } - - public void addListener(ITestListener listener) - { - if (null != listener) { - m_testListeners.add(listener); - } - } - - public void addListener(IReporter listener) - { - if (null != listener) { - m_reporters.add(listener); - } - } - - public void addInvokedMethodListener(IInvokedMethodListener listener) - { - m_invokedMethodListeners.add(listener); - } - - public Set getReporters() - { - return m_reporters; - } - - public List getTestListeners() - { - return m_testListeners; - } - - public List getSuiteListeners() - { - return m_suiteListeners; - } - - /** - * If m_verbose gets set, it will override the verbose setting in testng.xml - */ - private Integer m_verbose = null; - - private final IAnnotationTransformer m_defaultAnnoProcessor = new DefaultAnnotationTransformer(); - private IAnnotationTransformer m_annotationTransformer = m_defaultAnnoProcessor; - - private Boolean m_skipFailedInvocationCounts = false; - - private IMethodInterceptor m_methodInterceptor = null; - - /** - * The list of test names to run from the given suite - */ - private List m_testNames; - - private Integer m_suiteThreadPoolSize = CommandLineArgs.SUITE_THREAD_POOL_SIZE_DEFAULT; - - private boolean m_randomizeSuites = Boolean.FALSE; - - private boolean m_preserveOrder = false; - private Boolean m_groupByInstances; - - private IConfiguration m_configuration; - - /** - * Sets the level of verbosity. This value will override the value specified - * in the test suites. - * - * @param verbose the verbosity level (0 to 10 where 10 is most detailed) - * Actually, this is a lie: you can specify -1 and this will put TestNG - * in debug mode (no longer slicing off stack traces and all). - */ - public void setVerbose(int verbose) - { - m_verbose = verbose; - } - - private void initializeCommandLineSuites() - { - if (m_commandLineTestClasses != null || m_commandLineMethods != null) { - if (null != m_commandLineMethods) { - m_cmdlineSuites = createCommandLineSuitesForMethods(m_commandLineMethods); - } else { - m_cmdlineSuites = createCommandLineSuitesForClasses(m_commandLineTestClasses); - } - - for (XmlSuite s : m_cmdlineSuites) { - for (XmlTest t : s.getTests()) { - t.setPreserveOrder(m_preserveOrder ? "true " : "false"); - } - m_suites.add(s); - if (m_groupByInstances != null) { - s.setGroupByInstances(m_groupByInstances); - } - } - } - } - - private void initializeCommandLineSuitesParams() - { - if (null == m_cmdlineSuites) { - return; - } - - for (XmlSuite s : m_cmdlineSuites) { - if (m_useThreadCount) { - s.setThreadCount(m_threadCount); - } - if (m_useParallelMode) { - s.setParallel(m_parallelMode); - } - if (m_configFailurePolicy != null) { - s.setConfigFailurePolicy(m_configFailurePolicy.toString()); - } - } - - } - - private void initializeCommandLineSuitesGroups() - { - // If groups were specified on the command line, they should override groups - // specified in the XML file - boolean hasIncludedGroups = null != m_includedGroups && m_includedGroups.length > 0; - boolean hasExcludedGroups = null != m_excludedGroups && m_excludedGroups.length > 0; - List suites = m_cmdlineSuites != null ? m_cmdlineSuites : m_suites; - if (hasIncludedGroups || hasExcludedGroups) { - for (XmlSuite s : suites) { - //set on each test, instead of just the first one of the suite - for (XmlTest t : s.getTests()) { - if (hasIncludedGroups) { - t.setIncludedGroups(Arrays.asList(m_includedGroups)); - } - if (hasExcludedGroups) { - t.setExcludedGroups(Arrays.asList(m_excludedGroups)); - } - } - } - } - } - - private void addReporter(Class reporterClass) - { - if (m_reporters.stream().noneMatch(reporterClass::isInstance)) { - m_reporters.add(ClassHelper.newInstance(reporterClass)); - } - } - - private void initializeDefaultListeners() - { - m_testListeners.add(new ExitCodeListener(this)); - - if (m_useDefaultListeners) { - addReporter(SuiteHTMLReporter.class); - addReporter(Main.class); - addReporter(FailedReporter.class); - addReporter(XMLReporter.class); - if (System.getProperty("oldTestngEmailableReporter") != null) { - addReporter(EmailableReporter.class); - } else if (System.getProperty("noEmailableReporter") == null) { - addReporter(EmailableReporter2.class); - } - addReporter(JUnitReportReporter.class); - if (m_verbose != null && m_verbose > 4) { - addListener(new VerboseReporter("[TestNG] ")); - } - } - } - - private void initializeConfiguration() - { - ITestObjectFactory factory = m_objectFactory; - // - // Install the listeners found in ServiceLoader (or use the class - // loader for tests, if specified). - // - addServiceLoaderListeners(); - - // - // Install the listeners found in the suites - // - for (XmlSuite s : m_suites) { - for (String listenerName : s.getListeners()) { - Class listenerClass = ClassHelper.forName(listenerName); - - // If specified listener does not exist, a TestNGException will be thrown - if (listenerClass == null) { - throw new TestNGException( - "Listener " + listenerName - + " was not found in project's classpath" - ); - } - - Object listener = ClassHelper.newInstance(listenerClass); - addListener(listener); - } - - // - // Install the method selectors - // - for (XmlMethodSelector methodSelector : s.getMethodSelectors()) { - addMethodSelector(methodSelector.getClassName(), methodSelector.getPriority()); - } - - // - // Find if we have an object factory - // - if (s.getObjectFactory() != null) { - if (factory == null) { - factory = s.getObjectFactory(); - } else { - throw new TestNGException("Found more than one object-factory tag in your suites"); - } - } - } - - m_configuration.setAnnotationFinder(new JDK15AnnotationFinder(getAnnotationTransformer())); - m_configuration.setHookable(m_hookable); - m_configuration.setConfigurable(m_configurable); - m_configuration.setObjectFactory(factory); - } - - /** - * Using reflection to remain Java 5 compliant. - */ - private void addServiceLoaderListeners() - { - try { - Class c = Class.forName("java.util.ServiceLoader"); - List parameters = Lists.newArrayList(); - parameters.add(ITestNGListener.class); - Method loadMethod; - if (m_serviceLoaderClassLoader != null) { - parameters.add(m_serviceLoaderClassLoader); - loadMethod = c.getMethod("load", Class.class, ClassLoader.class); - } else { - loadMethod = c.getMethod("load", Class.class); - } - Iterable loader = - (Iterable) loadMethod.invoke(c, parameters.toArray()); - for (ITestNGListener l : loader) { - Utils.log("[TestNG]", 2, "Adding ServiceLoader listener:" + l); - addListener(l); - addServiceLoaderListener(l); - } - } - catch (ClassNotFoundException ex) { - // Ignore - } - catch (NoSuchMethodException ex) { - // Ignore - } - catch (IllegalAccessException ex) { - // Ignore - } - catch (InvocationTargetException ex) { - // Ignore - } - } - - /** - * Before suites are executed, do a sanity check to ensure all required - * conditions are met. If not, throw an exception to stop test execution - * - * @throws TestNGException if the sanity check fails - */ - private void sanityCheck() - { - checkTestNames(m_suites); - checkSuiteNames(m_suites); - } - - /** - * Ensure that two XmlTest within the same XmlSuite don't have the same name - */ - private void checkTestNames(List suites) - { - for (XmlSuite suite : suites) { - Set testNames = Sets.newHashSet(); - for (XmlTest test : suite.getTests()) { - if (testNames.contains(test.getName())) { - throw new TestNGException( - "Two tests in the same suite " - + "cannot have the same name: " + test.getName() - ); - } else { - testNames.add(test.getName()); - } - } - checkTestNames(suite.getChildSuites()); - } - } - - /** - * Ensure that two XmlSuite don't have the same name - * Otherwise will be clash in SuiteRunnerMap - * See issue #302 - */ - private void checkSuiteNames(List suites) - { - checkSuiteNamesInternal(suites, Sets.newHashSet()); - } - - private void checkSuiteNamesInternal(List suites, Set names) - { - for (XmlSuite suite : suites) { - final String name = suite.getName(); - if (names.contains(name)) { - throw new TestNGException("Two suites cannot have the same name: " + name); - } - names.add(name); - checkSuiteNamesInternal(suite.getChildSuites(), names); - } - } - - /** - * Run TestNG. - */ - public void run() - { - initializeSuitesAndJarFile(); - initializeConfiguration(); - initializeDefaultListeners(); - initializeCommandLineSuites(); - initializeCommandLineSuitesParams(); - initializeCommandLineSuitesGroups(); - - sanityCheck(); - - List suiteRunners = null; - - runExecutionListeners(true /* start */); - - m_start = System.currentTimeMillis(); - - if (m_slavefileName != null) { - // - // Slave mode - // - SuiteSlave slave = new SuiteSlave(m_slavefileName, this); - slave.waitForSuites(); - } else if (m_masterfileName == null) { - // - // Regular mode - // - suiteRunners = runSuitesLocally(); - } else { - // - // Master mode - // - SuiteDispatcher dispatcher = new SuiteDispatcher(m_masterfileName); - suiteRunners = dispatcher.dispatch( - getConfiguration(), - m_suites, getOutputDirectory(), - getTestListeners() - ); - } - - m_end = System.currentTimeMillis(); - runExecutionListeners(false /* finish */); - - if (null != suiteRunners) { - generateReports(suiteRunners); - } - - if (!m_hasTests) { - setStatus(HAS_NO_TEST); - if (TestRunner.getVerbose() > 1) { - LOGGER.error("[TestNG] No tests found. Nothing was run"); - usage(); - } - } - } - - private void runExecutionListeners(boolean start) - { - for (List listeners - : Arrays.asList(m_executionListeners, m_configuration.getExecutionListeners())) { - for (IExecutionListener l : listeners) { - if (start) { - l.onExecutionStart(); - } else { - l.onExecutionFinish(); - } - } - } - } - - public void addExecutionListener(IExecutionListener l) - { - m_executionListeners.add(l); - } - - private static void usage() - { - if (m_jCommander == null) { - m_jCommander = new JCommander(new CommandLineArgs()); - } - m_jCommander.usage(); - } - - private void generateReports(List suiteRunners) - { - for (IReporter reporter : m_reporters) { - try { - long start = System.currentTimeMillis(); - reporter.generateReport(m_suites, suiteRunners, m_outputDir); - Utils.log( - "TestNG", 2, "Time taken by " + reporter + ": " - + (System.currentTimeMillis() - start) + " ms" - ); - } - catch (Exception ex) { - LOGGER.error("[TestNG] Reporter " + reporter + " failed", ex); - } - } - } - - /** - * This needs to be public for maven2, for now..At least - * until an alternative mechanism is found. - */ - public List runSuitesLocally() - { - SuiteRunnerMap suiteRunnerMap = new SuiteRunnerMap(); - if (m_suites.size() > 0) { - if (m_suites.get(0).getVerbose() >= 2) { - Version.displayBanner(); - } - - // First initialize the suite runners to ensure there are no configuration issues. - // Create a map with XmlSuite as key and corresponding SuiteRunner as value - for (XmlSuite xmlSuite : m_suites) { - createSuiteRunners(suiteRunnerMap, xmlSuite); - } - - // - // Run suites - // - if (m_suiteThreadPoolSize == 1 && !m_randomizeSuites) { - // Single threaded and not randomized: run the suites in order - for (XmlSuite xmlSuite : m_suites) { - runSuitesSequentially( - xmlSuite, suiteRunnerMap, getVerbose(xmlSuite), - getDefaultSuiteName() - ); - } - } else { - // Multithreaded: generate a dynamic graph that stores the suite hierarchy. This is then - // used to run related suites in specific order. Parent suites are run only - // once all the child suites have completed execution - DynamicGraph suiteGraph = new DynamicGraph(); - for (XmlSuite xmlSuite : m_suites) { - populateSuiteGraph(suiteGraph, suiteRunnerMap, xmlSuite); - } - - IThreadWorkerFactory factory = new SuiteWorkerFactory( - suiteRunnerMap, - 0 /* verbose hasn't been set yet */, getDefaultSuiteName() - ); - GraphThreadPoolExecutor pooledExecutor = - new GraphThreadPoolExecutor( - suiteGraph, factory, m_suiteThreadPoolSize, - m_suiteThreadPoolSize, Integer.MAX_VALUE, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue() - ); - - Utils.log("TestNG", 2, "Starting executor for all suites"); - // Run all suites in parallel - pooledExecutor.run(); - try { - pooledExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); - pooledExecutor.shutdownNow(); - } - catch (InterruptedException handled) { - Thread.currentThread().interrupt(); - error("Error waiting for concurrent executors to finish " + handled.getMessage()); - } - } - } else { - setStatus(HAS_NO_TEST); - error("No test suite found. Nothing to run"); - usage(); - } - - // - // Generate the suites report - // - return Lists.newArrayList(suiteRunnerMap.values()); - } - - private static void error(String s) - { - LOGGER.error(s); - } - - /** - * @return the verbose level, checking in order: the verbose level on - * the suite, the verbose level on the TestNG object, or 1. - */ - private int getVerbose(XmlSuite xmlSuite) - { - int result = xmlSuite.getVerbose() != null ? xmlSuite.getVerbose() - : (m_verbose != null ? m_verbose : DEFAULT_VERBOSE); - return result; - } - - /** - * Recursively runs suites. Runs the children suites before running the parent - * suite. This is done so that the results for parent suite can reflect the - * combined results of the children suites. - * - * @param xmlSuite XML Suite to be executed - * @param suiteRunnerMap Maps {@code XmlSuite}s to respective {@code ISuite} - * @param verbose verbose level - * @param defaultSuiteName default suite name - */ - private void runSuitesSequentially( - XmlSuite xmlSuite, - SuiteRunnerMap suiteRunnerMap, int verbose, String defaultSuiteName - ) - { - for (XmlSuite childSuite : xmlSuite.getChildSuites()) { - runSuitesSequentially(childSuite, suiteRunnerMap, verbose, defaultSuiteName); - } - SuiteRunnerWorker srw = new SuiteRunnerWorker( - suiteRunnerMap.get(xmlSuite), suiteRunnerMap, - verbose, defaultSuiteName - ); - srw.run(); - } - - /** - * Populates the dynamic graph with the reverse hierarchy of suites. Edges are - * added pointing from child suite runners to parent suite runners, hence making - * parent suite runners dependent on all the child suite runners - * - * @param suiteGraph dynamic graph representing the reverse hierarchy of SuiteRunners - * @param suiteRunnerMap Map with XMLSuite as key and its respective SuiteRunner as value - * @param xmlSuite XML Suite - */ - private void populateSuiteGraph( - DynamicGraph suiteGraph /* OUT */, - SuiteRunnerMap suiteRunnerMap, XmlSuite xmlSuite - ) - { - ISuite parentSuiteRunner = suiteRunnerMap.get(xmlSuite); - if (xmlSuite.getChildSuites().isEmpty()) { - suiteGraph.addNode(parentSuiteRunner); - } else { - for (XmlSuite childSuite : xmlSuite.getChildSuites()) { - suiteGraph.addEdge(parentSuiteRunner, suiteRunnerMap.get(childSuite)); - populateSuiteGraph(suiteGraph, suiteRunnerMap, childSuite); - } - } - } - - /** - * Creates the {@code SuiteRunner}s and populates the suite runner map with - * this information - * - * @param suiteRunnerMap Map with XMLSuite as key and it's respective - * SuiteRunner as value. This is updated as part of this method call - * @param xmlSuite Xml Suite (and its children) for which {@code SuiteRunner}s are created - */ - private void createSuiteRunners(SuiteRunnerMap suiteRunnerMap /* OUT */, XmlSuite xmlSuite) - { - if (null != m_isJUnit && !m_isJUnit.equals(XmlSuite.DEFAULT_JUNIT)) { - xmlSuite.setJUnit(m_isJUnit); - } - - // If the skip flag was invoked on the command line, it - // takes precedence - if (null != m_skipFailedInvocationCounts) { - xmlSuite.setSkipFailedInvocationCounts(m_skipFailedInvocationCounts); - } - - // Override the XmlSuite verbose value with the one from TestNG - if (m_verbose != null) { - xmlSuite.setVerbose(m_verbose); - } - - if (null != m_configFailurePolicy) { - xmlSuite.setConfigFailurePolicy(m_configFailurePolicy); - } - - for (XmlTest t : xmlSuite.getTests()) { - for (Map.Entry ms : m_methodDescriptors.entrySet()) { - XmlMethodSelector xms = new XmlMethodSelector(); - xms.setName(ms.getKey()); - xms.setPriority(ms.getValue()); - t.getMethodSelectors().add(xms); - } - } - - suiteRunnerMap.put(xmlSuite, createSuiteRunner(xmlSuite)); - - for (XmlSuite childSuite : xmlSuite.getChildSuites()) { - createSuiteRunners(suiteRunnerMap, childSuite); - } - } - - /** - * Creates a suite runner and configures its initial state - * - * @param xmlSuite - * - * @return returns the newly created suite runner - */ - private SuiteRunner createSuiteRunner(XmlSuite xmlSuite) - { - SuiteRunner result = new SuiteRunner( - getConfiguration(), xmlSuite, - m_outputDir, - m_testRunnerFactory, - m_useDefaultListeners, - m_methodInterceptor, - m_invokedMethodListeners, - m_testListeners - ); - - for (ISuiteListener isl : m_suiteListeners) { - result.addListener(isl); - } - - for (IReporter r : result.getReporters()) { - addListener(r); - } - - for (IConfigurationListener cl : m_configuration.getConfigurationListeners()) { - result.addListener(cl); - } - - return result; - } - - protected IConfiguration getConfiguration() - { - return m_configuration; - } - - /** - * The TestNG entry point for command line execution. - * - * @param argv the TestNG command line parameters. - * - * @throws FileNotFoundException - */ - public static void main(String[] argv) - { - TestNG testng = privateMain(argv, null); - System.exit(testng.getStatus()); - } - - /** - * Note: this method is not part of the public API and is meant for internal usage only. - */ - public static TestNG privateMain(String[] argv, ITestListener listener) - { - TestNG result = new TestNG(); - - if (null != listener) { - result.addListener(listener); - } - - // - // Parse the arguments - // - try { - CommandLineArgs cla = new CommandLineArgs(); - m_jCommander = new JCommander(cla, argv); - validateCommandLineParameters(cla); - result.configure(cla); - } - catch (ParameterException ex) { - exitWithError(ex.getMessage()); - } - - // - // Run - // - try { - result.run(); - } - catch (TestNGException ex) { - if (TestRunner.getVerbose() > 1) { - LOGGER.error("", ex); - } else { - error(ex.getMessage()); - } - result.setStatus(HAS_FAILURE); - } - - return result; - } - - /** - * Configure the TestNG instance based on the command line parameters. - */ - protected void configure(CommandLineArgs cla) - { - if (cla.verbose != null) { - setVerbose(cla.verbose); - } - setOutputDirectory(cla.outputDirectory); - - String testClasses = cla.testClass; - if (null != testClasses) { - String[] strClasses = testClasses.split(","); - List classes = Lists.newArrayList(); - for (String c : strClasses) { - classes.add(ClassHelper.fileToClass(c)); - } - - setTestClasses(classes.toArray(new Class[classes.size()])); - } - - setOutputDirectory(cla.outputDirectory); - - if (cla.testNames != null) { - setTestNames(Arrays.asList(cla.testNames.split(","))); - } - - // Note: can't use a Boolean field here because we are allowing a boolean - // parameter with an arity of 1 ("-usedefaultlisteners false") - if (cla.useDefaultListeners != null) { - setUseDefaultListeners("true".equalsIgnoreCase(cla.useDefaultListeners)); - } - - setGroups(cla.groups); - setExcludedGroups(cla.excludedGroups); - setTestJar(cla.testJar); - setXmlPathInJar(cla.xmlPathInJar); - setJUnit(cla.junit); - setMixed(cla.mixed); - setMaster(cla.master); - setSlave(cla.slave); - setSkipFailedInvocationCounts(cla.skipFailedInvocationCounts); - if (cla.parallelMode != null) { - setParallel(cla.parallelMode); - } - if (cla.configFailurePolicy != null) { - setConfigFailurePolicy(cla.configFailurePolicy); - } - if (cla.threadCount != null) { - setThreadCount(cla.threadCount); - } - if (cla.dataProviderThreadCount != null) { - setDataProviderThreadCount(cla.dataProviderThreadCount); - } - if (cla.suiteName != null) { - setDefaultSuiteName(cla.suiteName); - } - if (cla.testName != null) { - setDefaultTestName(cla.testName); - } - if (cla.listener != null) { - String sep = ";"; - if (cla.listener.indexOf(",") >= 0) { - sep = ","; - } - String[] strs = Utils.split(cla.listener, sep); - List classes = Lists.newArrayList(); - - for (String cls : strs) { - classes.add(ClassHelper.fileToClass(cls)); - } - - setListenerClasses(classes); - } - - if (null != cla.methodSelectors) { - String[] strs = Utils.split(cla.methodSelectors, ","); - for (String cls : strs) { - String[] sel = Utils.split(cls, ":"); - try { - if (sel.length == 2) { - addMethodSelector(sel[0], Integer.valueOf(sel[1])); - } else { - error("Method selector value was not in the format org.example.Selector:4"); - } - } - catch (NumberFormatException nfe) { - error("Method selector value was not in the format org.example.Selector:4"); - } - } - } - - if (cla.objectFactory != null) { - setObjectFactory(ClassHelper.fileToClass(cla.objectFactory)); - } - if (cla.testRunnerFactory != null) { - setTestRunnerFactoryClass( - ClassHelper.fileToClass(cla.testRunnerFactory) - ); - } - //######### PATCH Begins - if (System.getProperty("testrunfactory") != null) { - setTestRunnerFactoryClass( - ClassHelper.fileToClass(System.getProperty("testrunfactory")) - ); - } - - //######### PATCH ends - - if (cla.reporter != null) { - ReporterConfig reporterConfig = ReporterConfig.deserialize(cla.reporter); - addReporter(reporterConfig); - } - - if (cla.commandLineMethods.size() > 0) { - m_commandLineMethods = cla.commandLineMethods; - } - - if (cla.suiteFiles != null) { - setTestSuites(cla.suiteFiles); - } - - setSuiteThreadPoolSize(cla.suiteThreadPoolSize); - setRandomizeSuites(cla.randomizeSuites); - } - - public void setSuiteThreadPoolSize(Integer suiteThreadPoolSize) - { - m_suiteThreadPoolSize = suiteThreadPoolSize; - } - - public Integer getSuiteThreadPoolSize() - { - return m_suiteThreadPoolSize; - } - - public void setRandomizeSuites(boolean randomizeSuites) - { - m_randomizeSuites = randomizeSuites; - } - - /** - * This method is invoked by Maven's Surefire, only remove it once - * Surefire has been modified to no longer call it. - */ - public void setSourcePath(String path) - { - // nop - } - - /** - * This method is invoked by Maven's Surefire to configure the runner, - * do not remove unless you know for sure that Surefire has been updated - * to use the new configure(CommandLineArgs) method. - * - * @deprecated use new configure(CommandLineArgs) method - */ - @SuppressWarnings({"unchecked"}) - @Deprecated - public void configure(Map cmdLineArgs) - { - CommandLineArgs result = new CommandLineArgs(); - - Integer verbose = (Integer) cmdLineArgs.get(CommandLineArgs.LOG); - if (null != verbose) { - result.verbose = verbose; - } - result.outputDirectory = (String) cmdLineArgs.get(CommandLineArgs.OUTPUT_DIRECTORY); - - String testClasses = (String) cmdLineArgs.get(CommandLineArgs.TEST_CLASS); - if (null != testClasses) { - result.testClass = testClasses; - } - - String testNames = (String) cmdLineArgs.get(CommandLineArgs.TEST_NAMES); - if (testNames != null) { - result.testNames = testNames; - } - - String useDefaultListeners = (String) cmdLineArgs.get(CommandLineArgs.USE_DEFAULT_LISTENERS); - if (null != useDefaultListeners) { - result.useDefaultListeners = useDefaultListeners; - } - - result.groups = (String) cmdLineArgs.get(CommandLineArgs.GROUPS); - result.excludedGroups = (String) cmdLineArgs.get(CommandLineArgs.EXCLUDED_GROUPS); - result.testJar = (String) cmdLineArgs.get(CommandLineArgs.TEST_JAR); - result.xmlPathInJar = (String) cmdLineArgs.get(CommandLineArgs.XML_PATH_IN_JAR); - result.junit = (Boolean) cmdLineArgs.get(CommandLineArgs.JUNIT); - result.mixed = (Boolean) cmdLineArgs.get(CommandLineArgs.MIXED); - result.master = (String) cmdLineArgs.get(CommandLineArgs.MASTER); - result.slave = (String) cmdLineArgs.get(CommandLineArgs.SLAVE); - result.skipFailedInvocationCounts = (Boolean) cmdLineArgs.get( - CommandLineArgs.SKIP_FAILED_INVOCATION_COUNTS - ); - String parallelMode = (String) cmdLineArgs.get(CommandLineArgs.PARALLEL); - if (parallelMode != null) { - result.parallelMode = parallelMode; - } - - String threadCount = (String) cmdLineArgs.get(CommandLineArgs.THREAD_COUNT); - if (threadCount != null) { - result.threadCount = Integer.parseInt(threadCount); - } - - // Not supported by Surefire yet - Integer dptc = (Integer) cmdLineArgs.get(CommandLineArgs.DATA_PROVIDER_THREAD_COUNT); - if (dptc != null) { - result.dataProviderThreadCount = dptc; - } - String defaultSuiteName = (String) cmdLineArgs.get(CommandLineArgs.SUITE_NAME); - if (defaultSuiteName != null) { - result.suiteName = defaultSuiteName; - } - - String defaultTestName = (String) cmdLineArgs.get(CommandLineArgs.TEST_NAME); - if (defaultTestName != null) { - result.testName = defaultTestName; - } - - Object listeners = cmdLineArgs.get(CommandLineArgs.LISTENER); - if (listeners instanceof List) { - result.listener = Utils.join((List) listeners, ","); - } else { - result.listener = (String) listeners; - } - - String ms = (String) cmdLineArgs.get(CommandLineArgs.METHOD_SELECTORS); - if (null != ms) { - result.methodSelectors = ms; - } - - String objectFactory = (String) cmdLineArgs.get(CommandLineArgs.OBJECT_FACTORY); - if (null != objectFactory) { - result.objectFactory = objectFactory; - } - - String runnerFactory = (String) cmdLineArgs.get(CommandLineArgs.TEST_RUNNER_FACTORY); - if (null != runnerFactory) { - result.testRunnerFactory = runnerFactory; - } - - String reporterConfigs = (String) cmdLineArgs.get(CommandLineArgs.REPORTER); - if (reporterConfigs != null) { - result.reporter = reporterConfigs; - } - - String failurePolicy = (String) cmdLineArgs.get(CommandLineArgs.CONFIG_FAILURE_POLICY); - if (failurePolicy != null) { - result.configFailurePolicy = failurePolicy; - } - - configure(result); - } - - /** - * Only run the specified tests from the suite. - */ - public void setTestNames(List testNames) - { - m_testNames = testNames; - } - - public void setSkipFailedInvocationCounts(Boolean skip) - { - m_skipFailedInvocationCounts = skip; - } - - private void addReporter(ReporterConfig reporterConfig) - { - Object instance = reporterConfig.newReporterInstance(); - if (instance != null) { - addListener(instance); - } else { - LOGGER.warn("Could not find reporte class : " + reporterConfig.getClassName()); - } - } - - /** - * Specify if this run should be in Master-Slave mode as Master - * - * @param fileName remote.properties path - */ - public void setMaster(String fileName) - { - m_masterfileName = fileName; - } - - /** - * Specify if this run should be in Master-Slave mode as slave - * - * @param fileName remote.properties path - */ - public void setSlave(String fileName) - { - m_slavefileName = fileName; - } - - /** - * Specify if this run should be made in JUnit mode - * - * @param isJUnit - */ - public void setJUnit(Boolean isJUnit) - { - m_isJUnit = isJUnit; - } - - /** - * Specify if this run should be made in mixed mode - */ - public void setMixed(Boolean isMixed) - { - if (isMixed == null) { - return; - } - m_isMixed = isMixed; - } - - /** - * @deprecated The TestNG version is now established at load time. This - * method is not required anymore and is now a no-op. - */ - @Deprecated - public static void setTestNGVersion() - { - LOGGER.info("setTestNGVersion has been deprecated."); - } - - /** - * Returns true if this is the JDK 1.4 JAR version of TestNG, false otherwise. - * - * @return true if this is the JDK 1.4 JAR version of TestNG, false otherwise. - */ - @Deprecated - public static boolean isJdk14() - { - return false; - } - - /** - * Double check that the command line parameters are valid. - */ - protected static void validateCommandLineParameters(CommandLineArgs args) - { - String testClasses = args.testClass; - List testNgXml = args.suiteFiles; - String testJar = args.testJar; - String slave = args.slave; - List methods = args.commandLineMethods; - - if (testClasses == null && slave == null && testJar == null - && (testNgXml == null || testNgXml.isEmpty()) - && (methods == null || methods.isEmpty())) { - throw new ParameterException( - "You need to specify at least one testng.xml, one class" - + " or one method" - ); - } - - String groups = args.groups; - String excludedGroups = args.excludedGroups; - - if (testJar == null && - (null != groups || null != excludedGroups) && testClasses == null - && (testNgXml == null || testNgXml.isEmpty())) { - throw new ParameterException("Groups option should be used with testclass option"); - } - - if (args.slave != null && args.master != null) { - throw new ParameterException( - CommandLineArgs.SLAVE + " can't be combined with " - + CommandLineArgs.MASTER - ); - } - - Boolean junit = args.junit; - Boolean mixed = args.mixed; - if (junit && mixed) { - throw new ParameterException( - CommandLineArgs.MIXED + " can't be combined with " - + CommandLineArgs.JUNIT - ); - } - } - - /** - * @return true if at least one test failed. - */ - public boolean hasFailure() - { - return (getStatus() & HAS_FAILURE) == HAS_FAILURE; - } - - /** - * @return true if at least one test failed within success percentage. - */ - public boolean hasFailureWithinSuccessPercentage() - { - return (getStatus() & HAS_FSP) == HAS_FSP; - } - - /** - * @return true if at least one test was skipped. - */ - public boolean hasSkip() - { - return (getStatus() & HAS_SKIPPED) == HAS_SKIPPED; - } - - static void exitWithError(String msg) - { - LOGGER.error(msg); - usage(); - System.exit(1); - } - - public String getOutputDirectory() - { - return m_outputDir; - } - - public IAnnotationTransformer getAnnotationTransformer() - { - return m_annotationTransformer; - } - - public void setAnnotationTransformer(IAnnotationTransformer t) - { - // compare by reference! - if (m_annotationTransformer != m_defaultAnnoProcessor && m_annotationTransformer != t) { - LOGGER.warn("AnnotationTransformer already set"); - } - m_annotationTransformer = t; - } - - /** - * @return the defaultSuiteName - */ - public String getDefaultSuiteName() - { - return m_defaultSuiteName; - } - - /** - * @param defaultSuiteName the defaultSuiteName to set - */ - public void setDefaultSuiteName(String defaultSuiteName) - { - m_defaultSuiteName = defaultSuiteName; - } - - /** - * @return the defaultTestName - */ - public String getDefaultTestName() - { - return m_defaultTestName; - } - - /** - * @param defaultTestName the defaultTestName to set - */ - public void setDefaultTestName(String defaultTestName) - { - m_defaultTestName = defaultTestName; - } - - /** - * Sets the policy for whether or not to ever invoke a configuration method again after - * it has failed once. Possible values are defined in {@link XmlSuite}. The default - * value is {@link XmlSuite#SKIP}. - * - * @param failurePolicy the configuration failure policy - */ - public void setConfigFailurePolicy(String failurePolicy) - { - m_configFailurePolicy = failurePolicy; - } - - /** - * Returns the configuration failure policy. - * - * @return config failure policy - */ - public String getConfigFailurePolicy() - { - return m_configFailurePolicy; - } - - // DEPRECATED: to be removed after a major version change - - /** - * @deprecated since 5.1 - */ - @Deprecated - public static TestNG getDefault() - { - return m_instance; - } - - /** - * @deprecated since 5.1 - */ - @Deprecated - public void setHasFailure(boolean hasFailure) - { - m_status |= HAS_FAILURE; - } - - /** - * @deprecated since 5.1 - */ - @Deprecated - public void setHasFailureWithinSuccessPercentage(boolean hasFailureWithinSuccessPercentage) - { - m_status |= HAS_FSP; - } - - /** - * @deprecated since 5.1 - */ - @Deprecated - public void setHasSkip(boolean hasSkip) - { - m_status |= HAS_SKIPPED; - } - - public static class ExitCodeListener implements IResultListener2 - { - private TestNG m_mainRunner; - - public ExitCodeListener() - { - m_mainRunner = TestNG.m_instance; - } - - public ExitCodeListener(TestNG runner) - { - m_mainRunner = runner; - } - - @Override - public void beforeConfiguration(ITestResult tr) - { - } - - @Override - public void onTestFailure(ITestResult result) - { - setHasRunTests(); - m_mainRunner.setStatus(HAS_FAILURE); - } - - @Override - public void onTestSkipped(ITestResult result) - { - setHasRunTests(); - m_mainRunner.setStatus(HAS_SKIPPED); - } - - @Override - public void onTestFailedButWithinSuccessPercentage(ITestResult result) - { - setHasRunTests(); - m_mainRunner.setStatus(HAS_FSP); - } - - @Override - public void onTestSuccess(ITestResult result) - { - setHasRunTests(); - } - - @Override - public void onStart(ITestContext context) - { - setHasRunTests(); - } - - @Override - public void onFinish(ITestContext context) - { - } - - @Override - public void onTestStart(ITestResult result) - { - setHasRunTests(); - } - - private void setHasRunTests() - { - m_mainRunner.m_hasTests = true; - } - - /** - * @see IConfigurationListener#onConfigurationFailure(ITestResult) - */ - @Override - public void onConfigurationFailure(ITestResult itr) - { - m_mainRunner.setStatus(HAS_FAILURE); - } - - /** - * @see IConfigurationListener#onConfigurationSkip(ITestResult) - */ - @Override - public void onConfigurationSkip(ITestResult itr) - { - m_mainRunner.setStatus(HAS_SKIPPED); - } - - /** - * @see IConfigurationListener#onConfigurationSuccess(ITestResult) - */ - @Override - public void onConfigurationSuccess(ITestResult itr) - { - } - } - - private void setConfigurable(IConfigurable c) - { - // compare by reference! - if (m_configurable != null && m_configurable != c) { - LOGGER.warn("Configurable already set"); - } - m_configurable = c; - } - - private void setHookable(IHookable h) - { - // compare by reference! - if (m_hookable != null && m_hookable != h) { - LOGGER.warn("Hookable already set"); - } - m_hookable = h; - } - - public void setMethodInterceptor(IMethodInterceptor i) - { - // compare by reference! - if (m_methodInterceptor != null && m_methodInterceptor != i) { - LOGGER.warn("MethodInterceptor already set"); - } - m_methodInterceptor = i; - } - - public void setDataProviderThreadCount(int count) - { - m_dataProviderThreadCount = count; - } - - /** - * Add a class loader to the searchable loaders. - */ - public void addClassLoader(final ClassLoader loader) - { - if (loader != null) { - ClassHelper.addClassLoader(loader); - } - } - - public void setPreserveOrder(boolean b) - { - m_preserveOrder = b; - } - - protected long getStart() - { - return m_start; - } - - protected long getEnd() - { - return m_end; - } - - public void setGroupByInstances(boolean b) - { - m_groupByInstances = b; - } - - ///// - // ServiceLoader testing - // - - private URLClassLoader m_serviceLoaderClassLoader; - private List m_serviceLoaderListeners = Lists.newArrayList(); - - /** - * Used to test ServiceClassLoader - */ - public void setServiceLoaderClassLoader(URLClassLoader ucl) - { - m_serviceLoaderClassLoader = ucl; - } - - /** - * Used to test ServiceClassLoader - */ - private void addServiceLoaderListener(ITestNGListener l) - { - m_serviceLoaderListeners.add(l); - } - - /** - * Used to test ServiceClassLoader - */ - public List getServiceLoaderListeners() - { - return m_serviceLoaderListeners; - } - - // - // ServiceLoader testing - ///// -} diff --git a/integration-tests/src/main/java/org/testng/remote/RemoteTestNG.java b/integration-tests/src/main/java/org/testng/remote/RemoteTestNG.java deleted file mode 100644 index 78807e69587e..000000000000 --- a/integration-tests/src/main/java/org/testng/remote/RemoteTestNG.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Licensed to Metamarkets Group Inc. (Metamarkets) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. Metamarkets licenses this file - * to you 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 org.testng.remote; - -import com.beust.jcommander.JCommander; -import com.beust.jcommander.ParameterException; -import org.testng.CommandLineArgs; -import org.testng.IInvokedMethodListener; -import org.testng.ISuite; -import org.testng.ISuiteListener; -import org.testng.ITestRunnerFactory; -import org.testng.TestNG; -import org.testng.TestNGException; -import org.testng.TestRunner; -import org.testng.collections.Lists; -import org.testng.internal.ClassHelper; -import org.testng.log4testng.Logger; -import org.testng.remote.strprotocol.GenericMessage; -import org.testng.remote.strprotocol.IMessageSender; -import org.testng.remote.strprotocol.MessageHelper; -import org.testng.remote.strprotocol.MessageHub; -import org.testng.remote.strprotocol.RemoteTestListener; -import org.testng.remote.strprotocol.SerializedMessageSender; -import org.testng.remote.strprotocol.StringMessageSender; -import org.testng.remote.strprotocol.SuiteMessage; -import org.testng.reporters.JUnitXMLReporter; -import org.testng.reporters.TestHTMLReporter; -import org.testng.xml.XmlSuite; -import org.testng.xml.XmlTest; - -import java.util.Arrays; -import java.util.List; - -import static org.testng.internal.Utils.defaultIfStringEmpty; - -/** - * Class copied from TestNG library ver 6.8.7 to apply a workaround for http://jira.codehaus.org/browse/SUREFIRE-622 - * To Locate the PATCHED AREA search for keyword "PATCH" in this class file - *

- * Extension of TestNG registering a remote TestListener. - * - * @author Cedric Beust - */ -public class RemoteTestNG extends TestNG -{ - private static final Logger LOGGER = Logger.getLogger(TestNG.class); - - // The following constants are referenced by the Eclipse plug-in, make sure you - // modify the plug-in as well if you change any of them. - public static final String DEBUG_PORT = "12345"; - public static final String DEBUG_SUITE_FILE = "testng-customsuite.xml"; - public static final String DEBUG_SUITE_DIRECTORY = System.getProperty("java.io.tmpdir"); - public static final String PROPERTY_DEBUG = "testng.eclipse.debug"; - public static final String PROPERTY_VERBOSE = "testng.eclipse.verbose"; - private static final String LOCALHOST = "localhost"; - // End of Eclipse constants. - /** - * Port used for the serialized protocol - */ - private static Integer m_serPort = null; - private static boolean m_debug; - private static boolean m_dontExit; - private static boolean m_ack; - private ITestRunnerFactory m_customTestRunnerFactory; - private String m_host; - /** - * Port used for the string protocol - */ - private Integer m_port = null; - - public static void main(String[] args) throws ParameterException - { - CommandLineArgs cla = new CommandLineArgs(); - RemoteArgs ra = new RemoteArgs(); - m_jCommander = new JCommander(Arrays.asList(cla, ra), args); - m_dontExit = ra.dontExit; - if (cla.port != null && ra.serPort != null) { - throw new TestNGException( - "Can only specify one of " + CommandLineArgs.PORT - + " and " + RemoteArgs.PORT - ); - } - m_debug = cla.debug; - m_ack = ra.ack; - if (m_debug) { - initAndRun(args, cla, ra); - } else { - initAndRun(args, cla, ra); - } - } - - private static void initAndRun(String[] args, CommandLineArgs cla, RemoteArgs ra) - { - RemoteTestNG remoteTestNg = new RemoteTestNG(); - if (m_debug) { - // In debug mode, override the port and the XML file to a fixed location - cla.port = Integer.parseInt(DEBUG_PORT); - ra.serPort = cla.port; - cla.suiteFiles = Arrays.asList( - new String[]{ - DEBUG_SUITE_DIRECTORY + DEBUG_SUITE_FILE - } - ); - } - remoteTestNg.configure(cla); - remoteTestNg.setHost(cla.host); - m_serPort = ra.serPort; - remoteTestNg.m_port = cla.port; - if (isVerbose()) { - StringBuilder sb = new StringBuilder("Invoked with "); - for (String s : args) { - sb.append(s).append(" "); - } - p(sb.toString()); - } - validateCommandLineParameters(cla); - remoteTestNg.run(); - } - - private static void p(String s) - { - if (isVerbose()) { - LOGGER.info("[RemoteTestNG] " + s); - } - } - - public static boolean isVerbose() - { - boolean result = System.getProperty(PROPERTY_VERBOSE) != null || isDebug(); - return result; - } - - public static boolean isDebug() - { - return m_debug || System.getProperty(PROPERTY_DEBUG) != null; - } - - private void calculateAllSuites(List suites, List outSuites) - { - for (XmlSuite s : suites) { - outSuites.add(s); - } - } - - @Override - public void run() - { - IMessageSender sender = m_serPort != null - ? new SerializedMessageSender(m_host, m_serPort, m_ack) - : new StringMessageSender(m_host, m_port); - final MessageHub msh = new MessageHub(sender); - msh.setDebug(isDebug()); - try { - msh.connect(); - // We couldn't do this until now in debug mode since the .xml file didn't exist yet. - // Now that we have connected with the Eclipse client, we know that it created the .xml - // file so we can proceed with the initialization - initializeSuitesAndJarFile(); - - List suites = Lists.newArrayList(); - calculateAllSuites(m_suites, suites); - if (suites.size() > 0) { - - int testCount = 0; - - for (XmlSuite suite : suites) { - testCount += suite.getTests().size(); - } - - GenericMessage gm = new GenericMessage(MessageHelper.GENERIC_SUITE_COUNT); - gm.setSuiteCount(suites.size()); - gm.setTestCount(testCount); - msh.sendMessage(gm); - - addListener(new RemoteSuiteListener(msh)); - setTestRunnerFactory(new DelegatingTestRunnerFactory(buildTestRunnerFactory(), msh)); - - super.run(); - } else { - LOGGER.error("No test suite found. Nothing to run"); - } - } - catch (Throwable cause) { - LOGGER.error("", cause); - } - finally { - msh.shutDown(); - if (!m_debug && !m_dontExit) { - System.exit(0); - } - } - } - - /** - * Override by the plugin if you need to configure differently the TestRunner - * (usually this is needed if different listeners/reporters are needed). - * Note: you don't need to worry about the wiring listener, because it is added - * automatically. - */ - protected ITestRunnerFactory buildTestRunnerFactory() - { - //################### PATCH STARTS - if (System.getProperty("testrunfactory") != null) { - m_customTestRunnerFactory = (ITestRunnerFactory) ClassHelper.newInstance( - ClassHelper.fileToClass( - System.getProperty( - "testrunfactory" - ) - ) - ); - //################## PATCH ENDS - } else if (null == m_customTestRunnerFactory) { - m_customTestRunnerFactory = new ITestRunnerFactory() - { - @Override - public TestRunner newTestRunner( - ISuite suite, XmlTest xmlTest, - List listeners - ) - { - TestRunner runner = - new TestRunner( - getConfiguration(), suite, xmlTest, - false /*skipFailedInvocationCounts */, - listeners - ); - if (m_useDefaultListeners) { - runner.addListener(new TestHTMLReporter()); - runner.addListener(new JUnitXMLReporter()); - } - - return runner; - } - }; - } - - return m_customTestRunnerFactory; - } - - private String getHost() - { - return m_host; - } - - public void setHost(String host) - { - m_host = defaultIfStringEmpty(host, LOCALHOST); - } - - private int getPort() - { - return m_port; - } - - /** - * A ISuiteListener wiring the results using the internal string-based protocol. - */ - private static class RemoteSuiteListener implements ISuiteListener - { - private final MessageHub m_messageSender; - - RemoteSuiteListener(MessageHub smsh) - { - m_messageSender = smsh; - } - - @Override - public void onFinish(ISuite suite) - { - m_messageSender.sendMessage(new SuiteMessage(suite, false /*start*/)); - } - - @Override - public void onStart(ISuite suite) - { - m_messageSender.sendMessage(new SuiteMessage(suite, true /*start*/)); - } - } - - private static class DelegatingTestRunnerFactory implements ITestRunnerFactory - { - private final ITestRunnerFactory m_delegateFactory; - private final MessageHub m_messageSender; - - DelegatingTestRunnerFactory(ITestRunnerFactory trf, MessageHub smsh) - { - m_delegateFactory = trf; - m_messageSender = smsh; - } - - @Override - public TestRunner newTestRunner( - ISuite suite, XmlTest test, - List listeners - ) - { - TestRunner tr = m_delegateFactory.newTestRunner(suite, test, listeners); - tr.addListener(new RemoteTestListener(suite, test, m_messageSender)); - return tr; - } - } -}