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
.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
.BufferedReader
;
22 import java
.io
.ByteArrayOutputStream
;
24 import java
.io
.FileReader
;
25 import java
.io
.IOException
;
26 import java
.lang
.reflect
.InvocationTargetException
;
27 import java
.lang
.reflect
.Method
;
28 import java
.util
.ArrayList
;
29 import java
.util
.Arrays
;
30 import java
.util
.List
;
31 import java
.util
.Random
;
32 import java
.util
.stream
.Collectors
;
34 import org
.apache
.log4j
.ConsoleAppender
;
35 import org
.apache
.log4j
.Logger
;
36 import org
.apache
.log4j
.SimpleLayout
;
37 import org
.eclipse
.core
.runtime
.FileLocator
;
38 import org
.eclipse
.jdt
.annotation
.NonNull
;
39 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
40 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
41 import org
.eclipse
.swtbot
.swt
.finder
.SWTBot
;
42 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
43 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
44 import org
.eclipse
.swtbot
.swt
.finder
.results
.BoolResult
;
45 import org
.eclipse
.swtbot
.swt
.finder
.results
.Result
;
46 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
47 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotMenu
;
48 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
49 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.table
.AbstractSegmentStoreTableView
;
50 import org
.eclipse
.tracecompass
.analysis
.timing
.ui
.views
.segmentstore
.table
.AbstractSegmentStoreTableViewer
;
51 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.ui
.views
.latency
.SystemCallLatencyView
;
52 import org
.eclipse
.tracecompass
.segmentstore
.core
.BasicSegment
;
53 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
54 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
55 import org
.eclipse
.tracecompass
.tmf
.ui
.dialog
.TmfFileDialogFactory
;
56 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
57 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
58 import org
.eclipse
.tracecompass
.tmf
.ui
.tests
.shared
.WaitUtils
;
59 import org
.eclipse
.ui
.IViewPart
;
60 import org
.eclipse
.ui
.IViewReference
;
61 import org
.eclipse
.ui
.PlatformUI
;
62 import org
.eclipse
.ui
.WorkbenchException
;
63 import org
.junit
.After
;
64 import org
.junit
.Before
;
65 import org
.junit
.BeforeClass
;
66 import org
.junit
.Test
;
67 import org
.junit
.runner
.RunWith
;
70 * Tests of the latency table
72 * @author Matthew Khouzam
74 @RunWith(SWTBotJunit4ClassRunner
.class)
75 public class SystemCallLatencyTableAnalysisTest
{
77 private static final String TRACE_TYPE
= "org.eclipse.linuxtools.lttng2.kernel.tracetype";
78 private static final String PROJECT_NAME
= "test";
79 private static final String VIEW_ID
= SystemCallLatencyView
.ID
;
80 private static final String TRACING_PERSPECTIVE_ID
= "org.eclipse.linuxtools.tmf.ui.perspective";
82 /** The Log4j logger instance. */
83 private static final Logger fLogger
= Logger
.getRootLogger();
84 private SystemCallLatencyView fLatencyView
;
85 private AbstractSegmentStoreTableViewer fTable
;
91 public static void beforeClass() {
93 SWTBotUtils
.initialize();
94 Thread
.currentThread().setName("SWTBotTest");
95 /* set up for swtbot */
96 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
97 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
98 fLogger
.removeAllAppenders();
99 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
100 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
101 final List
<SWTBotView
> openViews
= bot
.views();
102 for (SWTBotView view
: openViews
) {
103 if (view
.getTitle().equals("Welcome")) {
105 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
108 /* Switch perspectives */
109 switchTracingPerspective();
110 /* Finish waiting for eclipse to load */
111 WaitUtils
.waitForJobs();
116 * Opens a latency table
119 public void createTable() {
123 SWTBotUtils
.openView(VIEW_ID
);
124 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
125 SWTBotView viewBot
= bot
.viewById(VIEW_ID
);
126 final IViewReference viewReference
= viewBot
.getViewReference();
127 IViewPart viewPart
= UIThreadRunnable
.syncExec(new Result
<IViewPart
>() {
129 public IViewPart
run() {
130 return viewReference
.getView(true);
133 assertNotNull(viewPart
);
134 if (!(viewPart
instanceof SystemCallLatencyView
)) {
135 fail("Could not instanciate view");
137 fLatencyView
= (SystemCallLatencyView
) viewPart
;
138 fTable
= fLatencyView
.getSegmentStoreViewer();
139 assertNotNull(fTable
);
146 public void closeTable() {
147 final SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
148 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
152 private static void switchTracingPerspective() {
153 final Exception retE
[] = new Exception
[1];
154 if (!UIThreadRunnable
.syncExec(new BoolResult() {
156 public Boolean
run() {
158 PlatformUI
.getWorkbench().showPerspective(TRACING_PERSPECTIVE_ID
,
159 PlatformUI
.getWorkbench().getActiveWorkbenchWindow());
160 } catch (WorkbenchException e
) {
167 fail(retE
[0].getMessage());
176 public void climbTest() {
177 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
178 for (int i
= 0; i
< 100; i
++) {
179 fixture
.add(new BasicSegment(i
, 2 * i
));
182 assertNotNull(fTable
);
183 fTable
.updateModel(fixture
);
184 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
185 SWTBot bot
= new SWTBot();
186 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
187 tableBot
.header("Duration").click();
188 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
189 tableBot
.header("Duration").click();
190 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "99", 0, 2));
197 public void decrementingTest() {
198 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
199 for (int i
= 100; i
>= 0; i
--) {
200 fixture
.add(new BasicSegment(i
, 2 * i
));
202 assertNotNull(fTable
);
203 fTable
.updateModel(fixture
);
204 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
205 SWTBot bot
= new SWTBot();
206 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "100", 0, 2));
207 tableBot
.header("Duration").click();
208 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
209 tableBot
.header("Duration").click();
210 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "100", 0, 2));
217 public void smallTest() {
218 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
219 for (int i
= 1; i
>= 0; i
--) {
220 fixture
.add(new BasicSegment(i
, 2 * i
));
222 assertNotNull(fTable
);
223 fTable
.updateModel(fixture
);
224 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
225 SWTBot bot
= new SWTBot();
226 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
227 tableBot
.header("Duration").click();
228 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
229 tableBot
.header("Duration").click();
230 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
237 public void largeTest() {
238 final int size
= 1000000;
239 BasicSegment
[] fixture
= new BasicSegment
[size
];
240 for (int i
= 0; i
< size
; i
++) {
241 fixture
[i
] = (new BasicSegment(i
, 2 * i
));
243 assertNotNull(fTable
);
244 fTable
.updateModel(fixture
);
245 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
246 SWTBot bot
= new SWTBot();
247 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
248 tableBot
.header("Duration").click();
249 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
250 tableBot
.header("Duration").click();
251 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "999,999", 0, 2));
258 public void noiseTest() {
259 Random rnd
= new Random();
261 final int size
= 1000000;
262 BasicSegment
[] fixture
= new BasicSegment
[size
];
263 for (int i
= 0; i
< size
; i
++) {
264 int start
= Math
.abs(rnd
.nextInt(100000000));
265 int end
= start
+ Math
.abs(rnd
.nextInt(1000000));
266 fixture
[i
] = (new BasicSegment(start
, end
));
268 assertNotNull(fTable
);
269 fTable
.updateModel(fixture
);
270 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
271 SWTBot bot
= new SWTBot();
272 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "894,633", 0, 2));
273 tableBot
.header("Duration").click();
274 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
275 tableBot
.header("Duration").click();
276 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "999,999", 0, 2));
280 * Test gaussian noise
283 public void gaussianNoiseTest() {
284 Random rnd
= new Random();
286 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
287 for (int i
= 1; i
<= 1000000; i
++) {
288 int start
= Math
.abs(rnd
.nextInt(100000000));
289 final int delta
= Math
.abs(rnd
.nextInt(1000));
290 int end
= start
+ delta
* delta
;
291 fixture
.add(new BasicSegment(start
, end
));
293 assertNotNull(fTable
);
294 fTable
.updateModel(fixture
);
295 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
296 SWTBot bot
= new SWTBot();
297 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "400,689", 0, 2));
298 tableBot
.header("Duration").click();
299 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
300 tableBot
.header("Duration").click();
301 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "998,001", 0, 2));
305 * Test creating a tsv
307 * @throws NoSuchMethodException
308 * Error creating the tsv
309 * @throws IOException
310 * no such file or the file is locked.
313 public void testWriteToTsv() throws NoSuchMethodException
, IOException
{
315 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
316 for (int i
= 1; i
<= 20; i
++) {
319 int end
= start
+ delta
* delta
;
320 fixture
.add(new BasicSegment(start
, end
));
322 assertNotNull(fTable
);
323 fTable
.updateModel(fixture
);
324 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
325 SWTBot bot
= new SWTBot();
326 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
327 SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
328 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
329 List
<String
> actionResult
= Arrays
.asList(testToTsv(viewBot
));
330 String absolutePath
= TmfTraceManager
.getTemporaryDirPath() + File
.separator
+ "syscallLatencyTest.testWriteToTsv.tsv";
331 TmfFileDialogFactory
.setOverrideFiles(absolutePath
);
332 SWTBotMenu menuBot
= viewBot
.viewMenu().menu("Export to TSV");
334 assertTrue(menuBot
.isEnabled());
335 assertTrue(menuBot
.isVisible());
338 try (BufferedReader br
= new BufferedReader(new FileReader(absolutePath
))) {
339 List
<String
> lines
= br
.lines().collect(Collectors
.toList());
340 assertEquals("Both reads", actionResult
, lines
);
343 new File(absolutePath
).delete();
348 private String
[] testToTsv(SWTBotView view
) throws NoSuchMethodException
{
349 ByteArrayOutputStream os
= new ByteArrayOutputStream();
351 Class
<@NonNull AbstractSegmentStoreTableView
> clazz
= AbstractSegmentStoreTableView
.class;
352 Method method
= clazz
.getDeclaredMethod("exportToTsv", java
.io
.OutputStream
.class);
353 method
.setAccessible(true);
354 final Exception
[] except
= new Exception
[1];
355 UIThreadRunnable
.syncExec(() -> {
357 method
.invoke(fLatencyView
, os
);
358 } catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException e
) {
362 assertNull(except
[0]);
363 @SuppressWarnings("null")
364 String
[] lines
= String
.valueOf(os
).split(System
.getProperty("line.separator"));
365 assertNotNull(lines
);
366 assertEquals("number of lines", 21, lines
.length
);
367 assertEquals("header", "Start Time\tEnd Time\tDuration", lines
[0]);
368 // not a straight up string compare due to time zones. Kathmandu and
369 // Eucla have 15 minute time zones.
370 assertTrue("line 1", lines
[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1"));
375 * Test with an actual trace, this is more of an integration test than a
376 * unit test. This test is a slow one too. If some analyses are not well
377 * configured, this test will also generates null pointer exceptions. These
378 * are will be logged.
380 * @throws IOException
384 public void testWithTrace() throws IOException
{
386 tracePath
= FileLocator
.toFileURL(CtfTestTrace
.ARM_64_BIT_HEADER
.getTraceURL()).getPath();
387 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
388 SWTBotView view
= bot
.viewById(VIEW_ID
);
390 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
391 SWTBotUtils
.createProject(PROJECT_NAME
);
392 SWTBotUtils
.openTrace(PROJECT_NAME
, tracePath
, TRACE_TYPE
);
393 WaitUtils
.waitForJobs();
395 WaitUtils
.waitForJobs();
396 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
397 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "24,100", 0, 2));
398 tableBot
.header("Duration").click();
399 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1,000", 0, 2));
400 tableBot
.header("Duration").click();
401 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "5,904,091,700", 0, 2));
402 bot
.closeAllEditors();
403 SWTBotUtils
.deleteProject(PROJECT_NAME
, bot
);