/* Copyright (c) 2008-2009 HomeAway, Inc.
* All rights reserved. http://www.perf4j.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.perf4j.helpers;
import org.perf4j.GroupedTimingStatistics;
import org.perf4j.TimingTestCase;
import org.perf4j.StopWatch;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.NotificationListener;
import javax.management.Notification;
import java.util.Arrays;
/**
* Tests the StatisticsExposingMBean.
*/
public class StatisticsExposingMBeanTest extends TimingTestCase {
public void testStatisticsExposingMBean() throws Exception {
GroupedTimingStatistics groupedTimingStats = new GroupedTimingStatistics();
groupedTimingStats.setStartTime(System.currentTimeMillis());
groupedTimingStats.setStopTime(System.currentTimeMillis() + 1000L);
groupedTimingStats.addStopWatches(this.testStopWatches);
StatisticsExposingMBean mBean = new StatisticsExposingMBean(StatisticsExposingMBean.DEFAULT_MBEAN_NAME,
Arrays.asList("tag", "tag3"),
null /* no notifications */);
mBean.updateCurrentTimingStatistics(groupedTimingStats);
MBeanInfo mBeanInfo = mBean.getMBeanInfo();
MBeanAttributeInfo[] attributeInfos = mBeanInfo.getAttributes();
assertEquals(mBean.getStatsValueRetrievers().size() * 2, attributeInfos.length);
assertEquals(groupedTimingStats.getStatisticsByTag().get("tag").getMean(),
mBean.getAttribute("tagMean"));
assertEquals(groupedTimingStats.getStatisticsByTag().get("tag").getStandardDeviation(),
mBean.getAttribute("tagStdDev"));
assertEquals(groupedTimingStats.getStatisticsByTag().get("tag").getMax(),
mBean.getAttribute("tagMax"));
assertEquals(groupedTimingStats.getStatisticsByTag().get("tag").getMin(),
mBean.getAttribute("tagMin"));
assertEquals(groupedTimingStats.getStatisticsByTag().get("tag").getCount(),
mBean.getAttribute("tagCount"));
assertEquals(((double) groupedTimingStats.getStatisticsByTag().get("tag").getCount()) /
((double) (groupedTimingStats.getStopTime() - groupedTimingStats.getStartTime()) / 1000.0),
mBean.getAttribute("tagTPS"));
//test notifications
DummyNotificationListener notificationListener = new DummyNotificationListener();
mBean = new StatisticsExposingMBean(StatisticsExposingMBean.DEFAULT_MBEAN_NAME,
Arrays.asList("tag", "tag3"),
Arrays.asList(new AcceptableRangeConfiguration("tagMean(<2000)"),
new AcceptableRangeConfiguration("unknownTagMean(<100)")));
mBean.addNotificationListener(notificationListener, null, null);
//no notification should be sent here, the timing stats are good
mBean.updateCurrentTimingStatistics(groupedTimingStats);
Thread.sleep(50); //need to sleep because notification is sent in a separate thread.
assertNull(notificationListener.lastReceivedNotification);
//add a stop watch that should make the mean be too high, causing a notification to be sent
GroupedTimingStatistics badStats = groupedTimingStats.clone();
badStats.addStopWatch(new StopWatch(groupedTimingStats.getStartTime(), 100000L, "tag", "message"));
mBean.updateCurrentTimingStatistics(badStats);
Thread.sleep(50);
assertEquals(StatisticsExposingMBean.OUT_OF_RANGE_NOTIFICATION_TYPE,
notificationListener.lastReceivedNotification.getType());
notificationListener.lastReceivedNotification = null;
//now when we update the timing stats again we should NOT receive another notification, because
//we only want a notification the first time it goes bad.
mBean.updateCurrentTimingStatistics(badStats);
Thread.sleep(50);
assertNull(notificationListener.lastReceivedNotification);
//one more time go from good to bad - we should get another notification
mBean.updateCurrentTimingStatistics(groupedTimingStats);
Thread.sleep(50);
assertNull(notificationListener.lastReceivedNotification);
mBean.updateCurrentTimingStatistics(badStats);
Thread.sleep(50);
assertEquals(StatisticsExposingMBean.OUT_OF_RANGE_NOTIFICATION_TYPE,
notificationListener.lastReceivedNotification.getType());
notificationListener.lastReceivedNotification = null;
//test invalid AcceptableRangeConfiguration string
try {
new StatisticsExposingMBean(StatisticsExposingMBean.DEFAULT_MBEAN_NAME,
Arrays.asList("tag"),
Arrays.asList(new AcceptableRangeConfiguration("tagNoStat(<100)")));
fail("Should have thrown an illegal argument exception");
} catch (IllegalArgumentException iae) { /* expected */ }
//TODO - more tests - update current statistics, check for unsupported ops.
}
protected static class DummyNotificationListener implements NotificationListener {
public Notification lastReceivedNotification;
public void handleNotification(Notification notification, Object handback) {
lastReceivedNotification = notification;
}
}
}