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
.Test
;
33 import org
.junit
.runner
.RunWith
;
34 import org
.lttng
.tools
.ILttngSession
;
35 import org
.lttng
.ust
.agent
.ILttngHandler
;
36 import org
.lttng
.ust
.agent
.filter
.FilterChangeNotifier
;
37 import org
.lttng
.ust
.agent
.filter
.IFilterChangeListener
;
38 import org
.lttng
.ust
.agent
.session
.EventRule
;
39 import org
.lttng
.ust
.agent
.session
.LogLevelSelector
;
40 import org
.lttng
.ust
.agent
.session
.LogLevelSelector
.LogLevelType
;
41 import org
.lttng
.ust
.agent
.utils
.EventRuleFactory
;
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 private static final String EVENT_NAME_A
= "eventA";
54 private static final String EVENT_NAME_B
= "eventB";
55 private static final String EVENT_NAME_C
= "eventC";
57 private ILttngSession session
;
58 private TestFilterListener listener
;
59 private ILttngHandler handler
;
61 protected abstract ILttngSession
.Domain
getSessionDomain();
62 protected abstract ILttngHandler
getLogHandler() throws SecurityException
, IOException
;
63 protected abstract ILogLevelStrings
getLogLevelStrings();
68 * @throws SecurityException
72 public void setup() throws SecurityException
, IOException
{
73 handler
= getLogHandler();
74 listener
= new TestFilterListener();
75 FilterChangeNotifier
.getInstance().registerListener(listener
);
76 session
= ILttngSession
.createSession(null, getSessionDomain());
78 assertEquals(0, listener
.getNbNotifications());
85 public void teardown() {
87 FilterChangeNotifier
.getInstance().unregisterListener(listener
);
93 * Test not sending any commands.
96 public void testNoRules() {
97 assertEquals(0, listener
.getNbNotifications());
98 assertEquals(Collections
.EMPTY_SET
, listener
.getCurrentRules());
102 * Test sending one event rule.
105 public void testOneRule() {
106 Set
<EventRule
> rules
= Collections
.singleton(
107 EventRuleFactory
.createRule(EVENT_NAME_A
));
109 session
.enableEvent(EVENT_NAME_A
, null, false, null);
111 assertEquals(1, listener
.getNbNotifications());
112 assertEquals(rules
, listener
.getCurrentRules());
116 * Test sending many event rules.
119 public void testManyRules() {
120 Set
<EventRule
> rules
= Stream
.of(
121 EventRuleFactory
.createRule(EVENT_NAME_A
),
122 EventRuleFactory
.createRule(EVENT_NAME_B
),
123 EventRuleFactory
.createRule(EVENT_NAME_C
))
124 .collect(Collectors
.toSet());
126 session
.enableEvent(EVENT_NAME_A
, null, false, null);
127 session
.enableEvent(EVENT_NAME_B
, null, false, null);
128 session
.enableEvent(EVENT_NAME_C
, null, false, null);
130 assertEquals(3, listener
.getNbNotifications());
131 assertEquals(rules
, listener
.getCurrentRules());
135 * Test enabling then disabling some events.
138 public void testManyRulesDisableSome() {
139 Set
<EventRule
> rules
= Collections
.singleton(
140 EventRuleFactory
.createRule(EVENT_NAME_A
));
142 session
.enableEvent(EVENT_NAME_A
, null, false, null);
143 session
.enableEvent(EVENT_NAME_B
, null, false, null);
144 session
.enableEvent(EVENT_NAME_C
, null, false, null);
145 session
.disableEvents(EVENT_NAME_B
);
146 session
.disableEvents(EVENT_NAME_C
);
148 assertEquals(5, listener
.getNbNotifications());
149 assertEquals(rules
, listener
.getCurrentRules());
153 * Test enabling some rules, then calling disable-event -a.
156 public void testManyRulesDisableAll() {
157 Set
<EventRule
> rules
= Collections
.EMPTY_SET
;
159 session
.enableEvent(EVENT_NAME_A
, null, false, null);
160 session
.enableEvent(EVENT_NAME_B
, null, false, null);
161 session
.enableEvent(EVENT_NAME_C
, null, false, null);
162 session
.disableAllEvents();
165 * We should receive 6 notifications, because a "disable-event -a" sends
166 * one for each event that was enabled.
168 assertEquals(6, listener
.getNbNotifications());
169 assertEquals(rules
, listener
.getCurrentRules());
173 * Test enabling the same event name with various values of loglevels.
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 EventRuleFactory
.createRule(EVENT_NAME_A
, lls1
),
183 EventRuleFactory
.createRule(EVENT_NAME_A
, lls2
),
184 EventRuleFactory
.createRule(EVENT_NAME_A
, lls3
))
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.
199 public void testSameEventsDiffFilters() {
200 String filterA
= "filterA";
201 String filterB
= "filterB";
203 Set
<EventRule
> rules
= Stream
.of(
204 EventRuleFactory
.createRule(EVENT_NAME_A
),
205 EventRuleFactory
.createRule(EVENT_NAME_B
, EventRuleFactory
.LOG_LEVEL_UNSPECIFIED
, filterA
),
206 EventRuleFactory
.createRule(EVENT_NAME_C
, EventRuleFactory
.LOG_LEVEL_UNSPECIFIED
, filterB
))
207 .collect(Collectors
.toSet());
209 session
.enableEvent(EVENT_NAME_A
, null, false, null);
210 session
.enableEvent(EVENT_NAME_B
, null, false, filterA
);
211 session
.enableEvent(EVENT_NAME_C
, null, false, filterB
);
213 assertEquals(3, listener
.getNbNotifications());
214 assertEquals(rules
, listener
.getCurrentRules());
218 * Test sending some notifications then detaching a listener. Subsequent
219 * notifications should not be sent.
222 public void testDetachingListener() {
223 Set
<EventRule
> rules
= Stream
.of(
224 EventRuleFactory
.createRule(EVENT_NAME_A
),
225 EventRuleFactory
.createRule(EVENT_NAME_B
))
226 .collect(Collectors
.toSet());
228 session
.enableEvent(EVENT_NAME_A
, null, false, null);
229 session
.enableEvent(EVENT_NAME_B
, null, false, null);
230 FilterChangeNotifier
.getInstance().unregisterListener(listener
);
231 session
.enableEvent(EVENT_NAME_C
, null, false, null);
233 assertEquals(2, listener
.getNbNotifications());
234 assertEquals(rules
, listener
.getCurrentRules());
238 * Run a test with multiple listeners attached to the manager. All listeners
239 * should receive all the data.
242 public void testMultipleListeners() {
243 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
244 TestFilterListener listener2
= new TestFilterListener();
245 TestFilterListener listener3
= new TestFilterListener();
246 fcn
.registerListener(listener2
);
247 fcn
.registerListener(listener3
);
249 Set
<EventRule
> rules
= Stream
.of(
250 EventRuleFactory
.createRule(EVENT_NAME_A
),
251 EventRuleFactory
.createRule(EVENT_NAME_B
))
252 .collect(Collectors
.toSet());
254 session
.enableEvent(EVENT_NAME_A
, null, false, null);
255 session
.enableEvent(EVENT_NAME_B
, null, false, null);
256 session
.enableEvent(EVENT_NAME_C
, null, false, null);
257 session
.disableEvents(EVENT_NAME_C
);
259 assertEquals(4, listener
.getNbNotifications());
260 assertEquals(rules
, listener
.getCurrentRules());
262 assertEquals(4, listener2
.getNbNotifications());
263 assertEquals(rules
, listener2
.getCurrentRules());
265 assertEquals(4, listener3
.getNbNotifications());
266 assertEquals(rules
, listener3
.getCurrentRules());
268 fcn
.unregisterListener(listener2
);
269 fcn
.unregisterListener(listener3
);
273 * Test with both attached and unattached listeners. The unattached ones
274 * should not receive anything, but should not interfere with the other
278 public void testUnattachedListeners() {
279 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
280 TestFilterListener listener2
= new TestFilterListener();
281 TestFilterListener listener3
= new TestFilterListener();
282 /* We attach then detach listener2. We never attach listener3 */
283 fcn
.registerListener(listener2
);
284 fcn
.unregisterListener(listener2
);
286 Set
<EventRule
> rules
= Stream
.of(
287 EventRuleFactory
.createRule(EVENT_NAME_A
),
288 EventRuleFactory
.createRule(EVENT_NAME_B
))
289 .collect(Collectors
.toSet());
291 session
.enableEvent(EVENT_NAME_A
, null, false, null);
292 session
.enableEvent(EVENT_NAME_B
, null, false, null);
294 assertEquals(2, listener
.getNbNotifications());
295 assertEquals(rules
, listener
.getCurrentRules());
297 assertEquals(0, listener2
.getNbNotifications());
298 assertEquals(Collections
.EMPTY_SET
, listener2
.getCurrentRules());
300 assertEquals(0, listener3
.getNbNotifications());
301 assertEquals(Collections
.EMPTY_SET
, listener3
.getCurrentRules());
305 * Test that a newly-registered listener correctly receives the "statedump",
306 * which means all the rules currently active, upon registration.
309 public void testStatedump() {
310 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
311 TestFilterListener listener2
= new TestFilterListener();
313 Set
<EventRule
> rules1
= Stream
.of(
314 EventRuleFactory
.createRule(EVENT_NAME_A
),
315 EventRuleFactory
.createRule(EVENT_NAME_B
))
316 .collect(Collectors
.toSet());
317 Set
<EventRule
> rules2
= Stream
.of(
318 EventRuleFactory
.createRule(EVENT_NAME_A
),
319 EventRuleFactory
.createRule(EVENT_NAME_C
))
320 .collect(Collectors
.toSet());
322 session
.enableEvent(EVENT_NAME_A
, null, false, null);
323 session
.enableEvent(EVENT_NAME_B
, null, false, null);
324 fcn
.registerListener(listener2
);
326 /* We should have received the "statedump" when registering */
327 assertEquals(2, listener2
.getNbNotifications());
328 assertEquals(rules1
, listener2
.getCurrentRules());
330 session
.enableEvent(EVENT_NAME_C
, null, false, null);
331 session
.disableEvents(EVENT_NAME_B
);
333 /* Subsequent changes should also be received */
334 assertEquals(4, listener2
.getNbNotifications());
335 assertEquals(rules2
, listener2
.getCurrentRules());
337 fcn
.unregisterListener(listener2
);
341 * The filter listener used for tests.
343 static class TestFilterListener
implements IFilterChangeListener
{
345 private final Set
<EventRule
> currentRules
= new HashSet
<>();
346 private volatile int currentNotifications
= 0;
348 public TestFilterListener() {}
351 public void eventRuleAdded(EventRule rule
) {
352 currentRules
.add(rule
);
353 currentNotifications
++;
357 public void eventRuleRemoved(EventRule rule
) {
358 currentRules
.remove(rule
);
359 currentNotifications
++;
362 public int getNbNotifications() {
363 return currentNotifications
;
366 public Set
<EventRule
> getCurrentRules() {