1 /*******************************************************************************
2 * Copyright (c) 2015, 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
.*;
17 import java
.io
.ByteArrayOutputStream
;
18 import java
.io
.IOException
;
19 import java
.lang
.reflect
.InvocationTargetException
;
20 import java
.lang
.reflect
.Method
;
21 import java
.util
.ArrayList
;
22 import java
.util
.List
;
23 import java
.util
.Random
;
25 import org
.apache
.log4j
.ConsoleAppender
;
26 import org
.apache
.log4j
.Logger
;
27 import org
.apache
.log4j
.SimpleLayout
;
28 import org
.eclipse
.core
.runtime
.FileLocator
;
29 import org
.eclipse
.jdt
.annotation
.NonNull
;
30 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
31 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
32 import org
.eclipse
.swtbot
.swt
.finder
.SWTBot
;
33 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
34 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
35 import org
.eclipse
.swtbot
.swt
.finder
.results
.BoolResult
;
36 import org
.eclipse
.swtbot
.swt
.finder
.results
.Result
;
37 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
38 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotMenu
;
39 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
40 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.table
.AbstractSegmentStoreTableView
;
41 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.table
.AbstractSegmentStoreTableViewer
;
42 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.ui
.views
.latency
.SystemCallLatencyView
;
43 import org
.eclipse
.tracecompass
.segmentstore
.core
.BasicSegment
;
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
.ui
.IViewPart
;
48 import org
.eclipse
.ui
.IViewReference
;
49 import org
.eclipse
.ui
.PlatformUI
;
50 import org
.eclipse
.ui
.WorkbenchException
;
51 import org
.junit
.After
;
52 import org
.junit
.Before
;
53 import org
.junit
.BeforeClass
;
54 import org
.junit
.Test
;
55 import org
.junit
.runner
.RunWith
;
58 * Tests of the latency table
60 * @author Matthew Khouzam
62 @RunWith(SWTBotJunit4ClassRunner
.class)
63 public class SystemCallLatencyTableAnalysisTest
{
65 private static final String TRACE_TYPE
= "org.eclipse.linuxtools.lttng2.kernel.tracetype";
66 private static final String PROJECT_NAME
= "test";
67 private static final String VIEW_ID
= SystemCallLatencyView
.ID
;
68 private static final String TRACING_PERSPECTIVE_ID
= "org.eclipse.linuxtools.tmf.ui.perspective";
70 /** The Log4j logger instance. */
71 private static final Logger fLogger
= Logger
.getRootLogger();
72 private SystemCallLatencyView fLatencyView
;
73 private AbstractSegmentStoreTableViewer fTable
;
79 public static void beforeClass() {
81 SWTBotUtils
.initialize();
82 Thread
.currentThread().setName("SWTBotTest");
83 /* set up for swtbot */
84 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
85 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
86 fLogger
.removeAllAppenders();
87 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
88 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
89 final List
<SWTBotView
> openViews
= bot
.views();
90 for (SWTBotView view
: openViews
) {
91 if (view
.getTitle().equals("Welcome")) {
93 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
96 /* Switch perspectives */
97 switchTracingPerspective();
98 /* Finish waiting for eclipse to load */
99 SWTBotUtils
.waitForJobs();
104 * Opens a latency table
107 public void createTable() {
111 SWTBotUtils
.openView(VIEW_ID
);
112 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
113 SWTBotView viewBot
= bot
.viewById(VIEW_ID
);
114 final IViewReference viewReference
= viewBot
.getViewReference();
115 IViewPart viewPart
= UIThreadRunnable
.syncExec(new Result
<IViewPart
>() {
117 public IViewPart
run() {
118 return viewReference
.getView(true);
121 assertNotNull(viewPart
);
122 if (!(viewPart
instanceof SystemCallLatencyView
)) {
123 fail("Could not instanciate view");
125 fLatencyView
= (SystemCallLatencyView
) viewPart
;
126 fTable
= fLatencyView
.getSegmentStoreViewer();
127 assertNotNull(fTable
);
134 public void closeTable() {
135 final SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
136 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
140 private static void switchTracingPerspective() {
141 final Exception retE
[] = new Exception
[1];
142 if (!UIThreadRunnable
.syncExec(new BoolResult() {
144 public Boolean
run() {
146 PlatformUI
.getWorkbench().showPerspective(TRACING_PERSPECTIVE_ID
,
147 PlatformUI
.getWorkbench().getActiveWorkbenchWindow());
148 } catch (WorkbenchException e
) {
155 fail(retE
[0].getMessage());
164 public void climbTest() {
165 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
166 for (int i
= 0; i
< 100; i
++) {
167 fixture
.add(new BasicSegment(i
, 2 * i
));
170 assertNotNull(fTable
);
171 fTable
.updateModel(fixture
);
172 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
173 SWTBot bot
= new SWTBot();
174 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
175 tableBot
.header("Duration").click();
176 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
177 tableBot
.header("Duration").click();
178 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "99", 0, 2));
185 public void decrementingTest() {
186 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
187 for (int i
= 100; i
>= 0; i
--) {
188 fixture
.add(new BasicSegment(i
, 2 * i
));
190 assertNotNull(fTable
);
191 fTable
.updateModel(fixture
);
192 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
193 SWTBot bot
= new SWTBot();
194 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "100", 0, 2));
195 tableBot
.header("Duration").click();
196 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
197 tableBot
.header("Duration").click();
198 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "100", 0, 2));
205 public void smallTest() {
206 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
207 for (int i
= 1; i
>= 0; i
--) {
208 fixture
.add(new BasicSegment(i
, 2 * i
));
210 assertNotNull(fTable
);
211 fTable
.updateModel(fixture
);
212 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
213 SWTBot bot
= new SWTBot();
214 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
215 tableBot
.header("Duration").click();
216 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
217 tableBot
.header("Duration").click();
218 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
225 public void largeTest() {
226 final int size
= 1000000;
227 BasicSegment
[] fixture
= new BasicSegment
[size
];
228 for (int i
= 0; i
< size
; i
++) {
229 fixture
[i
] = (new BasicSegment(i
, 2 * i
));
231 assertNotNull(fTable
);
232 fTable
.updateModel(fixture
);
233 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
234 SWTBot bot
= new SWTBot();
235 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
236 tableBot
.header("Duration").click();
237 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
238 tableBot
.header("Duration").click();
239 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "999,999", 0, 2));
246 public void noiseTest() {
247 Random rnd
= new Random();
249 final int size
= 1000000;
250 BasicSegment
[] fixture
= new BasicSegment
[size
];
251 for (int i
= 0; i
< size
; i
++) {
252 int start
= Math
.abs(rnd
.nextInt(100000000));
253 int end
= start
+ Math
.abs(rnd
.nextInt(1000000));
254 fixture
[i
] = (new BasicSegment(start
, end
));
256 assertNotNull(fTable
);
257 fTable
.updateModel(fixture
);
258 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
259 SWTBot bot
= new SWTBot();
260 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "894,633", 0, 2));
261 tableBot
.header("Duration").click();
262 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
263 tableBot
.header("Duration").click();
264 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "999,999", 0, 2));
268 * Test gaussian noise
271 public void gaussianNoiseTest() {
272 Random rnd
= new Random();
274 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
275 for (int i
= 1; i
<= 1000000; i
++) {
276 int start
= Math
.abs(rnd
.nextInt(100000000));
277 final int delta
= Math
.abs(rnd
.nextInt(1000));
278 int end
= start
+ delta
* delta
;
279 fixture
.add(new BasicSegment(start
, end
));
281 assertNotNull(fTable
);
282 fTable
.updateModel(fixture
);
283 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
284 SWTBot bot
= new SWTBot();
285 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "400,689", 0, 2));
286 tableBot
.header("Duration").click();
287 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
288 tableBot
.header("Duration").click();
289 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "998,001", 0, 2));
293 * Test creating a tsv
295 * @throws NoSuchMethodException
296 * Error creating the tsv
299 public void testWriteToTsv() throws NoSuchMethodException
{
300 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
301 for (int i
= 1; i
<= 20; i
++) {
304 int end
= start
+ delta
* delta
;
305 fixture
.add(new BasicSegment(start
, end
));
307 assertNotNull(fTable
);
308 fTable
.updateModel(fixture
);
309 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
310 SWTBot bot
= new SWTBot();
311 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
312 SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
313 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
315 SWTBotMenu menuBot
= viewBot
.viewMenu().menu("Export to TSV");
316 assertTrue(menuBot
.isEnabled());
317 assertTrue(menuBot
.isVisible());
320 private void testToTsv(SWTBotView view
) throws NoSuchMethodException
{
321 ByteArrayOutputStream os
= new ByteArrayOutputStream();
323 Class
<@NonNull AbstractSegmentStoreTableView
> clazz
= AbstractSegmentStoreTableView
.class;
324 Method method
= clazz
.getDeclaredMethod("exportToTsv", java
.io
.OutputStream
.class);
325 method
.setAccessible(true);
326 final Exception
[] except
= new Exception
[1];
327 UIThreadRunnable
.syncExec(() -> {
329 method
.invoke(fLatencyView
, os
);
330 } catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException e
) {
334 assertNull(except
[0]);
335 @SuppressWarnings("null")
336 String
[] lines
= String
.valueOf(os
).split(System
.getProperty("line.separator"));
337 assertNotNull(lines
);
338 assertEquals("number of lines", 21, lines
.length
);
339 assertEquals("header", "Start Time\tEnd Time\tDuration", lines
[0]);
340 // not a straight up string compare due to time zones. Kathmandu and Eucla have 15 minute time zones.
341 assertTrue("line 1", lines
[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1"));
345 * Test with an actual trace, this is more of an integration test than a
346 * unit test. This test is a slow one too. If some analyses are not well
347 * configured, this test will also generates null pointer exceptions. These
348 * are will be logged.
350 * @throws IOException
354 public void testWithTrace() throws IOException
{
356 tracePath
= FileLocator
.toFileURL(CtfTestTrace
.ARM_64_BIT_HEADER
.getTraceURL()).getPath();
357 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
358 SWTBotView view
= bot
.viewById(VIEW_ID
);
360 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
361 SWTBotUtils
.createProject(PROJECT_NAME
);
362 SWTBotUtils
.openTrace(PROJECT_NAME
, tracePath
, TRACE_TYPE
);
363 SWTBotUtils
.waitForJobs();
365 SWTBotUtils
.waitForJobs();
366 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
367 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "24,100", 0, 2));
368 tableBot
.header("Duration").click();
369 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1,000", 0, 2));
370 tableBot
.header("Duration").click();
371 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "5,904,091,700", 0, 2));
372 bot
.closeAllEditors();
373 SWTBotUtils
.deleteProject(PROJECT_NAME
, bot
);