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