Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@miquelsi
Copy link
Contributor

@miquelsi miquelsi commented Jul 5, 2024

Closes #30616

Copy link

@keycloak-github-bot keycloak-github-bot bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreported flaky test detected, please review

@keycloak-github-bot
Copy link

Unreported flaky test detected

If the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR.

org.keycloak.testsuite.federation.ldap.LDAPReadOnlyTest#testReadOnlyUserGetsPermanentlyLocked

Keycloak CI - Base IT (5)

java.lang.AssertionError
	at org.junit.Assert.fail(Assert.java:87)
	at org.junit.Assert.assertTrue(Assert.java:42)
	at org.junit.Assert.assertFalse(Assert.java:65)
	at org.junit.Assert.assertFalse(Assert.java:75)
...

Report flaky test

@Override
public InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> getValue(Registry registry, KeycloakIntegrationTest annotation) {
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
DatabaseConfig databaseConfig = annotation.dbconfig() != null ? SupplierHelpers.getInstance(annotation.dbconfig()) : new DefaultDatabaseConfig();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be left like this because the dbconfig() returns the default value (DefaultDatabaseConfig.class) if it is not entered.

Suggested change
DatabaseConfig databaseConfig = annotation.dbconfig() != null ? SupplierHelpers.getInstance(annotation.dbconfig()) : new DefaultDatabaseConfig();
DatabaseConfig databaseConfig = SupplierHelpers.getInstance(annotation.dbconfig());

@miquelsi miquelsi force-pushed the main_db branch 2 times, most recently from 9ca00b2 to 93f632e Compare July 8, 2024 15:57
Copy link
Contributor

@stianst stianst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I had in mind is close to this, but not quite.

My idea was that we would have multiple database suppliers:

  • PostgresDatabaseSupplier
  • MySQLDatabaseSupplier
  • DevFileDatabaseSupplier
  • DevMemDatabaseSupplier

Each supplier would supply a TestDatabase with start/stop methods, and a getConfig() method.

You'd select which DB supplier to use with #30609 in the same way as we would select a different server run-mode or browser.

TestDatabase would be responsible for starting/stopping the DB container using test containers.

For now it's fine that DBs are not configurable (we just let it auto configure itself to some sensible defaults), and that we don't support connecting to external DBs, we can do that as a follow-up.

@miquelsi miquelsi force-pushed the main_db branch 3 times, most recently from 18f01af to cf6eae4 Compare July 10, 2024 08:38
@miquelsi miquelsi changed the title DRAFT. Adding database configuration. DRAFT. Adding database suppliers. Jul 10, 2024
@miquelsi miquelsi force-pushed the main_db branch 2 times, most recently from 20c5a3f to a7f61f5 Compare July 10, 2024 11:15
@miquelsi miquelsi changed the title DRAFT. Adding database suppliers. Adding database suppliers Jul 11, 2024
@miquelsi miquelsi force-pushed the main_db branch 2 times, most recently from db709fe to 9869df8 Compare July 11, 2024 10:15
@miquelsi miquelsi marked this pull request as ready for review July 11, 2024 11:05
@miquelsi miquelsi requested a review from a team as a code owner July 11, 2024 11:05
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this class?

@Override
public InstanceWrapper<KeycloakTestServer, KeycloakIntegrationTest> getValue(Registry registry, KeycloakIntegrationTest annotation) {
KeycloakTestServerConfig serverConfig = SupplierHelpers.getInstance(annotation.config());
DatabaseSupplier databaseSupplier = new DevMemDatabaseSupplier();
Copy link
Contributor

@stianst stianst Jul 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not create the database supplier, but it should just use the registry to look it up:

TestDatabase database = registry.getDependency(TestDatabase.class, wrapper);

See

InstanceWrapper<RealmResource, TestRealm> wrapper = new InstanceWrapper<>(this, annotation);
LifeCycle lifecycle = annotation.lifecycle();
Keycloak adminClient = registry.getDependency(Keycloak.class, wrapper);
RealmConfig config = SupplierHelpers.getInstance(annotation.config());
RealmRepresentation realmRepresentation = config.getRepresentation();
if (realmRepresentation.getRealm() == null) {
String realmName = lifecycle.equals(LifeCycle.GLOBAL) ? config.getClass().getSimpleName() : registry.getCurrentContext().getRequiredTestClass().getSimpleName();
realmRepresentation.setRealm(realmName);
}
String realmName = realmRepresentation.getRealm();
wrapper.addNote(REALM_NAME_KEY, realmName);
adminClient.realms().create(realmRepresentation);
RealmResource realmResource = adminClient.realm(realmRepresentation.getRealm());
wrapper.setValue(realmResource, lifecycle);
return wrapper;
as an example on how to get a dependency in a supplier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather then getting supplier I am thinking of fully manged DB called within the KeycloakIntegrationTest annotation as a prerequisite, do you think @stianst it makes sense?

@@ -0,0 +1,4 @@
package org.keycloak.test.framework.database;

public class DevMemDatabaseConfig implements DatabaseConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you want to introduce rather DefaultDatabaseConfig class?


import java.lang.annotation.Annotation;

public abstract class DatabaseSupplier implements Supplier<TestDatabase, Annotation> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider some TestManagedDatabase annotation which will be reused within KeycloakIntegrationTest annotation for ServiceLoader injection?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


@Override
public void start(KeycloakTestServerConfig serverConfig) {
public void start(KeycloakTestServerConfig serverConfig, TestDatabase testDatabase) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be cleaner to just pass the DatabaseConfig? Makes it clear that it shouldn't be stopping/starting the db or anything like that ;)


public abstract class DatabaseSupplier implements Supplier<TestDatabase, Annotation> {

protected static TestDatabase testDatabase = new TestDatabase(new DevMemDatabaseConfig());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import java.util.Collections;
import java.util.Map;

public interface DatabaseConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to provide default implementations here? Or would all database providers have to implement this? Perhaps we can provide something else than an empty string such as null or Optional.empty()?

Comment on lines 8 to 40
default String vendor() {
return "";
}

default String containerImage() {
return "";
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both vendor and containerImage are not used anywhere, perhaps remove these until we need them to support a functionality?

Suggested change
default String vendor() {
return "";
}
default String containerImage() {
return "";
}

Comment on lines 35 to 37
public TestDatabase getTestDatabase() {
return testDatabase;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is never used anywhere.

Suggested change
public TestDatabase getTestDatabase() {
return testDatabase;
}

Comment on lines 11 to 25
public void start() {

}

public void stop() {

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these methods currently do anything? Is there a place where we actually need to start a database and tear it down? Also it seems that stop() is never called.

serverConfig.adminUserName().ifPresent(username -> rawOptions.add("--bootstrap-admin-username=" + username));
serverConfig.adminUserPassword().ifPresent(password -> rawOptions.add("--bootstrap-admin-password=" + password));

serverConfig.adminUserName().ifPresent(username -> System.setProperty("keycloakAdmin", username));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miquelsi dont't forget to rebase to main, because this change was added few days ago: 4970a9b

@stianst stianst merged commit 73247f5 into keycloak:main Jul 16, 2024
@miquelsi miquelsi deleted the main_db branch July 16, 2024 07:40
stianst added a commit to stianst/keycloak that referenced this pull request Jul 25, 2024
* Closes keycloak#30616. Added database suppliers.

Signed-off-by: Miquel Simon <[email protected]>
Co-authored-by: stianst <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Testsuite PoC - Add database suppliers

5 participants