| /******************************************************************************* |
| * Copyright (c) 2009, 2019 Ericsson |
| * |
| * 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 |
| * |
| * Contributors: |
| * Francois Chouinard - Initial API and implementation |
| * Francois Chouinard - Adjusted for new Trace Model |
| * Alexandre Montplaisir - Port to JUnit4 |
| * Patrick Tasse - Updated for rank in experiment location |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.tmf.core.tests.trace; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.tracecompass.internal.tmf.core.component.TmfProviderManager; |
| import org.eclipse.tracecompass.internal.tmf.core.synchronization.SyncAlgorithmFullyIncremental; |
| import org.eclipse.tracecompass.internal.tmf.core.trace.experiment.TmfExperimentContext; |
| import org.eclipse.tracecompass.internal.tmf.core.trace.experiment.TmfExperimentLocation; |
| import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; |
| import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
| import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; |
| import org.eclipse.tracecompass.tmf.core.project.model.ITmfPropertiesProvider; |
| import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; |
| import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; |
| import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; |
| import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; |
| import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform; |
| import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm; |
| import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory; |
| import org.eclipse.tracecompass.tmf.core.tests.analysis.AnalysisManagerTest; |
| import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace; |
| import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; |
| import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; |
| 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.core.trace.experiment.TmfExperiment; |
| import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; |
| import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; |
| import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestExperimentAnalysis; |
| import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfExperimentStub; |
| import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; |
| import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStubNs; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import com.google.common.collect.ImmutableMap; |
| |
| /** |
| * Test suite for the TmfExperiment class (single trace). |
| */ |
| @SuppressWarnings("javadoc") |
| public class TmfExperimentTest { |
| |
| // ------------------------------------------------------------------------ |
| // Attributes |
| // ------------------------------------------------------------------------ |
| |
| private static final String EXPERIMENT = "MyExperiment"; |
| private static int NB_EVENTS = 10000; |
| private static int BLOCK_SIZE = 1000; |
| |
| private static final double DELTA = 1e-15; |
| |
| private ITmfTrace[] fTestTraces; |
| private TmfExperimentStub fExperiment; |
| |
| private static byte SCALE = (byte) -3; |
| |
| // ------------------------------------------------------------------------ |
| // Housekeeping |
| // ------------------------------------------------------------------------ |
| |
| private synchronized ITmfTrace[] setupTrace(final String path) { |
| if (fTestTraces == null) { |
| fTestTraces = new ITmfTrace[1]; |
| try { |
| final TmfTraceStub trace = new TmfTraceStub(path, 0, true, null); |
| fTestTraces[0] = trace; |
| } catch (final TmfTraceException e) { |
| e.printStackTrace(); |
| } |
| } |
| return fTestTraces; |
| } |
| |
| private synchronized void setupExperiment() { |
| if (fExperiment == null) { |
| fExperiment = new TmfExperimentStub(EXPERIMENT, fTestTraces, BLOCK_SIZE); |
| fExperiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); |
| } |
| } |
| |
| @Before |
| public void setUp() { |
| setupTrace(TmfTestTrace.A_TEST_10K.getFullPath()); |
| setupExperiment(); |
| } |
| |
| @After |
| public void tearDown() { |
| if (fExperiment != null) { |
| fExperiment.dispose(); |
| } |
| assertEquals(0, TmfProviderManager.getProviders(ITmfEvent.class).length); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Constructor |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testSimpleTmfExperimentConstructor() { |
| TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, |
| fTestTraces, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null); |
| assertEquals("GetId", EXPERIMENT, experiment.getName()); |
| assertEquals("GetCacheSize", TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, experiment.getCacheSize()); |
| experiment.dispose(); |
| |
| experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, null, |
| TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null); |
| experiment.dispose(); |
| } |
| |
| @Test |
| public void testNormalTmfExperimentConstructor() { |
| assertEquals("GetId", EXPERIMENT, fExperiment.getName()); |
| assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); |
| |
| final long nbExperimentEvents = fExperiment.getNbEvents(); |
| assertEquals("GetNbEvents", NB_EVENTS, nbExperimentEvents); |
| |
| final long nbTraceEvents = fExperiment.getTraces().get(0).getNbEvents(); |
| assertEquals("GetNbEvents", NB_EVENTS, nbTraceEvents); |
| |
| final TmfTimeRange timeRange = fExperiment.getTimeRange(); |
| assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); |
| assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Experiment setup |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testExperimentInitialization() { |
| /* |
| * Calling default constructor, then init should be equivalent to |
| * calling the full constructor |
| */ |
| |
| TmfExperimentStub experiment = new TmfExperimentStub(EXPERIMENT, fTestTraces, 5000); |
| experiment.getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, true); |
| |
| assertEquals("GetId", EXPERIMENT, fExperiment.getName()); |
| assertEquals("GetNbEvents", NB_EVENTS, fExperiment.getNbEvents()); |
| |
| final long nbExperimentEvents = fExperiment.getNbEvents(); |
| assertEquals("GetNbEvents", NB_EVENTS, nbExperimentEvents); |
| |
| final long nbTraceEvents = fExperiment.getTraces().get(0).getNbEvents(); |
| assertEquals("GetNbEvents", NB_EVENTS, nbTraceEvents); |
| |
| final TmfTimeRange timeRange = fExperiment.getTimeRange(); |
| assertEquals("getStartTime", 1, timeRange.getStartTime().getValue()); |
| assertEquals("getEndTime", NB_EVENTS, timeRange.getEndTime().getValue()); |
| |
| experiment.dispose(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // getTimestamp |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testGetTimestamp() { |
| assertEquals("getTimestamp", TmfTimestamp.create( 1, (byte) -3), fExperiment.getTimestamp( 0)); |
| assertEquals("getTimestamp", TmfTimestamp.create( 2, (byte) -3), fExperiment.getTimestamp( 1)); |
| assertEquals("getTimestamp", TmfTimestamp.create( 11, (byte) -3), fExperiment.getTimestamp( 10)); |
| assertEquals("getTimestamp", TmfTimestamp.create( 101, (byte) -3), fExperiment.getTimestamp( 100)); |
| assertEquals("getTimestamp", TmfTimestamp.create( 1001, (byte) -3), fExperiment.getTimestamp(1000)); |
| assertEquals("getTimestamp", TmfTimestamp.create( 2001, (byte) -3), fExperiment.getTimestamp(2000)); |
| assertEquals("getTimestamp", TmfTimestamp.create( 2501, (byte) -3), fExperiment.getTimestamp(2500)); |
| assertEquals("getTimestamp", TmfTimestamp.create(10000, (byte) -3), fExperiment.getTimestamp(9999)); |
| assertNull("getTimestamp", fExperiment.getTimestamp(10000)); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // State system, statistics and modules methods |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testGetAnalysisModules() { |
| TmfExperiment experiment = fExperiment; |
| assertNotNull(experiment); |
| |
| /* There should not be any modules at this point */ |
| Iterable<IAnalysisModule> modules = experiment.getAnalysisModules(); |
| assertFalse(modules.iterator().hasNext()); |
| |
| /* Open the experiment, the modules should be populated */ |
| experiment.traceOpened(new TmfTraceOpenedSignal(this, experiment, null)); |
| modules = experiment.getAnalysisModules(); |
| Iterable<TestExperimentAnalysis> testModules = TmfTraceUtils.getAnalysisModulesOfClass(experiment, TestExperimentAnalysis.class); |
| assertTrue(modules.iterator().hasNext()); |
| assertTrue(testModules.iterator().hasNext()); |
| |
| /* |
| * Test that a module that applies to one of its trace is present in an |
| * experiment |
| */ |
| ITmfTrace trace1 = TmfTestTrace.A_TEST_10K.getTrace(); |
| ITmfTrace trace2 = TmfTestTrace.A_TEST_10K2.getTrace(); |
| ITmfTrace trace3 = TmfTestTrace.A_TEST_10K2.getTraceAsStub2(); |
| |
| /* |
| * Create an experiment with TmfTraceStub, the module other should not |
| * be there |
| */ |
| ITmfTrace[] tracesExp1 = { trace1, trace2 }; |
| TmfExperiment exp1 = new TmfExperiment(tracesExp1[0].getEventType(), "Experiment 1", tracesExp1, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null); |
| |
| /* |
| * Create an experiment containing some TmfTraceStub2, the module other |
| * should be present |
| */ |
| ITmfTrace[] tracesExp2 = { trace1, trace3 }; |
| TmfExperiment exp2 = new TmfExperiment(tracesExp2[0].getEventType(), "Experiment 1", tracesExp2, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null); |
| |
| try { |
| /* Open the experiment, the modules should be populated */ |
| exp1.traceOpened(new TmfTraceOpenedSignal(this, exp1, null)); |
| assertNull(exp1.getAnalysisModule(AnalysisManagerTest.MODULE_SECOND)); |
| |
| /* Open the experiment, the modules should be populated */ |
| exp2.traceOpened(new TmfTraceOpenedSignal(this, exp2, null)); |
| assertNotNull(exp2.getAnalysisModule(AnalysisManagerTest.MODULE_SECOND)); |
| } finally { |
| trace1.dispose(); |
| trace2.dispose(); |
| trace3.dispose(); |
| exp1.dispose(); |
| exp2.dispose(); |
| } |
| |
| } |
| |
| // ------------------------------------------------------------------------ |
| // seekEvent by location |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testSeekBadLocation() { |
| ITmfContext context = fExperiment.seekEvent(new TmfLongLocation(0L)); |
| assertNull("seekEvent", context); |
| } |
| |
| @Test |
| public void testSeekNoTrace() { |
| TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, EXPERIMENT, |
| null, TmfExperiment.DEFAULT_INDEX_PAGE_SIZE, null); |
| ITmfContext context = experiment.seekEvent((TmfExperimentLocation) null); |
| validateContextRanks(context); |
| experiment.dispose(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // seekEvent on ratio |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testSeekEventOnRatio() { |
| // First event |
| ITmfContext context = fExperiment.seekEvent(0.0); |
| assertEquals("Context rank", 0, context.getRank()); |
| ITmfEvent event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 0, context.getRank()); |
| |
| // Middle event |
| int midTrace = NB_EVENTS / 2; |
| context = fExperiment.seekEvent(0.5); |
| assertEquals("Context rank", midTrace, context.getRank()); |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", midTrace + 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", midTrace, context.getRank()); |
| |
| // Last event |
| context = fExperiment.seekEvent(1.0); |
| assertEquals("Context rank", NB_EVENTS, context.getRank()); |
| event = fExperiment.parseEvent(context); |
| assertNull("Event timestamp", event); |
| assertEquals("Context rank", NB_EVENTS, context.getRank()); |
| |
| // Beyond last event |
| context = fExperiment.seekEvent(1.1); |
| assertEquals("Context rank", NB_EVENTS, context.getRank()); |
| event = fExperiment.parseEvent(context); |
| assertNull("Event timestamp", event); |
| assertEquals("Context rank", NB_EVENTS, context.getRank()); |
| |
| // Negative ratio |
| context = fExperiment.seekEvent(-0.5); |
| assertEquals("Context rank", 0, context.getRank()); |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 0, context.getRank()); |
| } |
| |
| @Test |
| public void testGetLocationRatio() { |
| // First event |
| ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); |
| double ratio = fExperiment.getLocationRatio(context.getLocation()); |
| assertEquals("getLocationRatio", 0.0, ratio, DELTA); |
| |
| // Middle event |
| context = fExperiment.seekEvent(NB_EVENTS / 2); |
| ratio = fExperiment.getLocationRatio(context.getLocation()); |
| assertEquals("getLocationRatio", (double) (NB_EVENTS / 2) / NB_EVENTS, ratio, DELTA); |
| |
| // Last event |
| context = fExperiment.seekEvent(NB_EVENTS - 1); |
| ratio = fExperiment.getLocationRatio(context.getLocation()); |
| assertEquals("getLocationRatio", (double) (NB_EVENTS - 1) / NB_EVENTS, ratio, DELTA); |
| } |
| |
| // @SuppressWarnings("rawtypes") |
| // public void testGetCurrentLocation() { |
| // ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); |
| // ITmfLocation location = fExperiment.getCurrentLocation(); |
| // assertEquals("getCurrentLocation", location, context.getLocation()); |
| // } |
| |
| // ------------------------------------------------------------------------ |
| // seekEvent on rank |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testSeekRankOnCacheBoundary() { |
| long cacheSize = fExperiment.getCacheSize(); |
| |
| // On lower bound, returns the first event (TS = 1) |
| ITmfContext context = fExperiment.seekEvent(0); |
| assertEquals("Context rank", 0, context.getRank()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 1, context.getRank()); |
| |
| // Position trace at event rank [cacheSize] |
| context = fExperiment.seekEvent(cacheSize); |
| assertEquals("Context rank", cacheSize, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", cacheSize + 1, context.getRank()); |
| |
| // Position trace at event rank [4 * cacheSize] |
| context = fExperiment.seekEvent(4 * cacheSize); |
| assertEquals("Context rank", 4 * cacheSize, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); |
| } |
| |
| @Test |
| public void testSeekRankNotOnCacheBoundary() { |
| long cacheSize = fExperiment.getCacheSize(); |
| |
| // Position trace at event rank 9 |
| ITmfContext context = fExperiment.seekEvent(9); |
| assertEquals("Context rank", 9, context.getRank()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 10, context.getRank()); |
| |
| // Position trace at event rank [cacheSize - 1] |
| context = fExperiment.seekEvent(cacheSize - 1); |
| assertEquals("Context rank", cacheSize - 1, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); |
| assertEquals("Context rank", cacheSize, context.getRank()); |
| |
| // Position trace at event rank [cacheSize + 1] |
| context = fExperiment.seekEvent(cacheSize + 1); |
| assertEquals("Context rank", cacheSize + 1, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); |
| assertEquals("Context rank", cacheSize + 2, context.getRank()); |
| |
| // Position trace at event rank 4500 |
| context = fExperiment.seekEvent(4500); |
| assertEquals("Context rank", 4500, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 4501, context.getRank()); |
| } |
| |
| @Test |
| public void testSeekRankOutOfScope() { |
| // Position trace at beginning |
| ITmfContext context = fExperiment.seekEvent(-1); |
| assertEquals("Event rank", 0, context.getRank()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 1, context.getRank()); |
| |
| // Position trace at event passed the end |
| context = fExperiment.seekEvent(NB_EVENTS); |
| assertEquals("Context rank", NB_EVENTS, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertNull("Event", event); |
| assertEquals("Context rank", NB_EVENTS, context.getRank()); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // seekEvent on timestamp |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testSeekTimestampOnCacheBoundary() { |
| long cacheSize = fExperiment.getCacheSize(); |
| |
| // Position trace at event rank 0 |
| ITmfContext context = fExperiment.seekEvent(TmfTimestamp.create(1, SCALE)); |
| assertEquals("Context rank", 0, context.getRank()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 1, context.getRank()); |
| |
| // Position trace at event rank [cacheSize] |
| context = fExperiment.seekEvent(TmfTimestamp.create(cacheSize + 1, SCALE)); |
| assertEquals("Event rank", cacheSize, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", cacheSize + 1, context.getRank()); |
| |
| // Position trace at event rank [4 * cacheSize] |
| context = fExperiment.seekEvent(TmfTimestamp.create(4 * cacheSize + 1, SCALE)); |
| assertEquals("Context rank", 4 * cacheSize, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 4 * cacheSize + 1, context.getRank()); |
| } |
| |
| @Test |
| public void testSeekTimestampNotOnCacheBoundary() { |
| // Position trace at event rank 1 (TS = 2) |
| ITmfContext context = fExperiment.seekEvent(TmfTimestamp.create(2, SCALE)); |
| assertEquals("Context rank", 1, context.getRank()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 2, context.getRank()); |
| |
| // Position trace at event rank 9 (TS = 10) |
| context = fExperiment.seekEvent(TmfTimestamp.create(10, SCALE)); |
| assertEquals("Context rank", 9, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 10, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 10, context.getRank()); |
| |
| // Position trace at event rank 999 (TS = 1000) |
| context = fExperiment.seekEvent(TmfTimestamp.create(1000, SCALE)); |
| assertEquals("Context rank", 999, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1000, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 1000, context.getRank()); |
| |
| // Position trace at event rank 1001 (TS = 1002) |
| context = fExperiment.seekEvent(TmfTimestamp.create(1002, SCALE)); |
| assertEquals("Context rank", 1001, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1002, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 1002, context.getRank()); |
| |
| // Position trace at event rank 4500 (TS = 4501) |
| context = fExperiment.seekEvent(TmfTimestamp.create(4501, SCALE)); |
| assertEquals("Context rank", 4500, context.getRank()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); |
| assertEquals("Context rank", 4501, context.getRank()); |
| } |
| |
| @Test |
| public void testSeekTimestampOutOfScope() { |
| // Position trace at beginning |
| ITmfContext context = fExperiment.seekEvent(TmfTimestamp.create(-1, SCALE)); |
| assertEquals("Event rank", 0, context.getRank()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", 1, context.getRank()); |
| |
| // Position trace at event passed the end |
| context = fExperiment.seekEvent(TmfTimestamp.create(NB_EVENTS + 1, SCALE)); |
| event = fExperiment.getNext(context); |
| assertNull("Event location", event); |
| assertEquals("Event rank", ITmfContext.UNKNOWN_RANK, context.getRank()); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // seekEvent by location (context rank is undefined) |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testSeekLocationOnCacheBoundary() { |
| long cacheSize = fExperiment.getCacheSize(); |
| |
| // Position trace at event rank 0 |
| ITmfContext tmpContext = fExperiment.seekEvent(0); |
| ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 2, event.getTimestamp().getValue()); |
| |
| // Position trace at event rank 'cacheSize' |
| tmpContext = fExperiment.seekEvent(cacheSize); |
| context = fExperiment.seekEvent(tmpContext.getLocation()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize + 2, event.getTimestamp().getValue()); |
| |
| // Position trace at event rank 4 * 'cacheSize' |
| tmpContext = fExperiment.seekEvent(4 * cacheSize); |
| context = fExperiment.seekEvent(tmpContext.getLocation()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4 * cacheSize + 1, event.getTimestamp().getValue()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4 * cacheSize + 2, event.getTimestamp().getValue()); |
| } |
| |
| @Test |
| public void testSeekLocationNotOnCacheBoundary() { |
| long cacheSize = fExperiment.getCacheSize(); |
| |
| // Position trace at event 'cacheSize' - 1 |
| ITmfContext tmpContext = fExperiment.seekEvent(cacheSize - 1); |
| ITmfContext context = fExperiment.seekEvent(tmpContext.getLocation()); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize, event.getTimestamp().getValue()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", cacheSize + 1, event.getTimestamp().getValue()); |
| |
| // Position trace at event rank 2 * 'cacheSize' - 1 |
| tmpContext = fExperiment.seekEvent(2 * cacheSize - 1); |
| context = fExperiment.seekEvent(tmpContext.getLocation()); |
| context = fExperiment.seekEvent(2 * cacheSize - 1); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 2 * cacheSize, event.getTimestamp().getValue()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 2 * cacheSize + 1, event.getTimestamp().getValue()); |
| |
| // Position trace at event rank 4500 |
| tmpContext = fExperiment.seekEvent(4500); |
| context = fExperiment.seekEvent(tmpContext.getLocation()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4501, event.getTimestamp().getValue()); |
| |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 4502, event.getTimestamp().getValue()); |
| } |
| |
| @Test |
| public void testSeekLocationOutOfScope() { |
| // Position trace at beginning |
| ITmfContext context = fExperiment.seekEvent((ITmfLocation) null); |
| |
| ITmfEvent event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", 1, event.getTimestamp().getValue()); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // getNext - updates the context |
| // ------------------------------------------------------------------------ |
| |
| private static void validateContextRanks(ITmfContext context) { |
| assertTrue("Experiment context type", context instanceof TmfExperimentContext); |
| TmfExperimentContext ctx = (TmfExperimentContext) context; |
| |
| ITmfContext[] subContexts = ctx.getContexts(); |
| |
| long expRank = 0; |
| for (ITmfContext subContext : subContexts) { |
| assertNotNull(subContext); |
| long rank = subContext.getRank(); |
| if (rank == -1) { |
| expRank = -1; |
| break; |
| } |
| expRank += rank - 1; |
| } |
| assertEquals("Experiment context rank", expRank, ctx.getRank()); |
| } |
| |
| @Test |
| public void testGetNextAfteSeekingOnTS_1() { |
| |
| final long INITIAL_TS = 1; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (ts = 1) |
| final ITmfContext context = fExperiment.seekEvent(TmfTimestamp.create(INITIAL_TS, SCALE)); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + i, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfteSeekingOnTS_2() { |
| final long INITIAL_TS = 2; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (ts = 2) |
| final ITmfContext context = fExperiment.seekEvent(TmfTimestamp.create(INITIAL_TS, SCALE)); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + i, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfteSeekingOnTS_3() { |
| |
| final long INITIAL_TS = 500; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (ts = 500) |
| final ITmfContext context = fExperiment.seekEvent(TmfTimestamp.create(INITIAL_TS, SCALE)); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + i, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfterSeekingOnRank_1() { |
| final long INITIAL_RANK = 0L; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (rank = 0) |
| final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfterSeekingOnRank_2() { |
| final long INITIAL_RANK = 1L; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (rank = 0) |
| final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfterSeekingOnRank_3() { |
| final long INITIAL_RANK = 500L; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (rank = 0) |
| final ITmfContext context = fExperiment.seekEvent(INITIAL_RANK); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_RANK + i + 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_RANK + i + 1, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_RANK + NB_READS + 1, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_RANK + NB_READS, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfterSeekingOnLocation_1() { |
| final ITmfLocation INITIAL_LOC = null; |
| final long INITIAL_TS = 1; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (ts = 1) |
| final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + i, context.getRank()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); |
| assertEquals("Event rank", INITIAL_TS + NB_READS - 1, context.getRank()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfterSeekingOnLocation_2() { |
| final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(1L).getLocation(); |
| final long INITIAL_TS = 2; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (ts = 2) |
| final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextAfterSeekingOnLocation_3() { |
| final ITmfLocation INITIAL_LOC = fExperiment.seekEvent(500L).getLocation(); |
| final long INITIAL_TS = 501; |
| final int NB_READS = 20; |
| |
| // On lower bound, returns the first event (ts = 501) |
| final ITmfContext context = fExperiment.seekEvent(INITIAL_LOC); |
| |
| validateContextRanks(context); |
| |
| // Read NB_EVENTS |
| ITmfEvent event; |
| for (int i = 0; i < NB_READS; i++) { |
| event = fExperiment.getNext(context); |
| assertEquals("Event timestamp", INITIAL_TS + i, event.getTimestamp().getValue()); |
| } |
| |
| // Make sure we stay positioned |
| event = fExperiment.parseEvent(context); |
| assertEquals("Event timestamp", INITIAL_TS + NB_READS, event.getTimestamp().getValue()); |
| |
| validateContextRanks(context); |
| } |
| |
| @Test |
| public void testGetNextLocation() { |
| ITmfContext context1 = fExperiment.seekEvent(0); |
| fExperiment.getNext(context1); |
| ITmfLocation location = context1.getLocation(); |
| ITmfEvent event1 = fExperiment.getNext(context1); |
| ITmfContext context2 = fExperiment.seekEvent(location); |
| ITmfEvent event2 = fExperiment.getNext(context2); |
| assertEquals("Event timestamp", event1.getTimestamp().getValue(), event2.getTimestamp().getValue()); |
| } |
| |
| @Test |
| public void testGetNextEndLocation() { |
| ITmfContext context1 = fExperiment.seekEvent(fExperiment.getNbEvents() - 1); |
| fExperiment.getNext(context1); |
| ITmfLocation location = context1.getLocation(); |
| ITmfContext context2 = fExperiment.seekEvent(location); |
| ITmfEvent event = fExperiment.getNext(context2); |
| assertNull("Event", event); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // processRequest |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testProcessRequestForNbEvents() throws InterruptedException { |
| final int nbEvents = 1000; |
| final Vector<ITmfEvent> requestedEvents = new Vector<>(); |
| |
| final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); |
| final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, |
| range, 0, nbEvents, ExecutionType.FOREGROUND) { |
| @Override |
| public void handleData(final ITmfEvent event) { |
| super.handleData(event); |
| requestedEvents.add(event); |
| } |
| }; |
| fExperiment.sendRequest(request); |
| request.waitForCompletion(); |
| |
| assertEquals("nbEvents", nbEvents, requestedEvents.size()); |
| assertTrue("isCompleted", request.isCompleted()); |
| assertFalse("isCancelled", request.isCancelled()); |
| |
| // Ensure that we have distinct events. |
| // Don't go overboard: we are not validating the stub! |
| for (int i = 0; i < nbEvents; i++) { |
| assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); |
| } |
| } |
| |
| @Test |
| public void testProcessRequestForAllEvents() throws InterruptedException { |
| final int nbEvents = ITmfEventRequest.ALL_DATA; |
| final Vector<ITmfEvent> requestedEvents = new Vector<>(); |
| final long nbExpectedEvents = NB_EVENTS; |
| |
| final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); |
| final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, |
| range, 0, nbEvents, ExecutionType.FOREGROUND) { |
| @Override |
| public void handleData(final ITmfEvent event) { |
| super.handleData(event); |
| requestedEvents.add(event); |
| } |
| }; |
| fExperiment.sendRequest(request); |
| request.waitForCompletion(); |
| |
| assertEquals("nbEvents", nbExpectedEvents, requestedEvents.size()); |
| assertTrue("isCompleted", request.isCompleted()); |
| assertFalse("isCancelled", request.isCancelled()); |
| |
| // Ensure that we have distinct events. |
| // Don't go overboard: we are not validating the stub! |
| for (int i = 0; i < nbExpectedEvents; i++) { |
| assertEquals("Distinct events", i+1, requestedEvents.get(i).getTimestamp().getValue()); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| // cancel |
| // ------------------------------------------------------------------------ |
| |
| @Test |
| public void testCancel() throws InterruptedException { |
| final int nbEvents = NB_EVENTS; |
| final int limit = BLOCK_SIZE; |
| final Vector<ITmfEvent> requestedEvents = new Vector<>(); |
| |
| final TmfTimeRange range = new TmfTimeRange(TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH); |
| final TmfEventRequest request = new TmfEventRequest(ITmfEvent.class, |
| range, 0, nbEvents, ExecutionType.FOREGROUND) { |
| int nbRead = 0; |
| |
| @Override |
| public void handleData(final ITmfEvent event) { |
| super.handleData(event); |
| requestedEvents.add(event); |
| if (++nbRead == limit) { |
| cancel(); |
| } |
| } |
| |
| @Override |
| public void handleCancel() { |
| if (requestedEvents.size() < limit) { |
| System.out.println("aie"); |
| } |
| } |
| }; |
| fExperiment.sendRequest(request); |
| request.waitForCompletion(); |
| |
| assertEquals("nbEvents", limit, requestedEvents.size()); |
| assertTrue("isCompleted", request.isCompleted()); |
| assertTrue("isCancelled", request.isCancelled()); |
| } |
| |
| private static abstract class TestTrace extends TmfXmlTraceStubNs implements ITmfPropertiesProvider { |
| public TestTrace(@NonNull String name) { |
| setName(name); |
| } |
| } |
| |
| /** |
| * Tests that experiment with traces from the same host and a clock offset |
| * are well synchronized |
| */ |
| @Test |
| public void testWithSingleHostClockOffset() { |
| // Data for this specific test |
| String hostId = "Test Host 1"; |
| long minOffset = 2000; |
| long offset = 1000; |
| String clockOffset = "clock_offset"; |
| |
| ITmfTrace t1 = new TestTrace("t1") { |
| @Override |
| public @NonNull String getHostId() { |
| return hostId; |
| } |
| @Override |
| public @NonNull Map<@NonNull String, @NonNull String> getProperties() { |
| return ImmutableMap.of(clockOffset, String.valueOf(minOffset)); |
| } |
| }; |
| |
| ITmfTrace t2 = new TestTrace("t2") { |
| @Override |
| public @NonNull String getHostId() { |
| return hostId; |
| } |
| @Override |
| public @NonNull Map<@NonNull String, @NonNull String> getProperties() { |
| return ImmutableMap.of(clockOffset, String.valueOf(minOffset + offset)); |
| } |
| }; |
| TmfExperiment exp = new TmfExperimentStub(EXPERIMENT, new ITmfTrace[] { t1, t2 }, BLOCK_SIZE); |
| |
| try { |
| assertEquals(TimestampTransformFactory.createWithOffset(offset / 2), t1.getTimestampTransform()); |
| assertEquals(TimestampTransformFactory.createWithOffset(-offset / 2), t2.getTimestampTransform()); |
| |
| } finally { |
| exp.dispose(); |
| } |
| } |
| |
| /** |
| * Tests that opening an experiment whose traces already have a |
| * synchronization formula will not eliminate that formula. This test makes |
| * the supposition that the experiment was synchronized and the |
| * synchronization added the clock offset correction to the total formula. |
| */ |
| @Test |
| public void testWithMultiHostClockOffset() { |
| // Data for this specific test |
| String hostId = "Test Host 1"; |
| String hostId2 = "Test Host 2"; |
| long minOffset = 2000; |
| long offset = 1000; |
| String clockOffset = "clock_offset"; |
| |
| ITmfTimestampTransform tt1 = TimestampTransformFactory.createLinear(2.0, offset / 2); |
| ITmfTimestampTransform tt2 = TimestampTransformFactory.createLinear(2.0, -offset / 2); |
| ITmfTimestampTransform tt3 = TimestampTransformFactory.createWithOffset(offset); |
| |
| ITmfTrace t1 = new TestTrace("t1") { |
| @Override |
| public @NonNull String getHostId() { |
| return hostId; |
| } |
| @Override |
| public @NonNull Map<@NonNull String, @NonNull String> getProperties() { |
| return ImmutableMap.of(clockOffset, String.valueOf(minOffset)); |
| } |
| |
| }; |
| t1.setTimestampTransform(tt1); |
| |
| ITmfTrace t2 = new TestTrace("t2") { |
| @Override |
| public @NonNull String getHostId() { |
| return hostId; |
| } |
| @Override |
| public @NonNull Map<@NonNull String, @NonNull String> getProperties() { |
| return ImmutableMap.of(clockOffset, String.valueOf(minOffset + offset)); |
| } |
| }; |
| t2.setTimestampTransform(tt2); |
| |
| ITmfTrace t3 = new TmfXmlTraceStubNs() { |
| @Override |
| public @NonNull String getHostId() { |
| return hostId2; |
| } |
| }; |
| t3.setTimestampTransform(tt3); |
| |
| TmfExperiment exp = new TmfExperimentStub(EXPERIMENT, new ITmfTrace[] { t1, t2, t3 }, BLOCK_SIZE) { |
| |
| @Override |
| public SynchronizationAlgorithm synchronizeTraces() { |
| return new SyncAlgorithmFullyIncremental() { |
| |
| private static final long serialVersionUID = 4206172498287480153L; |
| |
| @Override |
| public ITmfTimestampTransform getTimestampTransform(String h) { |
| if (hostId.equals(h)) { |
| return TimestampTransformFactory.createLinear(2.0, 0); |
| } |
| return tt3; |
| } |
| }; |
| } |
| }; |
| |
| try { |
| assertEquals(tt1, t1.getTimestampTransform()); |
| assertEquals(tt2, t2.getTimestampTransform()); |
| assertEquals(tt3, t3.getTimestampTransform()); |
| |
| } finally { |
| exp.dispose(); |
| } |
| } |
| |
| } |