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

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actions/conditional/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ outputs:
ci-webauthn:
description: Should "ci.yml" execute (WebAuthn)
value: ${{ steps.changes.outputs.ci-webauthn }}
ci-test-poc:
description: Should "ci.yml" execute (Test PoC)
value: ${{ steps.changes.outputs.ci-test-poc }}
operator:
description: Should "operator-ci.yml" execute
value: ${{ steps.changes.outputs.operator }}
Expand Down
2 changes: 2 additions & 0 deletions .github/actions/conditional/conditions
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ js/libs/ui-shared/ ci ci-webauthn
themes/ codeql-themes

testsuite::database-suite ci-store

test-poc/ ci ci-test-poc
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
ci-sssd: ${{ steps.conditional.outputs.ci-sssd }}
ci-webauthn: ${{ steps.conditional.outputs.ci-webauthn }}
ci-store-matrix: ${{ steps.conditional-stores.outputs.matrix }}
ci-test-poc: ${{ steps.conditional.outputs.ci-test-poc }}
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -858,6 +859,26 @@ jobs:
with:
job-id: migration-tests-${{ matrix.old-version }}-${{ matrix.database }}

test-poc:
name: Test PoC
runs-on: ubuntu-latest
if: needs.conditional.outputs.ci-test-poc == 'true'
needs:
- conditional
- build
timeout-minutes: 30
steps:
- uses: actions/checkout@v4

- id: integration-test-setup
Copy link
Contributor

Choose a reason for hiding this comment

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

You can omit the id if you are not referencing it anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, just copy/paste from elsewhere though. Having id/name makes the run a bit more readable though as the output with reusable actions is not very elegant without it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I'd just add a human readable name to it and call it a day

name: Integration test setup
uses: ./.github/actions/integration-test-setup

- name: Run tests
run: |
cd test-poc
mvn clean install

