View Javadoc

1   /*
2    * $Id: AbstractStreamingCapacityTestCase.java 22450 2011-07-19 08:20:41Z dirk.olmes $
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.AbstractServiceAndFlowTestCase;
18  import org.mule.tck.functional.EventCallback;
19  import org.mule.tck.functional.FunctionalStreamingTestComponent;
20  
21  import java.util.concurrent.CountDownLatch;
22  import java.util.concurrent.TimeUnit;
23  import java.util.concurrent.atomic.AtomicReference;
24  
25  import org.junit.Test;
26  
27  import static org.junit.Assert.assertEquals;
28  import static org.junit.Assert.assertNotNull;
29  import static org.junit.Assert.assertTrue;
30  
31  /**
32   * IMPORTANT - DO NOT RUN THIS TEST IN AN IDE WITH LOG LEVEL OF DEBUG. USE INFO TO
33   * SEE DIAGNOSTICS. OTHERWISE THE CONSOLE OUTPUT WILL BE SIMILAR SIZE TO DATA
34   * TRANSFERRED, CAUSING CONFUSNG AND PROBABLY FATAL MEMORY USE.
35   */
36  public abstract class AbstractStreamingCapacityTestCase extends AbstractServiceAndFlowTestCase
37  {
38      public static final long ONE_KB = 1024;
39      public static final long ONE_MB = ONE_KB * ONE_KB;
40      public static final long ONE_GB = ONE_KB * ONE_MB;
41      public static final int MESSAGES = 21;
42  
43      private long size;
44  
45      public AbstractStreamingCapacityTestCase(ConfigVariant variant, String configResources, long size)
46      {
47          super(variant, configResources);
48          this.size = size;
49      }
50  
51      @Test
52      public void testSend() throws Exception
53      {
54          final CountDownLatch latch = new CountDownLatch(1);
55          final AtomicReference<String> message = new AtomicReference<String>();
56  
57          EventCallback callback = new EventCallback()
58          {
59              @Override
60              public synchronized void eventReceived(MuleEventContext context, Object component)
61              {
62                  try
63                  {
64                      FunctionalStreamingTestComponent ftc = (FunctionalStreamingTestComponent) component;
65                      message.set(ftc.getSummary());
66                      latch.countDown();
67                  }
68                  catch (Exception e)
69                  {
70                      logger.error(e.getMessage(), e);
71                  }
72              }
73          };
74  
75          Object ftc = getComponent("testComponent");
76          assertTrue("FunctionalStreamingTestComponent expected",
77              ftc instanceof FunctionalStreamingTestComponent);
78          assertNotNull(ftc);
79          ((FunctionalStreamingTestComponent) ftc).setEventCallback(callback, size);
80  
81          Runtime runtime = Runtime.getRuntime();
82          runtime.gc(); // i know, i know...
83          long freeStart = runtime.freeMemory();
84          long maxStart = runtime.maxMemory();
85          long timeStart = System.currentTimeMillis();
86  
87          BigInputStream stream = new BigInputStream(size, MESSAGES);
88          MuleClient client = new MuleClient(muleContext);
89          // dynamically get the endpoint to send to
90          client.dispatch(
91              ((InboundEndpoint) client.getMuleContext().getRegistry().lookupObject("testInbound")).getAddress(),
92              new DefaultMuleMessage(stream, muleContext));
93  
94          // if we assume 1MB/sec then we need at least...
95          long pause = Math.max(size / ONE_MB, 60 * 10) + 10;
96          logger.info("Waiting for up to " + pause + " seconds");
97  
98          latch.await(pause, TimeUnit.SECONDS);
99          assertEquals(stream.summary(), message.get());
100 
101         // neither of these memory tests are really reliable, but if we stay with 1.4
102         // i don't
103         // know of anything better.
104         // if these fail in practice i guess we just remove them.
105         long freeEnd = runtime.freeMemory();
106         long delta = freeStart - freeEnd;
107         long timeEnd = System.currentTimeMillis();
108         double speed = size / (double) (timeEnd - timeStart) * 1000 / ONE_MB;
109         logger.info("Transfer speed " + speed + " MB/s (" + size + " B in " + (timeEnd - timeStart) + " ms)");
110 
111         double expectPercent = 10.5; // add a little more wiggle room than 10%, we have seen 10.0x% before
112         double usePercent = 100.0 * delta / size;
113         logger.info("Memory delta " + delta + " B = " + usePercent + "%");
114 
115         String assertMessage = String.format("Expected memory usage to be lower than %f%% but was %f%%",
116             Double.valueOf(expectPercent), Double.valueOf(usePercent));
117         assertTrue(assertMessage, usePercent < expectPercent);
118 
119         long maxEnd = runtime.maxMemory();
120         assertEquals("Max memory shifted", 0, maxEnd - maxStart);
121     }
122 }