Skip to content

Commit

Permalink
Merge pull request #887 from stuartwdouglas/uri-injection
Browse files Browse the repository at this point in the history
Add support for directly injecting the HTTP URL into tests
  • Loading branch information
stuartwdouglas authored Feb 14, 2019
2 parents d336a57 + 323dc91 commit 0b8b0e7
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 10 deletions.
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 @@ -354,6 +354,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

0 comments on commit 0b8b0e7

Please sign in to comment.