check:
name: Status Check - Keycloak CI
if: always()
Expand All @@ -881,6 +902,7 @@ jobs:
- sssd-unit-tests
- migration-tests
- external-infinispan-tests
- test-poc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
public class NoAdminUserKeycloakTestServerConfig implements KeycloakTestServerConfig {

@Override
public Optional<String> adminUserName() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a fan of my optionals? 😢

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They have their place, but found it easier to not have it in this case, as it's both simpler to just return null, and found the checks when setting the values simpler without optional stuff ;)

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, it's a matter of personal preference I guess. However using optionals forces you to handle nullability, whereas nulls do not. Also:

serverConfig.adminUserName().ifPresentOrElse(
  username -> System.setProperty("keycloakAdmin", username),
  () -> System.getProperties().remove("keycloakAdmin")
);

return Optional.empty();
public String adminUserName() {
return null;
}

@Override
public Optional<String> adminUserPassword() {
return Optional.empty();
public String adminUserPassword() {
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,8 @@ public class PagesTest {
@Test
public void testLoginFromWelcome() {
welcomePage.navigateTo();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
loginPage.fillLogin("admin", "admin");
loginPage.submit();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import org.keycloak.admin.client.Keycloak;
import org.keycloak.test.framework.TestAdminClient;
import org.keycloak.test.framework.injection.InstanceWrapper;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.Registry;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;
import org.keycloak.test.framework.server.KeycloakTestServer;
Expand All @@ -22,25 +21,24 @@ public Class<Keycloak> getValueType() {
}

@Override
public InstanceWrapper<Keycloak, TestAdminClient> getValue(Registry registry, TestAdminClient annotation) {
InstanceWrapper<Keycloak, TestAdminClient> wrapper = new InstanceWrapper<>(this, annotation);

KeycloakTestServer testServer = registry.getDependency(KeycloakTestServer.class, wrapper);

Keycloak keycloak = Keycloak.getInstance(testServer.getBaseUrl(), "master", "admin", "admin", "admin-cli");
wrapper.setValue(keycloak, LifeCycle.GLOBAL);
public Keycloak getValue(InstanceContext<Keycloak, TestAdminClient> instanceContext) {
KeycloakTestServer testServer = instanceContext.getDependency(KeycloakTestServer.class);
return Keycloak.getInstance(testServer.getBaseUrl(), "master", "admin", "admin", "admin-cli");
}

return wrapper;
@Override
public LifeCycle getDefaultLifecycle() {
return LifeCycle.GLOBAL;
}

@Override
public boolean compatible(InstanceWrapper<Keycloak, TestAdminClient> a, RequestedInstance<Keycloak, TestAdminClient> b) {
public boolean compatible(InstanceContext<Keycloak, TestAdminClient> a, RequestedInstance<Keycloak, TestAdminClient> b) {
return true;
}

@Override
public void close(Keycloak keycloak) {
keycloak.close();
public void close(InstanceContext<Keycloak, TestAdminClient> instanceContext) {
instanceContext.getValue().close();
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package org.keycloak.test.framework.database;

import org.keycloak.test.framework.KeycloakTestDatabase;
import org.keycloak.test.framework.injection.InstanceWrapper;
import org.keycloak.test.framework.injection.InstanceContext;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.injection.Registry;
import org.keycloak.test.framework.injection.RequestedInstance;
import org.keycloak.test.framework.injection.Supplier;

Expand All @@ -23,17 +22,26 @@ public Class<TestDatabase> getValueType() {
}

@Override
public InstanceWrapper<TestDatabase, KeycloakTestDatabase> getValue(Registry registry, KeycloakTestDatabase annotation) {
public TestDatabase getValue(InstanceContext<TestDatabase, KeycloakTestDatabase> instanceContext) {
TestDatabase testDatabase = getTestDatabase();
testDatabase.start();
return new InstanceWrapper<>(this, annotation, testDatabase, LifeCycle.GLOBAL);
return testDatabase;
}

@Override
public boolean compatible(InstanceWrapper<TestDatabase, KeycloakTestDatabase> a, RequestedInstance<TestDatabase, KeycloakTestDatabase> b) {
public boolean compatible(InstanceContext<TestDatabase, KeycloakTestDatabase> a, RequestedInstance<TestDatabase, KeycloakTestDatabase> b) {
return true;
}

@Override
public LifeCycle getDefaultLifecycle() {
return LifeCycle.GLOBAL;
}

abstract TestDatabase getTestDatabase();

@Override
public void close(InstanceContext<TestDatabase, KeycloakTestDatabase> instanceContext) {
instanceContext.getValue().stop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,35 @@
import java.util.Map;
import java.util.Set;

public class InstanceWrapper<T, A extends Annotation> {
public class InstanceContext<T, A extends Annotation> {

private final Registry registry;
private final Supplier<T, A> supplier;
private final A annotation;
private final Set<InstanceWrapper<T, A>> dependencies = new HashSet<>();
private final Set<InstanceContext<T, A>> dependencies = new HashSet<>();
private T value;
private Class<? extends T> requestedValueType;
private LifeCycle lifeCycle;
private final Map<String, Object> notes = new HashMap<>();

public InstanceWrapper(Supplier<T, A> supplier, A annotation) {
public InstanceContext(Registry registry, Supplier<T, A> supplier, A annotation, Class<? extends T> requestedValueType) {
this.registry = registry;
this.supplier = supplier;
this.annotation = annotation;
this.requestedValueType = requestedValueType;
this.lifeCycle = supplier.getLifeCycle(annotation);
}

public InstanceWrapper(Supplier<T, A> supplier, A annotation, T value, LifeCycle lifeCycle) {
this.supplier = supplier;
this.annotation = annotation;
this.value = value;
this.lifeCycle = lifeCycle;
public <D> D getDependency(Class<D> typeClazz) {
return registry.getDependency(typeClazz, this);
}

public void setValue(T value, LifeCycle lifeCycle) {
public Registry getRegistry() {
return registry;
}

void setValue(T value) {
this.value = value;
this.lifeCycle = lifeCycle;
}

public Supplier<T, A> getSupplier() {
Expand All @@ -40,6 +45,10 @@ public T getValue() {
return value;
}

public Class<? extends T> getRequestedValueType() {
return requestedValueType;
}

public LifeCycle getLifeCycle() {
return lifeCycle;
}
Expand All @@ -48,12 +57,12 @@ public A getAnnotation() {
return annotation;
}

public Set<InstanceWrapper<T, A>> getDependencies() {
public Set<InstanceContext<T, A>> getDependencies() {
return dependencies;
}

public void registerDependency(InstanceWrapper<T, A> instanceWrapper) {
dependencies.add(instanceWrapper);
public void registerDependency(InstanceContext<T, A> instanceContext) {
dependencies.add(instanceContext);
}

public void addNote(String key, Object value) {
Expand Down
Loading