From 9a71ead6742d9192b41e3f809d291c20789c62e5 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Fri, 7 Jul 2017 16:59:45 -0400 Subject: [PATCH] lttng: Add test for kernel trace stream intersection Change-Id: Ia7b16253c269bf1ebab2fc035d4bcaab966a7c78 Signed-off-by: Alexandre Montplaisir --- .../META-INF/MANIFEST.MF | 6 +- .../KernelTraceStreamIntersectionTest.java | 176 ++++++++++++++++++ 2 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceStreamIntersectionTest.java diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF index c48436b009..754d6f278a 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF +++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF @@ -39,6 +39,8 @@ Export-Package: org.eclipse.tracecompass.lttng2.kernel.core.tests, 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, +Import-Package: com.google.common.base, + com.google.common.collect, + org.apache.commons.io, org.eclipse.test.performance, - org.eclipse.tracecompass.testtraces.ctf;version="1.6.0" + org.eclipse.tracecompass.testtraces.ctf;version="1.7.2" diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceStreamIntersectionTest.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceStreamIntersectionTest.java new file mode 100644 index 0000000000..99a13f1eec --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/trim/KernelTraceStreamIntersectionTest.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * 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.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +import org.apache.commons.io.FileUtils; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace; +import org.eclipse.tracecompass.lttng2.lttng.kernel.core.tests.shared.LttngKernelTestTraceUtils; +import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; +import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.tests.trim.CtfTmfTraceTrimmingTest; +import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Test the CTF stream-intersection operation on a LTTng kernel trace. + * + * @author Alexandre Montplaisir + */ +@Ignore("Trim command requires Babeltrace 2.0, which is not installed on most CIs. Test can be run manually.") +public class KernelTraceStreamIntersectionTest { + + private static final @NonNull CtfTestTrace TEST_TRACE = CtfTestTrace.UNEVEN_STREAMS; + + /* Stream-intersection range reported by Babeltrace's "query trace-info" */ + private static final long INTERSECTION_RANGE_START = 1499451535346019325L; + private static final long INTERSECTION_RANGE_END = 1499451539084288056L; + private static final int EXPECTED_NB_EVENTS = 283344; + + private CtfTmfTrace fOriginalTrace; + private CtfTmfTrace fNewTrace; + private Path fNewTracePath; + + /** + * Test setup. + */ + @Before + public void setup() { + fOriginalTrace = LttngKernelTestTraceUtils.getTrace(TEST_TRACE); + openTrace(fOriginalTrace); + + try { + /* Perform the stream intersection to create the new trace */ + fNewTracePath = checkNotNull(Files.createTempDirectory("trimmed-trace-test")); + fOriginalTrace.streamIntersection(fNewTracePath, new NullProgressMonitor()); + + /* 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()); + } + } + + /** + * Test teardown + */ + @After + public void tearDown() { + if (fOriginalTrace != null) { + fOriginalTrace.dispose(); + } + LttngKernelTestTraceUtils.dispose(TEST_TRACE); + + if (fNewTrace != null) { + fNewTrace.dispose(); + } + + if (fNewTracePath != null) { + FileUtils.deleteQuietly(fNewTracePath.toFile()); + } + } + + /** + * Simulate a trace being opened + */ + private static void openTrace(CtfTmfTrace trace) { + trace.indexTrace(true); + TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(CtfTmfTraceTrimmingTest.class, trace, null)); + } + + /** + * Test that all expected events are present in the new trace. + */ + @Test + public void testEvents() { + CtfTmfTrace initialTrace = fOriginalTrace; + CtfTmfTrace trimmedTrace = fNewTrace; + Path newTracePath = fNewTracePath; + assertNotNull(initialTrace); + assertNotNull(trimmedTrace); + assertNotNull(newTracePath); + + /* Verify the new trace bounds */ + final long newTraceStartTime = trimmedTrace.getStartTime().toNanos(); + final long newTraceEndTime = trimmedTrace.getEndTime().toNanos(); + assertTrue(INTERSECTION_RANGE_START <= newTraceStartTime); + assertTrue(newTraceEndTime <= INTERSECTION_RANGE_END); + + /* + * Verify that each event from the original trace in the intersection is + * present in the new one. + */ + ITmfContext context1 = initialTrace.seekEvent(TmfTimestamp.fromNanos(INTERSECTION_RANGE_START)); + CtfTmfEvent event1 = initialTrace.getNext(context1); + ITmfContext context2 = trimmedTrace.seekEvent(0L); + CtfTmfEvent event2 = trimmedTrace.getNext(context2); + + int count = 0; + while (event1 != null && event1.getTimestamp().toNanos() <= INTERSECTION_RANGE_END) { + assertNotNull(event1); + assertNotNull("Expected event not present in trimmed trace: " + eventToString(event1), event2); + + assertTrue("The following events are not the same: \n " + + eventToString(event1) + '\n' + + eventToString(event2), + eventsEquals(event1, event2)); + + event1 = initialTrace.getNext(context1); + event2 = trimmedTrace.getNext(context2); + count++; + } + + assertEquals(EXPECTED_NB_EVENTS, count); + } + + private static boolean eventsEquals(CtfTmfEvent event1, CtfTmfEvent event2) { + return Objects.equals(event1.getTimestamp(), event2.getTimestamp()) + && Objects.equals(event1.getType(), event2.getType()) + && Objects.equals(event1.getContent(), event2.getContent()) + && Objects.equals(event1.getCPU(), event2.getCPU()); + + // FIXME This currently gets renamed, but eventually won't. +// && Objects.equals(event1.getChannel(), event2.getChannel()); + } + + private static String eventToString(CtfTmfEvent event) { + return com.google.common.base.Objects.toStringHelper(event) + .add("Timestamp", event.getTimestamp()) + .add("Type", event.getType()) + .add("Content", event.getContent()) + .add("CPU", event.getCPU()) + .add("Channel", event.getChannel()) + .toString(); + } +} -- 2.34.1