/*******************************************************************************
* Copyright © 2012-2015 eBay Software Foundation
* This program is dual licensed under the MIT and Apache 2.0 licenses.
* Please see LICENSE for more information.
*******************************************************************************/
package com.ebay.jetstream.util;
import static org.junit.Assert.assertFalse;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import com.ebay.jetstream.util.FifoPriorityQueue.FifoPriorityQueueException;
public class RequestThreadTest {
private static class RequestQueueMonitor implements QueueMonitor {
private static class stats {
private int m_pauseCount;
private int m_resumeCount;
/**
* @return the pauseCount
*/
public int getPauseCount() {
return m_pauseCount;
}
/**
* @return the resumeCount
*/
public int getResumeCount() {
return m_resumeCount;
}
/**
* @param pauseCount
* the pauseCount to set
*/
public void incPauseCount() {
m_pauseCount++;
}
/**
* @param resumeCount
* the resumeCount to set
*/
public void incResumeCount() {
m_resumeCount++;
}
public boolean pauseCntMatchesResumeCnt() {
return m_pauseCount == m_resumeCount;
}
}
private ArrayList<stats> m_mystatsList;
private float m_highWaterMark = (float) 0.8;
private float m_lowWaterMark = (float) 0.2;
private RequestQueueMonitor() {
}
public RequestQueueMonitor(int numPrioritesToMonitor) {
m_mystatsList = new ArrayList<stats>(numPrioritesToMonitor);
for (int i = 0; i < numPrioritesToMonitor; i++) {
m_mystatsList.add(new stats());
}
}
public float getHighWaterMark() {
return m_highWaterMark;
}
public float getLowWaterMark() {
return m_lowWaterMark;
}
public boolean isPauseCntMatchesResumeCnt() {
for (int i = 0; i < m_mystatsList.size(); i++) {
if (!m_mystatsList.get(i).pauseCntMatchesResumeCnt())
return false;
}
return true;
}
public void pause(long queueSize, int priority) {
m_mystatsList.get(priority).incPauseCount();
System.out.println("Received Pause : queue size = " + queueSize + " : priority = " + priority); //KEEPME
}
public void resume(long queueSize, int priority) {
System.out.println("Received resume : queue size = " + queueSize + " : priority = " + priority); //KEEPME
m_mystatsList.get(priority).incResumeCount();
}
public void setHighWaterMark(float highWaterMark) {
m_highWaterMark = highWaterMark;
}
public void setLowWaterMark(float lowWaterMark) {
m_lowWaterMark = lowWaterMark;
}
}
private static class TestRequest extends Request {
int m_delay = 0;
public TestRequest(int delay) {
m_delay = delay;
}
// @Override
@Override
public boolean execute() {
try {
m_execCount.addAndGet(1);
if (m_delay > 0)
Thread.sleep(m_delay);
}
catch (InterruptedException e) {
e.printStackTrace(); //KEEPME
}
return false;
}
}
static AtomicInteger m_execCount = new AtomicInteger(0);
public static void main(String[] args) throws Exception {
RequestThreadTest mytest = new RequestThreadTest();
mytest.runtest(2, 50, 1000, 10, 2, true);
/*
* mytest.runtest(1, 50, 1000, 10, 1, true);
*
*
* mytest.runtest(1, 50, 0, 10, 1, true);
*
*
* mytest.runtest(2, 50, 0, 1000000, 1, true);
*
* mytest.runtest(1, 100000, 0, 1000000, 1, true);
*
* mytest.runtest(1, 100000, 0, 1000000, 1, false);
*
* mytest.runtest(2, 100000, 0, 1000000, 1, true);
*
* mytest.runtest(2, 100000, 0, 1000000, 3, true);
*
* mytest.runtest(2, 100000, 0, 1000000, 10, true);
*
*
* mytest.runtest(2, 100000, 0, 1000000, 10, false);
*/
}
@Test
public void executeTest() {
RequestThreadTest mytest = new RequestThreadTest();
mytest.runtest(2, 50, 1000, 10, 2, true);
/*
* mytest.runtest(1, 50, 1000, 10, 1, true);
*
* mytest.runtest(1, 50, 0, 10, 1, true);
*
* mytest.runtest(2, 50, 0, 1000000, 1, true);
*
* mytest.runtest(1, 100000, 0, 1000000, 1, true);
*
* mytest.runtest(1, 100000, 0, 1000000, 1, false);
*
* mytest.runtest(2, 100000, 0, 1000000, 1, true);
*
* mytest.runtest(2, 100000, 0, 1000000, 3, true);
*
* mytest.runtest(2, 100000, 0, 1000000, 10, true);
*
* mytest.runtest(2, 100000, 0, 1000000, 10, false);
*/
}
public void runtest(int numprios, int numreqs, int delay, int queueSize, int numThreads, boolean attachMonitor) {
RequestThreadTest.m_execCount.set(0);
FifoPriorityQueue myqueue = new FifoPriorityQueue(numprios);
myqueue.setMaxSize(queueSize);
// RequestThread mythread = new RequestThread(myqueue);
RequestThreadPool mythreadpool = new RequestThreadPool();
mythreadpool.init(myqueue, numThreads);
RequestQueueMonitor myqueuemonitor = new RequestQueueMonitor(numprios);
myqueuemonitor.setHighWaterMark((float) 0.85);
myqueuemonitor.setLowWaterMark((float) 0.2);
try {
if (attachMonitor)
myqueue.attachQueueMonitor(myqueuemonitor);
}
catch (FifoPriorityQueueException e1) {
e1.printStackTrace();
return;
}
try {
mythreadpool.start();
}
catch (Exception e1) {
e1.printStackTrace();
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e2) {
e2.printStackTrace();
}
Timer mytimer = new Timer();
mytimer.start();
long failedCnt = 0;
for (int i = 0; i < numreqs; i++) {
for (int j = 0; j < numprios; j++) {
Request myrequest = new TestRequest(delay);
myrequest.setPriority(j);
if (!myqueue.insertAtTail(myrequest, j))
failedCnt += 1;
}
}
System.out.println("time taken to submit " + numreqs * numprios + " reqs = " + mytimer.elapsedTimeInMillis()); //KEEPME
while (true) {
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (myqueue.isEmpty())
break;
}
System.out.println("time taken to submit and execute " + numreqs * numprios + " reqs with " + numThreads
+ " with queue monitoring " + attachMonitor + " time = " + mytimer.elapsedTimeInMillis() + " millisecs"); //KEEPME
mythreadpool.shutdown();
System.out.println("Total requests executed = " + RequestThreadTest.m_execCount); //KEEPME
System.out.println("My pause count matches Resume count = " + myqueuemonitor.isPauseCntMatchesResumeCnt()); //KEEPME
System.out.println("Failed count = " + failedCnt); //KEEPME
assertFalse(!myqueuemonitor.isPauseCntMatchesResumeCnt());
}
}