/* * * Copyright (c) void.fm * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * Neither the name void.fm nor the names of its contributors may be * used to endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ package etm.core.monitor; import etm.core.aggregation.Aggregate; import etm.core.aggregation.ExecutionAggregate; import etm.core.renderer.MeasurementRenderer; import junit.framework.TestCase; import etm.core.TestHelper; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Concurrency tests for flat monitor. * * @author void.fm * @version $Revision$ */ public class ConcurrentFlatMonitorTest extends TestCase { protected EtmMonitor monitor; private final Object lock = new Object(); private final List allPoints = new ArrayList(); private int running; /** * tests two points with multiple threads. * * @throws Exception Any unexpected exception. */ public void testThreadedTwoPoint() throws Exception { final int testSize = 50; final int iterations = 100; final String testPointGroup1 = "group1"; final String testPointGroup2 = "group2"; Runner[] runnerGroup1 = new Runner[testSize]; Runner[] runnerGroup2 = new Runner[testSize]; for (int i = 0; i < testSize; i++) { runnerGroup1[i] = new Runner(testPointGroup1, iterations); runnerGroup2[i] = new Runner(testPointGroup2, iterations); } for (int i = 0; i < testSize; i++) { runnerGroup1[i].start(); runnerGroup2[i].start(); } do { synchronized (lock) { lock.wait(); } } while (running > 0); final ExecutionAggregate group1 = new ExecutionAggregate(testPointGroup1); final ExecutionAggregate group2 = new ExecutionAggregate(testPointGroup2); for (int i = 0; i < allPoints.size(); i++) { EtmPoint point = (EtmPoint) allPoints.get(i); if (point.getName().equals(testPointGroup1)) { group1.addTransaction(point); } else { group2.addTransaction(point); } } monitor.render(new MeasurementRenderer() { public void render(Map points) { assertNotNull(points); assertTrue(points.size() == 2); int expectedExecutions = 2 * testSize * iterations; assertEquals(expectedExecutions, new TestHelper().countExecutions(points)); Aggregate aggregate = (Aggregate) points.get(testPointGroup1); assertNotNull(aggregate); assertEquals(testPointGroup1, aggregate.getName()); assertEquals(testSize * iterations, aggregate.getMeasurements()); assertEquals(group1.getTotal(), aggregate.getTotal(), 0.000001); assertEquals(group1.getMin(), aggregate.getMin(), 0.000001); assertEquals(group1.getMax(), aggregate.getMax(), 0.000001); Aggregate aggregate2 = (Aggregate) points.get(testPointGroup2); assertNotNull(aggregate2); assertEquals(testPointGroup2, aggregate2.getName()); assertEquals(testSize * iterations, aggregate2.getMeasurements()); assertEquals(group2.getTotal(), aggregate2.getTotal(), 0.000001); assertEquals(group2.getMin(), aggregate2.getMin(), 0.000001); assertEquals(group2.getMax(), aggregate2.getMax(), 0.000001); } }); } protected void tearDown() throws Exception { monitor.start(); monitor.reset(); monitor = null; } protected void setUp() throws Exception { monitor = new FlatMonitor(); monitor.start(); } class Runner extends Thread { List list = new ArrayList(); private String testPointName; private int runs; public Runner(String aTestPointName, int aRuns) { testPointName = aTestPointName; runs = aRuns; } public void run() { synchronized (allPoints) { running++; } try { while (runs > 0) { final EtmPoint point = monitor.createPoint(testPointName); Thread.sleep(1); point.collect(); list.add(point); runs--; } } catch (InterruptedException e) { // ignored } synchronized (allPoints) { allPoints.addAll(list); running--; } synchronized (lock) { lock.notifyAll(); } } } }