blob: c16e97dfe867090210fb6cc9724afaf3cc01b879 [file] [log] [blame]
package org.eclipse.osee.ote.message;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentAccessor;
import org.eclipse.osee.ote.message.data.MessageData;
/**
* This class will measure the time between sends.
* <pre>
* {@code
* MessageSendPeriodTrace trace = new MessageSendPeriodTrace(TimeUnit.NANOSECONDS, testMessage, logger);
* trace.start();
* //wait or do stuff
* trace.stop();
* trace.printResults();
* }
* </pre>
* @author Andrew M. Finkbeiner
*
*/
public class MessageSendPeriodTrace extends MessageTimeTrace {
public final String TRACE_TYPE = "MessageSendPeriodTrace";
private SendTimer sendTimer;
private int maxFlag = Integer.MAX_VALUE;
private int minError = Integer.MIN_VALUE;
private int maxError = Integer.MAX_VALUE;
private MessageTraceOutput messageTraceOutput;
private MessageTraceLogger messageTraceLogger;
/**
* @param environment - the test environment.
* @param timeUnit - determines the resolution of the timing that is measured.
* @param message - the message to measure
* @param messageTraceLogger - logger to write output
*/
@SuppressWarnings("rawtypes")
public MessageSendPeriodTrace(ITestEnvironmentAccessor environment, TimeUnit timeUnit, Message message, MessageTraceLogger messageTraceLogger) {
super(environment, message, timeUnit);
sendTimer = new SendTimer(this);
this.messageTraceOutput = new MessageTraceOutput();
this.messageTraceLogger = messageTraceLogger;
}
/**
*
* @param expected the expected period in the constructed TimeUnit
* @param maxError the max variance off of the period in the constructed TimeUnit
*/
public void setMaxVariance(int expected, int maxError){
this.maxFlag = maxError;
this.minError = expected - maxError;
this.maxError = expected + maxError;
}
public void addStartEvent(String message){
add(new TimeEvent(message));
}
@Override
public void start(){
super.start();
getMessage().getDefaultMessageData().addSendListener(sendTimer);
}
@Override
public void stop(){
super.stop();
getMessage().getDefaultMessageData().removeSendListener(sendTimer);
}
@Override
public synchronized void printResults(){
List<TimeEvent> events = get();
int count = 0;
int exceedanceCount = 0;
double average = 0.0;
double max = -1.0;
double min = -1.0;
SendEvent pre1 = null;
SendEvent pre2 = null;
for(TimeEvent event:events){
if(event instanceof SendEvent){
SendEvent sendEvent = (SendEvent)event;
if(sendEvent.type == SendEventType.pre){
pre1 = pre2;
pre2 = sendEvent;
}
}
if(pre1 != null && pre2 != null){
long nanoDiff = pre2.getNanoTime() - pre1.getNanoTime();
count++;
long currentTime = getTimeUnit().convert(nanoDiff, TimeUnit.NANOSECONDS);
if(currentTime >= 0){
if(max < 0 || currentTime > max){
max = currentTime;
}
if(min < 0 || currentTime < min){
min = currentTime;
}
if(currentTime > maxError || currentTime < minError){
exceedanceCount++;
String maxMessage = String.format("%s: count[%d] %d [%d (count)] [%s]", getName(), count, currentTime, exceedanceCount, getTimeUnit().name());
System.out.println(maxMessage);
}
average = (((count-1) * average) + currentTime)/count;
}
}
}
messageTraceOutput.setMessage(getMessage().getMessageName());
messageTraceOutput.setMessageRate(getMessageRate());
messageTraceOutput.setTimeUnit(getTimeUnit().name());
messageTraceOutput.setTraceType(TRACE_TYPE);
messageTraceOutput.setCount(count);
messageTraceOutput.setAverage(average);
messageTraceOutput.setMin(min);
messageTraceOutput.setMax(max);
messageTraceOutput.setExceedanceCount(exceedanceCount);
messageTraceOutput.setExceedanceThreshold(maxFlag);
messageTraceOutput.setTestDurationSec(testDurationSec);
if (messageTraceLogger != null){
messageTraceLogger.logMessageTraceOutput(messageTraceOutput);
}
}
private static class SendTimer implements IMessageSendListener {
private MessageSendPeriodTrace messageSendOperator;
public SendTimer(MessageSendPeriodTrace messageSendOperator) {
this.messageSendOperator = messageSendOperator;
}
@Override
public void onPreSend(MessageData messageData) {
messageSendOperator.add(new SendEvent(SendEventType.pre));
}
@Override
public void onPostSend(MessageData messageData) {
// Intentionally empty block
}
}
private static class SendEvent extends TimeEvent {
public final SendEventType type;
public SendEvent(SendEventType type) {
super(type.name());
this.type = type;
}
}
private enum SendEventType {
pre
}
}