blob: d6804190e7ff00f16ef3f6014f6a95956e9410d9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.geronimo.microprofile.metrics.test;
import static java.lang.ClassLoader.getSystemClassLoader;
import static java.lang.String.format;
import static java.util.Optional.of;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.loader.WebappClassLoaderBase;
import org.apache.catalina.loader.WebappLoader;
import org.apache.meecrowave.Meecrowave;
import org.apache.meecrowave.arquillian.MeecrowaveConfiguration;
import org.apache.meecrowave.arquillian.MeecrowaveContainer;
import org.apache.meecrowave.io.IO;
import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription;
import org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext;
import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData;
import org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
public class TckContainer extends MeecrowaveContainer {
private final Map<Archive<?>, Runnable> onUnDeploy = new HashMap<>();
@Override
public void setup(final MeecrowaveConfiguration configuration) {
super.setup(configuration);
getConfiguration().setWatcherBouncing(-1);
}
@Override
public ProtocolMetaData deploy(final Archive<?> archive) {
final File dump = toArchiveDump(archive);
archive.as(ZipExporter.class).exportTo(dump, true);
final String context = ""; // forced by tcks :(
onUnDeploy.put(archive, () -> {
getContainer().undeploy(""); // cause we forced the context name
IO.delete(dump);
of(new File(getContainer().getBase(), "webapps/ROOT")).filter(File::exists).ifPresent(IO::delete);
});
final Meecrowave container = getContainer();
container.deployWebapp(new Meecrowave.DeploymentMeta(context, dump, c -> {
c.setLoader(new WebappLoader() {
@Override
protected void startInternal() throws LifecycleException {
super.startInternal();
final WebappClassLoaderBase webappClassLoaderBase = WebappClassLoaderBase.class.cast(getClassLoader());
try {
final Method setJavaseClassLoader = WebappClassLoaderBase.class.getDeclaredMethod("setJavaseClassLoader", ClassLoader.class);
setJavaseClassLoader.setAccessible(true);
setJavaseClassLoader.invoke(webappClassLoaderBase, getSystemClassLoader());
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
});
}));
final Meecrowave.Builder configuration = container.getConfiguration();
final int port = configuration.isSkipHttp() ? configuration.getHttpsPort() : configuration.getHttpPort();
System.setProperty("test.url", format("http://localhost:%d", port)); // for tck
return new ProtocolMetaData().addContext(new HTTPContext(configuration.getHost(), port).add(new Servlet("arquillian", context)));
}
@Override
public void undeploy(final Archive<?> archive) { // we rename the archive so the context so we must align the undeploy
Runnable remove = onUnDeploy.remove(archive);
if (remove == null && onUnDeploy.size() == 1) { // assume it is the one
final Archive<?> key = onUnDeploy.keySet().iterator().next();
remove = onUnDeploy.remove(key);
}
if (remove != null) {
remove.run();
} else {
Logger.getLogger(getClass().getName())
.warning("Can't find " + archive + " to undeploy it, it can break next tests");
}
}
private Meecrowave.Builder getConfiguration() {
try {
final Field field = getClass().getSuperclass().getDeclaredField("configuration");
field.setAccessible(true);
return Meecrowave.Builder.class.cast(field.get(this));
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
private Meecrowave getContainer() {
try {
final Field field = getClass().getSuperclass().getDeclaredField("container");
field.setAccessible(true);
return Meecrowave.class.cast(field.get(this));
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
private File toArchiveDump(final Archive<?> argValue) {
try {
final Method method = getClass().getSuperclass().getDeclaredMethod("toArchiveDump", Archive.class);
method.setAccessible(true);
return File.class.cast(method.invoke(this, argValue));
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
}