[KEYCLOAK-13572] Doesn't observe After events due to assume check

This commit is contained in:
Martin Bartos 2020-03-27 10:04:23 +01:00 committed by Marek Posolda
parent 66c7ec6b08
commit 7ebdca48d3
7 changed files with 78 additions and 17 deletions

View file

@ -18,7 +18,26 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Repeatable(DisableFeatures.class)
@Inherited
public @interface DisableFeature {
/**
* Feature, which should be disabled.
*/
Profile.Feature value();
/**
* The feature will be disabled without restarting of a server.
*/
boolean skipRestart() default false;
/**
* The feature will be disabled only if the `product` profile is activated
*/
boolean onlyForProduct() default false;
/**
* Feature disable should be the last action in @Before context.
* If the test halted, the feature is returned to the previous state.
* If it's false, feature will be disabled before @Before method.
*/
boolean executeAsLast() default true;
}

View file

@ -18,7 +18,26 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Repeatable(EnableFeatures.class)
@Inherited
public @interface EnableFeature {
/**
* Feature, which should be enabled.
*/
Profile.Feature value();
/**
* The feature will be enabled without restarting of a server.
*/
boolean skipRestart() default false;
/**
* The feature will be enabled only if the `product` profile is activated
*/
boolean onlyForProduct() default false;
/**
* Feature enable should be the last action in @Before context.
* If the test halted, the feature is returned to the previous state.
* If it's false, feature will be enabled before @Before method.
*/
boolean executeAsLast() default true;
}

View file

