lttng: Add test for kernel trace trimming
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 7 Jul 2017 20:59:10 +0000 (16:59 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 7 Jul 2017 20:59:10 +0000 (16:59 -0400)
This test will verify that the statedump is saved
and restored correctly.

Change-Id: I808736ed6e3694ac7e6ab632cce507559ea698b4
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/trim/CtfTmfTraceTrimmingTest.java
lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF
lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceTrimmingTest.java [new file with mode: 0644]

index abe45c5496524539212e298f280d69a34840bd89..7bb65701b50ef6d43cabc13a005002e7001c2913 100644 (file)
@@ -68,12 +68,17 @@ public class CtfTmfTraceTrimmingTest {
 
     private final @NonNull CtfTestTrace fTestTrace;
 
-    private CtfTmfTrace fOriginalTrace;
-    private long fRequestedTraceCutStart;
-    private long fRequestedTraceCutEnd;
-
-    private CtfTmfTrace fNewTrace;
-    private Path fNewTracePath;
+    /** Trace on which to perform the trim */
+    protected CtfTmfTrace fOriginalTrace;
+    /** Start time of the trim range */
+    protected long fRequestedTraceCutStart;
+    /** End time of the trim range */
+    protected long fRequestedTraceCutEnd;
+
+    /** Reference to the newly-created trace */
+    protected CtfTmfTrace fNewTrace;
+    /** Filesystem path of the new trace */
+    protected Path fNewTracePath;
 
     // ------------------------------------------------------------------------
     // Test suite definition
@@ -205,8 +210,13 @@ public class CtfTmfTraceTrimmingTest {
         }
     }
 
-    /** Simulate a trace being opened */
-    private static void openTrace(CtfTmfTrace trace) {
+    /**
+     * Simulate a trace being opened
+     *
+     * @param trace
+     *            The trace to open
+     */
+    protected static void openTrace(CtfTmfTrace trace) {
         trace.indexTrace(true);
         TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(CtfTmfTraceTrimmingTest.class, trace, null));
     }
index 2927f6203a7c56c67334c2204709f3842c86912e..c48436b009e883287c614ff751daf0b66517f5fd 100644 (file)
@@ -36,6 +36,8 @@ Export-Package: org.eclipse.tracecompass.lttng2.kernel.core.tests,
  org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.tid,
  org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.event.matching,
  org.eclipse.tracecompass.lttng2.kernel.core.tests.stubs,
+ org.eclipse.tracecompass.lttng2.kernel.core.tests.synchronization,
+ org.eclipse.tracecompass.lttng2.kernel.core.tests.trim,
  org.eclipse.tracecompass.lttng2.lttng.kernel.core.tests.shared.vm
 Import-Package: com.google.common.collect,
  org.eclipse.test.performance,
diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceTrimmingTest.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceTrimmingTest.java
new file mode 100644 (file)
index 0000000..75cf44b
--- /dev/null
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.lttng2.kernel.core.tests.trim;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
+import org.eclipse.tracecompass.lttng2.lttng.kernel.core.tests.shared.LttngKernelTestTraceUtils;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.Statedump;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
+import org.eclipse.tracecompass.tmf.ctf.core.tests.trim.CtfTmfTraceTrimmingTest;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Test of the trace trimming feature on an LTTng kernel trace. It extends
+ * {@link CtfTmfTraceTrimmingTest} to add statedump checking of a kernel trace.
+ *
+ * @author Alexandre Montplaisir
+ */
+@Ignore("Trim command requires Babeltrace 2.0, which is not installed on most CIs. Test can be run manually.")
+@RunWith(Parameterized.class)
+public class KernelTraceTrimmingTest extends CtfTmfTraceTrimmingTest {
+
+    private static final @NonNull CtfTestTrace KERNEL_TRACE = CtfTestTrace.KERNEL;
+
+    /* Trace cutting parameters */
+    private static final long REQUESTED_START_TIME = 1332170682692698596L; // 11:24:42.692 698 596
+    private static final long REQUESTED_END_TIME = REQUESTED_START_TIME + 1000000000L; // 11:24:43.692 698 596
+
+    /**
+     * Test parameter generator
+     *
+     * @return The list of constructor parameters, one for each test instance.
+     */
+    @Parameters(name = "{index}: {0}")
+    public static Iterable<Object[]> getTestTraces() {
+        /* Only run this on the trace "kernel" */
+        return Collections.singletonList(new Object[] { KERNEL_TRACE });
+    }
+
+    /**
+     * Constructor. Receives parameters defined in {@link #getTestTraces()}.
+     *
+     * @param testTrace
+     *            The test trace to use for this test instance.
+     */
+    public KernelTraceTrimmingTest(@NonNull CtfTestTrace testTrace) {
+        super(testTrace);
+    }
+
+    /**
+     * Test setup.
+     *
+     * We're overriding the super.setup() because we need to save the statedump
+     * before opening the new trace.
+     */
+    @Override
+    @Before
+    public void setup() {
+        fOriginalTrace = LttngKernelTestTraceUtils.getTrace(KERNEL_TRACE);
+        openTrace(fOriginalTrace);
+
+        fRequestedTraceCutStart = REQUESTED_START_TIME;
+        fRequestedTraceCutEnd = REQUESTED_END_TIME;
+
+        TmfTimeRange range = new TmfTimeRange(TmfTimestamp.fromNanos(REQUESTED_START_TIME), TmfTimestamp.fromNanos(REQUESTED_END_TIME));
+        try {
+            /* Perform the trim to create the new trace */
+            fNewTracePath = checkNotNull(Files.createTempDirectory("trimmed-trace-test"));
+            fOriginalTrace.trim(range, fNewTracePath, new NullProgressMonitor());
+
+            /* Write the statedump */
+            KernelAnalysisModule module = getKernelModule((LttngKernelTrace) fOriginalTrace);
+            int providerVersion = checkNotNull(module.getProviderVersion());
+            ITmfStateSystem ss1 = module.getStateSystem();
+            assertNotNull(ss1);
+
+            Statedump statedump = new Statedump(ss1, REQUESTED_START_TIME, providerVersion);
+            statedump.dumpState(checkNotNull(fNewTracePath), ss1.getSSID());
+
+            /* Initialize and open the new trace */
+            fNewTrace = new LttngKernelTrace();
+            fNewTrace.initTrace(null, fNewTracePath.toString(), CtfTmfEvent.class);
+            openTrace(fNewTrace);
+
+        } catch (IOException | CoreException | TmfTraceException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    private static KernelAnalysisModule getKernelModule(@NonNull LttngKernelTrace trace) {
+        KernelAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(trace,
+                KernelAnalysisModule.class, KernelAnalysisModule.ID);
+        assertNotNull(module);
+        module.waitForCompletion();
+        return module;
+    }
+
+    /**
+     * Test that the statedump is saved and restored correctly.
+     *
+     * @throws Exception
+     *             If something fails
+     */
+    @Test
+    public void testTrimStatedump() throws Exception {
+        LttngKernelTrace initialTrace = (LttngKernelTrace) fOriginalTrace;
+        LttngKernelTrace trimmedTrace = (LttngKernelTrace) fNewTrace;
+        Path newTracePath = fNewTracePath;
+        assertNotNull(initialTrace);
+        assertNotNull(trimmedTrace);
+        assertNotNull(newTracePath);
+
+        final long newTraceStartTime = trimmedTrace.getStartTime().toNanos();
+        final long newTraceEndTime = trimmedTrace.getEndTime().toNanos();
+
+        ITmfStateSystem ss1 = getKernelModule(initialTrace).getStateSystem();
+        assertNotNull(ss1);
+        List<ITmfStateInterval> state1 = ss1.queryFullState(REQUESTED_START_TIME + 1);
+
+        ITmfStateSystem ss2 = getKernelModule(trimmedTrace).getStateSystem();
+        assertNotNull(ss2);
+        List<ITmfStateInterval> state2 = ss2.queryFullState(REQUESTED_START_TIME + 1);
+
+        assertEquals(state1.size(), state2.size());
+        for (int ss1quark = 0; ss1quark < state1.size(); ss1quark++) {
+            /*
+             * The quarks are not necessarily the same between the old and new
+             * state systems! We have to resolve new quarks from the full paths.
+             */
+            String[] attributePath = ss1.getFullAttributePathArray(ss1quark);
+            int ss2quark = ss2.getQuarkAbsolute(attributePath);
+
+            ITmfStateInterval interval1 = state1.get(ss1quark);
+            ITmfStateInterval interval2 = state2.get(ss2quark);
+
+            /*
+             * State start and end times may have been clamped to the beginning
+             * or end of the new trace, respectively.
+             */
+            long expectedStart = Math.max(newTraceStartTime, interval1.getStartTime());
+            long expectedEnd = Math.min(newTraceEndTime, interval1.getEndTime());
+
+            assertEquals("Mismatching start times for attribute " + Arrays.toString(attributePath),
+                    expectedStart, interval2.getStartTime());
+
+            assertEquals("Mismatching end times for attribute " + Arrays.toString(attributePath),
+                    expectedEnd, interval2.getEndTime());
+
+            assertEquals("Mismatching state values for attribute " + Arrays.toString(attributePath),
+                    interval1.getStateValue(), interval2.getStateValue());
+        }
+
+    }
+}
This page took 0.029679 seconds and 5 git commands to generate.