/******************************************************************************* * Copyright (c) 2013, 2014 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: * Simon Delisle - Initial API and implementation *******************************************************************************/ package org.eclipse.tracecompass.tmf.ctf.core.tests.temp.request; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; 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.request.ITmfEventRequest; import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils; import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.rules.Timeout; /** * Test suite for the scheduler. */ public class TmfSchedulerTest { /** Time-out tests after 60 seconds */ @Rule public TestRule globalTimeout = new Timeout(1, TimeUnit.MINUTES); // ------------------------------------------------------------------------ // Constants // ------------------------------------------------------------------------ private static final @NonNull CtfTestTrace testTrace = CtfTestTrace.KERNEL; private static final int NB_EVENTS_TRACE = 695319; private static final int NB_EVENTS_TIME_RANGE = 155133; // ------------------------------------------------------------------------ // Attributes // ------------------------------------------------------------------------ private CtfTmfTrace fixture; private long fStartTime; private long fEndTime; private TmfTimeRange fForegroundTimeRange; private final List<String> fOrderList = new ArrayList<>(); private int fForegroundId = 0; private int fBackgroundId = 0; /** * Perform pre-test initialization. */ @Before public void setUp() { fixture = CtfTmfTestTraceUtils.getTrace(testTrace); fixture.indexTrace(true); fStartTime = fixture.getStartTime().toNanos(); fEndTime = fixture.getEndTime().toNanos(); long foregroundStartTime = fStartTime + ((fEndTime - fStartTime) / 4); long foregroundEndTime = fStartTime + ((fEndTime - fStartTime) / 2); fForegroundTimeRange = new TmfTimeRange(TmfTimestamp.fromNanos(foregroundStartTime), TmfTimestamp.fromNanos(foregroundEndTime)); } /** * Perform post-test clean-up. */ @After public void tearDown() { if (fixture != null) { fixture.dispose(); } } // ------------------------------------------------------------------------ // Tests cases // ------------------------------------------------------------------------ /** * Test one background request */ @Test public void backgroundRequest() { BackgroundRequest background = new BackgroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(background); try { background.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, background.getNbEvents()); } /** * Test one foreground request */ @Test public void foregroundRequest() { ForegroundRequest foreground = new ForegroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(foreground); try { foreground.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, foreground.getNbEvents()); } /** * Test one foreground and one background request for the entire trace at * the same time */ @Test public void TestMultiRequest1() { BackgroundRequest background = new BackgroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground = new ForegroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(background); fixture.sendRequest(foreground); try { background.waitForCompletion(); foreground.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, background.getNbEvents()); assertEquals(NB_EVENTS_TRACE, foreground.getNbEvents()); } /** * Test one background request for the entire trace and one foreground * request for smaller time range */ @Test public void TestMultiRequest2() { BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground2 = new ForegroundRequest(fForegroundTimeRange); fixture.sendRequest(background2); fixture.sendRequest(foreground2); try { background2.waitForCompletion(); foreground2.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, background2.getNbEvents()); assertEquals(NB_EVENTS_TIME_RANGE, foreground2.getNbEvents()); } /** * Test two foreground request, one to select a time range and one to select * an event in this time range */ @Test public void TestMultiRequest3() { ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(foreground3); TmfSelectionRangeUpdatedSignal signal3 = new TmfSelectionRangeUpdatedSignal(this, fForegroundTimeRange.getStartTime()); fixture.broadcast(signal3); try { foreground3.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, foreground3.getNbEvents()); } /** * Test two foreground request, one to select a time range and one to select * an event before this time range */ @Test public void TestMultiRequest4() { ForegroundRequest foreground4 = new ForegroundRequest(fForegroundTimeRange); fixture.sendRequest(foreground4); TmfSelectionRangeUpdatedSignal signal4 = new TmfSelectionRangeUpdatedSignal(this, TmfTimestamp.fromSeconds(fStartTime + ((fEndTime - fStartTime) / 8))); fixture.broadcast(signal4); try { foreground4.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TIME_RANGE, foreground4.getNbEvents()); } /** * Test two foreground request, one to select a time range and one to select * an event after this time range */ @Test public void TestMultiRequest5() { ForegroundRequest foreground5 = new ForegroundRequest(fForegroundTimeRange); fixture.sendRequest(foreground5); TmfSelectionRangeUpdatedSignal signal5 = new TmfSelectionRangeUpdatedSignal(this, TmfTimestamp.fromSeconds(fEndTime - ((fEndTime - fStartTime) / 4))); fixture.broadcast(signal5); try { foreground5.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TIME_RANGE, foreground5.getNbEvents()); } /** * Test one background and one foreground request for the entire trace and * one foreground request to select an event */ @Test public void TestMultiRequest6() { BackgroundRequest background6 = new BackgroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground6 = new ForegroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(background6); fixture.sendRequest(foreground6); TmfSelectionRangeUpdatedSignal signal6 = new TmfSelectionRangeUpdatedSignal(this, TmfTimestamp.fromSeconds(fStartTime + ((fEndTime - fStartTime) / 8))); fixture.broadcast(signal6); try { background6.waitForCompletion(); foreground6.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, background6.getNbEvents()); assertEquals(NB_EVENTS_TRACE, foreground6.getNbEvents()); } /** * Four request, two foreground and two background */ @Test public void TestMultiRequest7() { ForegroundRequest foreground7 = new ForegroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground8 = new ForegroundRequest(fForegroundTimeRange); BackgroundRequest background7 = new BackgroundRequest(TmfTimeRange.ETERNITY); BackgroundRequest background8 = new BackgroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(foreground7); fixture.sendRequest(foreground8); fixture.sendRequest(background7); fixture.sendRequest(background8); try { foreground7.waitForCompletion(); foreground8.waitForCompletion(); background7.waitForCompletion(); background8.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(NB_EVENTS_TRACE, foreground7.getNbEvents()); assertEquals(NB_EVENTS_TIME_RANGE, foreground8.getNbEvents()); assertEquals(NB_EVENTS_TRACE, background7.getNbEvents()); assertEquals(NB_EVENTS_TRACE, background8.getNbEvents()); } /** * One long foreground request and one short foreground request, the short * one should finish first */ @Test public void preemptedForegroundRequest() { ForegroundRequest foreground9 = new ForegroundRequest(TmfTimeRange.ETERNITY); TmfTimeRange shortTimeRange = new TmfTimeRange(TmfTimestamp.fromNanos(fStartTime), TmfTimestamp.fromNanos(fStartTime + ((fEndTime - fStartTime) / 16))); ForegroundRequest shortForeground = new ForegroundRequest(shortTimeRange); fixture.sendRequest(foreground9); try { foreground9.waitForStart(); } catch (InterruptedException e) { fail(); } fixture.sendRequest(shortForeground); try { shortForeground.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertFalse(foreground9.isCompleted()); } /** * One long background request and one short foreground request, the * foreground request should finish first */ @Test public void preemptedBackgroundRequest() { BackgroundRequest background9 = new BackgroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground10 = new ForegroundRequest(fForegroundTimeRange); fixture.sendRequest(background9); fixture.sendRequest(foreground10); try { foreground10.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertTrue(foreground10.isCompleted()); assertFalse(background9.isCompleted()); } /** * Test if the scheduler is working as expected */ @Ignore @Test public void executionOrder() { List<String> expectedOrder = new LinkedList<>(); expectedOrder.add("FOREGROUND1"); expectedOrder.add("FOREGROUND2"); expectedOrder.add("FOREGROUND3"); expectedOrder.add("FOREGROUND4"); expectedOrder.add("BACKGROUND1"); expectedOrder.add("FOREGROUND1"); expectedOrder.add("FOREGROUND2"); expectedOrder.add("FOREGROUND3"); expectedOrder.add("FOREGROUND4"); expectedOrder.add("BACKGROUND2"); fOrderList.clear(); fForegroundId = 0; fBackgroundId = 0; BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY); BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY); ForegroundRequest foreground4 = new ForegroundRequest(TmfTimeRange.ETERNITY); fixture.sendRequest(foreground1); fixture.sendRequest(foreground2); fixture.sendRequest(foreground3); fixture.sendRequest(foreground4); fixture.sendRequest(background1); fixture.sendRequest(background2); try { foreground1.waitForCompletion(); foreground2.waitForCompletion(); foreground3.waitForCompletion(); foreground4.waitForCompletion(); background1.waitForCompletion(); background2.waitForCompletion(); } catch (InterruptedException e) { fail(); } assertEquals(expectedOrder, fOrderList.subList(0, expectedOrder.size())); } // ------------------------------------------------------------------------ // Helper methods // ------------------------------------------------------------------------ private class BackgroundRequest extends TmfEventRequest { private int nbEvents = 0; private String backgroundName; BackgroundRequest(TmfTimeRange timeRange) { super(fixture.getEventType(), timeRange, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND); backgroundName = getExecType().toString() + ++fBackgroundId; } @Override public void handleData(final ITmfEvent event) { super.handleData(event); synchronized (fOrderList) { if (fOrderList.isEmpty() || !fOrderList.get(fOrderList.size() - 1).equals(backgroundName)) { fOrderList.add(backgroundName); } } ++nbEvents; } public int getNbEvents() { return nbEvents; } } private class ForegroundRequest extends TmfEventRequest { private int nbEvents = 0; private String foregroundName; ForegroundRequest(TmfTimeRange timeRange) { super(fixture.getEventType(), timeRange, 0, ITmfEventRequest.ALL_DATA, ExecutionType.FOREGROUND); foregroundName = getExecType().toString() + ++fForegroundId; } @Override public void handleData(final ITmfEvent event) { super.handleData(event); synchronized (fOrderList) { if (fOrderList.isEmpty() || !fOrderList.get(fOrderList.size() - 1).equals(foregroundName)) { fOrderList.add(foregroundName); } } ++nbEvents; } public int getNbEvents() { return nbEvents; } } }