Add some integration tests for JUL
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 24 Jul 2015 00:53:57 +0000 (20:53 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 24 Jul 2015 02:28:08 +0000 (22:28 -0400)
as well as more functionality to LttngSessionControl.

Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
src/org/lttng/ust/agent/benchmarks/jul/handler/FileHandlerBenchmark.java
src/org/lttng/ust/agent/benchmarks/jul/handler/lttng/LttngJulHandlerTracingDisabledBenchmark.java
src/org/lttng/ust/agent/benchmarks/jul/handler/lttng/LttngJulHandlerTracingEnabledBenchmark.java
src/org/lttng/ust/agent/benchmarks/jul/handler/lttng/old/OldLttngJulHandlerTracingDisabledBenchmark.java
src/org/lttng/ust/agent/benchmarks/jul/handler/lttng/old/OldLttngJulHandlerTracingEnabledBenchmark.java
src/org/lttng/ust/agent/integration/jul/JulEnabledEventsTest.java
src/org/lttng/ust/agent/utils/LttngSessionControl.java

index d6095aa5bac1030d0a873e4622d44b77cae4b76d..167c7416446183523ac507515b47ee963f5a0cbd 100644 (file)
@@ -1,16 +1,28 @@
 package org.lttng.ust.agent.benchmarks.jul.handler;
 
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.logging.FileHandler;
 import java.util.logging.SimpleFormatter;
 
+import org.junit.After;
 import org.junit.Before;
 
 public class FileHandlerBenchmark extends AbstractJulBenchmark {
 
+    private Path outputFile;
+
     @Before
     public void testSetup() throws SecurityException, IOException {
-        handler = new FileHandler("/tmp/log", false);
+        outputFile = Files.createTempFile(this.getClass().getSimpleName(), null);
+
+        handler = new FileHandler(outputFile.toString(), false);
         handler.setFormatter(new SimpleFormatter());
     }
+
+    @After
+    public void testTeardown() throws IOException {
+        Files.deleteIfExists(outputFile);
+    }
 }
index 690af1d0d096e30fdcdeec251adb3e4bf9064f4f..562965dd1f15490308135629d62dfd4406b87999 100644 (file)
@@ -22,7 +22,7 @@ public class LttngJulHandlerTracingDisabledBenchmark extends AbstractJulBenchmar
 
     @After
     public void testTeardown() {
-        assertTrue(LttngSessionControl.stopSession());
-        assertTrue(LttngSessionControl.destroySession());
+        assertTrue(LttngSessionControl.stopSession(null));
+        assertTrue(LttngSessionControl.destroySession(null));
     }
 }
index eb0514ea023247343afc00661fc95834e73321d1..38b6aa6fc3f655b5d418b7329942ef29e6cd29da 100644 (file)
@@ -22,7 +22,7 @@ public class LttngJulHandlerTracingEnabledBenchmark extends AbstractJulBenchmark
 
     @After
     public void testTeardown() {
-        assertTrue(LttngSessionControl.stopSession());
-        assertTrue(LttngSessionControl.destroySession());
+        assertTrue(LttngSessionControl.stopSession(null));
+        assertTrue(LttngSessionControl.destroySession(null));
     }
 }
index c8cbe6e679d552599081c8b45645447ee05765a3..21ab953f41b588705b40e5e6f95d630212cba4ce 100644 (file)
@@ -23,8 +23,8 @@ public class OldLttngJulHandlerTracingDisabledBenchmark extends AbstractJulBench
 
     @After
     public void testTeardown() {
-        assertTrue(LttngSessionControl.stopSession());
-        assertTrue(LttngSessionControl.destroySession());
+        assertTrue(LttngSessionControl.stopSession(null));
+        assertTrue(LttngSessionControl.destroySession(null));
 
         LTTngAgent.dispose();
     }
