99ba6fb5adb89edf93ed97263603f02256b9bd7c
[lttng-ust-java-tests.git] /
1 /*
2 * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 package org.lttng.ust.agent.integration.context;
20
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.IOException;
27 import java.util.List;
28
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.lttng.tools.ILttngSession;
34 import org.lttng.tools.ILttngSession.Domain;
35 import org.lttng.ust.agent.ILttngHandler;
36 import org.lttng.ust.agent.context.ContextInfoManager;
37 import org.lttng.ust.agent.utils.TestPrintRunner;
38
39 /**
40 * Base abstract class to implement all sorts of integration tests verifying the
41 * presence of enabled application contexts in resulting traces.
42 */
43 @RunWith(TestPrintRunner.class)
44 public abstract class AppContextITBase {
45
46 protected static final String EVENT_NAME = "EventName";
47
48 protected static final String RETRIEVER_NAME_1 = "Retriever1";
49 protected static final String RETRIEVER_NAME_2 = "some.retriever_2";
50
51 private static final String CONTEXT_NAME = ContextInfoRetrieverStubs.CONTEXT_NAME;
52
53 private ContextInfoManager cim;
54 private ILttngSession session;
55
56 /* Field defined by the sub-class */
57 protected ILttngHandler logHandler;
58
59 protected abstract Domain getDomain();
60
61 protected abstract void sendEventsToLoggers();
62
63 /**
64 * Base test setup
65 */
66 @Before
67 public void testSetup() {
68 try {
69 cim = ContextInfoManager.getInstance();
70 } catch (SecurityException | IOException e) {
71 /* The native library is not available! */
72 fail(e.getMessage());
73 }
74 session = ILttngSession.createSession(null, getDomain());
75 }
76
77 /**
78 * Base test teardown
79 */
80 @After
81 public void testTeardown() {
82 session.close();
83
84 logHandler.close();
85 logHandler = null;
86
87 /* In case some tests fail or forget to unregister their retrievers */
88 cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1);
89 cim.unregisterContextInfoRetriever(RETRIEVER_NAME_2);
90 }
91
92 // ------------------------------------------------------------------------
93 // Context enabled/disabled tests
94 // ------------------------------------------------------------------------
95
96 /**
97 * Utility method to check that a context is present in all events of a
98 * trace output.
99 */
100 private static void testContextPresentInTrace(List<String> traceOutput, String retrieverName, String contextName, String contextValue) {
101 String traceRetrieverName = convertToNameInTrace(retrieverName);
102 String traceContextName = convertToNameInTrace(contextName);
103
104 String fullString = "_app_" + traceRetrieverName + "_" + traceContextName + " = " + contextValue;
105 traceOutput.forEach(line -> assertTrue(line.contains(fullString)));
106 }
107
108 /**
109 * Utility method to check that a context is *absent* from all events of a
110 * trace output
111 */
112 private static void testContextNotPresentInTrace(List<String> traceOutput, String retrieverName, String contextName) {
113 String traceRetrieverName = convertToNameInTrace(retrieverName);
114 String traceContextName = convertToNameInTrace(contextName);
115
116 String fullString = "_app_" + traceRetrieverName + "_" + traceContextName;
117 traceOutput.forEach(line -> assertFalse(line.contains(fullString)));
118 }
119
120 /**
121 * LTTng accepts periods in context names, but ends up printing them as
122 * underscores in the trace, so the metadata grammar remains valid.
123 */
124 private static String convertToNameInTrace(String name) {
125 return name.replace('.', '_');
126 }
127
128 /**
129 * Test that if no retrievers are declared, no context info is passed at
130 * all.
131 */
132 @Test
133 public void testNoContexts() {
134 assertTrue(session.enableAllEvents());
135 assertTrue(session.start());
136 sendEventsToLoggers();
137 assertTrue(session.stop());
138
139 List<String> output = session.view();
140 assertNotNull(output);
141 assertFalse(output.isEmpty());
142
143 /* Test that there is no "_app" contexts in the output */
144 output.forEach(line -> assertFalse(line.contains("_app")));
145 }
146
147 /**
148 * Test that if a retriever is registered and provides a context, but this
149 * context is not enabled in the tracing session, that it is not present in
150 * the trace.
151 */
152 @Test
153 public void testContextAvailableButNotEnabled() {
154 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
155
156 assertTrue(session.enableAllEvents());
157 assertTrue(session.start());
158 sendEventsToLoggers();
159 assertTrue(session.stop());
160
161 List<String> output = session.view();
162 assertNotNull(output);
163 assertFalse(output.isEmpty());
164
165 /* Test that there is no "_app" contexts in the output */
166 output.forEach(line -> assertFalse(line.contains("_app")));
167
168 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
169 }
170
171 /**
172 * Test that if a context is enabled, but no retriever provides it, that the
173 * retriever/context names are still mentioned in the event but no value is
174 * provided.
175 */
176 @Test
177 public void testContextNotAvailableButEnabled() {
178 assertTrue(session.enableAllEvents());
179 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
180
181 assertTrue(session.start());
182 sendEventsToLoggers();
183 assertTrue(session.stop());
184
185 List<String> output = session.view();
186 assertNotNull(output);
187 assertFalse(output.isEmpty());
188
189 /* Test that context name is there but value is not */
190 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ { } } }");
191 }
192
193 /**
194 * Test that if a context is enabled and provided by a retriever that it is
195 * correctly present in the tracing session.
196 */
197 @Test
198 public void testContextAvailableAndEnabled() {
199 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
200
201 assertTrue(session.enableAllEvents());
202 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
203
204 assertTrue(session.start());
205 sendEventsToLoggers();
206 assertTrue(session.stop());
207
208 List<String> output = session.view();
209 assertNotNull(output);
210 assertFalse(output.isEmpty());
211
212 /* Test that context name + value are present */
213 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
214 "{ \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" }");
215
216 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
217 }
218
219 /**
220 * Test that one context is available by a retriever, but another is is
221 * enabled in the session. Only the latter should be mentioned in events,
222 * with no value.
223 */
224 @Test
225 public void testContextsOneAvailableOtherEnabled() {
226 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
227
228 assertTrue(session.enableAllEvents());
229 assertTrue(session.enableAppContext(RETRIEVER_NAME_2, CONTEXT_NAME));
230
231 assertTrue(session.start());
232 sendEventsToLoggers();
233 assertTrue(session.stop());
234
235 List<String> output = session.view();
236 assertNotNull(output);
237 assertFalse(output.isEmpty());
238
239 /* Test that only retriever-name-2 is present, with no value */
240 testContextNotPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME);
241 testContextPresentInTrace(output, RETRIEVER_NAME_2, CONTEXT_NAME, "{ { } } }");
242
243 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
244 }
245
246 /**
247 * Test with two contexts provided in the application, but only one of them
248 * is enabled in the session. Only that one should be present in the trace,
249 * name and value.
250 */
251 @Test
252 public void testContextsTwoAvailableOneEnabled() {
253 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
254 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_2, ContextInfoRetrieverStubs.INTEGER_RETRIEVER));
255
256 assertTrue(session.enableAllEvents());
257 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
258
259 assertTrue(session.start());
260 sendEventsToLoggers();
261 assertTrue(session.stop());
262
263 List<String> output = session.view();
264 assertNotNull(output);
265 assertFalse(output.isEmpty());
266
267 /* Test that only retriever-name-1 is present, name + value */
268 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
269 "{ \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" }");
270 testContextNotPresentInTrace(output, RETRIEVER_NAME_2, CONTEXT_NAME);
271
272 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
273 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_2));
274 }
275
276 /**
277 * Test with two contexts enabled in the session but only one of them is
278 * provided by the application. Both should be mentioned in the trace, but
279 * only the provided one will have a value.
280 */
281 @Test
282 public void testContextsOneAvailableTwoEnabled() {
283 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
284
285 assertTrue(session.enableAllEvents());
286 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
287 assertTrue(session.enableAppContext(RETRIEVER_NAME_2, CONTEXT_NAME));
288
289 assertTrue(session.start());
290 sendEventsToLoggers();
291 assertTrue(session.stop());
292
293 List<String> output = session.view();
294 assertNotNull(output);
295 assertFalse(output.isEmpty());
296
297 /* Test that both contexts are present, but only retriever-1's has a value */
298 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
299 "{ \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" }");
300 testContextPresentInTrace(output, RETRIEVER_NAME_2, CONTEXT_NAME, "{ { } } }");
301
302 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
303 }
304
305 // ------------------------------------------------------------------------
306 // Context types tests
307 // ------------------------------------------------------------------------
308
309 /**
310 * Utility method to enable all events, add the one context we are looking
311 * for, take a trace, and return the trace output.
312 */
313 private List<String> enableContextAndTrace() {
314 assertTrue(session.enableAllEvents());
315 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
316 assertTrue(session.start());
317 sendEventsToLoggers();
318 assertTrue(session.stop());
319
320 List<String> output = session.view();
321 assertNotNull(output);
322 assertFalse(output.isEmpty());
323
324 return output;
325 }
326
327 /**
328 * Test a "null" context value.
329 */
330 @Test
331 public void testContextValueNull() {
332 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.NULL_RETRIEVER));
333
334 List<String> output = enableContextAndTrace();
335 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ { } } }");
336
337 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
338 }
339
340 /**
341 * Test an integer (int32) context value.
342 */
343 @Test
344 public void testContextValueInteger() {
345 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.INTEGER_RETRIEVER));
346
347 List<String> output = enableContextAndTrace();
348 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
349 "{ " + ContextInfoRetrieverStubs.INTEGER_VALUE + " } }");
350
351 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
352 }
353
354 /**
355 * Test a long (int64) context value.
356 */
357 @Test
358 public void testContextValueLong() {
359 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.LONG_RETRIEVER));
360
361 List<String> output = enableContextAndTrace();
362 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
363 "{ " + ContextInfoRetrieverStubs.LONG_VALUE + " } }");
364
365 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
366 }
367
368 /**
369 * Test a double context value.
370 */
371 @Test
372 public void testContextValueDouble() {
373 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.DOUBLE_RETRIEVER));
374
375 List<String> output = enableContextAndTrace();
376 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
377 "{ " + ContextInfoRetrieverStubs.DOUBLE_VALUE + " } }");
378
379 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
380 }
381
382 /**
383 * Test a character context value (should get converted to a string).
384 */
385 @Test
386 public void testContextValueCharacter() {
387 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.CHARACTER_RETRIEVER));
388
389 List<String> output = enableContextAndTrace();
390 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
391 "{ \"" + ContextInfoRetrieverStubs.CHARACTER_VALUE + "\" } }");
392
393 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
394 }
395
396 /**
397 * Test a float context value.
398 */
399 @Test
400 public void testContextValueFloat() {
401 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.FLOAT_RETRIEVER));
402
403 List<String> output = enableContextAndTrace();
404 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
405 "{ " + ContextInfoRetrieverStubs.FLOAT_VALUE + " } }");
406
407 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
408 }
409
410 /**
411 * Test a byte (int8) context value.
412 */
413 @Test
414 public void testContextValueByte() {
415 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.BYTE_RETRIEVER));
416
417 List<String> output = enableContextAndTrace();
418 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
419 "{ " + ContextInfoRetrieverStubs.BYTE_VALUE + " } }");
420
421 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
422 }
423
424 /**
425 * Test a short (int16) context value.
426 */
427 @Test
428 public void testContextValueShort() {
429 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.SHORT_RETRIEVER));
430
431 List<String> output = enableContextAndTrace();
432 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
433 "{ " + ContextInfoRetrieverStubs.SHORT_VALUE + " } }");
434
435 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
436 }
437
438 /**
439 * Test a "true" boolean context value (gets converted to a int8 of value 1).
440 */
441 @Test
442 public void testContextValueBooleanTrue() {
443 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.BOOLEAN_TRUE_RETRIEVER));
444
445 List<String> output = enableContextAndTrace();
446 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ 1 } }");
447
448 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
449 }
450
451 /**
452 * Test a "false" boolean context value (gets converted to a int8 of value 0).
453 */
454 @Test
455 public void testContextValueBooleanFalse() {
456 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.BOOLEAN_FALSE_RETRIEVER));
457
458 List<String> output = enableContextAndTrace();
459 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ 0 } }");
460
461 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
462 }
463
464 /**
465 * Test a string context value.
466 */
467 @Test
468 public void testContextValueString() {
469 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
470
471 List<String> output = enableContextAndTrace();
472 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
473 "{ \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" } }");
474
475 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
476 }
477
478 /**
479 * Test a Object context value (should be converted to a String via .toString()).
480 */
481 @Test
482 public void testContextValueObject() {
483 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.OBJECT_RETRIEVER));
484
485 List<String> output = enableContextAndTrace();
486 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
487 "{ \"" + ContextInfoRetrieverStubs.OBJECT_VALUE.toString() + "\" } }");
488
489 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
490 }
491
492 // ------------------------------------------------------------------------
493 // Tests related to filtering
494 // ------------------------------------------------------------------------
495
496 /**
497 * Test with a filter expression using a context, but not having the actual
498 * context enabled.
499 *
500 * The JNI should still send the context so UST can use it for filtering,
501 * but it should not be present in the resulting trace.
502 */
503 @Test
504 public void testContextFilterExpressionNotEnabled() {
505 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
506
507 assertTrue(session.enableEvent(EVENT_NAME, null, false,
508 "$app." + RETRIEVER_NAME_1 + ':' + CONTEXT_NAME + "==\"" + ContextInfoRetrieverStubs.STRING_VALUE + '\"'));
509
510 assertTrue(session.start());
511 sendEventsToLoggers();
512 assertTrue(session.stop());
513
514 List<String> output = session.view();
515 assertNotNull(output);
516 assertFalse(output.isEmpty());
517
518 testContextNotPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME);
519
520 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
521 }
522
523 /**
524 * Test with a filter expression and an enabled context. The filter however
525 * should *exclude* the events, so no events should be present in the
526 * resulting trace.
527 */
528 @Test
529 public void testContextFilterExpressionEnabledNotMatching() {
530 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
531
532 assertTrue(session.enableEvent(EVENT_NAME, null, false,
533 "$app." + RETRIEVER_NAME_1 + ':' + CONTEXT_NAME + "!=\"" + ContextInfoRetrieverStubs.STRING_VALUE + '\"'));
534
535 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
536 assertTrue(session.start());
537 sendEventsToLoggers();
538 assertTrue(session.stop());
539
540 List<String> output = session.view();
541 assertNotNull(output);
542 assertTrue(output.isEmpty());
543
544 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
545 }
546
547 /**
548 * Test with a filter expression and an enabled context. The filter however
549 * should match the events, so events with the context info should be
550 * present in the resulting trace.
551 */
552 @Test
553 public void testContextFilterExpressionEnabledMatching() {
554 assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
555
556 assertTrue(session.enableEvent(EVENT_NAME, null, false,
557 "$app." + RETRIEVER_NAME_1 + ':' + CONTEXT_NAME + "==\"" + ContextInfoRetrieverStubs.STRING_VALUE + '\"'));
558
559 assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
560 assertTrue(session.start());
561 sendEventsToLoggers();
562 assertTrue(session.stop());
563
564 List<String> output = session.view();
565 assertNotNull(output);
566 assertFalse(output.isEmpty());
567
568 testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
569 "{ \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" } }");
570
571 assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
572 }
573 }
This page took 0.052587 seconds and 3 git commands to generate.