2 * Copyright (C) 2015, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
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.
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.
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.
19 package org
.lttng
.ust
.agent
.integration
.filter
;
21 import static org
.junit
.Assert
.assertEquals
;
23 import java
.io
.IOException
;
24 import java
.util
.Collections
;
25 import java
.util
.HashSet
;
27 import java
.util
.stream
.Collectors
;
28 import java
.util
.stream
.Stream
;
30 import org
.junit
.After
;
31 import org
.junit
.Before
;
32 import org
.junit
.Ignore
;
33 import org
.junit
.Test
;
34 import org
.junit
.runner
.RunWith
;
35 import org
.lttng
.tools
.ILttngSession
;
36 import org
.lttng
.ust
.agent
.ILttngHandler
;
37 import org
.lttng
.ust
.agent
.filter
.FilterChangeNotifier
;
38 import org
.lttng
.ust
.agent
.filter
.IFilterChangeListener
;
39 import org
.lttng
.ust
.agent
.session
.EventRule
;
40 import org
.lttng
.ust
.agent
.session
.LogLevelSelector
;
41 import org
.lttng
.ust
.agent
.session
.LogLevelSelector
.LogLevelType
;
42 import org
.lttng
.ust
.agent
.utils
.ILogLevelStrings
;
43 import org
.lttng
.ust
.agent
.utils
.TestPrintRunner
;
46 * Base test class for {@link IFilterChangeListener} tests.
48 * @author Alexandre Montplaisir
50 @RunWith(TestPrintRunner
.class)
51 public abstract class FilterListenerITBase
{
53 protected static final LogLevelSelector LOG_LEVEL_UNSPECIFIED
= new LogLevelSelector(Integer
.MIN_VALUE
, 0);
55 private static final String EVENT_NAME_A
= "eventA";
56 private static final String EVENT_NAME_B
= "eventB";
57 private static final String EVENT_NAME_C
= "eventC";
59 private ILttngSession session
;
60 private TestFilterListener listener
;
61 private ILttngHandler handler
;
63 protected abstract ILttngSession
.Domain
getSessionDomain();
64 protected abstract ILttngHandler
getLogHandler() throws SecurityException
, IOException
;
65 protected abstract ILogLevelStrings
getLogLevelStrings();
70 * @throws SecurityException
74 public void setup() throws SecurityException
, IOException
{
75 handler
= getLogHandler();
76 listener
= new TestFilterListener();
77 FilterChangeNotifier
.getInstance().registerListener(listener
);
78 session
= ILttngSession
.createSession(null, getSessionDomain());
85 public void teardown() {
87 FilterChangeNotifier
.getInstance().unregisterListener(listener
);
92 * Test not sending any commands.
95 public void testNoRules() {
96 assertEquals(0, listener
.getNbNotifications());
97 assertEquals(Collections
.EMPTY_SET
, listener
.getCurrentRules());
101 * Test sending one event rule.
104 public void testOneRule() {
105 Set
<EventRule
> rules
= Collections
.singleton(
106 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null));
108 session
.enableEvent(EVENT_NAME_A
, null, false, null);
110 assertEquals(1, listener
.getNbNotifications());
111 assertEquals(rules
, listener
.getCurrentRules());
115 * Test sending many event rules.
118 public void testManyRules() {
119 Set
<EventRule
> rules
= Stream
120 .of(new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
121 new EventRule(EVENT_NAME_B
, LOG_LEVEL_UNSPECIFIED
, null),
122 new EventRule(EVENT_NAME_C
, LOG_LEVEL_UNSPECIFIED
, null))
123 .collect(Collectors
.toSet());
125 session
.enableEvent(EVENT_NAME_A
, null, false, null);
126 session
.enableEvent(EVENT_NAME_B
, null, false, null);
127 session
.enableEvent(EVENT_NAME_C
, null, false, null);
129 assertEquals(3, listener
.getNbNotifications());
130 assertEquals(rules
, listener
.getCurrentRules());
134 * Test enabling then disabling some events.
137 public void testManyRulesDisableSome() {
138 Set
<EventRule
> rules
= Collections
.singleton(
139 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null));
141 session
.enableEvent(EVENT_NAME_A
, null, false, null);
142 session
.enableEvent(EVENT_NAME_B
, null, false, null);
143 session
.enableEvent(EVENT_NAME_C
, null, false, null);
144 session
.disableEvents(EVENT_NAME_B
);
145 session
.disableEvents(EVENT_NAME_C
);
147 assertEquals(5, listener
.getNbNotifications());
148 assertEquals(rules
, listener
.getCurrentRules());
152 * Test enabling some rules, then calling disable-event -a.
155 public void testManyRulesDisableAll() {
156 Set
<EventRule
> rules
= Collections
.EMPTY_SET
;
158 session
.enableEvent(EVENT_NAME_A
, null, false, null);
159 session
.enableEvent(EVENT_NAME_B
, null, false, null);
160 session
.enableEvent(EVENT_NAME_C
, null, false, null);
161 session
.disableAllEvents();
164 * We should receive 6 notifications, because a "disable-event -a" sends
165 * one for each event that was enabled.
167 assertEquals(6, listener
.getNbNotifications());
168 assertEquals(rules
, listener
.getCurrentRules());
172 * Test enabling the same event name with various values of loglevels.
174 @Ignore("Does not work as expected atm, see http://bugs.lttng.org/issues/913")
176 public void testSameEventsDiffLogLevels() {
177 LogLevelSelector lls1
= new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType
.LTTNG_EVENT_LOGLEVEL_RANGE
);
178 LogLevelSelector lls2
= new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType
.LTTNG_EVENT_LOGLEVEL_SINGLE
);
179 LogLevelSelector lls3
= new LogLevelSelector(getLogLevelStrings().infoInt(), LogLevelType
.LTTNG_EVENT_LOGLEVEL_RANGE
);
181 Set
<EventRule
> rules
= Stream
.of(
182 new EventRule(EVENT_NAME_A
, lls1
, null),
183 new EventRule(EVENT_NAME_A
, lls2
, null),
184 new EventRule(EVENT_NAME_A
, lls3
, null))
185 .collect(Collectors
.toSet());
187 session
.enableEvent(EVENT_NAME_A
, getLogLevelStrings().warningName(), false, null);
188 session
.enableEvent(EVENT_NAME_A
, getLogLevelStrings().warningName(), true, null);
189 session
.enableEvent(EVENT_NAME_A
, getLogLevelStrings().infoName(), false, null);
191 assertEquals(3, listener
.getNbNotifications());
192 assertEquals(rules
, listener
.getCurrentRules());
196 * Test enabling the same event name with various filters.
198 @Ignore("Filters are not tracked yet")
200 public void testSameEventsDiffFilters() {
201 String filterA
= "filterA";
202 String filterB
= "filterB";
204 Set
<EventRule
> rules
= Stream
.of(
205 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
206 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, filterA
),
207 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, filterB
))
208 .collect(Collectors
.toSet());
210 session
.enableEvent(EVENT_NAME_A
, null, false, null);
211 session
.enableEvent(EVENT_NAME_B
, null, false, filterA
);
212 session
.enableEvent(EVENT_NAME_C
, null, false, filterB
);
214 assertEquals(3, listener
.getNbNotifications());
215 assertEquals(rules
, listener
.getCurrentRules());
219 * Test sending some notifications then detaching a listener. Subsequent
220 * notifications should not be sent.
223 public void testDetachingListener() {
224 Set
<EventRule
> rules
= Stream
.of(
225 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
226 new EventRule(EVENT_NAME_B
, LOG_LEVEL_UNSPECIFIED
, null))
227 .collect(Collectors
.toSet());
229 session
.enableEvent(EVENT_NAME_A
, null, false, null);
230 session
.enableEvent(EVENT_NAME_B
, null, false, null);
231 FilterChangeNotifier
.getInstance().unregisterListener(listener
);
232 session
.enableEvent(EVENT_NAME_C
, null, false, null);
234 assertEquals(2, listener
.getNbNotifications());
235 assertEquals(rules
, listener
.getCurrentRules());
239 * Run a test with multiple listeners attached to the manager. All listeners
240 * should receive all the data.
243 public void testMultipleListeners() {
244 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
245 TestFilterListener listener2
= new TestFilterListener();
246 TestFilterListener listener3
= new TestFilterListener();
247 fcn
.registerListener(listener2
);
248 fcn
.registerListener(listener3
);
250 Set
<EventRule
> rules
= Stream
.of(
251 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
252 new EventRule(EVENT_NAME_B
, LOG_LEVEL_UNSPECIFIED
, null))
253 .collect(Collectors
.toSet());
255 session
.enableEvent(EVENT_NAME_A
, null, false, null);
256 session
.enableEvent(EVENT_NAME_B
, null, false, null);
257 session
.enableEvent(EVENT_NAME_C
, null, false, null);
258 session
.disableEvents(EVENT_NAME_C
);
260 assertEquals(4, listener
.getNbNotifications());
261 assertEquals(rules
, listener
.getCurrentRules());
263 assertEquals(4, listener2
.getNbNotifications());
264 assertEquals(rules
, listener2
.getCurrentRules());
266 assertEquals(4, listener3
.getNbNotifications());
267 assertEquals(rules
, listener3
.getCurrentRules());
269 fcn
.unregisterListener(listener2
);
270 fcn
.unregisterListener(listener3
);
274 * Test with both attached and unattached listeners. The unattached ones
275 * should not receive anything, but should not interfere with the other
279 public void testUnattachedListeners() {
280 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
281 TestFilterListener listener2
= new TestFilterListener();
282 TestFilterListener listener3
= new TestFilterListener();
283 /* We attach then detach listener2. We never attach listener3 */
284 fcn
.registerListener(listener2
);
285 fcn
.unregisterListener(listener2
);
287 Set
<EventRule
> rules
= Stream
.of(
288 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
289 new EventRule(EVENT_NAME_B
, LOG_LEVEL_UNSPECIFIED
, null))
290 .collect(Collectors
.toSet());
292 session
.enableEvent(EVENT_NAME_A
, null, false, null);
293 session
.enableEvent(EVENT_NAME_B
, null, false, null);
295 assertEquals(2, listener
.getNbNotifications());
296 assertEquals(rules
, listener
.getCurrentRules());
298 assertEquals(0, listener2
.getNbNotifications());
299 assertEquals(Collections
.EMPTY_SET
, listener2
.getCurrentRules());
301 assertEquals(0, listener3
.getNbNotifications());
302 assertEquals(Collections
.EMPTY_SET
, listener3
.getCurrentRules());
306 * Test that a newly-registered listener correctly receives the "statedump",
307 * which means all the rules currently active, upon registration.
310 public void testStatedump() {
311 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
312 TestFilterListener listener2
= new TestFilterListener();
314 Set
<EventRule
> rules1
= Stream
.of(
315 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
316 new EventRule(EVENT_NAME_B
, LOG_LEVEL_UNSPECIFIED
, null))
317 .collect(Collectors
.toSet());
318 Set
<EventRule
> rules2
= Stream
.of(
319 new EventRule(EVENT_NAME_A
, LOG_LEVEL_UNSPECIFIED
, null),
320 new EventRule(EVENT_NAME_C
, LOG_LEVEL_UNSPECIFIED
, null))
321 .collect(Collectors
.toSet());
323 session
.enableEvent(EVENT_NAME_A
, null, false, null);
324 session
.enableEvent(EVENT_NAME_B
, null, false, null);
325 fcn
.registerListener(listener2
);
327 /* We should have received the "statedump" when registering */
328 assertEquals(2, listener2
.getNbNotifications());
329 assertEquals(rules1
, listener2
.getCurrentRules());
331 session
.enableEvent(EVENT_NAME_C
, null, false, null);
332 session
.disableEvents(EVENT_NAME_B
);
334 /* Subsequent changes should also be received */
335 assertEquals(4, listener2
.getNbNotifications());
336 assertEquals(rules2
, listener2
.getCurrentRules());
338 fcn
.unregisterListener(listener2
);
342 * The filter listener used for tests.
347 * <li>Specify the expected number of notifications and end rules with
348 * {@link #setParameters}.</li>
349 * <li>Send the commands to LTTng (using {@link ILttngSession} for example.
351 * <li>Call {@link #waitForAllNotifications()}.</li>
352 * <li>Verify that {@link #checkRules()} returns true.</li>
356 private static class TestFilterListener
implements IFilterChangeListener
{
358 private final Set
<EventRule
> currentRules
= new HashSet
<>();
359 private volatile int currentNotifications
= 0;
361 public TestFilterListener() {}
364 public void eventRuleAdded(EventRule rule
) {
365 currentRules
.add(rule
);
366 currentNotifications
++;
370 public void eventRuleRemoved(EventRule rule
) {
371 currentRules
.remove(rule
);
372 currentNotifications
++;
375 public int getNbNotifications() {
376 return currentNotifications
;
379 public Set
<EventRule
> getCurrentRules() {