Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for directly injecting the HTTP URL into tests #887

Merged
merged 2 commits into from
Feb 14, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@

import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.config.SmallRyeConfigProviderResolver;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.spi.ConfigBuilder;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.eclipse.microprofile.config.spi.ConfigSource;
Expand Down Expand Up @@ -152,6 +155,7 @@ public ConfigurationBuildItem initializeConfiguration(
for (Class<?> clazz : ServiceUtil.classesNamedIn(extensionClassLoaderBuildItem.getExtensionClassLoader(), "META-INF/shamrock-config-roots.list")) {
configDefinition.registerConfigRoot(clazz);
}
SmallRyeConfigProviderResolver.instance().registerConfig(src, Thread.currentThread().getContextClassLoader());
configDefinition.loadConfiguration(src);
return new ConfigurationBuildItem(configDefinition);
}
Expand Down
17 changes: 17 additions & 0 deletions docs/src/main/asciidoc/getting-started-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,23 @@ These tests use http://rest-assured.io/[RestAssured], but feel free to use your

You can run the test from your IDE directly (be sure you stopped the application first), or from Maven using: `mvn test`.

By default tests will run on port `8081` so as not to conflict with the running application. We automatically
configure RestAssured to use this port. If you want to use a different client you should use the `@TestHTTPResource`
annotation to directly inject the URL of the test into a field on the test class. This field can be of the type
`String`, `URL` or `URI`. This annotation can also be given a value for the test path. For example if I want to test
a Servlet mapped to `/myservlet` I would just add the following to my test:


[source,java]
----
@TestHTTPResource("/myservlet")
URL testUrl;
----

The test port can be controlled via the `shamrock.http.test-port` config property. Shamrock also creates a system
property called `test.url` that is set to the base test URL for situations where you cannot use injection.


== Packaging and run the application

