View Javadoc

1   /*
2    * $Id: AbstractStreamingCapacityTestCase.java 20056 2010-11-02 23:27:26Z dzapata $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.tcp.integration;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.api.MuleEventContext;
15  import org.mule.api.endpoint.InboundEndpoint;
16  import org.mule.module.client.MuleClient;
17  import org.mule.tck.DynamicPortTestCase;
18  import org.mule.tck.functional.EventCallback;
19  import org.mule.tck.functional.FunctionalStreamingTestComponent;
20  
21  import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
22  import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
23  import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /**
29   * IMPORTANT - DO NOT RUN THIS TEST IN AN IDE WITH LOG LEVEL OF DEBUG. USE INFO TO
30   * SEE DIAGNOSTICS. OTHERWISE THE CONSOLE OUTPUT WILL BE SIMILAR SIZE TO DATA
31   * TRANSFERRED, CAUSING CONFUSNG AND PROBABLY FATAL MEMORY USE.
32   */
33  public abstract class AbstractStreamingCapacityTestCase extends DynamicPortTestCase
34  {
35  
36      public static final long ONE_KB = 1024;
37      public static final long ONE_MB = ONE_KB * ONE_KB;
38      public static final long ONE_GB = ONE_KB * ONE_MB;
39      public static final int MESSAGES = 21;
40  
41      protected final Log logger = LogFactory.getLog(getClass());
42      private long size;
43     
44      public AbstractStreamingCapacityTestCase(long size)
45      {
46          this.size = size;
47      }
48  
49      public void testSend() throws Exception
50      {
51          final CountDownLatch latch = new CountDownLatch(1);
52          final AtomicReference message = new AtomicReference();
53  
54          EventCallback callback = new EventCallback()
55          {
56              public synchronized void eventReceived(MuleEventContext context, Object component)
57              {
58                  try
59                  {
60                      FunctionalStreamingTestComponent ftc = (FunctionalStreamingTestComponent) component;
61                      message.set(ftc.getSummary());
62                      latch.countDown();
63                  }
64                  catch (Exception e)
65                  {
66                      logger.error(e.getMessage(), e);
67                  }
68              }
69          };
70  
71          Object ftc = getComponent("testComponent");
72          assertTrue("FunctionalStreamingTestComponent expected",
73              ftc instanceof FunctionalStreamingTestComponent);
74          assertNotNull(ftc);
75          ((FunctionalStreamingTestComponent) ftc).setEventCallback(callback, size);
76  
77          Runtime runtime = Runtime.getRuntime();
78          runtime.gc(); // i know, i know...
79          long freeStart = runtime.freeMemory();
80          long maxStart = runtime.maxMemory();
81          long timeStart = System.currentTimeMillis();
82  
83          BigInputStream stream = new BigInputStream(size, MESSAGES);
84          MuleClient client = new MuleClient(muleContext);
85          // dynamically get the endpoint to send to
86          client.dispatch(
87              ((InboundEndpoint) client.getMuleContext().getRegistry().lookupObject("testInbound")).getAddress(),
88              new DefaultMuleMessage(stream, muleContext));
89  
90          // if we assume 1MB/sec then we need at least...
91          long pause = Math.max(size / ONE_MB, 60 * 10) + 10;
92          logger.info("Waiting for up to " + pause + " seconds");
93  
94          latch.await(pause, TimeUnit.SECONDS);
95          assertEquals(stream.summary(), message.get());
96  
97          // neither of these memory tests are really reliable, but if we stay with 1.4
98          // i don't
99          // know of anything better.
100         // if these fail in practice i guess we just remove them.
101         long freeEnd = runtime.freeMemory();
102         long delta = freeStart - freeEnd;
103         long timeEnd = System.currentTimeMillis();
104         double speed = size / (double) (timeEnd - timeStart) * 1000 / ONE_MB;
105         logger.info("Transfer speed " + speed + " MB/s (" + size + " B in " + (timeEnd - timeStart) + " ms)");
106 
107         double expectPercent = 10.5; // add a little more wiggle room than 10%, we have seen 10.0x% before
108         double usePercent = 100.0 * delta / size;
109         logger.info("Memory delta " + delta + " B = " + usePercent + "%");
110 
111         String assertMessage = String.format("Expected memory usage to be lower than %f%% but was %f%%",
112             Double.valueOf(expectPercent), Double.valueOf(usePercent));
113         assertTrue(assertMessage, usePercent < expectPercent);
114 
115         long maxEnd = runtime.maxMemory();
116         assertEquals("Max memory shifted", 0, maxEnd - maxStart);
117     }
118 }