[Test Migration] New testsuites: Clusterless, Multisite, VolatileSessions, migrated test: SessionTest

Closes #35391
Closes #35393
Closes #42619

Signed-off-by: Lukas Hanusovsky <lhanusov@redhat.com>
This commit is contained in:
Lukas Hanusovsky 2025-10-03 19:23:15 +02:00 committed by GitHub
parent 3de1613251
commit 64ffb3a83f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 176 additions and 143 deletions

View File

@ -379,6 +379,10 @@ jobs:
echo "Tests: $TESTS"
./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus "-Dwebdriver.chrome.driver=$CHROMEWEBDRIVER/chromedriver" -Dauth.server.feature.disable=persistent-user-sessions -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh
- name: Run new base tests
run: |
./mvnw package -f tests/pom.xml -Dtest=VolatileSessionsTestSuite
- uses: ./.github/actions/upload-flaky-tests
name: Upload flaky tests
env:
@ -394,7 +398,7 @@ jobs:
timeout-minutes: 150
strategy:
matrix:
variant: [ "clusterless,multi-site" ]
variant: [clusterless, multi-site]
fail-fast: false
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@ -409,6 +413,11 @@ jobs:
echo "Tests: $TESTS"
./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus -Pinfinispan-server -Dauth.server.feature=${{ matrix.variant }} -Dauth.server.feature.disable=persistent-user-sessions -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh
- name: Run new base tests without cache
run: |
CLASS_NAME=$(echo ${{ matrix.variant }} | sed 's/\([[:alpha:]]\)/\U\1/' | sed 's/-//')TestSuite
./mvnw package -f tests/pom.xml -Dtest=$CLASS_NAME
- uses: ./.github/actions/upload-flaky-tests
name: Upload flaky tests
env:

View File

