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
.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 SystemCallLatencyTableAnalysisTest
{
66 private static final String TRACE_TYPE
= "org.eclipse.linuxtools.lttng2.kernel.tracetype";
67 private static final String PROJECT_NAME
= "test";
68 private static final String VIEW_ID
= SystemCallLatencyView
.ID
;
69 private static final String TRACING_PERSPECTIVE_ID
= "org.eclipse.linuxtools.tmf.ui.perspective";
71 /** The Log4j logger instance. */
72 private static final Logger fLogger
= Logger
.getRootLogger();
73 private SystemCallLatencyView fLatencyView
;
74 private AbstractSegmentStoreTableViewer fTable
;
80 public static void beforeClass() {
82 SWTBotUtils
.initialize();
83 Thread
.currentThread().setName("SWTBotTest");
84 /* set up for swtbot */
85 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
86 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
87 fLogger
.removeAllAppenders();
88 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
89 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
90 final List
<SWTBotView
> openViews
= bot
.views();
91 for (SWTBotView view
: openViews
) {
92 if (view
.getTitle().equals("Welcome")) {
94 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
97 /* Switch perspectives */
98 switchTracingPerspective();
99 /* Finish waiting for eclipse to load */
100 WaitUtils
.waitForJobs();
105 * Opens a latency table
108 public void createTable() {
112 SWTBotUtils
.openView(VIEW_ID
);
113 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
114 SWTBotView viewBot
= bot
.viewById(VIEW_ID
);
115 final IViewReference viewReference
= viewBot
.getViewReference();
116 IViewPart viewPart
= UIThreadRunnable
.syncExec(new Result
<IViewPart
>() {
118 public IViewPart
run() {
119 return viewReference
.getView(true);
122 assertNotNull(viewPart
);
123 if (!(viewPart
instanceof SystemCallLatencyView
)) {
124 fail("Could not instanciate view");
126 fLatencyView
= (SystemCallLatencyView
) viewPart
;
127 fTable
= fLatencyView
.getSegmentStoreViewer();
128 assertNotNull(fTable
);
135 public void closeTable() {
136 final SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
137 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
141 private static void switchTracingPerspective() {
142 final Exception retE
[] = new Exception
[1];
143 if (!UIThreadRunnable
.syncExec(new BoolResult() {
145 public Boolean
run() {
147 PlatformUI
.getWorkbench().showPerspective(TRACING_PERSPECTIVE_ID
,
148 PlatformUI
.getWorkbench().getActiveWorkbenchWindow());
149 } catch (WorkbenchException e
) {
156 fail(retE
[0].getMessage());
165 public void climbTest() {
166 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
167 for (int i
= 0; i
< 100; i
++) {
168 fixture
.add(new BasicSegment(i
, 2 * i
));
171 assertNotNull(fTable
);
172 fTable
.updateModel(fixture
);
173 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
174 SWTBot bot
= new SWTBot();
175 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
176 tableBot
.header("Duration").click();
177 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
178 tableBot
.header("Duration").click();
179 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "99", 0, 2));
186 public void decrementingTest() {
187 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
188 for (int i
= 100; i
>= 0; i
--) {
189 fixture
.add(new BasicSegment(i
, 2 * i
));
191 assertNotNull(fTable
);
192 fTable
.updateModel(fixture
);
193 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
194 SWTBot bot
= new SWTBot();
195 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "100", 0, 2));
196 tableBot
.header("Duration").click();
197 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
198 tableBot
.header("Duration").click();
199 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "100", 0, 2));
206 public void smallTest() {
207 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
208 for (int i
= 1; i
>= 0; i
--) {
209 fixture
.add(new BasicSegment(i
, 2 * i
));
211 assertNotNull(fTable
);
212 fTable
.updateModel(fixture
);
213 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
214 SWTBot bot
= new SWTBot();
215 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
216 tableBot
.header("Duration").click();
217 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
218 tableBot
.header("Duration").click();
219 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
226 public void largeTest() {
227 final int size
= 1000000;
228 BasicSegment
[] fixture
= new BasicSegment
[size
];
229 for (int i
= 0; i
< size
; i
++) {
230 fixture
[i
] = (new BasicSegment(i
, 2 * i
));
232 assertNotNull(fTable
);
233 fTable
.updateModel(fixture
);
234 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
235 SWTBot bot
= new SWTBot();
236 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
237 tableBot
.header("Duration").click();
238 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
239 tableBot
.header("Duration").click();
240 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "999,999", 0, 2));
247 public void noiseTest() {
248 Random rnd
= new Random();
250 final int size
= 1000000;
251 BasicSegment
[] fixture
= new BasicSegment
[size
];
252 for (int i
= 0; i
< size
; i
++) {
253 int start
= Math
.abs(rnd
.nextInt(100000000));
254 int end
= start
+ Math
.abs(rnd
.nextInt(1000000));
255 fixture
[i
] = (new BasicSegment(start
, end
));
257 assertNotNull(fTable
);
258 fTable
.updateModel(fixture
);
259 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
260 SWTBot bot
= new SWTBot();
261 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "894,633", 0, 2));
262 tableBot
.header("Duration").click();
263 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
264 tableBot
.header("Duration").click();
265 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "999,999", 0, 2));
269 * Test gaussian noise
272 public void gaussianNoiseTest() {
273 Random rnd
= new Random();
275 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
276 for (int i
= 1; i
<= 1000000; i
++) {
277 int start
= Math
.abs(rnd
.nextInt(100000000));
278 final int delta
= Math
.abs(rnd
.nextInt(1000));
279 int end
= start
+ delta
* delta
;
280 fixture
.add(new BasicSegment(start
, end
));
282 assertNotNull(fTable
);
283 fTable
.updateModel(fixture
);
284 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
285 SWTBot bot
= new SWTBot();
286 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "400,689", 0, 2));
287 tableBot
.header("Duration").click();
288 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "0", 0, 2));
289 tableBot
.header("Duration").click();
290 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "998,001", 0, 2));
294 * Test creating a tsv
296 * @throws NoSuchMethodException
297 * Error creating the tsv
300 public void testWriteToTsv() throws NoSuchMethodException
{
301 List
<@NonNull BasicSegment
> fixture
= new ArrayList
<>();
302 for (int i
= 1; i
<= 20; i
++) {
305 int end
= start
+ delta
* delta
;
306 fixture
.add(new BasicSegment(start
, end
));
308 assertNotNull(fTable
);
309 fTable
.updateModel(fixture
);
310 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
311 SWTBot bot
= new SWTBot();
312 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1", 0, 2));
313 SWTWorkbenchBot swtWorkbenchBot
= new SWTWorkbenchBot();
314 SWTBotView viewBot
= swtWorkbenchBot
.viewById(VIEW_ID
);
316 SWTBotMenu menuBot
= viewBot
.viewMenu().menu("Export to TSV");
317 assertTrue(menuBot
.isEnabled());
318 assertTrue(menuBot
.isVisible());
321 private void testToTsv(SWTBotView view
) throws NoSuchMethodException
{
322 ByteArrayOutputStream os
= new ByteArrayOutputStream();
324 Class
<@NonNull AbstractSegmentStoreTableView
> clazz
= AbstractSegmentStoreTableView
.class;
325 Method method
= clazz
.getDeclaredMethod("exportToTsv", java
.io
.OutputStream
.class);
326 method
.setAccessible(true);
327 final Exception
[] except
= new Exception
[1];
328 UIThreadRunnable
.syncExec(() -> {
330 method
.invoke(fLatencyView
, os
);
331 } catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException e
) {
335 assertNull(except
[0]);
336 @SuppressWarnings("null")
337 String
[] lines
= String
.valueOf(os
).split(System
.getProperty("line.separator"));
338 assertNotNull(lines
);
339 assertEquals("number of lines", 21, lines
.length
);
340 assertEquals("header", "Start Time\tEnd Time\tDuration", lines
[0]);
341 // not a straight up string compare due to time zones. Kathmandu and Eucla have 15 minute time zones.
342 assertTrue("line 1", lines
[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1"));
346 * Test with an actual trace, this is more of an integration test than a
347 * unit test. This test is a slow one too. If some analyses are not well
348 * configured, this test will also generates null pointer exceptions. These
349 * are will be logged.
351 * @throws IOException
355 public void testWithTrace() throws IOException
{
357 tracePath
= FileLocator
.toFileURL(CtfTestTrace
.ARM_64_BIT_HEADER
.getTraceURL()).getPath();
358 SWTWorkbenchBot bot
= new SWTWorkbenchBot();
359 SWTBotView view
= bot
.viewById(VIEW_ID
);
361 bot
.waitUntil(ConditionHelpers
.ViewIsClosed(view
));
362 SWTBotUtils
.createProject(PROJECT_NAME
);
363 SWTBotUtils
.openTrace(PROJECT_NAME
, tracePath
, TRACE_TYPE
);
364 WaitUtils
.waitForJobs();
366 WaitUtils
.waitForJobs();
367 SWTBotTable tableBot
= new SWTBotTable(fTable
.getTableViewer().getTable());
368 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "24,100", 0, 2));
369 tableBot
.header("Duration").click();
370 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "1,000", 0, 2));
371 tableBot
.header("Duration").click();
372 bot
.waitUntil(ConditionHelpers
.isTableCellFilled(tableBot
, "5,904,091,700", 0, 2));
373 bot
.closeAllEditors();
374 SWTBotUtils
.deleteProject(PROJECT_NAME
, bot
);