Skip to content

Commit

Permalink
decreasing complexity of transform in PhasedTestListener (#135)
Browse files Browse the repository at this point in the history
* decreasing complexity of transform in PhasedTestListener
* Fixed #99 making the retry anylizer disabled at one go only
* Moved the exceptions to a dedicated package. 
* RenamedPhasedTestConfigValueHandler to ConfigValueHandlerPhased
  • Loading branch information
baubakg committed Sep 14, 2023
1 parent 0f411f6 commit 3276ddd
Show file tree
Hide file tree
Showing 29 changed files with 164 additions and 187 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ For now, we do not know how parallel execution will work with phased tests. So i
For now, we have not come around to deciding how retry should work in the case of phased tests. By default, we deactivate them on the phased tests unless the user specifically chooses to activate them by setting the system property `PHASED.TESTS.RETRY.DISABLED` to false.

## Release Notes
### Up-Coming
* Renaming ConfigValueHandler to PhasedTest
### 8.0.0
* [Non-Interrupted Events](#Shuffled---Non-Interruptive)
* [#112](https://github.com/adobe/phased-testing/issues/112) Technical : Extracted the execution properties to the class ConfigValueHandler.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.adobe.campaign.tests.integro.phased.utils;

import com.adobe.campaign.tests.integro.phased.PhasedTestManager;
import com.adobe.campaign.tests.integro.phased.Phases;
package com.adobe.campaign.tests.integro.phased;

import java.util.Arrays;

public enum ConfigValueHandler {
public enum ConfigValueHandlerPhased {
PROP_SELECTED_PHASE("PHASED.TESTS.PHASE", Phases.NON_PHASED.name(), false),
EVENTS_NONINTERRUPTIVE("PHASED.EVENTS.NONINTERRUPTIVE",null, false),
PROP_PHASED_TEST_DATABROKER("PHASED.TESTS.DATABROKER", null, false),
Expand All @@ -33,7 +30,7 @@ public enum ConfigValueHandler {
public final String defaultValue;
public final boolean requiredValue;

ConfigValueHandler(String in_propertyName, String in_defaultValue, boolean in_requiredValue) {
ConfigValueHandlerPhased(String in_propertyName, String in_defaultValue, boolean in_requiredValue) {
systemName =in_propertyName;
defaultValue=in_defaultValue;
requiredValue=in_requiredValue;
Expand Down Expand Up @@ -66,7 +63,7 @@ public void reset() {
* Resets all of the values
*/
public static void resetAllValues() {
Arrays.stream(values()).forEach(ConfigValueHandler::reset);
Arrays.stream(values()).forEach(ConfigValueHandlerPhased::reset);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
*/
package com.adobe.campaign.tests.integro.phased;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestingEventException;

public abstract class NonInterruptiveEvent implements Runnable {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
*/
package com.adobe.campaign.tests.integro.phased;

import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestConfigurationException;
import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestException;
import com.adobe.campaign.tests.integro.phased.utils.ClassPathParser;
import com.adobe.campaign.tests.integro.phased.utils.ConfigValueHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.ITestResult;
Expand Down Expand Up @@ -45,15 +46,15 @@ public static String fetchApplicableEvent(Method in_method) {
return in_method.getDeclaredAnnotation(PhaseEvent.class).eventClasses()[0];
} else if (PhasedTestManager.isPhasedTest(in_method) && (in_method.getDeclaringClass().getDeclaredAnnotation(PhasedTest.class).eventClasses().length > 0)) {
return in_method.getDeclaringClass().getDeclaredAnnotation(PhasedTest.class).eventClasses()[0];
} else if (ConfigValueHandler.EVENTS_NONINTERRUPTIVE.isSet()) {
return ConfigValueHandler.EVENTS_NONINTERRUPTIVE.fetchValue();
} else if (ConfigValueHandlerPhased.EVENTS_NONINTERRUPTIVE.isSet()) {
return ConfigValueHandlerPhased.EVENTS_NONINTERRUPTIVE.fetchValue();
}
return null;
}

protected static enum EventMode {START, END};

static Map<String, NonInterruptiveEvent> events = new HashMap<String, NonInterruptiveEvent>();
static Map<String, NonInterruptiveEvent> events = new HashMap<>();


private static List<PhasedEventLogEntry> eventLogs = new ArrayList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
*/
package com.adobe.campaign.tests.integro.phased;

import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestConfigurationException;
import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestException;
import com.adobe.campaign.tests.integro.phased.internal.PhaseProcessorFactory;
import com.adobe.campaign.tests.integro.phased.permutational.ScenarioStepDependencies;
import com.adobe.campaign.tests.integro.phased.permutational.ScenarioStepDependencyFactory;
import com.adobe.campaign.tests.integro.phased.permutational.StepDependencies;
import com.adobe.campaign.tests.integro.phased.utils.ClassPathParser;
import com.adobe.campaign.tests.integro.phased.utils.ConfigValueHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.*;
Expand Down Expand Up @@ -55,12 +56,12 @@ public void alter(List<XmlSuite> suites) {

// *** Import DataBroker ***
String l_phasedDataBrokerClass = null;
if (ConfigValueHandler.PROP_PHASED_TEST_DATABROKER.isSet()) {
l_phasedDataBrokerClass = ConfigValueHandler.PROP_PHASED_TEST_DATABROKER.fetchValue();
if (ConfigValueHandlerPhased.PROP_PHASED_TEST_DATABROKER.isSet()) {
l_phasedDataBrokerClass = ConfigValueHandlerPhased.PROP_PHASED_TEST_DATABROKER.fetchValue();
} else if (suites.get(0).getAllParameters()
.containsKey(ConfigValueHandler.PROP_PHASED_TEST_DATABROKER.systemName)) {
.containsKey(ConfigValueHandlerPhased.PROP_PHASED_TEST_DATABROKER.systemName)) {
l_phasedDataBrokerClass = suites.get(0)
.getParameter(ConfigValueHandler.PROP_PHASED_TEST_DATABROKER.systemName);
.getParameter(ConfigValueHandlerPhased.PROP_PHASED_TEST_DATABROKER.systemName);
} else if (!Phases.NON_PHASED.isSelected()) {
log.info("{} No PhasedDataBroker set. Using the file system path {}/{} instead ",
PhasedTestManager.PHASED_TEST_LOG_PREFIX, PhasedTestManager.STD_STORE_DIR,
Expand Down Expand Up @@ -121,12 +122,6 @@ public void onTestStart(ITestResult result) {
if (PhasedTestManager.isPhasedTest(l_method)) {

//Cases 1,2,4,5
//Disable retrying of phased tests
if (ConfigValueHandler.PROP_DISABLE_RETRY.is("true")) {
log.info("{} Disabling Retry for phased Tests.", PhasedTestManager.PHASED_TEST_LOG_PREFIX);
result.getMethod().setRetryAnalyzerClass(DisabledRetryAnalyzer.class);
}

final String l_dataProvider = PhasedTestManager.concatenateParameterArray(result.getParameters());

PhasedTestManager.storePhasedContext(ClassPathParser.fetchFullName(l_method), l_dataProvider);
Expand Down Expand Up @@ -302,7 +297,7 @@ public void onFinish(ITestContext context) {
Collectors.toList()));

for (Entry<String, List<ITestResult>> each : l_phasedScenarios.entrySet()) {
log.info(PhasedTestManager.PHASED_TEST_LOG_PREFIX + "Reducing Report for " + each);
log.info("{} Reducing Report for {}",PhasedTestManager.PHASED_TEST_LOG_PREFIX, each);

//When the phase test scenario was not a success
if (PhasedTestManager.getScenarioContext().get(each.getKey()).isPassed()) {
Expand Down Expand Up @@ -420,50 +415,38 @@ private void handleFailedPhases(ITestContext context, Entry<String, List<ITestRe
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor,
Method testMethod) {
if (testClass != null) {

//inject the selector by PRODUCER
if (PhasedTestManager.isTestsSelectedByProducerMode() && PhasedTestManager.fetchExecutedPhasedClasses()
.contains(testClass.getTypeName())) {
//Create new group array
Set<String> l_newArrayString = new HashSet<>(Arrays.asList(annotation.getGroups()));
l_newArrayString.add(PhasedTestManager.STD_GROUP_SELECT_TESTS_BY_PRODUCER);
String[] l_newGroupArray = new String[l_newArrayString.size()];
annotation.setGroups(l_newArrayString.toArray(l_newGroupArray));
}

if (PhasedTestManager.isPhasedTest(testClass)) {
if (Phases.NON_PHASED.isSelected()) {
annotation.setDataProvider(
ConfigValueHandler.PHASED_TEST_NONPHASED_LEGACY.is("true") ? PhasedDataProvider.SINGLE : PhasedDataProvider.DEFAULT);
if (testClass == null && testMethod==null) {
return;
}

} else {
annotation.setDataProvider(PhasedTestManager.isPhasedTestShuffledMode(
testClass) ? PhasedDataProvider.SHUFFLED : PhasedDataProvider.SINGLE);
}
Class l_currentClass = testClass != null ? testClass : testMethod.getDeclaringClass();

annotation.setDataProviderClass(PhasedDataProvider.class);
}

//inject the selector by PRODUCER
if (PhasedTestManager.isTestsSelectedByProducerMode() && PhasedTestManager.fetchExecutedPhasedClasses()
.contains(l_currentClass.getTypeName())) {
//Create new group array
Set<String> l_newArrayString = new HashSet<>(Arrays.asList(annotation.getGroups()));
l_newArrayString.add(PhasedTestManager.STD_GROUP_SELECT_TESTS_BY_PRODUCER);
String[] l_newGroupArray = new String[l_newArrayString.size()];
annotation.setGroups(l_newArrayString.toArray(l_newGroupArray));
}

//Managing Phased tests on method level
if (testMethod == null) {
return;
}
if (PhasedTestManager.isPhasedTest(testMethod)) {
if (PhasedTestManager.isPhasedTest(l_currentClass)) {
if (Phases.NON_PHASED.isSelected()) {
annotation.setDataProvider(
ConfigValueHandler.PHASED_TEST_NONPHASED_LEGACY.is("true") ? PhasedDataProvider.SINGLE : PhasedDataProvider.DEFAULT);
ConfigValueHandlerPhased.PHASED_TEST_NONPHASED_LEGACY.is("true") ? PhasedDataProvider.SINGLE : PhasedDataProvider.DEFAULT);

} else {
annotation.setDataProvider(PhasedTestManager.isPhasedTestShuffledMode(
testMethod) ? PhasedDataProvider.SHUFFLED : PhasedDataProvider.SINGLE);
}
l_currentClass) ? PhasedDataProvider.SHUFFLED : PhasedDataProvider.SINGLE);
}

annotation.setDataProviderClass(PhasedDataProvider.class);
}
}


private static Stream<ITestResult> mergedStreamOfAllResults(ITestContext context) {
return Stream.concat(context.getFailedTests().getAllResults().stream(),
Stream.concat(
Expand All @@ -480,8 +463,13 @@ public List<IMethodInstance> intercept(List<IMethodInstance> list, ITestContext
Map<Class<?>, List<String>> l_classMethodMap = new HashMap<>();
Set<Class> l_phasedClasses = new HashSet<>();

if (ConfigValueHandlerPhased.PROP_DISABLE_RETRY.is("true")) {
log.debug("{} Disabling Retry for phased Tests.", PhasedTestManager.PHASED_TEST_LOG_PREFIX);
list.stream().filter(l -> PhasedTestManager.isPhasedTest(l.getMethod().getRealClass())).forEach(i -> i.getMethod().setRetryAnalyzerClass(DisabledRetryAnalyzer.class));
}

for (Method lt_method : list.stream()
.map(mi -> mi.getMethod().getConstructorOrMethod().getMethod()).filter(f -> PhasedTestManager.isPhasedTest(f))
.map(mi -> mi.getMethod().getConstructorOrMethod().getMethod()).filter(PhasedTestManager::isPhasedTest)
.collect(Collectors.toList())) {
l_phasedClasses.add(lt_method.getDeclaringClass());
//Method lt_method = lt_testNGMethod.getConstructorOrMethod().getMethod();
Expand Down Expand Up @@ -519,7 +507,7 @@ public List<IMethodInstance> intercept(List<IMethodInstance> list, ITestContext
}

//If the property PHASED.TESTS.DETECT.ORDER not set, we follow the standard TestNG order
if (ConfigValueHandler.PHASED_TEST_DETECT_ORDER.is("false")) {
if (ConfigValueHandlerPhased.PHASED_TEST_DETECT_ORDER.is("false")) {
log.info("{} Generating Phased Providers", PhasedTestManager.PHASED_TEST_LOG_PREFIX);
//NIA
PhasedTestManager.generatePhasedProviders(l_classMethodMap, Phases.getCurrentPhase());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
*/
package com.adobe.campaign.tests.integro.phased;

import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestConfigurationException;
import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestException;
import com.adobe.campaign.tests.integro.phased.permutational.ScenarioStepDependencies;
import com.adobe.campaign.tests.integro.phased.utils.ClassPathParser;
import com.adobe.campaign.tests.integro.phased.utils.ConfigValueHandler;
import com.adobe.campaign.tests.integro.phased.utils.GeneralTestUtils;
import com.adobe.campaign.tests.integro.phased.utils.StackTraceManager;
import java.util.Map.Entry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.ITestResult;
Expand All @@ -28,6 +28,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

public final class PhasedTestManager {
Expand All @@ -45,7 +46,7 @@ private PhasedTestManager() {
private static final Logger log = LogManager.getLogger();

public static final String DEFAULT_CACHE_DIR = "phased_output";
public static final String STD_CACHE_DIR = ConfigValueHandler.PROP_OUTPUT_DIR.fetchValue();
public static final String STD_CACHE_DIR = ConfigValueHandlerPhased.PROP_OUTPUT_DIR.fetchValue();
public static final String STD_STORE_DIR = "phased_tests";
public static final String STD_STORE_FILE = "phaseData.properties";

Expand Down Expand Up @@ -81,7 +82,7 @@ public enum ScenarioState {

static Boolean selectTestsByProducerMode = Boolean.FALSE;

static final String SCENARIO_CONTEXT_PREFIX = ConfigValueHandler.PROP_SCENARIO_EXPORTED_PREFIX.fetchValue();
static final String SCENARIO_CONTEXT_PREFIX = ConfigValueHandlerPhased.PROP_SCENARIO_EXPORTED_PREFIX.fetchValue();

public static class MergedReportData {

Expand Down Expand Up @@ -407,8 +408,8 @@ public static File exportPhaseData() {
public static File fetchExportFile() {
File l_exportCacheFile;

if (ConfigValueHandler.PROP_PHASED_DATA_PATH.isSet() ) {
return new File(ConfigValueHandler.PROP_PHASED_DATA_PATH.fetchValue());
if (ConfigValueHandlerPhased.PROP_PHASED_DATA_PATH.isSet() ) {
return new File(ConfigValueHandlerPhased.PROP_PHASED_DATA_PATH.fetchValue());
} else {
return new File(GeneralTestUtils.fetchCacheDirectory(STD_STORE_DIR), STD_STORE_FILE);
}
Expand Down Expand Up @@ -495,13 +496,13 @@ static Properties importPhaseData() {

if (dataBroker == null) {

if (ConfigValueHandler.PROP_PHASED_DATA_PATH.isSet()) {
l_importCacheFile = new File(ConfigValueHandler.PROP_PHASED_DATA_PATH.fetchValue());
if (ConfigValueHandlerPhased.PROP_PHASED_DATA_PATH.isSet()) {
l_importCacheFile = new File(ConfigValueHandlerPhased.PROP_PHASED_DATA_PATH.fetchValue());

} else {
l_importCacheFile = new File(GeneralTestUtils.fetchCacheDirectory(STD_STORE_DIR), STD_STORE_FILE);
log.warn("{} The system property {} not set. Fetching Phased Test data from {}.",
PHASED_TEST_LOG_PREFIX, ConfigValueHandler.PROP_PHASED_DATA_PATH.fetchValue(), l_importCacheFile.getPath());
PHASED_TEST_LOG_PREFIX, ConfigValueHandlerPhased.PROP_PHASED_DATA_PATH.systemName, l_importCacheFile.getPath());
}
} else {
log.info("{} Fetching cache through DataBroker.", PHASED_TEST_LOG_PREFIX);
Expand Down Expand Up @@ -1442,11 +1443,11 @@ public static String fetchClassFromScenarioContext(String in_scenario) {
*/
static void applyMergeReportChoice() {
//Activating merge results if the value is set in the system properties
if (ConfigValueHandler.PROP_MERGE_STEP_RESULTS.is("true")) {
if (ConfigValueHandlerPhased.PROP_MERGE_STEP_RESULTS.is("true")) {
activateMergedReports();
}

if (ConfigValueHandler.PROP_MERGE_STEP_RESULTS.is("false")) {
if (ConfigValueHandlerPhased.PROP_MERGE_STEP_RESULTS.is("false")) {
deactivateMergedReports();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
*/
package com.adobe.campaign.tests.integro.phased;

import com.adobe.campaign.tests.integro.phased.utils.ConfigValueHandler;

import java.util.Arrays;

public enum Phases {
Expand All @@ -34,7 +32,7 @@ public enum Phases {
*
*/
public static Phases getCurrentPhase() {
return fetchCorrespondingPhase(ConfigValueHandler.PROP_SELECTED_PHASE.fetchValue());
return fetchCorrespondingPhase(ConfigValueHandlerPhased.PROP_SELECTED_PHASE.fetchValue());
}

/**
Expand Down Expand Up @@ -90,7 +88,7 @@ public boolean hasSplittingEvent() {
*
*/
void activate() {
ConfigValueHandler.PROP_SELECTED_PHASE.activate(this.name());
ConfigValueHandlerPhased.PROP_SELECTED_PHASE.activate(this.name());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.adobe.campaign.tests.integro.phased;
package com.adobe.campaign.tests.integro.phased.exceptions;

/**
* Exceptions that are thrown when preparing the tests. Exceptions of this type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
*
*/
package com.adobe.campaign.tests.integro.phased;
package com.adobe.campaign.tests.integro.phased.exceptions;

/**
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.adobe.campaign.tests.integro.phased;
package com.adobe.campaign.tests.integro.phased.exceptions;

public class PhasedTestingEventException extends RuntimeException {
public PhasedTestingEventException(String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
package com.adobe.campaign.tests.integro.phased.internal;

import com.adobe.campaign.tests.integro.phased.PhasedTestConfigurationException;
import com.adobe.campaign.tests.integro.phased.exceptions.PhasedTestConfigurationException;
import com.adobe.campaign.tests.integro.phased.Phases;
import com.adobe.campaign.tests.integro.phased.utils.ClassPathParser;
import java.lang.annotation.Annotation;
Expand Down
Loading

0 comments on commit 3276ddd

Please sign in to comment.