3
3
import static org .hamcrest .CoreMatchers .containsString ;
4
4
import static org .hamcrest .MatcherAssert .assertThat ;
5
5
import static org .junit .jupiter .api .Assertions .assertNotEquals ;
6
+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
6
7
import static org .junit .jupiter .api .Assumptions .assumeFalse ;
7
8
9
+ import com .squareup .moshi .JsonAdapter ;
10
+ import com .squareup .moshi .Moshi ;
8
11
import datadog .trace .api .Platform ;
9
- import java .io .BufferedReader ;
10
12
import java .io .File ;
11
- import java .io .InputStreamReader ;
13
+ import java .io .IOException ;
14
+ import java .nio .charset .StandardCharsets ;
12
15
import java .nio .file .FileSystems ;
13
16
import java .nio .file .Files ;
14
17
import java .nio .file .Path ;
18
+ import java .nio .file .Paths ;
15
19
import java .util .Arrays ;
16
20
import java .util .Comparator ;
21
+ import java .util .concurrent .BlockingQueue ;
22
+ import java .util .concurrent .LinkedBlockingQueue ;
23
+ import java .util .concurrent .TimeUnit ;
17
24
import java .util .stream .Stream ;
18
25
import okhttp3 .mockwebserver .Dispatcher ;
19
26
import okhttp3 .mockwebserver .MockResponse ;
20
27
import okhttp3 .mockwebserver .MockWebServer ;
21
28
import okhttp3 .mockwebserver .RecordedRequest ;
29
+ import org .junit .jupiter .api .AfterAll ;
22
30
import org .junit .jupiter .api .AfterEach ;
23
31
import org .junit .jupiter .api .BeforeAll ;
24
32
import org .junit .jupiter .api .BeforeEach ;
29
37
* that ships with OS X by default.
30
38
*/
31
39
public class CrashtrackingSmokeTest {
40
+ private static final long DATA_TIMEOUT_MS = 10 * 1000 ;
41
+ private static final OutputThreads OUTPUT = new OutputThreads ();
42
+ private static final Path LOG_FILE_DIR =
43
+ Paths .get (System .getProperty ("datadog.smoketest.builddir" ), "reports" );
44
+
32
45
private MockWebServer tracingServer ;
46
+ private TestUDPServer udpServer ;
47
+ private final BlockingQueue <CrashTelemetryData > crashEvents = new LinkedBlockingQueue <>();
33
48
34
49
@ BeforeAll
35
50
static void setupAll () {
@@ -43,27 +58,61 @@ static void setupAll() {
43
58
void setup () throws Exception {
44
59
tempDir = Files .createTempDirectory ("dd-smoketest-" );
45
60
61
+ crashEvents .clear ();
62
+
63
+ Moshi moshi = new Moshi .Builder ().build ();
46
64
tracingServer = new MockWebServer ();
47
65
tracingServer .setDispatcher (
48
66
new Dispatcher () {
49
67
@ Override
50
- public MockResponse dispatch (final RecordedRequest request ) throws InterruptedException {
68
+ public MockResponse dispatch (final RecordedRequest request ) {
69
+ System .out .println ("URL ====== " + request .getPath ());
70
+
71
+ String data = request .getBody ().readString (StandardCharsets .UTF_8 );
72
+
73
+ if ("/telemetry/proxy/api/v2/apmtelemetry" .equals (request .getPath ())) {
74
+ try {
75
+ JsonAdapter <MinimalTelemetryData > adapter =
76
+ moshi .adapter (MinimalTelemetryData .class );
77
+ MinimalTelemetryData minimal = adapter .fromJson (data );
78
+ if ("logs" .equals (minimal .request_type )) {
79
+ JsonAdapter <CrashTelemetryData > crashAdapter =
80
+ moshi .adapter (CrashTelemetryData .class );
81
+ crashEvents .add (crashAdapter .fromJson (data ));
82
+ }
83
+ } catch (IOException e ) {
84
+ System .out .println ("Unable to parse " + e );
85
+ }
86
+ }
87
+
88
+ System .out .println (data );
89
+
51
90
return new MockResponse ().setResponseCode (200 );
52
91
}
53
92
});
54
- // tracingServer.start(8126);
93
+
94
+ udpServer = new TestUDPServer ();
95
+ udpServer .start ();
96
+
97
+ OUTPUT .clearMessages ();
55
98
}
56
99
57
100
@ AfterEach
58
101
void teardown () throws Exception {
59
102
tracingServer .shutdown ();
103
+ udpServer .close ();
60
104
61
105
try (Stream <Path > fileStream = Files .walk (tempDir )) {
62
106
fileStream .sorted (Comparator .reverseOrder ()).map (Path ::toFile ).forEach (File ::delete );
63
107
}
64
108
Files .deleteIfExists (tempDir );
65
109
}
66
110
111
+ @ AfterAll
112
+ static void shutdown () {
113
+ OUTPUT .close ();
114
+ }
115
+
67
116
private static String javaPath () {
68
117
final String separator = FileSystems .getDefault ().getSeparator ();
69
118
return System .getProperty ("java.home" ) + separator + "bin" + separator + "java" ;
@@ -108,52 +157,12 @@ void testCrashTracking() throws Exception {
108
157
appShadowJar (),
109
158
script .toString ()));
110
159
pb .environment ().put ("DD_TRACE_AGENT_PORT" , String .valueOf (tracingServer .getPort ()));
111
- StringBuilder stdoutStr = new StringBuilder ();
112
- StringBuilder stderrStr = new StringBuilder ();
113
160
114
161
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 ();
162
+ OUTPUT .captureOutput (p , LOG_FILE_DIR .resolve ("testProcess.testCrashTracking.log" ).toFile ());
149
163
150
164
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" ));
165
+ assertCrashData ();
157
166
}
158
167
159
168
/*
@@ -183,52 +192,14 @@ void testCrashTrackingLegacy() throws Exception {
183
192
appShadowJar (),
184
193
script .toString ()));
185
194
pb .environment ().put ("DD_TRACE_AGENT_PORT" , String .valueOf (tracingServer .getPort ()));
186
- StringBuilder stdoutStr = new StringBuilder ();
187
- StringBuilder stderrStr = new StringBuilder ();
188
195
189
196
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 ();
197
+ OUTPUT .captureOutput (
198
+ p , LOG_FILE_DIR .resolve ("testProcess.testCrashTrackingLegacy.log" ).toFile ());
224
199
225
200
assertNotEquals (0 , p .waitFor (), "Application should have crashed" );
226
201
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" ));
202
+ assertCrashData ();
232
203
}
233
204
234
205
/*
@@ -255,51 +226,13 @@ void testOomeTracking() throws Exception {
255
226
"-jar" ,
256
227
appShadowJar (),
257
228
script .toString ()));
258
- StringBuilder stdoutStr = new StringBuilder ();
259
- StringBuilder stderrStr = new StringBuilder ();
229
+ pb .environment ().put ("DD_DOGSTATSD_PORT" , String .valueOf (udpServer .getPort ()));
260
230
261
231
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 ();
232
+ OUTPUT .captureOutput (p , LOG_FILE_DIR .resolve ("testProcess.testOomeTracking.log" ).toFile ());
296
233
297
234
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" ));
235
+ assertOOMEvent ();
303
236
}
304
237
305
238
@ Test
@@ -326,58 +259,34 @@ void testCombineTracking() throws Exception {
326
259
appShadowJar (),
327
260
oomeScript .toString ()));
328
261
pb .environment ().put ("DD_TRACE_AGENT_PORT" , String .valueOf (tracingServer .getPort ()));
329
- StringBuilder stdoutStr = new StringBuilder ();
330
- StringBuilder stderrStr = new StringBuilder ();
262
+ pb .environment ().put ("DD_DOGSTATSD_PORT" , String .valueOf (udpServer .getPort ()));
331
263
332
264
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 ();
265
+ OUTPUT .captureOutput (p , LOG_FILE_DIR .resolve ("testProcess.testCombineTracking.log" ).toFile ());
367
266
368
267
assertNotEquals (0 , p .waitFor (), "Application should have crashed" );
369
268
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" ));
269
+ assertCrashData ();
270
+ assertOOMEvent ();
271
+ }
272
+
273
+ private void assertCrashData () throws InterruptedException {
274
+ CrashTelemetryData crashData = crashEvents .poll (DATA_TIMEOUT_MS , TimeUnit .MILLISECONDS );
275
+ assertNotNull (crashData , "Crash data not uploaded" );
276
+ assertThat (crashData .payload .get (0 ).message , containsString ("OutOfMemory" ));
277
+ assertThat (crashData .payload .get (0 ).tags , containsString ("severity:crash" ));
278
+ }
279
+
280
+ private void assertOOMEvent () throws InterruptedException {
281
+ String event ;
282
+ do {
283
+ event = udpServer .getMessages ().poll (DATA_TIMEOUT_MS , TimeUnit .MILLISECONDS );
284
+ } while (event != null && !event .startsWith ("_e" ));
285
+
286
+ assertNotNull (event , "OOM Event not received" );
287
+
288
+ assertThat (event , containsString (":OutOfMemoryError" ));
289
+ assertThat (event , containsString ("t:error" ));
290
+ assertThat (event , containsString ("s:java" ));
382
291
}
383
292
}
0 commit comments