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; | |
18 | import java.io.FileNotFoundException; | |
19 | import java.io.IOException; | |
20 | import java.io.PrintWriter; | |
21 | import java.util.List; | |
22 | ||
23 | import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; | |
24 | import org.eclipse.linuxtools.tmf.core.statesystem.AttributeNotFoundException; | |
25 | import org.eclipse.linuxtools.tmf.core.statesystem.StateHistorySystem; | |
26 | import org.eclipse.linuxtools.tmf.core.statesystem.TimeRangeException; | |
27 | import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.HistoryTreeBackend; | |
28 | import org.eclipse.linuxtools.tmf.core.statesystem.helpers.HistoryBuilder; | |
29 | import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateChangeInput; | |
30 | import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateHistoryBackend; | |
31 | import org.eclipse.linuxtools.tmf.core.statevalue.StateValueTypeException; | |
dc0f7bfe | 32 | import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CtfKernelStateInput; |
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; | |
51 | static StateHistorySystem shs; | |
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(); | |
72 | shs = (StateHistorySystem) builder.getSS(); | |
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) ) { | |
82 | System.err.println("Error cleaning up during unit testing, " + | |
83 | "you might have leftovers state history files in /tmp"); | |
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... | |
90 | */ | |
91 | @Test | |
92 | public void testBuild() { | |
93 | HistoryBuilder zebuilder; | |
94 | IStateChangeInput zeinput; | |
95 | IStateHistoryBackend zehp; | |
96 | ||
97 | try { | |
dc0f7bfe | 98 | zeinput = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); |
efc403bb AM |
99 | zehp = new HistoryTreeBackend(stateFileBenchmark, |
100 | zeinput.getStartTime()); | |
101 | zebuilder = new HistoryBuilder(zeinput, zehp); | |
102 | zebuilder.run(); | |
103 | } catch (Exception e) { | |
104 | e.printStackTrace(); | |
105 | } | |
106 | } | |
107 | ||
108 | @Test | |
109 | public void testOpenExistingStateFile() { | |
110 | IStateHistoryBackend hp2 = null; | |
111 | StateHistorySystem shs2 = null; | |
112 | try { | |
113 | /* 'newStateFile' should have already been created */ | |
114 | hp2 = new HistoryTreeBackend(stateFile); | |
115 | shs2 = new StateHistorySystem(hp2, false); | |
116 | } catch (IOException e) { | |
117 | e.printStackTrace(); | |
118 | } | |
119 | assertTrue(shs2 != null); | |
120 | } | |
121 | ||
122 | @Test | |
123 | public void testFullQuery1() throws StateValueTypeException, | |
124 | AttributeNotFoundException, TimeRangeException { | |
125 | ||
dad01d27 | 126 | List<ITmfStateInterval> list; |
efc403bb | 127 | ITmfStateInterval interval; |
ae54340d | 128 | int quark, quark2, valueInt; |
efc403bb AM |
129 | String valueStr; |
130 | ||
dad01d27 | 131 | list = shs.loadStateAtTime(interestingTimestamp1); |
efc403bb AM |
132 | |
133 | quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
dad01d27 | 134 | interval = list.get(quark); |
efc403bb | 135 | valueInt = interval.getStateValue().unboxInt(); |
2359ecca | 136 | assertEquals(1397, valueInt); |
efc403bb | 137 | |
2359ecca | 138 | quark = shs.getQuarkAbsolute("Threads", "1432", "Exec_name"); |
dad01d27 | 139 | interval = list.get(quark); |
efc403bb | 140 | valueStr = interval.getStateValue().unboxStr(); |
2359ecca | 141 | assertEquals("gdbus", valueStr); |
efc403bb | 142 | |
ae54340d AM |
143 | /* Query a stack attribute, has to be done in two passes */ |
144 | quark = shs.getQuarkAbsolute("Threads", "1432", "Exec_mode_stack"); | |
ab9bc51b | 145 | interval = list.get(quark); |
ae54340d AM |
146 | valueInt = interval.getStateValue().unboxInt(); /* The stack depth */ |
147 | quark2 = shs.getQuarkRelative(quark, Integer.toString(valueInt)); | |
ab9bc51b | 148 | interval = list.get(quark2); |
ae54340d AM |
149 | valueStr = interval.getStateValue().unboxStr(); |
150 | assertTrue(valueStr.equals("sys_poll")); | |
efc403bb AM |
151 | } |
152 | ||
153 | @Test | |
154 | public void testFullQuery2() { | |
155 | // | |
156 | } | |
157 | ||
158 | @Test | |
159 | public void testFullQuery3() { | |
160 | // | |
161 | } | |
162 | ||
163 | @Test | |
164 | public void testSingleQuery1() throws AttributeNotFoundException, | |
165 | TimeRangeException, StateValueTypeException { | |
166 | ||
2359ecca | 167 | long timestamp = interestingTimestamp1; |
efc403bb AM |
168 | int quark; |
169 | ITmfStateInterval interval; | |
170 | String valueStr; | |
171 | ||
2359ecca | 172 | quark = shs.getQuarkAbsolute("Threads", "1432", "Exec_name"); |
efc403bb AM |
173 | interval = shs.querySingleState(timestamp, quark); |
174 | valueStr = interval.getStateValue().unboxStr(); | |
2359ecca | 175 | assertEquals("gdbus", valueStr); |
efc403bb AM |
176 | } |
177 | ||
178 | @Test | |
179 | public void testSingleQuery2() { | |
180 | // | |
181 | } | |
182 | ||
183 | @Test | |
184 | public void testSingleQuery3() { | |
185 | // | |
186 | } | |
187 | ||
ab9bc51b AM |
188 | /** |
189 | * Test a range query (with no resolution parameter, so all intervals) | |
190 | */ | |
efc403bb AM |
191 | @Test |
192 | public void testRangeQuery1() throws AttributeNotFoundException, | |
193 | TimeRangeException, StateValueTypeException { | |
194 | ||
2359ecca | 195 | long time1 = interestingTimestamp1; |
dc0f7bfe | 196 | long time2 = time1 + 1L * CtfTestFiles.NANOSECS_PER_SEC; |
efc403bb AM |
197 | int quark; |
198 | List<ITmfStateInterval> intervals; | |
199 | ||
200 | quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
201 | intervals = shs.queryHistoryRange(quark, time1, time2); | |
2359ecca AM |
202 | assertEquals(487, intervals.size()); /* Number of context switches! */ |
203 | assertEquals(1685, intervals.get(100).getStateValue().unboxInt()); | |
cc2292bd | 204 | assertEquals(1331668248427681372L, intervals.get(205).getEndTime()); |
efc403bb AM |
205 | } |
206 | ||
1d3d1293 AM |
207 | /** |
208 | * Range query, but with a t2 far off the end of the trace. | |
209 | * The result should still be valid. | |
210 | */ | |
211 | @Test | |
212 | public void testRangeQuery2() throws TimeRangeException, | |
213 | AttributeNotFoundException { | |
214 | ||
215 | List<ITmfStateInterval> intervals; | |
216 | ||
217 | int quark = shs.getQuarkAbsolute("CPUs", "0", "IRQ_stack"); | |
218 | long ts1 = shs.getHistoryBackend().getStartTime(); /* start of the trace */ | |
219 | long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid, but ignored */ | |
220 | ||
221 | intervals = shs.queryHistoryRange(quark, ts1, ts2); | |
222 | ||
223 | /* Nb of IRQs on CPU 0 during the whole trace */ | |
224 | assertEquals(1653, intervals.size()); | |
225 | } | |
226 | ||
ab9bc51b AM |
227 | /** |
228 | * Test a range query with a resolution | |
229 | */ | |
230 | @Test | |
1d3d1293 | 231 | public void testRangeQuery3() throws AttributeNotFoundException, |
ab9bc51b AM |
232 | TimeRangeException, StateValueTypeException { |
233 | ||
234 | long time1 = interestingTimestamp1; | |
dc0f7bfe | 235 | long time2 = time1 + 1L * CtfTestFiles.NANOSECS_PER_SEC; |
ab9bc51b AM |
236 | long resolution = 1000000; /* One query every millisecond */ |
237 | int quark; | |
238 | List<ITmfStateInterval> intervals; | |
239 | ||
240 | quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
241 | intervals = shs.queryHistoryRange(quark, time1, time2, resolution); | |
242 | assertEquals(129, intervals.size()); /* Number of context switches! */ | |
243 | assertEquals(1452, intervals.get(50).getStateValue().unboxInt()); | |
cc2292bd | 244 | assertEquals(1331668248784789238L, intervals.get(100).getEndTime()); |
ab9bc51b AM |
245 | } |
246 | ||
efc403bb AM |
247 | /** |
248 | * Ask for a time range outside of the trace's range | |
249 | * | |
250 | * @throws TimeRangeException | |
251 | */ | |
252 | @Test(expected = TimeRangeException.class) | |
253 | public void testFullQueryInvalidTime1() throws TimeRangeException { | |
dc0f7bfe | 254 | long ts = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; |
2359ecca | 255 | shs.loadStateAtTime(ts); |
efc403bb AM |
256 | |
257 | } | |
258 | ||
259 | @Test(expected = TimeRangeException.class) | |
260 | public void testFullQueryInvalidTime2() throws TimeRangeException { | |
dc0f7bfe | 261 | long ts = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; |
2359ecca | 262 | shs.loadStateAtTime(ts); |
efc403bb AM |
263 | |
264 | } | |
265 | ||
266 | @Test(expected = TimeRangeException.class) | |
267 | public void testSingleQueryInvalidTime1() | |
268 | throws AttributeNotFoundException, TimeRangeException { | |
269 | ||
270 | int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
dc0f7bfe | 271 | long ts = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; |
2359ecca | 272 | shs.querySingleState(ts, quark); |
efc403bb AM |
273 | } |
274 | ||
275 | @Test(expected = TimeRangeException.class) | |
276 | public void testSingleQueryInvalidTime2() | |
277 | throws AttributeNotFoundException, TimeRangeException { | |
278 | ||
279 | int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
dc0f7bfe | 280 | long ts = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; |
2359ecca | 281 | shs.querySingleState(ts, quark); |
efc403bb AM |
282 | } |
283 | ||
284 | @Test(expected = TimeRangeException.class) | |
285 | public void testRangeQueryInvalidTime1() throws AttributeNotFoundException, | |
286 | TimeRangeException { | |
287 | ||
288 | int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
dc0f7bfe AM |
289 | long ts1 = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ |
290 | long ts2 = CtfTestFiles.startTime + 1L * CtfTestFiles.NANOSECS_PER_SEC; /* valid */ | |
efc403bb | 291 | |
2359ecca | 292 | shs.queryHistoryRange(quark, ts1, ts2); |
efc403bb AM |
293 | } |
294 | ||
295 | @Test(expected = TimeRangeException.class) | |
296 | public void testRangeQueryInvalidTime2() throws TimeRangeException, | |
297 | AttributeNotFoundException { | |
298 | ||
efc403bb | 299 | int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); |
dc0f7bfe AM |
300 | long ts1 = CtfTestFiles.startTime - 1L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ |
301 | long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ | |
efc403bb | 302 | |
2359ecca | 303 | shs.queryHistoryRange(quark, ts1, ts2); |
efc403bb AM |
304 | } |
305 | ||
306 | /** | |
307 | * Ask for a non-existing attribute | |
308 | * | |
309 | * @throws AttributeNotFoundException | |
310 | */ | |
311 | @Test(expected = AttributeNotFoundException.class) | |
312 | public void testQueryInvalidAttribute() throws AttributeNotFoundException { | |
313 | ||
314 | shs.getQuarkAbsolute("There", "is", "no", "cow", "level"); | |
315 | } | |
316 | ||
317 | /** | |
318 | * Query but with the wrong State Value type | |
319 | * | |
320 | * @throws StateValueTypeException | |
321 | * @throws AttributeNotFoundException | |
322 | * @throws TimeRangeException | |
323 | */ | |
324 | @Test(expected = StateValueTypeException.class) | |
325 | public void testQueryInvalidValuetype1() throws StateValueTypeException, | |
326 | AttributeNotFoundException, TimeRangeException { | |
dad01d27 | 327 | List<ITmfStateInterval> list; |
efc403bb AM |
328 | ITmfStateInterval interval; |
329 | int quark; | |
330 | ||
dad01d27 | 331 | list = shs.loadStateAtTime(interestingTimestamp1); |
efc403bb | 332 | quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); |
dad01d27 | 333 | interval = list.get(quark); |
2359ecca AM |
334 | |
335 | /* This is supposed to be an int value */ | |
336 | interval.getStateValue().unboxStr(); | |
efc403bb AM |
337 | } |
338 | ||
339 | @Test(expected = StateValueTypeException.class) | |
340 | public void testQueryInvalidValuetype2() throws StateValueTypeException, | |
341 | AttributeNotFoundException, TimeRangeException { | |
dad01d27 | 342 | List<ITmfStateInterval> list; |
efc403bb AM |
343 | ITmfStateInterval interval; |
344 | int quark; | |
345 | ||
dad01d27 | 346 | list = shs.loadStateAtTime(interestingTimestamp1); |
2359ecca | 347 | quark = shs.getQuarkAbsolute("Threads", "1432", "Exec_name"); |
dad01d27 | 348 | interval = list.get(quark); |
2359ecca AM |
349 | |
350 | /* This is supposed to be a String value */ | |
351 | interval.getStateValue().unboxInt(); | |
efc403bb AM |
352 | } |
353 | ||
354 | @Test | |
355 | public void testFullAttributeName() throws AttributeNotFoundException { | |
356 | int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread"); | |
357 | String name = shs.getFullAttributePath(quark); | |
2359ecca | 358 | assertEquals(name, "CPUs/0/Current_thread"); |
efc403bb AM |
359 | } |
360 | ||
6abc2d88 AM |
361 | @Test |
362 | public void testGetQuarks_begin() { | |
363 | List<Integer> list = shs.getQuarks("*", "1577", "Exec_name"); | |
364 | ||
365 | assertEquals(1, list.size()); | |
366 | assertEquals(Integer.valueOf(479), list.get(0)); | |
367 | } | |
368 | ||
369 | @Test | |
370 | public void testGetQuarks_middle() { | |
371 | List<Integer> list = shs.getQuarks("Threads", "*", "Exec_name"); | |
372 | ||
373 | assertEquals(Integer.valueOf(36), list.get(4)); | |
374 | assertEquals(Integer.valueOf(100), list.get(10)); | |
375 | assertEquals(Integer.valueOf(116), list.get(12)); | |
376 | } | |
377 | ||
378 | @Test | |
379 | public void testGetQuarks_end() { | |
380 | List<Integer> list = shs.getQuarks("Threads", "1577", "*"); | |
381 | ||
382 | assertEquals(3, list.size()); | |
383 | assertEquals(Integer.valueOf(479), list.get(1)); | |
384 | } | |
385 | ||
efc403bb AM |
386 | @Test |
387 | public void testDebugPrinting() throws FileNotFoundException { | |
6f04204e AM |
388 | PrintWriter pw = new PrintWriter(new File("/dev/null")); |
389 | shs.debugPrint(pw); | |
390 | pw.close(); | |
efc403bb AM |
391 | } |
392 | } |