Author: hadrian Date: Tue Jul 17 20:23:12 2012 New Revision: 1362634 URL: http://svn.apache.org/viewvc?rev=1362634&view=rev Log: CAMEL-5443. Added a simple test to benchmark performance
Added: camel/trunk/tests/camel-itest-performance/src/main/java/ camel/trunk/tests/camel-itest-performance/src/main/java/org/ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/EchoTestComponent.java (with props) camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/PerformanceTestComponent.java (with props) camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/echo camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/test-perf camel/trunk/tests/camel-itest-performance/src/test/java/org/apache/camel/tests/performance/ProducerCacheHitsTest.java (with props) Modified: camel/trunk/tests/camel-itest-performance/src/test/resources/log4j.properties Added: camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/EchoTestComponent.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/EchoTestComponent.java?rev=1362634&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/EchoTestComponent.java (added) +++ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/EchoTestComponent.java Tue Jul 17 20:23:12 2012 @@ -0,0 +1,80 @@ +/** + * 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.camel.tests.component; + +import java.util.Map; + +import org.apache.camel.AsyncCallback; +import org.apache.camel.AsyncProcessor; +import org.apache.camel.Component; +import org.apache.camel.Consumer; +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultComponent; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.impl.DefaultProducer; + +public class EchoTestComponent extends DefaultComponent { + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + Endpoint endpoint = new EchoEndpoint(uri, this); + setProperties(endpoint, parameters); + return endpoint; + } + + private final class EchoEndpoint extends DefaultEndpoint { + public EchoEndpoint(String uri, Component component) { + super(uri, component); + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + // Component only supports Producers + return null; + } + + @Override + public Producer createProducer() throws Exception { + return new EchoProducer(this); + } + + @Override + public boolean isSingleton() { + return false; + } + } + + private final class EchoProducer extends DefaultProducer implements AsyncProcessor { + public EchoProducer(Endpoint endpoint) { + super(endpoint); + } + + @Override + public void process(Exchange exchange) throws Exception { + // do nothing, echo is implicit + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + // do nothing, echo is implicit + return true; + } + } +} \ No newline at end of file Propchange: camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/EchoTestComponent.java ------------------------------------------------------------------------------ svn:eol-style = native Added: camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/PerformanceTestComponent.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/PerformanceTestComponent.java?rev=1362634&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/PerformanceTestComponent.java (added) +++ camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/PerformanceTestComponent.java Tue Jul 17 20:23:12 2012 @@ -0,0 +1,149 @@ +/** + * 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.camel.tests.component; + +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; + +import org.apache.camel.AsyncCallback; +import org.apache.camel.AsyncProcessor; +import org.apache.camel.Component; +import org.apache.camel.Consumer; +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultComponent; +import org.apache.camel.impl.DefaultConsumer; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.impl.DefaultProducer; +import org.apache.camel.util.ExchangeHelper; +import org.apache.camel.util.StopWatch; + +public class PerformanceTestComponent extends DefaultComponent { + static public final String HEADER_THREADS = "CamelPerfThreads"; + static public final String HEADER_ITERATIONS = "CamelPerfIterations"; + + static private final int DEFAULT_THREADS = 8; + static private final int DEFAULT_ITERATIONS = 100; + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + Endpoint endpoint = new PerformanceTestEndpoint(uri, this); + setProperties(endpoint, parameters); + return endpoint; + } + + public static int getHeaderValue(Exchange exchange, String header) { + Integer value = exchange.getContext().getTypeConverter().convertTo(Integer.class, exchange, exchange.getIn().getHeader(header)); + return value != null ? value + : header.equals(HEADER_THREADS) ? DEFAULT_THREADS + : header.equals(HEADER_ITERATIONS) ? DEFAULT_ITERATIONS : 0; + } + + private final class PerformanceTestEndpoint extends DefaultEndpoint { + private PerformanceTestConsumer consumer; + + public PerformanceTestEndpoint(String uri, Component component) { + super(uri, component); + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + synchronized (this) { + if (consumer != null && processor != consumer.getProcessor()) { + throw new Exception("PerformanceTestEndpoint doesn not support multiple consumers per Endpoint"); + } + consumer = new PerformanceTestConsumer(this, processor); + } + return consumer; + } + + @Override + public Producer createProducer() throws Exception { + return new PerformanceTestProducer(this); + } + + @Override + public boolean isSingleton() { + return true; + } + + public Consumer getConsumer() { + return consumer; + } + } + + private final class PerformanceTestConsumer extends DefaultConsumer { + public PerformanceTestConsumer(Endpoint endpoint, Processor processor) { + super(endpoint, processor); + } + } + + private final class PerformanceTestProducer extends DefaultProducer implements AsyncProcessor { + public PerformanceTestProducer(Endpoint endpoint) { + super(endpoint); + } + + @Override + public void process(final Exchange exchange) throws Exception { + final int count = getHeaderValue(exchange, HEADER_ITERATIONS); + final int threads = getHeaderValue(exchange, HEADER_THREADS); + PerformanceTestEndpoint endpoint = (PerformanceTestEndpoint)getEndpoint(); + if (endpoint != null) { + final DefaultConsumer consumer = (DefaultConsumer)endpoint.getConsumer(); + ExecutorService executor = exchange.getContext().getExecutorServiceManager().newFixedThreadPool(this, "perf", threads); + CompletionService<Exchange> tasks = new ExecutorCompletionService<Exchange>(executor); + + // StopWatch watch = new StopWatch(); // if we want to clock how long it takes + for (int i = 0; i < count; i++) { + tasks.submit(new Callable<Exchange>() { + @Override + public Exchange call() throws Exception { + Exchange exch = ExchangeHelper.createCopy(exchange, false); + try { + consumer.getProcessor().process(exch); + } catch (final Exception e) { + exch.setException(e); + } + return exch; + } + }); + } + + for (int i = 0; i < count; i++) { + // Future<Exchange> result = tasks.take(); + tasks.take(); // wait for all exchanges to complete + } + } + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + try { + this.process(exchange); + } catch (Exception e) { + exchange.setException(e); + } + callback.done(true); + return true; + } + } +} \ No newline at end of file Propchange: camel/trunk/tests/camel-itest-performance/src/main/java/org/apache/camel/tests/component/PerformanceTestComponent.java ------------------------------------------------------------------------------ svn:eol-style = native Added: camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/echo URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/echo?rev=1362634&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/echo (added) +++ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/echo Tue Jul 17 20:23:12 2012 @@ -0,0 +1,17 @@ +# 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. +# + +class=org.apache.camel.tests.component.EchoTestComponent Added: camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/test-perf URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/test-perf?rev=1362634&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/test-perf (added) +++ camel/trunk/tests/camel-itest-performance/src/main/resources/META-INF/services/org/apache/camel/component/test-perf Tue Jul 17 20:23:12 2012 @@ -0,0 +1,17 @@ +# 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. +# + +class=org.apache.camel.tests.component.PerformanceTestComponent Added: camel/trunk/tests/camel-itest-performance/src/test/java/org/apache/camel/tests/performance/ProducerCacheHitsTest.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-performance/src/test/java/org/apache/camel/tests/performance/ProducerCacheHitsTest.java?rev=1362634&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-performance/src/test/java/org/apache/camel/tests/performance/ProducerCacheHitsTest.java (added) +++ camel/trunk/tests/camel-itest-performance/src/test/java/org/apache/camel/tests/performance/ProducerCacheHitsTest.java Tue Jul 17 20:23:12 2012 @@ -0,0 +1,103 @@ +/** + * 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.camel.tests.performance; + +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.camel.tests.component.PerformanceTestComponent; +import org.apache.camel.util.StopWatch; +import org.junit.Test; + + +public class ProducerCacheHitsTest extends CamelTestSupport { + private static final String SMALL_MESSAGE = "message"; + private static final DecimalFormat FORMAT = new DecimalFormat("#.##"); + + @Test + public void testRepeatProcessing() throws Exception { + MockEndpoint data = getMandatoryEndpoint("mock:results", MockEndpoint.class); + data.expectedMessageCount(4 * 7); + + for (int iter = 10; iter <= 10000; iter *= 10) { + for (int t = 2; t <= 128; t *= 2) { + runTest("test-perf:endpoint", SMALL_MESSAGE, iter, t); + } + } + + data.assertIsSatisfied(); + for (Exchange ex : data.getExchanges()) { + TestResult r = ex.getIn().getBody(TestResult.class); + + log.info(r.toString()); + + } + } + + protected Object runTest(String uri, String body, int iterations, int threads) { + Map<String, Object> headers = new HashMap<String, Object>(); + headers.put(PerformanceTestComponent.HEADER_ITERATIONS, iterations); + headers.put(PerformanceTestComponent.HEADER_THREADS, threads); + + StopWatch watch = new StopWatch(); + Object result = template.requestBodyAndHeaders(uri, body, headers); + template.sendBody("mock:results", new TestResult(uri, iterations, threads, watch.stop())); + return result; + } + + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from("test-perf:endpoint").to("echo:echo"); + } + }; + } + + public final class TestResult { + public String uri; + public int iterations; + public int threads; + public long time; + + public TestResult(String uri, int iterations, int threads, long time) { + this.uri = uri; + this.iterations = iterations; + this.threads = threads; + this.time = time; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + sb.append(FORMAT.format(1000.0 * iterations / time)); + sb.append(" /s], "); + sb.append(uri); + sb.append(", "); + sb.append(iterations); + sb.append(", "); + sb.append(threads); + sb.append(", "); + sb.append(time); + return sb.toString(); + } + } +} \ No newline at end of file Propchange: camel/trunk/tests/camel-itest-performance/src/test/java/org/apache/camel/tests/performance/ProducerCacheHitsTest.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: camel/trunk/tests/camel-itest-performance/src/test/resources/log4j.properties URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-performance/src/test/resources/log4j.properties?rev=1362634&r1=1362633&r2=1362634&view=diff ============================================================================== --- camel/trunk/tests/camel-itest-performance/src/test/resources/log4j.properties (original) +++ camel/trunk/tests/camel-itest-performance/src/test/resources/log4j.properties Tue Jul 17 20:23:12 2012 @@ -18,9 +18,9 @@ # # The logging properties used during tests.. # -log4j.rootLogger=INFO, out +log4j.rootLogger=INFO, stdout -# Use the following line to turn on debug output for camel +# Use the following line to turn on debug output fmsg)(or camel #log4j.logger.org.apache.camel=DEBUG l# CONSOLE appender not used by default