### Question:
PassiveScanDecoupler extends SourceDesiredRateDecoupler { @Override void newValueEvent() { newEvent(DesiredRateEvent.Type.VALUE); } PassiveScanDecoupler(ScheduledExecutorService scannerExecutor,
            Duration maxDuration, DesiredRateEventListener listener);   }### Answer:
@Test public void slowEvents() throws Exception { repeatTest(10, new Callable<Object>() { @Override public Object call() throws Exception { DesiredRateEventLog log = new DesiredRateEventLog(); SourceDesiredRateDecoupler decoupler = new PassiveScanDecoupler(PVManager.getReadScannerExecutorService(), TimeDuration.ofHertz(50), log); log.setDecoupler(decoupler); decoupler.start(); Thread.sleep(100); decoupler.newValueEvent(); Thread.sleep(100); decoupler.newValueEvent(); Thread.sleep(100); decoupler.newValueEvent(); Thread.sleep(100); decoupler.stop(); assertThat(log.getEvents().size(), equalTo(4)); return null; } }); }
@Test public void fastEvents() throws Exception { repeatTest(10, new Callable<Object>() { @Override public Object call() throws Exception { log = new DesiredRateEventLog(); SourceDesiredRateDecoupler decoupler = new PassiveScanDecoupler(PVManager.getReadScannerExecutorService(), TimeDuration.ofHertz(10), log); log.setDecoupler(decoupler); decoupler.start(); Thread.sleep(100); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(1); decoupler.newValueEvent(); Thread.sleep(100); decoupler.stop(); assertThat(log.getEvents().size(), equalTo(3)); return null; } }); }
@Test public void rescheduling() throws Exception { repeatTest(10, new Callable<Object>() { @Override public Object call() throws Exception { log = new DesiredRateEventLog(10); SourceDesiredRateDecoupler decoupler = new PassiveScanDecoupler(PVManager.getReadScannerExecutorService(), TimeDuration.ofHertz(20), log); log.setDecoupler(decoupler); decoupler.start(); Thread.sleep(60); long startTime = System.nanoTime(); for (int i = 0; i < 4*5+2; i++) { decoupler.newValueEvent(); Thread.sleep(10); } long period = System.nanoTime() - startTime; Thread.sleep(100); decoupler.stop(); int expectedEvents = (int) (period / 50000000) + 1 + 1; assertThat(log.getEvents().size(), isOneOf(expectedEvents, expectedEvents + 1)); return null; } }); }
@Test public void slowResponse() throws Exception { repeatTest(10, new Callable<Object>() { @Override public Object call() throws Exception { log = new DesiredRateEventLog(100); SourceDesiredRateDecoupler decoupler = new PassiveScanDecoupler(PVManager.getReadScannerExecutorService(), TimeDuration.ofHertz(50), log); log.setDecoupler(decoupler); decoupler.start(); Thread.sleep(125); decoupler.newValueEvent(); Thread.sleep(25); decoupler.newValueEvent(); Thread.sleep(25); decoupler.newValueEvent(); Thread.sleep(500); decoupler.stop(); assertThat(log.getEvents().size(), equalTo(3)); return null; } }); }