1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.analysis
.os
.linux
.ui
.swtbot
.tests
.latency
;
15 import static org
.junit
.Assert
.assertEquals
;
16 import static org
.junit
.Assert
.assertNotNull
;
17 import static org
.junit
.Assert
.assertNull
;
18 import static org
.junit
.Assert
.assertTrue
;
19 import static org
.junit
.Assert
.fail
;
21 import java
.io
.ByteArrayOutputStream
;
22 import java
.io
.IOException
;
23 import java
.lang
.reflect
.InvocationTargetException
;
24 import java
.lang
.reflect
.Method
;
25 import java
.util
.List
;
27 import org
.apache
.log4j
.ConsoleAppender
;
28 import org
.apache
.log4j
.Logger
;
29 import org
.apache
.log4j
.SimpleLayout
;
30 import org
.eclipse
.core
.runtime
.FileLocator
;
31 import org
.eclipse
.jdt
.annotation
.NonNull
;
32 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
33 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
34 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
35 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
36 import org
.eclipse
.swtbot
.swt
.finder
.results
.BoolResult
;
37 import org
.eclipse
.swtbot
.swt
.finder
.results
.Result
;
38 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
39 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotMenu
;
40 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
41 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
42 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.statistics
.AbstractSegmentStoreStatisticsView
;
43 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.ui
.views
.latency
.statistics
.SystemCallLatencyStatisticsView
;
44 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
45 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
46 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
47 import org
.eclipse
.tracecompass
.tmf
.ui
.tests
.shared
.WaitUtils
;
48 import org
.eclipse
.ui
.IViewPart
;
49 import org
.eclipse
.ui
.IViewReference
;
50 import org
.eclipse
.ui
.PlatformUI
;
51 import org
.eclipse
.ui
.WorkbenchException
;
52 import org
.junit
.After
;
53 import org
.junit
.Before
;
54 import org
.junit
.BeforeClass
;
55 import org
.junit
.Test
;
56 import org
.junit
.runner
.RunWith
;
59 * Tests of the latency table
61 * @author Matthew Khouzam
63 @RunWith(SWTBotJunit4ClassRunner
.class)
64 public class SystemCallLatencyStatisticsTableAnalysisTest
{
66 private static final int MIN_COL
= 1;
67 private static final int MAX_COL
= 2;
68 private static final int AVERAGE_COL
= 3;
69 private static final int STDEV_COL
= 4;
70 private static final int COUNT_COL
= 5;
71 private static final String TRACE_TYPE
= "org.eclipse.linuxtools.lttng2.kernel.tracetype";
72 private static final String PROJECT_NAME
= "test";
73 private static final String VIEW_ID
= SystemCallLatencyStatisticsView
.ID
;
74 private static final String TRACING_PERSPECTIVE_ID
= "org.eclipse.linuxtools.tmf.ui.perspective";
76 /** The Log4j logger instance. */
77 private static final Logger fLogger
= Logger
.getRootLogger();
78 private SWTBotTree fTreeBot
;
84 public static void beforeClass() {
85 SWTBotUtils
.initialize();
86 Thread
.currentThread().setName("SWTBotTest");
87 /* set up for swtbot */
88 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
89 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
90 fLogger
.removeAllAppenders();
91 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
92 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
93 final List
<SWTBotView
> openViews
= bot
.views();
94 for (SWTBotView view
: openViews
) {
95 if (view
.getTitle().equals("Welcome")) {
97 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
100 /* Switch perspectives */
101 switchTracingPerspective();
102 /* Finish waiting for eclipse to load */
103 WaitUtils
.waitForJobs();
108 * Opens a latency table
111 public void createTree() {
115 SWTBotUtils
.openView(VIEW_ID
);
116 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
117 SWTBotView viewBot
= bot
.viewById(VIEW_ID
);
118 final IViewReference viewReference
= viewBot
.getViewReference();
119 IViewPart viewPart
= UIThreadRunnable
.syncExec(new Result
<IViewPart
>() {
121 public IViewPart
run() {
122 return viewReference
.getView(true);
125 assertNotNull(viewPart
);
126 if (!(viewPart
instanceof SystemCallLatencyStatisticsView
)) {
127 fail("Could not instanciate view");
129 fTreeBot
= viewBot
.bot().tree();
130 assertNotNull(fTreeBot
);
137 public void closeTree() {
138 final SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
139 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
143 private static void switchTracingPerspective() {
144 final Exception retE
[] = new Exception
[1];
145 if (!UIThreadRunnable
.syncExec(new BoolResult() {
147 public Boolean
run() {
149 PlatformUI
.getWorkbench().showPerspective(TRACING_PERSPECTIVE_ID
,
150 PlatformUI
.getWorkbench().getActiveWorkbenchWindow());
151 } catch (WorkbenchException e
) {
158 fail(retE
[0].getMessage());
164 * Test with an actual trace, this is more of an integration test than a
165 * unit test. This test is a slow one too. If some analyses are not well
166 * configured, this test will also generates null pointer exceptions. These
167 * are will be logged.
169 * @throws IOException
171 * @throws SecurityException
173 * @throws NoSuchMethodException
175 * @throws IllegalArgumentException
179 public void testWithTrace() throws IOException
, NoSuchMethodException
, SecurityException
, IllegalArgumentException
{
181 tracePath
= FileLocator
.toFileURL(CtfTestTrace
.ARM_64_BIT_HEADER
.getTraceURL()).getPath();
182 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
183 SWTBotView view
= bot
.viewById(VIEW_ID
);
185 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
186 SWTBotUtils
.createProject(PROJECT_NAME
);
187 SWTBotUtils
.openTrace(PROJECT_NAME
, tracePath
, TRACE_TYPE
);
188 WaitUtils
.waitForJobs();
190 WaitUtils
.waitForJobs();
191 assertEquals("1.000 µs", fTreeBot
.cell(0, MIN_COL
));
192 assertEquals("5.904 s", fTreeBot
.cell(0, MAX_COL
));
193 assertEquals("15.628 ms", fTreeBot
.cell(0, AVERAGE_COL
)); // double
194 assertEquals("175.875 ms", fTreeBot
.cell(0, STDEV_COL
));
195 assertEquals("1801", fTreeBot
.cell(0, COUNT_COL
));
196 SWTBotTreeItem treeItem
= fTreeBot
.getTreeItem("Total");
197 treeItem
= treeItem
.getNode(0);
198 assertEquals(55, treeItem
.getNodes().size());
199 validate(treeItem
.getNode(2), "select", "13.600 µs", "1.509 s", "192.251 ms", "386.369 ms", "58");
200 validate(treeItem
.getNode(3), "poll", "6.300 µs", "6.800 µs", "6.550 µs", "---", "2");
201 validate(treeItem
.getNode(5), "set_tid_address", "2.300 µs", "2.300 µs", "2.300 µs", "---", "1");
202 validate(treeItem
.getNode(7), "pipe", "27.900 µs", "29.700 µs", "28.800 µs", "---", "2");
204 SWTBotMenu menuBot
= view
.viewMenu().menu("Export to TSV");
205 assertTrue(menuBot
.isEnabled());
206 assertTrue(menuBot
.isVisible());
208 bot
.closeAllEditors();
209 SWTBotUtils
.deleteProject(PROJECT_NAME
, bot
);
212 private static void testToTsv(SWTBotView view
) throws NoSuchMethodException
{
213 ByteArrayOutputStream os
= new ByteArrayOutputStream();
215 IViewPart viewPart
= view
.getReference().getView(true);
216 assertTrue(viewPart
instanceof SystemCallLatencyStatisticsView
);
217 Class
<@NonNull AbstractSegmentStoreStatisticsView
> clazz
= AbstractSegmentStoreStatisticsView
.class;
218 Method method
= clazz
.getDeclaredMethod("exportToTsv", java
.io
.OutputStream
.class);
219 method
.setAccessible(true);
220 final Exception
[] except
= new Exception
[1];
221 UIThreadRunnable
.syncExec(() -> {
223 method
.invoke((SystemCallLatencyStatisticsView
) viewPart
, os
);
224 } catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException e
) {
228 assertNull(except
[0]);
229 @SuppressWarnings("null")
230 String
[] lines
= String
.valueOf(os
).split(System
.getProperty("line.separator"));
231 assertNotNull(lines
);
232 assertEquals("header", "Level\tMinimum\tMaximum\tAverage\tStandard Deviation\tCount\tTotal", lines
[0]);
233 assertEquals("line 1", "Total\t1.000 µs\t5.904 s\t15.628 ms\t175.875 ms\t1801\t28.146 s", lines
[1]);
237 private static void validate(SWTBotTreeItem treeItem
, final String nodeName
, final String min
, final String max
, final String avg
, final String stdev
, final String count
) {
238 assertEquals(nodeName
, treeItem
.cell(0));
239 assertEquals(min
, treeItem
.cell(MIN_COL
));
240 assertEquals(max
, treeItem
.cell(MAX_COL
));
241 assertEquals(avg
, treeItem
.cell(AVERAGE_COL
)); // double
242 assertEquals(stdev
, treeItem
.cell(STDEV_COL
));
243 assertEquals(count
, treeItem
.cell(COUNT_COL
));