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() {