1
1
package datadog .smoketest ;
2
2
3
3
import static org .hamcrest .CoreMatchers .containsString ;
4
+ import static org .hamcrest .CoreMatchers .startsWith ;
4
5
import static org .hamcrest .MatcherAssert .assertThat ;
5
6
import static org .junit .jupiter .api .Assertions .assertNotEquals ;
7
+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
6
8
import static org .junit .jupiter .api .Assumptions .assumeFalse ;
7
9
10
+ import com .squareup .moshi .JsonAdapter ;
11
+ import com .squareup .moshi .Moshi ;
8
12
import datadog .trace .api .Platform ;
9
- import java .io .BufferedReader ;
10
13
import java .io .File ;
11
- import java .io .InputStreamReader ;
14
+ import java .io .IOException ;
15
+ import java .nio .charset .StandardCharsets ;
12
16
import java .nio .file .FileSystems ;
13
17
import java .nio .file .Files ;
14
18
import java .nio .file .Path ;
19
+ import java .nio .file .Paths ;
15
20
import java .util .Arrays ;
16
21
import java .util .Comparator ;
22
+ import java .util .concurrent .BlockingQueue ;
23
+ import java .util .concurrent .LinkedBlockingQueue ;
24
+ import java .util .concurrent .TimeUnit ;
17
25
import java .util .stream .Stream ;
18
26
import okhttp3 .mockwebserver .Dispatcher ;
19
27
import okhttp3 .mockwebserver .MockResponse ;
20
28
import okhttp3 .mockwebserver .MockWebServer ;
21
29
import okhttp3 .mockwebserver .RecordedRequest ;
30
+ import org .junit .jupiter .api .AfterAll ;
22
31
import org .junit .jupiter .api .AfterEach ;
23
32
import org .junit .jupiter .api .BeforeAll ;
24
33
import org .junit .jupiter .api .BeforeEach ;
29
38
* that ships with OS X by default.
30
39
*/
31
40
public class CrashtrackingSmokeTest {
41
+ private static final long DATA_TIMEOUT_MS = 10 * 1000 ;
42
+ private static Path LOG_FILE_DIR ;
32
43
private MockWebServer tracingServer ;
44
+ private TestUDPServer udpServer ;
45
+ private BlockingQueue <CrashTelemetryData > crashEvents = new LinkedBlockingQueue <>();
33
46
34
47
@ BeforeAll
35
48
static void setupAll () {
36
49
// Only Hotspot based implementation are supported
37
50
assumeFalse (Platform .isJ9 ());
51
+
52
+ LOG_FILE_DIR = Paths .get (System .getProperty ("datadog.smoketest.builddir" ), "reports" );
38
53
}
39
54
40
55
private Path tempDir ;
56
+ private static OutputThreads outputThreads = new OutputThreads ();
41
57
42
58
@ BeforeEach
43
59
void setup () throws Exception {
44
60
tempDir = Files .createTempDirectory ("dd-smoketest-" );
45
61
62
+ crashEvents .clear ();
63
+
64
+ Moshi moshi = new Moshi .Builder ().build ();
46
65
tracingServer = new MockWebServer ();
47
66
tracingServer .setDispatcher (
48
67
new Dispatcher () {
49
68
@ Override
50
69
public MockResponse dispatch (final RecordedRequest request ) throws InterruptedException {
70
+ String data = request .getBody ().readString (StandardCharsets .UTF_8 );
71
+
72
+ if ("/telemetry/proxy/api/v2/apmtelemetry" .equals (request .getPath ())) {
73
+ try {
74
+ JsonAdapter <MinimalTelemetryData > adapter =
75
+ moshi .adapter (MinimalTelemetryData .class );
76
+ MinimalTelemetryData minimal = adapter .fromJson (data );
77
+ if ("logs" .equals (minimal .request_type )) {
78
+ JsonAdapter <CrashTelemetryData > crashAdapter =
79
+ moshi .adapter (CrashTelemetryData .class );
80
+ crashEvents .add (crashAdapter .fromJson (data ));
81
+ }
82
+ } catch (IOException e ) {
83
+ System .out .println ("Unable to parse " + e );
84
+ }
85
+ }
86
+ System .out .println ("URL ====== " + request .getPath ());
87
+ System .out .println (data );
88
+
51
89
return new MockResponse ().setResponseCode (200 );
52
90
}
53
91
});
54
- // tracingServer.start(8126);
92
+
93
+ udpServer = new TestUDPServer ();
94
+ udpServer .start ();
95
+
96
+ synchronized (outputThreads .testLogMessages ) {
97
+ outputThreads .testLogMessages .clear ();
98
+ }
55
99
}
56
100
57
101
@ AfterEach
58
102
void teardown () throws Exception {
59
103
tracingServer .shutdown ();
104
+ udpServer .close ();
60
105
61
106
try (Stream <Path > fileStream = Files .walk (tempDir )) {
62
107
fileStream .sorted (Comparator .reverseOrder ()).map (Path ::toFile ).forEach (File ::delete );
63
108
}
64
109
Files .deleteIfExists (tempDir );
65
110
}
66
111
112
+ @ AfterAll
113
+ static void shutdown () {
114
+ outputThreads .close ();
115
+ }
116
+
67
117
private static String javaPath () {
68
118
final String separator = FileSystems .getDefault ().getSeparator ();
69
119
return System .getProperty ("java.home" ) + separator + "bin" + separator + "java" ;
@@ -108,52 +158,13 @@ void testCrashTracking() throws Exception {
108
158
appShadowJar (),
109
159
script .toString ()));
110
160
pb .environment ().put ("DD_TRACE_AGENT_PORT" , String .valueOf (tracingServer .getPort ()));
111
- StringBuilder stdoutStr = new StringBuilder ();
112
- StringBuilder stderrStr = new StringBuilder ();
113
161
114
162
Process p = pb .start ();
115
- Thread stdout =
116
- new Thread (
117
- () -> {
118
- try (BufferedReader br =
119
- new BufferedReader (new InputStreamReader (p .getInputStream ()))) {
120
- br .lines ()
121
- .forEach (
122
- l -> {
123
- System .out .println (l );
124
- stdoutStr .append (l ).append ('\n' );
125
- });
126
- } catch (Exception e ) {
127
- throw new RuntimeException (e );
128
- }
129
- });
130
- Thread stderr =
131
- new Thread (
132
- () -> {
133
- try (BufferedReader br =
134
- new BufferedReader (new InputStreamReader (p .getErrorStream ()))) {
135
- br .lines ()
136
- .forEach (
137
- l -> {
138
- System .err .println (l );
139
- stderrStr .append (l ).append ('\n' );
140
- });
141
- } catch (Exception e ) {
142
- throw new RuntimeException (e );
143
- }
144
- });
145
- stdout .setDaemon (true );
146
- stderr .setDaemon (true );
147
- stdout .start ();
148
- stderr .start ();
163
+ outputThreads .captureOutput (
164
+ p , LOG_FILE_DIR .resolve ("testProcess.testCrashTracking.log" ).toFile ());
149
165
150
166
assertNotEquals (0 , p .waitFor (), "Application should have crashed" );
151
-
152
- assertThat (stdoutStr .toString (), containsString (" was uploaded successfully" ));
153
- assertThat (
154
- stderrStr .toString (),
155
- containsString (
156
- "com.datadog.crashtracking.CrashUploader - Successfully uploaded the crash files" ));
167
+ assertCrashData ();
157
168
}
158
169
159
170
/*
@@ -183,52 +194,14 @@ void testCrashTrackingLegacy() throws Exception {
183
194
appShadowJar (),
184
195
script .toString ()));
185
196
pb .environment ().put ("DD_TRACE_AGENT_PORT" , String .valueOf (tracingServer .getPort ()));
186
- StringBuilder stdoutStr = new StringBuilder ();
187
- StringBuilder stderrStr = new StringBuilder ();
188
197
189
198
Process p = pb .start ();
190
- Thread stdout =
191
- new Thread (
192
- () -> {
193
- try (BufferedReader br =
194
- new BufferedReader (new InputStreamReader (p .getInputStream ()))) {
195
- br .lines ()
196
- .forEach (
197
- l -> {
198
- System .out .println (l );
199
- stdoutStr .append (l ).append ('\n' );
200
- });
201
- } catch (Exception e ) {
202
- throw new RuntimeException (e );
203
- }
204
- });
205
- Thread stderr =
206
- new Thread (
207
- () -> {
208
- try (BufferedReader br =
209
- new BufferedReader (new InputStreamReader (p .getErrorStream ()))) {
210
- br .lines ()
211
- .forEach (
212
- l -> {
213
- System .err .println (l );
214
- stderrStr .append (l ).append ('\n' );
215
- });
216
- } catch (Exception e ) {
217
- throw new RuntimeException (e );
218
- }
219
- });
220
- stdout .setDaemon (true );
221
- stderr .setDaemon (true );
222
- stdout .start ();
223
- stderr .start ();
199
+ outputThreads .captureOutput (
200
+ p , LOG_FILE_DIR .resolve ("testProcess.testCrashTrackingLegacy.log" ).toFile ());
224
201
225
202
assertNotEquals (0 , p .waitFor (), "Application should have crashed" );
226
203
227
- assertThat (stdoutStr .toString (), containsString (" was uploaded successfully" ));
228
- assertThat (
229
- stderrStr .toString (),
230
- containsString (
231
- "com.datadog.crashtracking.CrashUploader - Successfully uploaded the crash files" ));
204
+ assertCrashData ();
232
205
}
233
206
234
207
/*
@@ -255,51 +228,14 @@ void testOomeTracking() throws Exception {
255
228
"-jar" ,
256
229
appShadowJar (),
257
230
script .toString ()));
258
- StringBuilder stdoutStr = new StringBuilder ();
259
- StringBuilder stderrStr = new StringBuilder ();
260
231
261
232
Process p = pb .start ();
262
- Thread stdout =
263
- new Thread (
264
- () -> {
265
- try (BufferedReader br =
266
- new BufferedReader (new InputStreamReader (p .getInputStream ()))) {
267
- br .lines ()
268
- .forEach (
269
- l -> {
270
- System .out .println (l );
271
- stdoutStr .append (l ).append ('\n' );
272
- });
273
- } catch (Exception e ) {
274
- throw new RuntimeException (e );
275
- }
276
- });
277
- Thread stderr =
278
- new Thread (
279
- () -> {
280
- try (BufferedReader br =
281
- new BufferedReader (new InputStreamReader (p .getErrorStream ()))) {
282
- br .lines ()
283
- .forEach (
284
- l -> {
285
- System .err .println (l );
286
- stderrStr .append (l ).append ('\n' );
287
- });
288
- } catch (Exception e ) {
289
- throw new RuntimeException (e );
290
- }
291
- });
292
- stdout .setDaemon (true );
293
- stderr .setDaemon (true );
294
- stdout .start ();
295
- stderr .start ();
233
+ outputThreads .captureOutput (
234
+ p , LOG_FILE_DIR .resolve ("testProcess.testOomeTracking.log" ).toFile ());
235
+ pb .environment ().put ("DD_DOGSTATSD_PORT" , String .valueOf (udpServer .getPort ()));
296
236
297
237
assertNotEquals (0 , p .waitFor (), "Application should have crashed" );
298
-
299
- assertThat (
300
- stderrStr .toString (),
301
- containsString ("com.datadog.crashtracking.OOMENotifier - OOME event sent" ));
302
- assertThat (stdoutStr .toString (), containsString ("OOME Event generated successfully" ));
238
+ assertOOMEvent ();
303
239
}
304
240
305
241
@ Test
@@ -326,58 +262,33 @@ void testCombineTracking() throws Exception {
326
262
appShadowJar (),
327
263
oomeScript .toString ()));
328
264
pb .environment ().put ("DD_TRACE_AGENT_PORT" , String .valueOf (tracingServer .getPort ()));
329
- StringBuilder stdoutStr = new StringBuilder ();
330
- StringBuilder stderrStr = new StringBuilder ();
265
+ pb .environment ().put ("DD_DOGSTATSD_PORT" , String .valueOf (udpServer .getPort ()));
331
266
332
267
Process p = pb .start ();
333
- Thread stdout =
334
- new Thread (
335
- () -> {
336
- try (BufferedReader br =
337
- new BufferedReader (new InputStreamReader (p .getInputStream ()))) {
338
- br .lines ()
339
- .forEach (
340
- l -> {
341
- System .out .println (l );
342
- stdoutStr .append (l ).append ('\n' );
343
- });
344
- } catch (Exception e ) {
345
- throw new RuntimeException (e );
346
- }
347
- });
348
- Thread stderr =
349
- new Thread (
350
- () -> {
351
- try (BufferedReader br =
352
- new BufferedReader (new InputStreamReader (p .getErrorStream ()))) {
353
- br .lines ()
354
- .forEach (
355
- l -> {
356
- System .err .println (l );
357
- stderrStr .append (l ).append ('\n' );
358
- });
359
- } catch (Exception e ) {
360
- throw new RuntimeException (e );
361
- }
362
- });
363
- stdout .setDaemon (true );
364
- stderr .setDaemon (true );
365
- stdout .start ();
366
- stderr .start ();
268
+ outputThreads .captureOutput (
269
+ p , LOG_FILE_DIR .resolve ("testProcess.testCombineTracking.log" ).toFile ());
367
270
368
271
assertNotEquals (0 , p .waitFor (), "Application should have crashed" );
369
272
370
- // Crash uploader did get triggered
371
- assertThat (stdoutStr .toString (), containsString (" was uploaded successfully" ));
372
- assertThat (
373
- stderrStr .toString (),
374
- containsString (
375
- "com.datadog.crashtracking.CrashUploader - Successfully uploaded the crash files" ));
376
-
377
- // OOME notifier did get triggered
378
- assertThat (
379
- stderrStr .toString (),
380
- containsString ("com.datadog.crashtracking.OOMENotifier - OOME event sent" ));
381
- assertThat (stdoutStr .toString (), containsString ("OOME Event generated successfully" ));
273
+ assertCrashData ();
274
+ assertOOMEvent ();
275
+ }
276
+
277
+ private void assertCrashData () throws InterruptedException {
278
+ CrashTelemetryData crashData = crashEvents .poll (DATA_TIMEOUT_MS , TimeUnit .MILLISECONDS );
279
+ assertNotNull (crashData , "Crash data not uploaded" );
280
+ assertThat (crashData .payload .get (0 ).message , containsString ("OutOfMemory" ));
281
+ assertThat (crashData .payload .get (0 ).tags , containsString ("severity:crash" ));
282
+ }
283
+
284
+ private void assertOOMEvent () throws InterruptedException {
285
+ byte [] data = udpServer .getMessages ().poll (DATA_TIMEOUT_MS , TimeUnit .MILLISECONDS );
286
+ assertNotNull (data , "OOM Event not received" );
287
+ String event = new String (data );
288
+
289
+ assertThat (event , startsWith ("_e" ));
290
+ assertThat (event , containsString (":OutOfMemoryError" ));
291
+ assertThat (event , containsString ("t:error" ));
292
+ assertThat (event , containsString ("s:java" ));
382
293
}
383
294
}
0 commit comments