Commit | Line | Data |
---|---|---|
efc403bb AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2012 Ericsson | |
3 | * Copyright (c) 2010, 2011 École Polytechnique de Montréal | |
4 | * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com> | |
5 | * | |
6 | * All rights reserved. This program and the accompanying materials are | |
7 | * made available under the terms of the Eclipse Public License v1.0 which | |
8 | * accompanies this distribution, and is available at | |
9 | * http://www.eclipse.org/legal/epl-v10.html | |
10 | * | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider; | |
14 | ||
15 | import static org.junit.Assert.*; | |
16 | ||
17 | import java.io.File; | |
efc403bb | 18 | import java.io.IOException; |
efc403bb AM |
19 | import java.util.List; |
20 | ||
6d08acca AM |
21 | import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; |
22 | import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; | |
23 | import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; | |
1e4bb526 | 24 | import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; |
efc403bb | 25 | import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; |
18ab1d18 AM |
26 | import org.eclipse.linuxtools.tmf.core.statesystem.HistoryBuilder; |
27 | import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput; | |
28 | import org.eclipse.linuxtools.tmf.core.statesystem.IStateHistoryBackend; | |
29 | import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemBuilder; | |
efc403bb | 30 | import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.HistoryTreeBackend; |
dc0f7bfe | 31 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CtfKernelStateInput; |
6b78e55b | 32 | import org.eclipse.linuxtools.lttng2.kernel.core.trace.Attributes; |
efc403bb AM |
33 | import org.junit.*; |
34 | ||
35 | /** | |
36 | * Unit tests for the StateHistorySystem, which uses a full (non-partial) | |
37 | * history and the non-threaded CTF kernel handler. | |
38 | * | |
39 | * @author alexmont | |
40 | * | |
41 | */ | |
42 | @SuppressWarnings("nls") | |
43 | public class StateSystemFullHistoryTest { | |
44 | ||
ebd67b34 AM |
45 | static File stateFile; |
46 | static File stateFileBenchmark; | |
efc403bb | 47 | |
ebd67b34 AM |
48 | static HistoryBuilder builder; |
49 | static IStateChangeInput input; | |
50 | static IStateHistoryBackend hp; | |
d26f90fd | 51 | static IStateSystemBuilder ssb; |
efc403bb | 52 | |
cc2292bd AM |
53 | /* Offset in the trace + start time of the trace */ |
54 | private final static long interestingTimestamp1 = 18670067372290L + 1331649577946812237L; | |
2359ecca | 55 | |
efc403bb AM |
56 | protected static String getTestFileName() { |
57 | return "/tmp/statefile.ht"; //$NON-NLS-1$ | |
58 | } | |
59 | ||
60 | @BeforeClass | |
61 | public static void initialize() { | |
62 | stateFile = new File(getTestFileName()); | |
63 | stateFileBenchmark = new File(getTestFileName() + ".benchmark"); //$NON-NLS-1$ | |
64 | try { | |
dc0f7bfe | 65 | input = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); |
efc403bb AM |
66 | hp = new HistoryTreeBackend(stateFile, input.getStartTime()); |
67 | builder = new HistoryBuilder(input, hp); | |
68 | } catch (Exception e) { | |
69 | e.printStackTrace(); | |
70 | } | |
71 | builder.run(); | |
d26f90fd | 72 | ssb = builder.getStateSystemBuilder(); |
fee997a5 | 73 | builder.close(); /* Waits for the construction to finish */ |
efc403bb AM |
74 | } |
75 | ||
76 | @AfterClass | |
77 | public static void cleanup() { | |
ebd67b34 AM |
78 | boolean ret1, ret2; |
79 | ret1 = stateFile.delete(); | |
80 | ret2 = stateFileBenchmark.delete(); | |
81 | if ( !(ret1 && ret2) ) { | |
6b78e55b AM |
82 | System.err.println("Error cleaning up during unit testing, " + //$NON-NLS-1$ |
83 | "you might have leftovers state history files in /tmp"); //$NON-NLS-1$ | |
ebd67b34 | 84 | } |
efc403bb AM |
85 | } |
86 | ||
87 | /** | |
88 | * Rebuild independently so we can benchmark it. Too bad JUnit doesn't allow | |
89 | * us to @Test the @BeforeClass... | |
1e4bb526 AM |
90 | * |
91 | * @throws IOException | |
92 | * @throws TmfTraceException | |
efc403bb AM |
93 | */ |
94 | @Test | |
1e4bb526 | 95 | public void testBuild() throws IOException, TmfTraceException { |
efc403bb AM |
96 | HistoryBuilder zebuilder; |
97 | IStateChangeInput zeinput; | |
1e4bb526 | 98 | IStateHistoryBackend zehp = null; |
efc403bb | 99 | |
1e4bb526 AM |
100 | zeinput = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); |
101 | zehp = new HistoryTreeBackend(stateFileBenchmark, zeinput.getStartTime()); | |
102 | zebuilder = new HistoryBuilder(zeinput, zehp); | |
103 | zebuilder.run(); | |
104 | zebuilder.close(); | |
105 | ||
106 | assertEquals(CtfTestFiles.startTime, zehp.getStartTime()); | |
107 | assertEquals(CtfTestFiles.endTime, zehp.getEndTime()); | |
efc403bb AM |
108 | } |
109 | ||
110 | @Test | |
1e4bb526 | 111 | public void testOpenExistingStateFile() throws IOException { |
efc403bb | 112 | IStateHistoryBackend hp2 = null; |
d26f90fd | 113 | IStateSystemBuilder ssb2 = null; |
1e4bb526 AM |
114 | |
115 | /* 'newStateFile' should have already been created */ | |
116 | hp2 = new HistoryTreeBackend(stateFile); | |
d26f90fd | 117 | ssb2 = HistoryBuilder.openExistingHistory(hp2); |
1e4bb526 | 118 | |
d26f90fd | 119 | assertNotNull(ssb2); |
1e4bb526 AM |
120 | assertEquals(CtfTestFiles.startTime, hp2.getStartTime()); |
121 | assertEquals(CtfTestFiles.endTime, hp2.getEndTime()); | |
efc403bb AM |
122 | } |
123 | ||
124 | @Test | |
125 | public void testFullQuery1() throws StateValueTypeException, | |
126 | AttributeNotFoundException, TimeRangeException { | |
127 | ||
dad01d27 | 128 | List<ITmfStateInterval> list; |
efc403bb | 129 | ITmfStateInterval interval; |
ae54340d | 130 | int quark, quark2, valueInt; |
efc403bb AM |
131 | String valueStr; |
132 | ||
d26f90fd | 133 | list = ssb.loadStateAtTime(interestingTimestamp1); |
efc403bb | 134 | |
d26f90fd | 135 | quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
dad01d27 | 136 | interval = list.get(quark); |
efc403bb | 137 | valueInt = interval.getStateValue().unboxInt(); |
2359ecca | 138 | assertEquals(1397, valueInt); |
efc403bb | 139 | |
d26f90fd | 140 | quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); |
dad01d27 | 141 | interval = list.get(quark); |
efc403bb | 142 | valueStr = interval.getStateValue().unboxStr(); |
2359ecca | 143 | assertEquals("gdbus", valueStr); |
efc403bb | 144 | |
ae54340d | 145 | /* Query a stack attribute, has to be done in two passes */ |
d26f90fd | 146 | quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_MODE_STACK); |
ab9bc51b | 147 | interval = list.get(quark); |
ae54340d | 148 | valueInt = interval.getStateValue().unboxInt(); /* The stack depth */ |
d26f90fd | 149 | quark2 = ssb.getQuarkRelative(quark, Integer.toString(valueInt)); |
ab9bc51b | 150 | interval = list.get(quark2); |
ae54340d AM |
151 | valueStr = interval.getStateValue().unboxStr(); |
152 | assertTrue(valueStr.equals("sys_poll")); | |
efc403bb AM |
153 | } |
154 | ||
155 | @Test | |
156 | public void testFullQuery2() { | |
157 | // | |
158 | } | |
159 | ||
160 | @Test | |
161 | public void testFullQuery3() { | |
162 | // | |
163 | } | |
164 | ||
165 | @Test | |
166 | public void testSingleQuery1() throws AttributeNotFoundException, | |
167 | TimeRangeException, StateValueTypeException { | |
168 | ||
2359ecca | 169 | long timestamp = interestingTimestamp1; |
efc403bb AM |
170 | int quark; |
171 | ITmfStateInterval interval; | |
172 | String valueStr; | |
173 | ||
d26f90fd AM |
174 | quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); |
175 | interval = ssb.querySingleState(timestamp, quark); | |
efc403bb | 176 | valueStr = interval.getStateValue().unboxStr(); |
2359ecca | 177 | assertEquals("gdbus", valueStr); |
efc403bb AM |
178 | } |
179 | ||
180 | @Test | |
181 | public void testSingleQuery2() { | |
182 | // | |
183 | } | |
184 | ||
185 | @Test | |
186 | public void testSingleQuery3() { | |
187 | // | |
188 | } | |
189 | ||
ab9bc51b AM |
190 | /** |
191 | * Test a range query (with no resolution parameter, so all intervals) | |
192 | */ | |
efc403bb AM |
193 | @Test |
194 | public void testRangeQuery1() throws AttributeNotFoundException, | |
195 | TimeRangeException, StateValueTypeException { | |
196 | ||
2359ecca | 197 | long time1 = interestingTimestamp1; |
dc0f7bfe | 198 | long time2 = time1 + 1L * CtfTestFiles.NANOSECS_PER_SEC; |
efc403bb AM |
199 | int quark; |
200 | List<ITmfStateInterval> intervals; | |
201 | ||
d26f90fd AM |
202 | quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
203 | intervals = ssb.queryHistoryRange(quark, time1, time2); | |
2359ecca AM |
204 | assertEquals(487, intervals.size()); /* Number of context switches! */ |
205 | assertEquals(1685, intervals.get(100).getStateValue().unboxInt()); | |
cc2292bd | 206 | assertEquals(1331668248427681372L, intervals.get(205).getEndTime()); |
efc403bb AM |
207 | } |
208 | ||
1d3d1293 AM |
209 | /** |
210 | * Range query, but with a t2 far off the end of the trace. | |
211 | * The result should still be valid. | |
212 | */ | |
213 | @Test | |
214 | public void testRangeQuery2() throws TimeRangeException, | |
215 | AttributeNotFoundException { | |
216 | ||
217 | List<ITmfStateInterval> intervals; | |
218 | ||
d26f90fd AM |
219 | int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.IRQ_STACK); |
220 | long ts1 = ssb.getStartTime(); /* start of the trace */ | |
1d3d1293 AM |
221 | long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid, but ignored */ |
222 | ||
d26f90fd | 223 | intervals = ssb.queryHistoryRange(quark, ts1, ts2); |
1d3d1293 AM |
224 | |
225 | /* Nb of IRQs on CPU 0 during the whole trace */ | |
226 | assertEquals(1653, intervals.size()); | |
227 | } | |
228 | ||
ab9bc51b AM |
229 | /** |
230 | * Test a range query with a resolution | |
231 | */ | |
232 | @Test | |
1d3d1293 | 233 | public void testRangeQuery3() throws AttributeNotFoundException, |
ab9bc51b AM |
234 | TimeRangeException, StateValueTypeException { |
235 | ||
236 | long time1 = interestingTimestamp1; | |
dc0f7bfe | 237 | long time2 = time1 + 1L * CtfTestFiles.NANOSECS_PER_SEC; |
ab9bc51b AM |
238 | long resolution = 1000000; /* One query every millisecond */ |
239 | int quark; | |
240 | List<ITmfStateInterval> intervals; | |
241 | ||
d26f90fd AM |
242 | quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
243 | intervals = ssb.queryHistoryRange(quark, time1, time2, resolution); | |
ab9bc51b AM |
244 | assertEquals(129, intervals.size()); /* Number of context switches! */ |
245 | assertEquals(1452, intervals.get(50).getStateValue().unboxInt()); | |
cc2292bd | 246 | assertEquals(1331668248784789238L, intervals.get(100).getEndTime()); |
ab9bc51b AM |
247 | } |
248 | ||
efc403bb AM |
249 | /** |
250 | * Ask for a time range outside of the trace's range | |
251 | * | |
252 | * @throws TimeRangeException | |
253 | */ | |
254 | @Test(expected = TimeRangeException.class) | |
255 | public void testFullQueryInvalidTime1() throws TimeRangeException { | |
dc0f7bfe | 256 | long ts = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; |
d26f90fd | 257 | ssb.loadStateAtTime(ts); |
efc403bb AM |
258 | |
259 | } | |
260 | ||
261 | @Test(expected = TimeRangeException.class) | |
262 | public void testFullQueryInvalidTime2() throws TimeRangeException { | |
dc0f7bfe | 263 | long ts = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; |
d26f90fd | 264 | ssb.loadStateAtTime(ts); |
efc403bb AM |
265 | |
266 | } | |
267 | ||
268 | @Test(expected = TimeRangeException.class) | |
269 | public void testSingleQueryInvalidTime1() | |
270 | throws AttributeNotFoundException, TimeRangeException { | |
271 | ||
d26f90fd | 272 | int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
dc0f7bfe | 273 | long ts = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; |
d26f90fd | 274 | ssb.querySingleState(ts, quark); |
efc403bb AM |
275 | } |
276 | ||
277 | @Test(expected = TimeRangeException.class) | |
278 | public void testSingleQueryInvalidTime2() | |
279 | throws AttributeNotFoundException, TimeRangeException { | |
280 | ||
d26f90fd | 281 | int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
dc0f7bfe | 282 | long ts = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; |
d26f90fd | 283 | ssb.querySingleState(ts, quark); |
efc403bb AM |
284 | } |
285 | ||
286 | @Test(expected = TimeRangeException.class) | |
287 | public void testRangeQueryInvalidTime1() throws AttributeNotFoundException, | |
288 | TimeRangeException { | |
289 | ||
d26f90fd | 290 | int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
dc0f7bfe AM |
291 | long ts1 = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ |
292 | long ts2 = CtfTestFiles.startTime + 1L * CtfTestFiles.NANOSECS_PER_SEC; /* valid */ | |
efc403bb | 293 | |
d26f90fd | 294 | ssb.queryHistoryRange(quark, ts1, ts2); |
efc403bb AM |
295 | } |
296 | ||
297 | @Test(expected = TimeRangeException.class) | |
298 | public void testRangeQueryInvalidTime2() throws TimeRangeException, | |
299 | AttributeNotFoundException { | |
300 | ||
d26f90fd | 301 | int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
dc0f7bfe AM |
302 | long ts1 = CtfTestFiles.startTime - 1L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ |
303 | long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ | |
efc403bb | 304 | |
d26f90fd | 305 | ssb.queryHistoryRange(quark, ts1, ts2); |
efc403bb AM |
306 | } |
307 | ||
308 | /** | |
309 | * Ask for a non-existing attribute | |
310 | * | |
311 | * @throws AttributeNotFoundException | |
312 | */ | |
313 | @Test(expected = AttributeNotFoundException.class) | |
314 | public void testQueryInvalidAttribute() throws AttributeNotFoundException { | |
315 | ||
d26f90fd | 316 | ssb.getQuarkAbsolute("There", "is", "no", "cow", "level"); |
efc403bb AM |
317 | } |
318 | ||
319 | /** | |
320 | * Query but with the wrong State Value type | |
321 | * | |
322 | * @throws StateValueTypeException | |
323 | * @throws AttributeNotFoundException | |
324 | * @throws TimeRangeException | |
325 | */ | |
326 | @Test(expected = StateValueTypeException.class) | |
327 | public void testQueryInvalidValuetype1() throws StateValueTypeException, | |
328 | AttributeNotFoundException, TimeRangeException { | |
dad01d27 | 329 | List<ITmfStateInterval> list; |
efc403bb AM |
330 | ITmfStateInterval interval; |
331 | int quark; | |
332 | ||
d26f90fd AM |
333 | list = ssb.loadStateAtTime(interestingTimestamp1); |
334 | quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); | |
dad01d27 | 335 | interval = list.get(quark); |
2359ecca AM |
336 | |
337 | /* This is supposed to be an int value */ | |
338 | interval.getStateValue().unboxStr(); | |
efc403bb AM |
339 | } |
340 | ||
341 | @Test(expected = StateValueTypeException.class) | |
342 | public void testQueryInvalidValuetype2() throws StateValueTypeException, | |
343 | AttributeNotFoundException, TimeRangeException { | |
dad01d27 | 344 | List<ITmfStateInterval> list; |
efc403bb AM |
345 | ITmfStateInterval interval; |
346 | int quark; | |
347 | ||
d26f90fd AM |
348 | list = ssb.loadStateAtTime(interestingTimestamp1); |
349 | quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); | |
dad01d27 | 350 | interval = list.get(quark); |
2359ecca AM |
351 | |
352 | /* This is supposed to be a String value */ | |
353 | interval.getStateValue().unboxInt(); | |
efc403bb AM |
354 | } |
355 | ||
356 | @Test | |
357 | public void testFullAttributeName() throws AttributeNotFoundException { | |
d26f90fd AM |
358 | int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
359 | String name = ssb.getFullAttributePath(quark); | |
2359ecca | 360 | assertEquals(name, "CPUs/0/Current_thread"); |
efc403bb AM |
361 | } |
362 | ||
6abc2d88 AM |
363 | @Test |
364 | public void testGetQuarks_begin() { | |
d26f90fd | 365 | List<Integer> list = ssb.getQuarks("*", "1577", Attributes.EXEC_NAME); |
6abc2d88 AM |
366 | |
367 | assertEquals(1, list.size()); | |
6abc2d88 AM |
368 | } |
369 | ||
370 | @Test | |
371 | public void testGetQuarks_middle() { | |
d26f90fd | 372 | List<Integer> list = ssb.getQuarks(Attributes.THREADS, "*", Attributes.EXEC_NAME); |
6abc2d88 | 373 | |
1ba498e5 AM |
374 | /* Number of different kernel threads in the trace */ |
375 | assertEquals(168, list.size()); | |
6abc2d88 AM |
376 | } |
377 | ||
378 | @Test | |
379 | public void testGetQuarks_end() { | |
d26f90fd | 380 | List<Integer> list = ssb.getQuarks(Attributes.THREADS, "1577", "*"); |
6abc2d88 | 381 | |
1ba498e5 AM |
382 | /* There should be 4 sub-attributes for each Thread node */ |
383 | assertEquals(4, list.size()); | |
6abc2d88 | 384 | } |
efc403bb | 385 | } |