From: Patrick Tasse Date: Tue, 30 Aug 2016 21:43:21 +0000 (-0400) Subject: tmf: Bug 500542: Missing zoomed events in time graph entry X-Git-Url: http://git.efficios.com/?p=deliverable%2Ftracecompass.git;a=commitdiff_plain;h=9597a3b53931e8e6ade3c8d59534a8918a0d25e8 tmf: Bug 500542: Missing zoomed events in time graph entry When adding an event that starts before the current zoomed event list's first event, the list is deemed to be incomplete and missing events at the beginning of the zoom range. The list is cleared and the new event is added. The remaining events for the full zoom range should follow. Change-Id: I7057fbaac6ca3a57b2923c786c08142b2ebf6fc3 Signed-off-by: Patrick Tasse Reviewed-on: https://git.eclipse.org/r/80076 Reviewed-by: Hudson CI Reviewed-by: Matthew Khouzam --- diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/widgets/timegraph/model/TimeGraphEntryTest.java b/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/widgets/timegraph/model/TimeGraphEntryTest.java new file mode 100644 index 0000000000..d8d056d3e4 --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.ui.tests/src/org/eclipse/tracecompass/tmf/ui/tests/widgets/timegraph/model/TimeGraphEntryTest.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson + * + * 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 + * + * Contributors: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.ui.tests.widgets.timegraph.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; + +import org.eclipse.swt.SWT; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.junit.Test; + +import com.google.common.collect.Iterators; + +/** + * Test the {@link TimeGraphEntry} class + */ +public class TimeGraphEntryTest { + + private final static String NAME = "name"; + + /** + * Test method addEvent. + */ + @Test + public void testAddEvent() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + entry.addEvent(event1); + entry.addEvent(event2); + assertEquals(0, entry.getStartTime()); + assertEquals(20, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2), entry.getTimeEventsIterator()); + } + + /** + * Test method addEvent with replaced last event. + */ + @Test + public void testAddEventReplaceLast() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3a = new TimeEvent(entry, 20, 5, 3); + ITimeEvent event3 = new TimeEvent(entry, 20, 10, 3); + entry.addEvent(event1); + entry.addEvent(event2); + entry.addEvent(event3a); + // last event is replaced + entry.addEvent(event3); + assertEquals(0, entry.getStartTime()); + assertEquals(30, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2, event3), entry.getTimeEventsIterator()); + } + + /** + * Test method addEvent with null events. + */ + @Test + public void testAddEventNulls() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new NullTimeEvent(entry, 0, 10); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3 = new NullTimeEvent(entry, 20, 10); + // null events do not affect start and end time + entry.addEvent(event1); + entry.addEvent(event2); + entry.addEvent(event3); + assertEquals(10, entry.getStartTime()); + assertEquals(20, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2, event3), entry.getTimeEventsIterator()); + } + /** + * Test method addZoomedEvent. + */ + @Test + public void testaddZoomedEvent() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + assertEquals(0, entry.getStartTime()); + assertEquals(20, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2), entry.getTimeEventsIterator()); + } + + /** + * Test method addZoomedEvent with duplicates. + */ + @Test + public void testaddZoomedEventDuplicate() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3 = new TimeEvent(entry, 20, 10, 3); + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + // duplicate events are not added twice + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + entry.addZoomedEvent(event3); + assertEquals(0, entry.getStartTime()); + assertEquals(30, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2, event3), entry.getTimeEventsIterator()); + } + + /** + * Test method addZoomedEvent with replaced last event. + */ + @Test + public void testaddZoomedEventReplaceLast() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3a = new TimeEvent(entry, 20, 5, 3); + ITimeEvent event3 = new TimeEvent(entry, 20, 10, 3); + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + entry.addZoomedEvent(event3a); + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + // last event is replaced + entry.addZoomedEvent(event3); + assertEquals(0, entry.getStartTime()); + assertEquals(30, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2, event3), entry.getTimeEventsIterator()); + } + + /** + * Test method addZoomedEvent with null events. + */ + @Test + public void testAddZoomedEventNulls() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new NullTimeEvent(entry, 0, 10); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3 = new NullTimeEvent(entry, 20, 10); + // null events do not affect start and end time + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + entry.addZoomedEvent(event3); + assertEquals(10, entry.getStartTime()); + assertEquals(20, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2, event3), entry.getTimeEventsIterator()); + } + + /** + * Test method addZoomedEvent with partial list restarted. + */ + @Test + public void testaddZoomedEventPartialRestart() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3 = new TimeEvent(entry, 20, 10, 3); + entry.addZoomedEvent(event2); + entry.addZoomedEvent(event3); + // zoomed list is cleared and restarted + entry.addZoomedEvent(event1); + entry.addZoomedEvent(event2); + entry.addZoomedEvent(event3); + assertEquals(0, entry.getStartTime()); + assertEquals(30, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2, event3), entry.getTimeEventsIterator()); + } + + /** + * Test method getTimeEventsIterator with event list and zoomed list. + */ + @Test + public void testGetTimeEventsIteratorMixed() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3 = new TimeEvent(entry, 20, 10, 3); + ITimeEvent event2a = new TimeEvent(entry, 10, 5, 4); + ITimeEvent event2b = new TimeEvent(entry, 15, 5, 5); + entry.addEvent(event1); + entry.addEvent(event2); + entry.addEvent(event3); + // zoomed events override normal events they overlap completely + entry.addZoomedEvent(event2a); + entry.addZoomedEvent(event2b); + assertEquals(0, entry.getStartTime()); + assertEquals(30, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1, event2a, event2b, event3), entry.getTimeEventsIterator()); + } + + /** + * Test method getTimeEventsIterator with event list and zoomed list partially overlapping. + */ + @Test + public void testGetTimeEventsIteratorMixedSplit() { + TimeGraphEntry entry = new TimeGraphEntry(NAME, SWT.DEFAULT, SWT.DEFAULT); + ITimeEvent event1 = new TimeEvent(entry, 0, 10, 1); + ITimeEvent event2 = new TimeEvent(entry, 10, 10, 2); + ITimeEvent event3 = new TimeEvent(entry, 20, 10, 3); + ITimeEvent event2a = new TimeEvent(entry, 5, 10, 4); + ITimeEvent event2b = new TimeEvent(entry, 15, 10, 5); + ITimeEvent event1s = new TimeEvent(entry, 0, 5, 1); + ITimeEvent event3s = new TimeEvent(entry, 25, 5, 3); + entry.addEvent(event1); + entry.addEvent(event2); + entry.addEvent(event3); + // zoomed events split and override normal events they overlap partially + entry.addZoomedEvent(event2a); + entry.addZoomedEvent(event2b); + assertEquals(0, entry.getStartTime()); + assertEquals(30, entry.getEndTime()); + assertIteratorsEqual(Iterators.forArray(event1s, event2a, event2b, event3s), entry.getTimeEventsIterator()); + } + + private static void assertIteratorsEqual(Iterator expected, Iterator actual) { + int i = 0; + while (expected.hasNext()) { + assertTrue("missing event at position " + i, actual.hasNext()); + ITimeEvent e1 = expected.next(); + ITimeEvent e2 = actual.next(); + assertEquals("not equal events at position " + i, e1, e2); + i++; + } + assertFalse("extra event at position " + i, actual.hasNext()); + } +} diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java index 4ddb9a1d04..8f36276a5e 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java @@ -221,6 +221,8 @@ public class TimeGraphEntry implements ITimeGraphEntry { * starts at the same time as the event to add, it is replaced by the new * event. If the new event starts before the zoomed event list's last event, * the new event is ignored and is assumed to be already part of the list. + * If the new event starts before the zoomed event list's first event, the + * list is assumed to be incomplete and is cleared, and the event is added. * * @param event * The time event to add @@ -235,6 +237,9 @@ public class TimeGraphEntry implements ITimeGraphEntry { fZoomedEventList.add(event); } else if (start == lastStart) { fZoomedEventList.set(lastIndex, event); + } else if (start < fZoomedEventList.get(0).getTime()) { + fZoomedEventList.clear(); + fZoomedEventList.add(event); } if (event instanceof NullTimeEvent) { /* A NullTimeEvent should not affect the entry bounds */