[KEYCLOAK-13572] Doesn't observe After events due to assume check
This commit is contained in:
parent
66c7ec6b08
commit
7ebdca48d3
7 changed files with 78 additions and 17 deletions
|
@ -18,7 +18,26 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
@Repeatable(DisableFeatures.class)
|
@Repeatable(DisableFeatures.class)
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface DisableFeature {
|
public @interface DisableFeature {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature, which should be disabled.
|
||||||
|
*/
|
||||||
Profile.Feature value();
|
Profile.Feature value();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The feature will be disabled without restarting of a server.
|
||||||
|
*/
|
||||||
boolean skipRestart() default false;
|
boolean skipRestart() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The feature will be disabled only if the `product` profile is activated
|
||||||
|
*/
|
||||||
boolean onlyForProduct() default false;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,26 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
@Repeatable(EnableFeatures.class)
|
@Repeatable(EnableFeatures.class)
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface EnableFeature {
|
public @interface EnableFeature {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feature, which should be enabled.
|
||||||
|
*/
|
||||||
Profile.Feature value();
|
Profile.Feature value();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The feature will be enabled without restarting of a server.
|
||||||
|
*/
|
||||||
boolean skipRestart() default false;
|
boolean skipRestart() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The feature will be enabled only if the `product` profile is activated
|
||||||
|
*/
|
||||||
boolean onlyForProduct() default false;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,14 +144,14 @@ public class KeycloakContainerFeaturesController {
|
||||||
private void checkAnnotatedElementForFeatureAnnotations(AnnotatedElement annotatedElement, State state) throws Exception {
|
private void checkAnnotatedElementForFeatureAnnotations(AnnotatedElement annotatedElement, State state) throws Exception {
|
||||||
List<UpdateFeature> updateFeatureList = new ArrayList<>(0);
|
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))
|
updateFeatureList.addAll(Arrays.stream(annotatedElement.getAnnotationsByType(EnableFeature.class))
|
||||||
.map(annotation -> new UpdateFeature(annotation.value(), annotation.skipRestart(),
|
.map(annotation -> new UpdateFeature(annotation.value(), annotation.skipRestart(),
|
||||||
state == State.BEFORE ? FeatureAction.ENABLE : FeatureAction.DISABLE, annotation.onlyForProduct()))
|
state == State.BEFORE ? FeatureAction.ENABLE : FeatureAction.DISABLE, annotation.onlyForProduct()))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (annotatedElement.isAnnotationPresent(DisableFeatures.class) || annotatedElement.isAnnotationPresent(DisableFeature.class)) {
|
if (isDisableFeature(annotatedElement)) {
|
||||||
updateFeatureList.addAll(Arrays.stream(annotatedElement.getAnnotationsByType(DisableFeature.class))
|
updateFeatureList.addAll(Arrays.stream(annotatedElement.getAnnotationsByType(DisableFeature.class))
|
||||||
.map(annotation -> new UpdateFeature(annotation.value(), annotation.skipRestart(),
|
.map(annotation -> new UpdateFeature(annotation.value(), annotation.skipRestart(),
|
||||||
state == State.BEFORE ? FeatureAction.DISABLE : FeatureAction.ENABLE, annotation.onlyForProduct()))
|
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 {
|
public void handleEnableFeaturesAnnotationBeforeClass(@Observes(precedence = 1) BeforeClass event) throws Exception {
|
||||||
checkAnnotatedElementForFeatureAnnotations(event.getTestClass().getJavaClass(), State.BEFORE);
|
checkAnnotatedElementForFeatureAnnotations(event.getTestClass().getJavaClass(), State.BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleEnableFeaturesAnnotationBeforeTest(@Observes(precedence = 1) Before event) throws Exception {
|
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 {
|
public void handleEnableFeaturesAnnotationAfterTest(@Observes(precedence = 2) After event) throws Exception {
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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() {
|
public void testTokenScriptMapping() {
|
||||||
{
|
{
|
||||||
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.keycloak.testsuite.script;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.keycloak.common.Profile.Feature.SCRIPTS;
|
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 static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -35,7 +34,6 @@ import org.jboss.shrinkwrap.api.asset.StringAsset;
|
||||||
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -51,7 +49,6 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.representations.provider.ScriptProviderDescriptor;
|
import org.keycloak.representations.provider.ScriptProviderDescriptor;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.ProfileAssume;
|
|
||||||
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
||||||
import org.keycloak.testsuite.forms.AbstractFlowTest;
|
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>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
@EnableFeature(SCRIPTS)
|
@EnableFeature(value = SCRIPTS, skipRestart = true)
|
||||||
public class DeployedScriptAuthenticatorTest extends AbstractFlowTest {
|
public class DeployedScriptAuthenticatorTest extends AbstractFlowTest {
|
||||||
|
|
||||||
public static final String EXECUTION_ID = "scriptAuth";
|
public static final String EXECUTION_ID = "scriptAuth";
|
||||||
|
@ -210,7 +207,7 @@ public class DeployedScriptAuthenticatorTest extends AbstractFlowTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisableFeature(SCRIPTS)
|
@DisableFeature(value = SCRIPTS, executeAsLast = false, skipRestart = true)
|
||||||
public void testScriptAuthenticatorNotAvailable() {
|
public void testScriptAuthenticatorNotAvailable() {
|
||||||
assertFalse(testRealm().flows().getAuthenticatorProviders().stream().anyMatch(
|
assertFalse(testRealm().flows().getAuthenticatorProviders().stream().anyMatch(
|
||||||
provider -> ScriptBasedAuthenticatorFactory.PROVIDER_ID.equals(provider.get("id"))));
|
provider -> ScriptBasedAuthenticatorFactory.PROVIDER_ID.equals(provider.get("id"))));
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class DeployedScriptMapperTest extends AbstractTestRealmKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFeature(SCRIPTS)
|
@EnableFeature(value = SCRIPTS, skipRestart = true, executeAsLast = false)
|
||||||
public void testTokenScriptMapping() {
|
public void testTokenScriptMapping() {
|
||||||
{
|
{
|
||||||
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.script;
|
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.junit.Assert.assertTrue;
|
||||||
import static org.keycloak.common.Profile.Feature.SCRIPTS;
|
import static org.keycloak.common.Profile.Feature.SCRIPTS;
|
||||||
import static org.keycloak.testsuite.admin.ApiUtil.findClientResourceByClientId;
|
import static org.keycloak.testsuite.admin.ApiUtil.findClientResourceByClientId;
|
||||||
|
@ -38,16 +36,12 @@ import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.admin.client.resource.ClientResource;
|
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.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.provider.ScriptProviderDescriptor;
|
import org.keycloak.representations.provider.ScriptProviderDescriptor;
|
||||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
||||||
import org.keycloak.testsuite.util.ContainerAssume;
|
import org.keycloak.testsuite.util.ContainerAssume;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +88,7 @@ public class UndeployedScriptMapperNotAvailableTest extends AbstractTestRealmKey
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFeature(SCRIPTS)
|
@EnableFeature(value = SCRIPTS, skipRestart = true, executeAsLast = false)
|
||||||
public void testMapperNotRecognizedWhenDisabled() throws Exception {
|
public void testMapperNotRecognizedWhenDisabled() throws Exception {
|
||||||
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue