TimestampTracker { @VisibleForTesting static void registerTimestampForTracking( Clock clock, MetricsManager metricsManager, String shortName, Supplier<Long> supplier) { metricsManager.registerMetric( TimestampTracker.class, shortName, TrackerUtils.createCachingMonotonicIncreasingGauge(log, clock, shortName, supplier)); } private  TimestampTracker(); static void instrumentTimestamps(
            MetricsManager metricsManager, TimelockService timeLockService, Cleaner cleaner);  }
@Test public void doesNotCallSupplierOnRequestsWithinRetriggerInterval() { when(mockClock.getTick()).thenReturn(0L, 1L, 2L); AtomicLong timestampValue = new AtomicLong(0L); TimestampTracker.registerTimestampForTracking( mockClock, metricsManager, FAKE_METRIC, timestampValue::incrementAndGet); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); }
@Test public void callsSupplierAgainAfterTimeElapses() { when(mockClock.getTick()).thenReturn(0L, CACHE_INTERVAL_NANOS - 1, CACHE_INTERVAL_NANOS + 1); AtomicLong timestampValue = new AtomicLong(0L); TimestampTracker.registerTimestampForTracking( mockClock, metricsManager, FAKE_METRIC, timestampValue::incrementAndGet); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(2L); }
@Test public void doesNotCallSupplierUnlessGaugeIsQueried() { when(mockClock.getTick()).thenReturn(0L, CACHE_INTERVAL_NANOS * 50000); AtomicLong timestampValue = new AtomicLong(0L); TimestampTracker.registerTimestampForTracking( mockClock, metricsManager, FAKE_METRIC, timestampValue::incrementAndGet); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(1L); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(2L); }
@Test public void timestampTrackersDoNotThrowEvenIfUnderlyingSupplierThrows() { when(mockClock.getTick()).thenReturn(0L, CACHE_INTERVAL_NANOS); TimestampTracker.registerTimestampForTracking(mockClock, metricsManager, FAKE_METRIC, () -> { throw new IllegalArgumentException("illegal argument"); }); getGauge(FAKE_METRIC).getValue(); }
@Test public void timestampTrackersReturnTheLastKnownValueIfUnderlyingSupplierThrows() { when(mockClock.getTick()).thenReturn(0L, CACHE_INTERVAL_NANOS + 1); TimestampTracker.registerTimestampForTracking(mockClock, metricsManager, FAKE_METRIC, new Supplier<Long>() { private boolean allowRequest = true; @Override public Long get() { Preconditions.checkArgument(allowRequest, "not allowed"); allowRequest = false; return FORTY_TWO; } }); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(FORTY_TWO); assertThat(getGauge(FAKE_METRIC).getValue()).isEqualTo(FORTY_TWO); }
@Test public void doesNotThrowIfMetricsAreAccidentallyRegisteredMultipleTimes() { TimestampTracker.registerTimestampForTracking(mockClock, metricsManager, FAKE_METRIC, () -> 1L); TimestampTracker.registerTimestampForTracking(mockClock, metricsManager, FAKE_METRIC, () -> 2L); assertThat(getGauge(FAKE_METRIC).getValue()).isIn(1L, 2L); }