16
16
17
17
package io .micrometer .tracing .test ;
18
18
19
- import java .util .ArrayList ;
20
- import java .util .Arrays ;
21
- import java .util .Deque ;
22
- import java .util .List ;
23
- import java .util .Locale ;
24
- import java .util .concurrent .CopyOnWriteArrayList ;
25
- import java .util .function .BiConsumer ;
26
-
27
19
import io .micrometer .common .util .StringUtils ;
28
20
import io .micrometer .common .util .internal .logging .InternalLogger ;
29
21
import io .micrometer .common .util .internal .logging .InternalLoggerFactory ;
33
25
import io .micrometer .observation .Observation ;
34
26
import io .micrometer .observation .ObservationHandler ;
35
27
import io .micrometer .observation .ObservationRegistry ;
28
+ import io .micrometer .observation .ObservationRegistry .ObservationConfig ;
36
29
import io .micrometer .observation .TestConfigAccessor ;
37
30
import io .micrometer .tracing .Tracer ;
38
31
import io .micrometer .tracing .handler .TracingObservationHandler ;
43
36
import io .micrometer .tracing .test .reporter .wavefront .WavefrontOtelSetup ;
44
37
import io .micrometer .tracing .test .reporter .zipkin .ZipkinBraveSetup ;
45
38
import io .micrometer .tracing .test .reporter .zipkin .ZipkinOtelSetup ;
46
- import org .junit .jupiter .api .AfterAll ;
47
39
import org .junit .jupiter .api .AfterEach ;
48
40
import org .junit .jupiter .api .Assertions ;
49
41
import org .junit .jupiter .api .Assumptions ;
53
45
import zipkin2 .CheckResult ;
54
46
import zipkin2 .reporter .Sender ;
55
47
48
+ import java .util .ArrayList ;
49
+ import java .util .Arrays ;
50
+ import java .util .Deque ;
51
+ import java .util .List ;
52
+ import java .util .Locale ;
53
+ import java .util .function .BiConsumer ;
54
+
56
55
/**
57
56
* Prepares the required tracing setup and reporters / exporters. The user needs to just
58
57
* provide the code to test and that way all the combinations of tracers and exporters
59
58
* will be automatically applied. It also sets up the {@link MeterRegistry} in such a way
60
59
* that it consists all {@link TracingObservationHandler} injected into
61
60
* {@link ObservationRegistry#observationConfig()}.
62
61
* <p>
63
- * When extending this class you can either eagerly pass the {@link MeterRegistry} and
64
- * {@link SampleRunnerConfig} by calling this class' constructors. Another option is to
65
- * lazilly load those objects. To do it use the default constructor but override
66
- * {@link SampleTestRunner#getMeterRegistry()} and
67
- * {@link SampleTestRunner#getSampleRunnerConfig()} methods and provide your own ways of
68
- * retrieving {@link MeterRegistry} and {@link SampleRunnerConfig}.
62
+ * When extending this class you can eagerly pass the {@link SampleRunnerConfig} by
63
+ * calling this class' constructors. Different registry instances can be provided by
64
+ * overriding {@link SampleTestRunner#createMeterRegistry()} and/or
65
+ * {@link SampleTestRunner#createObservationRegistry()}.
69
66
*
70
67
* @author Marcin Grzejszczak
71
68
* @since 1.0.0
@@ -74,57 +71,40 @@ public abstract class SampleTestRunner {
74
71
75
72
private static final InternalLogger log = InternalLoggerFactory .getInstance (SampleTestRunner .class );
76
73
77
- private static final List <MeterRegistry > meterRegistries = new CopyOnWriteArrayList <>();
78
-
79
74
private SampleRunnerConfig sampleRunnerConfig ;
80
75
81
76
private ObservationRegistry observationRegistry ;
82
77
83
78
private MeterRegistry meterRegistry ;
84
79
85
- private final List <ObservationHandler <?>> observationHandlersCopy ;
86
-
87
80
/**
88
- * Creates a new instance of the {@link SampleTestRunner} with a pre-created
89
- * configuration and {@link MeterRegistry}.
81
+ * Creates a new instance of the {@link SampleTestRunner}.
90
82
* @param sampleRunnerConfig configuration for the SampleTestRunner
91
- * @param observationRegistry provided {@link ObservationRegistry} instance
92
- * @param meterRegistry provided {@link MeterRegistry} instance
93
83
*/
94
- public SampleTestRunner (SampleRunnerConfig sampleRunnerConfig , ObservationRegistry observationRegistry ,
95
- MeterRegistry meterRegistry ) {
84
+ public SampleTestRunner (SampleRunnerConfig sampleRunnerConfig ) {
96
85
this .sampleRunnerConfig = sampleRunnerConfig ;
97
- this .observationRegistry = observationRegistry ;
98
- this .meterRegistry = meterRegistry ;
99
- this .observationHandlersCopy = new ArrayList <>();
100
86
}
101
87
102
88
/**
103
- * Creates a new instance of the {@link SampleTestRunner} with a pre-created
104
- * configuration and a default {@link MeterRegistry}.
105
- * @param sampleRunnerConfig configuration for the SampleTestRunner
89
+ * Creates a new instance of the {@link SampleTestRunner} with a default
90
+ * configuration.
106
91
*/
107
- public SampleTestRunner (SampleRunnerConfig sampleRunnerConfig ) {
108
- this (sampleRunnerConfig , ObservationRegistry .create (), new SimpleMeterRegistry ());
109
- getObservationRegistry ().observationConfig ()
110
- .observationHandler (new DefaultMeterObservationHandler (getMeterRegistry ()));
92
+ public SampleTestRunner () {
93
+ this .sampleRunnerConfig = SampleRunnerConfig .builder ().build ();
111
94
}
112
95
113
96
/**
114
- * Creates a new instance of the {@link SampleTestRunner} that will have configuration
115
- * and {@link MeterRegistry} resolved lazilly at runtime. Remember that if you don't
116
- * override the {@link SampleTestRunner#getMeterRegistry()} and
117
- * {@link SampleTestRunner#getSampleRunnerConfig()} methods you will get NPEs.
97
+ * Create a new instance of {@link MeterRegistry}. Each parameterized test run calls
98
+ * this method to create a new instance. Override this method to use different
99
+ * {@link MeterRegistry} implementation.
100
+ * @return a new meter registry
118
101
*/
119
- public SampleTestRunner () {
120
- this .sampleRunnerConfig = SampleRunnerConfig .builder ().build ();
121
- this .meterRegistry = null ;
122
- this .observationHandlersCopy = new ArrayList <>();
102
+ protected MeterRegistry createMeterRegistry () {
103
+ return new SimpleMeterRegistry ();
123
104
}
124
105
125
106
/**
126
- * Override this to resolve the {@link MeterRegistry} at runtime. If not overridden
127
- * will return the passed {@link MeterRegistry} from the constructor.
107
+ * Returns the {@link MeterRegistry} instance used during each parameterized test run.
128
108
* @return meter registry to be used in tests
129
109
*/
130
110
protected MeterRegistry getMeterRegistry () {
@@ -134,8 +114,19 @@ protected MeterRegistry getMeterRegistry() {
134
114
}
135
115
136
116
/**
137
- * Override this to resolve the {@link ObservationRegistry} at runtime. If not
138
- * overridden will return the passed {@link ObservationRegistry} from the constructor.
117
+ * Create a new instance of {@link ObservationRegistry}. Override this method to use
118
+ * different {@link ObservationRegistry} implementation.
119
+ * @return a new observation registry
120
+ */
121
+ protected ObservationRegistry createObservationRegistry () {
122
+ ObservationRegistry registry = ObservationRegistry .create ();
123
+ registry .observationConfig ().observationHandler (new DefaultMeterObservationHandler (getMeterRegistry ()));
124
+ return registry ;
125
+ }
126
+
127
+ /**
128
+ * Returns the {@link ObservationRegistry} instance used during each parameterized
129
+ * test run.
139
130
* @return observation registry to be used in tests
140
131
*/
141
132
protected ObservationRegistry getObservationRegistry () {
@@ -160,18 +151,14 @@ void run(TracingSetup tracingSetup) {
160
151
}
161
152
162
153
@ BeforeEach
163
- void setupRegistry () {
164
- this .observationHandlersCopy
165
- . addAll ( TestConfigAccessor . getHandlers ( getObservationRegistry (). observationConfig ()) );
154
+ protected void setupRegistry () {
155
+ this .meterRegistry = createMeterRegistry ();
156
+ this . observationRegistry = createObservationRegistry ( );
166
157
}
167
158
168
159
@ AfterEach
169
- void clearMeterRegistry () {
170
- TestConfigAccessor .clearHandlers (getObservationRegistry ().observationConfig ());
171
- this .observationHandlersCopy
172
- .forEach (handler -> getObservationRegistry ().observationConfig ().observationHandler (handler ));
173
- getMeterRegistry ().clear ();
174
- meterRegistries .add (getMeterRegistry ());
160
+ protected void closeMeterRegistry () {
161
+ getMeterRegistry ().close ();
175
162
}
176
163
177
164
private void printMetrics () {
@@ -183,11 +170,6 @@ private void printMetrics() {
183
170
log .info ("Gathered the following metrics\n " + stringBuilder );
184
171
}
185
172
186
- @ AfterAll
187
- static void closeAll () {
188
- meterRegistries .forEach (MeterRegistry ::close );
189
- }
190
-
191
173
/**
192
174
* Code that you want to measure and run.
193
175
* @return your code with access to the current tracing and measuring infrastructure
@@ -258,12 +240,14 @@ public enum TracingSetup {
258
240
void run (SampleRunnerConfig sampleRunnerConfig , ObservationRegistry observationRegistry ,
259
241
MeterRegistry meterRegistry , SampleTestRunner sampleTestRunner ) {
260
242
checkTracingSetupAssumptions (IN_MEMORY_OTEL , sampleTestRunner .getTracingSetup ());
261
- InMemoryOtelSetup setup = InMemoryOtelSetup .builder ()
262
- .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
263
- .register (observationRegistry );
264
- InMemoryOtelSetup .run (setup ,
265
- __ -> runTraced (sampleRunnerConfig , IN_MEMORY_OTEL , setup .getBuildingBlocks (),
266
- observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
243
+ scopeObservationHandlers (observationRegistry , () -> {
244
+ InMemoryOtelSetup setup = InMemoryOtelSetup .builder ()
245
+ .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
246
+ .register (observationRegistry );
247
+ InMemoryOtelSetup .run (setup ,
248
+ __ -> runTraced (sampleRunnerConfig , IN_MEMORY_OTEL , setup .getBuildingBlocks (),
249
+ observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
250
+ });
267
251
}
268
252
269
253
@ Override
@@ -280,12 +264,14 @@ void printTracingLink(SampleRunnerConfig sampleRunnerConfig, String traceId) {
280
264
void run (SampleRunnerConfig sampleRunnerConfig , ObservationRegistry observationRegistry ,
281
265
MeterRegistry meterRegistry , SampleTestRunner sampleTestRunner ) {
282
266
checkTracingSetupAssumptions (IN_MEMORY_BRAVE , sampleTestRunner .getTracingSetup ());
283
- InMemoryBraveSetup setup = InMemoryBraveSetup .builder ()
284
- .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
285
- .register (observationRegistry );
286
- InMemoryBraveSetup .run (setup ,
287
- __ -> runTraced (sampleRunnerConfig , IN_MEMORY_BRAVE , setup .getBuildingBlocks (),
288
- observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
267
+ scopeObservationHandlers (observationRegistry , () -> {
268
+ InMemoryBraveSetup setup = InMemoryBraveSetup .builder ()
269
+ .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
270
+ .register (observationRegistry );
271
+ InMemoryBraveSetup .run (setup ,
272
+ __ -> runTraced (sampleRunnerConfig , IN_MEMORY_BRAVE , setup .getBuildingBlocks (),
273
+ observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
274
+ });
289
275
}
290
276
291
277
@ Override
@@ -302,12 +288,15 @@ void printTracingLink(SampleRunnerConfig sampleRunnerConfig, String traceId) {
302
288
void run (SampleRunnerConfig sampleRunnerConfig , ObservationRegistry observationRegistry ,
303
289
MeterRegistry meterRegistry , SampleTestRunner sampleTestRunner ) {
304
290
checkTracingSetupAssumptions (ZIPKIN_OTEL , sampleTestRunner .getTracingSetup ());
305
- ZipkinOtelSetup setup = ZipkinOtelSetup .builder ()
306
- .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
307
- .zipkinUrl (sampleRunnerConfig .zipkinUrl ).register (observationRegistry );
308
- checkZipkinAssumptions (setup .getBuildingBlocks ().getSender ());
309
- ZipkinOtelSetup .run (setup , __ -> runTraced (sampleRunnerConfig , ZIPKIN_OTEL , setup .getBuildingBlocks (),
310
- observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
291
+ scopeObservationHandlers (observationRegistry , () -> {
292
+ ZipkinOtelSetup setup = ZipkinOtelSetup .builder ()
293
+ .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
294
+ .zipkinUrl (sampleRunnerConfig .zipkinUrl ).register (observationRegistry );
295
+ checkZipkinAssumptions (setup .getBuildingBlocks ().getSender ());
296
+ ZipkinOtelSetup .run (setup ,
297
+ __ -> runTraced (sampleRunnerConfig , ZIPKIN_OTEL , setup .getBuildingBlocks (),
298
+ observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
299
+ });
311
300
}
312
301
313
302
@ Override
@@ -325,12 +314,15 @@ void printTracingLink(SampleRunnerConfig sampleRunnerConfig, String traceId) {
325
314
void run (SampleRunnerConfig sampleRunnerConfig , ObservationRegistry observationRegistry ,
326
315
MeterRegistry meterRegistry , SampleTestRunner sampleTestRunner ) {
327
316
checkTracingSetupAssumptions (ZIPKIN_BRAVE , sampleTestRunner .getTracingSetup ());
328
- ZipkinBraveSetup setup = ZipkinBraveSetup .builder ()
329
- .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
330
- .zipkinUrl (sampleRunnerConfig .zipkinUrl ).register (observationRegistry );
331
- checkZipkinAssumptions (setup .getBuildingBlocks ().getSender ());
332
- ZipkinBraveSetup .run (setup , __ -> runTraced (sampleRunnerConfig , ZIPKIN_BRAVE , setup .getBuildingBlocks (),
333
- observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
317
+ scopeObservationHandlers (observationRegistry , () -> {
318
+ ZipkinBraveSetup setup = ZipkinBraveSetup .builder ()
319
+ .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
320
+ .zipkinUrl (sampleRunnerConfig .zipkinUrl ).register (observationRegistry );
321
+ checkZipkinAssumptions (setup .getBuildingBlocks ().getSender ());
322
+ ZipkinBraveSetup .run (setup ,
323
+ __ -> runTraced (sampleRunnerConfig , ZIPKIN_BRAVE , setup .getBuildingBlocks (),
324
+ observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
325
+ });
334
326
}
335
327
336
328
@ Override
@@ -349,15 +341,18 @@ void run(SampleRunnerConfig sampleRunnerConfig, ObservationRegistry observationR
349
341
MeterRegistry meterRegistry , SampleTestRunner sampleTestRunner ) {
350
342
checkTracingSetupAssumptions (WAVEFRONT_OTEL , sampleTestRunner .getTracingSetup ());
351
343
checkWavefrontAssumptions (sampleRunnerConfig );
352
- WavefrontOtelSetup setup = WavefrontOtelSetup
353
- .builder (sampleRunnerConfig .wavefrontServerUrl , sampleRunnerConfig .wavefrontToken )
354
- .applicationName (sampleRunnerConfig .wavefrontApplicationName )
355
- .serviceName (sampleRunnerConfig .wavefrontServiceName ).source (sampleRunnerConfig .wavefrontSource )
356
- .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
357
- .register (observationRegistry , meterRegistry );
358
- WavefrontOtelSetup .run (setup ,
359
- __ -> runTraced (sampleRunnerConfig , WAVEFRONT_OTEL , setup .getBuildingBlocks (),
360
- observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
344
+ scopeObservationHandlers (observationRegistry , () -> {
345
+ WavefrontOtelSetup setup = WavefrontOtelSetup
346
+ .builder (sampleRunnerConfig .wavefrontServerUrl , sampleRunnerConfig .wavefrontToken )
347
+ .applicationName (sampleRunnerConfig .wavefrontApplicationName )
348
+ .serviceName (sampleRunnerConfig .wavefrontServiceName )
349
+ .source (sampleRunnerConfig .wavefrontSource )
350
+ .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
351
+ .register (observationRegistry , meterRegistry );
352
+ WavefrontOtelSetup .run (setup ,
353
+ __ -> runTraced (sampleRunnerConfig , WAVEFRONT_OTEL , setup .getBuildingBlocks (),
354
+ observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
355
+ });
361
356
}
362
357
363
358
@ Override
@@ -380,15 +375,18 @@ void run(SampleRunnerConfig sampleRunnerConfig, ObservationRegistry observationR
380
375
MeterRegistry meterRegistry , SampleTestRunner sampleTestRunner ) {
381
376
checkTracingSetupAssumptions (WAVEFRONT_BRAVE , sampleTestRunner .getTracingSetup ());
382
377
checkWavefrontAssumptions (sampleRunnerConfig );
383
- WavefrontBraveSetup setup = WavefrontBraveSetup
384
- .builder (sampleRunnerConfig .wavefrontServerUrl , sampleRunnerConfig .wavefrontToken )
385
- .applicationName (sampleRunnerConfig .wavefrontApplicationName )
386
- .serviceName (sampleRunnerConfig .wavefrontServiceName ).source (sampleRunnerConfig .wavefrontSource )
387
- .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
388
- .register (meterRegistry , observationRegistry );
389
- WavefrontBraveSetup .run (setup ,
390
- __ -> runTraced (sampleRunnerConfig , WAVEFRONT_BRAVE , setup .getBuildingBlocks (),
391
- observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
378
+ scopeObservationHandlers (observationRegistry , () -> {
379
+ WavefrontBraveSetup setup = WavefrontBraveSetup
380
+ .builder (sampleRunnerConfig .wavefrontServerUrl , sampleRunnerConfig .wavefrontToken )
381
+ .applicationName (sampleRunnerConfig .wavefrontApplicationName )
382
+ .serviceName (sampleRunnerConfig .wavefrontServiceName )
383
+ .source (sampleRunnerConfig .wavefrontSource )
384
+ .observationHandlerCustomizer (sampleTestRunner .customizeObservationHandlers ())
385
+ .register (meterRegistry , observationRegistry );
386
+ WavefrontBraveSetup .run (setup ,
387
+ __ -> runTraced (sampleRunnerConfig , WAVEFRONT_BRAVE , setup .getBuildingBlocks (),
388
+ observationRegistry , meterRegistry , sampleTestRunner .runWithMetricsPrinting ()));
389
+ });
392
390
}
393
391
394
392
@ Override
@@ -402,6 +400,19 @@ void printTracingLink(SampleRunnerConfig sampleRunnerConfig, String traceId) {
402
400
}
403
401
};
404
402
403
+ private static void scopeObservationHandlers (ObservationRegistry observationRegistry , Runnable runnable ) {
404
+ ObservationConfig observationConfig = observationRegistry .observationConfig ();
405
+ List <ObservationHandler <?>> originalHandlers = new ArrayList <>(
406
+ TestConfigAccessor .getHandlers (observationConfig ));
407
+ try {
408
+ runnable .run ();
409
+ }
410
+ finally {
411
+ TestConfigAccessor .clearHandlers (observationConfig );
412
+ originalHandlers .forEach (observationConfig ::observationHandler );
413
+ }
414
+ }
415
+
405
416
private static void runTraced (SampleRunnerConfig sampleRunnerConfig , TracingSetup tracingSetup ,
406
417
BuildingBlocks bb , ObservationRegistry observationRegistry , MeterRegistry meterRegistry ,
407
418
SampleTestRunnerConsumer runnable ) {
0 commit comments