You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2015/09/16 19:16:28 UTC
svn commit: r1703437 - in /sling/whiteboard/bdelacretaz/test-rules: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/sling/ src/main/java/org/apache/sling/testing/
src/main/java/org/apache/sling/tes...
Author: bdelacretaz
Date: Wed Sep 16 17:16:26 2015
New Revision: 1703437
URL: http://svn.apache.org/r1703437
Log:
Rough prototype - JUnit rule to simplify writing server-side tests
Added:
sling/whiteboard/bdelacretaz/test-rules/ (with props)
sling/whiteboard/bdelacretaz/test-rules/pom.xml
sling/whiteboard/bdelacretaz/test-rules/src/
sling/whiteboard/bdelacretaz/test-rules/src/main/
sling/whiteboard/bdelacretaz/test-rules/src/main/java/
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/
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/main/java/org/apache/sling/testing/rules/MultipartAdapter.java
sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java
sling/whiteboard/bdelacretaz/test-rules/src/test/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/
sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java
Propchange: sling/whiteboard/bdelacretaz/test-rules/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Sep 16 17:16:26 2015
@@ -0,0 +1,19 @@
+target
+sling
+bin
+logs
+jackrabbit-repository
+derby.log
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
+jackrabbit
+
+
+
+
Added: sling/whiteboard/bdelacretaz/test-rules/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/test-rules/pom.xml?rev=1703437&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/test-rules/pom.xml (added)
+++ sling/whiteboard/bdelacretaz/test-rules/pom.xml Wed Sep 16 17:16:26 2015
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>23</version>
+ <relativePath/>
+ </parent>
+
+ <artifactId>org.apache.sling.testing.rules</artifactId>
+ <version>0.1.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Apache Sling Testing Rules</name>
+ <description>JUnit Rules for Sling testing</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.tinybundles</groupId>
+ <artifactId>tinybundles</artifactId>
+ <version>2.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: 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=1703437&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java (added)
+++ sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ClientSideSupport.java Wed Sep 16 17:16:26 2015
@@ -0,0 +1,28 @@
+/*
+ * 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.sling.testing.rules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+
+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;
+}
Added: 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=1703437&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java (added)
+++ sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/DefaultClientSideSupport.java Wed Sep 16 17:16:26 2015
@@ -0,0 +1,109 @@
+/*
+ * 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.sling.testing.rules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+
+class DefaultClientSideSupport implements ClientSideSupport {
+
+ private final String CHARSET = "UTF-8";
+
+ // TODO dynamic/configurable!!
+ private final String baseUrl = "http://localhost:8080";
+ private final String credentials = "admin:admin";
+
+ /** Build a test bundle that contains c as a Sling server-side test.
+ * Need to include the ServerSideTest class as c refers to it.
+ */
+ public InputStream buildTestBundle(Class<?> c, String bundleSymbolicName) {
+ return TinyBundles.bundle()
+ .set(Constants.BUNDLE_SYMBOLICNAME, bundleSymbolicName)
+ .set("Sling-Test-Regexp", c.getName() + ".*")
+ .add(c)
+ .add(ServerSideTest.class)
+ .build(TinyBundles.withBnd());
+ }
+
+ public void setCredentials(URLConnection c) {
+ final String basicAuth = "Basic " + new String(DatatypeConverter.printBase64Binary(credentials.getBytes()));
+ c.setRequestProperty ("Authorization", basicAuth);
+
+ }
+
+ @Override
+ public void installBundle(InputStream bundle, String bundleSymbolicName) throws MalformedURLException, IOException {
+ // Equivalent of
+ // curl -u admin:admin -F action=install -Fbundlestart=1 -Fbundlefile=@somefile.jar http://localhost:8080/system/console/bundles
+ 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);
+ }
+ }
+
+ @Override
+ public void uninstallBundle(String bundleSymbolicName) throws MalformedURLException, IOException {
+ // equivalent of
+ // 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);
+ }
+ }
+
+ @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");
+ 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);
+ }
+ // TODO read test results etc
+ }
+}
Added: sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/MultipartAdapter.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/MultipartAdapter.java?rev=1703437&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/MultipartAdapter.java (added)
+++ sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/MultipartAdapter.java Wed Sep 16 17:16:26 2015
@@ -0,0 +1,79 @@
+/*
+ * 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.sling.testing.rules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+
+/** Minimal HTTP client functionality for multipart POST requests */
+class MultipartAdapter {
+ final OutputStream out;
+ final PrintWriter pw;
+ final String boundary = "______________" + Double.toHexString(Math.random()) + "______________";
+ final String eol = "\r\n";
+ final String dashes = "--";
+ final String charset;
+ int counter = 0;
+
+ MultipartAdapter(HttpURLConnection c, String charset) throws IOException {
+ this.charset = charset;
+ c.setUseCaches(false);
+ c.setDoOutput(true);
+ c.setInstanceFollowRedirects(false);
+ c.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
+ out = c.getOutputStream();
+ pw = new PrintWriter(new OutputStreamWriter(out, charset), true);
+ }
+
+ void close() throws IOException {
+ pw.append(dashes).append(boundary).append(dashes).append(eol).flush();
+ out.close();
+ }
+
+ MultipartAdapter parameter(String name, String value) {
+ pw.append(dashes).append(boundary).append(eol);
+ pw.append("Content-Disposition: form-data; name=\"" + name + "\"").append(eol);
+ pw.append("Content-Type: text/plain; charset=").append(charset).append(eol);
+ pw.append(eol).append(value).append(eol).flush();
+ return this;
+ }
+
+ MultipartAdapter file(String fieldName, String filename, String contentType, InputStream data) throws IOException {
+ pw.append(dashes).append(boundary).append(eol);
+ pw.append("Content-Disposition: form-data; name=\"").append(fieldName).append("\"");
+ pw.append("; filename=\"").append(filename).append("\"").append(eol);
+ pw.append("Content-Type: ").append(contentType).append(eol);
+ pw.append("Content-Transfer-Encoding: binary").append(eol);
+ pw.append(eol).flush();
+ copy(data, out);
+ pw.append(eol).flush();
+ return this;
+ }
+
+ private void copy(InputStream is, OutputStream os) throws IOException {
+ final byte[] buffer = new byte[16384];
+ int n=0;
+ while((n = is.read(buffer, 0, buffer.length)) > 0) {
+ os.write(buffer, 0, n);
+ }
+ os.flush();
+ }
+}
Added: 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/ServerSideTest.java?rev=1703437&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java (added)
+++ sling/whiteboard/bdelacretaz/test-rules/src/main/java/org/apache/sling/testing/rules/ServerSideTest.java Wed Sep 16 17:16:26 2015
@@ -0,0 +1,79 @@
+/*
+ * 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.sling.testing.rules;
+
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.rules.ExternalResource;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/** JUnit Rule that executes the current test in a Sling instance, by
+ * 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 {
+
+ private final Class<?> classUnderTest;
+ private final String bundleSymbolicName;
+ private final ClientSideSupport css;
+
+ /** Build a server-side test rule that uses the default test server */
+ ServerSideTest(Class<?> underTest) {
+ this(underTest, null);
+ }
+
+ /** Build a server-side test rule that can use a specific test server */
+ ServerSideTest(Class<?> underTest, String serverSelector) {
+ this.classUnderTest = underTest;
+
+ // Unique and somewhat identifiable name for our test bundle
+ final SimpleDateFormat fmt = new SimpleDateFormat("HH-mm-ss-");
+ bundleSymbolicName = getClass().getSimpleName() + "." + fmt.format(new Date()) + "." + UUID.randomUUID();
+
+ // Try to load our default bundle builder - we don't have it on the server side (see that class for details)
+ ClientSideSupport s = null;
+ try {
+ s = (ClientSideSupport)getClass().getClassLoader().loadClass("org.apache.sling.testing.rules.DefaultClientSideSupport").newInstance();
+ } catch(Exception ignoreWeAreProbablyOnTheServerSide) {
+ }
+ css = s;
+ }
+
+ @Override
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ if(css != null) {
+ final InputStream bundle = css.buildTestBundle(classUnderTest, bundleSymbolicName);
+ css.installBundle(bundle, bundleSymbolicName);
+ try {
+ css.runTests(classUnderTest);
+ } finally {
+ css.uninstallBundle(bundleSymbolicName);
+ }
+ } else {
+ base.evaluate();
+ }
+ }
+ };
+ }
+}
Added: 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=1703437&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java (added)
+++ sling/whiteboard/bdelacretaz/test-rules/src/test/java/org/apache/sling/testing/rules/DummyTest.java Wed Sep 16 17:16:26 2015
@@ -0,0 +1,38 @@
+/*
+ * 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.sling.testing.rules;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.ClassRule;
+import org.junit.Test;
+
+public class DummyTest {
+
+ @ClassRule
+ public static final ServerSideTest t = new ServerSideTest(DummyTest.class);
+
+ @Test
+ public void semiRandomFailure() {
+ assertTrue("Semi-randomly failing, by design", Math.random() < 0.5);
+ }
+
+ @Test
+ public void alwaysPasses() {
+ }
+
+}