From: Alexandre Montplaisir Date: Thu, 2 Jun 2016 05:14:06 +0000 (-0400) Subject: Add base and JUL tests to test logger hierarchy X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=fe6a3925eb9ae4514ff89db93c743e030f7afa99;p=lttng-ust-java-tests.git Add base and JUL tests to test logger hierarchy Make sure "lttng list" correctly includes parent/child loggers that may be visible by UST, even if they themselves do not have LTTng log handlers attached. Signed-off-by: Alexandre Montplaisir --- diff --git a/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/events/LoggerHierachyListITBase.java b/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/events/LoggerHierachyListITBase.java new file mode 100644 index 0000000..5e1af16 --- /dev/null +++ b/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/events/LoggerHierachyListITBase.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.lttng.ust.agent.integration.events; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runners.Parameterized.Parameters; +import org.lttng.tools.ILttngSession; + +/** + * Base class testing the "lttng list" command when using loggers organized as a + * hierarchy. + * + * For example, if a "org.myapp" logger exists and has a LTTng handler attached, + * a "org.myapp.mycomponent" logger should show up in "lttng list", even if + * itself does not have a handler, because its parent's handler can catch the + * log events as UST tracepoints. + * + * @author Alexandre Montplaisir + */ +public abstract class LoggerHierachyListITBase { + + protected static final String PARENT_LOGGER = "org.lttng"; + protected static final String CHILD_LOGGER = "org.lttng.mycomponent"; + + protected final boolean parentLoggerActive; + protected final boolean parentLoggerHasHandler; + protected final boolean childLoggerActive; + protected final boolean childLoggerHasHandler; + + private ILttngSession session; + + // ------------------------------------------------------------------------ + // Test parameter definition + // ------------------------------------------------------------------------ + + /** + * Generator for the test parameters. + * + * Generates all possible combinations of the 4 constructor parameters, + * except "parentActive" is necessarily true when "hasHandler" is true for a + * given logger. + * + * @return The test parameters + */ + @Parameters(name = "{index}: parentActive={0}, parentHasHandler={1}, childActive={2}, childHasHandler={3}") + public static Iterable testCases() { + /* + * Kept the whole array for clarity, but some cases are commented out: + * it is impossible to attach an handler if the logger itself is not + * defined! + */ + return Arrays.asList(new Object[][] { + { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE }, + { Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE }, +// { Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.TRUE }, + { Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.FALSE }, + + { Boolean.TRUE, Boolean.FALSE, Boolean.TRUE, Boolean.TRUE }, + { Boolean.TRUE, Boolean.FALSE, Boolean.TRUE, Boolean.FALSE }, +// { Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, Boolean.TRUE }, + { Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE }, + +// { Boolean.FALSE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE }, +// { Boolean.FALSE, Boolean.TRUE, Boolean.TRUE, Boolean.FALSE }, +// { Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, Boolean.TRUE }, +// { Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, Boolean.FALSE }, + + { Boolean.FALSE, Boolean.FALSE, Boolean.TRUE, Boolean.TRUE }, + { Boolean.FALSE, Boolean.FALSE, Boolean.TRUE, Boolean.FALSE }, +// { Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, Boolean.TRUE }, + { Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE }, + }); + } + + /** + * Test constructor + * + * @param parentLoggerActive + * Parent logger has been instantiated + * @param parentLoggerHasHandler + * Parent logger has a LTTng handler attached to it + * @param childLoggerActive + * Child logger has been instantiated + * @param childLoggerHasHandler + * Child logger has a LTTng handler attached to it + */ + public LoggerHierachyListITBase(boolean parentLoggerActive, + boolean parentLoggerHasHandler, + boolean childLoggerActive, + boolean childLoggerHasHandler) { + this.parentLoggerActive = parentLoggerActive; + this.parentLoggerHasHandler = parentLoggerHasHandler; + this.childLoggerActive = childLoggerActive; + this.childLoggerHasHandler = childLoggerHasHandler; + } + + protected ILttngSession getSession() { + return session; + } + + // ------------------------------------------------------------------------ + // Maintenance + // ------------------------------------------------------------------------ + + /** + * Common test setup + */ + @Before + public void testSetup() { + session = ILttngSession.createSession(null, getDomain()); + } + + /** + * Common test teardown + */ + @After + public void testTeardown() { + session.close(); + } + + // ------------------------------------------------------------------------ + // Abstract methods + // ------------------------------------------------------------------------ + + protected abstract ILttngSession.Domain getDomain(); + + protected abstract void activateLoggers() throws IOException; + + // ------------------------------------------------------------------------ + // Common tests + // ------------------------------------------------------------------------ + + /** + * Test the output of the "lttng list" command. + * + * @throws IOException + * Fails the test + */ + @Test + public void testList() throws IOException { + activateLoggers(); + + List enabledEvents = session.listEvents(); + List expectedEvents = new ArrayList<>(); + + /* Reminder: "hasHandler" implies "isActive" */ + + if (parentLoggerHasHandler) { + expectedEvents.add(PARENT_LOGGER); + } + if (childLoggerHasHandler || + (childLoggerActive && parentLoggerHasHandler)) { + expectedEvents.add(CHILD_LOGGER); + } + + Collections.sort(enabledEvents); + Collections.sort(expectedEvents); + assertEquals(expectedEvents, enabledEvents); + } +} diff --git a/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/events/JulLegacyApiLoggerHierarchyListIT.java b/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/events/JulLegacyApiLoggerHierarchyListIT.java new file mode 100644 index 0000000..a9ecf8c --- /dev/null +++ b/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/events/JulLegacyApiLoggerHierarchyListIT.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.lttng.ust.agent.integration.events; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.lttng.tools.ILttngSession.Domain; +import org.lttng.ust.agent.LTTngAgent; +import org.lttng.ust.agent.utils.JulTestUtils; + +/** + * Implementation of {@link LoggerHierachyListITBase} for the JUL part of the + * legacy LTTngAgent API. + * + * @author Alexandre Montplaisir + */ +@SuppressWarnings("deprecation") +@RunWith(Parameterized.class) +public class JulLegacyApiLoggerHierarchyListIT extends LoggerHierachyListITBase { + + private LTTngAgent agent; + private Logger parentLogger; + private Logger childLogger; + + /** + * Test constructor + * + * @param parentLoggerActive + * Parent logger has been instantiated + * @param parentLoggerHasHandler + * Parent logger has a LTTng handler attached to it + * @param childLoggerActive + * Child logger has been instantiated + * @param childLoggerHasHandler + * Child logger has a LTTng handler attached to it + */ + public JulLegacyApiLoggerHierarchyListIT(boolean parentLoggerActive, + boolean parentLoggerHasHandler, + boolean childLoggerActive, + boolean childLoggerHasHandler) { + /* Set by parameters defined in the base class */ + super(parentLoggerActive, + parentLoggerHasHandler, + childLoggerActive, + childLoggerHasHandler); + } + + // ------------------------------------------------------------------------ + // Maintenance + // ------------------------------------------------------------------------ + + /** + * Class setup + */ + @BeforeClass + public static void julClassSetup() { + JulTestUtils.testClassSetup(); + } + + /** + * Class cleanup + */ + @AfterClass + public static void julClassCleanup() { + JulTestUtils.testClassCleanup(); + } + + /** + * Test setup + */ + @SuppressWarnings("static-method") + @Before + public void setup() { + LogManager.getLogManager().reset(); + System.gc(); + } + + /** + * Test cleanup + */ + @After + public void cleanup() { + agent.dispose(); + + if (parentLogger != null) { + parentLogger = null; + } + + if (childLogger != null) { + childLogger = null; + } + + LogManager.getLogManager().reset(); + System.gc(); + } + + // ------------------------------------------------------------------------ + // Abstract methods + // ------------------------------------------------------------------------ + + @Override + protected Domain getDomain() { + return Domain.JUL; + } + + @Override + protected void activateLoggers() throws IOException { + agent = LTTngAgent.getLTTngAgent(); + + /* + * There is no notion of "hasHandler" for the legacy API: there is only + * one log handler attached to the root logger, so there are no handlers + * to specific events/loggers. + */ + + if (parentLoggerActive) { + parentLogger = Logger.getLogger(PARENT_LOGGER); + } + + if (childLoggerActive) { + childLogger = Logger.getLogger(CHILD_LOGGER); + } + } + + // ------------------------------------------------------------------------ + // Overridden tests + // ------------------------------------------------------------------------ + + /** + * Due to how the legacy agent works, there is no notion of "hasHandler". If + * the logger exists, it will be visible in "lttng list" because the single + * log handler is attached to the root logger. + */ + @Override + @Test + public void testList() throws IOException { + activateLoggers(); + + List enabledEvents = getSession().listEvents(); + List expectedEvents = new ArrayList<>(); + + if (parentLoggerActive) { + expectedEvents.add(PARENT_LOGGER); + } + if (childLoggerActive) { + expectedEvents.add(CHILD_LOGGER); + } + + Collections.sort(enabledEvents); + Collections.sort(expectedEvents); + assertEquals(expectedEvents, enabledEvents); + } + +} diff --git a/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/events/JulLoggerHierarchyListIT.java b/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/events/JulLoggerHierarchyListIT.java new file mode 100644 index 0000000..4254aaf --- /dev/null +++ b/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/events/JulLoggerHierarchyListIT.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.lttng.ust.agent.integration.events; + +import java.io.IOException; +import java.util.logging.Handler; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.lttng.tools.ILttngSession.Domain; +import org.lttng.ust.agent.jul.LttngLogHandler; +import org.lttng.ust.agent.utils.JulTestUtils; + +/** + * Implementation of {@link LoggerHierachyListITBase} for JUL log handlers. + * + * @author Alexandre Montplaisir + */ +@RunWith(Parameterized.class) +public class JulLoggerHierarchyListIT extends LoggerHierachyListITBase { + + private Logger parentLogger; + private Logger childLogger; + + private Handler parentHandler; + private Handler childHandler; + + /** + * Test constructor + * + * @param parentLoggerActive + * Parent logger has been instantiated + * @param parentLoggerHasHandler + * Parent logger has a LTTng handler attached to it + * @param childLoggerActive + * Child logger has been instantiated + * @param childLoggerHasHandler + * Child logger has a LTTng handler attached to it + */ + public JulLoggerHierarchyListIT(boolean parentLoggerActive, + boolean parentLoggerHasHandler, + boolean childLoggerActive, + boolean childLoggerHasHandler) { + /* Set by parameters defined in the base class */ + super(parentLoggerActive, + parentLoggerHasHandler, + childLoggerActive, + childLoggerHasHandler); + } + + // ------------------------------------------------------------------------ + // Maintenance + // ------------------------------------------------------------------------ + + /** + * Class setup + */ + @BeforeClass + public static void julClassSetup() { + JulTestUtils.testClassSetup(); + } + + /** + * Class cleanup + */ + @AfterClass + public static void julClassCleanup() { + JulTestUtils.testClassCleanup(); + } + + /** + * + */ + @After + public void cleanup() { + if (parentLogger != null) { + if (parentHandler != null) { + parentLogger.removeHandler(parentHandler); + parentHandler.close(); + parentHandler = null; + } + parentLogger = null; + } + + if (childLogger != null) { + if (childHandler != null) { + childLogger.removeHandler(childHandler); + childHandler.close(); + childHandler = null; + } + childLogger = null; + } + + /* + * Kind of hackish, but it's the only way to ensure that loggers are + * really removed in-between tests, since LogManager does not provide a + * way to forcibly remove a logger, and it doesn't seem like it will any + * time soon, see http://bugs.java.com/view_bug.do?bug_id=4811930 + */ + LogManager.getLogManager().reset(); + System.gc(); + } + + // ------------------------------------------------------------------------ + // Abstract methods + // ------------------------------------------------------------------------ + + @Override + protected Domain getDomain() { + return Domain.JUL; + } + + @Override + protected void activateLoggers() throws IOException { + if (parentLoggerActive) { + parentLogger = Logger.getLogger(PARENT_LOGGER); + if (parentLoggerHasHandler) { + parentHandler = new LttngLogHandler(); + parentLogger.addHandler(parentHandler); + } + } + + if (childLoggerActive) { + childLogger = Logger.getLogger(CHILD_LOGGER); + if (childLoggerHasHandler) { + childHandler = new LttngLogHandler(); + childLogger.addHandler(childHandler); + } + } + } + +} diff --git a/pom.xml b/pom.xml index 786ed97..642e7eb 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,14 @@ + + + com.google.guava + guava + 19.0 + + +