*/
Set<String> listEvents();
+ /**
+ * Enable an application context with the provided retriever/context names.
+ *
+ * There is currently no direct command to remove an existing context, the
+ * session has to be destroyed and re-created to do so.
+ *
+ * @param retrieverName
+ * The name of the retriever (or "namespace" of the context)
+ * @param contextName
+ * The name of the context
+ * @return If the command executed successfully (return code = 0)
+ */
+ boolean enableAppContext(String retrieverName, String contextName);
+
/**
* Start tracing
*
.collect(Collectors.toSet());
}
+ @Override
+ public boolean enableAppContext(String retrieverName, String contextName) {
+ return executeCommand(Arrays.asList(
+ "lttng", "add-context", domain.flag(),
+ "-t", "$app." + retrieverName + ':' + contextName,
+ "-s", sessionName));
+ }
+
@Override
public boolean start() {
/*
eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.lttng.tools.ILttngSession;
+import org.lttng.tools.ILttngSession.Domain;
+import org.lttng.ust.agent.ILttngHandler;
+import org.lttng.ust.agent.context.ContextInfoManager;
+import org.lttng.ust.agent.utils.TestPrintRunner;
+
+/**
+ * Base abstract class to implement all sorts of integration tests verifying the
+ * presence of enabled application contexts in resulting traces.
+ */
+@RunWith(TestPrintRunner.class)
+public abstract class AppContextITBase {
+
+ protected static final String EVENT_NAME = "EventName";
+
+ protected static final String RETRIEVER_NAME_1 = "Retriever1";
+ protected static final String RETRIEVER_NAME_2 = "Retriever2";
+
+ private static final String CONTEXT_NAME = ContextInfoRetrieverStubs.CONTEXT_NAME;
+
+ private ContextInfoManager cim;
+ private ILttngSession session;
+
+ /* Field defined by the sub-class */
+ protected ILttngHandler logHandler;
+
+ protected abstract Domain getDomain();
+
+ protected abstract void sendEventsToLoggers();
+
+ /**
+ * Base test setup
+ */
+ @Before
+ public void testSetup() {
+ try {
+ cim = ContextInfoManager.getInstance();
+ } catch (SecurityException | IOException e) {
+ /* The native library is not available! */
+ fail();
+ }
+ session = ILttngSession.createSession(null, getDomain());
+ }
+
+ /**
+ * Base test teardown
+ */
+ @After
+ public void testTeardown() {
+ session.close();
+
+ logHandler.close();
+ logHandler = null;
+
+ /* In case some tests fail or forget to unregister their retrievers */
+ cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1);
+ cim.unregisterContextInfoRetriever(RETRIEVER_NAME_2);
+ }
+
+ // ------------------------------------------------------------------------
+ // Context enabled/disabled tests
+ // ------------------------------------------------------------------------
+
+ /**
+ * Utility method to check that a context is present in all events of a
+ * trace output.
+ */
+ private static void testContextPresentInTrace(List<String> traceOutput, String retrieverName, String contextName, String contextValue) {
+ String fullString = "_app_" + retrieverName + "_" + contextName + " = " + contextValue;
+ traceOutput.forEach(line -> assertTrue(line.contains(fullString)));
+ }
+
+ /**
+ * Utility method to check that a context is *absent* from all events of a
+ * trace output
+ */
+ private static void testContextNotPresentInTrace(List<String> traceOutput, String retrieverName, String contextName) {
+ String fullString = "_app_" + retrieverName + "_" + contextName;
+ traceOutput.forEach(line -> assertFalse(line.contains(fullString)));
+ }
+
+ /**
+ * Test that if no retrievers are declared, no context info is passed at
+ * all.
+ */
+ @Test
+ public void testNoContexts() {
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that there is no "_app" contexts in the output */
+ output.forEach(line -> assertFalse(line.contains("_app")));
+ }
+
+ /**
+ * Test that if a retriever is registered and provides a context, but this
+ * context is not enabled in the tracing session, that it is not present in
+ * the trace.
+ */
+ @Test
+ public void testContextAvailableButNotEnabled() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
+
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that there is no "_app" contexts in the output */
+ output.forEach(line -> assertFalse(line.contains("_app")));
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test that if a context is enabled, but no retriever provides it, that the
+ * retriever/context names are still mentioned in the event but no value is
+ * provided.
+ */
+ @Test
+ public void testContextNotAvailableButEnabled() {
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
+
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that context name is there but value is not */
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ none = { } } }");
+ }
+
+ /**
+ * Test that if a context is enabled and provided by a retriever that it is
+ * correctly present in the tracing session.
+ */
+ @Test
+ public void testContextAvailableAndEnabled() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
+
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
+
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that context name + value are present */
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ string = \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test that one context is available by a retriever, but another is is
+ * enabled in the session. Only the latter should be mentioned in events,
+ * with no value.
+ */
+ @Test
+ public void testContextsOneAvailableOtherEnabled() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
+
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_2, CONTEXT_NAME));
+
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that only retriever-name-2 is present, with no value */
+ testContextNotPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME);
+ testContextPresentInTrace(output, RETRIEVER_NAME_2, CONTEXT_NAME, "{ none = { } } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test with two contexts provided in the application, but only one of them
+ * is enabled in the session. Only that one should be present in the trace,
+ * name and value.
+ */
+ @Test
+ public void testContextsTwoAvailableOneEnabled() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_2, ContextInfoRetrieverStubs.INTEGER_RETRIEVER));
+
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
+
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that only retriever-name-1 is present, name + value */
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ string = \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" }");
+ testContextNotPresentInTrace(output, RETRIEVER_NAME_2, CONTEXT_NAME);
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_2));
+ }
+
+ /**
+ * Test with two contexts enabled in the session but only one of them is
+ * provided by the application. Both should be mentioned in the trace, but
+ * only the provided one will have a value.
+ */
+ @Test
+ public void testContextsOneAvailableTwoEnabled() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
+
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_2, CONTEXT_NAME));
+
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ /* Test that both contexts are present, but only retriever-1's has a value */
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ string = \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" }");
+ testContextPresentInTrace(output, RETRIEVER_NAME_2, CONTEXT_NAME, "{ none = { } } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ // ------------------------------------------------------------------------
+ // Context types tests
+ // ------------------------------------------------------------------------
+
+ /**
+ * Utility method to enable all events, add the one context we are looking
+ * for, take a trace, and return the trace output.
+ */
+ private List<String> enableContextAndTrace() {
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME_1, CONTEXT_NAME));
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ return output;
+ }
+
+ /**
+ * Test a "null" context value.
+ */
+ @Test
+ public void testContextValueNull() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.NULL_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ none = { } } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test an integer (int32) context value.
+ */
+ @Test
+ public void testContextValueInteger() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.INTEGER_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ int32 = " + ContextInfoRetrieverStubs.INTEGER_VALUE + " } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a long (int64) context value.
+ */
+ @Test
+ public void testContextValueLong() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.LONG_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ int64 = " + ContextInfoRetrieverStubs.LONG_VALUE + " } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a double context value.
+ */
+ @Test
+ public void testContextValueDouble() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.DOUBLE_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ double = " + ContextInfoRetrieverStubs.DOUBLE_VALUE + " } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a character context value (should get converted to a string).
+ */
+ @Test
+ public void testContextValueCharacter() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.CHARACTER_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ string = \"" + ContextInfoRetrieverStubs.CHARACTER_VALUE + "\" } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a float context value.
+ */
+ @Test
+ public void testContextValueFloat() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.FLOAT_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ float = " + ContextInfoRetrieverStubs.FLOAT_VALUE + " } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a byte (int8) context value.
+ */
+ @Test
+ public void testContextValueByte() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.BYTE_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ int8 = " + ContextInfoRetrieverStubs.BYTE_VALUE + " } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a short (int16) context value.
+ */
+ @Test
+ public void testContextValueShort() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.SHORT_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ int16 = " + ContextInfoRetrieverStubs.SHORT_VALUE + " } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a "true" boolean context value (gets converted to a int8 of value 1).
+ */
+ @Test
+ public void testContextValueBooleanTrue() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.BOOLEAN_TRUE_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ int8 = 1 } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a "false" boolean context value (gets converted to a int8 of value 0).
+ */
+ @Test
+ public void testContextValueBooleanFalse() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.BOOLEAN_FALSE_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME, "{ int8 = 0 } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a string context value.
+ */
+ @Test
+ public void testContextValueString() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.STRING_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ string = \"" + ContextInfoRetrieverStubs.STRING_VALUE + "\" } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+
+ /**
+ * Test a Object context value (should be converted to a String via .toString()).
+ */
+ @Test
+ public void testContextValueObject() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME_1, ContextInfoRetrieverStubs.OBJECT_RETRIEVER));
+
+ List<String> output = enableContextAndTrace();
+ testContextPresentInTrace(output, RETRIEVER_NAME_1, CONTEXT_NAME,
+ "{ string = \"" + ContextInfoRetrieverStubs.OBJECT_VALUE.toString() + "\" } }");
+
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME_1));
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.lttng.tools.ILttngSession;
+import org.lttng.tools.LttngToolsHelper;
+import org.lttng.tools.ILttngSession.Domain;
+import org.lttng.ust.agent.ILttngHandler;
+import org.lttng.ust.agent.context.ContextInfoManager;
+import org.lttng.ust.agent.context.IContextInfoRetriever;
+import org.lttng.ust.agent.utils.TestPrintRunner;
+
+/**
+ * To obtain application contexts in a trace, three steps are required:
+ *
+ * <ul>
+ * <li>Having the Java agent register to the sessiond (Agent)</li>
+ * <li>Registering the application-provided context info retriever (Retriever)</li>
+ * <li>Enabling the contexts in the tracing session (Session)</li>
+ * </ul>
+ *
+ * These three steps however can occur in any order ; this means there are 6
+ * possible cases. The goal of this class is to test all these cases.
+ */
+@RunWith(TestPrintRunner.class)
+public abstract class AppContextOrderingITBase {
+
+ protected static final String EVENT_NAME = "EventName";
+
+ private static final IContextInfoRetriever RETRIEVER = ContextInfoRetrieverStubs.STRING_RETRIEVER;
+ private static final String RETRIEVER_NAME = "MyRetriever";
+ private static final String CONTEXT_NAME = ContextInfoRetrieverStubs.CONTEXT_NAME;
+ private static final String CONTEXT_VALUE = ContextInfoRetrieverStubs.STRING_VALUE;
+
+ protected ILttngHandler logHandler;
+
+ private ContextInfoManager cim;
+ private ILttngSession session;
+
+ protected abstract Domain getDomain();
+ protected abstract void sendEventsToLoggers();
+
+ /**
+ * Base test setup
+ */
+ @Before
+ public void testSetup() {
+ try {
+ cim = ContextInfoManager.getInstance();
+ } catch (SecurityException | IOException e) {
+ /* The native library is not available! */
+ fail();
+ }
+ session = ILttngSession.createSession(null, getDomain());
+ }
+
+ /**
+ * Base test cleanup
+ */
+ @After
+ public void testCleanup() {
+ session.close();
+ assertTrue(cim.unregisterContextInfoRetriever(RETRIEVER_NAME));
+ }
+
+ /**
+ * Base class cleanup
+ */
+ @AfterClass
+ public static void julClassCleanup() {
+ LttngToolsHelper.deleteAllTraces();
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Instantiate the log handler for the corresponding logging API. This will
+ * also spawn the agent and have it register to the sessiond, so it
+ * corresponds to the "Agent" step.
+ *
+ * This method should set the 'logHandler' field accordingly.
+ */
+ protected abstract void registerAgent();
+
+ /**
+ * Register the context info retriever to UST. This corresponds to the
+ * "Retriever" step.
+ */
+ private void registerRetriever() {
+ assertTrue(cim.registerContextInfoRetriever(RETRIEVER_NAME, RETRIEVER));
+ }
+
+ /**
+ * Enable the contexts in the tracing session. This corresponds to the "Session" step.
+ */
+ private void enableContextInSessions() {
+ assertTrue(session.enableAllEvents());
+ assertTrue(session.enableAppContext(RETRIEVER_NAME, CONTEXT_NAME));
+ }
+
+ /**
+ * Start tracing, send events from the application, and verify that the
+ * output contains the expected context information.
+ *
+ * This should be called only after all 3 steps above are done.
+ */
+ private void traceSendEventsAndVerify() {
+ assertTrue(session.start());
+ sendEventsToLoggers();
+ assertTrue(session.stop());
+
+ List<String> output = session.view();
+ assertNotNull(output);
+ assertFalse(output.isEmpty());
+
+ String expectedString = "_app_" + RETRIEVER_NAME + "_" + CONTEXT_NAME + " = { string = \"" + CONTEXT_VALUE + "\" } }";
+ output.forEach(line -> assertTrue(line.contains(expectedString)));
+ }
+
+ // ------------------------------------------------------------------------
+ // Test methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Test the sequence Agent -> Retriever -> Session
+ */
+ @Test
+ public void testAgentRetrieverSession() {
+ registerAgent();
+ registerRetriever();
+ enableContextInSessions();
+
+ traceSendEventsAndVerify();
+ }
+
+ /**
+ * Test the sequence Agent -> Session -> Retriever
+ */
+ @Test
+ public void testAgentSessionRetriever() {
+ registerAgent();
+ enableContextInSessions();
+ registerRetriever();
+
+ traceSendEventsAndVerify();
+ }
+
+ /**
+ * Test the sequence Retriever -> Agent -> Session
+ */
+ @Test
+ public void testRetrieverAgentSession() {
+ registerRetriever();
+ registerAgent();
+ enableContextInSessions();
+
+ traceSendEventsAndVerify();
+ }
+
+ /**
+ * Test the sequence Retriever -> Session -> Agent
+ */
+ @Test
+ public void testRetrieverSessionAgent() {
+ registerAgent();
+ registerRetriever();
+ enableContextInSessions();
+
+ traceSendEventsAndVerify();
+ }
+
+ /**
+ * Test the sequence Session -> Agent -> Retriever
+ */
+ @Test
+ public void testSessionAgentRetriever() {
+ registerAgent();
+ registerRetriever();
+ enableContextInSessions();
+
+ traceSendEventsAndVerify();
+ }
+
+ /**
+ * Test the sequence Session -> Retriever -> Agent
+ */
+ @Test
+ public void testSessionRetrieverAgent() {
+ registerAgent();
+ registerRetriever();
+ enableContextInSessions();
+
+ traceSendEventsAndVerify();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import org.lttng.ust.agent.context.IContextInfoRetriever;
+
+interface ContextInfoRetrieverStubs {
+
+ String CONTEXT_NAME = "ContextName";
+
+ Integer INTEGER_VALUE = Integer.valueOf(42);
+ Long LONG_VALUE = Long.valueOf(9001);
+ Double DOUBLE_VALUE = Double.valueOf(11.55);
+ Character CHARACTER_VALUE = Character.valueOf('a');
+ Float FLOAT_VALUE = Float.valueOf(2.8f);
+ Byte BYTE_VALUE = Byte.valueOf((byte) 8);
+ Short SHORT_VALUE = Short.valueOf((short) 500);
+ String STRING_VALUE = "ContextValue";
+
+ String OBJECT_VALUE_STRING = "ValueToString";
+ Object OBJECT_VALUE = new Object() {
+ @Override
+ public String toString() {
+ return OBJECT_VALUE_STRING;
+ }
+ };
+
+
+ IContextInfoRetriever NULL_RETRIEVER = (key -> null);
+ IContextInfoRetriever INTEGER_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? INTEGER_VALUE : null));
+ IContextInfoRetriever LONG_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? LONG_VALUE : null));
+ IContextInfoRetriever DOUBLE_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? DOUBLE_VALUE : null));
+ IContextInfoRetriever CHARACTER_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? CHARACTER_VALUE : null));
+ IContextInfoRetriever FLOAT_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? FLOAT_VALUE : null));
+ IContextInfoRetriever BYTE_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? BYTE_VALUE : null));
+ IContextInfoRetriever SHORT_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? SHORT_VALUE : null));
+ IContextInfoRetriever BOOLEAN_TRUE_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? Boolean.TRUE : null));
+ IContextInfoRetriever BOOLEAN_FALSE_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? Boolean.FALSE : null));
+ IContextInfoRetriever STRING_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? STRING_VALUE : null));
+ IContextInfoRetriever OBJECT_RETRIEVER = (key -> (CONTEXT_NAME.equals(key) ? OBJECT_VALUE : null));
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+/**
+ * Values defined by the LTTng tracer related to dynamically-typed contexts
+ */
+interface LttngContextValues {
+
+ // TODO check that these are all the right values
+ String NULL_TYPE_NAME = "";
+ String INTEGER_TYPE_NAME = "int";
+ String LONG_TYPE_NAME = "long";
+ String DOUBLE_TYPE_NAME = "double";
+ String CHARACTER_TYPE_NAME = "char";
+ String FLOAT_TYPE_NAME = "float";
+ String BYTE_TYPE_NAME = "byte";
+ String SHORT_TYPE_NAME = "short";
+ String BOOLEAN_TYPE_NAME = "bool";
+ String STRING_TYPE_NAME = "string";
+}
private final List<EventRule> enabledEventCommands = Collections.synchronizedList(new ArrayList<>());
private final List<String> disabledEventCommands = Collections.synchronizedList(new ArrayList<>());
+ private final List<String> enabledAppContextCommands = Collections.synchronizedList(new ArrayList<>());
+ private final List<String> disabledAppContextCommands = Collections.synchronizedList(new ArrayList<>());
+
@Override
public boolean eventEnabled(EventRule rule) {
enabledEventCommands.add(rule);
}
@Override
- public boolean appContextDisabled(String contextRetrieverName, String contextName) {
- // TODO NYI
- return false;
+ public boolean appContextEnabled(String contextRetrieverName, String contextName) {
+ enabledAppContextCommands.add(contextRetrieverName + ':' + contextName);
+ return true;
}
@Override
- public boolean appContextEnabled(String contextRetrieverName, String contextName) {
- // TODO NYI
- return false;
+ public boolean appContextDisabled(String contextRetrieverName, String contextName) {
+ disabledAppContextCommands.add(contextRetrieverName + ':' + contextName);
+ return true;
}
/**
}
}
+ /**
+ * @return The "add-context" commands that were received since instantiation
+ * or the last {@link #clearAllCommands}.
+ */
+ public List<String> getEnabledAppContextCommands() {
+ synchronized (enabledAppContextCommands) {
+ return new ArrayList<>(enabledAppContextCommands);
+ }
+ }
+
+ /**
+ * Return the number of "context disabled" commands received.
+ *
+ * There is no equivalent command in the lttng CLI, but the sessiond will
+ * send such messages through the agent socket when a session is destroyed
+ * and had contexts enabled.
+ *
+ * @return The number of "context disabled" commands received.
+ */
+ public List<String> getDisabledAppContextCommands() {
+ synchronized (disabledAppContextCommands) {
+ return new ArrayList<>(disabledAppContextCommands);
+ }
+ }
+
/**
* Clear all tracked data.
*/
public void clearAllCommands() {
enabledEventCommands.clear();
disabledEventCommands.clear();
+ enabledAppContextCommands.clear();
+ disabledAppContextCommands.clear();
}
}
private static final String EVENT_NAME_B = "eventB";
private static final String EVENT_NAME_C = "eventC";
+ private static final String CONTEXT_RETRIEVER_NAME_A = "retrieverA";
+ private static final String CONTEXT_RETRIEVER_NAME_B = "retrieverB";
+ private static final String CONTEXT_NAME_A = "contextA";
+ private static final String CONTEXT_NAME_B = "contextB";
+
/* Test configuration */
private static final int DOMAIN_VALUE = ILttngAgent.Domain.JUL.value();
private static final ILttngSession.Domain SESSION_DOMAIN = ILttngSession.Domain.JUL;
}
// ------------------------------------------------------------------------
- // Test cases
+ // Event enabling/disabling test cases
// ------------------------------------------------------------------------
/**
assertEquals(expectedCommands, actualCommands);
}
+
+ // ------------------------------------------------------------------------
+ // Application context enabling/disabling test cases
+ // ------------------------------------------------------------------------
+
+ /**
+ * Test enabling one application context.
+ */
+ @Test
+ public void testEnableAppContext() {
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+
+ List<String> expectedCommands = Collections.singletonList(
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A);
+
+ List<String> actualCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedCommands, actualCommands);
+ }
+
+ /**
+ * Test enabling two application contexts sharing the same retriever name.
+ */
+ @Test
+ public void testEnableAppContextsSameRetriever() {
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_B);
+
+ List<String> expectedCommands = Arrays.asList(
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A,
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_B);
+
+ List<String> actualCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedCommands, actualCommands);
+ }
+
+ /**
+ * Test enabling two application contexts sharing the same context name, but
+ * with different retrievers. Unusual, but they should still be recognized
+ * separately.
+ */
+ @Test
+ public void testEnableAppContextsSameContext() {
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_B, CONTEXT_NAME_A);
+
+ List<String> expectedCommands = Arrays.asList(
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A,
+ CONTEXT_RETRIEVER_NAME_B + ':' + CONTEXT_NAME_A);
+
+ List<String> actualCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedCommands, actualCommands);
+ }
+
+ /**
+ * Test enabling one application context, then destroying the session. We
+ * should receive the corresponding "context removed" message.
+ */
+ @Test
+ @SuppressWarnings("static-method")
+ public void testEnableAppContextThenDestroy() {
+ try (ILttngSession session2 = ILttngSession.createSession(null, SESSION_DOMAIN);) {
+ session2.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+ } // close(), aka destroy the session, sending "disable context" messages
+
+ List<String> expectedEnabledCommands = Collections.singletonList(CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A);
+ List<String> expectedDisabledCommands = Collections.singletonList(CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A);
+ List<String> actualEnabledCommands = clientListener.getEnabledAppContextCommands();
+ List<String> actualDisabledCommands = clientListener.getDisabledAppContextCommands();
+
+ assertEquals(expectedEnabledCommands, actualEnabledCommands);
+ assertEquals(expectedDisabledCommands, actualDisabledCommands);
+ }
+
+ /**
+ * Test enabling the same application context in two different sessions.
+ * Upon destroying one, we should only receive one "destroyed" message.
+ */
+ @Test
+ public void testEnableSameAppContextTwoSessions() {
+ List<String> expectedEnabledCommands = Arrays.asList(
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A,
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A);
+ List<String> actualEnabledCommands;
+
+ try (ILttngSession session2 = ILttngSession.createSession(null, SESSION_DOMAIN);) {
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+ session2.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+
+ actualEnabledCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedEnabledCommands, actualEnabledCommands);
+ } // close/destroy session2
+
+ actualEnabledCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedEnabledCommands, actualEnabledCommands);
+
+ List<String> expectedDisabledCommands = Collections.singletonList(CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A);
+ List<String> actualDisabledCommands = clientListener.getDisabledAppContextCommands();
+
+ assertEquals(expectedDisabledCommands, actualDisabledCommands);
+ }
+
+ /**
+ * Test enabling two different application context in two different
+ * sessions. Upon destroying one, we should receive the correct "destroyed"
+ * message.
+ */
+ @Test
+ public void testEnableDiffAppContextTwoSessions() {
+ List<String> expectedEnabledCommands = Arrays.asList(
+ CONTEXT_RETRIEVER_NAME_A + ':' + CONTEXT_NAME_A,
+ CONTEXT_RETRIEVER_NAME_B + ':' + CONTEXT_NAME_B);
+ List<String> actualEnabledCommands;
+
+ try (ILttngSession session2 = ILttngSession.createSession(null, SESSION_DOMAIN);) {
+ session.enableAppContext(CONTEXT_RETRIEVER_NAME_A, CONTEXT_NAME_A);
+ session2.enableAppContext(CONTEXT_RETRIEVER_NAME_B, CONTEXT_NAME_B);
+
+ actualEnabledCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedEnabledCommands, actualEnabledCommands);
+ } // close/destroy session2
+
+ actualEnabledCommands = clientListener.getEnabledAppContextCommands();
+ assertEquals(expectedEnabledCommands, actualEnabledCommands);
+
+ List<String> expectedDisabledCommands = Collections.singletonList(CONTEXT_RETRIEVER_NAME_B + ':' + CONTEXT_NAME_B);
+ List<String> actualDisabledCommands = clientListener.getDisabledAppContextCommands();
+
+ assertEquals(expectedDisabledCommands, actualDisabledCommands);
+ }
}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import static org.junit.Assume.assumeTrue;
+
+import java.io.IOException;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.lttng.tools.ILttngSession.Domain;
+import org.lttng.tools.LttngToolsHelper;
+import org.lttng.ust.agent.jul.LttngLogHandler;
+import org.lttng.ust.agent.utils.JulTestUtils;
+import org.lttng.ust.agent.utils.LttngUtils;
+
+/**
+ * Enabled app contexts test for the LTTng-UST JUL log handler.
+ */
+public class JulAppContextIT extends AppContextITBase {
+
+ private static final Domain DOMAIN = Domain.JUL;
+
+ private Logger logger;
+
+ /**
+ * Class setup
+ */
+ @BeforeClass
+ public static void julClassSetup() {
+ /* Skip tests if we can't find the JNI library or lttng-tools */
+ assumeTrue(JulTestUtils.checkForJulLibrary());
+ assumeTrue(LttngUtils.checkForLttngTools(Domain.JUL));
+
+ LttngToolsHelper.destroyAllSessions();
+ }
+
+ /**
+ * Class cleanup
+ */
+ @AfterClass
+ public static void julClassCleanup() {
+ LttngToolsHelper.deleteAllTraces();
+ }
+
+ /**
+ * Test setup
+ *
+ * @throws SecurityException
+ * @throws IOException
+ */
+ @Before
+ public void julSetup() throws SecurityException, IOException {
+ logger = Logger.getLogger(EVENT_NAME);
+ logger.setLevel(Level.ALL);
+
+ logHandler = new LttngLogHandler();
+ logger.addHandler((Handler) logHandler);
+ }
+
+ /**
+ * Test teardown
+ */
+ @After
+ public void julTeardown() {
+ logger.removeHandler((Handler) logHandler);
+ logger = null;
+ }
+
+ @Override
+ protected Domain getDomain() {
+ return DOMAIN;
+ }
+
+ @Override
+ protected void sendEventsToLoggers() {
+ JulTestUtils.send10EventsTo(logger);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.IOException;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.lttng.tools.ILttngSession.Domain;
+import org.lttng.tools.LttngToolsHelper;
+import org.lttng.ust.agent.jul.LttngLogHandler;
+import org.lttng.ust.agent.utils.JulTestUtils;
+import org.lttng.ust.agent.utils.LttngUtils;
+
+/**
+ * Implementation of {@link AppContextOrderingITBase} for the JUL API.
+ */
+public class JulAppContextOrderingIT extends AppContextOrderingITBase {
+
+ private Logger logger;
+
+ /**
+ * Class setup
+ */
+ @BeforeClass
+ public static void julClassSetup() {
+ /* Skip tests if we can't find the JNI library or lttng-tools */
+ assumeTrue(JulTestUtils.checkForJulLibrary());
+ assumeTrue(LttngUtils.checkForLttngTools(Domain.JUL));
+
+ LttngToolsHelper.destroyAllSessions();
+ }
+
+ /**
+ * Test teardown
+ */
+ @After
+ public void julTeardown() {
+ logger.removeHandler((Handler) logHandler);
+ logger = null;
+
+ logHandler.close();
+ logHandler = null;
+ }
+
+ @Override
+ protected Domain getDomain() {
+ return Domain.JUL;
+ }
+
+ @Override
+ protected void registerAgent() {
+ logger = Logger.getLogger(EVENT_NAME);
+ logger.setLevel(Level.ALL);
+
+ try {
+ logHandler = new LttngLogHandler();
+ } catch (SecurityException | IOException e) {
+ fail();
+ }
+ logger.addHandler((Handler) logHandler);
+ }
+
+ @Override
+ protected void sendEventsToLoggers() {
+ JulTestUtils.send10EventsTo(logger);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import static org.junit.Assume.assumeTrue;
+
+import java.io.IOException;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.lttng.tools.ILttngSession.Domain;
+import org.lttng.tools.LttngToolsHelper;
+import org.lttng.ust.agent.log4j.LttngLogAppender;
+import org.lttng.ust.agent.utils.Log4jTestUtils;
+import org.lttng.ust.agent.utils.LttngUtils;
+
+/**
+ * Enabled app contexts test for the LTTng-UST JUL log handler.
+ */
+public class Log4jAppContextIT extends AppContextITBase {
+
+ private static final Domain DOMAIN = Domain.LOG4J;
+
+ private Logger logger;
+
+ /**
+ * Class setup
+ */
+ @BeforeClass
+ public static void julClassSetup() {
+ /* Skip tests if we can't find the log4j library or lttng-tools */
+ assumeTrue(Log4jTestUtils.checkForLog4jLibrary());
+ assumeTrue(LttngUtils.checkForLttngTools(Domain.LOG4J));
+
+ LttngToolsHelper.destroyAllSessions();
+ }
+
+ /**
+ * Class cleanup
+ */
+ @AfterClass
+ public static void julClassCleanup() {
+ LttngToolsHelper.deleteAllTraces();
+ }
+
+ /**
+ * Test setup
+ *
+ * @throws SecurityException
+ * @throws IOException
+ */
+ @Before
+ public void julSetup() throws SecurityException, IOException {
+ logger = Logger.getLogger(EVENT_NAME);
+ logger.setLevel(Level.ALL);
+
+ logHandler = new LttngLogAppender();
+ logger.addAppender((Appender) logHandler);
+ }
+
+ /**
+ * Test teardown
+ */
+ @After
+ public void julTeardown() {
+ logger.removeAppender((Appender) logHandler);
+ logger = null;
+ }
+
+ @Override
+ protected Domain getDomain() {
+ return DOMAIN;
+ }
+
+ @Override
+ protected void sendEventsToLoggers() {
+ Log4jTestUtils.send10Events(logger);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2016, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * 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.context;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.IOException;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.lttng.tools.ILttngSession.Domain;
+import org.lttng.tools.LttngToolsHelper;
+import org.lttng.ust.agent.log4j.LttngLogAppender;
+import org.lttng.ust.agent.utils.Log4jTestUtils;
+import org.lttng.ust.agent.utils.LttngUtils;
+
+/**
+ * Implementation of {@link AppContextOrderingITBase} for the log4j API.
+ */
+public class Log4jAppContextOrderingIT extends AppContextOrderingITBase {
+
+ private Logger logger;
+
+ /**
+ * Class setup
+ */
+ @BeforeClass
+ public static void log4jClassSetup() {
+ /* Skip tests if we can't find the JNI library or lttng-tools */
+ assumeTrue(Log4jTestUtils.checkForLog4jLibrary());
+ assumeTrue(LttngUtils.checkForLttngTools(Domain.LOG4J));
+
+ LttngToolsHelper.destroyAllSessions();
+ }
+
+ /**
+ * Test teardown
+ */
+ @After
+ public void log4jTeardown() {
+ logger.removeAppender((Appender) logHandler);
+ logger = null;
+
+ logHandler.close();
+ logHandler = null;
+ }
+
+ @Override
+ protected Domain getDomain() {
+ return Domain.LOG4J;
+ }
+
+ @Override
+ protected void registerAgent() {
+ logger = Logger.getLogger(EVENT_NAME);
+ logger.setLevel(Level.ALL);
+
+ try {
+ logHandler = new LttngLogAppender();
+ } catch (SecurityException | IOException e) {
+ fail();
+ }
+ logger.addAppender((Appender) logHandler);
+ }
+
+ @Override
+ protected void sendEventsToLoggers() {
+ Log4jTestUtils.send10Events(logger);
+ }
+}
LttngLogAppender testAppender = new LttngLogAppender();
testAppender.close();
} catch (SecurityException | IOException e) {
+ e.printStackTrace();
return false;
}
return true;