blob: 6c799adacb0ad424abd69b8ad11ea71b2f996d90 [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* one or more patents listed at http://www.pivotal.io/patents.
*=========================================================================
*/
package com.gemstone.gemfire.internal.statistics;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import static org.junit.Assert.*;
import com.gemstone.gemfire.StatisticDescriptor;
import com.gemstone.gemfire.Statistics;
import com.gemstone.gemfire.StatisticsType;
import com.gemstone.gemfire.internal.NanoTimer;
import com.gemstone.gemfire.internal.StatisticsManager;
import com.gemstone.gemfire.internal.statistics.StatisticsNotification.Type;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
import dunit.DistributedTestCase;
import dunit.DistributedTestCase.WaitCriterion;
import junit.framework.TestCase;
/**
* Integration test for the SampleCollector class.
*
* @author Kirk Lund
* @since 7.0
*/
@Category(IntegrationTest.class)
public class ValueMonitorJUnitTest {
private Mockery mockContext;
@Before
public void setUp() throws Exception {
this.mockContext = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
}
@After
public void tearDown() throws Exception {
this.mockContext.assertIsSatisfied();
this.mockContext = null;
}
@Test
public void testAddRemoveListener() throws Exception {
final long startTime = System.currentTimeMillis();
final List<Statistics> statsList = new ArrayList<Statistics>();
final StatisticsManager mockStatisticsManager = this.mockContext.mock(StatisticsManager.class, "testAddRemoveListener$StatisticsManager");
this.mockContext.checking(new Expectations() {{
allowing(mockStatisticsManager).getName();
will(returnValue("mockStatisticsManager"));
allowing(mockStatisticsManager).getId();
will(returnValue(1));
allowing(mockStatisticsManager).getStartTime();
will(returnValue(startTime));
allowing(mockStatisticsManager).getStatListModCount();
will(returnValue(0));
allowing(mockStatisticsManager).getStatsList();
will(returnValue(statsList));
}});
final StatisticsSampler mockStatisticsSampler = this.mockContext.mock(StatisticsSampler.class, "testAddRemoveListener$StatisticsSampler");
this.mockContext.checking(new Expectations() {{
allowing(mockStatisticsSampler).getStatisticsModCount();
will(returnValue(0));
allowing(mockStatisticsSampler).getStatistics();
will(returnValue(new Statistics[]{}));
}});
final StatArchiveHandlerConfig mockStatArchiveHandlerConfig = this.mockContext.mock(StatArchiveHandlerConfig.class, "testAddRemoveListener$StatArchiveHandlerConfig");
this.mockContext.checking(new Expectations() {{
allowing(mockStatArchiveHandlerConfig).getArchiveFileName();
will(returnValue(new File("")));
allowing(mockStatArchiveHandlerConfig).getArchiveFileSizeLimit();
will(returnValue(0));
allowing(mockStatArchiveHandlerConfig).getArchiveDiskSpaceLimit();
will(returnValue(0));
allowing(mockStatArchiveHandlerConfig).getSystemId();
will(returnValue(1));
allowing(mockStatArchiveHandlerConfig).getSystemStartTime();
will(returnValue(startTime));
allowing(mockStatArchiveHandlerConfig).getSystemDirectoryPath();
will(returnValue(""));
allowing(mockStatArchiveHandlerConfig).getProductDescription();
will(returnValue("testAddRemoveListener"));
}});
// need a real SampleCollector for this test or the monitor can't get the handler
SampleCollector sampleCollector = new SampleCollector(mockStatisticsSampler);
sampleCollector.initialize(mockStatArchiveHandlerConfig, NanoTimer.getTime());
final List<StatisticsNotification> notifications = new ArrayList<StatisticsNotification>();
StatisticsListener listener = new StatisticsListener() {
@Override
public void handleNotification(StatisticsNotification notification) {
notifications.add(notification);
}
};
ValueMonitor monitor = new ValueMonitor();
long timeStamp = System.currentTimeMillis();
Type type = Type.VALUE_CHANGED;
Number value = 43;
StatisticsNotification notification = createStatisticsNotification(timeStamp, type, value);
monitor.notifyListeners(notification);
assertTrue(notifications.isEmpty());
monitor.addListener(listener);
monitor.notifyListeners(notification);
assertEquals(1, notifications.size());
notification = notifications.remove(0);
assertNotNull(notification);
assertEquals(timeStamp, notification.getTimeStamp());
assertEquals(type, notification.getType());
StatisticId statId = createStatisticId(null, null);
assertEquals(value, notification.getValue(statId));
monitor.removeListener(listener);
monitor.notifyListeners(notification);
assertTrue(notifications.isEmpty());
}
@Test
public void testValueMonitorListener() throws Exception {
final long startTime = System.currentTimeMillis();
TestStatisticsManager manager = new TestStatisticsManager(
1,
"ValueMonitorJUnitTest",
startTime);
StatisticsSampler sampler = new TestStatisticsSampler(manager);
final StatArchiveHandlerConfig mockStatArchiveHandlerConfig =
this.mockContext.mock(StatArchiveHandlerConfig.class, "testFoo$StatArchiveHandlerConfig");
this.mockContext.checking(new Expectations() {{
allowing(mockStatArchiveHandlerConfig).getArchiveFileName();
will(returnValue(new File("")));
allowing(mockStatArchiveHandlerConfig).getArchiveFileSizeLimit();
will(returnValue(0));
allowing(mockStatArchiveHandlerConfig).getArchiveDiskSpaceLimit();
will(returnValue(0));
allowing(mockStatArchiveHandlerConfig).getSystemId();
will(returnValue(1));
allowing(mockStatArchiveHandlerConfig).getSystemStartTime();
will(returnValue(startTime));
allowing(mockStatArchiveHandlerConfig).getSystemDirectoryPath();
will(returnValue(""));
allowing(mockStatArchiveHandlerConfig).getProductDescription();
will(returnValue("testFoo"));
}});
SampleCollector sampleCollector = new SampleCollector(sampler);
sampleCollector.initialize(mockStatArchiveHandlerConfig, NanoTimer.getTime());
StatisticDescriptor[] statsST1 = new StatisticDescriptor[] {
manager.createDoubleCounter("double_counter_1", "double_counter_1_desc", "double_counter_1_units"),
manager.createIntCounter( "int_counter_2", "int_counter_2_desc", "int_counter_2_units"),
manager.createLongCounter( "long_counter_3", "long_counter_3_desc", "long_counter_3_units")
};
StatisticsType ST1 = manager.createType("ST1_name", "ST1_desc", statsST1);
Statistics st1_1 = manager.createAtomicStatistics(ST1, "st1_1_text", 1);
Statistics st1_2 = manager.createAtomicStatistics(ST1, "st1_2_text", 2);
st1_1.incDouble("double_counter_1", 1000.0001);
st1_1.incInt("int_counter_2", 2);
st1_1.incLong("long_counter_3", 3333333333L);
st1_2.incDouble("double_counter_1", 2000.0002);
st1_2.incInt("int_counter_2", 3);
st1_2.incLong("long_counter_3", 4444444444L);
final List<StatisticsNotification> notifications = new ArrayList<StatisticsNotification>();
StatisticsListener listener = new StatisticsListener() {
@Override
public void handleNotification(StatisticsNotification notification) {
notifications.add(notification);
}
};
ValueMonitor monitor = new ValueMonitor().addStatistics(st1_1);
monitor.addListener(listener);
assertTrue("Unexpected notifications: " + notifications, notifications.isEmpty());
long timeStamp = NanoTimer.getTime();
sampleCollector.sample(timeStamp);
waitForNotification(notifications, 2*1000, 10, false);
assertEquals("Unexpected notifications: " + notifications, 1, notifications.size());
StatisticsNotification notification = notifications.remove(0);
assertEquals(StatisticsNotification.Type.VALUE_CHANGED, notification.getType());
// validate 1 notification occurs with all 3 stats of st1_1
st1_1.incDouble("double_counter_1", 1.1);
st1_1.incInt("int_counter_2", 2);
st1_1.incLong("long_counter_3", 3);
timeStamp += NanoTimer.millisToNanos(1000);
sampleCollector.sample(timeStamp);
waitForNotification(notifications, 2*1000, 10, false);
assertEquals("Unexpected notifications: " + notifications, 1, notifications.size());
notification = notifications.remove(0);
assertEquals(StatisticsNotification.Type.VALUE_CHANGED, notification.getType());
int statCount = 0;
Map<String, Number> expectedValues = new HashMap<String, Number>();
expectedValues.put("double_counter_1", 1001.1001);
expectedValues.put("int_counter_2", 4);
expectedValues.put("long_counter_3", 3333333336L);
for (StatisticId statId : notification) {
Number value = expectedValues.remove(statId.getStatisticDescriptor().getName());
assertNotNull(value);
assertEquals(value, notification.getValue(statId));
statCount++;
}
assertEquals(3, statCount);
// validate no notification occurs when no stats are updated
timeStamp += NanoTimer.millisToNanos(1000);
sampleCollector.sample(timeStamp);
waitForNotification(notifications, 2*1000, 10, false);
assertTrue("Unexpected notifications: " + notifications, notifications.isEmpty());
// validate no notification occurs when only other stats are updated
st1_2.incDouble("double_counter_1", 3.3);
st1_2.incInt("int_counter_2", 1);
st1_2.incLong("long_counter_3", 2);
timeStamp += NanoTimer.millisToNanos(1000);
sampleCollector.sample(timeStamp);
waitForNotification(notifications, 2*1000, 10, false);
assertTrue("Unexpected notifications: " + notifications, notifications.isEmpty());
// validate notification only contains stats added to monitor
st1_1.incInt("int_counter_2", 100);
st1_2.incInt("int_counter_2", 200);
assertEquals(2, sampleCollector.currentHandlersForTesting().size());
timeStamp += NanoTimer.millisToNanos(1000);
sampleCollector.sample(timeStamp);
waitForNotification(notifications, 2*1000, 10, false);
assertEquals("Unexpected notifications: " + notifications, 1, notifications.size());
notification = notifications.remove(0);
assertEquals(StatisticsNotification.Type.VALUE_CHANGED, notification.getType());
statCount = 0;
expectedValues = new HashMap<String, Number>();
expectedValues.put("int_counter_2", 104);
for (StatisticId statId : notification) {
Number value = expectedValues.remove(statId.getStatisticDescriptor().getName());
assertNotNull(value);
assertEquals(value, notification.getValue(statId));
statCount++;
}
assertEquals(1, statCount);
}
protected StatisticId createStatisticId(
final StatisticDescriptor descriptor, final Statistics stats) {
return new StatisticId() {
@Override
public StatisticDescriptor getStatisticDescriptor() {
return descriptor;
}
@Override
public Statistics getStatistics() {
return stats;
}
};
}
protected StatisticsNotification createStatisticsNotification(
final long timeStamp, final Type type, final Number value) {
return new StatisticsNotification() {
@Override
public long getTimeStamp() {
return timeStamp;
}
@Override
public Type getType() {
return type;
}
@Override
public Iterator<StatisticId> iterator() {
return null; // TODO
}
@Override
public Iterator<StatisticId> iterator(StatisticDescriptor statDesc) {
return null; // TODO
}
@Override
public Iterator<StatisticId> iterator(Statistics statistics) {
return null; // TODO
}
@Override
public Iterator<StatisticId> iterator(StatisticsType statisticsType) {
return null; // TODO
}
@Override
public Number getValue(StatisticId statId) throws StatisticNotFoundException {
return value;
}
};
}
private static void waitForNotification(final List<StatisticsNotification> notifications, long ms, long interval, boolean throwOnTimeout) {
WaitCriterion wc = new WaitCriterion() {
public boolean done() {
return notifications.size() > 0;
}
public String description() {
return "waiting for notification";
}
};
DistributedTestCase.waitForCriterion(wc, ms, interval, throwOnTimeout);
}
}