blob: cf5c3e5296ced5c06ce3fa708631a4bcbed6f789 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2015 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:
* Matthew Khouzam - Initial API and implementation
* Marc-Andre Laperle
* Patrick Tasse - Extract base class from ImportAndReadKernelSmokeTest
*******************************************************************************/
package org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests;
import static org.eclipse.swtbot.swt.finder.waits.Conditions.treeHasRows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.ControlFlowView;
import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage.CpuUsageView;
import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesView;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
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.shared.CtfTmfTestTraceUtils;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView;
import org.eclipse.tracecompass.tmf.ui.views.statesystem.TmfStateSystemExplorer;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.collect.ImmutableSet;
/**
* SWTBot Smoke test for LTTng Kernel UI.
*
* @author Matthew Khouzam
*/
@RunWith(SWTBotJunit4ClassRunner.class)
public class ImportAndReadKernelSmokeTest extends KernelTestBase {
private static final @NonNull Set<Entry<String, Set<String>>> EXPECTED_ANALYSES;
static {
Map<String, Set<String>> map = new HashMap<>();
map.put("Input/Output", Collections.emptySet());
map.put("Statistics", ImmutableSet.of("org.eclipse.linuxtools.tmf.statistics.totals", "org.eclipse.linuxtools.tmf.statistics.types"));
map.put("Active Thread", Collections.singleton("org.eclipse.tracecompass.analysis.os.linux.kernel.tid"));
map.put("Linux Kernel", Collections.singleton("org.eclipse.tracecompass.analysis.os.linux.kernel"));
map.put("Context switch", Collections.emptySet());
map.put("Kernel memory usage", Collections.emptySet());
map.put("CPU usage", Collections.singleton("org.eclipse.tracecompass.analysis.os.linux.cpuusage"));
map.put("Futex Contention Analysis", Collections.emptySet());
map.put("IRQ Analysis", Collections.emptySet());
EXPECTED_ANALYSES = map.entrySet();
}
private ITmfEvent fDesired1;
private ITmfEvent fDesired2;
/**
* Main test case
*/
@Test
public void test() {
CtfTmfTrace trace = CtfTmfTestTraceUtils.getSyntheticTrace();
try {
Matcher<IEditorReference> matcher = WidgetMatcherFactory.withPartName(trace.getName());
IEditorPart iep = fBot.editor(matcher).getReference().getEditor(true);
final TmfEventsEditor tmfEd = (TmfEventsEditor) iep;
fDesired1 = getEvent(trace, 100);
fDesired2 = getEvent(trace, 10000);
UIThreadRunnable.syncExec(new VoidResult() {
@Override
public void run() {
tmfEd.setFocus();
tmfEd.selectionChanged(new SelectionChangedEvent(tmfEd, new StructuredSelection(fDesired1)));
}
});
testHV(getViewPart("Histogram"));
testCFV((ControlFlowView) getViewPart("Control Flow"));
testRV((ResourcesView) getViewPart("Resources"));
testStateSystemExplorer(trace.getPath());
} finally {
trace.dispose();
}
}
private static void testCFV(ControlFlowView vp) {
assertNotNull(vp);
}
private void testHV(IViewPart vp) {
SWTBotView hvBot = (new SWTWorkbenchBot()).viewById(HistogramView.ID);
List<SWTBotToolbarButton> hvTools = hvBot.getToolbarButtons();
for (SWTBotToolbarButton hvTool : hvTools) {
if (hvTool.getToolTipText().toLowerCase().contains("lost")) {
hvTool.click();
}
}
HistogramView hv = (HistogramView) vp;
final TmfSelectionRangeUpdatedSignal signal = new TmfSelectionRangeUpdatedSignal(hv, fDesired1.getTimestamp());
final TmfSelectionRangeUpdatedSignal signal2 = new TmfSelectionRangeUpdatedSignal(hv, fDesired2.getTimestamp());
hvBot.close();
hv = (HistogramView) UIThreadRunnable.syncExec(() -> {
try {
return (PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(HistogramView.ID));
} catch (PartInitException e) {
// Do nothing, returning null fails
}
return null;
});
assertNotNull(hv);
hvBot = (new SWTWorkbenchBot()).viewById(HistogramView.ID);
hv.updateTimeRange(100000);
WaitUtils.waitForJobs();
hv.selectionRangeUpdated(signal);
hv.broadcast(signal);
WaitUtils.waitForJobs();
SWTBotUtils.delay(1000);
hv.updateTimeRange(1000000000);
WaitUtils.waitForJobs();
hv.selectionRangeUpdated(signal2);
hv.broadcast(signal2);
WaitUtils.waitForJobs();
SWTBotUtils.delay(1000);
assertNotNull(hv);
}
private static void testRV(ResourcesView vp) {
assertNotNull(vp);
}
private static CtfTmfEvent getEvent(CtfTmfTrace trace, int rank) {
ITmfContext ctx = trace.seekEvent(0);
for (int i = 0; i < rank; i++) {
trace.getNext(ctx);
}
return trace.getNext(ctx);
}
private static IViewPart getViewPart(final String viewTile) {
final IViewPart[] vps = new IViewPart[1];
UIThreadRunnable.syncExec(new VoidResult() {
@Override
public void run() {
IViewReference[] viewRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences();
for (IViewReference viewRef : viewRefs) {
IViewPart vp = viewRef.getView(true);
if (vp.getTitle().equals(viewTile)) {
vps[0] = vp;
return;
}
}
}
});
return vps[0];
}
private static void testStateSystemExplorer(String tracePath) {
// Set up
SWTWorkbenchBot bot = new SWTWorkbenchBot();
SWTBotUtils.openView(CpuUsageView.ID);
SWTBotView cpuUsageBot = bot.viewById(CpuUsageView.ID);
// Open the view
SWTBotUtils.openView(TmfStateSystemExplorer.ID);
SWTBotView sseBot = bot.viewByTitle("State System Explorer");
sseBot.show();
Set<@NonNull Entry<String, Set<String>>> actualAnalyses = getSsNames(sseBot);
assertTrue("Wrong state systems: expected: " + EXPECTED_ANALYSES + ", actual: " + actualAnalyses, actualAnalyses.containsAll(EXPECTED_ANALYSES));
// Re-open the view and make sure it has the same results
sseBot.close();
SWTBotUtils.openView(TmfStateSystemExplorer.ID);
sseBot = bot.viewByTitle("State System Explorer");
sseBot.show();
actualAnalyses = getSsNames(sseBot);
assertTrue("Wrong state systems: expected: " + EXPECTED_ANALYSES + ", actual: " + actualAnalyses, actualAnalyses.containsAll(EXPECTED_ANALYSES));
// Close the trace, and re-open it, let's compare one last time
bot.closeAllEditors();
bot.waitUntil(treeHasRows(sseBot.bot().tree(), 0));
// re-open the trace
SWTBotUtils.openTrace(TRACE_PROJECT_NAME, tracePath, KERNEL_TRACE_TYPE);
actualAnalyses = getSsNames(sseBot);
assertTrue("Wrong state systems: expected: " + EXPECTED_ANALYSES + ", actual: " + actualAnalyses, actualAnalyses.containsAll(EXPECTED_ANALYSES));
sseBot.close();
cpuUsageBot.close();
}
private static @NonNull Set<@NonNull Entry<String, Set<String>>> getSsNames(SWTBotView bot) {
SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(bot.bot());
SWTBotTimeGraphEntry trace = timeGraph.getEntry("synthetic-trace");
SWTBotTimeGraphEntry[] traceEntries = timeGraph.getEntries();
assertEquals("State system explorer should have a single trace entry: " + Arrays.toString(traceEntries), 1, traceEntries.length);
SWTBotTimeGraphEntry[] modules = trace.getEntries();
Map<String, Set<String>> modulesToStateSystems = new HashMap<>();
for (SWTBotTimeGraphEntry module : modules) {
Set<String> stateSystems = new HashSet<>();
for (SWTBotTimeGraphEntry stateSystem : module.getEntries()) {
stateSystems.add(stateSystem.getText());
}
modulesToStateSystems.put(module.getText(), stateSystems);
}
return modulesToStateSystems.entrySet();
}
}