Add tests for application context retrieval
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Wed, 20 Jan 2016 20:01:47 +0000 (15:01 -0500)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 5 Feb 2016 21:55:40 +0000 (16:55 -0500)
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
14 files changed:
lttng-tools-java/src/main/java/org/lttng/tools/ILttngSession.java
lttng-tools-java/src/main/java/org/lttng/tools/LttngCommandLineSession.java
lttng-ust-java-tests-common/.settings/org.eclipse.core.resources.prefs
lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/AppContextITBase.java [new file with mode: 0644]
lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/AppContextOrderingITBase.java [new file with mode: 0644]
lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/ContextInfoRetrieverStubs.java [new file with mode: 0644]
lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/LttngContextValues.java [new file with mode: 0644]
lttng-ust-java-tests-common/src/test/java/org/lttng/ust/agent/integration/client/TcpClientDebugListener.java
lttng-ust-java-tests-common/src/test/java/org/lttng/ust/agent/integration/client/TcpClientIT.java
lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/context/JulAppContextIT.java [new file with mode: 0644]
lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/context/JulAppContextOrderingIT.java [new file with mode: 0644]
lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/integration/context/Log4jAppContextIT.java [new file with mode: 0644]
lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/integration/context/Log4jAppContextOrderingIT.java [new file with mode: 0644]
lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/utils/Log4jTestUtils.java

index a28a4aa555a90221f5c3b84fb687b5937024d186..704705f25f99b1a9746570adbb469b90fb4e77c6 100644 (file)
@@ -158,6 +158,20 @@ public interface ILttngSession extends AutoCloseable {
      */
     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
      *
index 171cffbf08ac3559e2c9d365a04a3ff8fda05bf0..3859e2fcd49ca11bd40ebe122ad833de1b8f299b 100644 (file)
@@ -147,6 +147,14 @@ class LttngCommandLineSession implements ILttngSession {
                 .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() {
         /*
index 8dd9b1df3d66f1efc3bc1c9e516c16a1b034e689..f9fe34593fcd3624a964478aeb438b0d44fe7237 100644 (file)
@@ -1,3 +1,4 @@
 eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
 encoding//src/test/java=UTF-8
 encoding/<project>=UTF-8
diff --git a/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/AppContextITBase.java b/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/AppContextITBase.java
new file mode 100644 (file)
index 0000000..721b619
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * 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));
+    }
+}
diff --git a/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/AppContextOrderingITBase.java b/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/AppContextOrderingITBase.java
new file mode 100644 (file)
index 0000000..d0acca3
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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();
+    }
+}
diff --git a/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/ContextInfoRetrieverStubs.java b/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/ContextInfoRetrieverStubs.java
new file mode 100644 (file)
index 0000000..0981f77
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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));
+
+}
diff --git a/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/LttngContextValues.java b/lttng-ust-java-tests-common/src/main/java/org/lttng/ust/agent/integration/context/LttngContextValues.java
new file mode 100644 (file)
index 0000000..5c9fc92
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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";
+}
index 1b6ce47bd55cfde6ea814264ee3d5abc9c3e721f..abc9d423b031b3a4ed415d74d5362be3e2b26c43 100644 (file)
@@ -36,6 +36,9 @@ public class TcpClientDebugListener implements ILttngTcpClientListener {
     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);
@@ -49,15 +52,15 @@ public class TcpClientDebugListener implements ILttngTcpClientListener {
     }
 
     @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;
     }
 
     /**
@@ -89,12 +92,39 @@ public class TcpClientDebugListener implements ILttngTcpClientListener {
         }
     }
 
+    /**
+     * @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();
     }
 
 }
index 16c7d0185f623e247155148f3f1acfe19364efa0..a86a273cc3f969d07cba3f0e6830aa1e2b9b5f18 100644 (file)
@@ -64,6 +64,11 @@ public class TcpClientIT {
     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;
@@ -147,7 +152,7 @@ public class TcpClientIT {
     }
 
     // ------------------------------------------------------------------------
-    // Test cases
+    // Event enabling/disabling test cases
     // ------------------------------------------------------------------------
 
     /**
@@ -392,4 +397,133 @@ public class TcpClientIT {
 
         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);
+    }
 }
diff --git a/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/context/JulAppContextIT.java b/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/context/JulAppContextIT.java
new file mode 100644 (file)
index 0000000..aaecf41
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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);
+    }
+}
diff --git a/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/context/JulAppContextOrderingIT.java b/lttng-ust-java-tests-jul/src/test/java/org/lttng/ust/agent/integration/context/JulAppContextOrderingIT.java
new file mode 100644 (file)
index 0000000..1cef0d4
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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);
+    }
+}
diff --git a/lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/integration/context/Log4jAppContextIT.java b/lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/integration/context/Log4jAppContextIT.java
new file mode 100644 (file)
index 0000000..bc8e631
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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);
+    }
+}
diff --git a/lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/integration/context/Log4jAppContextOrderingIT.java b/lttng-ust-java-tests-log4j/src/test/java/org/lttng/ust/agent/integration/context/Log4jAppContextOrderingIT.java
new file mode 100644 (file)
index 0000000..69e45bc
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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);
+    }
+}
index 3e67f1fe2335b439b837fc96e813cea7ca0025d5..b356dbe21f295a74e9393665aedd81f5c9c81d18 100644 (file)
@@ -43,6 +43,7 @@ public final class Log4jTestUtils {
             LttngLogAppender testAppender = new LttngLogAppender();
             testAppender.close();
         } catch (SecurityException | IOException e) {
+            e.printStackTrace();
             return false;
         }
         return true;
This page took 0.038629 seconds and 4 git commands to generate.