| /******************************************************************************* |
| * 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 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.tmf.ctf.core.tests.trace; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertNotEquals; |
| |
| import java.util.function.Predicate; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace; |
| import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
| import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; |
| import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
| import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; |
| import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils; |
| import org.junit.AfterClass; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| /** |
| * Tests for the event-searching methods in {@link TmfTraceUtils}. |
| * |
| * @author Alexandre Montplaisir |
| */ |
| public class TmfTraceUtilsSearchingTest { |
| |
| private static final @NonNull CtfTestTrace TEST_TRACE = CtfTestTrace.TRACE2; |
| private static final long START_RANK = 500L; |
| |
| private static ITmfTrace fTrace; |
| private static ITmfEvent fStartEvent; |
| |
| /** |
| * Test setup |
| */ |
| @BeforeClass |
| public static void setUp() { |
| fTrace = CtfTmfTestTraceUtils.getTrace(TEST_TRACE); |
| |
| ITmfContext ctx = fTrace.seekEvent(START_RANK); |
| fStartEvent = fTrace.getNext(ctx); |
| assertEquals("softirq_raise", fStartEvent.getName()); |
| } |
| |
| /** |
| * Test cleanup |
| */ |
| @AfterClass |
| public static void tearDown() { |
| if (fTrace != null) { |
| fTrace.dispose(); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Forwards searches |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Test the {@link TmfTraceUtils#getNextEventMatching} method. |
| */ |
| @Test |
| public void testNextMatchingEvent() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch"); |
| |
| ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, null); |
| |
| ITmfContext ctx = trace.seekEvent(508L); // following sched_switch event |
| ITmfEvent expectedEvent = trace.getNext(ctx); |
| |
| assertEquals(expectedEvent, actualEvent); |
| } |
| |
| /** |
| * Test that the presence of progress monitor does not affect the results. |
| */ |
| @Test |
| public void testNextMatchingEventProgressMonitor() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch"); |
| |
| IProgressMonitor monitor = new NullProgressMonitor(); |
| ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, monitor); |
| |
| ITmfContext ctx = trace.seekEvent(508L); // following sched_switch event |
| ITmfEvent expectedEvent = trace.getNext(ctx); |
| |
| assertEquals(expectedEvent, actualEvent); |
| } |
| |
| /** |
| * Test the {@link TmfTraceUtils#getNextEventMatching} method where no event |
| * matches the passed predicate. It should return null. |
| */ |
| @Test |
| public void testNextMatchingEventNoMatch() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("non-existent-event"); |
| |
| ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, null); |
| assertNull(actualEvent); |
| } |
| |
| /** |
| * Test the {@link TmfTraceUtils#getNextEventMatching} method, where the |
| * event from which we start the search already matches the criterion (it |
| * should be correctly skipped so we can advance). |
| */ |
| @Test |
| public void testNextMatchingEventStartMatches() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("softirq_raise"); |
| ITmfEvent foundEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, null); |
| |
| assertNotNull(foundEvent); |
| assertNotEquals(fStartEvent, foundEvent); |
| } |
| |
| /** |
| * Test with a progress monitor that cancels the job. |
| */ |
| @Test |
| public void testNextMatchingEventCancelled() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch"); |
| |
| IProgressMonitor monitor = new NullProgressMonitor(); |
| monitor.setCanceled(true); |
| ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, monitor); |
| |
| /* No event should be returend */ |
| assertNull(actualEvent); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Backwards searches |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Test the {@link TmfTraceUtils#getPreviousEventMatching} method. |
| */ |
| @Test |
| public void testPreviousMatchingEvent() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch"); |
| |
| ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null); |
| |
| ITmfContext ctx = trace.seekEvent(455L); // previous sched_switch event |
| ITmfEvent expectedEvent = trace.getNext(ctx); |
| |
| assertEquals(expectedEvent, actualEvent); |
| } |
| |
| /** |
| * Test that the presence of progress monitor does not affect the results. |
| */ |
| @Test |
| public void testPreviousMatchingEventProgressMonitor() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch"); |
| |
| IProgressMonitor monitor = new NullProgressMonitor(); |
| ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, monitor); |
| |
| ITmfContext ctx = trace.seekEvent(455L); // previous sched_switch event |
| ITmfEvent expectedEvent = trace.getNext(ctx); |
| |
| assertEquals(expectedEvent, actualEvent); |
| } |
| |
| /** |
| * Test the {@link TmfTraceUtils#getPreviousEventMatching} method where no event |
| * matches the passed predicate. It should return null. |
| */ |
| @Test |
| public void testPreviousMatchingEventNoMatch() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("non-existent-event"); |
| |
| ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null); |
| assertNull(actualEvent); |
| } |
| |
| /** |
| * Test the {@link TmfTraceUtils#getPreviousEventMatching} method, where the |
| * event from which we start the search already matches the criterion (it |
| * should be correctly skipped). |
| */ |
| @Test |
| public void testPreviousMatchingEventStartMatches() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("softirq_raise"); |
| ITmfEvent foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null); |
| |
| assertNotNull(foundEvent); |
| assertNotEquals(fStartEvent, foundEvent); |
| } |
| |
| /** |
| * Test the {@link TmfTraceUtils#getPreviousEventMatching} method with an |
| * event that is expected to take more than one inner request. |
| */ |
| @Test |
| public void testPreviousMatchingEventFar() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sys_write"); |
| ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null); |
| |
| ITmfContext ctx = trace.seekEvent(387L); // previous sched_switch event |
| ITmfEvent expectedEvent = trace.getNext(ctx); |
| |
| assertEquals(expectedEvent, actualEvent); |
| } |
| |
| /** |
| * When doing a backwards search near the beginning of the trace (when |
| * startRank < step), make sure that we do not go beyond the start rank. |
| */ |
| @Test |
| public void testPreviousMatchingBeginningOfTrace() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| final int startRank = 3; |
| ITmfContext ctx = fTrace.seekEvent(startRank); |
| ITmfEvent startEvent = fTrace.getNext(ctx); |
| assertEquals("exit_syscall", startEvent.getName()); |
| |
| /* There is a sys_mmap at rank 6, it should not be matched! */ |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sys_mmap"); |
| ITmfEvent foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, startRank, predicate, null); |
| assertNull(foundEvent); |
| |
| /* Do not match the event itself either, or any later "exit_syscall" */ |
| predicate = event -> event.getName().equals("exit_syscall"); |
| foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, startRank, predicate, null); |
| assertNull(foundEvent); |
| } |
| |
| /** |
| * Test with a progress monitor that cancels the job. |
| */ |
| @Test |
| public void testPreviousMatchingEventCancelled() { |
| ITmfTrace trace = fTrace; |
| assertNotNull(trace); |
| |
| Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch"); |
| |
| IProgressMonitor monitor = new NullProgressMonitor(); |
| monitor.setCanceled(true); |
| ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, monitor); |
| |
| /* No event should be returend */ |
| assertNull(actualEvent); |
| } |
| } |