index 3e6636baa518487256d13b7200cc36e843a14767..29439a0ca9d77af66c98fa23b67f569263dfd5b3 100644 (file)
@@ -48,8 +48,8 @@ public class OldLttngJulHandlerTracingEnabledBenchmark extends AbstractJulBenchm
 
     @After
     public void testTeardown() {
-        assertTrue(LttngSessionControl.stopSession());
-        assertTrue(LttngSessionControl.destroySession());
+        assertTrue(LttngSessionControl.stopSession(null));
+        assertTrue(LttngSessionControl.destroySession(null));
 
         logger.removeHandler(agentHandler);
         LTTngAgent.dispose();
index 27f033e1f485f3c6cd96e0b2833f8376bcc76508..53fdafe78f8a9b878069a128a2ed20685334239e 100644 (file)
@@ -7,11 +7,11 @@ import static org.junit.Assume.assumeTrue;
 
 import java.io.IOException;
 import java.util.List;
-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.junit.Test;
@@ -23,6 +23,8 @@ public class JulEnabledEventsTest {
 
     private static final Domain DOMAIN = Domain.JUL;
 
+    private static final String SESSION_NAME = JulEnabledEventsTest.class.getSimpleName();
+
     private static final String EVENT_NAME_A = "EventA";
     private static final String EVENT_NAME_B = "EventAB";
     private static final String EVENT_NAME_C = "EventABC";
@@ -33,9 +35,9 @@ public class JulEnabledEventsTest {
     private Logger loggerC;
     private Logger loggerD;
 
-    private Handler handlerA;
-    private Handler handlerB;
-    private Handler handlerC;
+    private LttngLogHandler handlerA;
+    private LttngLogHandler handlerB;
+    private LttngLogHandler handlerC;
 
     @BeforeClass
     public static void classSetup() {
@@ -48,13 +50,23 @@ public class JulEnabledEventsTest {
         }
 
         boolean ret1 = LttngSessionControl.setupSession(null, DOMAIN);
-        boolean ret2 = LttngSessionControl.stopSession();
-        boolean ret3 = LttngSessionControl.destroySession();
+        boolean ret2 = LttngSessionControl.stopSession(null);
+        /* "lttng view" also tests that Babeltrace is installed and working */
+        List<String> contents = LttngSessionControl.viewSession(null);
+        boolean ret3 = LttngSessionControl.destroySession(null);
         assumeTrue(ret1 && ret2 && ret3);
+        assumeTrue(contents.isEmpty());
+    }
+
+    @AfterClass
+    public static void classCleanup() {
+        LttngSessionControl.deleteAllTracee();
     }
 
     @Before
     public void setup() throws SecurityException, IOException {
+        // TODO Wipe all existing LTTng sessions?
+
         loggerA = Logger.getLogger(EVENT_NAME_A);
         loggerB = Logger.getLogger(EVENT_NAME_B);
         loggerC = Logger.getLogger(EVENT_NAME_C);
@@ -71,11 +83,14 @@ public class JulEnabledEventsTest {
 
         loggerA.addHandler(handlerA);
         loggerB.addHandler(handlerB);
-        loggerC.addHandler(handlerB);
+        loggerC.addHandler(handlerC);
     }
 
     @After
     public void teardown() {
+        /* Just in case the test failed */
+        LttngSessionControl.tryDestroySession(SESSION_NAME);
+
         loggerA.removeHandler(handlerA);
         loggerB.removeHandler(handlerB);
         loggerC.removeHandler(handlerC);
@@ -95,24 +110,29 @@ public class JulEnabledEventsTest {
 
     /**
      * Test sending events on the Java side, but no events enabled in the
-     * tracing session. There should be nothing in the resulting trace.
+     * tracing session. There should be nothing in the resulting trace, and
+     * handlers should not have logged anything.
      */
     @Test
     public void testNoEvents() {
-        assertTrue(LttngSessionControl.setupSession(null, DOMAIN));
+        assertTrue(LttngSessionControl.setupSession(SESSION_NAME, DOMAIN));
 
         send10Events(loggerA);
         send10Events(loggerB);
         send10Events(loggerC);
         send10Events(loggerD);
 
-        assertTrue(LttngSessionControl.stopSession());
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
 
-        List<String> output = LttngSessionControl.viewSession();
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
         assertNotNull(output);
         assertTrue(output.isEmpty());
 
-        assertTrue(LttngSessionControl.destroySession());
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(0, handlerA.getEventCount());
+        assertEquals(0, handlerB.getEventCount());
+        assertEquals(0, handlerC.getEventCount());
     }
 
     /**
@@ -121,20 +141,24 @@ public class JulEnabledEventsTest {
      */
     @Test
     public void testAllEvents() {
-        assertTrue(LttngSessionControl.setupSessionAllEvents(null, DOMAIN));
+        assertTrue(LttngSessionControl.setupSessionAllEvents(SESSION_NAME, DOMAIN));
 
         send10Events(loggerA);
         send10Events(loggerB);
         send10Events(loggerC);
         send10Events(loggerD);
 
-        assertTrue(LttngSessionControl.stopSession());
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
 
-        List<String> output = LttngSessionControl.viewSession();
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
         assertNotNull(output);
-        assertEquals(20, output.size()); // loggerC has no handler attached
+        assertEquals(30, output.size()); // loggerD has no handler attached
 
-        assertTrue(LttngSessionControl.destroySession());
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(10, handlerA.getEventCount());
+        assertEquals(10, handlerB.getEventCount());
+        assertEquals(10, handlerC.getEventCount());
     }
 
     /**
@@ -143,28 +167,173 @@ public class JulEnabledEventsTest {
      */
     @Test
     public void testSomeEvents() {
-        assertTrue(LttngSessionControl.setupSession(null, DOMAIN,
-                EVENT_NAME_A, EVENT_NAME_D));
+        assertTrue(LttngSessionControl.setupSession(SESSION_NAME, DOMAIN,
+                EVENT_NAME_A, EVENT_NAME_C, EVENT_NAME_D));
+
+        send10Events(loggerA);
+        send10Events(loggerB);
+        send10Events(loggerC);
+        send10Events(loggerD);
+
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
+
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
+        assertNotNull(output);
+        assertEquals(20, output.size());
+
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(10, handlerA.getEventCount());
+        assertEquals(0, handlerB.getEventCount());
+        assertEquals(10, handlerC.getEventCount());
+    }
+
+    /**
+     * Test with all events enabled (-a), plus some other events added manually.
+     * Events should still be retained, but there should be no duplicates.
+     */
+    @Test
+    public void testAllEventsAndSome() {
+        assertTrue(LttngSessionControl.setupSessionAllEvents(SESSION_NAME, DOMAIN));
+        assertTrue(LttngSessionControl.enableEvents(SESSION_NAME, DOMAIN,
+                EVENT_NAME_A, EVENT_NAME_B));
+
+        send10Events(loggerA);
+        send10Events(loggerB);
+        send10Events(loggerC);
+        send10Events(loggerD);
+
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
+
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
+        assertNotNull(output);
+        assertEquals(30, output.size());
+
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(10, handlerA.getEventCount());
+        assertEquals(10, handlerB.getEventCount());
+        assertEquals(10, handlerC.getEventCount());
+    }
+
+    /**
+     * Same as {@link #testSomeEvents()}, but some events were enabled first,
+     * then disabled. Makes sure the enabled-event refcounting works properly.
+     */
+    @Test
+    public void testSomeEventsAfterDisabling() {
+        assertTrue(LttngSessionControl.setupSession(SESSION_NAME, DOMAIN,
+                EVENT_NAME_A, EVENT_NAME_C, EVENT_NAME_D));
+
+        assertTrue(LttngSessionControl.disableEvents(SESSION_NAME, DOMAIN,
+                EVENT_NAME_C));
+
+        send10Events(loggerA);
+        send10Events(loggerB);
+        send10Events(loggerC);
+        send10Events(loggerD);
+
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
+
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
+        assertNotNull(output);
+        assertEquals(10, output.size());
+
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(10, handlerA.getEventCount());
+        assertEquals(0, handlerB.getEventCount());
+        assertEquals(0, handlerC.getEventCount());
+    }
+
+    /**
+     * Test enabling an event prefix, which means an event name ending with a *,
+     * to match all events starting with this name.
+     */
+    @Test
+    public void testEventPrefix() {
+        assertTrue(LttngSessionControl.setupSession(SESSION_NAME, DOMAIN,
+                "EventAB*")); // should match event/loggers B and C, but not A.
+
+        send10Events(loggerA);
+        send10Events(loggerB);
+        send10Events(loggerC);
+        send10Events(loggerD);
+
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
+
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
+        assertNotNull(output);
+        assertEquals(20, output.size());
+
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(0, handlerA.getEventCount());
+        assertEquals(10, handlerB.getEventCount());
+        assertEquals(10, handlerC.getEventCount());
+    }
+
+    /**
+     * Same as {@link #testEventPrefix()}, but with multiple prefixes that
+     * overlap. There should not be any duplicate events in the trace or in the
+     * handlers.
+     */
+    @Test
+    public void testEventPrefixOverlapping() {
+        assertTrue(LttngSessionControl.setupSession(SESSION_NAME, DOMAIN,
+                "EventAB*", "EventABC*")); // should still match B and C
 
         send10Events(loggerA);
         send10Events(loggerB);
         send10Events(loggerC);
         send10Events(loggerD);
 
-        assertTrue(LttngSessionControl.stopSession());
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
 
-        List<String> output = LttngSessionControl.viewSession();
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
         assertNotNull(output);
-        assertEquals(10, output.size()); // loggerC has no handler attached
+        assertEquals(20, output.size());
+
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
+
+        assertEquals(0, handlerA.getEventCount());
+        assertEquals(10, handlerB.getEventCount());
+        assertEquals(10, handlerC.getEventCount());
+    }
+
+    /**
+     * Test with all events enabled (-a), plus an event prefix. Once again,
+     * there should be no duplicates.
+     */
+    @Test
+    public void testAllEventsAndPrefix() {
+        assertTrue(LttngSessionControl.setupSessionAllEvents(SESSION_NAME, DOMAIN));
+        assertTrue(LttngSessionControl.enableEvents(SESSION_NAME, DOMAIN,
+                "EventAB*")); // should match B and C
+
+        send10Events(loggerA);
+        send10Events(loggerB);
+        send10Events(loggerC);
+        send10Events(loggerD);
+
+        assertTrue(LttngSessionControl.stopSession(SESSION_NAME));
+
+        List<String> output = LttngSessionControl.viewSession(SESSION_NAME);
+        assertNotNull(output);
+        assertEquals(30, output.size());
+
+        assertTrue(LttngSessionControl.destroySession(SESSION_NAME));
 
-        assertTrue(LttngSessionControl.destroySession());
+        assertEquals(10, handlerA.getEventCount());
+        assertEquals(10, handlerB.getEventCount());
+        assertEquals(10, handlerC.getEventCount());
     }
 
     private static void send10Events(Logger logger) {
         String a = new String("a");
-        Object[] params = {a, new String("b"), new Object()};
+        Object[] params = { a, new String("b"), new Object() };
 
-     // Levels are FINE, FINER, FINEST, INFO, SEVERE, WARNING
+        // Levels are FINE, FINER, FINEST, INFO, SEVERE, WARNING
         logger.fine("A fine level message");
         logger.finer("A finer level message");
         logger.finest("A finest level message");
index 48eacc52852e0ce797ac8c906732626d9333addb..3e10bd5ef813ef9e84c3b892ae31ff4dd266dfc8 100644 (file)
@@ -2,8 +2,13 @@ package org.lttng.ust.agent.utils;
 
 import java.io.IOException;
 import java.lang.ProcessBuilder.Redirect;
+import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -91,26 +96,164 @@ public final class LttngSessionControl {
         });
     }
 
+    /**
+     * Send a separate enable-event command.
+     *
+     * @param sessionName
+     *            Name of the session in which to enable events. Use null for
+     *            current session.
+     * @param domain
+     *            The tracing domain
+     * @param enabledEvents
+     *            The list of events to enable. Should not be null or empty
+     * @return If the command executed successfully (return code = 0).
+     */
+    public static boolean enableEvents(String sessionName, Domain domain, String... enabledEvents) {
+        if (enabledEvents == null || enabledEvents.length == 0) {
+            throw new IllegalArgumentException();
+        }
+        List<String> command = new ArrayList<String>();
+        command.add("lttng");
+        command.add("enable-event");
+        command.add(domain.flag());
+        command.add(Arrays.stream(enabledEvents).collect(Collectors.joining(",")));
+        if (sessionName != null) {
+            command.add("-s");
+            command.add(sessionName);
+        }
+        return executeCommand(command.toArray(new String[0]));
+    }
+
+    /**
+     * Send a disable-event command. Used to disable events that were previously
+     * enabled.
+     *
+     * @param sessionName
+     *            Name of the session in which to disable events. Use null for
+     *            current session.
+     * @param domain
+     *            The tracing domain
+     * @param disabledEvents
+     *            The list of disabled events. Should not be null or empty
+     * @return If the command executed successfully (return code = 0).
+     */
+    public static boolean disableEvents(String sessionName, Domain domain, String... disabledEvents) {
+        if (disabledEvents == null || disabledEvents.length == 0) {
+            throw new IllegalArgumentException();
+        }
+        List<String> command = new ArrayList<String>();
+        command.add("lttng");
+        command.add("disable-event");
+        command.add(domain.flag());
+        command.add(Arrays.stream(disabledEvents).collect(Collectors.joining(",")));
+        if (sessionName != null) {
+            command.add("-s");
+            command.add(sessionName);
+        }
+        return executeCommand(command.toArray(new String[0]));
+    }
+
     /**
      * Stop the current tracing session
      *
+     * @param sessionName
+     *            The name of the session to stop. Use null for the current
+     *            session.
      * @return If the command executed successfully (return code = 0).
      */
-    public static boolean stopSession() {
-        return executeCommand(new String[] { "lttng", "stop" });
+    public static boolean stopSession(String sessionName) {
+        List<String> command = new ArrayList<String>();
+        command.add("lttng");
+        command.add("stop");
+        if (sessionName != null) {
+            command.add(sessionName);
+        }
+        return executeCommand(command.toArray(new String[0]));
     }
 
-    public static List<String> viewSession() {
-        return getOutputFromCommand(new String[] { "lttng", "view" });
+    /**
+     * Issue a "lttng view" command on the provided session, and returns its
+     * output. This effectively returns the current content of the trace in text
+     * form.
+     *
+     * @param sessionName
+     *            The name of the session to print. Use null for the current
+     *            session.
+     * @return The output of Babeltrace on the session's current trace
+     */
+    public static List<String> viewSession(String sessionName) {
+        List<String> command = new ArrayList<String>();
+        command.add("lttng");
+        command.add("view");
+        if (sessionName != null) {
+            command.add(sessionName);
+        }
+        return getOutputFromCommand(command.toArray(new String[0]));
     }
 
     /**
      * Destroy the current tracing session
      *
+     * @param sessionName
+     *            The name of the session to destroy. Use null for the current
+     *            session.
      * @return If the command executed successfully (return code = 0).
      */
-    public static boolean destroySession() {
-        return executeCommand(new String[] { "lttng", "destroy" });
+    public static boolean destroySession(String sessionName) {
+        List<String> command = new ArrayList<String>();
+        command.add("lttng");
+        command.add("destroy");
+        if (sessionName != null) {
+            command.add(sessionName);
+        }
+        return executeCommand(command.toArray(new String[0]));
+    }
+
+    /**
+     * Try destroying the given tracing session, fail silently if there is no
+     * session.
+     *
+     * @param sessionName
+     *            The name of the session to destroy. Use null for the current
+     *            session.
+     */
+    public static void tryDestroySession(String sessionName) {
+        getOutputFromCommand(false, new String[] { "lttng", "destroy" });
+    }
+
+    /**
+     * Outside of the scope of lttng-tools, but this utility method can be used
+     * to delete all traces currently under ~/lttng-traces/. This can be used by
+     * tests to cleanup a trace they have created.
+     *
+     * @return True if the command completes successfully, false if there was an
+     *         error.
+     */
+    public static boolean deleteAllTracee() {
+        String tracesDir = new String(System.getProperty("user.home") + "/lttng-traces/");
+        return deleteDirectory(Paths.get(tracesDir));
+    }
+
+    private static boolean deleteDirectory(Path directory) {
+        try {
+            Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+                    Files.delete(dir);
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        } catch (IOException e) {
+            /* At least we tried... */
+            return false;
+        }
+        return true;
     }
 
     // ------------------------------------------------------------------------
@@ -149,6 +292,10 @@ public final class LttngSessionControl {
     }
 
     private static List<String> getOutputFromCommand(String[] command) {
+        return getOutputFromCommand(true, command);
+    }
+
+    private static List<String> getOutputFromCommand(boolean print, String[] command) {
         try {
             Path tempFile = Files.createTempFile("test-output", null);
 
@@ -162,8 +309,10 @@ public final class LttngSessionControl {
             List<String> lines = Files.readAllLines(tempFile);
             Files.delete(tempFile);
 
-            /* Also print the output to the console */
-            lines.stream().forEach(s -> System.out.println(s));
+            if (print) {
+                /* Also print the output to the console */
+                lines.stream().forEach(s -> System.out.println(s));
+            }
 
             return lines;
 
This page took 0.031596 seconds and 4 git commands to generate.