
com.adobe.cq.testing.junit.rules.toggles.TogglesAwareTestRule Maven / Gradle / Ivy
/*
* Copyright 2021 Adobe
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adobe.cq.testing.junit.rules.toggles;
import com.adobe.cq.testing.client.TogglesClient;
import org.apache.sling.testing.clients.SlingClient;
import org.apache.sling.testing.clients.util.poller.Polling;
import org.junit.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
* Junit rule for filtering tests based on the toggles enabled on the remote instance.
*
* The rule is used in combination with the annotations {@link RunIfToggleEnabled} and
* {@link SkipIfToggleEnabled}.
* If both annotations are applied to a test, both conditions must be met (AND operation).
*
* @see RunIfToggleEnabled
* @see SkipIfToggleEnabled
*/
public class TogglesAwareTestRule implements TestRule {
private static final Logger LOG = LoggerFactory.getLogger(TogglesAwareTestRule.class);
/**
* Supplier of the client needed for retrieving the enabled toggles.
*/
private final Supplier clientSupplier;
public TogglesAwareTestRule(Supplier clientSupplier) {
this.clientSupplier = clientSupplier;
}
@Override
public Statement apply(Statement base, Description description) {
if (shouldRunTest(description)) {
return base;
} else {
return emptyStatement(description.getDisplayName());
}
}
protected boolean shouldRunTest(Description description) {
Optional runIfToggle = getRunIfToggle(description);
Optional skipIfToggle = getSkipIfToggle(description);
if (!runIfToggle.isPresent() && !skipIfToggle.isPresent()) {
return true; // no annotation was applied to the test
}
AtomicReference> enabledToggles = new AtomicReference<>();
try {
new Polling(() -> {
enabledToggles.set(clientSupplier.get().adaptTo(TogglesClient.class).getEnabledToggles());
return true;
}).poll(SECONDS.toMillis(30), SECONDS.toMillis(1));
} catch (TimeoutException e) {
LOG.warn("Failed to retrieve toggles", e);
return true; // if something goes wrong we assume test should run
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return true; // thread was interrupted, we assume test should run
}
if (runIfToggle.filter(s -> !enabledToggles.get().contains(s)).isPresent()) {
return false; // RunIfToggleEnabled condition was not met, skipping
}
return !skipIfToggle.filter(s -> enabledToggles.get().contains(s)).isPresent();
}
private Optional getRunIfToggle(Description description) {
RunIfToggleEnabled annotation = description.getAnnotation(RunIfToggleEnabled.class);
return Optional.ofNullable(annotation).map(RunIfToggleEnabled::value);
}
private Optional getSkipIfToggle(Description description) {
SkipIfToggleEnabled annotation = description.getAnnotation(SkipIfToggleEnabled.class);
return Optional.ofNullable(annotation).map(SkipIfToggleEnabled::value);
}
private Statement emptyStatement(final String testName) {
return new Statement() {
@Override
public void evaluate() {
throw new AssumptionViolatedException("Test " + testName + " was ignored by TogglesAwareTestRule");
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy