Commit | Line | Data |
---|---|---|
032ecd45 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2013, 2014 Ericsson |
032ecd45 MAL |
3 | * |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Marc-Andre Laperle - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
2bdf0193 | 13 | package org.eclipse.tracecompass.tmf.core.tests.trace.indexer; |
032ecd45 MAL |
14 | |
15 | import static org.junit.Assert.assertEquals; | |
16 | import static org.junit.Assert.assertFalse; | |
17 | import static org.junit.Assert.assertTrue; | |
18 | ||
19 | import java.io.File; | |
20 | import java.io.IOException; | |
21 | import java.io.RandomAccessFile; | |
22 | import java.util.ArrayList; | |
23 | import java.util.Random; | |
24 | ||
2bdf0193 AM |
25 | import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.ICheckpointCollection; |
26 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
27 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; | |
28 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
29 | import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; | |
30 | import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; | |
31 | import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; | |
032ecd45 MAL |
32 | import org.junit.After; |
33 | import org.junit.Before; | |
34 | import org.junit.Test; | |
35 | ||
36 | /** | |
37 | * Common code for ICheckpointCollection test classes | |
38 | * | |
39 | * @author Marc-Andre Laperle | |
40 | */ | |
41 | public abstract class AbstractCheckpointCollectionTest { | |
42 | ||
43 | private static final String INDEX_FILE_NAME = "checkpoint.idx"; //$NON-NLS-1$ | |
44 | ||
45 | /** | |
46 | * The number of checkpoints to be inserted in insert tests | |
47 | */ | |
48 | protected static final int CHECKPOINTS_INSERT_NUM = 50000; | |
49 | /** | |
50 | * The collection being tested | |
51 | */ | |
52 | protected ICheckpointCollection fCheckpointCollection = null; | |
53 | ||
54 | private TmfTraceStub fTrace; | |
55 | private File fFile = new File(INDEX_FILE_NAME); | |
56 | ||
57 | /** | |
58 | * Setup the test. Make sure the index is deleted. | |
59 | */ | |
60 | @Before | |
61 | public void setUp() { | |
62 | fTrace = new TmfTraceStub(); | |
63 | if (fFile.exists()) { | |
64 | fFile.delete(); | |
65 | } | |
66 | fCheckpointCollection = createCollection(); | |
67 | } | |
68 | ||
69 | /** | |
70 | * Tear down the test. Make sure the index is deleted. | |
71 | */ | |
72 | @After | |
73 | public void tearDown() { | |
74 | fTrace.dispose(); | |
75 | fTrace = null; | |
76 | if (fCheckpointCollection != null) { | |
77 | fCheckpointCollection.dispose(); | |
78 | } | |
79 | if (fFile.exists()) { | |
80 | fFile.delete(); | |
81 | } | |
82 | } | |
83 | ||
84 | /** | |
85 | * Get the trace being tested. | |
86 | * | |
87 | * @return the trace being tested. | |
88 | */ | |
89 | public ITmfTrace getTrace() { | |
90 | return fTrace; | |
91 | } | |
92 | ||
93 | /** | |
94 | * Returns whether or not the collection is persisted to disk | |
95 | * | |
96 | * @return true if the collection is persisted to disk, false otherwise | |
97 | */ | |
98 | public boolean isPersistableCollection() { | |
99 | return false; | |
100 | } | |
101 | ||
102 | /** | |
103 | * Get the file used for the index being tested. | |
104 | * | |
105 | * @return the file used for the index being tested. | |
106 | */ | |
107 | public File getFile() { | |
108 | return fFile; | |
109 | } | |
110 | ||
111 | /** | |
112 | * Test constructing a new checkpoint collection | |
113 | */ | |
114 | @Test | |
115 | public void testConstructor() { | |
116 | if (isPersistableCollection()) { | |
117 | assertTrue(fFile.exists()); | |
118 | } | |
119 | assertTrue(fCheckpointCollection.isCreatedFromScratch()); | |
120 | } | |
121 | ||
122 | /** | |
123 | * Test constructing a new checkpoint collection, existing file | |
124 | */ | |
125 | @Test | |
126 | public void testConstructorExistingFile() { | |
127 | if (isPersistableCollection()) { | |
128 | assertTrue(fFile.exists()); | |
032ecd45 MAL |
129 | fCheckpointCollection.dispose(); |
130 | ||
131 | fCheckpointCollection = createCollection(); | |
132 | assertFalse(fCheckpointCollection.isCreatedFromScratch()); | |
133 | } | |
134 | } | |
135 | ||
136 | /** | |
137 | * Test that a new checkpoint collection is considered created from scratch | |
138 | * and vice versa | |
139 | */ | |
140 | @Test | |
141 | public void testIsCreatedFromScratch() { | |
142 | assertTrue(fCheckpointCollection.isCreatedFromScratch()); | |
032ecd45 MAL |
143 | |
144 | if (isPersistableCollection()) { | |
145 | fCheckpointCollection.dispose(); | |
146 | fCheckpointCollection = createCollection(); | |
147 | assertFalse(fCheckpointCollection.isCreatedFromScratch()); | |
148 | } | |
149 | } | |
150 | ||
151 | /** | |
152 | * Test setTimeRange, getTimeRange | |
153 | */ | |
154 | @Test | |
155 | public void testSetGetTimeRange() { | |
156 | if (isPersistableCollection()) { | |
b2c971ec | 157 | TmfTimeRange timeRange = new TmfTimeRange(TmfTimestamp.fromSeconds(0), TmfTimestamp.fromSeconds(100)); |
032ecd45 MAL |
158 | fCheckpointCollection.setTimeRange(timeRange); |
159 | assertEquals(timeRange, fCheckpointCollection.getTimeRange()); | |
160 | } | |
161 | } | |
162 | ||
163 | /** | |
164 | * Create a collection for the test | |
165 | * | |
166 | * @return the collection | |
167 | */ | |
168 | abstract protected ICheckpointCollection createCollection(); | |
169 | ||
170 | /** | |
171 | * Test setNbEvents, getNbEvents | |
172 | */ | |
173 | @Test | |
174 | public void testSetGetNbEvents() { | |
175 | if (isPersistableCollection()) { | |
176 | int expected = 12345; | |
177 | fCheckpointCollection.setNbEvents(expected); | |
178 | assertEquals(expected, fCheckpointCollection.getNbEvents()); | |
179 | } | |
180 | } | |
181 | ||
182 | /** | |
0861e8e8 | 183 | * Test get size |
032ecd45 MAL |
184 | */ |
185 | @Test | |
0861e8e8 | 186 | public void testGetSize() { |
032ecd45 MAL |
187 | assertEquals(0, fCheckpointCollection.size()); |
188 | int expected = CHECKPOINTS_INSERT_NUM; | |
189 | for (int i = 0; i < expected; ++i) { | |
b2c971ec | 190 | fCheckpointCollection.insert(new TmfCheckpoint(TmfTimestamp.fromSeconds(i), new TmfLongLocation(i), i)); |
032ecd45 MAL |
191 | } |
192 | assertEquals(expected, fCheckpointCollection.size()); | |
193 | } | |
194 | ||
195 | /** | |
196 | * Test delete | |
197 | */ | |
198 | @Test | |
199 | public void testDelete() { | |
200 | if (isPersistableCollection()) { | |
201 | assertTrue(fFile.exists()); | |
202 | fCheckpointCollection.delete(); | |
203 | assertFalse(fFile.exists()); | |
204 | } | |
205 | } | |
206 | ||
207 | /** | |
208 | * Test version change | |
209 | * | |
210 | * @throws IOException | |
211 | * can throw this | |
212 | */ | |
213 | @Test | |
214 | public void testVersionChange() throws IOException { | |
032ecd45 | 215 | fCheckpointCollection.dispose(); |
ccf2bbb4 AM |
216 | try (RandomAccessFile f = new RandomAccessFile(fFile, "rw");) { |
217 | f.writeInt(-1); | |
218 | } | |
032ecd45 MAL |
219 | |
220 | fCheckpointCollection = createCollection(); | |
221 | assertTrue(fCheckpointCollection.isCreatedFromScratch()); | |
222 | } | |
223 | ||
4f1ec6cc MAL |
224 | /** |
225 | * Test version change | |
226 | * | |
227 | * @throws IOException | |
228 | * can throw this | |
229 | */ | |
230 | @Test | |
231 | public void testDeleteWhenInvalidBug479675() throws IOException { | |
232 | insertAlot(); | |
233 | try (RandomAccessFile f = new RandomAccessFile(fFile, "rw");) { | |
234 | f.writeInt(-1); | |
235 | } | |
236 | ||
237 | fCheckpointCollection = createCollection(); | |
238 | if (isPersistableCollection()) { | |
239 | ICheckpointCollection old = fCheckpointCollection; | |
240 | try { | |
241 | fCheckpointCollection = createCollection(); | |
242 | assertEquals(0, fCheckpointCollection.size()); | |
243 | } finally { | |
244 | old.dispose(); | |
245 | } | |
246 | } | |
247 | assertTrue(fCheckpointCollection.isCreatedFromScratch()); | |
248 | } | |
249 | ||
032ecd45 MAL |
250 | /** |
251 | * Test a single insertion | |
252 | */ | |
253 | @Test | |
254 | public void testInsert() { | |
b2c971ec | 255 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(12345), new TmfLongLocation(123456L), 0); |
032ecd45 MAL |
256 | fCheckpointCollection.insert(checkpoint); |
257 | ||
258 | long found = fCheckpointCollection.binarySearch(checkpoint); | |
259 | assertEquals(0, found); | |
0861e8e8 | 260 | assertEquals(1, fCheckpointCollection.size()); |
032ecd45 MAL |
261 | } |
262 | ||
263 | /** | |
264 | * Generate many checkpoints and insert them in the collection | |
265 | * | |
266 | * @return the list of generated checkpoints | |
267 | */ | |
268 | protected ArrayList<Integer> insertAlot() { | |
269 | for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { | |
b2c971ec | 270 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(12345 + i), new TmfLongLocation(123456L + i), i); |
032ecd45 MAL |
271 | fCheckpointCollection.insert(checkpoint); |
272 | } | |
273 | ||
0861e8e8 | 274 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); |
032ecd45 MAL |
275 | if (isPersistableCollection()) { |
276 | fCheckpointCollection.dispose(); | |
277 | } | |
278 | ||
279 | boolean random = true; | |
ccf2bbb4 | 280 | ArrayList<Integer> list = new ArrayList<>(); |
032ecd45 MAL |
281 | for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { |
282 | if (random) { | |
283 | Random rand = new Random(); | |
284 | list.add(rand.nextInt(CHECKPOINTS_INSERT_NUM)); | |
285 | } else { | |
286 | list.add(i); | |
287 | } | |
288 | } | |
289 | return list; | |
290 | } | |
291 | ||
292 | /** | |
293 | * Test many checkpoint insertions. Make sure they can be found after | |
294 | * re-opening the file | |
295 | */ | |
296 | @Test | |
297 | public void testInsertAlot() { | |
298 | ArrayList<Integer> list = insertAlot(); | |
299 | ||
300 | if (isPersistableCollection()) { | |
301 | fCheckpointCollection = createCollection(); | |
302 | } | |
0861e8e8 | 303 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); |
032ecd45 MAL |
304 | |
305 | for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { | |
306 | Integer randomCheckpoint = list.get(i); | |
b2c971ec | 307 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(12345 + randomCheckpoint), new TmfLongLocation(123456L + randomCheckpoint), 0); |
032ecd45 MAL |
308 | long found = fCheckpointCollection.binarySearch(checkpoint); |
309 | assertEquals(randomCheckpoint.intValue(), found); | |
310 | } | |
0861e8e8 MAL |
311 | |
312 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); | |
032ecd45 MAL |
313 | } |
314 | ||
315 | /** | |
316 | * Test many checkpoint insertions using the same timestamp. Make sure they | |
317 | * can be found after re-opening the file | |
318 | */ | |
319 | @Test | |
320 | public void testInsertSameTimestamp() { | |
321 | for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { | |
b2c971ec | 322 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(12345), new TmfLongLocation(123456L + i), i); |
032ecd45 MAL |
323 | fCheckpointCollection.insert(checkpoint); |
324 | } | |
0861e8e8 | 325 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); |
032ecd45 | 326 | |
032ecd45 MAL |
327 | if (isPersistableCollection()) { |
328 | fCheckpointCollection.dispose(); | |
329 | } | |
330 | ||
331 | boolean random = true; | |
ccf2bbb4 | 332 | ArrayList<Integer> list = new ArrayList<>(); |
032ecd45 MAL |
333 | for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { |
334 | if (random) { | |
335 | Random rand = new Random(); | |
336 | list.add(rand.nextInt(CHECKPOINTS_INSERT_NUM)); | |
337 | } else { | |
338 | list.add(i); | |
339 | } | |
340 | } | |
341 | ||
342 | if (isPersistableCollection()) { | |
343 | fCheckpointCollection = createCollection(); | |
344 | } | |
0861e8e8 | 345 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); |
032ecd45 MAL |
346 | |
347 | for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { | |
348 | Integer randomCheckpoint = list.get(i); | |
b2c971ec | 349 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(12345), new TmfLongLocation(123456L + randomCheckpoint), 0); |
032ecd45 MAL |
350 | long found = fCheckpointCollection.binarySearch(checkpoint); |
351 | assertEquals(randomCheckpoint.intValue(), found); | |
352 | } | |
353 | } | |
354 | ||
355 | /** | |
356 | * Tests that binarySearch find the correct checkpoint when the time stamp | |
357 | * is between checkpoints | |
358 | */ | |
359 | @Test | |
360 | public void testBinarySearchFindInBetween() { | |
361 | for (long i = 0; i < CHECKPOINTS_INSERT_NUM; i++) { | |
b2c971ec | 362 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(2 * i), new TmfLongLocation(2 * i), i); |
032ecd45 MAL |
363 | fCheckpointCollection.insert(checkpoint); |
364 | } | |
0861e8e8 | 365 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); |
032ecd45 | 366 | |
b2c971ec | 367 | TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(123), new TmfLongLocation(123L), 123); |
032ecd45 MAL |
368 | int expectedInsertionPoint = 61; |
369 | int expectedRank = -(expectedInsertionPoint + 2); | |
370 | ||
371 | long rank = fCheckpointCollection.binarySearch(searchedCheckpoint); | |
372 | assertEquals(expectedRank, rank); | |
373 | } | |
374 | ||
375 | ||
376 | /** | |
377 | * Tests that binarySearch finds the correct checkpoint when searching for a | |
378 | * checkpoint with a null location. It should return the previous checkpoint | |
379 | * from the first checkpoint that matches the timestamp. | |
380 | */ | |
381 | @Test | |
382 | public void testBinarySearchInBetweenSameTimestamp() { | |
383 | int checkpointNum = 0; | |
0861e8e8 | 384 | for (; checkpointNum < CHECKPOINTS_INSERT_NUM / 2; checkpointNum++) { |
b2c971ec | 385 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(0), new TmfLongLocation(checkpointNum), checkpointNum); |
032ecd45 MAL |
386 | fCheckpointCollection.insert(checkpoint); |
387 | } | |
388 | ||
0861e8e8 | 389 | for (; checkpointNum < CHECKPOINTS_INSERT_NUM; checkpointNum++) { |
b2c971ec | 390 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(1), new TmfLongLocation(checkpointNum), checkpointNum); |
032ecd45 MAL |
391 | fCheckpointCollection.insert(checkpoint); |
392 | } | |
0861e8e8 | 393 | assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size()); |
032ecd45 | 394 | |
b2c971ec | 395 | final TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(1), null, 0); |
032ecd45 MAL |
396 | |
397 | long found = fCheckpointCollection.binarySearch(searchedCheckpoint); | |
398 | ||
0861e8e8 | 399 | int expectedInsertionPoint = CHECKPOINTS_INSERT_NUM / 2 - 1; |
032ecd45 MAL |
400 | int expectedRank = -(expectedInsertionPoint + 2); |
401 | ||
402 | assertEquals(expectedRank, found); | |
403 | } | |
0861e8e8 MAL |
404 | |
405 | /** | |
406 | * Test checkpoint insertions after reopening the file. | |
407 | */ | |
408 | @Test | |
409 | public void testInsertAfterReopen() { | |
410 | if (!isPersistableCollection()) { | |
411 | return; | |
412 | } | |
413 | ||
b2c971ec | 414 | fCheckpointCollection.insert(new TmfCheckpoint(TmfTimestamp.fromSeconds(12345), new TmfLongLocation(123456L), 0)); |
0861e8e8 MAL |
415 | |
416 | assertEquals(1, fCheckpointCollection.size()); | |
417 | ||
418 | fCheckpointCollection.dispose(); | |
419 | fCheckpointCollection = createCollection(); | |
420 | assertEquals(1, fCheckpointCollection.size()); | |
421 | ||
b2c971ec | 422 | TmfCheckpoint checkpoint = new TmfCheckpoint(TmfTimestamp.fromSeconds(12345), new TmfLongLocation(123456L), 0); |
0861e8e8 MAL |
423 | long found = fCheckpointCollection.binarySearch(checkpoint); |
424 | assertEquals(0, found); | |
425 | ||
b2c971ec | 426 | fCheckpointCollection.insert(new TmfCheckpoint(TmfTimestamp.fromSeconds(12345 + 1), new TmfLongLocation(123456L + 1), 1)); |
0861e8e8 MAL |
427 | assertEquals(2, fCheckpointCollection.size()); |
428 | ||
429 | fCheckpointCollection.dispose(); | |
430 | fCheckpointCollection = createCollection(); | |
431 | assertEquals(2, fCheckpointCollection.size()); | |
432 | } | |
cf86857a MAL |
433 | |
434 | /** | |
435 | * Test that a checkpoint can be inserted after reopening an empty index. | |
436 | */ | |
437 | @Test | |
438 | public void testInsertAfterEmptyReopen() { | |
439 | fCheckpointCollection.dispose(); | |
440 | fCheckpointCollection = createCollection(); | |
b2c971ec | 441 | fCheckpointCollection.insert(new TmfCheckpoint(TmfTimestamp.fromSeconds(12345), new TmfLongLocation(123456L), 0)); |
cf86857a MAL |
442 | assertEquals(1, fCheckpointCollection.size()); |
443 | } | |
032ecd45 | 444 | } |