Commit | Line | Data |
---|---|---|
101bcc65 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * 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 | |
8 | *******************************************************************************/ | |
9 | package org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table; | |
10 | ||
11 | import static org.junit.Assert.assertEquals; | |
12 | import static org.junit.Assert.assertNotNull; | |
13 | import static org.junit.Assert.assertNull; | |
14 | import static org.junit.Assert.assertTrue; | |
15 | ||
16 | import java.io.BufferedReader; | |
17 | import java.io.ByteArrayOutputStream; | |
18 | import java.io.File; | |
19 | import java.io.FileReader; | |
20 | import java.io.IOException; | |
21 | import java.lang.reflect.InvocationTargetException; | |
22 | import java.lang.reflect.Method; | |
fc409c43 GB |
23 | import java.nio.file.Files; |
24 | import java.nio.file.Path; | |
101bcc65 MK |
25 | import java.util.Arrays; |
26 | import java.util.Collections; | |
27 | import java.util.List; | |
28 | import java.util.Random; | |
29 | import java.util.stream.Collectors; | |
30 | ||
31 | import org.apache.log4j.ConsoleAppender; | |
32 | import org.apache.log4j.Logger; | |
33 | import org.apache.log4j.SimpleLayout; | |
34 | import org.eclipse.jdt.annotation.NonNull; | |
35 | import org.eclipse.jdt.annotation.Nullable; | |
36 | import org.eclipse.jface.viewers.TableViewer; | |
37 | import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; | |
38 | import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; | |
101bcc65 | 39 | import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; |
1ee63dfc | 40 | import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; |
101bcc65 MK |
41 | import org.eclipse.swtbot.swt.finder.results.Result; |
42 | import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; | |
43 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; | |
44 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; | |
45 | import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener; | |
46 | import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider; | |
47 | import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableView; | |
48 | import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table.AbstractSegmentStoreTableViewer; | |
49 | import org.eclipse.tracecompass.segmentstore.core.BasicSegment; | |
50 | import org.eclipse.tracecompass.segmentstore.core.ISegment; | |
51 | import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; | |
52 | import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory; | |
53 | import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory.SegmentStoreType; | |
54 | import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect; | |
55 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
56 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
57 | import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory; | |
58 | import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers; | |
59 | import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils; | |
60 | import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils; | |
61 | import org.eclipse.ui.IViewPart; | |
62 | import org.eclipse.ui.IWorkbench; | |
63 | import org.eclipse.ui.PartInitException; | |
64 | import org.eclipse.ui.PlatformUI; | |
65 | import org.junit.After; | |
66 | import org.junit.Before; | |
67 | import org.junit.BeforeClass; | |
68 | import org.junit.Test; | |
1ee63dfc | 69 | import org.junit.runner.RunWith; |
101bcc65 MK |
70 | |
71 | /** | |
72 | * Tests of the latency table to extend it to custom tables, 4 steps are needed. | |
73 | * <ol> | |
74 | * <li>Override {@link #createSegment(long, long)}</li> | |
75 | * <li>Override {@link #openTable()} to open the desired table view</li> | |
76 | * <li>Override {@link #getSegStoreProvider()} to retrieve the segment store | |
77 | * provider with the desirable aspects</li> | |
78 | * <li>Override {@link #testTsv(String[])} to test the content of the output to | |
79 | * TSV</li> | |
80 | * </ol> | |
81 | * | |
82 | * Feel free to override any test and add additional tests but remember to call | |
83 | * <code>super.test()</code> before. | |
84 | * | |
85 | * @author Matthew Khouzam | |
86 | */ | |
1ee63dfc | 87 | @RunWith(SWTBotJunit4ClassRunner.class) |
101bcc65 MK |
88 | public class SegmentTableTest { |
89 | ||
90 | /** | |
91 | * Test table | |
92 | * | |
93 | * @author Matthew Khouzam | |
94 | */ | |
95 | public static final class TestSegmentStoreTableView extends AbstractSegmentStoreTableView { | |
96 | /** | |
97 | * ID of this view | |
98 | */ | |
99 | public static final String ID = "org.eclipse.tracecompass.analysis.timing.ui.swtbot.tests.table.TestSegmentStoreTableView"; //$NON-NLS-1$ | |
100 | ||
101 | /** | |
102 | * Constructor | |
103 | */ | |
104 | public TestSegmentStoreTableView() { | |
105 | } | |
106 | ||
107 | SegmentTableTest fTest; | |
108 | ||
109 | /** | |
110 | * Set the parent test | |
111 | * | |
112 | * @param test | |
113 | * the test | |
114 | */ | |
115 | public void setTest(SegmentTableTest test) { | |
116 | fTest = test; | |
117 | } | |
118 | ||
119 | @Override | |
120 | protected @NonNull AbstractSegmentStoreTableViewer createSegmentStoreViewer(@NonNull TableViewer tableViewer) { | |
121 | return new AbstractSegmentStoreTableViewer(tableViewer) { | |
122 | ||
123 | @Override | |
124 | protected @Nullable ISegmentStoreProvider getSegmentStoreProvider(@NonNull ITmfTrace trace) { | |
125 | return fTest.getSegStoreProvider(); | |
126 | } | |
127 | }; | |
128 | } | |
129 | } | |
130 | ||
131 | private final class SimpleSegmentStoreProvider implements ISegmentStoreProvider { | |
132 | @Override | |
133 | public void removeListener(@NonNull IAnalysisProgressListener listener) { | |
134 | // do nothing | |
135 | } | |
136 | ||
137 | @Override | |
138 | public @Nullable ISegmentStore<@NonNull ISegment> getSegmentStore() { | |
139 | return fSs; | |
140 | } | |
141 | ||
142 | @Override | |
143 | public @NonNull Iterable<@NonNull ISegmentAspect> getSegmentAspects() { | |
144 | return Collections.emptyList(); | |
145 | } | |
146 | ||
147 | @Override | |
148 | public void addListener(@NonNull IAnalysisProgressListener listener) { | |
149 | // do nothing | |
150 | } | |
151 | } | |
152 | ||
153 | private AbstractSegmentStoreTableView fTableView; | |
154 | private AbstractSegmentStoreTableViewer fTable; | |
155 | private ISegmentStoreProvider fSsp; | |
156 | private final ISegmentStore<@NonNull ISegment> fSs = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Fast); | |
8318869d MAL |
157 | /** |
158 | * The workbench bot used during the test | |
159 | */ | |
160 | protected static SWTWorkbenchBot fBot; | |
101bcc65 MK |
161 | |
162 | /** The Log4j logger instance. */ | |
163 | private static final Logger fLogger = Logger.getRootLogger(); | |
164 | ||
165 | /** | |
166 | * Before class, call by all subclassed | |
167 | */ | |
168 | @BeforeClass | |
169 | public static void beforeClass() { | |
170 | ||
171 | SWTBotUtils.initialize(); | |
172 | Thread.currentThread().setName("SWTBotTest"); | |
173 | /* set up for swtbot */ | |
174 | SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */ | |
175 | SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US"; | |
176 | fLogger.removeAllAppenders(); | |
177 | fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT)); | |
8318869d MAL |
178 | fBot = new SWTWorkbenchBot(); |
179 | SWTBotUtils.closeView("welcome", fBot); | |
101bcc65 MK |
180 | /* Switch perspectives */ |
181 | SWTBotUtils.switchToTracingPerspective(); | |
182 | /* Finish waiting for eclipse to load */ | |
183 | WaitUtils.waitForJobs(); | |
184 | } | |
185 | ||
186 | /** | |
187 | * Opens a latency table | |
188 | */ | |
189 | @Before | |
190 | public void init() { | |
191 | setTableView(openTable()); | |
192 | assertNotNull(getTableView()); | |
193 | setTable(getTableView().getSegmentStoreViewer()); | |
194 | assertNotNull(getTable()); | |
195 | ISegmentStoreProvider segStoreProvider = getSegStoreProvider(); | |
196 | assertNotNull(segStoreProvider); | |
197 | UIThreadRunnable.syncExec(() -> getTable().setSegmentProvider(segStoreProvider)); | |
198 | } | |
199 | ||
200 | /** | |
201 | * Close the table | |
202 | */ | |
203 | @After | |
204 | public void finish() { | |
205 | new SWTWorkbenchBot().viewById(getTableView().getSite().getId()).close(); | |
206 | } | |
207 | ||
208 | /** | |
209 | * Create the table viewer to test | |
210 | * | |
211 | * @return the table viewer bot | |
212 | */ | |
213 | protected AbstractSegmentStoreTableView openTable() { | |
214 | AbstractSegmentStoreTableView tableView = getTableView(); | |
215 | if (tableView != null) { | |
216 | return tableView; | |
217 | } | |
218 | IViewPart vp = null; | |
219 | final IWorkbench workbench = PlatformUI.getWorkbench(); | |
220 | vp = UIThreadRunnable.syncExec((Result<IViewPart>) () -> { | |
221 | try { | |
222 | return workbench.getActiveWorkbenchWindow().getActivePage().showView(TestSegmentStoreTableView.ID); | |
223 | } catch (PartInitException e) { | |
224 | return null; | |
225 | } | |
226 | }); | |
227 | assertNotNull(vp); | |
228 | assertTrue(vp instanceof TestSegmentStoreTableView); | |
229 | TestSegmentStoreTableView testSegmentStoreTableView = (TestSegmentStoreTableView) vp; | |
230 | testSegmentStoreTableView.setTest(this); | |
231 | fTableView = testSegmentStoreTableView; | |
232 | ||
233 | return fTableView; | |
234 | } | |
235 | ||
236 | /** | |
237 | * Create a segment of the type supported by the table under test, with the | |
238 | * requested start and end time | |
239 | * | |
240 | * @param start | |
241 | * start time | |
242 | * @param end | |
243 | * end time | |
244 | * @return the segment | |
245 | */ | |
246 | protected @NonNull ISegment createSegment(long start, long end) { | |
247 | return new BasicSegment(start, end); | |
248 | } | |
249 | ||
250 | /** | |
251 | * Test a climbing data structure. | |
252 | * <p> | |
253 | * Create segments that are progressively larger and start later. Test that | |
254 | * the "duration" column sorts well | |
255 | */ | |
256 | @Test | |
257 | public void climbTest() { | |
fc409c43 | 258 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 MK |
259 | for (int i = 0; i < 100; i++) { |
260 | fixture.add(createSegment(i, 2 * i)); | |
261 | } | |
262 | ||
263 | assertNotNull(getTable()); | |
264 | getTable().updateModel(fixture); | |
265 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
8318869d | 266 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 267 | tableBot.header("Duration").click(); |
8318869d | 268 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 269 | tableBot.header("Duration").click(); |
8318869d | 270 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "99", 0, 2)); |
101bcc65 MK |
271 | } |
272 | ||
273 | /** | |
274 | * Test a decrementing data structure. | |
275 | * <p> | |
276 | * Create segments that are progressively shorter and start sooner, | |
277 | * effectively the inverse sorted {@link #climbTest()} datastructure. Test | |
278 | * that the "duration" column sorts well | |
279 | */ | |
280 | @Test | |
281 | public void decrementingTest() { | |
fc409c43 | 282 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 MK |
283 | for (int i = 100; i >= 0; i--) { |
284 | fixture.add(createSegment(i, 2 * i)); | |
285 | } | |
286 | assertNotNull(getTable()); | |
287 | getTable().updateModel(fixture); | |
288 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
fc409c43 | 289 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 290 | tableBot.header("Duration").click(); |
8318869d | 291 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 292 | tableBot.header("Duration").click(); |
8318869d | 293 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "100", 0, 2)); |
101bcc65 MK |
294 | } |
295 | ||
296 | /** | |
297 | * Test small table | |
298 | * <p> | |
299 | * Test table with 2 segments. Duration sort is tested. | |
300 | */ | |
301 | @Test | |
302 | public void smallTest() { | |
fc409c43 | 303 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 MK |
304 | for (int i = 1; i >= 0; i--) { |
305 | fixture.add(createSegment(i, 2 * i)); | |
306 | } | |
307 | assertNotNull(getTable()); | |
308 | getTable().updateModel(fixture); | |
309 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
fc409c43 | 310 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 311 | tableBot.header("Duration").click(); |
8318869d | 312 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 313 | tableBot.header("Duration").click(); |
8318869d | 314 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2)); |
101bcc65 MK |
315 | } |
316 | ||
317 | /** | |
318 | * Test large table | |
319 | * <p> | |
320 | * Test table with over 9000 segments. Duration sort is tested. | |
321 | */ | |
322 | @Test | |
323 | public void largeTest() { | |
324 | final int size = 1000000; | |
fc409c43 | 325 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 | 326 | for (int i = 0; i < size; i++) { |
fc409c43 | 327 | fixture.add(createSegment(i, 2 * i)); |
101bcc65 MK |
328 | } |
329 | assertNotNull(getTable()); | |
330 | getTable().updateModel(fixture); | |
331 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
8318869d | 332 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 333 | tableBot.header("Duration").click(); |
8318869d | 334 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 335 | tableBot.header("Duration").click(); |
8318869d | 336 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "999,999", 0, 2)); |
101bcc65 MK |
337 | } |
338 | ||
339 | /** | |
340 | * Test table with segments that have durations spread into a random (white | |
341 | * noise) distribution | |
342 | * <p> | |
343 | * Test table with a random distribution of segments. Duration sort is | |
344 | * tested. | |
345 | */ | |
346 | @Test | |
347 | public void noiseTest() { | |
348 | Random rnd = new Random(); | |
349 | rnd.setSeed(1234); | |
350 | final int size = 1000000; | |
fc409c43 | 351 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 MK |
352 | for (int i = 0; i < size; i++) { |
353 | int start = Math.abs(rnd.nextInt(100000000)); | |
354 | int end = start + Math.abs(rnd.nextInt(1000000)); | |
fc409c43 | 355 | fixture.add(createSegment(start, end)); |
101bcc65 MK |
356 | } |
357 | assertNotNull(getTable()); | |
358 | getTable().updateModel(fixture); | |
359 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
fc409c43 | 360 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "374,153", 0, 2)); |
101bcc65 | 361 | tableBot.header("Duration").click(); |
8318869d | 362 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 363 | tableBot.header("Duration").click(); |
8318869d | 364 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "999,999", 0, 2)); |
101bcc65 MK |
365 | } |
366 | ||
367 | /** | |
368 | * Test table with segments that have durations spread into a gaussian | |
369 | * (normal) distribution | |
370 | * <p> | |
371 | * Test table with a gaussian distribution of segments. Duration sort is | |
372 | * tested. | |
373 | */ | |
374 | @Test | |
375 | public void gaussianNoiseTest() { | |
376 | Random rnd = new Random(); | |
377 | rnd.setSeed(1234); | |
fc409c43 | 378 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 MK |
379 | for (int i = 1; i <= 1000000; i++) { |
380 | int start = Math.abs(rnd.nextInt(100000000)); | |
381 | final int delta = Math.abs(rnd.nextInt(1000)); | |
382 | int end = start + delta * delta; | |
383 | fixture.add(createSegment(start, end)); | |
384 | } | |
385 | assertNotNull(getTable()); | |
386 | getTable().updateModel(fixture); | |
387 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
fc409c43 | 388 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "23,409", 0, 2)); |
101bcc65 | 389 | tableBot.header("Duration").click(); |
8318869d | 390 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); |
101bcc65 | 391 | tableBot.header("Duration").click(); |
8318869d | 392 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "998,001", 0, 2)); |
101bcc65 MK |
393 | } |
394 | ||
fc409c43 GB |
395 | /** |
396 | * Test table with an on-disk segment store that is lazy loaded in the table | |
397 | * | |
398 | * @throws IOException | |
399 | */ | |
400 | @Test | |
401 | public void onDiskSegStoreTest() throws IOException { | |
402 | Path segmentFile = Files.createTempFile("tmpSegStore", ".tmp"); | |
403 | try { | |
404 | final int size = 1000000; | |
3866be8e | 405 | ISegmentStore<@NonNull BasicSegment> fixture = SegmentStoreFactory.createOnDiskSegmentStore(segmentFile, BasicSegment.BASIC_SEGMENT_READ_FACTORY); |
fc409c43 | 406 | for (int i = 0; i < size; i++) { |
3866be8e | 407 | fixture.add(new BasicSegment(i, 2 * i)); |
fc409c43 GB |
408 | } |
409 | assertNotNull(getTable()); | |
410 | getTable().updateModel(fixture); | |
411 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
412 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); | |
413 | tableBot.header("Duration").click(); | |
414 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "0", 0, 2)); | |
415 | tableBot.header("Duration").click(); | |
416 | // FIXME: Should be 999,999, but sorting on disk does not work well yet | |
d66a5f05 | 417 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "818,399", 0, 2)); |
fc409c43 GB |
418 | } finally { |
419 | Files.delete(segmentFile); | |
420 | } | |
421 | } | |
422 | ||
101bcc65 MK |
423 | /** |
424 | * Test creating a tsv | |
425 | * | |
426 | * @throws NoSuchMethodException | |
427 | * Error creating the tsv | |
428 | * @throws IOException | |
429 | * no such file or the file is locked. | |
430 | */ | |
431 | @Test | |
432 | public void testWriteToTsv() throws NoSuchMethodException, IOException { | |
433 | ||
fc409c43 | 434 | ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(); |
101bcc65 MK |
435 | for (int i = 1; i <= 20; i++) { |
436 | int start = i; | |
437 | final int delta = i; | |
438 | int end = start + delta * delta; | |
439 | fixture.add(createSegment(start, end)); | |
440 | } | |
441 | assertNotNull(getTable()); | |
442 | getTable().updateModel(fixture); | |
443 | SWTBotTable tableBot = new SWTBotTable(getTable().getTableViewer().getTable()); | |
8318869d | 444 | fBot.waitUntil(ConditionHelpers.isTableCellFilled(tableBot, "1", 0, 2)); |
101bcc65 MK |
445 | SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot(); |
446 | SWTBotView viewBot = swtWorkbenchBot.viewById(getTableView().getSite().getId()); | |
447 | String[] lines = extractTsv(viewBot); | |
448 | testTsv(lines); | |
449 | List<String> actionResult = Arrays.asList(lines); | |
450 | String absolutePath = TmfTraceManager.getTemporaryDirPath() + File.separator + "syscallLatencyTest.testWriteToTsv.tsv"; | |
451 | TmfFileDialogFactory.setOverrideFiles(absolutePath); | |
452 | SWTBotMenu menuBot = viewBot.viewMenu().menu("Export to TSV"); | |
453 | try { | |
454 | assertTrue(menuBot.isEnabled()); | |
455 | assertTrue(menuBot.isVisible()); | |
456 | menuBot.click(); | |
457 | ||
458 | try (BufferedReader br = new BufferedReader(new FileReader(absolutePath))) { | |
459 | List<String> actual = br.lines().collect(Collectors.toList()); | |
460 | assertEquals("Both reads", actionResult, actual); | |
461 | } | |
462 | } finally { | |
463 | new File(absolutePath).delete(); | |
464 | } | |
465 | ||
466 | } | |
467 | ||
468 | private String[] extractTsv(SWTBotView viewBot) throws NoSuchMethodException, SecurityException { | |
469 | ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
470 | assertNotNull(os); | |
471 | Class<@NonNull AbstractSegmentStoreTableView> clazz = AbstractSegmentStoreTableView.class; | |
472 | Method method = clazz.getDeclaredMethod("exportToTsv", java.io.OutputStream.class); | |
473 | method.setAccessible(true); | |
474 | final Exception[] except = new Exception[1]; | |
475 | UIThreadRunnable.syncExec(() -> { | |
476 | try { | |
477 | method.invoke(getTableView(), os); | |
478 | } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { | |
479 | except[0] = e; | |
480 | } | |
481 | }); | |
482 | assertNull(except[0]); | |
483 | @SuppressWarnings("null") | |
484 | String[] lines = String.valueOf(os).split(System.getProperty("line.separator")); | |
485 | return lines; | |
486 | } | |
487 | ||
488 | /** | |
489 | * Test the TSV generated. For each line, including the header, it should be | |
490 | * asserted that it is equal to the expected line | |
491 | * | |
492 | * @param lines | |
493 | * every entry, starting with the header | |
494 | */ | |
495 | protected void testTsv(String[] lines) { | |
496 | assertNotNull(lines); | |
497 | assertEquals("number of lines", 21, lines.length); | |
498 | assertEquals("header", "Start Time\tEnd Time\tDuration", lines[0]); | |
499 | // not a straight up string compare due to time zones. Kathmandu and | |
500 | // Eucla have 15 minute time zones. | |
501 | assertTrue("line 1", lines[1].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s001\\t\\d\\d:\\d\\d:00.000 000 002\\t1")); | |
502 | assertTrue("line 2", lines[2].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s002\\t\\d\\d:\\d\\d:00.000 000 006\\t4")); | |
503 | assertTrue("line 3", lines[3].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s003\\t\\d\\d:\\d\\d:00.000 000 012\\t9")); | |
504 | assertTrue("line 4", lines[4].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s004\\t\\d\\d:\\d\\d:00.000 000 020\\t16")); | |
505 | assertTrue("line 5", lines[5].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s005\\t\\d\\d:\\d\\d:00.000 000 030\\t25")); | |
506 | assertTrue("line 6", lines[6].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s006\\t\\d\\d:\\d\\d:00.000 000 042\\t36")); | |
507 | assertTrue("line 7", lines[7].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s007\\t\\d\\d:\\d\\d:00.000 000 056\\t49")); | |
508 | assertTrue("line 8", lines[8].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s008\\t\\d\\d:\\d\\d:00.000 000 072\\t64")); | |
509 | assertTrue("line 9", lines[9].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s009\\t\\d\\d:\\d\\d:00.000 000 090\\t81")); | |
510 | assertTrue("line 10", lines[10].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s010\\t\\d\\d:\\d\\d:00.000 000 110\\t100")); | |
511 | assertTrue("line 11", lines[11].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s011\\t\\d\\d:\\d\\d:00.000 000 132\\t121")); | |
512 | assertTrue("line 12", lines[12].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s012\\t\\d\\d:\\d\\d:00.000 000 156\\t144")); | |
513 | assertTrue("line 13", lines[13].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s013\\t\\d\\d:\\d\\d:00.000 000 182\\t169")); | |
514 | assertTrue("line 14", lines[14].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s014\\t\\d\\d:\\d\\d:00.000 000 210\\t196")); | |
515 | assertTrue("line 15", lines[15].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s015\\t\\d\\d:\\d\\d:00.000 000 240\\t225")); | |
516 | assertTrue("line 16", lines[16].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s016\\t\\d\\d:\\d\\d:00.000 000 272\\t256")); | |
517 | assertTrue("line 17", lines[17].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s017\\t\\d\\d:\\d\\d:00.000 000 306\\t289")); | |
518 | assertTrue("line 18", lines[18].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s018\\t\\d\\d:\\d\\d:00.000 000 342\\t324")); | |
519 | assertTrue("line 19", lines[19].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s019\\t\\d\\d:\\d\\d:00.000 000 380\\t361")); | |
520 | assertTrue("line 20", lines[20].matches("\\d\\d:\\d\\d:00\\.000\\s000\\s020\\t\\d\\d:\\d\\d:00.000 000 420\\t400")); | |
521 | } | |
522 | ||
523 | /** | |
524 | * Gets the table view | |
525 | * | |
526 | * @return the table view | |
527 | */ | |
528 | protected AbstractSegmentStoreTableView getTableView() { | |
529 | return fTableView; | |
530 | } | |
531 | ||
532 | /** | |
533 | * Sets the table view | |
534 | * | |
535 | * @param tableView | |
536 | * the table view | |
537 | */ | |
538 | protected void setTableView(AbstractSegmentStoreTableView tableView) { | |
539 | fTableView = tableView; | |
540 | } | |
541 | ||
542 | /** | |
543 | * Gets the table viewer | |
544 | * | |
545 | * @return the table viewer | |
546 | */ | |
547 | protected AbstractSegmentStoreTableViewer getTable() { | |
548 | return fTable; | |
549 | } | |
550 | ||
551 | /** | |
552 | * Set the table viewer | |
553 | * | |
554 | * @param table | |
555 | * the table viewer | |
556 | */ | |
557 | protected void setTable(AbstractSegmentStoreTableViewer table) { | |
558 | fTable = table; | |
559 | } | |
560 | ||
561 | /** | |
562 | * get the segment store provider | |
563 | * | |
564 | * @return the segment store provider | |
565 | */ | |
566 | protected ISegmentStoreProvider getSegStoreProvider() { | |
567 | ISegmentStoreProvider ssp = fSsp; | |
568 | if (ssp == null) { | |
569 | ssp = new SimpleSegmentStoreProvider(); | |
570 | fSsp = ssp; | |
571 | } | |
572 | return ssp; | |
573 | } | |
574 | } |