Commit | Line | Data |
---|---|---|
f9a76cac | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2012, 2015 Ericsson |
f9a76cac AM |
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 | ||
42d5b5f2 | 13 | package org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.kernel.statesystem; |
f9a76cac AM |
14 | |
15 | import static org.junit.Assert.assertEquals; | |
edbdb7ea | 16 | import static org.junit.Assert.assertNotNull; |
c4d139aa | 17 | import static org.junit.Assert.fail; |
58ba027e | 18 | import static org.junit.Assume.assumeTrue; |
f9a76cac AM |
19 | |
20 | import java.util.List; | |
21 | ||
e363eae1 | 22 | import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes; |
e894a508 | 23 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; |
1dd75589 | 24 | import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; |
e894a508 AM |
25 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; |
26 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
27 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; | |
28 | import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; | |
29 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; | |
30 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; | |
2bdf0193 | 31 | import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace; |
edbdb7ea AM |
32 | import org.junit.Before; |
33 | import org.junit.Rule; | |
f9a76cac | 34 | import org.junit.Test; |
edbdb7ea AM |
35 | import org.junit.rules.TestRule; |
36 | import org.junit.rules.Timeout; | |
f9a76cac AM |
37 | |
38 | /** | |
39 | * Base unit tests for the StateHistorySystem. Extension can be made to test | |
40 | * different state back-end types or configurations. | |
41 | * | |
42 | * @author Alexandre Montplaisir | |
f9a76cac | 43 | */ |
4e0b52e0 | 44 | @SuppressWarnings("javadoc") |
f9a76cac AM |
45 | public abstract class StateSystemTest { |
46 | ||
edbdb7ea AM |
47 | /** Timeout the tests after 2 minutes */ |
48 | @Rule | |
49 | public TestRule timeoutRule = new Timeout(120000); | |
50 | ||
9ac63b5b AM |
51 | /** Test trace used for these tests */ |
52 | protected static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.TRACE2; | |
92ba8466 AM |
53 | |
54 | /** Expected start time of the test trace/state history */ | |
55 | protected static final long startTime = 1331668247314038062L; | |
56 | ||
57 | /** Expected end time of the state history built from the test trace */ | |
58 | protected static final long endTime = 1331668259054285979L; | |
59 | ||
edbdb7ea AM |
60 | /** Offset in the trace + start time of the trace */ |
61 | protected static final long interestingTimestamp1 = 18670067372290L + 1331649577946812237L; | |
62 | ||
92ba8466 AM |
63 | /** Number of nanoseconds in one second */ |
64 | private static final long NANOSECS_PER_SEC = 1000000000L; | |
65 | ||
392bf486 AM |
66 | protected static ITmfStateSystem fixture; |
67 | protected static boolean traceIsPresent = false; | |
f9a76cac | 68 | |
58ba027e | 69 | /** |
392bf486 | 70 | * Test set-up |
58ba027e | 71 | */ |
edbdb7ea AM |
72 | @Before |
73 | public void setUp() { | |
392bf486 AM |
74 | assumeTrue(traceIsPresent); |
75 | /* Subclasses should set-up 'fixture' */ | |
edbdb7ea AM |
76 | assertNotNull(fixture); |
77 | } | |
78 | ||
f9a76cac | 79 | @Test |
c4d139aa | 80 | public void testFullQuery1() { |
f9a76cac AM |
81 | List<ITmfStateInterval> list; |
82 | ITmfStateInterval interval; | |
83 | int quark, valueInt; | |
84 | String valueStr; | |
85 | ||
c4d139aa | 86 | try { |
edbdb7ea | 87 | list = fixture.queryFullState(interestingTimestamp1); |
c4d139aa | 88 | |
edbdb7ea | 89 | quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa AM |
90 | interval = list.get(quark); |
91 | valueInt = interval.getStateValue().unboxInt(); | |
92 | assertEquals(1397, valueInt); | |
93 | ||
edbdb7ea | 94 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); |
c4d139aa AM |
95 | interval = list.get(quark); |
96 | valueStr = interval.getStateValue().unboxStr(); | |
97 | assertEquals("gdbus", valueStr); | |
98 | ||
edbdb7ea | 99 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.SYSTEM_CALL); |
c4d139aa AM |
100 | interval = list.get(quark); |
101 | valueStr = interval.getStateValue().unboxStr(); | |
7411cd67 | 102 | assertEquals("sys_poll", valueStr); |
c4d139aa | 103 | |
edbdb7ea | 104 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
105 | fail(); |
106 | } | |
f9a76cac AM |
107 | } |
108 | ||
109 | @Test | |
c4d139aa | 110 | public void testSingleQuery1() { |
f9a76cac AM |
111 | long timestamp = interestingTimestamp1; |
112 | int quark; | |
113 | ITmfStateInterval interval; | |
114 | String valueStr; | |
115 | ||
c4d139aa | 116 | try { |
edbdb7ea AM |
117 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); |
118 | interval = fixture.querySingleState(timestamp, quark); | |
c4d139aa AM |
119 | valueStr = interval.getStateValue().unboxStr(); |
120 | assertEquals("gdbus", valueStr); | |
121 | ||
edbdb7ea | 122 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
123 | fail(); |
124 | } | |
f9a76cac AM |
125 | } |
126 | ||
127 | /** | |
128 | * Test a range query (with no resolution parameter, so all intervals) | |
129 | */ | |
130 | @Test | |
c4d139aa | 131 | public void testRangeQuery1() { |
f9a76cac | 132 | long time1 = interestingTimestamp1; |
92ba8466 | 133 | long time2 = time1 + 1L * NANOSECS_PER_SEC; |
f9a76cac AM |
134 | int quark; |
135 | List<ITmfStateInterval> intervals; | |
136 | ||
1dd75589 AM |
137 | final ITmfStateSystem ss = fixture; |
138 | assertNotNull(ss); | |
139 | ||
c4d139aa | 140 | try { |
1dd75589 AM |
141 | quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
142 | intervals = StateSystemUtils.queryHistoryRange(ss, quark, time1, time2); | |
c4d139aa AM |
143 | assertEquals(487, intervals.size()); /* Number of context switches! */ |
144 | assertEquals(1685, intervals.get(100).getStateValue().unboxInt()); | |
145 | assertEquals(1331668248427681372L, intervals.get(205).getEndTime()); | |
146 | ||
edbdb7ea | 147 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
148 | fail(); |
149 | } | |
f9a76cac AM |
150 | } |
151 | ||
152 | /** | |
b9f6183a AM |
153 | * Range query, but with a t2 far off the end of the trace. The result |
154 | * should still be valid. | |
f9a76cac AM |
155 | */ |
156 | @Test | |
c4d139aa | 157 | public void testRangeQuery2() { |
f9a76cac AM |
158 | List<ITmfStateInterval> intervals; |
159 | ||
1dd75589 AM |
160 | final ITmfStateSystem ss = fixture; |
161 | assertNotNull(ss); | |
162 | ||
c4d139aa | 163 | try { |
1dd75589 AM |
164 | int quark = ss.getQuarkAbsolute(Attributes.RESOURCES, Attributes.IRQS, "1"); |
165 | long ts1 = ss.getStartTime(); /* start of the trace */ | |
c4d139aa AM |
166 | long ts2 = startTime + 20L * NANOSECS_PER_SEC; /* invalid, but ignored */ |
167 | ||
1dd75589 | 168 | intervals = StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); |
f9a76cac | 169 | |
c4d139aa AM |
170 | /* Activity of IRQ 1 over the whole trace */ |
171 | assertEquals(65, intervals.size()); | |
f9a76cac | 172 | |
edbdb7ea | 173 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
174 | fail(); |
175 | } | |
f9a76cac AM |
176 | } |
177 | ||
178 | /** | |
179 | * Test a range query with a resolution | |
180 | */ | |
181 | @Test | |
c4d139aa | 182 | public void testRangeQuery3() { |
f9a76cac | 183 | long time1 = interestingTimestamp1; |
92ba8466 | 184 | long time2 = time1 + 1L * NANOSECS_PER_SEC; |
f9a76cac AM |
185 | long resolution = 1000000; /* One query every millisecond */ |
186 | int quark; | |
187 | List<ITmfStateInterval> intervals; | |
188 | ||
1dd75589 AM |
189 | final ITmfStateSystem ss = fixture; |
190 | assertNotNull(ss); | |
191 | ||
c4d139aa | 192 | try { |
1dd75589 AM |
193 | quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
194 | intervals = StateSystemUtils.queryHistoryRange(ss, quark, time1, time2, resolution, null); | |
c4d139aa AM |
195 | assertEquals(126, intervals.size()); /* Number of context switches! */ |
196 | assertEquals(1452, intervals.get(50).getStateValue().unboxInt()); | |
197 | assertEquals(1331668248815698779L, intervals.get(100).getEndTime()); | |
198 | ||
edbdb7ea | 199 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
200 | fail(); |
201 | } | |
f9a76cac AM |
202 | } |
203 | ||
204 | /** | |
205 | * Ask for a time range outside of the trace's range | |
206 | */ | |
207 | @Test(expected = TimeRangeException.class) | |
208 | public void testFullQueryInvalidTime1() throws TimeRangeException, | |
209 | StateSystemDisposedException { | |
92ba8466 | 210 | long ts = startTime + 20L * NANOSECS_PER_SEC; |
edbdb7ea | 211 | fixture.queryFullState(ts); |
f9a76cac AM |
212 | } |
213 | ||
214 | @Test(expected = TimeRangeException.class) | |
215 | public void testFullQueryInvalidTime2() throws TimeRangeException, | |
216 | StateSystemDisposedException { | |
92ba8466 | 217 | long ts = startTime - 20L * NANOSECS_PER_SEC; |
edbdb7ea | 218 | fixture.queryFullState(ts); |
f9a76cac AM |
219 | } |
220 | ||
221 | @Test(expected = TimeRangeException.class) | |
c4d139aa AM |
222 | public void testSingleQueryInvalidTime1() throws TimeRangeException { |
223 | try { | |
edbdb7ea | 224 | int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa | 225 | long ts = startTime + 20L * NANOSECS_PER_SEC; |
edbdb7ea | 226 | fixture.querySingleState(ts, quark); |
c4d139aa | 227 | |
edbdb7ea | 228 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
229 | fail(); |
230 | } | |
f9a76cac AM |
231 | } |
232 | ||
233 | @Test(expected = TimeRangeException.class) | |
c4d139aa AM |
234 | public void testSingleQueryInvalidTime2() throws TimeRangeException { |
235 | try { | |
edbdb7ea | 236 | int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa | 237 | long ts = startTime - 20L * NANOSECS_PER_SEC; |
edbdb7ea | 238 | fixture.querySingleState(ts, quark); |
c4d139aa | 239 | |
edbdb7ea | 240 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
241 | fail(); |
242 | } | |
f9a76cac AM |
243 | } |
244 | ||
245 | @Test(expected = TimeRangeException.class) | |
c4d139aa | 246 | public void testRangeQueryInvalidTime1() throws TimeRangeException { |
1dd75589 AM |
247 | final ITmfStateSystem ss = fixture; |
248 | assertNotNull(ss); | |
249 | ||
c4d139aa | 250 | try { |
1dd75589 | 251 | int quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa AM |
252 | long ts1 = startTime - 20L * NANOSECS_PER_SEC; /* invalid */ |
253 | long ts2 = startTime + 1L * NANOSECS_PER_SEC; /* valid */ | |
1dd75589 | 254 | StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); |
c4d139aa AM |
255 | |
256 | } catch (AttributeNotFoundException e) { | |
257 | fail(); | |
258 | } catch (StateSystemDisposedException e) { | |
259 | fail(); | |
260 | } | |
f9a76cac AM |
261 | } |
262 | ||
263 | @Test(expected = TimeRangeException.class) | |
c4d139aa | 264 | public void testRangeQueryInvalidTime2() throws TimeRangeException { |
1dd75589 AM |
265 | final ITmfStateSystem ss = fixture; |
266 | assertNotNull(ss); | |
267 | ||
c4d139aa | 268 | try { |
1dd75589 | 269 | int quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa AM |
270 | long ts1 = startTime - 1L * NANOSECS_PER_SEC; /* invalid */ |
271 | long ts2 = startTime + 20L * NANOSECS_PER_SEC; /* invalid */ | |
1dd75589 | 272 | StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); |
c4d139aa | 273 | |
edbdb7ea | 274 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
275 | fail(); |
276 | } | |
f9a76cac AM |
277 | } |
278 | ||
279 | /** | |
280 | * Ask for a non-existing attribute | |
281 | * | |
282 | * @throws AttributeNotFoundException | |
283 | */ | |
284 | @Test(expected = AttributeNotFoundException.class) | |
285 | public void testQueryInvalidAttribute() throws AttributeNotFoundException { | |
edbdb7ea | 286 | fixture.getQuarkAbsolute("There", "is", "no", "cow", "level"); |
f9a76cac AM |
287 | } |
288 | ||
289 | /** | |
290 | * Query but with the wrong State Value type | |
291 | */ | |
292 | @Test(expected = StateValueTypeException.class) | |
c4d139aa | 293 | public void testQueryInvalidValuetype1() throws StateValueTypeException { |
f9a76cac AM |
294 | List<ITmfStateInterval> list; |
295 | ITmfStateInterval interval; | |
296 | int quark; | |
297 | ||
c4d139aa | 298 | try { |
edbdb7ea AM |
299 | list = fixture.queryFullState(interestingTimestamp1); |
300 | quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); | |
c4d139aa AM |
301 | interval = list.get(quark); |
302 | ||
303 | /* This is supposed to be an int value */ | |
304 | interval.getStateValue().unboxStr(); | |
305 | ||
edbdb7ea | 306 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
307 | fail(); |
308 | } | |
f9a76cac AM |
309 | } |
310 | ||
311 | @Test(expected = StateValueTypeException.class) | |
c4d139aa | 312 | public void testQueryInvalidValuetype2() throws StateValueTypeException { |
f9a76cac AM |
313 | List<ITmfStateInterval> list; |
314 | ITmfStateInterval interval; | |
315 | int quark; | |
316 | ||
c4d139aa | 317 | try { |
edbdb7ea AM |
318 | list = fixture.queryFullState(interestingTimestamp1); |
319 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); | |
c4d139aa AM |
320 | interval = list.get(quark); |
321 | ||
322 | /* This is supposed to be a String value */ | |
323 | interval.getStateValue().unboxInt(); | |
324 | ||
edbdb7ea | 325 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
326 | fail(); |
327 | } | |
f9a76cac AM |
328 | } |
329 | ||
330 | @Test | |
c4d139aa AM |
331 | public void testFullAttributeName() { |
332 | try { | |
edbdb7ea AM |
333 | int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
334 | String name = fixture.getFullAttributePath(quark); | |
c4d139aa AM |
335 | assertEquals(name, "CPUs/0/Current_thread"); |
336 | ||
337 | } catch (AttributeNotFoundException e) { | |
338 | fail(); | |
339 | } | |
f9a76cac AM |
340 | } |
341 | ||
342 | @Test | |
343 | public void testGetQuarks_begin() { | |
edbdb7ea | 344 | List<Integer> list = fixture.getQuarks("*", "1577", Attributes.EXEC_NAME); |
f9a76cac AM |
345 | |
346 | assertEquals(1, list.size()); | |
347 | } | |
348 | ||
349 | @Test | |
350 | public void testGetQuarks_middle() { | |
edbdb7ea | 351 | List<Integer> list = fixture.getQuarks(Attributes.THREADS, "*", Attributes.EXEC_NAME); |
f9a76cac AM |
352 | |
353 | /* Number of different kernel threads in the trace */ | |
354 | assertEquals(168, list.size()); | |
355 | } | |
356 | ||
357 | @Test | |
358 | public void testGetQuarks_end() { | |
edbdb7ea | 359 | List<Integer> list = fixture.getQuarks(Attributes.THREADS, "1577", "*"); |
f9a76cac AM |
360 | |
361 | /* There should be 4 sub-attributes for each Thread node */ | |
362 | assertEquals(4, list.size()); | |
363 | } | |
b33f7554 AM |
364 | |
365 | // ------------------------------------------------------------------------ | |
366 | // Tests verifying the *complete* results of a full queries | |
367 | // ------------------------------------------------------------------------ | |
368 | ||
369 | protected long getStartTimes(int idx) { | |
370 | return TestValues.startTimes[idx]; | |
371 | } | |
372 | ||
373 | protected long getEndTimes(int idx) { | |
374 | return TestValues.endTimes[idx]; | |
375 | } | |
376 | ||
377 | protected ITmfStateValue getStateValues(int idx) { | |
378 | return TestValues.values[idx]; | |
379 | } | |
380 | ||
381 | @Test | |
382 | public void testFullQueryThorough() { | |
383 | try { | |
edbdb7ea | 384 | List<ITmfStateInterval> state = fixture.queryFullState(interestingTimestamp1); |
b33f7554 AM |
385 | assertEquals(TestValues.size, state.size()); |
386 | ||
387 | for (int i = 0; i < state.size(); i++) { | |
388 | /* Test each component of the intervals */ | |
389 | assertEquals(getStartTimes(i), state.get(i).getStartTime()); | |
390 | assertEquals(getEndTimes(i), state.get(i).getEndTime()); | |
391 | assertEquals(i, state.get(i).getAttribute()); | |
392 | assertEquals(getStateValues(i), state.get(i).getStateValue()); | |
393 | } | |
394 | ||
b33f7554 AM |
395 | } catch (StateSystemDisposedException e) { |
396 | fail(); | |
397 | } | |
398 | } | |
b9f6183a AM |
399 | |
400 | @Test | |
401 | public void testFirstIntervalIsConsidered() { | |
402 | try { | |
edbdb7ea | 403 | List<ITmfStateInterval> list = fixture.queryFullState(1331668248014135800L); |
b9f6183a AM |
404 | ITmfStateInterval interval = list.get(233); |
405 | assertEquals(1331668247516664825L, interval.getStartTime()); | |
406 | ||
407 | int valueInt = interval.getStateValue().unboxInt(); | |
408 | assertEquals(1, valueInt); | |
edbdb7ea | 409 | |
b9f6183a AM |
410 | } catch (StateSystemDisposedException e) { |
411 | fail(); | |
b9f6183a AM |
412 | } |
413 | } | |
0fdd2c45 FG |
414 | |
415 | @Test | |
416 | public void testParentAttribute() { | |
417 | String[] path = { "CPUs/0/Current_thread", | |
418 | "CPUs/0", | |
419 | "CPUs" }; | |
420 | try { | |
edbdb7ea | 421 | int q = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
0fdd2c45 | 422 | for (int i = 0; i < path.length; i++) { |
edbdb7ea | 423 | String name = fixture.getFullAttributePath(q); |
0fdd2c45 | 424 | assertEquals(path[i], name); |
edbdb7ea | 425 | q = fixture.getParentAttributeQuark(q); |
0fdd2c45 FG |
426 | } |
427 | assertEquals(-1, q); | |
edbdb7ea | 428 | q = fixture.getParentAttributeQuark(q); |
0fdd2c45 FG |
429 | assertEquals(-1, q); |
430 | } catch (AttributeNotFoundException e) { | |
431 | fail(); | |
432 | } | |
433 | } | |
434 | ||
f9a76cac | 435 | } |