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());
83 public void teardown() {
85 FilterChangeNotifier
.getInstance().unregisterListener(listener
);
90 * Test not sending any commands.
93 public void testNoRules() {
94 assertEquals(0, listener
.getNbNotifications());
95 assertEquals(Collections
.EMPTY_SET
, listener
.getCurrentRules());
99 * Test sending one event rule.
102 public void testOneRule() {
103 Set
<EventRule
> rules
= Collections
.singleton(
104 EventRuleFactory
.createRule(EVENT_NAME_A
));
106 session
.enableEvent(EVENT_NAME_A
, null, false, null);
108 assertEquals(1, listener
.getNbNotifications());
109 assertEquals(rules
, listener
.getCurrentRules());
113 * Test sending many event rules.
116 public void testManyRules() {
117 Set
<EventRule
> rules
= Stream
.of(
118 EventRuleFactory
.createRule(EVENT_NAME_A
),
119 EventRuleFactory
.createRule(EVENT_NAME_B
),
120 EventRuleFactory
.createRule(EVENT_NAME_C
))
121 .collect(Collectors
.toSet());
123 session
.enableEvent(EVENT_NAME_A
, null, false, null);
124 session
.enableEvent(EVENT_NAME_B
, null, false, null);
125 session
.enableEvent(EVENT_NAME_C
, null, false, null);
127 assertEquals(3, listener
.getNbNotifications());
128 assertEquals(rules
, listener
.getCurrentRules());
132 * Test enabling then disabling some events.
135 public void testManyRulesDisableSome() {
136 Set
<EventRule
> rules
= Collections
.singleton(
137 EventRuleFactory
.createRule(EVENT_NAME_A
));
139 session
.enableEvent(EVENT_NAME_A
, null, false, null);
140 session
.enableEvent(EVENT_NAME_B
, null, false, null);
141 session
.enableEvent(EVENT_NAME_C
, null, false, null);
142 session
.disableEvents(EVENT_NAME_B
);
143 session
.disableEvents(EVENT_NAME_C
);
145 assertEquals(5, listener
.getNbNotifications());
146 assertEquals(rules
, listener
.getCurrentRules());
150 * Test enabling some rules, then calling disable-event -a.
153 public void testManyRulesDisableAll() {
154 Set
<EventRule
> rules
= Collections
.EMPTY_SET
;
156 session
.enableEvent(EVENT_NAME_A
, null, false, null);
157 session
.enableEvent(EVENT_NAME_B
, null, false, null);
158 session
.enableEvent(EVENT_NAME_C
, null, false, null);
159 session
.disableAllEvents();
162 * We should receive 6 notifications, because a "disable-event -a" sends
163 * one for each event that was enabled.
165 assertEquals(6, listener
.getNbNotifications());
166 assertEquals(rules
, listener
.getCurrentRules());
170 * Test enabling the same event name with various values of loglevels.
173 public void testSameEventsDiffLogLevels() {
174 LogLevelSelector lls1
= new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType
.LTTNG_EVENT_LOGLEVEL_RANGE
);
175 LogLevelSelector lls2
= new LogLevelSelector(getLogLevelStrings().warningInt(), LogLevelType
.LTTNG_EVENT_LOGLEVEL_SINGLE
);
176 LogLevelSelector lls3
= new LogLevelSelector(getLogLevelStrings().infoInt(), LogLevelType
.LTTNG_EVENT_LOGLEVEL_RANGE
);
178 Set
<EventRule
> rules
= Stream
.of(
179 EventRuleFactory
.createRule(EVENT_NAME_A
, lls1
),
180 EventRuleFactory
.createRule(EVENT_NAME_A
, lls2
),
181 EventRuleFactory
.createRule(EVENT_NAME_A
, lls3
))
182 .collect(Collectors
.toSet());
184 session
.enableEvent(EVENT_NAME_A
, getLogLevelStrings().warningName(), false, null);
185 session
.enableEvent(EVENT_NAME_A
, getLogLevelStrings().warningName(), true, null);
186 session
.enableEvent(EVENT_NAME_A
, getLogLevelStrings().infoName(), false, null);
188 assertEquals(3, listener
.getNbNotifications());
189 assertEquals(rules
, listener
.getCurrentRules());
193 * Test enabling the same event name with various filters.
196 public void testSameEventsDiffFilters() {
197 String filterA
= "filterA";
198 String filterB
= "filterB";
200 Set
<EventRule
> rules
= Stream
.of(
201 EventRuleFactory
.createRule(EVENT_NAME_A
),
202 EventRuleFactory
.createRule(EVENT_NAME_B
, EventRuleFactory
.LOG_LEVEL_UNSPECIFIED
, filterA
),
203 EventRuleFactory
.createRule(EVENT_NAME_C
, EventRuleFactory
.LOG_LEVEL_UNSPECIFIED
, filterB
))
204 .collect(Collectors
.toSet());
206 session
.enableEvent(EVENT_NAME_A
, null, false, null);
207 session
.enableEvent(EVENT_NAME_B
, null, false, filterA
);
208 session
.enableEvent(EVENT_NAME_C
, null, false, filterB
);
210 assertEquals(3, listener
.getNbNotifications());
211 assertEquals(rules
, listener
.getCurrentRules());
215 * Test sending some notifications then detaching a listener. Subsequent
216 * notifications should not be sent.
219 public void testDetachingListener() {
220 Set
<EventRule
> rules
= Stream
.of(
221 EventRuleFactory
.createRule(EVENT_NAME_A
),
222 EventRuleFactory
.createRule(EVENT_NAME_B
))
223 .collect(Collectors
.toSet());
225 session
.enableEvent(EVENT_NAME_A
, null, false, null);
226 session
.enableEvent(EVENT_NAME_B
, null, false, null);
227 FilterChangeNotifier
.getInstance().unregisterListener(listener
);
228 session
.enableEvent(EVENT_NAME_C
, null, false, null);
230 assertEquals(2, listener
.getNbNotifications());
231 assertEquals(rules
, listener
.getCurrentRules());
235 * Run a test with multiple listeners attached to the manager. All listeners
236 * should receive all the data.
239 public void testMultipleListeners() {
240 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
241 TestFilterListener listener2
= new TestFilterListener();
242 TestFilterListener listener3
= new TestFilterListener();
243 fcn
.registerListener(listener2
);
244 fcn
.registerListener(listener3
);
246 Set
<EventRule
> rules
= Stream
.of(
247 EventRuleFactory
.createRule(EVENT_NAME_A
),
248 EventRuleFactory
.createRule(EVENT_NAME_B
))
249 .collect(Collectors
.toSet());
251 session
.enableEvent(EVENT_NAME_A
, null, false, null);
252 session
.enableEvent(EVENT_NAME_B
, null, false, null);
253 session
.enableEvent(EVENT_NAME_C
, null, false, null);
254 session
.disableEvents(EVENT_NAME_C
);
256 assertEquals(4, listener
.getNbNotifications());
257 assertEquals(rules
, listener
.getCurrentRules());
259 assertEquals(4, listener2
.getNbNotifications());
260 assertEquals(rules
, listener2
.getCurrentRules());
262 assertEquals(4, listener3
.getNbNotifications());
263 assertEquals(rules
, listener3
.getCurrentRules());
265 fcn
.unregisterListener(listener2
);
266 fcn
.unregisterListener(listener3
);
270 * Test with both attached and unattached listeners. The unattached ones
271 * should not receive anything, but should not interfere with the other
275 public void testUnattachedListeners() {
276 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
277 TestFilterListener listener2
= new TestFilterListener();
278 TestFilterListener listener3
= new TestFilterListener();
279 /* We attach then detach listener2. We never attach listener3 */
280 fcn
.registerListener(listener2
);
281 fcn
.unregisterListener(listener2
);
283 Set
<EventRule
> rules
= Stream
.of(
284 EventRuleFactory
.createRule(EVENT_NAME_A
),
285 EventRuleFactory
.createRule(EVENT_NAME_B
))
286 .collect(Collectors
.toSet());
288 session
.enableEvent(EVENT_NAME_A
, null, false, null);
289 session
.enableEvent(EVENT_NAME_B
, null, false, null);
291 assertEquals(2, listener
.getNbNotifications());
292 assertEquals(rules
, listener
.getCurrentRules());
294 assertEquals(0, listener2
.getNbNotifications());
295 assertEquals(Collections
.EMPTY_SET
, listener2
.getCurrentRules());
297 assertEquals(0, listener3
.getNbNotifications());
298 assertEquals(Collections
.EMPTY_SET
, listener3
.getCurrentRules());
302 * Test that a newly-registered listener correctly receives the "statedump",
303 * which means all the rules currently active, upon registration.
306 public void testStatedump() {
307 FilterChangeNotifier fcn
= FilterChangeNotifier
.getInstance();
308 TestFilterListener listener2
= new TestFilterListener();
310 Set
<EventRule
> rules1
= Stream
.of(
311 EventRuleFactory
.createRule(EVENT_NAME_A
),
312 EventRuleFactory
.createRule(EVENT_NAME_B
))
313 .collect(Collectors
.toSet());
314 Set
<EventRule
> rules2
= Stream
.of(
315 EventRuleFactory
.createRule(EVENT_NAME_A
),
316 EventRuleFactory
.createRule(EVENT_NAME_C
))
317 .collect(Collectors
.toSet());
319 session
.enableEvent(EVENT_NAME_A
, null, false, null);
320 session
.enableEvent(EVENT_NAME_B
, null, false, null);
321 fcn
.registerListener(listener2
);
323 /* We should have received the "statedump" when registering */
324 assertEquals(2, listener2
.getNbNotifications());
325 assertEquals(rules1
, listener2
.getCurrentRules());
327 session
.enableEvent(EVENT_NAME_C
, null, false, null);
328 session
.disableEvents(EVENT_NAME_B
);
330 /* Subsequent changes should also be received */
331 assertEquals(4, listener2
.getNbNotifications());
332 assertEquals(rules2
, listener2
.getCurrentRules());
334 fcn
.unregisterListener(listener2
);
338 * The filter listener used for tests.
340 private static class TestFilterListener
implements IFilterChangeListener
{
342 private final Set
<EventRule
> currentRules
= new HashSet
<>();
343 private volatile int currentNotifications
= 0;
345 public TestFilterListener() {}
348 public void eventRuleAdded(EventRule rule
) {
349 currentRules
.add(rule
);
350 currentNotifications
++;
354 public void eventRuleRemoved(EventRule rule
) {
355 currentRules
.remove(rule
);
356 currentNotifications
++;
359 public int getNbNotifications() {
360 return currentNotifications
;
363 public Set
<EventRule
> getCurrentRules() {