/**
* Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
* All rights reserved. Use is subject to license terms. See LICENSE.TXT
*/
package org.diirt.datasource;
import org.diirt.datasource.test.CountDownPVReaderListener;
import org.diirt.datasource.test.MockDataSource;
import java.util.Arrays;
import java.util.concurrent.Executor;
import org.diirt.datasource.expression.Queue;
import static org.junit.Assert.*;
import org.junit.*;
import static org.diirt.datasource.ExpressionLanguage.*;
import static java.time.Duration.*;
import static org.hamcrest.Matchers.*;
/**
* Tests rate decoupling and throttling.
*
* @author carcassi
*/
public class NotificationRateTest {
public NotificationRateTest() {
}
@Before
public void setUp() {
pv = null;
}
@After
public void tearDown() {
if (pv != null) {
pv.close();
pv = null;
}
}
private volatile PVReader<?> pv;
private final Executor delayedExecutor = new Executor() {
@Override
public void execute(Runnable command) {
try {
Thread.sleep(500);
command.run();
} catch(InterruptedException ex) {
Thread.interrupted();
}
}
};
@Test
public void rateThrottling1() throws Exception {
Queue<Integer> queue = queueOf(Integer.class).maxSize(10);
CountDownPVReaderListener listener = new CountDownPVReaderListener(1);
pv = PVManager.read(queue).from(new MockDataSource())
.notifyOn(delayedExecutor)
.readListener(listener)
.maxRate(ofMillis(10));
// Wait for connection
listener.await(ofMillis(700));
assertThat(listener.getCount(), equalTo(0));
listener.resetCount(1);
// No new values, should get no new notification
listener.await(ofMillis(500));
assertThat(listener.getCount(), equalTo(1));
// Add one value, notification should not come right away
queue.add(1);
listener.await(ofMillis(100));
assertThat(listener.getCount(), equalTo(1));
// Add a few other values, still no new notification
queue.add(2);
queue.add(3);
listener.await(ofMillis(100));
assertThat(listener.getCount(), equalTo(1));
queue.add(4);
// Wait longer for first notification
listener.await(ofMillis(500));
assertThat(listener.getCount(), equalTo(0));
assertThat(pv.getValue(), equalTo((Object) Arrays.asList(1)));
listener.resetCount(1);
// Wait for second notification
listener.await(ofMillis(700));
assertThat(listener.getCount(), equalTo(0));
assertThat(pv.getValue(), equalTo((Object) Arrays.asList(2,3,4)));
}
@Test
public void rateDecoupling() throws Exception {
Queue<Integer> queue = queueOf(Integer.class).maxSize(10);
CountDownPVReaderListener listener = new CountDownPVReaderListener(1);
pv = PVManager.read(queue).from(new MockDataSource()).readListener(listener).maxRate(ofMillis(100));
// Wait for connection
listener.await(ofMillis(200));
assertThat(listener.getCount(), equalTo(0));
listener.resetCount(1);
// No new values, should get no new notification
listener.await(ofMillis(500));
assertThat(listener.getCount(), equalTo(1));
// Add one value, should get one notification
queue.add(1);
listener.await(ofMillis(150));
assertThat(listener.getCount(), equalTo(0));
listener.resetCount(1);
// No new values, should get no new notification
listener.await(ofMillis(500));
assertThat(listener.getCount(), equalTo(1));
listener.resetCount(3);
// Add multiple values, should get at max two notification
queue.add(2);
queue.add(3);
queue.add(4);
queue.add(5);
queue.add(6);
listener.await(ofMillis(500));
assertThat(listener.getCount(), not(equalTo(3)));
assertThat(listener.getCount(), not(equalTo(0)));
}
}