Author: bdelacretaz
Date: Thu Sep 17 13:20:19 2015
New Revision: 1703615
URL: http://svn.apache.org/r1703615
Log:
Read test results, and use @Rule instead of @ClassRule for correct mapping of
the test methods in an IDE
Added:
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTestRule.java
- copied, changed from r1703437,
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java
Removed:
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java
Modified:
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java
Modified:
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java?rev=1703615&r1=1703614&r2=1703615&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java
(original)
+++
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java
Thu Sep 17 13:20:19 2015
@@ -20,9 +20,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
+import org.junit.runners.model.MultipleFailureException;
+
interface ClientSideSupport {
InputStream buildTestBundle(Class<?> c, String bundleSymbolicName);
void installBundle(InputStream bundle, String bundleSymbolicName) throws
MalformedURLException, IOException;
void uninstallBundle(String bundleSymbolicName) throws
MalformedURLException, IOException;
- void runTests(Class<?> c) throws MalformedURLException, IOException;
+ void runTests(String testSelectionPath, int testReadyTimeoutSeconds)
throws MalformedURLException, IOException, MultipleFailureException;
}
Modified:
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java?rev=1703615&r1=1703614&r2=1703615&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java
(original)
+++
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java
Thu Sep 17 13:20:19 2015
@@ -16,6 +16,7 @@
*/
package org.apache.sling.testing.rules;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
@@ -23,9 +24,14 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
import javax.xml.bind.DatatypeConverter;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.model.MultipleFailureException;
import org.ops4j.pax.tinybundles.core.TinyBundles;
import org.osgi.framework.Constants;
@@ -41,11 +47,12 @@ class DefaultClientSideSupport implement
* Need to include the ServerSideTest class as c refers to it.
*/
public InputStream buildTestBundle(Class<?> c, String bundleSymbolicName) {
+ // TODO find the required classes via reflection?
return TinyBundles.bundle()
.set(Constants.BUNDLE_SYMBOLICNAME, bundleSymbolicName)
.set("Sling-Test-Regexp", c.getName() + ".*")
.add(c)
- .add(ServerSideTest.class)
+ .add(ServerSideTestRule.class)
.build(TinyBundles.withBnd());
}
@@ -62,15 +69,20 @@ class DefaultClientSideSupport implement
final String url = baseUrl + "/system/console/bundles";
final String contentType = "application/octet-stream";
final HttpURLConnection c = (HttpURLConnection)new
URL(url).openConnection();
- setCredentials(c);
- new MultipartAdapter(c, CHARSET)
- .parameter("action", "install")
- .parameter("bundlestart", "1")
- .file("bundlefile", bundleSymbolicName + ".jar", contentType, bundle)
- .close();
- final int status = c.getResponseCode();
- if(status != 302) {
- throw new IOException("Got status code " + status + " for " + url);
+
+ try {
+ setCredentials(c);
+ new MultipartAdapter(c, CHARSET)
+ .parameter("action", "install")
+ .parameter("bundlestart", "1")
+ .file("bundlefile", bundleSymbolicName + ".jar", contentType,
bundle)
+ .close();
+ final int status = c.getResponseCode();
+ if(status != 302) {
+ throw new IOException("Got status code " + status + " for " +
url);
+ }
+ } finally {
+ c.disconnect();
}
}
@@ -80,30 +92,74 @@ class DefaultClientSideSupport implement
// curl -u admin:admin -F action=uninstall
http://localhost:8080/system/console/bundles/$N
final String url = baseUrl + "/system/console/bundles/" +
bundleSymbolicName;
final HttpURLConnection c = (HttpURLConnection)new
URL(url).openConnection();
- setCredentials(c);
- new MultipartAdapter(c, CHARSET)
- .parameter("action", "uninstall")
- .close();
- final int status = c.getResponseCode();
- if(status != 200) {
- throw new IOException("Got status code " + status + " for " + url);
+
+ try {
+ setCredentials(c);
+ new MultipartAdapter(c, CHARSET)
+ .parameter("action", "uninstall")
+ .close();
+ final int status = c.getResponseCode();
+ if(status != 200) {
+ throw new IOException("Got status code " + status + " for " +
url);
+ }
+ } finally {
+ c.disconnect();
}
}
-
- @Override
- public void runTests(Class<?> clazz) throws MalformedURLException,
IOException {
- final String testUrl = baseUrl + "/system/sling/junit/" +
clazz.getName() + ".json";
- final HttpURLConnection c = (HttpURLConnection)new
URL(testUrl).openConnection();
- // TODO wait for non-404 response, signals that test bundle is ready
- c.setRequestMethod("POST");
+
+ private int getHttpGetStatus(String url) throws MalformedURLException,
IOException {
+ final HttpURLConnection c = (HttpURLConnection)new
URL(url).openConnection();
c.setUseCaches(false);
c.setDoOutput(true);
c.setDoInput(true);
c.setInstanceFollowRedirects(false);
- final int status = c.getResponseCode();
- if(status != 200) {
- throw new IOException("Got status code " + status + " for " +
testUrl);
+ try {
+ return c.getResponseCode();
+ } finally {
+ c.disconnect();
+ }
+ }
+
+ @Override
+ public void runTests(String testSelectionPath, int
testReadyTimeoutSeconds) throws MalformedURLException, IOException,
MultipleFailureException {
+ final String testUrl = baseUrl + "/system/sling/junit/" +
testSelectionPath + ".junit_result";
+
+ // Wait for non-404 response that signals that test bundle is ready
+ final long timeout = System.currentTimeMillis() +
(testReadyTimeoutSeconds * 1000L);
+ while(true) {
+ if(getHttpGetStatus(testUrl) == 200) {
+ break;
+ }
+ if(System.currentTimeMillis() > timeout) {
+ fail("Timeout waiting for test at " + testUrl + " (" +
testReadyTimeoutSeconds + " seconds)");
+ break;
+ }
+ }
+
+ final HttpURLConnection c = (HttpURLConnection)new
URL(testUrl).openConnection();
+ try {
+ c.setRequestMethod("POST");
+ c.setUseCaches(false);
+ c.setDoOutput(true);
+ c.setDoInput(true);
+ c.setInstanceFollowRedirects(false);
+ final int status = c.getResponseCode();
+ if(status != 200) {
+ throw new IOException("Got status code " + status + " for " +
testUrl);
+ }
+
+ final Result result = (Result)new
ObjectInputStream(c.getInputStream()).readObject();
+ if(result.getFailureCount() > 0) {
+ final List<Throwable> failures = new
ArrayList<Throwable>(result.getFailureCount());
+ for (Failure f : result.getFailures()) {
+ failures.add(f.getException());
+ }
+ throw new MultipleFailureException(failures);
+ }
+ } catch(ClassNotFoundException e) {
+ throw new IOException("Exception reading test results:" + e, e);
+ } finally {
+ c.disconnect();
}
- // TODO read test results etc
}
}
Copied:
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTestRule.java
(from r1703437,
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTestRule.java?p2=sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTestRule.java&p1=sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java&r1=1703437&r2=1703615&rev=1703615&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java
(original)
+++
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTestRule.java
Thu Sep 17 13:20:19 2015
@@ -29,19 +29,22 @@ import org.junit.runners.model.Statement
* packaging it in a temporary OSGi bundle, installing that bundle on
* the Sling instance and executing the test via the Sling JUnit servlet.
*/
-public class ServerSideTest extends ExternalResource {
+public class ServerSideTestRule extends ExternalResource {
private final Class<?> classUnderTest;
private final String bundleSymbolicName;
private final ClientSideSupport css;
+ // TODO configurable
+ private final int testReadyTimeoutSeconds = 5;
+
/** Build a server-side test rule that uses the default test server */
- ServerSideTest(Class<?> underTest) {
+ ServerSideTestRule(Class<?> underTest) {
this(underTest, null);
}
/** Build a server-side test rule that can use a specific test server */
- ServerSideTest(Class<?> underTest, String serverSelector) {
+ ServerSideTestRule(Class<?> underTest, String serverSelector) {
this.classUnderTest = underTest;
// Unique and somewhat identifiable name for our test bundle
@@ -58,15 +61,22 @@ public class ServerSideTest extends Exte
}
@Override
- public Statement apply(final Statement base, Description description) {
+ public Statement apply(final Statement base, final Description
description) {
+ // As this is not a ClassRule (which wouldn't map the test results
correctly in an IDE)
+ // we currently create and install a test bundle for every test
method. It might be good
+ // to optimize this, but as those test bundles are usually very small
that doesn't seem
+ // to be a real problem in terms of performance.
return new Statement() {
@Override
public void evaluate() throws Throwable {
if(css != null) {
final InputStream bundle =
css.buildTestBundle(classUnderTest, bundleSymbolicName);
+ // TODO check that test is absent before installing
bundle??
+ // Or verify the "version" of the test??
css.installBundle(bundle, bundleSymbolicName);
try {
- css.runTests(classUnderTest);
+ final String testPath = description.getClassName() +
"/" + description.getMethodName();
+ css.runTests(testPath, testReadyTimeoutSeconds);
} finally {
css.uninstallBundle(bundleSymbolicName);
}
Modified:
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java?rev=1703615&r1=1703614&r2=1703615&view=diff
==============================================================================
---
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java
(original)
+++
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java
Thu Sep 17 13:20:19 2015
@@ -17,14 +17,15 @@
package org.apache.sling.testing.rules;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
public class DummyTest {
- @ClassRule
- public static final ServerSideTest t = new ServerSideTest(DummyTest.class);
+ @Rule
+ public final ServerSideTestRule t = new ServerSideTestRule(getClass());
@Test
public void semiRandomFailure() {
@@ -35,4 +36,9 @@ public class DummyTest {
public void alwaysPasses() {
}
+ @Test
+ public void alwaysFails() {
+ fail("This one always fails");
+ }
+
}