Commit | Line | Data |
---|---|---|
f37120c3 AM |
1 | /* |
2 | * Copyright (C) 2015, 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.client; | |
20 | ||
21 | import static org.junit.Assert.assertEquals; | |
22 | import static org.junit.Assert.assertTrue; | |
23 | import static org.junit.Assume.assumeTrue; | |
24 | ||
25 | import java.util.ArrayList; | |
26 | import java.util.Arrays; | |
27 | import java.util.Collections; | |
28 | import java.util.List; | |
29 | ||
30 | import org.junit.After; | |
31 | import org.junit.AfterClass; | |
32 | import org.junit.Before; | |
33 | import org.junit.BeforeClass; | |
f37120c3 | 34 | import org.junit.Test; |
1df8e5d7 | 35 | import org.junit.runner.RunWith; |
f37120c3 AM |
36 | import org.lttng.tools.ILttngSession; |
37 | import org.lttng.tools.LttngToolsHelper; | |
38 | import org.lttng.ust.agent.ILttngAgent; | |
39 | import org.lttng.ust.agent.client.LttngTcpSessiondClient; | |
40 | import org.lttng.ust.agent.session.EventRule; | |
329f5794 AM |
41 | import org.lttng.ust.agent.session.LogLevelSelector; |
42 | import org.lttng.ust.agent.session.LogLevelSelector.LogLevelType; | |
1df8e5d7 | 43 | import org.lttng.ust.agent.utils.EventRuleFactory; |
f37120c3 | 44 | import org.lttng.ust.agent.utils.ILogLevelStrings; |
1df8e5d7 | 45 | import org.lttng.ust.agent.utils.TestPrintRunner; |
f37120c3 AM |
46 | |
47 | /** | |
48 | * Tests for the TCP client only, without using an agent. | |
49 | * | |
50 | * This test suite requires that a *root* session daemon is running on the | |
51 | * system. Since we have to explicitly tell the TCP client which sessiond to | |
52 | * connect to, we have to hard-code it in here. | |
53 | * | |
54 | * @author Alexandre Montplaisir | |
55 | */ | |
1df8e5d7 | 56 | @RunWith(TestPrintRunner.class) |
f37120c3 AM |
57 | public class TcpClientIT { |
58 | ||
59 | // ------------------------------------------------------------------------ | |
60 | // Attributes | |
61 | // ------------------------------------------------------------------------ | |
62 | ||
f37120c3 AM |
63 | private static final String EVENT_NAME_A = "eventA"; |
64 | private static final String EVENT_NAME_B = "eventB"; | |
65 | private static final String EVENT_NAME_C = "eventC"; | |
f37120c3 AM |
66 | |
67 | /* Test configuration */ | |
68 | private static final int DOMAIN_VALUE = ILttngAgent.Domain.JUL.value(); | |
69 | private static final ILttngSession.Domain SESSION_DOMAIN = ILttngSession.Domain.JUL; | |
70 | private static final boolean ROOT_SESSIOND = true; | |
71 | ||
72 | private static TcpClientDebugListener clientListener; | |
73 | private static LttngTcpSessiondClient client; | |
74 | private static Thread clientThread; | |
75 | ||
76 | private ILttngSession session; | |
77 | ||
78 | // ------------------------------------------------------------------------ | |
79 | // Maintenance | |
80 | // ------------------------------------------------------------------------ | |
81 | ||
82 | /** | |
83 | * Class setup | |
84 | */ | |
85 | @BeforeClass | |
86 | public static void setupClass() { | |
87 | LttngToolsHelper.destroyAllSessions(); | |
88 | ||
89 | clientListener = new TcpClientDebugListener(); | |
90 | client = new LttngTcpSessiondClient(clientListener, DOMAIN_VALUE, ROOT_SESSIOND); | |
91 | ||
92 | clientThread = new Thread(client); | |
93 | clientThread.start(); | |
94 | ||
95 | assumeTrue("Timed out waiting for root sessiond", client.waitForConnection(5)); | |
96 | } | |
97 | ||
98 | /** | |
99 | * Class teardown | |
100 | */ | |
101 | @AfterClass | |
102 | public static void teardownClass() { | |
103 | if (client != null) { | |
104 | client.close(); | |
105 | } | |
106 | if (clientThread != null) { | |
107 | try { | |
108 | clientThread.join(); | |
109 | } catch (InterruptedException e) { | |
110 | } | |
111 | } | |
112 | } | |
113 | ||
114 | /** | |
115 | * Test setup | |
116 | */ | |
117 | @Before | |
118 | public void setup() { | |
119 | session = ILttngSession.createSession(null, SESSION_DOMAIN); | |
120 | clientListener.clearAllCommands(); | |
121 | } | |
122 | ||
123 | /** | |
124 | * Test teardown | |
125 | */ | |
126 | @After | |
127 | public void teardown() { | |
128 | session.close(); | |
129 | } | |
130 | ||
131 | ||
132 | private static ILogLevelStrings getLogLevelStrings() { | |
133 | return ILogLevelStrings.JUL_LOGLEVEL_STRINGS; | |
134 | } | |
135 | ||
136 | /** | |
137 | * Check that two lists contain the exact same element (including | |
138 | * duplicates), but their order does not matter. | |
139 | */ | |
140 | private static <T extends Comparable<T>> boolean containSameElements(List<T> list1, List<T> list2) { | |
141 | List<T> newlist1 = new ArrayList<>(list1); | |
142 | List<T> newlist2 = new ArrayList<>(list2); | |
143 | Collections.sort(newlist1); | |
144 | Collections.sort(newlist2); | |
145 | return (newlist1.equals(newlist2)); | |
146 | ||
147 | } | |
148 | ||
149 | // ------------------------------------------------------------------------ | |
150 | // Test cases | |
151 | // ------------------------------------------------------------------------ | |
152 | ||
153 | /** | |
154 | * Test enabling one event. | |
155 | */ | |
156 | @Test | |
157 | public void testEnableEvent() { | |
158 | session.enableEvent(EVENT_NAME_A, null, false, null); | |
159 | ||
160 | List<EventRule> expectedCommands = Collections.singletonList( | |
1df8e5d7 | 161 | EventRuleFactory.createRule(EVENT_NAME_A)); |
f37120c3 AM |
162 | |
163 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); | |
164 | assertEquals(expectedCommands, actualCommands); | |
165 | } | |
166 | ||
167 | /** | |
168 | * Test an "enable-event -a" command. | |
169 | */ | |
170 | @Test | |
171 | public void testEnableAllEvents() { | |
172 | session.enableAllEvents(); | |
173 | ||
174 | List<EventRule> expectedCommands = Collections.singletonList( | |
1df8e5d7 | 175 | EventRuleFactory.createRuleAllEvents()); |
f37120c3 AM |
176 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); |
177 | ||
178 | assertEquals(expectedCommands, actualCommands); | |
179 | } | |
180 | ||
181 | /** | |
182 | * Test enabling then disabling one event. | |
183 | */ | |
184 | @Test | |
185 | public void testEnableThenDisableOneEvent() { | |
186 | session.enableEvent(EVENT_NAME_A, null, false, null); | |
187 | session.disableEvents(EVENT_NAME_A); | |
188 | ||
189 | List<EventRule> expectedEnableCommands = Collections.singletonList( | |
1df8e5d7 | 190 | EventRuleFactory.createRule(EVENT_NAME_A)); |
f37120c3 AM |
191 | List<String> expectedDisableCommands = Collections.singletonList(EVENT_NAME_A); |
192 | ||
193 | assertEquals(expectedEnableCommands, clientListener.getEnabledEventCommands()); | |
194 | assertTrue(containSameElements(expectedDisableCommands, clientListener.getDisabledEventCommands())); | |
195 | } | |
196 | ||
197 | /** | |
198 | * Test enabling some events manually, then disabling all events (-a). | |
199 | */ | |
200 | @Test | |
201 | public void testEnableSomeThenDisableAll() { | |
202 | session.enableEvent(EVENT_NAME_A, null, false, null); | |
203 | session.enableEvent(EVENT_NAME_B, null, false, null); | |
204 | session.enableEvent(EVENT_NAME_C, null, false, null); | |
205 | session.disableAllEvents(); | |
206 | ||
207 | List<EventRule> expectedEnableCommands = Arrays.asList( | |
1df8e5d7 AM |
208 | EventRuleFactory.createRule(EVENT_NAME_A), |
209 | EventRuleFactory.createRule(EVENT_NAME_B), | |
210 | EventRuleFactory.createRule(EVENT_NAME_C)); | |
f37120c3 AM |
211 | /* |
212 | * A "disable-event -a" will send one command for each enabled event. | |
213 | * The order may be different though. | |
214 | */ | |
215 | List<String> expectedDisableCommands = Arrays.asList( | |
216 | EVENT_NAME_A, EVENT_NAME_B, EVENT_NAME_C); | |
217 | ||
218 | assertEquals(expectedEnableCommands, clientListener.getEnabledEventCommands()); | |
219 | assertTrue(containSameElements(expectedDisableCommands, clientListener.getDisabledEventCommands())); | |
220 | } | |
221 | ||
222 | /** | |
223 | * Test enabling then (enable-event -a) then disabling all (disable-event -a) events. | |
224 | */ | |
225 | @Test | |
226 | public void testEnableAllThenDisableAll() { | |
227 | session.enableAllEvents(); | |
228 | session.disableAllEvents(); | |
229 | ||
1df8e5d7 AM |
230 | List<EventRule> expectedEnableCommands = Arrays.asList(EventRuleFactory.createRuleAllEvents()); |
231 | List<String> expectedDisableCommands = Arrays.asList(EventRuleFactory.EVENT_NAME_ALL); | |
f37120c3 AM |
232 | |
233 | assertEquals(expectedEnableCommands, clientListener.getEnabledEventCommands()); | |
234 | assertTrue(containSameElements(expectedDisableCommands, clientListener.getDisabledEventCommands())); | |
235 | } | |
236 | ||
c5796c3e AM |
237 | /** |
238 | * Test enabling then destroying the session (should send corresponding | |
239 | * disable event messages). | |
240 | */ | |
241 | @SuppressWarnings("static-method") | |
242 | @Test | |
243 | public void testEnableEventThenDestroy() { | |
244 | try (ILttngSession session2 = ILttngSession.createSession(null, SESSION_DOMAIN);) { | |
245 | session2.enableEvent(EVENT_NAME_A, null, false, null); | |
246 | session2.enableEvent(EVENT_NAME_B, null, false, null); | |
247 | } // close(), aka destroy the session, sending "disable event" messages | |
248 | ||
249 | List<EventRule> expectedEnabledCommands = Arrays.asList(EventRuleFactory.createRule(EVENT_NAME_A), EventRuleFactory.createRule(EVENT_NAME_B)); | |
250 | List<String> expectedDisabledCommands = Arrays.asList(EVENT_NAME_A, EVENT_NAME_B); | |
251 | ||
252 | assertEquals(expectedEnabledCommands, clientListener.getEnabledEventCommands()); | |
253 | assertEquals(expectedDisabledCommands, clientListener.getDisabledEventCommands()); | |
254 | } | |
255 | ||
f37120c3 AM |
256 | /** |
257 | * Test specifying an event with a --loglevel option. | |
258 | */ | |
259 | @Test | |
260 | public void testEnableEventLogLevelRange() { | |
329f5794 | 261 | LogLevelSelector lls = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_RANGE); |
f37120c3 AM |
262 | |
263 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), false, null); | |
264 | ||
265 | List<EventRule> expectedCommands = Collections.singletonList( | |
1df8e5d7 | 266 | EventRuleFactory.createRule(EVENT_NAME_A, lls)); |
f37120c3 AM |
267 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); |
268 | ||
269 | assertEquals(expectedCommands, actualCommands); | |
270 | } | |
271 | ||
272 | /** | |
273 | * Test enabling an event with a --loglevel-only option. | |
274 | */ | |
275 | @Test | |
276 | public void testEnableEventLogLevelSingle() { | |
329f5794 | 277 | LogLevelSelector lls = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_SINGLE); |
f37120c3 AM |
278 | |
279 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), true, null); | |
280 | ||
281 | List<EventRule> expectedCommands = Collections.singletonList( | |
1df8e5d7 | 282 | EventRuleFactory.createRule(EVENT_NAME_A, lls)); |
f37120c3 AM |
283 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); |
284 | ||
285 | assertEquals(expectedCommands, actualCommands); | |
286 | } | |
287 | ||
288 | /** | |
289 | * Test enabling an event twice, for the same loglevel, with --loglevel followed by --loglevel-only. | |
290 | */ | |
f37120c3 AM |
291 | @Test |
292 | public void testEnableEventsLogLevelRangeAndSingle() { | |
329f5794 AM |
293 | LogLevelSelector lls1 = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_RANGE); |
294 | LogLevelSelector lls2 = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_SINGLE); | |
f37120c3 AM |
295 | |
296 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), false, null); | |
297 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), true, null); | |
298 | ||
299 | List<EventRule> expectedCommands = Arrays.asList( | |
1df8e5d7 AM |
300 | EventRuleFactory.createRule(EVENT_NAME_A, lls1), |
301 | EventRuleFactory.createRule(EVENT_NAME_A, lls2) | |
f37120c3 AM |
302 | ); |
303 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); | |
304 | ||
305 | assertEquals(expectedCommands, actualCommands); | |
306 | } | |
307 | ||
308 | /** | |
1df8e5d7 | 309 | * Test enabling an event twice, for the same loglevel, with --loglevel-only followed by --loglevel. |
f37120c3 | 310 | */ |
f37120c3 AM |
311 | @Test |
312 | public void testEnableEventsLogLevelSingleAndRange() { | |
329f5794 AM |
313 | LogLevelSelector lls1 = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_SINGLE); |
314 | LogLevelSelector lls2 = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_RANGE); | |
f37120c3 AM |
315 | |
316 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), true, null); | |
317 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), false, null); | |
318 | ||
319 | List<EventRule> expectedCommands = Arrays.asList( | |
1df8e5d7 AM |
320 | EventRuleFactory.createRule(EVENT_NAME_A, lls1), |
321 | EventRuleFactory.createRule(EVENT_NAME_A, lls2) | |
f37120c3 AM |
322 | ); |
323 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); | |
324 | ||
325 | assertEquals(expectedCommands, actualCommands); | |
326 | } | |
327 | ||
328 | /** | |
329 | * Test enabling the same event, same loglevel, but different loglevel types | |
330 | * (--loglevel vs --loglevel-only) in two separate sessions. | |
331 | */ | |
332 | @Test | |
333 | public void testEnableEventsLogLevelRangeAndSingleDiffSessions() { | |
334 | try (ILttngSession session2 = ILttngSession.createSession(null, SESSION_DOMAIN);) { | |
335 | ||
329f5794 AM |
336 | LogLevelSelector lls1 = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_RANGE); |
337 | LogLevelSelector lls2 = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_SINGLE); | |
f37120c3 AM |
338 | |
339 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), false, null); | |
340 | session2.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), true, null); | |
341 | ||
1df8e5d7 AM |
342 | List<EventRule> expectedCommands = Arrays.asList( |
343 | EventRuleFactory.createRule(EVENT_NAME_A, lls1), | |
344 | EventRuleFactory.createRule(EVENT_NAME_A, lls2)); | |
f37120c3 AM |
345 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); |
346 | ||
347 | assertEquals(expectedCommands, actualCommands); | |
348 | } | |
349 | } | |
1df8e5d7 AM |
350 | |
351 | /** | |
352 | * Enable the same event multiple times with different filter strings. | |
353 | */ | |
354 | @Test | |
355 | public void testEnableEventsDiffFilters() { | |
356 | final String filter1 = "filter1"; | |
357 | final String filter2 = "filter2"; | |
358 | ||
359 | session.enableEvent(EVENT_NAME_A, null, false, null); | |
360 | session.enableEvent(EVENT_NAME_A, null, false, filter1); | |
361 | session.enableEvent(EVENT_NAME_A, null, false, filter2); | |
362 | ||
363 | List<EventRule> expectedCommands = Arrays.asList( | |
364 | EventRuleFactory.createRule(EVENT_NAME_A), | |
365 | EventRuleFactory.createRule(EVENT_NAME_A, EventRuleFactory.LOG_LEVEL_UNSPECIFIED, filter1), | |
366 | EventRuleFactory.createRule(EVENT_NAME_A, EventRuleFactory.LOG_LEVEL_UNSPECIFIED, filter2)); | |
367 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); | |
368 | ||
369 | assertEquals(expectedCommands, actualCommands); | |
370 | } | |
371 | ||
372 | /** | |
373 | * Enable the same event multiple times with different log levels and | |
374 | * filters. | |
375 | */ | |
376 | @Test | |
377 | public void testEnableEventsLogLevelAndFilters() { | |
378 | final LogLevelSelector lls = new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType.LTTNG_EVENT_LOGLEVEL_RANGE); | |
379 | final String filter = "filter1"; | |
380 | ||
381 | session.enableEvent(EVENT_NAME_A, null, false, null); | |
382 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), false, null); | |
383 | session.enableEvent(EVENT_NAME_A, null, false, filter); | |
384 | session.enableEvent(EVENT_NAME_A, getLogLevelStrings().warningName(), false, filter); | |
385 | ||
386 | List<EventRule> expectedCommands = Arrays.asList( | |
387 | EventRuleFactory.createRule(EVENT_NAME_A), | |
388 | EventRuleFactory.createRule(EVENT_NAME_A, lls), | |
389 | EventRuleFactory.createRule(EVENT_NAME_A, EventRuleFactory.LOG_LEVEL_UNSPECIFIED, filter), | |
390 | EventRuleFactory.createRule(EVENT_NAME_A, lls, filter)); | |
391 | List<EventRule> actualCommands = clientListener.getEnabledEventCommands(); | |
392 | ||
393 | assertEquals(expectedCommands, actualCommands); | |
394 | } | |
f37120c3 | 395 | } |