lab/src/test/java/net/engio/lab/LaboratoryTest.java

342 lines
13 KiB
Java

package net.engio.lab;
import net.engio.pips.lab.Benchmark;
import net.engio.pips.lab.ExecutionContext;
import net.engio.pips.lab.LabException;
import net.engio.pips.lab.Laboratory;
import net.engio.pips.lab.workload.*;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author bennidi
* Date: 2/25/14
*/
public class LaboratoryTest extends UnitTest{
public static ITaskFactory NoOperation = new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
// do nothing
}
};
}
};
@Test
public void testInvalidWorkloadSetups() throws Exception {
Workload withoutFactory = new Workload("without factory")
.starts().immediately()
.duration().repetitions(1);
Workload withoutStart = new Workload("without start")
.setITaskFactory(NoOperation)
.duration().repetitions(1);
Workload withoutDuration = new Workload("without duration")
.starts().immediately()
.setITaskFactory(NoOperation);
Workload cyclicStart1 = new Workload("without duration");
Workload cyclicStart2 = new Workload("without duration");
cyclicStart1
.starts().after(cyclicStart2)
.duration().repetitions(1)
.setITaskFactory(NoOperation);
cyclicStart2
.starts().after(cyclicStart1)
.duration().repetitions(1)
.setITaskFactory(NoOperation);
Workload cyclicDuration1 = new Workload("without duration");
Workload cyclicDuration2 = new Workload("without duration");
cyclicDuration1
.starts().immediately()
.duration().depends(cyclicDuration2)
.setITaskFactory(NoOperation);
cyclicDuration2
.starts().immediately()
.duration().depends(cyclicDuration1)
.setITaskFactory(NoOperation);
Laboratory lab = new Laboratory();
try {
lab.run(new Benchmark("Invalid").addWorkload(withoutFactory));
fail();
} catch (LabException e) {
assertEquals(e.getCode(), LabException.ErrorCode.WLWithoutFactory);
}
try {
lab.run(new Benchmark("Invalid").addWorkload(withoutStart));
fail();
} catch (LabException e) {
assertEquals(e.getCode(), LabException.ErrorCode.WLWithoutStart);
}
try {
lab.run(new Benchmark("Invalid").addWorkload(withoutDuration));
fail();
} catch (LabException e) {
assertEquals(e.getCode(), LabException.ErrorCode.WLWithoutDuration);
}
try {
lab.run(new Benchmark("Invalid").addWorkload(cyclicStart1, cyclicStart2));
fail();
} catch (LabException e) {
assertEquals(e.getCode(), LabException.ErrorCode.WLWithCycleInStart);
}
try {
lab.run(new Benchmark("Invalid").addWorkload(cyclicDuration1, cyclicDuration2));
fail();
} catch (LabException e) {
assertEquals(e.getCode(), LabException.ErrorCode.WLWithCycleInDuration);
}
}
@Test
public void testWorkloadSchedulingStartingAfter() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
Workload first = new Workload("First workload")
.setParallelTasks(15)
.setITaskFactory(new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
counter.incrementAndGet();
}
};
}
})
.duration().repetitions(1)
.starts().immediately();
Workload second = new Workload("Second Workload")
.setParallelTasks(15)
.setITaskFactory(new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
counter.decrementAndGet();
}
};
}
})
.handle(ExecutionEvent.WorkloadInitialization, new ExecutionHandler() {
@Override
public void handle(ExecutionContext context) {
// the first workload
assertEquals(15, counter.get());
}
})
.duration().repetitions(1)
.starts().after(first);
Laboratory lab = new Laboratory();
lab.run(new Benchmark("test").addWorkload(first, second));
Thread.sleep(100);
// both have run in the end
assertEquals(0, counter.get());
}
//@Test
// TODO: this invalid start/end dependency tree must be fixed
public void testWorkloadSchedulingStartingAfterDelayed() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
Workload first = new Workload("First workload")
.setParallelTasks(15)
.setITaskFactory(new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
counter.incrementAndGet();
}
};
}
})
.duration().repetitions(1)
.starts().after(2, TimeUnit.SECONDS);
Workload second = new Workload("Second Workload")
.setParallelTasks(15)
.setITaskFactory(new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
counter.decrementAndGet();
}
};
}
})
.handle(ExecutionEvent.WorkloadInitialization, new ExecutionHandler() {
@Override
public void handle(ExecutionContext context) {
// the first workload
assertEquals(15, counter.get());
}
})
.duration().depends(first)
.starts().after(first);
Laboratory lab = new Laboratory();
lab.run(new Benchmark("test").addWorkload(first, second));
Thread.sleep(4000);
// both have run in the end
assertEquals(0, counter.get());
}
@Test
public void testWorkloadShutdownCancelsTasks() throws Exception {
final AtomicInteger first = new AtomicInteger(1);
final AtomicInteger second = new AtomicInteger(1);
Workload countUp = new Workload("First workload")
.setParallelTasks(15)
.setITaskFactory(new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
first.incrementAndGet();
}
};
}
})
.duration().lasts(5, TimeUnit.SECONDS)
.starts().immediately();
Workload countDown = new Workload("Second Workload")
.setParallelTasks(15)
.setITaskFactory(new ITaskFactory() {
@Override
public ITask create(ExecutionContext context) {
return new ITask() {
@Override
public void run(ExecutionContext context) throws Exception {
second.incrementAndGet();
}
};
}
})
.duration().depends(countUp)
.starts().immediately();
Laboratory lab = new Laboratory();
lab.run(new Benchmark("test").addWorkload(countUp, countDown));
int firstVal = first.get();
int secondVal = second.get();
// no threads that change the counter are running anymore
Thread.sleep(1000);
assertEquals(firstVal, first.get());
assertEquals(secondVal, second.get());
assertTrue(firstVal > 1);
assertTrue(secondVal > 1);
}
@Test
public void testWorkloadSchedulingDurationDepends() throws Exception {
final AtomicLong start = new AtomicLong(0);
final AtomicLong finish = new AtomicLong(0);
final AtomicLong finishSecond = new AtomicLong(0);
int duration = 3;
Workload first = new Workload("First workload")
.setParallelTasks(5)
.duration().lasts(duration, TimeUnit.SECONDS)
.starts().immediately()
.setITaskFactory(NoOperation)
.handle(ExecutionEvent.WorkloadInitialization, new ExecutionHandler() {
@Override
public void handle(ExecutionContext context) {
start.set(System.currentTimeMillis());
}
})
.handle(ExecutionEvent.WorkloadCompletion, new ExecutionHandler() {
@Override
public void handle(ExecutionContext context) {
finish.set(System.currentTimeMillis());
}
});
Workload second = new Workload("Second Workload")
.setParallelTasks(5)
.setITaskFactory(NoOperation)
.handle(ExecutionEvent.WorkloadCompletion, new ExecutionHandler() {
@Override
public void handle(ExecutionContext context) {
// the first workload
finishSecond.set(System.currentTimeMillis());
}
})
.duration().depends(first)
.starts().immediately();
Laboratory lab = new Laboratory();
lab.run(new Benchmark("test").addWorkload(first, second));
// first workload has run at least duration seconds
assertTrue(finish.get() - start.get() >= duration * 1000);
// second workload has not run significantly longer then first (~1ms per thread)
assertTrue(finishSecond.get() - finish.get() < 5);
}
@Test
public void testMultipleDependencies() throws Exception {
final AtomicBoolean finished = new AtomicBoolean(false);
Workload first = new Workload("First workload")
.setParallelTasks(5)
.duration().lasts(10, TimeUnit.SECONDS)
.starts().immediately()
.setITaskFactory(NoOperation);
Workload second = new Workload("Second Workload")
.setParallelTasks(5)
.setITaskFactory(NoOperation)
.duration().depends(first)
.starts().immediately();
Workload third = new Workload("Third Workload")
.setParallelTasks(5)
.setITaskFactory(NoOperation)
.duration().depends(first)
.starts().immediately()
.handle(ExecutionEvent.WorkloadCompletion, new ExecutionHandler() {
@Override
public void handle(ExecutionContext context) {
finished.set(true);
}
});
Laboratory lab = new Laboratory();
lab.run(new Benchmark("test").addWorkload(first, second, third));
assertTrue(finished.get());
}
}