@Test public void queuePollTracksOnNext() { //prepare registry with mock clock MockClock clock = new MockClock(); removeRegistry(); registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock); Metrics.globalRegistry.add(registry); AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create(); MicrometerFluxMetricsFuseableSubscriber<Integer> fuseableSubscriber = new MicrometerFluxMetricsFuseableSubscriber<>(testSubscriber, registry, clock, "foo", Collections.emptyList()); Fuseable.QueueSubscription<Integer> testQueue = new FluxPeekFuseableTest.AssertQueueSubscription<>(); testQueue.offer(1); fuseableSubscriber.onSubscribe(testQueue); clock.add(Duration.ofMillis(200)); Integer val1 = fuseableSubscriber.poll(); Integer val2 = fuseableSubscriber.poll(); assertThat(val1).isEqualTo(1); assertThat(val2).isNull(); //test meters Timer nextTimer = registry.find(METER_ON_NEXT_DELAY) .timer(); assertThat(nextTimer).isNotNull(); assertThat(nextTimer.max(TimeUnit.MILLISECONDS)).as("onNext max delay").isEqualTo(200); }
@Test public void queuePollSyncTracksOnComplete() { //prepare registry with mock clock MockClock clock = new MockClock(); removeRegistry(); registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock); Metrics.globalRegistry.add(registry); AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create(); MicrometerFluxMetricsFuseableSubscriber<Integer> fuseableSubscriber = new MicrometerFluxMetricsFuseableSubscriber<>(testSubscriber, registry, clock, "foo", Collections.emptyList()); Fuseable.QueueSubscription<Integer> testQueue = new FluxPeekFuseableTest.AssertQueueSubscription<>(); testQueue.offer(1); fuseableSubscriber.onSubscribe(testQueue); fuseableSubscriber.requestFusion(Fuseable.SYNC); clock.add(Duration.ofMillis(200)); Integer val1 = fuseableSubscriber.poll(); clock.add(Duration.ofMillis(123)); Integer val2 = fuseableSubscriber.poll(); assertThat(val1).isEqualTo(1); assertThat(val2).isNull(); //test meters Timer terminationTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); assertThat(terminationTimer).isNotNull(); assertThat(terminationTimer.max(TimeUnit.MILLISECONDS)).as("terminate max delay").isEqualTo(323); }
@Test public void queuePollSyncTracksOnComplete() { //prepare registry with mock clock MockClock clock = new MockClock(); removeRegistry(); registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock); Metrics.globalRegistry.add(registry); AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create(); MicrometerMonoMetricsFuseableSubscriber<Integer> fuseableSubscriber = new MicrometerMonoMetricsFuseableSubscriber<>(testSubscriber, registry, clock, "foo", Collections.emptyList()); Fuseable.QueueSubscription<Integer> testQueue = new FluxPeekFuseableTest.AssertQueueSubscription<>(); testQueue.offer(1); fuseableSubscriber.onSubscribe(testQueue); fuseableSubscriber.requestFusion(Fuseable.SYNC); clock.add(Duration.ofMillis(200)); Integer val1 = fuseableSubscriber.poll(); clock.add(Duration.ofMillis(123)); Integer val2 = fuseableSubscriber.poll(); assertThat(val1).isEqualTo(1); assertThat(val2).isNull(); //test meters Timer terminationTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); assertThat(terminationTimer).isNotNull(); assertThat(terminationTimer.max(TimeUnit.MILLISECONDS)).as("terminate max delay").isEqualTo(323); }
@Test public void subscribeToComplete() { Mono<Long> source = Mono.delay(Duration.ofMillis(100)) .hide(); new MonoMetrics<>(source, registry) .block(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isGreaterThanOrEqualTo(100); assertThat(stcErrorTimer) .as("subscribe to error timer is lazily registered") .isNull(); assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isZero(); }
@Test public void subscribeToErrorFuseable() { Mono<Long> source = Mono.delay(Duration.ofMillis(100)) .map(v -> 100 / v); new MonoMetricsFuseable<>(source, registry) .onErrorReturn(-1L) .block(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to error timer") .isGreaterThanOrEqualTo(100); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isZero(); }); }
@Test public void subscribeToError() { Mono<Long> source = Mono.delay(Duration.ofMillis(100)) .map(v -> 100 / v) .hide(); new MonoMetrics<>(source, registry) .onErrorReturn(-1L) .block(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to error timer") .isGreaterThanOrEqualTo(100); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isZero(); }); }
@Test public void queuePollError() { //prepare registry with mock clock MockClock clock = new MockClock(); removeRegistry(); registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock); Metrics.globalRegistry.add(registry); AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create(); MicrometerMonoMetricsFuseableSubscriber<Integer> fuseableSubscriber = new MicrometerMonoMetricsFuseableSubscriber<>(testSubscriber, registry, clock, "foo", Collections.emptyList()); FluxPeekFuseableTest.AssertQueueSubscription<Integer> testQueue = new FluxPeekFuseableTest.AssertQueueSubscription<>(); testQueue.setCompleteWithError(true); testQueue.offer(1); fuseableSubscriber.onSubscribe(testQueue); fuseableSubscriber.requestFusion(Fuseable.SYNC); clock.add(Duration.ofMillis(200)); Integer val1 = fuseableSubscriber.poll(); assertThat(val1).isEqualTo(1); clock.add(Duration.ofMillis(123)); assertThatIllegalStateException().isThrownBy(fuseableSubscriber::poll) .withMessage("AssertQueueSubscriber poll error"); //test meters Timer terminationTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); assertThat(terminationTimer).isNotNull(); assertThat(terminationTimer.max(TimeUnit.MILLISECONDS)).as("terminate max delay").isEqualTo(323); }
@Test public void queuePollError() { //prepare registry with mock clock MockClock clock = new MockClock(); removeRegistry(); registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock); Metrics.globalRegistry.add(registry); AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create(); MicrometerFluxMetricsFuseableSubscriber<Integer> fuseableSubscriber = new MicrometerFluxMetricsFuseableSubscriber<>(testSubscriber, registry, clock, "foo", Collections.emptyList()); FluxPeekFuseableTest.AssertQueueSubscription<Integer> testQueue = new FluxPeekFuseableTest.AssertQueueSubscription<>(); testQueue.setCompleteWithError(true); testQueue.offer(1); fuseableSubscriber.onSubscribe(testQueue); fuseableSubscriber.requestFusion(Fuseable.SYNC); clock.add(Duration.ofMillis(200)); Integer val1 = fuseableSubscriber.poll(); assertThat(val1).isEqualTo(1); clock.add(Duration.ofMillis(123)); assertThatIllegalStateException().isThrownBy(fuseableSubscriber::poll) .withMessage("AssertQueueSubscriber poll error"); //test meters Timer terminationTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); assertThat(terminationTimer).isNotNull(); assertThat(terminationTimer.max(TimeUnit.MILLISECONDS)).as("terminate max delay").isEqualTo(323); }
@Test public void subscribeToErrorFuseable() { //not really fuseable, goes through onError path, but tests FluxMetricsFuseable at least Flux<Long> source = Flux.just(0L) .delayElements(Duration.ofMillis(100)) .map(v -> 100 / v); new FluxMetricsFuseable<>(source, registry) .onErrorReturn(-1L) .blockLast(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to error timer") .isGreaterThanOrEqualTo(100); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isZero(); }); }
@Test public void subscribeToError() { Flux<Integer> source = Flux.just(1, 0) .delayElements(Duration.ofMillis(100)) .map(v -> 100 / v) .hide(); new FluxMetrics<>(source, registry) .onErrorReturn(-1) .blockLast(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to error timer") .isGreaterThanOrEqualTo(100); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isZero(); }); }
@Test public void subscribeToCancelFuseable() throws InterruptedException { Mono<String> source = Mono.delay(Duration.ofMillis(200)) .map(i -> "foo"); Disposable disposable = new MonoMetricsFuseable<>(source, registry).subscribe(); Thread.sleep(100); disposable.dispose(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer) .as("subscribe to error timer is lazily registered") .isNull(); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isGreaterThanOrEqualTo(100); }); }
@Test public void subscribeToCancel() throws InterruptedException { Mono<Long> source = Mono.delay(Duration.ofMillis(200)) .hide(); Disposable disposable = new MonoMetrics<>(source, registry).subscribe(); Thread.sleep(100); disposable.dispose(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer) .as("subscribe to error timer is lazily registered") .isNull(); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isGreaterThanOrEqualTo(100); }); }
@Test public void subscribeToComplete() { Flux<String> source = Flux.just("foo") .delayElements(Duration.ofMillis(100)) .hide(); new FluxMetrics<>(source, registry) .blockLast(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isGreaterThanOrEqualTo(100); softly.assertThat(stcErrorTimer) .as("subscribe to error timer is lazily registered") .isNull(); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isZero(); }); }
@Test public void subscribeToCancel() { Flux<Integer> source = Flux.just(1, 0) .delayElements(Duration.ofMillis(100)) .hide(); new FluxMetrics<>(source, registry) .take(1) .blockLast(); Timer stcCompleteTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_COMPLETE) .timer(); Timer stcErrorTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_ON_ERROR) .timer(); Timer stcCancelTimer = registry.find(METER_FLOW_DURATION) .tag(TAG_STATUS, TAGVALUE_CANCEL) .timer(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(stcCompleteTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to complete timer") .isZero(); softly.assertThat(stcErrorTimer) .as("subscribe to error timer is lazily registered") .isNull(); softly.assertThat(stcCancelTimer.max(TimeUnit.MILLISECONDS)) .as("subscribe to cancel timer") .isGreaterThanOrEqualTo(100); }); }
private static JsonObject timerToJson(JsonObject obj, Timer timer) { return obj.put("type", "timer") .put("count", timer.count()) .put("totalTimeMs", timer.totalTime(TimeUnit.MILLISECONDS)) .put("meanMs", timer.mean(TimeUnit.MILLISECONDS)) .put("maxMs", timer.max(TimeUnit.MILLISECONDS)); }
assertNotNull(clientTimer); assertEquals(1, clientTimer.count()); assertTrue(clientTimer.max(TimeUnit.SECONDS) < 1); assertNotNull(serverTimer); assertEquals(1, serverTimer.count()); assertTrue(serverTimer.max(TimeUnit.SECONDS) < 1); assertTrue(serverTimer.max(TimeUnit.SECONDS) <= clientTimer.max(TimeUnit.SECONDS)); assertEquals(2, responseReceivedCounter.count()); assertEquals(2, clientTimer.count()); assertTrue(clientTimer.max(TimeUnit.SECONDS) < 1); assertEquals(2, responsesSentCounter.count()); assertEquals(2, serverTimer.count()); assertTrue(serverTimer.max(TimeUnit.SECONDS) < 1); assertTrue(serverTimer.max(TimeUnit.SECONDS) <= clientTimer.max(TimeUnit.SECONDS)); log.info("--- Test completed ---");
assertNotNull(clientTimer); assertEquals(1, clientTimer.count()); assertTrue(clientTimer.max(TimeUnit.SECONDS) < 1); assertNotNull(serverTimer); assertEquals(1, serverTimer.count()); assertTrue(serverTimer.max(TimeUnit.SECONDS) < 1); assertTrue(serverTimer.max(TimeUnit.SECONDS) <= clientTimer.max(TimeUnit.SECONDS)); log.info("--- Test completed ---");
private Stream<String> writeTimer(Timer timer) { final long wallTime = clock.wallTime(); final Stream.Builder<String> metrics = Stream.builder(); Meter.Id id = timer.getId(); addMetric(metrics, id, "sum", wallTime, timer.totalTime(getBaseTimeUnit())); addMetric(metrics, id, "count", wallTime, timer.count()); addMetric(metrics, id, "avg", wallTime, timer.mean(getBaseTimeUnit())); addMetric(metrics, id, "max", wallTime, timer.max(getBaseTimeUnit())); return metrics.build(); }