package org.keycloak.testsuite.arquillian;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.InstanceProducer;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.core.api.annotation.Observes;
import org.jboss.arquillian.test.spi.annotation.ClassScoped;
import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
import org.jboss.logging.Logger;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
/**
*
* @author tkyjovsk
*/
public class AppServerTestEnricher {
protected final Logger log = Logger.getLogger(this.getClass());
@Inject
@ClassScoped
private InstanceProducer<TestContext> testContextProducer;
private TestContext testContext;
public static String getAppServerQualifier(Class testClass) {
Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class);
String appServerQ = (annotatedClass == null ? null
: annotatedClass.getAnnotation(AppServerContainer.class).value());
return annotatedClass == null ? null // no @AppServerContainer annotation --> no adapter test
: (appServerQ == null || appServerQ.isEmpty() // @AppServerContainer annotation present but qualifier not set --> relative adapter test
? AuthServerTestEnricher.AUTH_SERVER_CONTAINER // app server == auth server
: appServerQ);
}
public static String getAppServerContextRoot() {
return getAppServerContextRoot(0);
}
public static String getAppServerContextRoot(int clusterPortOffset) {
String host = System.getProperty("app.server.host", "localhost");
int httpPort = Integer.parseInt(System.getProperty("app.server.http.port")); // property must be set
int httpsPort = Integer.parseInt(System.getProperty("app.server.https.port")); // property must be set
boolean sslRequired = Boolean.parseBoolean(System.getProperty("app.server.ssl.required"));
String scheme = sslRequired ? "https" : "http";
int port = sslRequired ? httpsPort : httpPort;
return String.format("%s://%s:%s", scheme, host, port + clusterPortOffset);
}
public void updateTestContextWithAppServerInfo(@Observes(precedence = 1) BeforeClass event) {
testContext = testContextProducer.get();
String appServerQualifier = getAppServerQualifier(testContext.getTestClass());
for (ContainerInfo container : testContext.getSuiteContext().getContainers()) {
if (container.getQualifier().equals(appServerQualifier)) {
testContext.setAppServerInfo(updateWithAppServerInfo(container));
}
}
// validate app server
if (appServerQualifier != null && testContext.getAppServerInfo() == null) {
throw new RuntimeException(String.format("No app server container matching '%s' was activated. Check if defined and enabled in arquillian.xml.", appServerQualifier));
}
log.info("\n\n" + testContext);
}
private ContainerInfo updateWithAppServerInfo(ContainerInfo appServerInfo) {
return updateWithAppServerInfo(appServerInfo, 0);
}
private ContainerInfo updateWithAppServerInfo(ContainerInfo appServerInfo, int clusterPortOffset) {
try {
String appServerContextRootStr = isRelative(testContext.getTestClass())
? getAuthServerContextRoot(clusterPortOffset)
: getAppServerContextRoot(clusterPortOffset);
appServerInfo.setContextRoot(new URL(appServerContextRootStr));
} catch (MalformedURLException ex) {
throw new IllegalArgumentException(ex);
}
return appServerInfo;
}
@Inject
private Instance<ContainerController> containerConrollerInstance;
public void startAppServer(@Observes(precedence = -1) BeforeClass event) throws MalformedURLException, InterruptedException, IOException {
if (testContext.isAdapterTest() && !testContext.isRelativeAdapterTest()) {
ContainerController controller = containerConrollerInstance.get();
if (!controller.isStarted(testContext.getAppServerInfo().getQualifier())) {
log.info("Starting app server: " + testContext.getAppServerInfo().getQualifier());
controller.start(testContext.getAppServerInfo().getQualifier());
}
}
}
/**
*
* @param testClass
* @param annotationClass
* @return testClass or the nearest superclass of testClass annotated with
* annotationClass
*/
public static Class getNearestSuperclassWithAnnotation(Class testClass, Class annotationClass) {
return testClass.isAnnotationPresent(annotationClass) ? testClass
: (testClass.getSuperclass().equals(Object.class) ? null // stop recursion
: getNearestSuperclassWithAnnotation(testClass.getSuperclass(), annotationClass)); // continue recursion
}
public static boolean hasAppServerContainerAnnotation(Class testClass) {
return getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class) != null;
}
public static boolean isRelative(Class testClass) {
return getAppServerQualifier(testClass).equals(AuthServerTestEnricher.AUTH_SERVER_CONTAINER);
}
public static boolean isWildflyAppServer(Class testClass) {
return getAppServerQualifier(testClass).contains("wildfly");
}
public static boolean isTomcatAppServer(Class testClass) {
return getAppServerQualifier(testClass).contains("tomcat");
}
public static boolean isOSGiAppServer(Class testClass) {
String q = getAppServerQualifier(testClass);
return q.contains("karaf") || q.contains("fuse");
}
}