Invoker.java revision d7e500014dc797345bc2e4f9ceb176fa225b8a37
1f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustpackage org.testng.internal; 2f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 3f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 4f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.lang.reflect.InvocationTargetException; 5f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.lang.reflect.Method; 6f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.ArrayList; 7f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.HashMap; 8f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.Hashtable; 9f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.Iterator; 10f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.List; 11f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.Map; 12f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport java.util.Set; 13f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 14f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.IClass; 15f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.IHookable; 16f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.IRetryAnalyzer; 17f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.ITestClass; 18f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.ITestContext; 19f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.ITestListener; 20f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.ITestNGMethod; 21f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.ITestResult; 22f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.Reporter; 23f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.SkipException; 24f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.SuiteRunState; 25f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.TestException; 26f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.TestNGException; 27f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.internal.InvokeMethodRunnable.TestNGRuntimeException; 28f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.internal.annotations.AnnotationHelper; 29f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.internal.annotations.IAnnotationFinder; 30f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.internal.annotations.IConfiguration; 31f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.internal.thread.ThreadExecutionException; 32f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.internal.thread.ThreadUtil; 33f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.xml.XmlClass; 34f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.xml.XmlSuite; 35f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustimport org.testng.xml.XmlTest; 36f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 37f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust/** 38f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * This class is responsible for invoking methods: 39f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * - test methods 40f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * - configuration methods 41f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * - possibly in a separate thread 42f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * and then for notifying the result listeners. 43f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * 44f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @author <a href="mailto:cedric@beust.com">Cedric Beust</a> 45f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a> 46f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 47f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beustpublic class Invoker implements IInvoker { 48f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ITestContext m_testContext; 49f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ITestResultNotifier m_notifier; 50f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private IAnnotationFinder m_annotationFinder; 51f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private SuiteRunState m_suiteState; 526cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust private boolean m_skipFailedInvocationCounts; 53f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 54f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public Invoker(ITestContext testContext, 55f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResultNotifier notifier, 56f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust SuiteRunState state, 576cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust IAnnotationFinder annotationFinder, 586cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust boolean skipFailedInvocationCounts) { 59f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_testContext= testContext; 60f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_suiteState= state; 61f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier= notifier; 62f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_annotationFinder= annotationFinder; 636cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust m_skipFailedInvocationCounts = skipFailedInvocationCounts; 64f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 65f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 66f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 67f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Invoke configuration methods if they belong to the same TestClass passed 68f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * in parameter.. <p/>TODO: Calculate ahead of time which methods should be 69f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * invoked for each class. Might speed things up for users who invoke the 70f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * same test class with different parameters in the same suite run. 71f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * 72f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * If instance is non-null, the configuration will be run on it. If it is null, 73f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * the configuration methods will be run on all the instances retrieved 74f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * from the ITestClass. 75f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 76f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public void invokeConfigurations(IClass testClass, 77f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] allMethods, 78f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 79f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> params, 80f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object instance) 81f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 82f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeConfigurations(testClass, null, allMethods, suite, params, instance); 83f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 84f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 85f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void invokeConfigurations(IClass testClass, 86f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod currentTestMethod, 87f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] allMethods, 88f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 89f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> params, 90f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object instance) 91f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 92f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == allMethods) { 93f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(5, "No @Configuration methods found"); 94f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 95f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return; 96f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 97f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 98f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] methods= filterMethodsUnique(testClass, allMethods); 99f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 100f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(ITestNGMethod tm : methods) { 101f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == testClass) { 102f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testClass= tm.getTestClass(); 103f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 104f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 105f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResult testResult= new TestResult(testClass, 106f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust instance, 107f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm, 108f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust null, 109f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis(), 110f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis()); 111f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 112f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust IConfiguration configurationAnnotation= null; 113f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 114f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] instances= tm.getInstances(); 115f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (instances == null || instances.length == 0) instances = new Object[] { instance }; 116f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Class<?> objectClass= instances[0].getClass(); 117f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Method method= tm.getMethod(); 118f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 119f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Only run the configuration if 120f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // - the test is enabled and 121f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // - the Configuration method belongs to the same class or a parent 122f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(MethodHelper.isEnabled(objectClass, m_annotationFinder)) { 123f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust configurationAnnotation= (IConfiguration) AnnotationHelper.findConfiguration(m_annotationFinder, method); 124f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 125f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean isClassConfiguration= isClassConfiguration(configurationAnnotation); 126f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean alwaysRun= isAlwaysRun(configurationAnnotation); 127f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 128f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(!confInvocationPassed(tm) && !alwaysRun) { 129f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleConfigurationSkip(tm, testResult); 130f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust continue; 131f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 132f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 133f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(3, "Invoking " + Utils.detailedMethodName(tm, true)); 134f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 135f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameters= Parameters.createConfigurationParameters(tm.getMethod(), 136f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust params, 137f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust currentTestMethod, 138f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_annotationFinder, 139f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust suite, 140f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_testContext); 141f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setParameters(parameters); 142f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 143f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] newInstances= (null != instance) ? new Object[] { instance } : instances; 144f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 145ec9d2748fd87c650757fe06ee7cff536ee0bbc40Cédric Beust invokeConfigurationMethod(newInstances, tm, 146ec9d2748fd87c650757fe06ee7cff536ee0bbc40Cédric Beust parameters, isClassConfiguration, testResult); 147f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 148f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // TODO: probably we should trigger the event for each instance??? 149f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setEndMillis(System.currentTimeMillis()); 150f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runConfigurationListeners(testResult); 151f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // if is enabled 152f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 153f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(3, 154f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust "Skipping " 155f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust + Utils.detailedMethodName(tm, true) 156f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust + " because " 157f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust + objectClass.getName() 158f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust + " is not enabled"); 159f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 160f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 161f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(InvocationTargetException ex) { 162f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, suite); 163f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 164f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(TestNGException ex) { 165f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Don't wrap TestNGExceptions, it could be a missing parameter on a 166f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // @Configuration method 167f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, suite); 168f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 169f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(Throwable ex) { // covers the non-wrapper exceptions 170f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, suite); 171f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 172f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // for methods 173f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 174f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 175f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 176f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Marks the currect <code>TestResult</code> as skipped and invokes the listeners. 177f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 178f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void handleConfigurationSkip(ITestNGMethod tm, ITestResult testResult) { 179f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SKIP); 180f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runConfigurationListeners(testResult); 181f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 182f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 183f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 184f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Is the current <code>IConfiguration</code> a class-level method. 185f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 186f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean isClassConfiguration(IConfiguration configurationAnnotation) { 187f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == configurationAnnotation) { 188f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return false; 189f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 190f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 191f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean before= (null != configurationAnnotation) 192f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ? configurationAnnotation.getBeforeTestClass() 193f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust : false; 194f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 195f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean after= (null != configurationAnnotation) 196f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ? configurationAnnotation.getAfterTestClass() 197f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust : false; 198f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 199f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return (before || after); 200f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 201f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 202f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 203f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Is the <code>IConfiguration</code> marked as alwaysRun. 204f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 205f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean isAlwaysRun(IConfiguration configurationAnnotation) { 206f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == configurationAnnotation) { 207f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return false; 208f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 209f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 210f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean alwaysRun= false; 211f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if ((configurationAnnotation.getAfterSuite() 212f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust || configurationAnnotation.getAfterTest() 213f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust || configurationAnnotation.getAfterTestClass() 214f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust || configurationAnnotation.getAfterTestMethod()) 215f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust && configurationAnnotation.getAlwaysRun()) 216f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 217f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust alwaysRun= true; 218f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 219f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 220f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return alwaysRun; 221f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 222f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 223f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void handleConfigurationFailure(Throwable ite, 224f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod tm, 225f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResult testResult, 226f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust IConfiguration annotation, 227f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite) 228f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 229f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Throwable cause= ite.getCause() != null ? ite.getCause() : ite; 230f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 231f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(SkipException.class.isAssignableFrom(cause.getClass())) { 232f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust SkipException skipEx= (SkipException) cause; 233f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(!skipEx.isSkip()) { 234f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(skipEx); 235f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleConfigurationSkip(tm, testResult); 236f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return; 237f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 238f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 239f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Utils.log("", 3, "Failed to invoke @Configuration method " 240f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust + tm.getRealClass().getName() + "." + tm.getMethodName() + ":" + cause.getMessage()); 241f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleException(cause, tm, testResult, 1); 242f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runConfigurationListeners(testResult); 243f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 244f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 245f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If in TestNG mode, need to take a look at the annotation to figure out 246f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // what kind of @Configuration method we're dealing with 247f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 248f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (null != annotation) { 249f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust recordConfigurationInvocationFailed(tm, annotation, suite); 250f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 251f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 252f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 253f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 254f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return All the classes that belong to the same <test> tag as @param cls 255f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 256f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private XmlClass[] findClassesInSameTest(Class<?> cls, XmlSuite suite) { 257f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, XmlClass> vResult= new HashMap<String, XmlClass>(); 258f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String className= cls.getName(); 259f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(XmlTest test : suite.getTests()) { 260f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(XmlClass testClass : test.getXmlClasses()) { 261f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(testClass.getName().equals(className)) { 262f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 263f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Found it, add all the classes in this test in the result 264f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(XmlClass thisClass : test.getXmlClasses()) { 265f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust vResult.put(thisClass.getName(), thisClass); 266f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 267f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Note: we need to iterate through the entire suite since the same 268f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // class might appear in several <test> tags 269f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 270f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 271f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 272f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 273f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlClass[] result= vResult.values().toArray(new XmlClass[vResult.size()]); 274f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 275f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 276f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 277f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 278f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 279f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Record internally the failure of a Configuration, so that we can determine 280f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * later if @Test should be skipped. 281f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 282f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void recordConfigurationInvocationFailed(ITestNGMethod tm, IConfiguration annotation, XmlSuite suite) { 283f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If beforeTestClass/beforeTestMethod or afterTestClass/afterTestMethod 284f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // failed, mark this entire class as failed, but only this class (the other 285f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // classes should keep running normally) 286f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(annotation.getBeforeTestClass() 287f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust || annotation.getAfterTestClass() 288f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust || annotation.getBeforeTestMethod() 289f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust || annotation.getAfterTestMethod()) 290f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 291f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust setClassInvocationFailure(tm.getRealClass(), false); 292f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 293f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 294f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If beforeSuite or afterSuite failed, mark *all* the classes as failed 295f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // for configurations. At this point, the entire Suite is screwed 296f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if (annotation.getBeforeSuite() || annotation.getAfterSuite()) { 297f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_suiteState.failed(); 298f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 299f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 300f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // beforeTest or afterTest: mark all the classes in the same 301f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // <test> stanza as failed for configuration 302f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if (annotation.getBeforeTest() || annotation.getAfterTest()) { 303f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlClass[] classes= findClassesInSameTest(tm.getRealClass(), suite); 304f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(XmlClass xmlClass : classes) { 305f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust setClassInvocationFailure(xmlClass.getSupportClass(), false); 306f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 307f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 308f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] beforeGroups= annotation.getBeforeGroups(); 309f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null != beforeGroups && beforeGroups.length > 0) { 310f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(String group: beforeGroups) { 311f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_beforegroupsFailures.put(group, Boolean.FALSE); 312f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 313f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 314f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 315f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 316f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 317f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return true if this class has successfully run all its @Configuration 318f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * method or false if at least one of these methods failed. 319f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 320f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean confInvocationPassed(ITestNGMethod method) { 321f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean result= true; 322f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 323f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Class<?> cls= method.getMethod().getDeclaringClass(); 324f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 325f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(m_suiteState.isFailed()) { 326f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result= false; 327f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 328f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 329f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(m_classInvocationResults.containsKey(cls)) { 330f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result= m_classInvocationResults.get(cls); 331f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 332f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 333f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(Class<?> clazz: m_classInvocationResults.keySet()) { 334f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(clazz.isAssignableFrom(cls)) { 335f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result= false; 336f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 337f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 338f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 339f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 340f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 341f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 342f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // check if there are failed @BeforeGroups 343f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] groups= method.getGroups(); 344f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null != groups && groups.length > 0) { 345f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(String group: groups) { 346f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(m_beforegroupsFailures.containsKey(group)) { 347f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result= false; 348f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 349f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 350f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 351f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 352f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 353f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 354f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 355f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** Group failures must be synched as the Invoker is accessed concurrently */ 356f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private Map<String, Boolean> m_beforegroupsFailures= new Hashtable<String, Boolean>(); 357f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 358f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** Class failures must be synched as the Invoker is accessed concurrently */ 359f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private Map<Class<?>, Boolean> m_classInvocationResults= new Hashtable<Class<?>, Boolean>(); 360f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 361f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void setClassInvocationFailure(Class<?> clazz, boolean flag) { 362f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_classInvocationResults.put(clazz, flag); 363f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 364f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 365f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 366f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Effectively invokes a configuration method on all passed in instances. 367f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * 368f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param instances the instances to invoke the configuration method on 369f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param tm the configuration method 370f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param params the parameters needed for method invocation 371f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param isClass flag if the configuration method is a class level method // FIXME: this looks like a missusage 372f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param testResult 373f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @throws InvocationTargetException 374f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @throws IllegalAccessException 375f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 376f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void invokeConfigurationMethod(Object[] instances, 377f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod tm, 378f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] params, 379f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean isClass, 380f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResult testResult) 381f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust throws InvocationTargetException, IllegalAccessException 382f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 383f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Mark this method with the current thread id 384f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm.setId(ThreadUtil.currentThreadInfo()); 385f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 386f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(Object targetInstance : instances) { 387f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust InvokedMethod im= new InvokedMethod(targetInstance, 388f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm, 389f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust params, 390f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust false, /* isTest */ 391f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust isClass, /* ??? */ 392f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis()); 393f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 394f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addInvokedMethod(im); 395f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 396f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 397f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Reporter.setCurrentTestResult(testResult); 398f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.invokeMethod(tm.getMethod(), targetInstance, params); 399f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 400f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust finally { 401f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Reporter.setCurrentTestResult(testResult); 402f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 403f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 404f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 405f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 406f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ITestResult invokeMethod(Object[] instances, 407f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int instanceIndex, 408f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ITestNGMethod tm, 409f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameterValues, 410f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 411f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> params, 412f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestClass testClass, 413f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] beforeMethods, 414f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afterMethods, 415f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods) { 416f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 417f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Invoke beforeGroups configurations 418f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 419f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeBeforeGroupsConfigurations(testClass, tm, groupMethods, suite, params, 420f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust instances[instanceIndex]); 421f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 422f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 42345a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // Invoke beforeMethods only if 42445a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // - firstTimeOnly is not set 42545a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // - firstTimeOnly is set, and we are reaching at the first invocationCount 426f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 42745a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust invokeConfigurations(testClass, tm, 42845a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust filterConfigurationMethods(tm, beforeMethods, true /* beforeMethods */), 42945a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust suite, params, 43045a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust instances[instanceIndex]); 431f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 432f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 433f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Create the ExtraOutput for this method 434f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 435f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust TestResult testResult = null; 436f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 437f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult= new TestResult(testClass, instances[instanceIndex], 438f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm, 439f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust null, 440f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis(), 441f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 0); 442f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setParameters(parameterValues); 443f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setHost(m_testContext.getHost()); 444f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.STARTED); 445f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runTestListeners(testResult); 446f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 447f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust InvokedMethod invokedMethod= new InvokedMethod(instances[instanceIndex], 448f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm, 449f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues, 450f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust true, 451f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust false, 452f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis()); 453f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 454f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addInvokedMethod(invokedMethod); 455f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 456f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Method thisMethod= tm.getMethod(); 457f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 458f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(confInvocationPassed(tm)) { 459f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(3, "Invoking " + thisMethod.getDeclaringClass().getName() + "." + 460f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust thisMethod.getName()); 461f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 462f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If no timeOut, just invoke the method 463f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(tm.getTimeOut() <= 0) { 464f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 465f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If this method is a IHookable, invoke its run() method 466f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 467f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (IHookable.class.isAssignableFrom(thisMethod.getDeclaringClass())) { 468f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.invokeHookable(instances[instanceIndex], 469f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues, testClass, thisMethod, testResult); 470f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SUCCESS); 471f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 472f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 473f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Not a IHookable, invoke directly 474f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 475f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 476f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 477f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Reporter.setCurrentTestResult(testResult); 478f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.invokeMethod(thisMethod, instances[instanceIndex], 479f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues); 480f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SUCCESS); 481f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 482f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust finally { 483f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Reporter.setCurrentTestResult(null); 484f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 485f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 486f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 487f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 488f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 489f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Reporter.setCurrentTestResult(testResult); 490f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.invokeWithTimeout(tm, instances[instanceIndex], 491f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues, testResult); 492f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 493f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust finally { 494f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Reporter.setCurrentTestResult(null); 495f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 496f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 497f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 498f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 499f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SKIP); 500f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 501f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 502f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(InvocationTargetException ite) { 503f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(ite.getCause()); 504f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 505f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(ThreadExecutionException tee) { // wrapper for TestNGRuntimeException 506f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Throwable cause= tee.getCause(); 507f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(TestNGRuntimeException.class.equals(cause.getClass())) { 508f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(cause.getCause()); 509f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 510f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 511f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(cause); 512f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 513f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 514f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(Throwable thr) { // covers the non-wrapper exceptions 515f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(thr); 516f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 517f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust finally { 518f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 519f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Increment the invocation count for this method 520f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 521f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm.incrementCurrentInvocationCount(); 522f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 523f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (testResult != null) { 524f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setEndMillis(System.currentTimeMillis()); 525f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 526f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 52745a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // Invoke afterMethods only if 52845a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // - lastTimeOnly is not set 52945a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // - lastTimeOnly is set, and we are reaching the last invocationCount 530f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 53145a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust invokeConfigurations(testClass, tm, 53245a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust filterConfigurationMethods(tm, afterMethods, false /* beforeMethods */), 53345a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust suite, params, 534f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust instances[instanceIndex]); 535f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 536f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 53745a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust // Invoke afterGroups configurations 538f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 539f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeAfterGroupsConfigurations(testClass, tm, groupMethods, suite, 540f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust params, instances[instanceIndex]); 541f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 542f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return testResult; 543f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 544f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 545f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 54645a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust * The array of methods contains @BeforeMethods if isBefore if true, @AfterMethods 54745a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust * otherwise. This function removes all the methods that should not be run at this 54845a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust * point because they are either firstTimeOnly or lastTimeOnly and we haven't reached 54945a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust * the current invocationCount yet 55045a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust */ 55145a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust private ITestNGMethod[] filterConfigurationMethods(ITestNGMethod tm, 55245a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust ITestNGMethod[] methods, boolean isBefore) 55345a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust { 55445a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust List<ITestNGMethod> result = new ArrayList<ITestNGMethod>(); 55545a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust for (ITestNGMethod m : methods) { 55645a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust ConfigurationMethod cm = (ConfigurationMethod) m; 55745a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust if (isBefore) { 55845a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust if (! cm.isFirstTimeOnly() || 55945a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust (cm.isFirstTimeOnly() && tm.getCurrentInvocationCount() == 0)) 56045a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust { 56145a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust result.add(m); 56245a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust } 56345a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust } 56445a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust else { 565d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust int current = tm.getCurrentInvocationCount(); 566d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust boolean isLast = false; 567d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust if (tm.getParameterInvocationCount() > 0) { 568d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust isLast = current == tm.getParameterInvocationCount(); 569d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust } 570d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust else if (tm.getInvocationCount() > 1) { 571d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust isLast = current == tm.getInvocationCount(); 572d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust } 573d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust// boolean isLastInvocationCount 574d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust// = tm.getInvocationCount() == 1 || 575d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust// current == tm.getInvocationCount(); 576d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust// boolean isLastParameterInvocationCount 577d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust// = tm.getParameterInvocationCount() > 0 && 578d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust// current == tm.getParameterInvocationCount(); 579d7e500014dc797345bc2e4f9ceb176fa225b8a37Cédric Beust if (! cm.isLastTimeOnly() || (cm.isLastTimeOnly() && isLast)) { 58045a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust result.add(m); 58145a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust } 58245a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust } 58345a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust } 58445a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust 58545a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust return result.toArray(new ITestNGMethod[result.size()]); 58645a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust } 58745a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust 58845a161fb7f6ba0937ec480fef1a803524bc07214Cédric Beust /** 589f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * {@link #invokeTestMethods()} eventually converge here to invoke a single @Test method. 590f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <p/> 591f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * This method is responsible for actually invoking the method. It decides if the invocation 592f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * must be done: 593f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <ul> 594f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <li>through an <code>IHookable</code></li> 595f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <li>directly (through reflection)</li> 596f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <li>in a separate thread (in case it needs to timeout) 597f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * </ul> 598f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * 599f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <p/> 600f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * This method is also reponsible for invoking @BeforeGroup, @BeforeMethod, @AfterMethod, @AfterGroup 601f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * if it is the case for the passed in @Test method. 602f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 603f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private List<ITestResult> invokeTestMethod(Object[] instances, 604f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ITestNGMethod tm, 605f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameterValues, 606f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 607f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> params, 608f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestClass testClass, 609f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] beforeMethods, 610f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afterMethods, 611f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods) 612f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 613f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> results = new ArrayList<ITestResult>(); 614f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 615f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Mark this method with the current thread id 616f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tm.setId(ThreadUtil.currentThreadInfo()); 617f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 618f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(int i= 0; i < instances.length; i++) { 619f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust results.add( 620f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeMethod(instances, i, tm, parameterValues, suite, params, 621f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testClass, beforeMethods, afterMethods, groupMethods)); 622f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 623f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 624f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return results; 625f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 626f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 627f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 628f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Filter all the beforeGroups methods and invoke only those that apply 629f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * to the current test method 630f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 631f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void invokeBeforeGroupsConfigurations(ITestClass testClass, 632f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod currentTestMethod, 633f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 634f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 635f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> params, 636f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object instance) 637f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 638f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust synchronized(groupMethods) { 639f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestNGMethod> filteredMethods = new ArrayList<ITestNGMethod>(); 640f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] groups = currentTestMethod.getGroups(); 641f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, List<ITestNGMethod>> beforeGroupMap = groupMethods.getBeforeGroupsMap(); 642f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 643f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (String group : groups) { 644f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestNGMethod> methods = beforeGroupMap.get(group); 645f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (methods != null) { 646f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust filteredMethods.addAll(methods); 647f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 648f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 649f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 650f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] beforeMethodsArray = filteredMethods.toArray(new ITestNGMethod[filteredMethods.size()]); 651f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 652f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Invoke the right groups methods 653f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 654f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(beforeMethodsArray.length > 0) { 655f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // don't pass the IClass or the instance as the method may be external 656f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // the invocation must be similar to @BeforeTest/@BeforeSuite 657f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeConfigurations(null, beforeMethodsArray, suite, params, null); 658f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 659f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 660f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 661f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Remove them so they don't get run again 662f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 663f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust groupMethods.removeBeforeGroups(groups); 664f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 665f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 666f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 667f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void invokeAfterGroupsConfigurations(ITestClass testClass, 668f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod currentTestMethod, 669f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 670f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 671f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> params, 672f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object instance) 673f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 674f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Skip this if the current method doesn't belong to any group 675f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // (only a method that belongs to a group can trigger the invocation 676f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // of afterGroups methods) 677f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (currentTestMethod.getGroups().length == 0) return; 678f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 679f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // See if the currentMethod is the last method in any of the groups 680f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // it belongs to 681f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> filteredGroups = new HashMap<String, String>(); 682f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] groups = currentTestMethod.getGroups(); 683f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust synchronized(groupMethods) { 684f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (String group : groups) { 685f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (groupMethods.isLastMethodForGroup(group, currentTestMethod)) { 686f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust filteredGroups.put(group, group); 687f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 688f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 689f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 690f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(filteredGroups.isEmpty()) return; 691f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 692f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // The list of afterMethods to run 693f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<ITestNGMethod, ITestNGMethod> afterMethods = new HashMap<ITestNGMethod, ITestNGMethod>(); 694f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 695f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Now filteredGroups contains all the groups for which we need to run the afterGroups 696f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // method. Find all the methods that correspond to these groups and invoke them. 697f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, List<ITestNGMethod>> map = groupMethods.getAfterGroupsMap(); 698f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (String g : filteredGroups.values()) { 699f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestNGMethod> methods = map.get(g); 700f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Note: should put them in a map if we want to make sure the same afterGroups 701f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // doesn't get run twice 702f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (methods != null) { 703f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (ITestNGMethod m : methods) { 704f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust afterMethods.put(m, m); 705f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 706f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 707f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 708f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 709f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Got our afterMethods, invoke them 710f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afterMethodsArray = afterMethods.keySet().toArray(new ITestNGMethod[afterMethods.size()]); 711f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // don't pass the IClass or the instance as the method may be external 712f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // the invocation must be similar to @BeforeTest/@BeforeSuite 713f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeConfigurations(null, afterMethodsArray, suite, params, null); 714f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 715f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Remove the groups so they don't get run again 716f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust groupMethods.removeAfterGroups(filteredGroups.keySet()); 717f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 718f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 719f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 720f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private Object[] getParametersFromIndex(Iterator<Object[]> parametersValues, int index) { 721f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust while (parametersValues.hasNext()) { 722f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameters = parametersValues.next(); 723f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 724f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (index == 0) { 725f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return parameters; 726f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 727f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust index--; 728f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 729f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return null; 730f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 731f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 732f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private int retryFailed(Object[] instances, 733f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int instanceIndex, 734f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ITestNGMethod tm, 735f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 736f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestClass testClass, 737f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] beforeMethods, 738f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afterMethods, 739f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 740f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> result, 741f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int failureCount, 742f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Class<?>[] expectedExceptionClasses, 743f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestContext testContext, 744f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters, 745f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int parametersIndex) { 74692206009b23ecbbf29e5a0d20f6b095a552afcb8Cédric Beust List<Object> failedInstances; 747f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 74892206009b23ecbbf29e5a0d20f6b095a552afcb8Cédric Beust do { 74992206009b23ecbbf29e5a0d20f6b095a552afcb8Cédric Beust failedInstances = new ArrayList<Object>(); 750f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> allParameters = new HashMap<String, String>(); 751f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 752f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * TODO: This recreates all the parameters every time when we only need 753f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * one specific set. Should optimize it by only recreating the set needed. 754f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 755f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ParameterBag bag = createParameters(testClass, tm, parameters, 756f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameters, suite, testContext); 757f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameterValues = getParametersFromIndex(bag.parameterValues, parametersIndex); 758f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 759f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result.add( 760f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeMethod(instances, instanceIndex, tm, parameterValues, suite, 761f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameters, testClass, beforeMethods, afterMethods, groupMethods)); 762f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failureCount = handleInvocationResults(tm, result, failedInstances, 763f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failureCount, expectedExceptionClasses, true); 764f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 765f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust while (!failedInstances.isEmpty()); 766f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return failureCount; 767f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 768f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 769f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ParameterBag createParameters(ITestClass testClass, 770f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod testMethod, 771f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters, 772f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> allParameterNames, 773f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 774f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestContext testContext) { 775f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object instance = testClass.getInstances(true)[0]; 776f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ParameterBag bag= handleParameters(testMethod, 777f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust instance, allParameterNames, parameters, suite, testContext); 778f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 779f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return bag; 780f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 781f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 782f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 783f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Invoke all the test methods. Note the plural: the method passed in 784f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * parameter might be invoked several times if the test class it belongs 785f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * to has more than one instance (i.e., if an @Factory method has been 786f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * declared somewhere that returns several instances of this TestClass). 787f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * If no @Factory method was specified, testMethod will only be invoked 788f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * once. 789f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * <p/> 790f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Note that this method also takes care of invoking the beforeTestMethod 791f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * and afterTestMethod, if any. 792f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * 793f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Note (alex): this method can be refactored to use a SingleTestMethodWorker that 794f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * directly invokes 795f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * {@link #invokeTestMethod(Object[], ITestNGMethod, Object[], XmlSuite, Map, ITestClass, ITestNGMethod[], ITestNGMethod[], ConfigurationGroupMethods)} 796f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * and this would simplify the implementation (see how DataTestMethodWorker is used) 797f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 798f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod, 799f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] allTestMethods, 800f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int testMethodIndex, 801f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 802f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters, 803f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 804f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] instances, 805f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestContext testContext) 806f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 807f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Potential bug here if the test method was declared on a parent class 808f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust assert null != testMethod.getTestClass() 809f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust : "COULDN'T FIND TESTCLASS FOR " + testMethod.getMethod().getDeclaringClass(); 810f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 811f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> result = new ArrayList<ITestResult>(); 812f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 813f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestClass testClass= testMethod.getTestClass(); 814f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust long start= System.currentTimeMillis(); 815f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 816f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 817f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // TODO: 818f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // - [DONE] revisit invocationCount, threadPoolSize values 819f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // - try to remove the isWithinThreadedMethod: still needed to determine the @BeforeMethod + @AfterMethod 820f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // - [DONE] solve the results different approaches: assignment and addAll 821f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 8226cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust // For invocationCount>1 and threadPoolSize>1 the method will be invoked on a thread pool 823f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int invocationCount = (testMethod.getThreadPoolSize() > 1 ? 1 : testMethod.getInvocationCount()); 824f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 825f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int failureCount = 0; 826f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 827f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Class<?>[] expectedExceptionClasses = 828f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.findExpectedExceptions(m_annotationFinder, testMethod.getMethod()); 829f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust while(invocationCount-- > 0) { 830f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean okToProceed = checkDependencies(testMethod, testClass, allTestMethods); 831f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 832f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (okToProceed) { 833f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 834f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Invoke the test method if it's enabled 835f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 836f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (MethodHelper.isEnabled(testMethod.getMethod(), m_annotationFinder)) { 837f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 8386cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust // If threadPoolSize specified, run this method in its own pool thread. 839f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 840f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (testMethod.getThreadPoolSize() > 1 && testMethod.getInvocationCount() > 1) { 841f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return invokePooledTestMethods(testMethod, allTestMethods, suite, 842f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameters, groupMethods, testContext); 843f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 844f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 845f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 846f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // No threads, regular invocation 847f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 848f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 849f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] beforeMethods = filterMethods(testClass, testClass.getBeforeTestMethods()); 850f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afterMethods = filterMethods(testClass, testClass.getAfterTestMethods()); 851f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 852f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 853f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> allParameterNames = new HashMap<String, String>(); 854f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ParameterBag bag = createParameters(testClass, testMethod, 855f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameters, allParameterNames, suite, testContext); 856f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 857f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(bag.hasErrors()) { 858f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failureCount = handleInvocationResults(testMethod, 859f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust bag.errorResults, null, failureCount, expectedExceptionClasses, true); 860f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // there is nothing we can do more 861f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust continue; 862f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 863f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 864f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Iterator<Object[]> allParameterValues= bag.parameterValues; 865f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 866f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(testMethod.getThreadPoolSize() > 1) { 867f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return invokePooledTestMethods(instances, 868f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod, 869f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allTestMethods, 870f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust beforeMethods, 871f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust afterMethods, 872f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust groupMethods, 873f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust suite, 874f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameters, 875f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameterNames, 876f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameterValues); 877f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 878f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 879f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int parametersIndex = 0; 880f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 881f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust while (allParameterValues.hasNext()) { 882f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameterValues= allParameterValues.next(); 883f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> tmpResults = new ArrayList<ITestResult>(); 884f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 885f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 886f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust tmpResults.addAll(invokeTestMethod(instances, 887f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod, 888f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues, 889f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust suite, 890f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameterNames, 891f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testClass, 892f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust beforeMethods, 893f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust afterMethods, 894f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust groupMethods)); 895f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 896f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust finally { 897f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<Object> failedInstances = new ArrayList<Object>(); 898f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 899f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failureCount = handleInvocationResults(testMethod, tmpResults, 900f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failedInstances, failureCount, expectedExceptionClasses, true); 901f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (failedInstances.isEmpty()) { 902f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result.addAll(tmpResults); 903f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } else { 904f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (int i = 0; i < failedInstances.size(); i++) { 905f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> retryResults = new ArrayList<ITestResult>(); 906f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 9076cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust failureCount = 9086cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust retryFailed(failedInstances.toArray(), 9096cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust i, testMethod, suite, testClass, beforeMethods, 9106cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust afterMethods, groupMethods, retryResults, 9116cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust failureCount, expectedExceptionClasses, 9126cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust testContext, parameters, parametersIndex); 9136cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust result.addAll(retryResults); 914f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 915f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 9166cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust 9176cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust // 9186cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust // If we have a failure, skip all the 9196cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust // other invocationCounts 9206cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust // 92161e3a3733701551995e8330db1db52a53a185404Cédric Beust 92261e3a3733701551995e8330db1db52a53a185404Cédric Beust // If not specified globally, use the attribute 92361e3a3733701551995e8330db1db52a53a185404Cédric Beust // on the annotation 92461e3a3733701551995e8330db1db52a53a185404Cédric Beust // 92561e3a3733701551995e8330db1db52a53a185404Cédric Beust if (! m_skipFailedInvocationCounts) { 92661e3a3733701551995e8330db1db52a53a185404Cédric Beust m_skipFailedInvocationCounts = testMethod.skipFailedInvocations(); 92761e3a3733701551995e8330db1db52a53a185404Cédric Beust } 9286cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust if (failureCount > 0 && m_skipFailedInvocationCounts) { 9296cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust while (invocationCount-- > 0) { 9306cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust ITestResult r = 9316cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust new TestResult(testMethod.getTestClass(), 9326cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust instances[0], 9336cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust testMethod, 9346cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust null, 9356cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust start, 9366cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust System.currentTimeMillis()); 9376cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust r.setStatus(TestResult.SKIP); 9386cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust result.add(r); 9396cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust runTestListeners(r); 9406cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust m_notifier.addSkippedTest(testMethod, r); 9416cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust } 9426cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust break; 9436cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust } 944f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 945f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parametersIndex++; 946f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 947f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // for parameters 948f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 949f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 950f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // isTestMethodEnabled 951f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 952f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // okToProceed 953f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 954f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 955f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Test is being skipped 956f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 957f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResult testResult= new TestResult(testClass, null, 958f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod, 959f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust null, 960f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust start, 961f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis()); 962f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setEndMillis(System.currentTimeMillis()); 963f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String missingGroup = testMethod.getMissingGroup(); 964f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (missingGroup != null) { 965f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(new Throwable("Method " + testMethod 966f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust + " depends on nonexistent group \"" + missingGroup + "\"")); 967f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 968f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 969f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SKIP); 970f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addSkippedTest(testMethod, testResult); 971f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runTestListeners(testResult); 972f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 973f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 974f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 975f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 976f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 977f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // invokeTestMethod 978f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 979f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ParameterBag handleParameters(ITestNGMethod testMethod, 980f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object instance, 981f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> allParameterNames, 982f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters, 983f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 984f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestContext testContext) 985f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 986f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust try { 987f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return new ParameterBag(Parameters.handleParameters(testMethod, 988f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameterNames, 989f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust instance, 990f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust new Parameters.MethodParameters(parameters, testMethod.getMethod(), testContext), 991f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust suite, 992f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_annotationFinder), null); 993f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 994f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust catch(Throwable cause) { 995f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return new ParameterBag(null, 996f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust new TestResult( 997f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod.getTestClass(), 998f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust instance, 999f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod, 1000f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust cause, 1001f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis(), 1002f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.currentTimeMillis())); 1003f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1004f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1005f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1006f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1007f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private List<ITestResult> invokePooledTestMethods(Object[] instances, 1008f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod testMethod, 1009f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] allTestMethods, 1010f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] beforeMethods, 1011f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afterMethods, 1012f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 1013f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 1014f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters, 1015f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> allParameterNames, 1016f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Iterator<Object[]> allParameterValues) 1017f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 1018f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1019f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Create the workers 1020f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1021f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<IMethodWorker> workers= new ArrayList<IMethodWorker>(); 1022f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1023f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust while (allParameterValues.hasNext()) { 1024f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] parameterValues= allParameterValues.next(); 1025f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust workers.add(new DataTestMethodWorker(instances, 1026f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod.clone(), // we use clones for reporting purposes 1027f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues, 1028f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust beforeMethods, 1029f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust afterMethods, 1030f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust groupMethods, 1031f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust suite, 1032f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allParameterNames)); 1033f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1034f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1035f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return runWorkers(testMethod, workers, testMethod.getThreadPoolSize(), groupMethods, suite, parameters); 1036f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1037f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1038f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1039f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * Invokes a method that has a specified threadPoolSize. 1040f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1041f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private List<ITestResult> invokePooledTestMethods(ITestNGMethod testMethod, 1042f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] allTestMethods, 1043f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 1044f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters, 1045f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 1046f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestContext testContext) 1047f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 1048f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1049f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Create the workers 1050f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1051f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<IMethodWorker> workers= new ArrayList<IMethodWorker>(); 1052f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1053f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (int i = 0; i < testMethod.getInvocationCount(); i++) { 1054f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // we use clones for reporting purposes 1055f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod clonedMethod= testMethod.clone(); 1056f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust clonedMethod.setInvocationCount(1); 1057f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust clonedMethod.setThreadPoolSize(1); 1058f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1059f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodInstance mi = new MethodInstance(clonedMethod, clonedMethod.getTestClass().getInstances(true)); 1060f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust workers.add(new SingleTestMethodWorker(this, 1061f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust mi, 1062f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust suite, 1063f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameters, 1064f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allTestMethods, 1065f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testContext)); 1066f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1067f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1068f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return runWorkers(testMethod, workers, testMethod.getThreadPoolSize(), groupMethods, suite, parameters); 1069f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1070f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1071f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1072f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param testMethod 1073f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param result 1074f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param failureCount 1075f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param expectedExceptionClasses 1076f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return 1077f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1078f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private int handleInvocationResults(ITestNGMethod testMethod, 1079f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> result, 1080f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<Object> failedInstances, 1081f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int failureCount, 1082f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Class<?>[] expectedExceptionClasses, 1083f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean triggerListeners) { 1084f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1085f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Go through all the results and create a TestResult for each of them 1086f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1087f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> resultsToRetry = new ArrayList<ITestResult>(); 1088f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1089f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (int i = 0; i < result.size(); i++) { 1090f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResult testResult = result.get(i); 1091f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Throwable ite= testResult.getThrowable(); 1092f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int status= testResult.getStatus(); 1093f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1094f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Exception thrown? 1095f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(ite != null) { 1096f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1097f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Invocation caused an exception, see if the method was annotated with @ExpectedException 1098f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(isExpectedException(ite, expectedExceptionClasses)) { 1099f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SUCCESS); 1100f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust status= ITestResult.SUCCESS; 1101f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1102f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if (SkipException.class.isAssignableFrom(ite.getClass())){ 1103f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust SkipException skipEx= (SkipException) ite; 1104f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(skipEx.isSkip()) { 1105f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust status= ITestResult.SKIP; 1106f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1107f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 1108f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleException(ite, testMethod, testResult, failureCount++); 1109f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust status= ITestResult.FAILURE; 1110f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1111f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1112f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 1113f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust handleException(ite, testMethod, testResult, failureCount++); 1114f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust status= testResult.getStatus(); 1115f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1116f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1117f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1118f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // No exception thrown, make sure we weren't expecting one 1119f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if(status != ITestResult.SKIP) { 1120f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (expectedExceptionClasses.length > 0) { 1121f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable( 1122f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust new TestException("Expected an exception in test method " + testMethod)); 1123f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust status= ITestResult.FAILURE; 1124f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1125f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1126f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1127f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(status); 1128f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1129f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean retry = false; 1130f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1131f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (testResult.getStatus() == ITestResult.FAILURE) { 1132f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust IRetryAnalyzer retryAnalyzer = testMethod.getRetryAnalyzer(); 1133f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1134f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (retryAnalyzer != null) { 1135f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust retry = retryAnalyzer.retry(testResult); 1136f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1137f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1138f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (retry) { 1139f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust resultsToRetry.add(testResult); 1140f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (failedInstances != null) { 1141f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failedInstances.add(testResult.getMethod().getInstances()[i]); 1142f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1143f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1144f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1145f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (!retry) { 1146f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Collect the results 1147f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(ITestResult.SUCCESS == status) { 1148f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addPassedTest(testMethod, testResult); 1149f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1150f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if(ITestResult.SKIP == status) { 1151f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addSkippedTest(testMethod, testResult); 1152f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1153f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if(ITestResult.FAILURE == status) { 1154f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addFailedTest(testMethod, testResult); 1155f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1156f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else if(ITestResult.SUCCESS_PERCENTAGE_FAILURE == status) { 1157f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_notifier.addFailedButWithinSuccessPercentageTest(testMethod, testResult); 1158f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1159f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 1160f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust assert false : "UNKNOWN STATUS:" + status; 1161f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1162f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1163f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (triggerListeners) { 1164f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runTestListeners(testResult); 1165f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1166f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1167f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // for results 1168f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1169f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return removeResultsToRetryFromResult(resultsToRetry, result, failureCount); 1170f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1171f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1172f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private int removeResultsToRetryFromResult(List<ITestResult> resultsToRetry, 1173f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> result, int failureCount) { 1174f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (resultsToRetry != null) { 1175f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (ITestResult res : resultsToRetry) { 1176f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result.remove(res); 1177f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust failureCount--; 1178f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1179f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1180f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return failureCount; 1181f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1182f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1183f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1184f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * To reduce thread contention and also to correctly handle thread-confinement 1185f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * this method invokes the @BeforeGroups and @AfterGroups corresponding to the current @Test method. 1186f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1187f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private List<ITestResult> runWorkers(ITestNGMethod testMethod, 1188f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<IMethodWorker> workers, 1189f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int threadPoolSize, 1190f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 1191f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 1192f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> parameters) 1193f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 1194f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // HINT: invoke @BeforeGroups on the original method (reduce thread contention, and also solve thread confinement) 1195f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestClass testClass= testMethod.getTestClass(); 1196f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] instances = testClass.getInstances(true); 1197f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(Object instance: instances) { 1198f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeBeforeGroupsConfigurations(testClass, testMethod, groupMethods, suite, parameters, instance); 1199f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1200f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1201f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1202f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust long maxTimeOut= -1; // 10 seconds 1203f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1204f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(IMethodWorker tmw : workers) { 1205f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust long mt= tmw.getMaxTimeOut(); 1206f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(mt > maxTimeOut) { 1207f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust maxTimeOut= mt; 1208f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1209f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1210f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1211f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ThreadUtil.execute(workers, threadPoolSize, maxTimeOut, true); 1212f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1213f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1214f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Collect all the TestResults 1215f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // 1216f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> result = new ArrayList<ITestResult>(); 1217f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (IMethodWorker tmw : workers) { 1218f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result.addAll(tmw.getTestResults()); 1219f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1220f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1221f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(Object instance: instances) { 1222f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust invokeAfterGroupsConfigurations(testClass, testMethod, groupMethods, suite, parameters, instance); 1223f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1224f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1225f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 1226f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1227f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1228f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1229f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param testMethod 1230f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param testClass 1231f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return dependencies have been run successfully 1232f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1233f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean checkDependencies(ITestNGMethod testMethod, ITestClass testClass, ITestNGMethod[] allTestMethods) 1234f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust { 1235f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean result= true; 1236f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1237f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If this method is marked alwaysRun, no need to check for its 1238f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // dependencies 1239f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (testMethod.isAlwaysRun()) { 1240f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return true; 1241f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1242f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1243f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Any missing group? 1244f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (testMethod.getMissingGroup() != null) { 1245f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return false; 1246f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1247f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1248f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If this method depends on groups, collect all the methods that 1249f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // belong to these groups and make sure they have been run successfully 1250f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(dependsOnGroups(testMethod)) { 1251f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] groupsDependedUpon= testMethod.getGroupsDependedUpon(); 1252f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1253f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Get all the methods that belong to the group depended upon 1254f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(int i= 0; i < groupsDependedUpon.length; i++) { 1255f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] methods = 1256f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.findMethodsThatBelongToGroup(testMethod, 1257f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_testContext.getAllTestMethods(), 1258f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust groupsDependedUpon[i]); 1259f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1260f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result = result && haveBeenRunSuccessfully(methods); 1261f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1262f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } // depends on groups 1263f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1264f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If this method depends on other methods, make sure all these other 1265f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // methods have been run successfully 1266f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(dependsOnMethods(testMethod)) { 1267f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] methods = 1268f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust MethodHelper.findMethodsNamed(testMethod.getMethod().getName(), 1269f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust allTestMethods, 1270f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testMethod.getMethodsDependedUpon()); 1271f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1272f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust result= result && haveBeenRunSuccessfully(methods); 1273f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1274f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1275f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 1276f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1277f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1278f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1279f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return true if all the methods have been run successfully 1280f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1281f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean haveBeenRunSuccessfully(ITestNGMethod[] methods) { 1282f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // Make sure the method has been run successfully 1283f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(int j= 0; j < methods.length; j++) { 1284f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Set<ITestResult> results= m_notifier.getPassedTests(methods[j]); 1285f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1286f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // If no results were returned, then these tests didn't pass 1287f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if (results == null || results.size() == 0) return false; 1288f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1289f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (ITestResult result : results) { 1290f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(!result.isSuccess()) { 1291f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return false; 1292f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1293f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1294f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1295f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1296f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return true; 1297f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1298f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1299f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1300f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * An exception was thrown by the test, determine if this method 1301f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * should be marked as a failure or as failure_but_within_successPercentage 1302f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1303f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void handleException(Throwable throwable, 1304f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod testMethod, 1305f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestResult testResult, 1306f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int failureCount) { 1307f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setThrowable(throwable); 1308f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int successPercentage= testMethod.getSuccessPercentage(); 1309f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust int invocationCount= testMethod.getInvocationCount(); 1310f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust float numberOfTestsThatCanFail= ((100 - successPercentage) * invocationCount) / 100; 1311f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1312f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(failureCount < numberOfTestsThatCanFail) { 1313f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.SUCCESS_PERCENTAGE_FAILURE); 1314f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1315f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 1316f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testResult.setStatus(ITestResult.FAILURE); 1317f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1318f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1319f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1320f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1321f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1322f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param ite The exception that was just thrown 1323f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @param expectedExceptions The list of expected exceptions for this 1324f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * test method 1325f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return true if the exception that was just thrown is part of the 1326f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * expected exceptions 1327f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1328f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean isExpectedException(Throwable ite, Class<?>[] exceptions) { 1329f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == exceptions) { 1330f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return false; 1331f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1332f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1333f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Class<?> realExceptionClass= ite.getClass(); 1334f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1335f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(int i= 0; i < exceptions.length; i++) { 1336f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(exceptions[i].isAssignableFrom(realExceptionClass)) { 1337f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return true; 1338f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1339f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1340f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1341f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return false; 1342f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1343f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1344f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1345f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return Only the ITestNGMethods applicable for this testClass 1346f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1347f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ITestNGMethod[] filterMethods(IClass testClass, ITestNGMethod[] methods) { 1348f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestNGMethod> vResult= new ArrayList<ITestNGMethod>(); 1349f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1350f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(ITestNGMethod tm : methods) { 1351f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(tm.canRunFromClass(testClass)) { 1352f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(9, "Keeping method " + tm + " for class " + testClass); 1353f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust vResult.add(tm); 1354f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1355f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 1356f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(9, "Filtering out method " + tm + " for class " + testClass); 1357f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1358f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1359f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1360f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] result= vResult.toArray(new ITestNGMethod[vResult.size()]); 1361f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1362f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 1363f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1364f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1365f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private ITestNGMethod[] filterMethodsUnique(IClass testClass, ITestNGMethod[] methods) { 1366f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == testClass) { 1367f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return methods; 1368f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1369f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1370f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestNGMethod> vResult= new ArrayList<ITestNGMethod>(); 1371f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1372f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(ITestNGMethod tm : methods) { 1373f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(null == testClass) { 1374f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust testClass= tm.getTestClass(); 1375f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1376f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1377f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(tm.getTestClass().getName().equals(testClass.getName())) { 1378f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(9, " Keeping method " + tm + " for class " + testClass); 1379f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1380f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust vResult.add(tm); 1381f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1382f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust else { 1383f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust log(9, " Filtering out method " + tm + " for class " + testClass); 1384f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1385f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1386f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1387f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] result= vResult.toArray(new ITestNGMethod[vResult.size()]); 1388f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1389f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 1390f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1391f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1392f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1393f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return true if this method depends on certain groups. 1394f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1395f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean dependsOnGroups(ITestNGMethod tm) { 1396f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] groups= tm.getGroupsDependedUpon(); 1397f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean result= (null != groups) && (groups.length > 0); 1398f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1399f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 1400f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1401f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1402f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust /** 1403f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust * @return true if this method depends on certain groups. 1404f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust */ 1405f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private boolean dependsOnMethods(ITestNGMethod tm) { 1406f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust String[] methods= tm.getMethodsDependedUpon(); 1407f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust boolean result= (null != methods) && (methods.length > 0); 1408f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1409f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return result; 1410f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1411f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1412f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void runConfigurationListeners(ITestResult tr) { 1413f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for(IConfigurationListener icl: m_notifier.getConfigurationListeners()) { 1414f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust switch(tr.getStatus()) { 1415f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.SKIP: 1416f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust icl.onConfigurationSkip(tr); 1417f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1418f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.FAILURE: 1419f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust icl.onConfigurationFailure(tr); 1420f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1421f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.SUCCESS: 1422f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust icl.onConfigurationSuccess(tr); 1423f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1424f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1425f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1426f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1427f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1428f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void runTestListeners(ITestResult tr) { 1429f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust runTestListeners(tr, m_notifier.getTestListeners()); 1430f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1431f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1432f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust // TODO: move this from here as it is directly called from TestNG 1433f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public static void runTestListeners(ITestResult tr, List<ITestListener> listeners) { 1434f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust for (ITestListener itl : listeners) { 1435f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust switch(tr.getStatus()) { 1436f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.SKIP: { 1437f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust itl.onTestSkipped(tr); 1438f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1439f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1440f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.SUCCESS_PERCENTAGE_FAILURE: { 1441f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust itl.onTestFailedButWithinSuccessPercentage(tr); 1442f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1443f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1444f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.FAILURE: { 1445f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust itl.onTestFailure(tr); 1446f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1447f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1448f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.SUCCESS: { 1449f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust itl.onTestSuccess(tr); 1450f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1451f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1452f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1453f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust case ITestResult.STARTED: { 1454f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust itl.onTestStart(tr); 1455f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust break; 1456f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1457f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1458f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust default: { 1459f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust assert false : "UNKNOWN STATUS:" + tr; 1460f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1461f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1462f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1463f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1464f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1465f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private static void ppp(String s) { 1466f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust System.out.println("[Invoker]" + s); 1467f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1468f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1469f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private void log(int level, String s) { 1470f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Utils.log("Invoker " + Thread.currentThread().hashCode(), level, s); 1471f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1472f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1473f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private class DataTestMethodWorker implements IMethodWorker { 1474f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final Object[] m_instances; 1475f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ITestNGMethod m_testMethod; 1476f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ITestNGMethod[] m_beforeMethods; 1477f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ITestNGMethod[] m_afterMethods; 1478f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final ConfigurationGroupMethods m_groupMethods; 1479f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final Object[] m_parameters; 1480f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final XmlSuite m_suite; 1481f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final Map<String, String> m_allParameterNames; 1482f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1483f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust List<ITestResult> m_results; 1484f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1485f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public DataTestMethodWorker(Object[] instances, 1486f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod testMethod, 1487f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Object[] params, 1488f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] befores, 1489f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ITestNGMethod[] afters, 1490f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust ConfigurationGroupMethods groupMethods, 1491f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust XmlSuite suite, 1492f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust Map<String, String> paramNames) { 1493f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_instances= instances; 1494f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_testMethod= testMethod; 1495f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_parameters= params; 1496f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_beforeMethods= befores; 1497f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_afterMethods= afters; 1498f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_groupMethods= groupMethods; 1499f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_suite= suite; 1500f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_allParameterNames= paramNames; 1501f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1502f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1503f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public long getMaxTimeOut() { 1504f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return 0; 1505f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1506f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1507f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public void run() { 1508f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_results= invokeTestMethod(m_instances, 1509f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_testMethod, 1510f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_parameters, 1511f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_suite, 1512f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_allParameterNames, 1513f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_testMethod.getTestClass(), 1514f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_beforeMethods, 1515f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_afterMethods, 1516f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust m_groupMethods); 1517f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1518f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1519f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public List<ITestResult> getTestResults() { 1520f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return m_results; 1521f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1522f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1523f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1524f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust private static class ParameterBag { 1525f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final Iterator<Object[]> parameterValues; 1526f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust final List<ITestResult> errorResults= new ArrayList<ITestResult>(); 1527f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1528f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public ParameterBag(Iterator<Object[]> params, TestResult tr) { 1529f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust parameterValues= params; 1530f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust if(tr != null) { 1531f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust errorResults.add(tr); 1532f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1533f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1534f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust 1535f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust public boolean hasErrors() { 1536f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust return !errorResults.isEmpty(); 1537f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1538f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust } 1539f17a79b6a57f282e5cc0fbe741e73309e217976eCédric Beust} 1540