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


Reply via email to