21
21
import io .netty .channel .ChannelHandlerContext ;
22
22
import io .netty .channel .ChannelOutboundHandlerAdapter ;
23
23
import io .netty .channel .ChannelPromise ;
24
+ import io .netty .channel .unix .DomainSocketAddress ;
24
25
import io .netty .handler .logging .LogLevel ;
25
26
import io .netty .handler .logging .LoggingHandler ;
26
27
import org .junit .jupiter .api .AfterEach ;
27
28
import org .junit .jupiter .api .Test ;
29
+ import org .junit .jupiter .api .condition .OS ;
28
30
import org .junit .jupiter .params .ParameterizedTest ;
29
31
import org .junit .jupiter .params .provider .EnumSource ;
30
32
import reactor .core .Disposable ;
34
36
import reactor .netty .tcp .TcpServer ;
35
37
import reactor .netty .udp .UdpServer ;
36
38
39
+ import java .io .File ;
37
40
import java .net .InetSocketAddress ;
38
41
import java .time .Duration ;
39
42
import java .util .concurrent .CountDownLatch ;
44
47
45
48
import static org .assertj .core .api .Assertions .assertThat ;
46
49
import static org .awaitility .Awaitility .await ;
50
+ import static org .junit .jupiter .api .Assumptions .assumeTrue ;
47
51
48
52
/**
49
53
* Tests {@link StatsdMeterRegistry} metrics publishing functionality.
52
56
* @author Johnny Lim
53
57
*/
54
58
class StatsdMeterRegistryPublishTest {
59
+ public static final String UDS_DATAGRAM_SOCKET_PATH = "/tmp/test-server.sock" ;
55
60
56
61
StatsdMeterRegistry meterRegistry ;
57
62
DisposableChannel server ;
@@ -62,7 +67,9 @@ class StatsdMeterRegistryPublishTest {
62
67
63
68
@ AfterEach
64
69
void cleanUp () {
65
- meterRegistry .close ();
70
+ if (meterRegistry != null ) {
71
+ meterRegistry .close ();
72
+ }
66
73
if (server != null ) {
67
74
server .disposeNow ();
68
75
}
@@ -71,10 +78,11 @@ void cleanUp() {
71
78
@ ParameterizedTest
72
79
@ EnumSource (StatsdProtocol .class )
73
80
void receiveMetricsSuccessfully (StatsdProtocol protocol ) throws InterruptedException {
81
+ skipUdsTestOnWindows (protocol );
74
82
serverLatch = new CountDownLatch (3 );
75
83
server = startServer (protocol , 0 );
76
84
77
- final int port = getPort ();
85
+ final int port = getPort (protocol );
78
86
79
87
meterRegistry = new StatsdMeterRegistry (getUnbufferedConfig (protocol , port ), Clock .SYSTEM );
80
88
startRegistryAndWaitForClient ();
@@ -88,11 +96,12 @@ void receiveMetricsSuccessfully(StatsdProtocol protocol) throws InterruptedExcep
88
96
@ ParameterizedTest
89
97
@ EnumSource (StatsdProtocol .class )
90
98
void resumeSendingMetrics_whenServerIntermittentlyFails (StatsdProtocol protocol ) throws InterruptedException {
99
+ skipUdsTestOnWindows (protocol );
91
100
serverLatch = new CountDownLatch (1 );
92
101
AtomicInteger writeCount = new AtomicInteger ();
93
102
server = startServer (protocol , 0 );
94
103
95
- final int port = getPort ();
104
+ final int port = getPort (protocol );
96
105
97
106
meterRegistry = new StatsdMeterRegistry (getUnbufferedConfig (protocol , port ), Clock .SYSTEM );
98
107
startRegistryAndWaitForClient ();
@@ -134,10 +143,11 @@ void resumeSendingMetrics_whenServerIntermittentlyFails(StatsdProtocol protocol)
134
143
@ EnumSource (StatsdProtocol .class )
135
144
@ Issue ("#1676" )
136
145
void stopAndStartMeterRegistrySendsMetrics (StatsdProtocol protocol ) throws InterruptedException {
146
+ skipUdsTestOnWindows (protocol );
137
147
serverLatch = new CountDownLatch (3 );
138
148
server = startServer (protocol , 0 );
139
149
140
- final int port = getPort ();
150
+ final int port = getPort (protocol );
141
151
142
152
meterRegistry = new StatsdMeterRegistry (getUnbufferedConfig (protocol , port ), Clock .SYSTEM );
143
153
startRegistryAndWaitForClient ();
@@ -175,11 +185,12 @@ void stopAndStartMeterRegistryWithLineSink() throws InterruptedException {
175
185
@ ParameterizedTest
176
186
@ EnumSource (StatsdProtocol .class )
177
187
void whenBackendInitiallyDown_metricsSentAfterBackendStarts (StatsdProtocol protocol ) throws InterruptedException {
188
+ skipUdsTestOnWindows (protocol );
178
189
AtomicInteger writeCount = new AtomicInteger ();
179
190
serverLatch = new CountDownLatch (3 );
180
191
// start server to secure an open port
181
192
server = startServer (protocol , 0 );
182
- final int port = getPort ();
193
+ final int port = getPort (protocol );
183
194
server .disposeNow ();
184
195
meterRegistry = new StatsdMeterRegistry (getUnbufferedConfig (protocol , port ), Clock .SYSTEM );
185
196
meterRegistry .start ();
@@ -190,10 +201,10 @@ void whenBackendInitiallyDown_metricsSentAfterBackendStarts(StatsdProtocol proto
190
201
await ().until (() -> writeCount .get () == 3 );
191
202
}
192
203
server = startServer (protocol , port );
193
- if (protocol == StatsdProtocol .TCP ) {
194
- // client is null until TcpClient first connects
204
+ if (protocol == StatsdProtocol .TCP || protocol == StatsdProtocol . UDS_DATAGRAM ) {
205
+ // client is null until connection established
195
206
await ().until (() -> meterRegistry .statsdConnection .get () != null );
196
- // TcpClient may take some time to reconnect to the server
207
+ // client may take some time to reconnect to the server
197
208
await ().until (() -> !clientIsDisposed ());
198
209
}
199
210
assertThat (serverLatch .getCount ()).isEqualTo (3 );
@@ -213,10 +224,11 @@ void whenBackendInitiallyDown_metricsSentAfterBackendStarts(StatsdProtocol proto
213
224
@ ParameterizedTest
214
225
@ EnumSource (StatsdProtocol .class )
215
226
void whenRegistryStopped_doNotConnectToBackend (StatsdProtocol protocol ) throws InterruptedException {
227
+ skipUdsTestOnWindows (protocol );
216
228
serverLatch = new CountDownLatch (3 );
217
229
// start server to secure an open port
218
230
server = startServer (protocol , 0 );
219
- final int port = getPort ();
231
+ final int port = getPort (protocol );
220
232
meterRegistry = new StatsdMeterRegistry (getUnbufferedConfig (protocol , port ), Clock .SYSTEM );
221
233
startRegistryAndWaitForClient ();
222
234
server .disposeNow ();
@@ -232,9 +244,10 @@ void whenRegistryStopped_doNotConnectToBackend(StatsdProtocol protocol) throws I
232
244
@ EnumSource (StatsdProtocol .class )
233
245
@ Issue ("#2177" )
234
246
void whenSendError_reconnectsAndWritesNewMetrics (StatsdProtocol protocol ) throws InterruptedException {
247
+ skipUdsTestOnWindows (protocol );
235
248
serverLatch = new CountDownLatch (3 );
236
249
server = startServer (protocol , 0 );
237
- final int port = getPort ();
250
+ final int port = getPort (protocol );
238
251
meterRegistry = new StatsdMeterRegistry (getUnbufferedConfig (protocol , port ), Clock .SYSTEM );
239
252
startRegistryAndWaitForClient ();
240
253
((Connection ) meterRegistry .statsdConnection .get ()).addHandler ("writeFailure" , new ChannelOutboundHandlerAdapter () {
@@ -255,15 +268,21 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
255
268
await ().pollDelay (Duration .ofSeconds (1 )).atMost (Duration .ofSeconds (3 )).until (() -> serverMetricReadCount .get () == 3 );
256
269
}
257
270
258
- private int getPort () {
271
+ private void skipUdsTestOnWindows (StatsdProtocol protocol ) {
272
+ if (protocol == StatsdProtocol .UDS_DATAGRAM )
273
+ assumeTrue (!OS .WINDOWS .isCurrentOs ());
274
+ }
275
+
276
+ private int getPort (StatsdProtocol protocol ) {
277
+ if (protocol == StatsdProtocol .UDS_DATAGRAM ) return 0 ;
259
278
return ((InetSocketAddress ) server .address ()).getPort ();
260
279
}
261
280
262
281
private void trackWritesForUdpClient (StatsdProtocol protocol , AtomicInteger writeCount ) {
263
282
if (protocol == StatsdProtocol .UDP ) {
264
283
await ().until (() -> meterRegistry .statsdConnection .get () != null );
265
284
((Connection ) meterRegistry .statsdConnection .get ())
266
- .addHandler (new LoggingHandler ("udpclient " , LogLevel .INFO ))
285
+ .addHandler (new LoggingHandler ("testudpclient " , LogLevel .INFO ))
267
286
.addHandler (new ChannelOutboundHandlerAdapter () {
268
287
@ Override
269
288
public void write (ChannelHandlerContext ctx , Object msg , ChannelPromise promise ) throws Exception {
@@ -284,10 +303,10 @@ private boolean clientIsDisposed() {
284
303
}
285
304
286
305
private DisposableChannel startServer (StatsdProtocol protocol , int port ) {
287
- if (protocol == StatsdProtocol .UDP ) {
306
+ if (protocol == StatsdProtocol .UDP || protocol == StatsdProtocol . UDS_DATAGRAM ) {
288
307
return UdpServer .create ()
289
- .host ( "localhost" )
290
- . port ( port )
308
+ .bindAddress (() -> protocol == StatsdProtocol . UDP ? InetSocketAddress . createUnresolved ( "localhost" , port )
309
+ : newDomainSocketAddress () )
291
310
.handle ((in , out ) ->
292
311
in .receive ().asString ()
293
312
.flatMap (packet -> {
@@ -328,13 +347,30 @@ private DisposableChannel startServer(StatsdProtocol protocol, int port) {
328
347
}
329
348
}
330
349
350
+ private static DomainSocketAddress newDomainSocketAddress () {
351
+ try {
352
+ File tempFile = new File (UDS_DATAGRAM_SOCKET_PATH );
353
+ tempFile .delete ();
354
+ tempFile .deleteOnExit ();
355
+ return new DomainSocketAddress (tempFile );
356
+ }
357
+ catch (Exception e ) {
358
+ throw new RuntimeException ("Error creating a temporary file" , e );
359
+ }
360
+ }
361
+
331
362
private StatsdConfig getUnbufferedConfig (StatsdProtocol protocol , int port ) {
332
363
return new StatsdConfig () {
333
364
@ Override
334
365
public String get (String key ) {
335
366
return null ;
336
367
}
337
368
369
+ @ Override
370
+ public String host () {
371
+ return protocol == StatsdProtocol .UDS_DATAGRAM ? UDS_DATAGRAM_SOCKET_PATH : "localhost" ;
372
+ }
373
+
338
374
@ Override
339
375
public int port () {
340
376
return port ;
0 commit comments