001package ch.qos.logback.core.util;
002
003import static ch.qos.logback.core.util.DefaultInvocationGate.DEFAULT_MASK;
004import static ch.qos.logback.core.util.DefaultInvocationGate.MASK_DECREASE_RIGHT_SHIFT_COUNT;
005import static org.junit.Assert.*;
006
007import org.junit.Test;
008
009public class DefaultInvocationGateTest {
010
011    @Test
012    public void smoke() {
013        long currentTime = 0;
014        long minDelayThreshold = 4;
015        long maxDelayThreshold = 8;
016
017        DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
018        assertTrue(gate.isTooSoon(0));
019    }
020
021    @Test
022    public void closelyRepeatedCallsShouldCauseMaskToIncrease() {
023        long currentTime = 0;
024        long minDelayThreshold = 4;
025        long maxDelayThreshold = 8;
026
027        DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
028        for (int i = 0; i < DEFAULT_MASK; i++) {
029            assertTrue(gate.isTooSoon(0));
030        }
031        assertFalse(gate.isTooSoon(0));
032        assertTrue(gate.getMask() > DEFAULT_MASK);
033    }
034
035    @Test
036    public void stableAtSteadyRate() {
037        long currentTime = 0;
038        long minDelayThreshold = DEFAULT_MASK;
039        long maxDelayThreshold = DEFAULT_MASK * 2;
040
041        DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
042
043        for (int t = 0; t < 4 * minDelayThreshold; t++) {
044            gate.isTooSoon(currentTime++);
045            assertEquals(DEFAULT_MASK, gate.getMask());
046        }
047    }
048
049    @Test
050    public void intermittentCallsShouldCauseMaskToDecrease() {
051        long currentTime = 0;
052        long minDelayThreshold = 4;
053        long maxDelayThreshold = 8;
054
055        DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
056        int currentMask = DEFAULT_MASK;
057
058        currentTime += maxDelayThreshold + 1;
059        assertFalse(gate.isTooSoon(currentTime));
060        assertTrue(gate.getMask() < currentMask);
061    }
062
063    @Test
064    public void maskCanDropToZeroForInfrequentInvocations() {
065        long currentTime = 0;
066        long minDelayThreshold = 4;
067        long maxDelayThreshold = 8;
068
069        DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
070        int currentMask = DEFAULT_MASK;
071
072        do {
073            currentTime += maxDelayThreshold + 1;
074            assertFalse(gate.isTooSoon(currentTime));
075            assertTrue(gate.getMask() < currentMask);
076            currentMask = currentMask >> MASK_DECREASE_RIGHT_SHIFT_COUNT;
077        } while (currentMask > 0);
078
079        assertEquals(0, gate.getMask());
080        assertFalse(gate.isTooSoon(currentTime));
081    }
082}