/*
*
* 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.aggregation;
import etm.core.monitor.EtmMonitor;
import etm.core.monitor.EtmPoint;
import etm.core.renderer.MeasurementRenderer;
import junit.framework.TestCase;
import etm.core.TestHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Tests for flat concurrency testing.
*
* @author void.fm
* @version $Revision$
*/
public abstract class CommonConcurrentFlatAggregationTests extends TestCase {
protected EtmMonitor monitor;
private final Object lock = new Object();
private final List allPoints = new ArrayList();
private int running;
/**
* Tests one etm point with multiple threads.
*
* @throws Exception Unexcpeted Exception
*/
public void testManyThreadsOnePoint() throws Exception {
int testSize = 100;
int iterations = 500;
final String testPointGroup1 = "group1";
Runner[] runnerGroup1 = new Runner[testSize];
for (int i = 0; i < testSize; i++) {
runnerGroup1[i] = new Runner(testPointGroup1, iterations);
}
for (int i = 0; i < testSize; i++) {
runnerGroup1[i].start();
}
do {
synchronized (lock) {
lock.wait();
}
} while (running > 0);
final ExecutionAggregate group1 = new ExecutionAggregate(testPointGroup1);
for (int i = 0; i < allPoints.size(); i++) {
EtmPoint point = (EtmPoint) allPoints.get(i);
if (point.getName().equals(testPointGroup1)) {
group1.addTransaction(point);
} else {
fail("Unknown group " + point.getName());
}
}
monitor.render(new MeasurementRenderer() {
public void render(Map points) {
}
});
final int expectedExecutions = testSize * iterations;
monitor.render(new MeasurementRenderer() {
public void render(Map points) {
assertEquals(expectedExecutions, new TestHelper().countExecutions(points));
assertNotNull(points);
assertTrue(points.size() == 1);
Aggregate aggregate = (Aggregate) points.get(testPointGroup1);
assertNotNull(aggregate);
assertEquals(testPointGroup1, aggregate.getName());
assertEquals(group1.getMeasurements(), aggregate.getMeasurements());
assertEquals(group1.getTotal(), aggregate.getTotal(), 0.0001);
assertEquals(group1.getMin(), aggregate.getMin(), 0.0001);
assertEquals(group1.getMax(), aggregate.getMax(), 0.0001);
}
});
}
/**
* Tests many points with many threads.
*
* @throws Exception Unexpected exception.
*/
public void testManyThreadsManyPoints() throws Exception {
final int pointSize = 20;
int threadSize = 50;
int iterations = 500;
String testPrefix = "group";
Runner[][] runners = new Runner[pointSize][threadSize];
for (int j = 0; j < pointSize; j++) {
for (int i = 0; i < threadSize; i++) {
runners[j][i] = new Runner(testPrefix + j, iterations);
}
}
for (int j = 0; j < pointSize; j++) {
for (int i = 0; i < threadSize; i++) {
runners[j][i].start();
}
}
do {
synchronized (lock) {
lock.wait();
}
} while (running > 0);
final Map aggregates = new HashMap();
for (int i = 0; i < allPoints.size(); i++) {
EtmPoint point = (EtmPoint) allPoints.get(i);
ExecutionAggregate aggregate = (ExecutionAggregate) aggregates.get(point.getName());
if (aggregate == null) {
aggregate = new ExecutionAggregate(point.getName());
aggregates.put(point.getName(), aggregate);
}
aggregate.addTransaction(point);
}
assertEquals(aggregates.size(), pointSize);
final int expectedExecutions = pointSize * threadSize * iterations;
monitor.render(new MeasurementRenderer() {
public void render(Map points) {
assertNotNull(points);
assertTrue(points.size() == pointSize);
assertEquals(expectedExecutions, new TestHelper().countExecutions(points));
for (Iterator iterator = points.keySet().iterator(); iterator.hasNext();) {
String s = (String) iterator.next();
Aggregate renderAggregate = (Aggregate) points.get(s);
Aggregate actualAggregate = (Aggregate) aggregates.get(s);
assertNotNull(actualAggregate);
assertEquals(actualAggregate.getName(), renderAggregate.getName());
assertEquals(actualAggregate.getMeasurements(), renderAggregate.getMeasurements());
assertEquals(actualAggregate.getTotal(), renderAggregate.getTotal(), 0.00001);
assertEquals(actualAggregate.getMin(), renderAggregate.getMin(), 0.00001);
assertEquals(actualAggregate.getMax(), renderAggregate.getMax(), 0.00001);
}
}
});
}
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(10);
point.collect();
list.add(point);
runs--;
}
} catch (InterruptedException e) {
// ignored
}
synchronized (allPoints) {
allPoints.addAll(list);
running--;
}
synchronized (lock) {
lock.notifyAll();
}
}
}
}