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