@ -226,6 +226,11 @@ public class RealmConfigBuilder {
return this;
}
public RealmConfigBuilder setRememberMe(boolean enabled) {
rep.setRememberMe(enabled);
return this;
}
/**
* Best practice is to use other convenience methods when configuring a realm, but while the framework is under
* active development there may not be a way to perform all updates required. In these cases this method allows

View File

@ -211,11 +211,7 @@ public class KeycloakServerConfigBuilder {
List<String> args = new LinkedList<>();
args.add(command);
for (Map.Entry<String, String> e : options.entrySet()) {
if (e.getKey().startsWith("-D")) {
args.add(e.getKey() + "=" + e.getValue());
} else {
args.add("--" + e.getKey() + "=" + e.getValue());
}
args.add("--" + e.getKey() + "=" + e.getValue());
}
if (!features.isEmpty()) {
args.add("--features=" + String.join(",", features));

View File

@ -1,7 +1,6 @@
package org.keycloak.testframework.ui.page;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -17,6 +16,9 @@ public class LoginPage extends AbstractPage {
@FindBy(css = "[type=submit]")
private WebElement submitButton;
@FindBy(id = "rememberMe")
private WebElement rememberMe;
public LoginPage(WebDriver driver) {
super(driver);
}
@ -40,6 +42,17 @@ public class LoginPage extends AbstractPage {
return driver.findElement(By.id(id));
}
public void rememberMe(boolean value) {
boolean selected = isRememberMe();
if ((value && !selected) || !value && selected) {
rememberMe.click();
}
}
public boolean isRememberMe() {
return rememberMe.isSelected();
}
@Override
public String getExpectedPageId() {
return "login-login";

View File

@ -0,0 +1,140 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* 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 org.keycloak.tests.admin.client;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
import org.keycloak.testframework.annotations.InjectRealm;
import org.keycloak.testframework.annotations.InjectUser;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.oauth.OAuthClient;
import org.keycloak.testframework.oauth.annotations.InjectOAuthClient;
import org.keycloak.testframework.realm.ManagedRealm;
import org.keycloak.testframework.realm.ManagedUser;
import org.keycloak.testframework.realm.UserConfig;
import org.keycloak.testframework.realm.UserConfigBuilder;
import org.keycloak.testframework.ui.annotations.InjectPage;
import org.keycloak.testframework.ui.page.LoginPage;
import org.keycloak.tests.utils.admin.ApiUtil;
import org.keycloak.testsuite.util.AccountHelper;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
@KeycloakIntegrationTest
public class SessionTest {
@InjectRealm
ManagedRealm managedRealm;
@InjectUser(config = SessionTestUserConfig.class)
ManagedUser user;
@InjectOAuthClient
OAuthClient oauth;
@InjectPage
LoginPage loginPage;
@Test
public void testGetAppSessionCount() {
ClientResource accountClient = ApiUtil.findClientByClientId(managedRealm.admin(), "test-app");
int sessionCount = accountClient.getApplicationSessionCount().get("count");
assertEquals(0, sessionCount);
oauth.openLoginForm();
loginPage.fillLogin(user.getUsername(), user.getPassword());
loginPage.submit();
sessionCount = accountClient.getApplicationSessionCount().get("count");
assertEquals(1, sessionCount);
AccountHelper.logout(managedRealm.admin(), user.getUsername());
sessionCount = accountClient.getApplicationSessionCount().get("count");
assertEquals(0, sessionCount);
}
@Test
public void testGetUserSessions() {
ClientResource account = ApiUtil.findClientByClientId(managedRealm.admin(), "test-app");
oauth.openLoginForm();
loginPage.fillLogin(user.getUsername(), user.getPassword());
loginPage.submit();
List<UserSessionRepresentation> sessions = account.getUserSessions(0, 5);
assertEquals(1, sessions.size());
UserSessionRepresentation rep = sessions.get(0);
UserRepresentation testUserRep = user.admin().toRepresentation();
assertEquals(testUserRep.getId(), rep.getUserId());
assertEquals(testUserRep.getUsername(), rep.getUsername());
String clientId = account.toRepresentation().getId();
assertEquals("test-app", rep.getClients().get(clientId));
assertNotNull(rep.getIpAddress());
assertTrue(rep.getLastAccess() > 0);
assertTrue(rep.getStart() > 0);
assertFalse(rep.isRememberMe());
AccountHelper.logout(managedRealm.admin(), user.getUsername());
}
@Test
public void testGetUserSessionsWithRememberMe() {
managedRealm.updateWithCleanup(r -> r.setRememberMe(true));
oauth.openLoginForm();
loginPage.rememberMe(true);
loginPage.fillLogin(user.getUsername(), user.getPassword());
loginPage.submit();
ClientResource account = ApiUtil.findClientByClientId(managedRealm.admin(), "test-app");
List<UserSessionRepresentation> sessions = account.getUserSessions(0, 5);
assertEquals(1, sessions.size());
UserSessionRepresentation rep = sessions.get(0);
assertTrue(rep.isRememberMe());
AccountHelper.logout(managedRealm.admin(), user.getUsername());
}
private static class SessionTestUserConfig implements UserConfig {
@Override
public UserConfigBuilder configure(UserConfigBuilder config) {
return config.username("user")
.password("password")
.name("Session", "User")
.email("session@user.com")
.emailVerified(true);
}
}
}

View File

@ -8,10 +8,10 @@ import org.keycloak.common.Profile;
import org.keycloak.testframework.injection.SuiteSupport;
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
import org.keycloak.tests.admin.ClientTest;
import org.keycloak.tests.admin.client.SessionTest;
@Suite
@SelectClasses({ClientTest.class})
@SelectClasses({SessionTest.class})
public class ClusterlessTestSuite {
@BeforeSuite

View File

@ -8,10 +8,10 @@ import org.keycloak.common.Profile;
import org.keycloak.testframework.injection.SuiteSupport;
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
import org.keycloak.tests.admin.ClientTest;
import org.keycloak.tests.admin.client.SessionTest;
@Suite
@SelectClasses({ClientTest.class})
@SelectClasses({SessionTest.class})
public class MultisiteTestSuite {
@BeforeSuite

View File

@ -8,10 +8,10 @@ import org.keycloak.common.Profile;
import org.keycloak.testframework.injection.SuiteSupport;
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
import org.keycloak.tests.admin.ClientTest;
import org.keycloak.tests.admin.client.SessionTest;
@Suite
@SelectClasses(ClientTest.class)
@SelectClasses({SessionTest.class})
public class VolatileSessionsTestSuite {
@BeforeSuite

View File

@ -1,128 +0,0 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* 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 org.keycloak.testsuite.admin.client;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
import org.keycloak.testsuite.AbstractClientTest;
import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.AdminEventPaths;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
/**
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class SessionTest extends AbstractClientTest {
@Before
public void init() {
// make user test user exists in test realm
createTestUserWithAdminClient();
getCleanup().addUserId(testUser.getId());
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.userResourcePath(testUser.getId()), ResourceType.USER);
assertAdminEvents.assertEvent(getRealmId(), OperationType.ACTION, AdminEventPaths.userResetPasswordPath(testUser.getId()), ResourceType.USER);
createAppClientInRealm(testRealmResource().toRepresentation().getRealm());
}
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
loginPage.setAuthRealm(TEST);
}
@Test
public void testGetAppSessionCount() {
ClientResource accountClient = findClientResourceById("test-app");
int sessionCount = accountClient.getApplicationSessionCount().get("count");
assertEquals(0, sessionCount);
oauth.openLoginForm();
loginPage.form().login(testUser);
sessionCount = accountClient.getApplicationSessionCount().get("count");
assertEquals(1, sessionCount);
AccountHelper.logout(testRealmResource(), testUser.getUsername());
sessionCount = accountClient.getApplicationSessionCount().get("count");
assertEquals(0, sessionCount);
}
@Test
public void testGetUserSessions() {
//List<java.util.Map<String, String>> stats = this.testRealmResource().getClientSessionStats();
ClientResource account = findClientResourceById("test-app");
oauth.openLoginForm();
loginPage.form().login(testUser);
List<UserSessionRepresentation> sessions = account.getUserSessions(0, 5);
assertEquals(1, sessions.size());
UserSessionRepresentation rep = sessions.get(0);
UserRepresentation testUserRep = getFullUserRep(testUser.getUsername());
assertEquals(testUserRep.getId(), rep.getUserId());
assertEquals(testUserRep.getUsername(), rep.getUsername());
String clientId = account.toRepresentation().getId();
assertEquals("test-app", rep.getClients().get(clientId));
assertNotNull(rep.getIpAddress());
assertNotNull(rep.getLastAccess());
assertNotNull(rep.getStart());
assertFalse(rep.isRememberMe());
AccountHelper.logout(testRealmResource(), testUser.getUsername());
}
@Test
public void testGetUserSessionsWithRememberMe() {
RealmRepresentation realm = adminClient.realm(TEST).toRepresentation();
realm.setRememberMe(true);
adminClient.realm(TEST).update(realm);
oauth.openLoginForm();
loginPage.form().rememberMe(true);
loginPage.form().login(testUser);
ClientResource account = findClientResourceById("test-app");
List<UserSessionRepresentation> sessions = account.getUserSessions(0, 5);
assertEquals(1, sessions.size());
UserSessionRepresentation rep = sessions.get(0);
assertTrue(rep.isRememberMe());
AccountHelper.logout(testRealmResource(), testUser.getUsername());
}
}

View File

@ -1,4 +1,3 @@
SessionTest
KcSamlBrokerSessionNotOnOrAfterTest
OidcClaimToUserSessionNoteMapperTest
KcOidcBrokerTransientSessionsTest

View File

@ -1,4 +1,3 @@
SessionTest
KcSamlBrokerSessionNotOnOrAfterTest
OidcClaimToUserSessionNoteMapperTest
KcOidcBrokerTransientSessionsTest