The application is packaged using `mvn package`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ClientResource {
@Path("/manual")
public String manual() throws Exception {
RestInterface iface = RestClientBuilder.newBuilder()
.baseUrl(new URL("http", "localhost", 8081, "/"))
.baseUrl(new URL(System.getProperty("test.url")))
.build(RestInterface.class);
return iface.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
#

org.jboss.shamrock.example.rest.RestInterface/mp-rest/url=http://localhost:8081/
org.jboss.shamrock.example.rest.RestInterface/mp-rest/url=${test.url}
# Disabled by default as it establishes external connections.
# Uncomment when you want to test SSL support.
#org.jboss.shamrock.example.rest.SslRestInterface/mp-rest/url=https://www.example.com/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@
import java.net.URL;
import java.net.URLConnection;

import org.jboss.shamrock.test.common.http.TestHTTPResource;
import org.jboss.shamrock.test.junit.ShamrockTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

@ShamrockTest
public class FaultToleranceTestCase {

@TestHTTPResource("ft")
URL uri;

@Test
public void testRetry() throws Exception {
URL uri = new URL("http://localhost:8081/ft");
URLConnection connection = uri.openConnection();
InputStream in = connection.getInputStream();
byte[] buf = new byte[100];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import javax.json.JsonObject;
import javax.json.JsonReader;

import org.jboss.shamrock.test.common.http.TestHTTPResource;
import org.jboss.shamrock.test.junit.ShamrockTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand All @@ -37,9 +38,11 @@
@ShamrockTest
public class OpenApiTestCase {

@TestHTTPResource("openapi")
URL uri;

@Test
public void testOpenAPIJSON() throws Exception {
URL uri = new URL("http://localhost:8081/openapi");
URLConnection connection = uri.openConnection();
connection.setRequestProperty("Accept", "application/json");
InputStream in = connection.getInputStream();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@

import javax.json.Json;

import org.jboss.shamrock.test.common.http.TestHTTPResource;
import org.jboss.shamrock.test.junit.ShamrockTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

@ShamrockTest
public class ValidatorTestCase {

@TestHTTPResource("validator/manual")
URL uri;

@Test
public void testManualValidationFailed() throws Exception {
URL uri = new URL("http://localhost:8081/validator/manual");
URLConnection connection = uri.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
Expand All @@ -60,7 +63,6 @@ public void testManualValidationFailed() throws Exception {

@Test
public void testManualValidationPassed() throws Exception {
URL uri = new URL("http://localhost:8081/validator/manual");
URLConnection connection = uri.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@
import javax.websocket.MessageHandler;
import javax.websocket.Session;

import org.jboss.shamrock.test.common.http.TestHTTPResource;
import org.jboss.shamrock.test.junit.ShamrockTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

@ShamrockTest
public class WebsocketTestCase {

@TestHTTPResource("echo")
URI uri;

@Test
public void websocketTest() throws Exception {

final URI uri = new URI("http://localhost:8081/echo");

LinkedBlockingDeque<String> message = new LinkedBlockingDeque<>();
Session session = ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.Map;

import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.shamrock.test.common.http.TestHttpResourceManager;

public class NativeImageLauncher implements Closeable {

Expand Down Expand Up @@ -57,6 +58,7 @@ public void start() throws Exception {
List<String> args = new ArrayList<>();
args.add(path);
args.add("-Dshamrock.http.port=" + port);
args.add("-Dtest.url=" + TestHttpResourceManager.getUri());

System.out.println("Executing " + args);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.jboss.shamrock.test.common.http;

import java.lang.reflect.Field;
import java.net.URI;

public class StringTestHTTPResourceProvider implements TestHTTPResourceProvider<String> {
@Override
public Class<String> getProvidedType() {
return String.class;
}

@Override
public String provide(URI testUri, Field field) {
return testUri.toASCIIString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.jboss.shamrock.test.common.http;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Indicates that a field should be injected with a resource that is pre-configured
* to use the correct test URL.
*
* This could be a String or URL object, or some other HTTP/Websocket based client.
*
* This mechanism is plugable, via {@link TestHTTPResourceProvider}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TestHTTPResource {

/**
*
* @return The path part of the URL
*/
String value() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.jboss.shamrock.test.common.http;

import java.lang.reflect.Field;
import java.net.URI;

public interface TestHTTPResourceProvider<T> {

Class<T> getProvidedType();

/**
* Create the resource to be injected into the field.
* <p>
* Note that there is no need to directly call set() on the field, it is only provided
* to allow you to examine the generic type and any additional annotations.
*/
T provide(URI testUri, Field field);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.jboss.shamrock.test.common.http;

import java.lang.reflect.Field;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;

public class TestHttpResourceManager {

static final String uri;
static final Map<Class<?>, TestHTTPResourceProvider<?>> providers;

static {
Map<Class<?>, TestHTTPResourceProvider<?>> map = new HashMap<>();
for (TestHTTPResourceProvider i : ServiceLoader.load(TestHTTPResourceProvider.class)) {
map.put(i.getProvidedType(), i);
}
providers = Collections.unmodifiableMap(map);
Config config = ConfigProvider.getConfig();
String host = config.getOptionalValue("shamrock.http.host", String.class).orElse("localhost");
String port = config.getOptionalValue("shamrock.http.test-port", String.class).orElse("8081");
uri = "http://" + host + ":" + port;
System.setProperty("test.url", uri);
}

public static String getUri() {
return uri;
}

public static void inject(Object testCase) {
Class<?> c = testCase.getClass();
while (c != Object.class) {
for(Field f : c.getDeclaredFields()) {
TestHTTPResource resource = f.getAnnotation(TestHTTPResource.class);
if(resource != null) {
TestHTTPResourceProvider provider = providers.get(f.getType());
if(provider == null) {
throw new RuntimeException("Unable to inject TestHTTPResource field " + f + " as no provider exists for the type");
}
String path = resource.value();
String val;
if(path.startsWith("/")) {
val = uri + path;
} else {
val = uri + "/" + path;
}
f.setAccessible(true);
try {
f.set(testCase, provider.provide(new URI(val), f));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
c = c.getSuperclass();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.jboss.shamrock.test.common.http;

import java.lang.reflect.Field;
import java.net.URI;

public class URITestHTTPResourceProvider implements TestHTTPResourceProvider<URI> {
@Override
public Class<URI> getProvidedType() {
return URI.class;
}

@Override
public URI provide(URI testUri, Field field) {
return testUri;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.jboss.shamrock.test.common.http;

import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

public class URLTestHTTPResourceProvider implements TestHTTPResourceProvider<URL> {
@Override
public Class<URL> getProvidedType() {
return URL.class;
}

@Override
public URL provide(URI testUri, Field field) {
try {
return testUri.toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
org.jboss.shamrock.test.common.http.URLTestHTTPResourceProvider
org.jboss.shamrock.test.common.http.URITestHTTPResourceProvider
org.jboss.shamrock.test.common.http.StringTestHTTPResourceProvider
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public void testFinished(Description description) throws Exception {
RestAssuredPortManager.clearPort();
}



protected abstract void startShamrock() throws Exception;

protected abstract void stopShamrock() throws Exception;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.function.BiFunction;

import org.jboss.shamrock.test.common.http.TestHttpResourceManager;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
Expand Down Expand Up @@ -54,4 +55,11 @@ protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
notifier.fireTestIgnored(describeChild(method));
}
}

@Override
protected Object createTest() throws Exception {
Object instance = super.createTest();
TestHttpResourceManager.inject(instance);
return instance;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.jboss.shamrock.test.common.PathTestHelper;
import org.jboss.shamrock.test.common.RestAssuredPortManager;
import org.jboss.shamrock.test.common.TestResourceManager;
import org.jboss.shamrock.test.common.http.TestHttpResourceManager;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
Expand Down Expand Up @@ -104,7 +105,9 @@ public Object createTestInstance(TestInstanceFactoryContext factoryContext, Exte
.setSuperClass(testClass));

Object actualTestInstance = extensionContext.getStore(ExtensionContext.Namespace.GLOBAL).get(testClass.getName());

if(actualTestInstance != null) { //happens if a deployment exception is expected
TestHttpResourceManager.inject(actualTestInstance);
}
return factory.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Expand Down
Loading