KEYCLOAK-1678 generalized invalidation tests, added test for users and clients
This commit is contained in:
parent
fa3c0bb0aa
commit
acf8549d51
7 changed files with 438 additions and 139 deletions
|
@ -2,6 +2,7 @@ package org.keycloak.testsuite.cluster;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.jboss.arquillian.container.test.api.ContainerController;
|
import org.jboss.arquillian.container.test.api.ContainerController;
|
||||||
|
@ -10,6 +11,7 @@ import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.keycloak.admin.client.Keycloak;
|
import org.keycloak.admin.client.Keycloak;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
|
import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
|
||||||
|
@ -38,7 +40,7 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
|
||||||
if (currentFailNodeIndex >= getClusterSize()) {
|
if (currentFailNodeIndex >= getClusterSize()) {
|
||||||
currentFailNodeIndex = 0;
|
currentFailNodeIndex = 0;
|
||||||
}
|
}
|
||||||
logCurrentState();
|
logFailoverSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ContainerInfo getCurrentFailNode() {
|
protected ContainerInfo getCurrentFailNode() {
|
||||||
|
@ -51,7 +53,8 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
|
||||||
return survivors;
|
return survivors;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void logCurrentState() {
|
protected void logFailoverSetup() {
|
||||||
|
log.info("Current failover setup");
|
||||||
boolean started = controller.isStarted(getCurrentFailNode().getQualifier());
|
boolean started = controller.isStarted(getCurrentFailNode().getQualifier());
|
||||||
log.info("Fail node: " + getCurrentFailNode() + (started ? "" : " (stopped)"));
|
log.info("Fail node: " + getCurrentFailNode() + (started ? "" : " (stopped)"));
|
||||||
for (ContainerInfo survivor : getCurrentSurvivorNodes()) {
|
for (ContainerInfo survivor : getCurrentSurvivorNodes()) {
|
||||||
|
@ -72,6 +75,10 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ContainerInfo frontendNode() {
|
||||||
|
return suiteContext.getAuthServerInfo();
|
||||||
|
}
|
||||||
|
|
||||||
protected ContainerInfo backendNode(int i) {
|
protected ContainerInfo backendNode(int i) {
|
||||||
return suiteContext.getAuthServerBackendsInfo().get(i);
|
return suiteContext.getAuthServerBackendsInfo().get(i);
|
||||||
}
|
}
|
||||||
|
@ -101,15 +108,22 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
|
||||||
controller.kill(node.getQualifier());
|
controller.kill(node.getQualifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Keycloak getAdminClientFor(ContainerInfo backendNode) {
|
protected Keycloak getAdminClientFor(ContainerInfo node) {
|
||||||
return backendAdminClients.get(backendNode);
|
return node.equals(suiteContext.getAuthServerInfo())
|
||||||
|
? adminClient // frontend client
|
||||||
|
: backendAdminClients.get(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void beforeClusterTest() {
|
public void beforeClusterTest() {
|
||||||
failback();
|
failback();
|
||||||
logCurrentState();
|
logFailoverSetup();
|
||||||
pause(3000);
|
pause(3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
// no test realms will be created by the default
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
package org.keycloak.testsuite.cluster;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||||
|
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
|
||||||
|
import org.apache.commons.lang.builder.ToStringStyle;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tkyjovsk
|
||||||
|
*/
|
||||||
|
public abstract class AbstractInvalidationClusterTest<T> extends AbstractClusterTest {
|
||||||
|
|
||||||
|
private final SecureRandom random = new SecureRandom();
|
||||||
|
|
||||||
|
protected String randomString(int length) {
|
||||||
|
return new BigInteger(130, random).toString(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RealmRepresentation createTestRealmRepresentation() {
|
||||||
|
RealmRepresentation testRealm = new RealmRepresentation();
|
||||||
|
testRealm.setRealm("test_" + randomString(5));
|
||||||
|
testRealm.setEnabled(true);
|
||||||
|
return testRealm;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T createTestEntityRepresentation();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudWithoutFailover() {
|
||||||
|
crud(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudWithFailover() {
|
||||||
|
crud(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void crud(boolean backendFailover) {
|
||||||
|
T testEntity = createTestEntityRepresentation();
|
||||||
|
|
||||||
|
// CREATE
|
||||||
|
testEntity = createEntityOnCurrentFailNode(testEntity);
|
||||||
|
|
||||||
|
if (backendFailover) {
|
||||||
|
failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEntityOnSurvivorNodesEqualsTo(testEntity);
|
||||||
|
|
||||||
|
failback();
|
||||||
|
iterateCurrentFailNode();
|
||||||
|
|
||||||
|
// UPDATE(s)
|
||||||
|
testEntity = testEntityUpdates(testEntity, backendFailover);
|
||||||
|
|
||||||
|
// DELETE
|
||||||
|
deleteEntityOnCurrentFailNode(testEntity);
|
||||||
|
|
||||||
|
if (backendFailover) {
|
||||||
|
failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEntityOnSurvivorNodesIsDeleted(testEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T createEntity(T testEntity, ContainerInfo node);
|
||||||
|
|
||||||
|
protected abstract T readEntity(T entity, ContainerInfo node);
|
||||||
|
|
||||||
|
protected abstract T updateEntity(T entity, ContainerInfo node);
|
||||||
|
|
||||||
|
protected abstract void deleteEntity(T testEntity, ContainerInfo node);
|
||||||
|
|
||||||
|
protected T createEntityOnCurrentFailNode(T testEntity) {
|
||||||
|
return createEntity(testEntity, getCurrentFailNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T readEntityOnCurrentFailNode(T entity) {
|
||||||
|
return readEntity(entity, getCurrentFailNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T updateEntityOnCurrentFailNode(T entity) {
|
||||||
|
return updateEntity(entity, getCurrentFailNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void deleteEntityOnCurrentFailNode(T testEntity) {
|
||||||
|
deleteEntity(testEntity, getCurrentFailNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T testEntityUpdates(T testEntity, boolean backendFailover);
|
||||||
|
|
||||||
|
protected void verifyEntityUpdateDuringFailover(T testEntity, boolean backendFailover) {
|
||||||
|
if (backendFailover) {
|
||||||
|
failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEntityOnSurvivorNodesEqualsTo(testEntity);
|
||||||
|
|
||||||
|
failback();
|
||||||
|
iterateCurrentFailNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> excludedComparisonFields = new ArrayList<>();
|
||||||
|
|
||||||
|
protected void assertEntityOnSurvivorNodesEqualsTo(T testEntityOnFailNode) {
|
||||||
|
boolean entityDiffers = false;
|
||||||
|
for (ContainerInfo survivorNode : getCurrentSurvivorNodes()) {
|
||||||
|
T testEntityOnSurvivorNode = readEntity(testEntityOnFailNode, survivorNode);
|
||||||
|
if (EqualsBuilder.reflectionEquals(testEntityOnSurvivorNode, testEntityOnFailNode, excludedComparisonFields)) {
|
||||||
|
log.info("Verification on survivor " + survivorNode + " PASSED");
|
||||||
|
} else {
|
||||||
|
entityDiffers = true;
|
||||||
|
log.error("Verification on survivor " + survivorNode + " FAILED");
|
||||||
|
String tf = ReflectionToStringBuilder.reflectionToString(testEntityOnFailNode, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||||
|
String ts = ReflectionToStringBuilder.reflectionToString(testEntityOnSurvivorNode, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||||
|
log.error("\nEntity on fail node: \n\n" + tf + "\n"
|
||||||
|
+ "\nEntity on survivor node: \n" + ts + "\n"
|
||||||
|
+ "\nDifference: \n" + StringUtils.difference(tf, ts) + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertFalse(entityDiffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertEntityOnSurvivorNodesIsDeleted(T testEntityOnFailNode) {
|
||||||
|
// check if deleted from all survivor nodes
|
||||||
|
boolean entityExists = false;
|
||||||
|
for (ContainerInfo survivorNode : getCurrentSurvivorNodes()) {
|
||||||
|
T testEntityOnSurvivorNode = readEntity(testEntityOnFailNode, survivorNode);
|
||||||
|
if (testEntityOnSurvivorNode == null) {
|
||||||
|
log.info("Verification of deletion on survivor " + survivorNode + " PASSED");
|
||||||
|
} else {
|
||||||
|
entityExists = true;
|
||||||
|
log.error("Verification of deletion on survivor " + survivorNode + " FAILED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertFalse(entityExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.keycloak.testsuite.cluster;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tkyjovsk
|
||||||
|
*/
|
||||||
|
public abstract class AbstractInvalidationClusterTestWithTestRealm<T> extends AbstractInvalidationClusterTest<T> {
|
||||||
|
|
||||||
|
protected String testRealmName = null;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createTestRealm() {
|
||||||
|
createTestRealm(frontendNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createTestRealm(ContainerInfo node) {
|
||||||
|
RealmRepresentation r = createTestRealmRepresentation();
|
||||||
|
getAdminClientFor(node).realms().create(r);
|
||||||
|
testRealmName = r.getRealm();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package org.keycloak.testsuite.cluster;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.keycloak.admin.client.resource.ClientsResource;
|
||||||
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tkyjovsk
|
||||||
|
*/
|
||||||
|
public class ClientInvalidationClusterTest extends AbstractInvalidationClusterTestWithTestRealm<ClientRepresentation> {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setExcludedComparisonFields() {
|
||||||
|
excludedComparisonFields.add("protocolMappers");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientRepresentation createTestEntityRepresentation() {
|
||||||
|
ClientRepresentation client = new ClientRepresentation();
|
||||||
|
String s = randomString(5);
|
||||||
|
client.setClientId("client_" + s);
|
||||||
|
client.setName("name_" + s);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ClientsResource clients(ContainerInfo node) {
|
||||||
|
return getAdminClientFor(node).realm(testRealmName).clients();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientRepresentation createEntity(ClientRepresentation client, ContainerInfo node) {
|
||||||
|
Response response = clients(node).create(client);
|
||||||
|
String id = ApiUtil.getCreatedId(response);
|
||||||
|
response.close();
|
||||||
|
client.setId(id);
|
||||||
|
return readEntity(client, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientRepresentation readEntity(ClientRepresentation client, ContainerInfo node) {
|
||||||
|
ClientRepresentation u = null;
|
||||||
|
try {
|
||||||
|
u = clients(node).get(client.getId()).toRepresentation();
|
||||||
|
} catch (NotFoundException nfe) {
|
||||||
|
// exoected when client doesn't exist
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientRepresentation updateEntity(ClientRepresentation client, ContainerInfo node) {
|
||||||
|
clients(node).get(client.getId()).update(client);
|
||||||
|
return readEntity(client, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void deleteEntity(ClientRepresentation client, ContainerInfo node) {
|
||||||
|
clients(node).get(client.getId()).remove();
|
||||||
|
assertNull(readEntity(client, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientRepresentation testEntityUpdates(ClientRepresentation client, boolean backendFailover) {
|
||||||
|
|
||||||
|
// clientId
|
||||||
|
client.setClientId(client.getClientId() + "_updated");
|
||||||
|
client = updateEntity(client, getCurrentFailNode());
|
||||||
|
verifyEntityUpdateDuringFailover(client, backendFailover);
|
||||||
|
|
||||||
|
// name
|
||||||
|
client.setName(client.getName() + "_updated");
|
||||||
|
client = updateEntity(client, getCurrentFailNode());
|
||||||
|
verifyEntityUpdateDuringFailover(client, backendFailover);
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,134 +0,0 @@
|
||||||
package org.keycloak.testsuite.cluster;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
|
||||||
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author tkyjovsk
|
|
||||||
*/
|
|
||||||
public class EntityInvalidationClusterTest extends AbstractClusterTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void createRealmViaFrontend() {
|
|
||||||
String realm = TEST + "_fe";
|
|
||||||
|
|
||||||
RealmRepresentation testRealm = new RealmRepresentation();
|
|
||||||
testRealm.setRealm(realm);
|
|
||||||
testRealm.setEnabled(true);
|
|
||||||
|
|
||||||
// CREATE on frontend
|
|
||||||
adminClient.realms().create(testRealm);
|
|
||||||
|
|
||||||
// check if created on frontend
|
|
||||||
RealmRepresentation testRealmOnFrontend = adminClient.realms().realm(realm).toRepresentation();
|
|
||||||
assertEquals(testRealmOnFrontend.getRealm(), testRealm.getRealm());
|
|
||||||
|
|
||||||
// check if created on backend nodes
|
|
||||||
for (ContainerInfo backend : suiteContext.getAuthServerBackendsInfo()) {
|
|
||||||
RealmRepresentation testRealmOnBackend = getAdminClientFor(backend).realms().realm(realm).toRepresentation();
|
|
||||||
assertEquals(testRealmOnBackend.getId(), testRealmOnFrontend.getId());
|
|
||||||
assertEquals(testRealmOnBackend.getRealm(), testRealmOnFrontend.getRealm());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void realmCRUDWithoutFailover() {
|
|
||||||
realmCRUD(TEST + "_wofo", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void realmCRUDWithFailover() {
|
|
||||||
realmCRUD(TEST + "_wfo", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void realmCRUD(String realmName, boolean backendFailover) {
|
|
||||||
|
|
||||||
// CREATE on current fail node
|
|
||||||
log.info("Creating realm on : " + getCurrentFailNode());
|
|
||||||
RealmRepresentation testRealm = new RealmRepresentation();
|
|
||||||
testRealm.setRealm(realmName);
|
|
||||||
testRealm.setEnabled(true);
|
|
||||||
getAdminClientFor(getCurrentFailNode()).realms().create(testRealm);
|
|
||||||
|
|
||||||
// check if created on fail node
|
|
||||||
RealmRepresentation testRealmOnFailNode = getAdminClientFor(getCurrentFailNode()).realms().realm(realmName).toRepresentation();
|
|
||||||
assertEquals(testRealmOnFailNode.getRealm(), testRealm.getRealm());
|
|
||||||
|
|
||||||
if (backendFailover) {
|
|
||||||
failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if created on survivor nodes
|
|
||||||
for (ContainerInfo survivorNode : getCurrentSurvivorNodes()) {
|
|
||||||
RealmRepresentation testRealmOnSurvivorNode = getAdminClientFor(survivorNode).realms().realm(realmName).toRepresentation();
|
|
||||||
assertEquals(testRealmOnFailNode.getId(), testRealmOnSurvivorNode.getId());
|
|
||||||
assertEquals(testRealmOnFailNode.getRealm(), testRealmOnSurvivorNode.getRealm());
|
|
||||||
log.info("Creation on survivor: " + survivorNode + " verified");
|
|
||||||
}
|
|
||||||
|
|
||||||
failback();
|
|
||||||
iterateCurrentFailNode();
|
|
||||||
|
|
||||||
// UPDATE on current fail node
|
|
||||||
log.info("Updating realm on: " + getCurrentFailNode());
|
|
||||||
String realmBeforeUpdate = realmName;
|
|
||||||
realmName += "_updated";
|
|
||||||
testRealm = testRealmOnFailNode;
|
|
||||||
testRealm.setRealm(realmName);
|
|
||||||
getAdminClientFor(getCurrentFailNode()).realms().realm(realmBeforeUpdate).update(testRealm);
|
|
||||||
|
|
||||||
// check if updated on fail node
|
|
||||||
testRealmOnFailNode = getAdminClientFor(getCurrentFailNode()).realms().realm(realmName).toRepresentation();
|
|
||||||
assertEquals(testRealmOnFailNode.getRealm(), testRealm.getRealm());
|
|
||||||
|
|
||||||
if (backendFailover) {
|
|
||||||
failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if updated on survivor nodes
|
|
||||||
for (ContainerInfo survivorNode : getCurrentSurvivorNodes()) {
|
|
||||||
RealmRepresentation testRealmOnSurvivorNode = getAdminClientFor(survivorNode).realms().realm(realmName).toRepresentation();
|
|
||||||
assertEquals(testRealmOnFailNode.getId(), testRealmOnSurvivorNode.getId());
|
|
||||||
assertEquals(testRealmOnFailNode.getRealm(), testRealmOnSurvivorNode.getRealm());
|
|
||||||
log.info("Update on survivor: " + survivorNode + " verified");
|
|
||||||
}
|
|
||||||
|
|
||||||
failback();
|
|
||||||
iterateCurrentFailNode();
|
|
||||||
|
|
||||||
// DELETE on current fail node
|
|
||||||
log.info("Deleting realm on: " + getCurrentFailNode());
|
|
||||||
getAdminClientFor(getCurrentFailNode()).realms().realm(realmName).remove();
|
|
||||||
|
|
||||||
if (backendFailover) {
|
|
||||||
failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if deleted from all survivor nodes
|
|
||||||
boolean realmStillExists = false;
|
|
||||||
for (ContainerInfo survivorNode : getCurrentSurvivorNodes()) {
|
|
||||||
boolean realmStillExistsOnSurvivor = false;
|
|
||||||
for (RealmRepresentation realmOnSurvivorNode : getAdminClientFor(survivorNode).realms().findAll()) {
|
|
||||||
if (realmName.equals(realmOnSurvivorNode.getRealm())
|
|
||||||
|| testRealmOnFailNode.getId().equals(realmOnSurvivorNode.getId())) {
|
|
||||||
realmStillExistsOnSurvivor = true;
|
|
||||||
realmStillExists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.error("Deletion on survivor: " + survivorNode + (realmStillExistsOnSurvivor ? " FAILED" : " verified"));
|
|
||||||
}
|
|
||||||
assertFalse(realmStillExists);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package org.keycloak.testsuite.cluster;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tkyjovsk
|
||||||
|
*/
|
||||||
|
public class RealmInvalidationClusterTest extends AbstractInvalidationClusterTest<RealmRepresentation> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RealmRepresentation createTestEntityRepresentation() {
|
||||||
|
return createTestRealmRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RealmRepresentation createEntity(RealmRepresentation realm, ContainerInfo node) {
|
||||||
|
log.info("Creating realm on : " + getCurrentFailNode());
|
||||||
|
getAdminClientFor(getCurrentFailNode()).realms().create(realm);
|
||||||
|
// get created entity
|
||||||
|
return readEntity(realm, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RealmRepresentation readEntity(RealmRepresentation realm, ContainerInfo node) {
|
||||||
|
RealmRepresentation realmOnNode = null;
|
||||||
|
try {
|
||||||
|
realmOnNode = getAdminClientFor(node).realm(realm.getRealm()).toRepresentation();
|
||||||
|
} catch (NotFoundException nfe) {
|
||||||
|
// expected if realm not found
|
||||||
|
}
|
||||||
|
return realmOnNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RealmRepresentation updateEntity(RealmRepresentation realm, ContainerInfo node) {
|
||||||
|
getAdminClientFor(node).realms().realm(realm.getRealm()).update(realm);
|
||||||
|
return readEntity(realm, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void deleteEntity(RealmRepresentation realm, ContainerInfo node) {
|
||||||
|
log.info("Deleting realm on: " + getCurrentFailNode());
|
||||||
|
getAdminClientFor(node).realms().realm(realm.getRealm()).remove();
|
||||||
|
// check if deleted
|
||||||
|
assertNull(readEntity(realm, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RealmRepresentation testEntityUpdates(RealmRepresentation realm, boolean backendFailover) {
|
||||||
|
|
||||||
|
realm = updateRealmName(realm, realm.getRealm() + "_updated");
|
||||||
|
verifyEntityUpdateDuringFailover(realm, backendFailover);
|
||||||
|
|
||||||
|
realm = updateRealmEnabled(realm);
|
||||||
|
verifyEntityUpdateDuringFailover(realm, backendFailover);
|
||||||
|
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RealmRepresentation updateRealmName(RealmRepresentation realm, String newName) {
|
||||||
|
log.info("Updating realm on: " + getCurrentFailNode());
|
||||||
|
String originalName = realm.getRealm();
|
||||||
|
realm.setRealm(newName);
|
||||||
|
|
||||||
|
getAdminClientFor(getCurrentFailNode()).realms().realm(originalName).update(realm);
|
||||||
|
return readEntity(realm, getCurrentFailNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RealmRepresentation updateRealmEnabled(RealmRepresentation realm) {
|
||||||
|
log.info("Updating realm on: " + getCurrentFailNode());
|
||||||
|
realm.setEnabled(!realm.isEnabled());
|
||||||
|
return updateEntity(realm, getCurrentFailNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package org.keycloak.testsuite.cluster;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import org.keycloak.admin.client.resource.UsersResource;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tkyjovsk
|
||||||
|
*/
|
||||||
|
public class UserInvalidationClusterTest extends AbstractInvalidationClusterTestWithTestRealm<UserRepresentation> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UserRepresentation createTestEntityRepresentation() {
|
||||||
|
String firstName = "user";
|
||||||
|
String lastName = randomString(5);
|
||||||
|
UserRepresentation user = new UserRepresentation();
|
||||||
|
user.setUsername(firstName + "_" + lastName);
|
||||||
|
user.setEmail(user.getUsername() + "@email.test");
|
||||||
|
user.setFirstName(firstName);
|
||||||
|
user.setLastName(lastName);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UsersResource users(ContainerInfo node) {
|
||||||
|
return getAdminClientFor(node).realm(testRealmName).users();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UserRepresentation createEntity(UserRepresentation user, ContainerInfo node) {
|
||||||
|
Response response = users(node).create(user);
|
||||||
|
String id = ApiUtil.getCreatedId(response);
|
||||||
|
response.close();
|
||||||
|
user.setId(id);
|
||||||
|
return readEntity(user, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UserRepresentation readEntity(UserRepresentation user, ContainerInfo node) {
|
||||||
|
UserRepresentation u = null;
|
||||||
|
try {
|
||||||
|
u = users(node).get(user.getId()).toRepresentation();
|
||||||
|
} catch (NotFoundException nfe) {
|
||||||
|
// exoected when user doesn't exist
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UserRepresentation updateEntity(UserRepresentation user, ContainerInfo node) {
|
||||||
|
users(node).get(user.getId()).update(user);
|
||||||
|
return readEntity(user, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void deleteEntity(UserRepresentation user, ContainerInfo node) {
|
||||||
|
users(node).get(user.getId()).remove();
|
||||||
|
assertNull(readEntity(user, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UserRepresentation testEntityUpdates(UserRepresentation user, boolean backendFailover) {
|
||||||
|
|
||||||
|
// username
|
||||||
|
user.setUsername(user.getUsername() + "_updated");
|
||||||
|
user = updateEntity(user, getCurrentFailNode());
|
||||||
|
verifyEntityUpdateDuringFailover(user, backendFailover);
|
||||||
|
|
||||||
|
// first+lastName
|
||||||
|
user.setFirstName(user.getFirstName() + "_updated");
|
||||||
|
user.setLastName(user.getLastName() + "_updated");
|
||||||
|
user = updateEntity(user, getCurrentFailNode());
|
||||||
|
verifyEntityUpdateDuringFailover(user, backendFailover);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue