alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (RateLimiterTest.java)

This example Java source code file (RateLimiterTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

androidincompatible, capable, epsilon, fakestopwatch, illegalargumentexception, milliseconds, nanoseconds, now, object, override, random, ratelimiter, reflection, seconds, string, threading, threads, util

The RateLimiterTest.java Java example source code

/*
 * Copyright (C) 2012 The Guava Authors
 *
 * 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 com.google.common.util.concurrent;

import static java.lang.reflect.Modifier.isStatic;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.common.collect.ImmutableClassToInstanceMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.NullPointerTester.Visibility;
import com.google.common.util.concurrent.RateLimiter.SleepingStopwatch;

import junit.framework.TestCase;

import org.easymock.EasyMock;
import org.mockito.Mockito;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Tests for RateLimiter.
 *
 * @author Dimitris Andreou
 */
public class RateLimiterTest extends TestCase {
  private static final double EPSILON = 1e-8;

  private final FakeStopwatch stopwatch = new FakeStopwatch();

  public void testSimple() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    limiter.acquire(); // R0.00, since it's the first request
    limiter.acquire(); // R0.20
    limiter.acquire(); // R0.20
    assertEvents("R0.00", "R0.20", "R0.20");
  }

  public void testImmediateTryAcquire() {
    RateLimiter r = RateLimiter.create(1);
    assertTrue("Unable to acquire initial permit", r.tryAcquire());
    assertFalse("Capable of acquiring secondary permit", r.tryAcquire());
  }

  public void testDoubleMinValueCanAcquireExactlyOnce() {
    RateLimiter r = RateLimiter.create(stopwatch, Double.MIN_VALUE);
    assertTrue("Unable to acquire initial permit", r.tryAcquire());
    assertFalse("Capable of acquiring an additional permit", r.tryAcquire());
    stopwatch.sleepMillis(Integer.MAX_VALUE);
    assertFalse("Capable of acquiring an additional permit after sleeping", r.tryAcquire());
  }

  public void testSimpleRateUpdate() {
    RateLimiter limiter = RateLimiter.create(5.0, 5, SECONDS);
    assertEquals(5.0, limiter.getRate());
    limiter.setRate(10.0);
    assertEquals(10.0, limiter.getRate());

    try {
      limiter.setRate(0.0);
      fail();
    } catch (IllegalArgumentException expected) {}
    try {
      limiter.setRate(-10.0);
      fail();
    } catch (IllegalArgumentException expected) {}
  }

  public void testAcquireParameterValidation() {
    RateLimiter limiter = RateLimiter.create(999);
    try {
      limiter.acquire(0);
      fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
      limiter.acquire(-1);
      fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
      limiter.tryAcquire(0);
      fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
      limiter.tryAcquire(-1);
      fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
      limiter.tryAcquire(0, 1, SECONDS);
      fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
      limiter.tryAcquire(-1, 1, SECONDS);
      fail();
    } catch (IllegalArgumentException expected) {
    }
  }

  public void testSimpleWithWait() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    limiter.acquire();          // R0.00
    stopwatch.sleepMillis(200);    // U0.20, we are ready for the next request...
    limiter.acquire();          // R0.00, ...which is granted immediately
    limiter.acquire();          // R0.20
    assertEvents("R0.00", "U0.20", "R0.00", "R0.20");
  }

  public void testSimpleAcquireReturnValues() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    assertEquals(0.0, limiter.acquire(), EPSILON);  // R0.00
    stopwatch.sleepMillis(200);                     // U0.20, we are ready for the next request...
    assertEquals(0.0, limiter.acquire(), EPSILON);  // R0.00, ...which is granted immediately
    assertEquals(0.2, limiter.acquire(), EPSILON);  // R0.20
    assertEvents("R0.00", "U0.20", "R0.00", "R0.20");
  }

  public void testSimpleAcquireEarliestAvailableIsInPast() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    assertEquals(0.0, limiter.acquire(), EPSILON);
    stopwatch.sleepMillis(400);
    assertEquals(0.0, limiter.acquire(), EPSILON);
    assertEquals(0.0, limiter.acquire(), EPSILON);
    assertEquals(0.2, limiter.acquire(), EPSILON);
  }

  public void testOneSecondBurst() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    stopwatch.sleepMillis(1000); // max capacity reached
    stopwatch.sleepMillis(1000); // this makes no difference
    limiter.acquire(1); // R0.00, since it's the first request

    limiter.acquire(1); // R0.00, from capacity
    limiter.acquire(3); // R0.00, from capacity
    limiter.acquire(1); // R0.00, concluding a burst of 5 permits

    limiter.acquire(); // R0.20, capacity exhausted
    assertEvents("U1.00", "U1.00",
        "R0.00", "R0.00", "R0.00", "R0.00", // first request and burst
        "R0.20");
  }

  public void testCreateWarmupParameterValidation() {
    RateLimiter unused;
    unused = RateLimiter.create(1.0, 1, NANOSECONDS);
    unused = RateLimiter.create(1.0, 0, NANOSECONDS);

    try {
      RateLimiter.create(0.0, 1, NANOSECONDS);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    try {
      RateLimiter.create(1.0, -1, NANOSECONDS);
      fail();
    } catch (IllegalArgumentException expected) {
    }
  }

  @AndroidIncompatible // difference in String.format rounding?
  public void testWarmUp() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 2.0, 4000, MILLISECONDS, 3.0);
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #1
    }
    stopwatch.sleepMillis(500); // #2: to repay for the last acquire
    stopwatch.sleepMillis(4000); // #3: becomes cold again
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // // #4
    }
    stopwatch.sleepMillis(500); // #5: to repay for the last acquire
    stopwatch.sleepMillis(2000); // #6: didn't get cold! It would take another 2 seconds to go cold
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #7
    }
    assertEvents(
        "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
        "U0.50", // #2
        "U4.00", // #3
        "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #4
        "U0.50", // #5
        "U2.00", // #6
        "R0.00, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50"); // #7
  }

  public void testWarmUpWithColdFactor() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0, 4000, MILLISECONDS, 10.0);
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #1
    }
    stopwatch.sleepMillis(200); // #2: to repay for the last acquire
    stopwatch.sleepMillis(4000); // #3: becomes cold again
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // // #4
    }
    stopwatch.sleepMillis(200); // #5: to repay for the last acquire
    stopwatch.sleepMillis(1000); // #6: still warm! It would take another 3 seconds to go cold
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #7
    }
    assertEvents(
        "R0.00, R1.75, R1.26, R0.76, R0.30, R0.20, R0.20, R0.20", // #1
        "U0.20", // #2
        "U4.00", // #3
        "R0.00, R1.75, R1.26, R0.76, R0.30, R0.20, R0.20, R0.20", // #4
        "U0.20", // #5
        "U1.00", // #6
        "R0.00, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20"); // #7
  }

  public void testWarmUpWithColdFactor1() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0, 4000, MILLISECONDS, 1.0);
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #1
    }
    stopwatch.sleepMillis(340); // #2
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #3
    }
    assertEvents(
        "R0.00, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20", // #1
        "U0.34", // #2
        "R0.00, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20"); // #3
  }

  @AndroidIncompatible // difference in String.format rounding?
  public void testWarmUpAndUpdate() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 2.0, 4000, MILLISECONDS, 3.0);
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // // #1
    }
    stopwatch.sleepMillis(4500); // #2: back to cold state (warmup period + repay last acquire)
    for (int i = 0; i < 3; i++) { // only three steps, we're somewhere in the warmup period
      limiter.acquire(); // #3
    }

    limiter.setRate(4.0); // double the rate!
    limiter.acquire(); // #4, we repay the debt of the last acquire (imposed by the old rate)
    for (int i = 0; i < 4; i++) {
      limiter.acquire(); // #5
    }
    stopwatch.sleepMillis(4250); // #6, back to cold state (warmup period + repay last acquire)
    for (int i = 0; i < 11; i++) {
      limiter.acquire(); // #7, showing off the warmup starting from totally cold
    }

    // make sure the areas (times) remain the same, while permits are different
    assertEvents(
        "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
        "U4.50", // #2
        "R0.00, R1.38, R1.13", // #3, after that the rate changes
        "R0.88", // #4, this is what the throttling would be with the old rate
        "R0.34, R0.28, R0.25, R0.25", // #5
        "U4.25", // #6
        "R0.00, R0.72, R0.66, R0.59, R0.53, R0.47, R0.41", // #7
        "R0.34, R0.28, R0.25, R0.25"); // #7 (cont.), note, this matches #5
  }

  public void testWarmUpAndUpdateWithColdFactor() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0, 4000, MILLISECONDS, 10.0);
    for (int i = 0; i < 8; i++) {
      limiter.acquire(); // #1
    }
    stopwatch.sleepMillis(4200); // #2: back to cold state (warmup period + repay last acquire)
    for (int i = 0; i < 3; i++) { // only three steps, we're somewhere in the warmup period
      limiter.acquire(); // #3
    }

    limiter.setRate(10.0); // double the rate!
    limiter.acquire(); // #4, we repay the debt of the last acquire (imposed by the old rate)
    for (int i = 0; i < 4; i++) {
      limiter.acquire(); // #5
    }
    stopwatch.sleepMillis(4100); // #6, back to cold state (warmup period + repay last acquire)
    for (int i = 0; i < 11; i++) {
      limiter.acquire(); // #7, showing off the warmup starting from totally cold
    }

    // make sure the areas (times) remain the same, while permits are different
    assertEvents(
        "R0.00, R1.75, R1.26, R0.76, R0.30, R0.20, R0.20, R0.20", // #1
        "U4.20", // #2
        "R0.00, R1.75, R1.26", // #3, after that the rate changes
        "R0.76", // #4, this is what the throttling would be with the old rate
        "R0.20, R0.10, R0.10, R0.10", // #5
        "U4.10", // #6
        "R0.00, R0.94, R0.81, R0.69, R0.57, R0.44, R0.32", // #7
        "R0.20, R0.10, R0.10, R0.10"); // #7 (cont.), note, this matches #5
  }

  public void testBurstyAndUpdate() {
    RateLimiter rateLimiter = RateLimiter.create(stopwatch, 1.0);
    rateLimiter.acquire(1); // no wait
    rateLimiter.acquire(1); // R1.00, to repay previous

    rateLimiter.setRate(2.0); // update the rate!

    rateLimiter.acquire(1); // R1.00, to repay previous (the previous was under the old rate!)
    rateLimiter.acquire(2); // R0.50, to repay previous (now the rate takes effect)
    rateLimiter.acquire(4); // R1.00, to repay previous
    rateLimiter.acquire(1); // R2.00, to repay previous
    assertEvents("R0.00", "R1.00", "R1.00", "R0.50", "R1.00", "R2.00");
  }

  public void testTryAcquire_noWaitAllowed() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    assertTrue(limiter.tryAcquire(0, SECONDS));
    assertFalse(limiter.tryAcquire(0, SECONDS));
    assertFalse(limiter.tryAcquire(0, SECONDS));
    stopwatch.sleepMillis(100);
    assertFalse(limiter.tryAcquire(0, SECONDS));
  }

  public void testTryAcquire_someWaitAllowed() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    assertTrue(limiter.tryAcquire(0, SECONDS));
    assertTrue(limiter.tryAcquire(200, MILLISECONDS));
    assertFalse(limiter.tryAcquire(100, MILLISECONDS));
    stopwatch.sleepMillis(100);
    assertTrue(limiter.tryAcquire(100, MILLISECONDS));
  }

  public void testTryAcquire_overflow() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    assertTrue(limiter.tryAcquire(0, MICROSECONDS));
    stopwatch.sleepMillis(100);
    assertTrue(limiter.tryAcquire(Long.MAX_VALUE, MICROSECONDS));
  }

  public void testTryAcquire_negative() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 5.0);
    assertTrue(limiter.tryAcquire(5, 0, SECONDS));
    stopwatch.sleepMillis(900);
    assertFalse(limiter.tryAcquire(1, Long.MIN_VALUE, SECONDS));
    stopwatch.sleepMillis(100);
    assertTrue(limiter.tryAcquire(1, -1, SECONDS));
  }

  public void testSimpleWeights() {
    RateLimiter rateLimiter = RateLimiter.create(stopwatch, 1.0);
    rateLimiter.acquire(1); // no wait
    rateLimiter.acquire(1); // R1.00, to repay previous
    rateLimiter.acquire(2); // R1.00, to repay previous
    rateLimiter.acquire(4); // R2.00, to repay previous
    rateLimiter.acquire(8); // R4.00, to repay previous
    rateLimiter.acquire(1); // R8.00, to repay previous
    assertEvents("R0.00", "R1.00", "R1.00", "R2.00", "R4.00", "R8.00");
  }

  public void testInfinity_Bursty() {
    RateLimiter limiter = RateLimiter.create(stopwatch, Double.POSITIVE_INFINITY);
    limiter.acquire(Integer.MAX_VALUE / 4);
    limiter.acquire(Integer.MAX_VALUE / 2);
    limiter.acquire(Integer.MAX_VALUE);
    assertEvents("R0.00", "R0.00", "R0.00"); // no wait, infinite rate!

    limiter.setRate(2.0);
    limiter.acquire();
    limiter.acquire();
    limiter.acquire();
    limiter.acquire();
    limiter.acquire();
    assertEvents(
        "R0.00", // First comes the saved-up burst, which defaults to a 1-second burst (2 requests).
        "R0.00",
        "R0.00", // Now comes the free request.
        "R0.50", // Now it's 0.5 seconds per request.
        "R0.50");

    limiter.setRate(Double.POSITIVE_INFINITY);
    limiter.acquire();
    limiter.acquire();
    limiter.acquire();
    assertEvents("R0.50", "R0.00", "R0.00"); // we repay the last request (.5sec), then back to +oo
  }

  /** https://code.google.com/p/guava-libraries/issues/detail?id=1791 */
  public void testInfinity_BustyTimeElapsed() {
    RateLimiter limiter = RateLimiter.create(stopwatch, Double.POSITIVE_INFINITY);
    stopwatch.instant += 1000000;
    limiter.setRate(2.0);
    for (int i = 0; i < 5; i++) {
      limiter.acquire();
    }
    assertEvents(
        "R0.00", // First comes the saved-up burst, which defaults to a 1-second burst (2 requests).
        "R0.00",
        "R0.00", // Now comes the free request.
        "R0.50", // Now it's 0.5 seconds per request.
        "R0.50");
  }

  public void testInfinity_WarmUp() {
    RateLimiter limiter = RateLimiter.create(
        stopwatch, Double.POSITIVE_INFINITY, 10, SECONDS, 3.0);
    limiter.acquire(Integer.MAX_VALUE / 4);
    limiter.acquire(Integer.MAX_VALUE / 2);
    limiter.acquire(Integer.MAX_VALUE);
    assertEvents("R0.00", "R0.00", "R0.00");

    limiter.setRate(1.0);
    limiter.acquire();
    limiter.acquire();
    limiter.acquire();
    assertEvents("R0.00", "R1.00", "R1.00");

    limiter.setRate(Double.POSITIVE_INFINITY);
    limiter.acquire();
    limiter.acquire();
    limiter.acquire();
    assertEvents("R1.00", "R0.00", "R0.00");
  }

  public void testInfinity_WarmUpTimeElapsed() {
    RateLimiter limiter = RateLimiter.create(stopwatch, Double.POSITIVE_INFINITY, 10, SECONDS, 3.0);
    stopwatch.instant += 1000000;
    limiter.setRate(1.0);
    for (int i = 0; i < 5; i++) {
      limiter.acquire();
    }
    assertEvents("R0.00", "R1.00", "R1.00", "R1.00", "R1.00");
  }

  /**
   * Make sure that bursts can never go above 1-second-worth-of-work for the current
   * rate, even when we change the rate.
   */
  public void testWeNeverGetABurstMoreThanOneSec() {
    RateLimiter limiter = RateLimiter.create(stopwatch, 1.0);
    int[] rates = { 1000, 1, 10, 1000000, 10, 1};
    for (int rate : rates) {
      int oneSecWorthOfWork = rate;
      stopwatch.sleepMillis(rate * 1000);
      limiter.setRate(rate);
      long burst = measureTotalTimeMillis(limiter, oneSecWorthOfWork, new Random());
      // we allow one second worth of work to go in a burst (i.e. take less than a second)
      assertTrue(burst <= 1000);
      long afterBurst = measureTotalTimeMillis(limiter, oneSecWorthOfWork, new Random());
      // but work beyond that must take at least one second
      assertTrue(afterBurst >= 1000);
    }
  }

  /**
   * This neat test shows that no matter what weights we use in our requests, if we push X
   * amount of permits in a cool state, where X = rate * timeToCoolDown, and we have
   * specified a timeToWarmUp() period, it will cost as the prescribed amount of time. E.g.,
   * calling [acquire(5), acquire(1)] takes exactly the same time as
   * [acquire(2), acquire(3), acquire(1)].
   */
  public void testTimeToWarmUpIsHonouredEvenWithWeights() {
    Random random = new Random();
    int warmupPermits = 10;
    double[] coldFactorsToTest = { 2.0, 3.0, 10.0 };
    double[] qpsToTest = { 4.0, 2.0, 1.0, 0.5, 0.1 };
    for (int trial = 0; trial < 100; trial++) {
      for (double coldFactor : coldFactorsToTest) {
        for (double qps : qpsToTest) {
          // If warmupPermits = maxPermits - thresholdPermits then
          // warmupPeriod = (1 + coldFactor) * warmupPermits * stableInterval / 2
          long warmupMillis = (long) ((1 + coldFactor) * warmupPermits / (2.0 * qps) * 1000.0);
          RateLimiter rateLimiter = RateLimiter.create(
              stopwatch, qps, warmupMillis, MILLISECONDS, coldFactor);
          assertEquals(warmupMillis, measureTotalTimeMillis(rateLimiter, warmupPermits, random));
        }
      }
    }
  }

  public void testNulls() {
    NullPointerTester tester = new NullPointerTester()
        .setDefault(SleepingStopwatch.class, stopwatch)
        .setDefault(int.class, 1)
        .setDefault(double.class, 1.0d);
    tester.testStaticMethods(RateLimiter.class, Visibility.PACKAGE);
    tester.testInstanceMethods(RateLimiter.create(stopwatch, 5.0), Visibility.PACKAGE);
  }

  private long measureTotalTimeMillis(RateLimiter rateLimiter, int permits, Random random) {
    long startTime = stopwatch.instant;
    while (permits > 0) {
      int nextPermitsToAcquire = Math.max(1, random.nextInt(permits));
      permits -= nextPermitsToAcquire;
      rateLimiter.acquire(nextPermitsToAcquire);
    }
    rateLimiter.acquire(1); // to repay for any pending debt
    return NANOSECONDS.toMillis(stopwatch.instant - startTime);
  }

  private void assertEvents(String... events) {
    assertEquals(Arrays.toString(events), stopwatch.readEventsAndClear());
  }

  /**
   * The stopwatch gathers events and presents them as strings.
   * R0.6 means a delay of 0.6 seconds caused by the (R)ateLimiter
   * U1.0 means the (U)ser caused the stopwatch to sleep for a second.
   */
  static class FakeStopwatch extends SleepingStopwatch {
    long instant = 0L;
    final List<String> events = Lists.newArrayList();

    @Override
    public long readMicros() {
      return NANOSECONDS.toMicros(instant);
    }

    void sleepMillis(int millis) {
      sleepMicros("U", MILLISECONDS.toMicros(millis));
    }

    void sleepMicros(String caption, long micros) {
      instant += MICROSECONDS.toNanos(micros);
      events.add(caption + String.format(Locale.ROOT, "%3.2f", (micros / 1000000.0)));
    }

    @Override
    protected void sleepMicrosUninterruptibly(long micros) {
      sleepMicros("R", micros);
    }

    String readEventsAndClear() {
      try {
        return events.toString();
      } finally {
        events.clear();
      }
    }

    @Override
    public String toString() {
      return events.toString();
    }
  }

  /*
   * Note: Mockito appears to lose its ability to Mock doGetRate as of Android 21. If we start
   * testing with that version or newer, we'll need to suppress this test (or see if Mockito can be
   * changed to support this).
   */
  public void testMockingMockito() throws Exception {
    RateLimiter mock = Mockito.mock(RateLimiter.class);
    doTestMocking(mock);
  }

  @AndroidIncompatible // EasyMock Class Extension doesn't appear to work on Android.
  public void testMockingEasyMock() throws Exception {
    RateLimiter mock = EasyMock.createNiceMock(RateLimiter.class);
    EasyMock.replay(mock);
    doTestMocking(mock);
  }

  private static void doTestMocking(RateLimiter mock) throws Exception {
    for (Method method : RateLimiter.class.getMethods()) {
      if (!isStatic(method.getModifiers())
          && !NOT_WORKING_ON_MOCKS.contains(method.getName())
          && !method.getDeclaringClass().equals(Object.class)) {
        method.invoke(mock, arbitraryParameters(method));
      }
    }
  }

  private static Object[] arbitraryParameters(Method method) {
    Class<?>[] parameterTypes = method.getParameterTypes();
    Object[] params = new Object[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; i++) {
      params[i] = PARAMETER_VALUES.get(parameterTypes[i]);
    }
    return params;
  }

  private static final ImmutableSet<String> NOT_WORKING_ON_MOCKS =
      ImmutableSet.of("latestPermitAgeSec", "setRate", "getAvailablePermits");

  // We would use ArbitraryInstances, but it returns 0, invalid for many RateLimiter methods.
  private static final ImmutableClassToInstanceMap<Object> PARAMETER_VALUES =
      ImmutableClassToInstanceMap.builder()
          .put(int.class, 1)
          .put(long.class, 1L)
          .put(double.class, 1.0)
          .put(TimeUnit.class, SECONDS)
          .build();
}

Other Java examples (source code examples)

Here is a short list of links related to this Java RateLimiterTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.