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.jupiter.api.Assertions.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.jupiter.api.Test;
31 import org.junit.jupiter.api.extension.ExtendWith;
32 import org.junit.jupiter.api.AfterEach;
33 import org.junit.jupiter.api.BeforeEach;
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.TestPrintExtension;
46 * Base test class for {@link IFilterChangeListener} tests.
48 * @author Alexandre Montplaisir
50 @ExtendWith(TestPrintExtension.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() {