Index: plot.sh =================================================================== --- plot.sh (revision 0) +++ plot.sh (revision 0) @@ -0,0 +1,61 @@ +#!/bin/sh +# 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. + +# This is an example Gnuplot script for plotting the performance results +# produced by the Jackrabbit performance test suite. Before you run this +# script you need to preprocess the individual performance reports. + +cat <target/report.html + + + Jackrabbit performance + + +

Jackrabbit performance

+

+HTML + +for dat in */target/*.txt; do + cat "$dat" >>target/`basename "$dat"` +done + +for dat in target/*.txt; do + name=`basename "$dat" .txt` + rows=`grep -v "#" "$dat" | wc -l` + gnuplot <>target/report.html + $name +HTML +done + +cat <>target/report.html +

+ + +HTML + +echo file://`pwd`/target/report.html + Property changes on: plot.sh ___________________________________________________________________ Added: svn:executable + * Index: parent/pom.xml =================================================================== --- parent/pom.xml (revision 0) +++ parent/pom.xml (revision 0) @@ -0,0 +1,111 @@ + + + + + + 4.0.0 + + + + + + + org.apache + apache + 10 + + + + org.apache.jackrabbit.oak + oak-perf-parent + Oak Performance Test Parent + 0.3-SNAPSHOT + pom + + + \d\.\d + .* + 0 + + + + + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + maven-surefire-plugin + + -Xms256m -Xmx512m + false + + + derby.stream.error.file + target/derby.log + + + repo + ${repo} + + + only + ${only} + + + scale + ${scale} + + + + + + + + + + + profiler + + + agentlib + + + + + + + maven-surefire-plugin + + -Xmx512m -XX:MaxPermSize=512m -agentlib:${agentlib} + + + + + + + + + Index: base/src/main/java/org/apache/jackrabbit/oak/performance/SQL2DescendantSearchTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/SQL2DescendantSearchTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/SQL2DescendantSearchTest.java (revision 0) @@ -0,0 +1,35 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.RepositoryException; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; + +/** + * SQL-2 version of the sub-tree performance test. + */ +public class SQL2DescendantSearchTest extends DescendantSearchTest { + + protected Query createQuery(QueryManager manager, int i) + throws RepositoryException { + return manager.createQuery( + "SELECT * FROM [nt:base] AS n WHERE ISDESCENDANTNODE(n, '/testroot') AND testcount=" + i, + "JCR-SQL2"); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/SetPropertyTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/SetPropertyTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/SetPropertyTest.java (revision 0) @@ -0,0 +1,60 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +/** + * Test for measuring the performance of setting a single property and + * saving the change. + */ +public class SetPropertyTest extends AbstractTest { + + private Session session; + + private Node node; + + public void beforeSuite() throws RepositoryException { + session = getRepository().login(getCredentials()); + node = session.getRootNode().addNode("testnode", "nt:unstructured"); + session.save(); + } + + public void beforeTest() throws RepositoryException { + node.setProperty("count", -1); + session.save(); + } + + public void runTest() throws Exception { + for (int i = 0; i < 1000; i++) { + node.setProperty("count", i); + session.save(); + } + } + + public void afterTest() throws RepositoryException { + } + + public void afterSuite() throws RepositoryException { + session.getRootNode().getNode("testnode").remove(); + session.save(); + session.logout(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/LoginLogoutTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/LoginLogoutTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/LoginLogoutTest.java (revision 0) @@ -0,0 +1,46 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Credentials; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +public class LoginLogoutTest extends AbstractTest { + + @Override + public void setUp(Repository repository, Credentials credentials) + throws Exception { + super.setUp(repository, + new SimpleCredentials("admin", "admin".toCharArray())); + } + + public void runTest() throws RepositoryException { + Repository repository = getRepository(); + for (int i = 0; i < 1000; i++) { + Session session = repository.login(getCredentials()); + try { + session.getRootNode(); + } finally { + session.logout(); + } + } + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/AbstractTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/AbstractTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/AbstractTest.java (revision 0) @@ -0,0 +1,213 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.util.LinkedList; +import java.util.List; + +import javax.jcr.Credentials; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +/** + * Abstract base class for individual performance benchmarks. + */ +public abstract class AbstractTest { + + private Repository repository; + + private Credentials credentials; + + private List sessions; + + private List threads; + + private volatile boolean running; + + protected static int getScale(int def) { + int scale = Integer.getInteger("scale", 0); + if (scale == 0) { + scale = def; + } + return scale; + } + + /** + * Prepares this performance benchmark. + * + * @param repository the repository to use + * @param credentials credentials of a user with write access + * @throws Exception if the benchmark can not be prepared + */ + public void setUp(Repository repository, Credentials credentials) + throws Exception { + this.repository = repository; + this.credentials = credentials; + this.sessions = new LinkedList(); + this.threads = new LinkedList(); + + this.running = true; + + beforeSuite(); + } + + /** + * Executes a single iteration of this test. + * + * @return number of milliseconds spent in this iteration + * @throws Exception if an error occurs + */ + public long execute() throws Exception { + beforeTest(); + try { + long start = System.currentTimeMillis(); + runTest(); + return System.currentTimeMillis() - start; + } finally { + afterTest(); + } + } + /** + * Cleans up after this performance benchmark. + * + * @throws Exception if the benchmark can not be cleaned up + */ + public void tearDown() throws Exception { + this.running = false; + for (Thread thread : threads) { + thread.join(); + } + + afterSuite(); + + for (Session session : sessions) { + if (session.isLive()) { + session.logout(); + } + } + + this.threads = null; + this.sessions = null; + this.credentials = null; + this.repository = null; + } + + /** + * Run before any iterations of this test get executed. Subclasses can + * override this method to set up static test content. + * + * @throws Exception if an error occurs + */ + protected void beforeSuite() throws Exception { + } + + protected void beforeTest() throws Exception { + } + + protected abstract void runTest() throws Exception; + + protected void afterTest() throws Exception { + } + + /** + * Run after all iterations of this test have been executed. Subclasses can + * override this method to clean up static test content. + * + * @throws Exception if an error occurs + */ + protected void afterSuite() throws Exception { + } + + protected void failOnRepositoryVersions(String... versions) + throws RepositoryException { + String repositoryVersion = + repository.getDescriptor(Repository.REP_VERSION_DESC); + for (String version : versions) { + if (repositoryVersion.startsWith(version)) { + throw new RepositoryException( + "Unable to run " + getClass().getName() + + " on repository version " + version); + } + } + } + + protected Repository getRepository() { + return repository; + } + + protected Credentials getCredentials() { + return credentials; + } + + /** + * Returns a new reader session that will be automatically closed once + * all the iterations of this test have been executed. + * + * @return reader session + */ + protected Session loginReader() { + try { + Session session = repository.login(); + sessions.add(session); + return session; + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns a new writer session that will be automatically closed once + * all the iterations of this test have been executed. + * + * @return writer session + */ + protected Session loginWriter() { + try { + Session session = repository.login(credentials); + sessions.add(session); + return session; + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + /** + * Adds a background thread that repeatedly executes the given job + * until all the iterations of this test have been executed. + * + * @param job background job + */ + protected void addBackgroundJob(final Runnable job) { + Thread thread = new Thread() { + @Override + public void run() { + while (running) { + job.run(); + } + } + }; + thread.start(); + threads.add(thread); + } + + public String toString() { + String name = getClass().getName(); + return name.substring(name.lastIndexOf('.') + 1); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/UpdateManyChildNodesTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/UpdateManyChildNodesTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/UpdateManyChildNodesTest.java (revision 0) @@ -0,0 +1,62 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +/** + * Test for measuring the performance of adding one extra child node to + * node with {@value #CHILD_COUNT} existing child nodes. + */ +public class UpdateManyChildNodesTest extends AbstractTest { + + private static final int CHILD_COUNT = 10 * 1000; + + private Session session; + + private Node node; + + public void beforeSuite() throws RepositoryException { + session = getRepository().login(getCredentials()); + node = session.getRootNode().addNode("testnode", "nt:unstructured"); + for (int i = 0; i < CHILD_COUNT; i++) { + node.addNode("node" + i, "nt:unstructured"); + } + } + + public void beforeTest() throws RepositoryException { + } + + public void runTest() throws Exception { + node.addNode("onemore", "nt:unstructured"); + session.save(); + } + + public void afterTest() throws RepositoryException { + node.getNode("onemore").remove(); + session.save(); + } + + public void afterSuite() throws RepositoryException { + session.getRootNode().getNode("testnode").remove(); + session.save(); + session.logout(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/SmallFileReadTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/SmallFileReadTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/SmallFileReadTest.java (revision 0) @@ -0,0 +1,74 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.io.InputStream; +import java.util.Calendar; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.NullOutputStream; + +public class SmallFileReadTest extends AbstractTest { + + private static final int FILE_COUNT = 1000; + + private static final int FILE_SIZE = 10; + + private Session session; + + private Node root; + + public void beforeSuite() throws RepositoryException { + session = getRepository().login(getCredentials()); + + root = session.getRootNode().addNode( + "SmallFileReadTest", "nt:folder"); + for (int i = 0; i < FILE_COUNT; i++) { + Node file = root.addNode("file" + i, "nt:file"); + Node content = file.addNode("jcr:content", "nt:resource"); + content.setProperty("jcr:mimeType", "application/octet-stream"); + content.setProperty("jcr:lastModified", Calendar.getInstance()); + content.setProperty( + "jcr:data", new TestInputStream(FILE_SIZE * 1024)); + } + session.save(); + } + + public void runTest() throws Exception { + for (int i = 0; i < FILE_COUNT; i++) { + Node file = root.getNode("file" + i); + Node content = file.getNode("jcr:content"); + InputStream stream = content.getProperty("jcr:data").getStream(); + try { + IOUtils.copy(stream, new NullOutputStream()); + } finally { + stream.close(); + } + } + } + + public void afterSuite() throws RepositoryException { + root.remove(); + session.save(); + session.logout(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/SQL2SearchTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/SQL2SearchTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/SQL2SearchTest.java (revision 0) @@ -0,0 +1,32 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.RepositoryException; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; + +public class SQL2SearchTest extends SimpleSearchTest { + + protected Query createQuery(QueryManager manager, int i) + throws RepositoryException { + return manager.createQuery( + "SELECT * FROM [nt:base] WHERE testcount=" + i, + "JCR-SQL2"); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/LoginTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/LoginTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/LoginTest.java (revision 0) @@ -0,0 +1,49 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Credentials; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +public class LoginTest extends AbstractTest { + + private final Session[] sessions = new Session[1000]; + + @Override + public void setUp(Repository repository, Credentials credentials) + throws Exception { + super.setUp(repository, + new SimpleCredentials("admin", "admin".toCharArray())); + } + + public void runTest() throws RepositoryException { + for (int i = 0; i < sessions.length; i++) { + sessions[i] = getRepository().login(getCredentials(), "default"); + } + + } + + public void afterTest() throws RepositoryException { + for (int i = 0; i < sessions.length; i++) { + sessions[i].logout(); + } + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/TestInputStream.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/TestInputStream.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/TestInputStream.java (revision 0) @@ -0,0 +1,71 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.io.InputStream; +import java.util.Random; + +/** + * An input stream that returns a given number of dummy data. The returned + * data is designed to be non-compressible to prevent possible compression + * mechanisms from affecting performance measurements. + */ +class TestInputStream extends InputStream { + + private final int n; + + private int i; + + /** + * Source of the random stream of bytes. No fixed seed is used to + * prevent a solution like the Jackrabbit data store from using just + * a single storage location for multiple streams. + */ + private final Random random = new Random(); + + public TestInputStream(int length) { + n = length; + i = 0; + } + + @Override + public int read() { + if (i < n) { + i++; + byte[] b = new byte[1]; + random.nextBytes(b); + return b[0]; + } else { + return -1; + } + } + + @Override + public int read(byte[] b, int off, int len) { + if (i < n) { + byte[] data = new byte[Math.min(len, n - i)]; + random.nextBytes(data); + System.arraycopy(data, 0, b, off, data.length); + i += data.length; + return data.length; + } else { + return -1; + } + } + + +} \ No newline at end of file Index: base/src/main/java/org/apache/jackrabbit/oak/performance/ConcurrentReadTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/ConcurrentReadTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/ConcurrentReadTest.java (revision 0) @@ -0,0 +1,96 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.util.Random; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +/** + * Test case that traverses 10k unstructured nodes (100x100) while 50 concurrent + * readers randomly access nodes from within this tree. + */ +public class ConcurrentReadTest extends AbstractTest { + + protected static final int NODE_COUNT = 100; + + private static final int READER_COUNT = getScale(20); + + private Session session; + + protected Node root; + + public void beforeSuite() throws Exception { + session = getRepository().login( + new SimpleCredentials("admin", "admin".toCharArray())); + root = session.getRootNode().addNode("testroot", "nt:unstructured"); + for (int i = 0; i < NODE_COUNT; i++) { + Node node = root.addNode("node" + i, "nt:unstructured"); + for (int j = 0; j < NODE_COUNT; j++) { + node.addNode("node" + j, "nt:unstructured"); + } + session.save(); + } + + for (int i = 0; i < READER_COUNT; i++) { + addBackgroundJob(new Reader()); + } + } + + private class Reader implements Runnable { + + private Session session; + + private final Random random = new Random(); + + public void run() { + + try { + session = getRepository().login( + new SimpleCredentials("admin", "admin".toCharArray())); + int i = random.nextInt(NODE_COUNT); + int j = random.nextInt(NODE_COUNT); + session.getRootNode() + .getNode("testroot/node" + i + "/node" + j); + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + } + + public void runTest() throws Exception { + Reader reader = new Reader(); + for (int i = 0; i < 1000; i++) { + reader.run(); + } + } + + public void afterSuite() throws Exception { + for (int i = 0; i < NODE_COUNT; i++) { + root.getNode("node" + i).remove(); + session.save(); + } + + root.remove(); + session.save(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/SimpleSearchTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/SimpleSearchTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/SimpleSearchTest.java (revision 0) @@ -0,0 +1,78 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; + +public class SimpleSearchTest extends AbstractTest { + + private static final int NODE_COUNT = 100; + + private Session session; + + private Node root; + + protected Query createQuery(QueryManager manager, int i) + throws RepositoryException { + return manager.createQuery("//*[@testcount=" + i + "]", Query.XPATH); + } + + public void beforeSuite() throws RepositoryException { + session = getRepository().login(getCredentials()); + + root = session.getRootNode().addNode("testroot", "nt:unstructured"); + for (int i = 0; i < NODE_COUNT; i++) { + Node node = root.addNode("node" + i, "nt:unstructured"); + for (int j = 0; j < NODE_COUNT; j++) { + Node child = node.addNode("node" + j, "nt:unstructured"); + child.setProperty("testcount", j); + } + session.save(); + } + } + + public void runTest() throws Exception { + QueryManager manager = session.getWorkspace().getQueryManager(); + for (int i = 0; i < NODE_COUNT; i++) { + Query query = createQuery(manager, i); + NodeIterator iterator = query.execute().getNodes(); + while (iterator.hasNext()) { + Node node = iterator.nextNode(); + if (node.getProperty("testcount").getLong() != i) { + throw new Exception("Invalid test result: " + node.getPath()); + } + } + } + } + + public void afterSuite() throws RepositoryException { + for (int i = 0; i < NODE_COUNT; i++) { + root.getNode("node" + i).remove(); + session.save(); + } + + root.remove(); + session.save(); + session.logout(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/ReadPropertyTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/ReadPropertyTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/ReadPropertyTest.java (revision 0) @@ -0,0 +1,57 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.Session; + +/** + * ReadPropertyTest implements a performance test, which reads + * three properties: one with a jcr prefix, one with the empty prefix and a + * third one, which does not exist. + */ +public class ReadPropertyTest extends AbstractTest { + + private Session session; + + private Node root; + + @Override + protected void beforeSuite() throws Exception { + session = getRepository().login(getCredentials()); + root = session.getRootNode().addNode( + getClass().getSimpleName(), "nt:unstructured"); + root.setProperty("property", "value"); + session.save(); + } + + @Override + protected void runTest() throws Exception { + for (int i = 0; i < 10000; i++) { + root.getProperty("jcr:primaryType"); + root.getProperty("property"); + root.hasProperty("does-not-exist"); + } + } + + @Override + protected void afterSuite() throws Exception { + root.remove(); + session.save(); + session.logout(); + } +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/SmallFileWriteTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/SmallFileWriteTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/SmallFileWriteTest.java (revision 0) @@ -0,0 +1,61 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.util.Calendar; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +public class SmallFileWriteTest extends AbstractTest { + + private static final int FILE_COUNT = 100; + + private static final int FILE_SIZE = 10; + + private Session session; + + private Node root; + + public void beforeSuite() throws RepositoryException { + session = loginWriter(); + } + + public void beforeTest() throws RepositoryException { + root = session.getRootNode().addNode("SmallFileWriteTest", "nt:folder"); + session.save(); + } + + public void runTest() throws Exception { + for (int i = 0; i < FILE_COUNT; i++) { + Node file = root.addNode("file" + i, "nt:file"); + Node content = file.addNode("jcr:content", "nt:resource"); + content.setProperty("jcr:mimeType", "application/octet-stream"); + content.setProperty("jcr:lastModified", Calendar.getInstance()); + content.setProperty( + "jcr:data", new TestInputStream(FILE_SIZE * 1024)); + } + session.save(); + } + + public void afterTest() throws RepositoryException { + root.remove(); + session.save(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/CreateManyChildNodesTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/CreateManyChildNodesTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/CreateManyChildNodesTest.java (revision 0) @@ -0,0 +1,53 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +/** + * Test for measuring the performance of creating a node with + * {@value #CHILD_COUNT} child nodes. + */ +public class CreateManyChildNodesTest extends AbstractTest { + + private static final int CHILD_COUNT = 10 * 1000; + + private Session session; + + public void beforeSuite() throws RepositoryException { + session = loginWriter(); + } + + public void beforeTest() throws RepositoryException { + } + + public void runTest() throws Exception { + Node node = session.getRootNode().addNode("testnode", "nt:unstructured"); + for (int i = 0; i < CHILD_COUNT; i++) { + node.addNode("node" + i, "nt:unstructured"); + } + session.save(); + } + + public void afterTest() throws RepositoryException { + session.getRootNode().getNode("testnode").remove(); + session.save(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/AbstractPerformanceTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/AbstractPerformanceTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/AbstractPerformanceTest.java (revision 0) @@ -0,0 +1,145 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.regex.Pattern; + +import javax.jcr.Credentials; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.SimpleCredentials; + +import org.apache.commons.io.output.FileWriterWithEncoding; +import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; +import org.apache.jackrabbit.oak.jcr.RepositoryImpl; + +public abstract class AbstractPerformanceTest { + + private final int warmup = 1; + + private final int runtime = 10; + + private final Credentials credentials = new SimpleCredentials("admin", + "admin".toCharArray()); + + private final Pattern microKernelPattern = Pattern.compile(System + .getProperty("mk", ".*")); + private final Pattern testPattern = Pattern.compile(System.getProperty( + "only", ".*")); + + protected void testPerformance(String name, String microKernel) + throws Exception { + + runTest(new LoginTest(), name, microKernel); + runTest(new LoginLogoutTest(), name, microKernel); + runTest(new ReadPropertyTest(), name, microKernel); + runTest(new SetPropertyTest(), name, microKernel); + runTest(new SmallFileReadTest(), name, microKernel); + runTest(new SmallFileWriteTest(), name, microKernel); + runTest(new ConcurrentReadTest(), name, microKernel); + runTest(new ConcurrentReadWriteTest(), name, microKernel); + runTest(new SimpleSearchTest(), name, microKernel); + runTest(new SQL2SearchTest(), name, microKernel); + runTest(new DescendantSearchTest(), name, microKernel); + runTest(new SQL2DescendantSearchTest(), name, microKernel); + runTest(new CreateManyChildNodesTest(), name, microKernel); + runTest(new UpdateManyChildNodesTest(), name, microKernel); + runTest(new TransientManyChildNodesTest(), name, microKernel); + + } + + private void runTest(AbstractTest test, String name, String microKernel) { + if (microKernelPattern.matcher(microKernel).matches() + && testPattern.matcher(test.toString()).matches()) { + + RepositoryImpl repository; + try { + repository = createRepository(microKernel); + + // Run the test + DescriptiveStatistics statistics = runTest(test, repository); + if (statistics.getN() > 0) { + writeReport(test.toString(), name, microKernel, statistics); + } + } catch (RepositoryException re) { + re.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private DescriptiveStatistics runTest(AbstractTest test, + Repository repository) throws Exception { + DescriptiveStatistics statistics = new DescriptiveStatistics(); + + test.setUp(repository, credentials); + try { + // Run a few iterations to warm up the system + long warmupEnd = System.currentTimeMillis() + warmup * 1000; + while (System.currentTimeMillis() < warmupEnd) { + test.execute(); + } + + // Run test iterations, and capture the execution times + long runtimeEnd = System.currentTimeMillis() + runtime * 1000; + while (System.currentTimeMillis() < runtimeEnd) { + statistics.addValue(test.execute()); + } + } finally { + test.tearDown(); + } + + return statistics; + } + + private void writeReport(String test, String name, String microKernel, + DescriptiveStatistics statistics) throws IOException { + File report = new File("target", test + "-" + microKernel + ".txt"); + + boolean needsPrefix = !report.exists(); + PrintWriter writer = new PrintWriter(new FileWriterWithEncoding(report, + "UTF-8", true)); + try { + if (needsPrefix) { + writer.format( + "# %-34.34s min 10%% 50%% 90%% max%n", + test); + } + + writer.format("%-36.36s %6.0f %6.0f %6.0f %6.0f %6.0f%n", + name, statistics.getMin(), statistics.getPercentile(10.0), + statistics.getPercentile(50.0), + statistics.getPercentile(90.0), statistics.getMax()); + } finally { + writer.close(); + } + } + + protected RepositoryImpl createRepository(String microKernel) + throws RepositoryException { + + // TODO: depending on the microKernel string a particular repository + // with that MK must be returned + + return new RepositoryImpl(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/ConcurrentReadWriteTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/ConcurrentReadWriteTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/ConcurrentReadWriteTest.java (revision 0) @@ -0,0 +1,63 @@ +/* + * 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.jackrabbit.oak.performance; + +import java.util.Random; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +/** + * A {@link ConcurrentReadTest} with a single writer thread that continuously + * updates the nodes being accessed by the readers. + */ +public class ConcurrentReadWriteTest extends ConcurrentReadTest { + + public void beforeSuite() throws Exception { + super.beforeSuite(); + + addBackgroundJob(new Writer()); + } + + private class Writer implements Runnable { + + private Session session; + + private final Random random = new Random(); + + private long count = 0; + + public void run() { + try { + session = getRepository().login( + new SimpleCredentials("admin", "admin".toCharArray())); + int i = random.nextInt(NODE_COUNT); + int j = random.nextInt(NODE_COUNT); + Node node = session.getRootNode().getNode( + "testroot/node" + i + "/node" + j); + node.setProperty("count", count++); + session.save(); + } catch (RepositoryException e) { + throw new RuntimeException(e); + } + } + + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/TransientManyChildNodesTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/TransientManyChildNodesTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/TransientManyChildNodesTest.java (revision 0) @@ -0,0 +1,64 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +/** + * Test for measuring the performance of {@value #ITERATIONS} iterations of + * transiently adding and removing a child node to a node that already has + * {@value #CHILD_COUNT} existing child nodes. + */ +public class TransientManyChildNodesTest extends AbstractTest { + + private static final int CHILD_COUNT = 10 * 1000; + + private static final int ITERATIONS = 1000; + + private Session session; + + private Node node; + + public void beforeSuite() throws RepositoryException { + session = getRepository().login(getCredentials()); + node = session.getRootNode().addNode("testnode", "nt:unstructured"); + for (int i = 0; i < CHILD_COUNT; i++) { + node.addNode("node" + i, "nt:unstructured"); + } + } + + public void beforeTest() throws RepositoryException { + } + + public void runTest() throws Exception { + for (int i = 0; i < ITERATIONS; i++) { + node.addNode("onemore", "nt:unstructured").remove(); + } + } + + public void afterTest() throws RepositoryException { + } + + public void afterSuite() throws RepositoryException { + session.getRootNode().getNode("testnode").remove(); + session.save(); + session.logout(); + } + +} Index: base/src/main/java/org/apache/jackrabbit/oak/performance/DescendantSearchTest.java =================================================================== --- base/src/main/java/org/apache/jackrabbit/oak/performance/DescendantSearchTest.java (revision 0) +++ base/src/main/java/org/apache/jackrabbit/oak/performance/DescendantSearchTest.java (revision 0) @@ -0,0 +1,81 @@ +/* + * 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.jackrabbit.oak.performance; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; + +/** + * Performance test to check performance of queries on sub-trees. + */ +public class DescendantSearchTest extends AbstractTest { + + private static final int NODE_COUNT = 100; + + private Session session; + + private Node root; + + protected Query createQuery(QueryManager manager, int i) + throws RepositoryException { + return manager.createQuery("/jcr:root/testroot//element(*,nt:base)[@testcount=" + i + "]", Query.XPATH); + } + + public void beforeSuite() throws RepositoryException { + session = getRepository().login(getCredentials()); + + root = session.getRootNode().addNode("testroot", "nt:unstructured"); + for (int i = 0; i < NODE_COUNT; i++) { + Node node = root.addNode("node" + i, "nt:unstructured"); + for (int j = 0; j < NODE_COUNT; j++) { + Node child = node.addNode("node" + j, "nt:unstructured"); + child.setProperty("testcount", j); + } + session.save(); + } + } + + public void runTest() throws Exception { + QueryManager manager = session.getWorkspace().getQueryManager(); + for (int i = 0; i < NODE_COUNT; i++) { + Query query = createQuery(manager, i); + NodeIterator iterator = query.execute().getNodes(); + while (iterator.hasNext()) { + Node node = iterator.nextNode(); + if (node.getProperty("testcount").getLong() != i) { + throw new Exception("Invalid test result: " + node.getPath()); + } + } + } + } + + public void afterSuite() throws RepositoryException { + for (int i = 0; i < NODE_COUNT; i++) { + root.getNode("node" + i).remove(); + session.save(); + } + + root.remove(); + session.save(); + session.logout(); + } + +} Index: base/pom.xml =================================================================== --- base/pom.xml (revision 0) +++ base/pom.xml (revision 0) @@ -0,0 +1,83 @@ + + + + + + 4.0.0 + + + org.apache.jackrabbit.oak + oak-perf-parent + 1-SNAPSHOT + ../parent/pom.xml + + + oak-perf-base + Oak Performance Test Utilities + + + + javax.jcr + jcr + 2.0 + + + org.apache.commons + commons-math + 2.0 + + + org.apache.jackrabbit + oak-jcr + 0.3-SNAPSHOT + provided + + + + + commons-io + commons-io + 1.4 + + + org.slf4j + slf4j-api + 1.5.8 + + + org.slf4j + slf4j-nop + 1.5.8 + + + org.testng + testng + jdk15 + 5.8 + + + + + Index: pom.xml =================================================================== --- pom.xml (revision 0) +++ pom.xml (revision 0) @@ -0,0 +1,47 @@ + + + + + + 4.0.0 + + + + + + + org.apache.jackrabbit.oak + oak-perf-parent + 1-SNAPSHOT + parent/pom.xml + + + oak-perf + Oak Performance Tests + pom + + + parent + base + oak03 + + + Index: README.txt =================================================================== --- README.txt (revision 0) +++ README.txt (revision 0) @@ -0,0 +1,85 @@ +--------------------------------- +Oak Performance Test Suite +--------------------------------- + +This directory contains a simple performance test suite that can be +extended for ongoing Oak versions and micro kernels. Use the following +command to run this test suite: + + mvn clean install + +Note that the test suite will take more than an hour to complete, and to +avoid distorting the results you should avoid putting any extra load on +the computer while the test suite is running. + +The results are stored as oak*/target/*.txt report files and can +be combined into an HTML report by running the following command on a +(Unix) system where gnuplot is installed. + + sh plot.sh + +Mac OS X note : if you want to execute the above script, you will need +to install gnuplot and imagemagick2-svg from the Fink project. For +more information : http://finkproject.org + +Selecting which tests to run +---------------------------- + +The -Donly command line parameter allows you to specify a regexp for +selecting which performance test cases to run. To run a single test +case, use a command like this: + + mvn clean install -Donly=ConcurrentReadTest + +To run all concurrency tests, use: + + mvn clean install -Donly=Concurrent.*Test + +Selecting which micro kernel to test +---------------------------------------------------------- + +The -Dmk command line parameter allows you to specify a regexp for +selecting the micro kernel and configurations against which the +performance tests are run. The default setting selects only the default +micro kernel: + + mvn clean install -Dmk=\d\.\d + +To run the tests against all included configurations, use: + + mvn clean install -Dmk=.* + +Using a profiler +---------------- + +To enable a profiler, use the -Dagentlib= command line pameter: + + mvn clean install -Dagentlib=hprof=cpu=samples,depth=10 + +Adding a new performance test +----------------------------- + +The tests run by this performance test suite are listed in the +testPerformance() method of the AbstractPerformanceTest class in +the org.apache.jackrabbit.oak.performance package of the oak-perf-base +component that you can find in the ./base directory. + +Each test is a subclass of the AbstractTest class in that same package, +and you need to implement at least the abstract runTest() method when +creating a new test. The runTest() method should contain the code whose +performance you want to measure. For best measurement results the method +should normally take something between 0.1 to 10 seconds to execute, so +you may need to add a constant-size loop around your code like is done +for example in the LoginTest class. The test suite compares relative +performance between different Oak versions, so the absolute time +taken by the test method is irrelevant. + +Many performance tests need some setup and teardown code for things like +building the content tree against which the test is being run. Such work +should not be included in the runTest() method to prevent affecting the +performance measurements. Instead you can override the before/afterTest() +and before/afterSuite() methods that get called respectively before and +after each individual test iteration and the entire test suite. See for +example the SetPropertyTest class for an example of how these methods +are best used. + Index: oak03/src/test/java/org/apache/jackrabbit/oak/performance/PerformanceTest.java =================================================================== --- oak03/src/test/java/org/apache/jackrabbit/oak/performance/PerformanceTest.java (revision 0) +++ oak03/src/test/java/org/apache/jackrabbit/oak/performance/PerformanceTest.java (revision 0) @@ -0,0 +1,29 @@ +/* + * 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.jackrabbit.oak.performance; + +import org.apache.jackrabbit.oak.performance.AbstractPerformanceTest; +import org.testng.annotations.Test; + +public class PerformanceTest extends AbstractPerformanceTest { + + @Test + public void testPerformance() throws Exception { + testPerformance("0.3", "default"); + testPerformance("0.3", "other_mk"); + } +} Index: oak03/pom.xml =================================================================== --- oak03/pom.xml (revision 0) +++ oak03/pom.xml (revision 0) @@ -0,0 +1,64 @@ + + + + + + 4.0.0 + + + org.apache.jackrabbit.oak + oak-perf-parent + 1-SNAPSHOT + ../parent/pom.xml + + + oak-perf-oak03 + Oak 0.3 Performance Test + + + + org.apache.jackrabbit.oak + oak-perf-base + ${project.version} + test + + + javax.jcr + jcr + 2.0 + test + + + org.apache.jackrabbit + oak-jcr + 0.3-SNAPSHOT + provided + + + + + +