@ -144,14 +144,14 @@ public class KeycloakContainerFeaturesController {
private void checkAnnotatedElementForFeatureAnnotations(AnnotatedElement annotatedElement, State state) throws Exception {
List<UpdateFeature> updateFeatureList = new ArrayList<>(0);
if (annotatedElement.isAnnotationPresent(EnableFeatures.class) || annotatedElement.isAnnotationPresent(EnableFeature.class)) {
if (isEnableFeature(annotatedElement)) {
updateFeatureList.addAll(Arrays.stream(annotatedElement.getAnnotationsByType(EnableFeature.class))
.map(annotation -> new UpdateFeature(annotation.value(), annotation.skipRestart(),
state == State.BEFORE ? FeatureAction.ENABLE : FeatureAction.DISABLE, annotation.onlyForProduct()))
.collect(Collectors.toList()));
}
if (annotatedElement.isAnnotationPresent(DisableFeatures.class) || annotatedElement.isAnnotationPresent(DisableFeature.class)) {
if (isDisableFeature(annotatedElement)) {
updateFeatureList.addAll(Arrays.stream(annotatedElement.getAnnotationsByType(DisableFeature.class))
.map(annotation -> new UpdateFeature(annotation.value(), annotation.skipRestart(),
state == State.BEFORE ? FeatureAction.DISABLE : FeatureAction.ENABLE, annotation.onlyForProduct()))
@ -163,12 +163,44 @@ public class KeycloakContainerFeaturesController {
}
}
private boolean isEnableFeature(AnnotatedElement annotatedElement) {
return (annotatedElement.isAnnotationPresent(EnableFeatures.class) || annotatedElement.isAnnotationPresent(EnableFeature.class));
}
private boolean isDisableFeature(AnnotatedElement annotatedElement) {
return (annotatedElement.isAnnotationPresent(DisableFeatures.class) || annotatedElement.isAnnotationPresent(DisableFeature.class));
}
private boolean shouldExecuteAsLast(AnnotatedElement annotatedElement) {
if (isEnableFeature(annotatedElement)) {
return Arrays.stream(annotatedElement.getAnnotationsByType(EnableFeature.class))
.anyMatch(EnableFeature::executeAsLast);
}
if (isDisableFeature(annotatedElement)) {
return Arrays.stream(annotatedElement.getAnnotationsByType(DisableFeature.class))
.anyMatch(DisableFeature::executeAsLast);
}
return false;
}
public void handleEnableFeaturesAnnotationBeforeClass(@Observes(precedence = 1) BeforeClass event) throws Exception {
checkAnnotatedElementForFeatureAnnotations(event.getTestClass().getJavaClass(), State.BEFORE);
}
public void handleEnableFeaturesAnnotationBeforeTest(@Observes(precedence = 1) Before event) throws Exception {
checkAnnotatedElementForFeatureAnnotations(event.getTestMethod(), State.BEFORE);
if (!shouldExecuteAsLast(event.getTestMethod())) {
checkAnnotatedElementForFeatureAnnotations(event.getTestMethod(), State.BEFORE);
}
}
// KEYCLOAK-13572 Precedence is too low in order to ensure the feature change will be executed as last.
// If some fail occurs in @Before method, the feature doesn't change its state.
public void handleChangeStateFeaturePriorityBeforeTest(@Observes(precedence = -100) Before event) throws Exception {
if (shouldExecuteAsLast(event.getTestMethod())) {
checkAnnotatedElementForFeatureAnnotations(event.getTestMethod(), State.BEFORE);
}
}
public void handleEnableFeaturesAnnotationAfterTest(@Observes(precedence = 2) After event) throws Exception {

View file

@ -131,7 +131,7 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
}
@Test
@EnableFeature(value = Profile.Feature.UPLOAD_SCRIPTS) // This requires also SCRIPTS feature, therefore we need to restart container
@EnableFeature(value = Profile.Feature.UPLOAD_SCRIPTS, skipRestart = true) // This requires also SCRIPTS feature, therefore we need to restart container
public void testTokenScriptMapping() {
{
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");

View file

@ -18,7 +18,6 @@ package org.keycloak.testsuite.script;
import static org.junit.Assert.assertFalse;
import static org.keycloak.common.Profile.Feature.SCRIPTS;
import static org.keycloak.common.Profile.Feature.UPLOAD_SCRIPTS;
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
import java.io.IOException;
@ -35,7 +34,6 @@ import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
@ -51,7 +49,6 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.provider.ScriptProviderDescriptor;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.forms.AbstractFlowTest;
@ -66,7 +63,7 @@ import org.keycloak.util.JsonSerialization;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(SCRIPTS)
@EnableFeature(value = SCRIPTS, skipRestart = true)
public class DeployedScriptAuthenticatorTest extends AbstractFlowTest {
public static final String EXECUTION_ID = "scriptAuth";
@ -210,7 +207,7 @@ public class DeployedScriptAuthenticatorTest extends AbstractFlowTest {
}
@Test
@DisableFeature(SCRIPTS)
@DisableFeature(value = SCRIPTS, executeAsLast = false, skipRestart = true)
public void testScriptAuthenticatorNotAvailable() {
assertFalse(testRealm().flows().getAuthenticatorProviders().stream().anyMatch(
provider -> ScriptBasedAuthenticatorFactory.PROVIDER_ID.equals(provider.get("id"))));

View file

@ -102,7 +102,7 @@ public class DeployedScriptMapperTest extends AbstractTestRealmKeycloakTest {
}
@Test
@EnableFeature(SCRIPTS)
@EnableFeature(value = SCRIPTS, skipRestart = true, executeAsLast = false)
public void testTokenScriptMapping() {
{
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");

View file

@ -16,8 +16,6 @@
*/
package org.keycloak.testsuite.script;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.keycloak.common.Profile.Feature.SCRIPTS;
import static org.keycloak.testsuite.admin.ApiUtil.findClientResourceByClientId;
@ -38,16 +36,12 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.mappers.ScriptBasedOIDCProtocolMapper;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.provider.ScriptProviderDescriptor;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.util.ContainerAssume;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.util.JsonSerialization;
/**
@ -94,7 +88,7 @@ public class UndeployedScriptMapperNotAvailableTest extends AbstractTestRealmKey
}
@Test
@EnableFeature(SCRIPTS)
@EnableFeature(value = SCRIPTS, skipRestart = true, executeAsLast = false)
public void testMapperNotRecognizedWhenDisabled() throws Exception {
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");