From e41ec02aad337ff074f5209ee11fe2c8edb87a81 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Fri, 24 Jul 2015 04:58:25 -0400 Subject: [PATCH] Add multi-session tests Signed-off-by: Alexandre Montplaisir --- .../integration/common/MultiSessionTest.java | 336 ++++++++++++++++++ .../ust/agent/integration/jul/AllTests.java | 3 +- .../integration/jul/JulEnabledEventsTest.java | 4 +- .../integration/jul/JulLegacyApiTest.java | 2 + .../integration/jul/JulMultiSessionTest.java | 91 +++++ .../ust/agent/integration/log4j/AllTests.java | 3 +- .../log4j/Log4jEnabledEventsTest.java | 12 +- .../integration/log4j/Log4jLegacyApiTest.java | 2 + .../log4j/Log4jMultiSessionTest.java | 93 +++++ .../lttng/ust/agent/utils/LttngSession.java | 8 + 10 files changed, 544 insertions(+), 10 deletions(-) create mode 100644 src/org/lttng/ust/agent/integration/common/MultiSessionTest.java create mode 100644 src/org/lttng/ust/agent/integration/jul/JulMultiSessionTest.java create mode 100644 src/org/lttng/ust/agent/integration/log4j/Log4jMultiSessionTest.java diff --git a/src/org/lttng/ust/agent/integration/common/MultiSessionTest.java b/src/org/lttng/ust/agent/integration/common/MultiSessionTest.java new file mode 100644 index 0000000..9efcb63 --- /dev/null +++ b/src/org/lttng/ust/agent/integration/common/MultiSessionTest.java @@ -0,0 +1,336 @@ +package org.lttng.ust.agent.integration.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.lttng.ust.agent.ILttngHandler; +import org.lttng.ust.agent.utils.LttngSession; +import org.lttng.ust.agent.utils.LttngSession.Domain; + +/** + * Tests with multiple concurrent tracing sessions + */ +public abstract class MultiSessionTest { + + protected static final String EVENT_NAME_A = "EventA"; + protected static final String EVENT_NAME_B = "EventAB"; + protected static final String EVENT_NAME_C = "EventABC"; + protected static final String EVENT_NAME_D = "EventABCD"; + + private LttngSession session1; + private LttngSession session2; + private LttngSession session3; + + /* Fields defined by the sub-class */ + protected ILttngHandler handlerA; + protected ILttngHandler handlerB; + protected ILttngHandler handlerC; + protected ILttngHandler handlerD; + + protected abstract Domain getDomain(); + + protected abstract void sendEventsToLoggers(); + + @Before + public void testSetup() { + session1 = new LttngSession(null, getDomain()); + session2 = new LttngSession(null, getDomain()); + session3 = new LttngSession(null, getDomain()); + } + + @After + public void testTeardown() { + session1.close(); + session2.close(); + session3.close(); + + handlerA.close(); + handlerB.close(); + handlerC.close(); + handlerD.close(); + + handlerA = null; + handlerB = null; + handlerC = null; + handlerD = null; + } + + /** + * Test with no events in any session. + */ + @Test + public void testNoEvents() { + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertTrue(output1.isEmpty()); + assertTrue(output2.isEmpty()); + assertTrue(output3.isEmpty()); + + assertEquals(0, handlerA.getEventCount()); + assertEquals(0, handlerB.getEventCount()); + assertEquals(0, handlerC.getEventCount()); + assertEquals(0, handlerD.getEventCount()); + } + + /** + * Test with all events enabled in one session only. Everything should be + * sent through JNI, but only that session should keep the trace events. + */ + @Test + public void testAllEventsOneSession() { + assertTrue(session1.enableAllEvents()); + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(40, output1.size()); + assertTrue(output2.isEmpty()); + assertTrue(output3.isEmpty()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(10, handlerC.getEventCount()); + assertEquals(10, handlerD.getEventCount()); + } + + /** + * Test with all events enabled in all sessions. All traces and handlers + * should see every event that was logged. + */ + @Test + public void testAllEventsAllSessions() { + assertTrue(session1.enableAllEvents()); + assertTrue(session2.enableAllEvents()); + assertTrue(session3.enableAllEvents()); + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(40, output1.size()); + assertEquals(40, output2.size()); + assertEquals(40, output3.size()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(10, handlerC.getEventCount()); + assertEquals(10, handlerD.getEventCount()); + } + + /** + * Test enabling some events in some sessions only. + */ + @Test + public void testSomeEvents() { + assertTrue(session1.enableEvents(EVENT_NAME_A)); + assertTrue(session2.enableEvents(EVENT_NAME_B)); + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(10, output1.size()); + assertEquals(10, output2.size()); + assertEquals(0, output3.size()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(0, handlerC.getEventCount()); + assertEquals(0, handlerD.getEventCount()); + } + + /** + * Test with all events enabled in one session, and some others in another. + * All events should arrive where expected, with no duplicates. + */ + @Test + public void testAllEventsAndSome() { + assertTrue(session1.enableAllEvents()); + assertTrue(session2.enableEvents(EVENT_NAME_D)); + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(40, output1.size()); + assertEquals(10, output2.size()); + assertEquals(0, output3.size()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(10, handlerC.getEventCount()); + assertEquals(10, handlerD.getEventCount()); + } + + /** + * Test with enabling then disabling some events. Makes sure the refcounting + * works properly. + */ + @Test + public void testSomeEventsAfterDisabling() { + assertTrue(session1.enableEvents(EVENT_NAME_A, EVENT_NAME_B, EVENT_NAME_C)); + assertTrue(session2.enableEvents(EVENT_NAME_B, EVENT_NAME_C, EVENT_NAME_D)); + assertTrue(session3.enableEvents(EVENT_NAME_A)); + + assertTrue(session1.disableEvents(EVENT_NAME_C)); + assertTrue(session2.disableEvents(EVENT_NAME_B, EVENT_NAME_C)); + assertTrue(session3.disableEvents(EVENT_NAME_A)); + + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(20, output1.size()); + assertEquals(10, output2.size()); + assertEquals(0, output3.size()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(0, handlerC.getEventCount()); + assertEquals(10, handlerD.getEventCount()); + } + + /** + * Test with a prefix in one session and a standard event in another. + */ + @Test + public void testPrefixAndEvent() { + assertTrue(session1.enableEvents("EventAB*")); + assertTrue(session3.enableEvents(EVENT_NAME_A)); + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(30, output1.size()); + assertEquals(0, output2.size()); + assertEquals(10, output3.size()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(10, handlerC.getEventCount()); + assertEquals(10, handlerD.getEventCount()); + } + + /** + * Test with all events enabled in one session, and an event prefix in + * another. Once again, there should be no duplicates. + */ + @Test + public void testAllEventsAndPrefix() { + assertTrue(session1.enableAllEvents()); + assertTrue(session2.enableEvents("EventABC*")); + assertTrue(session1.start()); + assertTrue(session2.start()); + assertTrue(session3.start()); + + sendEventsToLoggers(); + + assertTrue(session1.stop()); + assertTrue(session2.stop()); + assertTrue(session3.stop()); + + List output1 = session1.view(); + List output2 = session2.view(); + List output3 = session3.view(); + assertNotNull(output1); + assertNotNull(output2); + assertNotNull(output3); + assertEquals(40, output1.size()); + assertEquals(20, output2.size()); + assertEquals(0, output3.size()); + + assertEquals(10, handlerA.getEventCount()); + assertEquals(10, handlerB.getEventCount()); + assertEquals(10, handlerC.getEventCount()); + assertEquals(10, handlerD.getEventCount()); + } +} diff --git a/src/org/lttng/ust/agent/integration/jul/AllTests.java b/src/org/lttng/ust/agent/integration/jul/AllTests.java index aa5cd80..0906e46 100644 --- a/src/org/lttng/ust/agent/integration/jul/AllTests.java +++ b/src/org/lttng/ust/agent/integration/jul/AllTests.java @@ -6,7 +6,8 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ JulEnabledEventsTest.class, - JulLegacyApiTest.class + JulLegacyApiTest.class, + JulMultiSessionTest.class }) public class AllTests { diff --git a/src/org/lttng/ust/agent/integration/jul/JulEnabledEventsTest.java b/src/org/lttng/ust/agent/integration/jul/JulEnabledEventsTest.java index cbb1413..0e546ac 100644 --- a/src/org/lttng/ust/agent/integration/jul/JulEnabledEventsTest.java +++ b/src/org/lttng/ust/agent/integration/jul/JulEnabledEventsTest.java @@ -31,6 +31,8 @@ public class JulEnabledEventsTest extends EnabledEventsTest { /* Skip tests if we can't find the JNI library or lttng-tools */ assumeTrue(TestUtils.checkForJulLibrary()); assumeTrue(TestUtils.checkForLttngTools(Domain.JUL)); + + LttngSession.destroyAllSessions(); } @AfterClass @@ -40,8 +42,6 @@ public class JulEnabledEventsTest extends EnabledEventsTest { @Before public void julSetup() 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); diff --git a/src/org/lttng/ust/agent/integration/jul/JulLegacyApiTest.java b/src/org/lttng/ust/agent/integration/jul/JulLegacyApiTest.java index d66479e..88ec268 100644 --- a/src/org/lttng/ust/agent/integration/jul/JulLegacyApiTest.java +++ b/src/org/lttng/ust/agent/integration/jul/JulLegacyApiTest.java @@ -40,6 +40,8 @@ public class JulLegacyApiTest { /* Skip tests if we can't find the JNI library or lttng-tools */ assumeTrue(TestUtils.checkForJulLibrary()); assumeTrue(TestUtils.checkForLttngTools(Domain.JUL)); + + LttngSession.destroyAllSessions(); } @AfterClass diff --git a/src/org/lttng/ust/agent/integration/jul/JulMultiSessionTest.java b/src/org/lttng/ust/agent/integration/jul/JulMultiSessionTest.java new file mode 100644 index 0000000..667c354 --- /dev/null +++ b/src/org/lttng/ust/agent/integration/jul/JulMultiSessionTest.java @@ -0,0 +1,91 @@ +package org.lttng.ust.agent.integration.jul; + +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.ust.agent.integration.common.MultiSessionTest; +import org.lttng.ust.agent.jul.LttngLogHandler; +import org.lttng.ust.agent.utils.LttngSession; +import org.lttng.ust.agent.utils.LttngSession.Domain; +import org.lttng.ust.agent.utils.TestUtils; + +public class JulMultiSessionTest extends MultiSessionTest { + + private static final Domain DOMAIN = Domain.JUL; + + private Logger loggerA; + private Logger loggerB; + private Logger loggerC; + private Logger loggerD; + + @BeforeClass + public static void julClassSetup() { + /* Skip tests if we can't find the JNI library or lttng-tools */ + assumeTrue(TestUtils.checkForJulLibrary()); + assumeTrue(TestUtils.checkForLttngTools(Domain.JUL)); + + LttngSession.destroyAllSessions(); + } + + @AfterClass + public static void julClassCleanup() { + LttngSession.deleteAllTracee(); + } + + @Before + public void julSetup() throws SecurityException, IOException { + loggerA = Logger.getLogger(EVENT_NAME_A); + loggerB = Logger.getLogger(EVENT_NAME_B); + loggerC = Logger.getLogger(EVENT_NAME_C); + loggerD = Logger.getLogger(EVENT_NAME_D); + + loggerA.setLevel(Level.ALL); + loggerB.setLevel(Level.ALL); + loggerC.setLevel(Level.ALL); + loggerD.setLevel(Level.ALL); + + handlerA = new LttngLogHandler(); + handlerB = new LttngLogHandler(); + handlerC = new LttngLogHandler(); + handlerD = new LttngLogHandler(); + + loggerA.addHandler((Handler) handlerA); + loggerB.addHandler((Handler) handlerB); + loggerC.addHandler((Handler) handlerC); + loggerD.addHandler((Handler) handlerD); + } + + @After + public void julTeardown() { + loggerA.removeHandler((Handler) handlerA); + loggerB.removeHandler((Handler) handlerB); + loggerC.removeHandler((Handler) handlerC); + loggerD.removeHandler((Handler) handlerD); + + loggerA = null; + loggerB = null; + loggerC = null; + loggerD = null; + } + + @Override + protected Domain getDomain() { + return DOMAIN; + } + + @Override + protected void sendEventsToLoggers() { + JulTestUtils.send10EventsTo(loggerA); + JulTestUtils.send10EventsTo(loggerB); + JulTestUtils.send10EventsTo(loggerC); + JulTestUtils.send10EventsTo(loggerD); + } +} diff --git a/src/org/lttng/ust/agent/integration/log4j/AllTests.java b/src/org/lttng/ust/agent/integration/log4j/AllTests.java index 3f99b13..4ab5d22 100644 --- a/src/org/lttng/ust/agent/integration/log4j/AllTests.java +++ b/src/org/lttng/ust/agent/integration/log4j/AllTests.java @@ -6,7 +6,8 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ Log4jEnabledEventsTest.class, - Log4jLegacyApiTest.class + Log4jLegacyApiTest.class, + Log4jMultiSessionTest.class }) public class AllTests { diff --git a/src/org/lttng/ust/agent/integration/log4j/Log4jEnabledEventsTest.java b/src/org/lttng/ust/agent/integration/log4j/Log4jEnabledEventsTest.java index a38d2e3..771d945 100644 --- a/src/org/lttng/ust/agent/integration/log4j/Log4jEnabledEventsTest.java +++ b/src/org/lttng/ust/agent/integration/log4j/Log4jEnabledEventsTest.java @@ -27,21 +27,21 @@ public class Log4jEnabledEventsTest extends EnabledEventsTest { private Logger loggerD; @BeforeClass - public static void julClassSetup() { + public static void log4jClassSetup() { /* Skip tests if we can't find the JNI library or lttng-tools */ assumeTrue(TestUtils.checkForLog4jLibrary()); assumeTrue(TestUtils.checkForLttngTools(Domain.LOG4J)); + + LttngSession.destroyAllSessions(); } @AfterClass - public static void julClassCleanup() { + public static void log4jClassCleanup() { LttngSession.deleteAllTracee(); } @Before - public void julSetup() throws SecurityException, IOException { - // TODO Wipe all existing LTTng sessions? - + public void log4jSetup() throws SecurityException, IOException { loggerA = Logger.getLogger(EVENT_NAME_A); loggerB = Logger.getLogger(EVENT_NAME_B); loggerC = Logger.getLogger(EVENT_NAME_C); @@ -62,7 +62,7 @@ public class Log4jEnabledEventsTest extends EnabledEventsTest { } @After - public void julTeardown() { + public void log4jTeardown() { loggerA.removeAppender((Appender) handlerA); loggerB.removeAppender((Appender) handlerB); loggerC.removeAppender((Appender) handlerC); diff --git a/src/org/lttng/ust/agent/integration/log4j/Log4jLegacyApiTest.java b/src/org/lttng/ust/agent/integration/log4j/Log4jLegacyApiTest.java index 1a240b0..aa847a4 100644 --- a/src/org/lttng/ust/agent/integration/log4j/Log4jLegacyApiTest.java +++ b/src/org/lttng/ust/agent/integration/log4j/Log4jLegacyApiTest.java @@ -40,6 +40,8 @@ public class Log4jLegacyApiTest { /* Skip tests if we can't find the JNI library or lttng-tools */ assumeTrue(TestUtils.checkForLog4jLibrary()); assumeTrue(TestUtils.checkForLttngTools(Domain.LOG4J)); + + LttngSession.destroyAllSessions(); } @AfterClass diff --git a/src/org/lttng/ust/agent/integration/log4j/Log4jMultiSessionTest.java b/src/org/lttng/ust/agent/integration/log4j/Log4jMultiSessionTest.java new file mode 100644 index 0000000..4716ed6 --- /dev/null +++ b/src/org/lttng/ust/agent/integration/log4j/Log4jMultiSessionTest.java @@ -0,0 +1,93 @@ +package org.lttng.ust.agent.integration.log4j; + +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.ust.agent.integration.common.MultiSessionTest; +import org.lttng.ust.agent.log4j.LttngLogAppender; +import org.lttng.ust.agent.utils.LttngSession; +import org.lttng.ust.agent.utils.LttngSession.Domain; +import org.lttng.ust.agent.utils.TestUtils; + +public class Log4jMultiSessionTest extends MultiSessionTest { + + private static final Domain DOMAIN = Domain.LOG4J; + + private Logger loggerA; + private Logger loggerB; + private Logger loggerC; + private Logger loggerD; + + @BeforeClass + public static void log4jClassSetup() { + /* Skip tests if we can't find the JNI library or lttng-tools */ + assumeTrue(TestUtils.checkForLog4jLibrary()); + assumeTrue(TestUtils.checkForLttngTools(Domain.LOG4J)); + + LttngSession.destroyAllSessions(); + } + + @AfterClass + public static void log4jClassCleanup() { + LttngSession.deleteAllTracee(); + } + + @Before + public void log4jSetup() 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); + loggerD = Logger.getLogger(EVENT_NAME_D); + + loggerA.setLevel(Level.ALL); + loggerB.setLevel(Level.ALL); + loggerC.setLevel(Level.ALL); + loggerD.setLevel(Level.ALL); + + handlerA = new LttngLogAppender(); + handlerB = new LttngLogAppender(); + handlerC = new LttngLogAppender(); + handlerD = new LttngLogAppender(); + + loggerA.addAppender((Appender) handlerA); + loggerB.addAppender((Appender) handlerB); + loggerC.addAppender((Appender) handlerC); + loggerD.addAppender((Appender) handlerD); + } + + @After + public void log4jTeardown() { + loggerA.removeAppender((Appender) handlerA); + loggerB.removeAppender((Appender) handlerB); + loggerC.removeAppender((Appender) handlerC); + loggerD.removeAppender((Appender) handlerD); + + loggerA = null; + loggerB = null; + loggerC = null; + loggerD = null; + } + + @Override + protected Domain getDomain() { + return DOMAIN; + } + + @Override + protected void sendEventsToLoggers() { + Log4jTestUtils.send10Events(loggerA); + Log4jTestUtils.send10Events(loggerB); + Log4jTestUtils.send10Events(loggerC); + Log4jTestUtils.send10Events(loggerD); + } +} diff --git a/src/org/lttng/ust/agent/utils/LttngSession.java b/src/org/lttng/ust/agent/utils/LttngSession.java index d13e2fb..fa387fb 100644 --- a/src/org/lttng/ust/agent/utils/LttngSession.java +++ b/src/org/lttng/ust/agent/utils/LttngSession.java @@ -137,6 +137,14 @@ public class LttngSession implements AutoCloseable { return TestUtils.getOutputFromCommand(Arrays.asList("lttng", "view", sessionName)); } + /** + * Utility method to destroy all existing sessions. Useful when first + * setting up a test to make sure no existing session interferes. + */ + public static void destroyAllSessions() { + executeCommand(Arrays.asList("lttng", "destroy", "-a")); + } + /** * 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 -- 2.34.1