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; |
f9a76cac AM |
18 | |
19 | import java.util.List; | |
d291a715 | 20 | import java.util.concurrent.TimeUnit; |
f9a76cac | 21 | |
c4d57ac1 | 22 | import org.eclipse.jdt.annotation.NonNull; |
e363eae1 | 23 | import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes; |
e894a508 | 24 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; |
1dd75589 | 25 | import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; |
e894a508 AM |
26 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; |
27 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
28 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; | |
29 | import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; | |
30 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; | |
31 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; | |
c4d57ac1 | 32 | import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace; |
edbdb7ea AM |
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 | |
d291a715 | 50 | public TestRule timeoutRule = new Timeout(2, TimeUnit.MINUTES); |
edbdb7ea | 51 | |
9ac63b5b | 52 | /** Test trace used for these tests */ |
c4d57ac1 | 53 | protected static final @NonNull CtfTestTrace testTrace = CtfTestTrace.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 | ||
392bf486 | 67 | protected static ITmfStateSystem fixture; |
f9a76cac | 68 | |
58ba027e | 69 | /** |
392bf486 | 70 | * Test set-up |
58ba027e | 71 | */ |
edbdb7ea AM |
72 | @Before |
73 | public void setUp() { | |
392bf486 | 74 | /* Subclasses should set-up 'fixture' */ |
edbdb7ea AM |
75 | assertNotNull(fixture); |
76 | } | |
77 | ||
f9a76cac | 78 | @Test |
c4d139aa | 79 | public void testFullQuery1() { |
f9a76cac AM |
80 | List<ITmfStateInterval> list; |
81 | ITmfStateInterval interval; | |
82 | int quark, valueInt; | |
83 | String valueStr; | |
84 | ||
c4d139aa | 85 | try { |
edbdb7ea | 86 | list = fixture.queryFullState(interestingTimestamp1); |
c4d139aa | 87 | |
edbdb7ea | 88 | quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa AM |
89 | interval = list.get(quark); |
90 | valueInt = interval.getStateValue().unboxInt(); | |
91 | assertEquals(1397, valueInt); | |
92 | ||
edbdb7ea | 93 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); |
c4d139aa AM |
94 | interval = list.get(quark); |
95 | valueStr = interval.getStateValue().unboxStr(); | |
96 | assertEquals("gdbus", valueStr); | |
97 | ||
edbdb7ea | 98 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.SYSTEM_CALL); |
c4d139aa AM |
99 | interval = list.get(quark); |
100 | valueStr = interval.getStateValue().unboxStr(); | |
7411cd67 | 101 | assertEquals("sys_poll", valueStr); |
c4d139aa | 102 | |
edbdb7ea | 103 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
104 | fail(); |
105 | } | |
f9a76cac AM |
106 | } |
107 | ||
108 | @Test | |
c4d139aa | 109 | public void testSingleQuery1() { |
f9a76cac AM |
110 | long timestamp = interestingTimestamp1; |
111 | int quark; | |
112 | ITmfStateInterval interval; | |
113 | String valueStr; | |
114 | ||
c4d139aa | 115 | try { |
edbdb7ea AM |
116 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); |
117 | interval = fixture.querySingleState(timestamp, quark); | |
c4d139aa AM |
118 | valueStr = interval.getStateValue().unboxStr(); |
119 | assertEquals("gdbus", valueStr); | |
120 | ||
edbdb7ea | 121 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
122 | fail(); |
123 | } | |
f9a76cac AM |
124 | } |
125 | ||
126 | /** | |
127 | * Test a range query (with no resolution parameter, so all intervals) | |
128 | */ | |
129 | @Test | |
c4d139aa | 130 | public void testRangeQuery1() { |
f9a76cac | 131 | long time1 = interestingTimestamp1; |
92ba8466 | 132 | long time2 = time1 + 1L * NANOSECS_PER_SEC; |
f9a76cac AM |
133 | int quark; |
134 | List<ITmfStateInterval> intervals; | |
135 | ||
1dd75589 AM |
136 | final ITmfStateSystem ss = fixture; |
137 | assertNotNull(ss); | |
138 | ||
c4d139aa | 139 | try { |
1dd75589 AM |
140 | quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
141 | intervals = StateSystemUtils.queryHistoryRange(ss, quark, time1, time2); | |
c4d139aa AM |
142 | assertEquals(487, intervals.size()); /* Number of context switches! */ |
143 | assertEquals(1685, intervals.get(100).getStateValue().unboxInt()); | |
144 | assertEquals(1331668248427681372L, intervals.get(205).getEndTime()); | |
145 | ||
edbdb7ea | 146 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
147 | fail(); |
148 | } | |
f9a76cac AM |
149 | } |
150 | ||
151 | /** | |
b9f6183a AM |
152 | * Range query, but with a t2 far off the end of the trace. The result |
153 | * should still be valid. | |
f9a76cac AM |
154 | */ |
155 | @Test | |
c4d139aa | 156 | public void testRangeQuery2() { |
f9a76cac AM |
157 | List<ITmfStateInterval> intervals; |
158 | ||
1dd75589 AM |
159 | final ITmfStateSystem ss = fixture; |
160 | assertNotNull(ss); | |
161 | ||
c4d139aa | 162 | try { |
1dd75589 AM |
163 | int quark = ss.getQuarkAbsolute(Attributes.RESOURCES, Attributes.IRQS, "1"); |
164 | long ts1 = ss.getStartTime(); /* start of the trace */ | |
c4d139aa AM |
165 | long ts2 = startTime + 20L * NANOSECS_PER_SEC; /* invalid, but ignored */ |
166 | ||
1dd75589 | 167 | intervals = StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); |
f9a76cac | 168 | |
c4d139aa AM |
169 | /* Activity of IRQ 1 over the whole trace */ |
170 | assertEquals(65, intervals.size()); | |
f9a76cac | 171 | |
edbdb7ea | 172 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
173 | fail(); |
174 | } | |
f9a76cac AM |
175 | } |
176 | ||
177 | /** | |
178 | * Test a range query with a resolution | |
179 | */ | |
180 | @Test | |
c4d139aa | 181 | public void testRangeQuery3() { |
f9a76cac | 182 | long time1 = interestingTimestamp1; |
92ba8466 | 183 | long time2 = time1 + 1L * NANOSECS_PER_SEC; |
f9a76cac AM |
184 | long resolution = 1000000; /* One query every millisecond */ |
185 | int quark; | |
186 | List<ITmfStateInterval> intervals; | |
187 | ||
1dd75589 AM |
188 | final ITmfStateSystem ss = fixture; |
189 | assertNotNull(ss); | |
190 | ||
c4d139aa | 191 | try { |
1dd75589 AM |
192 | quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
193 | intervals = StateSystemUtils.queryHistoryRange(ss, quark, time1, time2, resolution, null); | |
c4d139aa AM |
194 | assertEquals(126, intervals.size()); /* Number of context switches! */ |
195 | assertEquals(1452, intervals.get(50).getStateValue().unboxInt()); | |
196 | assertEquals(1331668248815698779L, intervals.get(100).getEndTime()); | |
197 | ||
edbdb7ea | 198 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
199 | fail(); |
200 | } | |
f9a76cac AM |
201 | } |
202 | ||
203 | /** | |
204 | * Ask for a time range outside of the trace's range | |
205 | */ | |
206 | @Test(expected = TimeRangeException.class) | |
207 | public void testFullQueryInvalidTime1() throws TimeRangeException, | |
208 | StateSystemDisposedException { | |
92ba8466 | 209 | long ts = startTime + 20L * NANOSECS_PER_SEC; |
edbdb7ea | 210 | fixture.queryFullState(ts); |
f9a76cac AM |
211 | } |
212 | ||
213 | @Test(expected = TimeRangeException.class) | |
214 | public void testFullQueryInvalidTime2() throws TimeRangeException, | |
215 | StateSystemDisposedException { | |
92ba8466 | 216 | long ts = startTime - 20L * NANOSECS_PER_SEC; |
edbdb7ea | 217 | fixture.queryFullState(ts); |
f9a76cac AM |
218 | } |
219 | ||
220 | @Test(expected = TimeRangeException.class) | |
c4d139aa AM |
221 | public void testSingleQueryInvalidTime1() throws TimeRangeException { |
222 | try { | |
edbdb7ea | 223 | int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa | 224 | long ts = startTime + 20L * NANOSECS_PER_SEC; |
edbdb7ea | 225 | fixture.querySingleState(ts, quark); |
c4d139aa | 226 | |
edbdb7ea | 227 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
228 | fail(); |
229 | } | |
f9a76cac AM |
230 | } |
231 | ||
232 | @Test(expected = TimeRangeException.class) | |
c4d139aa AM |
233 | public void testSingleQueryInvalidTime2() throws TimeRangeException { |
234 | try { | |
edbdb7ea | 235 | int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa | 236 | long ts = startTime - 20L * NANOSECS_PER_SEC; |
edbdb7ea | 237 | fixture.querySingleState(ts, quark); |
c4d139aa | 238 | |
edbdb7ea | 239 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
240 | fail(); |
241 | } | |
f9a76cac AM |
242 | } |
243 | ||
244 | @Test(expected = TimeRangeException.class) | |
c4d139aa | 245 | public void testRangeQueryInvalidTime1() throws TimeRangeException { |
1dd75589 AM |
246 | final ITmfStateSystem ss = fixture; |
247 | assertNotNull(ss); | |
248 | ||
c4d139aa | 249 | try { |
1dd75589 | 250 | int quark = ss.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 */ | |
1dd75589 | 253 | StateSystemUtils.queryHistoryRange(ss, 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 | 263 | public void testRangeQueryInvalidTime2() throws TimeRangeException { |
1dd75589 AM |
264 | final ITmfStateSystem ss = fixture; |
265 | assertNotNull(ss); | |
266 | ||
c4d139aa | 267 | try { |
1dd75589 | 268 | int quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
c4d139aa AM |
269 | long ts1 = startTime - 1L * NANOSECS_PER_SEC; /* invalid */ |
270 | long ts2 = startTime + 20L * NANOSECS_PER_SEC; /* invalid */ | |
1dd75589 | 271 | StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); |
c4d139aa | 272 | |
edbdb7ea | 273 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
274 | fail(); |
275 | } | |
f9a76cac AM |
276 | } |
277 | ||
278 | /** | |
279 | * Ask for a non-existing attribute | |
280 | * | |
281 | * @throws AttributeNotFoundException | |
282 | */ | |
283 | @Test(expected = AttributeNotFoundException.class) | |
284 | public void testQueryInvalidAttribute() throws AttributeNotFoundException { | |
edbdb7ea | 285 | fixture.getQuarkAbsolute("There", "is", "no", "cow", "level"); |
f9a76cac AM |
286 | } |
287 | ||
288 | /** | |
289 | * Query but with the wrong State Value type | |
290 | */ | |
291 | @Test(expected = StateValueTypeException.class) | |
c4d139aa | 292 | public void testQueryInvalidValuetype1() throws StateValueTypeException { |
f9a76cac AM |
293 | List<ITmfStateInterval> list; |
294 | ITmfStateInterval interval; | |
295 | int quark; | |
296 | ||
c4d139aa | 297 | try { |
edbdb7ea AM |
298 | list = fixture.queryFullState(interestingTimestamp1); |
299 | quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); | |
c4d139aa AM |
300 | interval = list.get(quark); |
301 | ||
302 | /* This is supposed to be an int value */ | |
303 | interval.getStateValue().unboxStr(); | |
304 | ||
edbdb7ea | 305 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
306 | fail(); |
307 | } | |
f9a76cac AM |
308 | } |
309 | ||
310 | @Test(expected = StateValueTypeException.class) | |
c4d139aa | 311 | public void testQueryInvalidValuetype2() throws StateValueTypeException { |
f9a76cac AM |
312 | List<ITmfStateInterval> list; |
313 | ITmfStateInterval interval; | |
314 | int quark; | |
315 | ||
c4d139aa | 316 | try { |
edbdb7ea AM |
317 | list = fixture.queryFullState(interestingTimestamp1); |
318 | quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); | |
c4d139aa AM |
319 | interval = list.get(quark); |
320 | ||
321 | /* This is supposed to be a String value */ | |
322 | interval.getStateValue().unboxInt(); | |
323 | ||
edbdb7ea | 324 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { |
c4d139aa AM |
325 | fail(); |
326 | } | |
f9a76cac AM |
327 | } |
328 | ||
329 | @Test | |
c4d139aa AM |
330 | public void testFullAttributeName() { |
331 | try { | |
edbdb7ea AM |
332 | int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); |
333 | String name = fixture.getFullAttributePath(quark); | |
c4d139aa AM |
334 | assertEquals(name, "CPUs/0/Current_thread"); |
335 | ||
336 | } catch (AttributeNotFoundException e) { | |
337 | fail(); | |
338 | } | |
f9a76cac AM |
339 | } |
340 | ||
341 | @Test | |
342 | public void testGetQuarks_begin() { | |
edbdb7ea | 343 | List<Integer> list = fixture.getQuarks("*", "1577", Attributes.EXEC_NAME); |
f9a76cac AM |
344 | |
345 | assertEquals(1, list.size()); | |
346 | } | |
347 | ||
348 | @Test | |
349 | public void testGetQuarks_middle() { | |
edbdb7ea | 350 | List<Integer> list = fixture.getQuarks(Attributes.THREADS, "*", Attributes.EXEC_NAME); |
f9a76cac AM |
351 | |
352 | /* Number of different kernel threads in the trace */ | |
353 | assertEquals(168, list.size()); | |
354 | } | |
355 | ||
356 | @Test | |
357 | public void testGetQuarks_end() { | |
edbdb7ea | 358 | List<Integer> list = fixture.getQuarks(Attributes.THREADS, "1577", "*"); |
f9a76cac | 359 | |
3bf563da CM |
360 | /* There should be 5 sub-attributes for each Thread node */ |
361 | assertEquals(5, list.size()); | |
f9a76cac | 362 | } |
b33f7554 AM |
363 | |
364 | // ------------------------------------------------------------------------ | |
365 | // Tests verifying the *complete* results of a full queries | |
366 | // ------------------------------------------------------------------------ | |
367 | ||
368 | protected long getStartTimes(int idx) { | |
369 | return TestValues.startTimes[idx]; | |
370 | } | |
371 | ||
372 | protected long getEndTimes(int idx) { | |
373 | return TestValues.endTimes[idx]; | |
374 | } | |
375 | ||
376 | protected ITmfStateValue getStateValues(int idx) { | |
377 | return TestValues.values[idx]; | |
378 | } | |
379 | ||
380 | @Test | |
381 | public void testFullQueryThorough() { | |
382 | try { | |
edbdb7ea | 383 | List<ITmfStateInterval> state = fixture.queryFullState(interestingTimestamp1); |
b33f7554 AM |
384 | assertEquals(TestValues.size, state.size()); |
385 | ||
386 | for (int i = 0; i < state.size(); i++) { | |
387 | /* Test each component of the intervals */ | |
388 | assertEquals(getStartTimes(i), state.get(i).getStartTime()); | |
389 | assertEquals(getEndTimes(i), state.get(i).getEndTime()); | |
390 | assertEquals(i, state.get(i).getAttribute()); | |
391 | assertEquals(getStateValues(i), state.get(i).getStateValue()); | |
392 | } | |
393 | ||
b33f7554 AM |
394 | } catch (StateSystemDisposedException e) { |
395 | fail(); | |
396 | } | |
397 | } | |
b9f6183a AM |
398 | |
399 | @Test | |
400 | public void testFirstIntervalIsConsidered() { | |
401 | try { | |
07ec1591 | 402 | int quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1397", Attributes.STATUS); |
edbdb7ea | 403 | List<ITmfStateInterval> list = fixture.queryFullState(1331668248014135800L); |
07ec1591 | 404 | ITmfStateInterval interval = list.get(quark); |
b9f6183a AM |
405 | assertEquals(1331668247516664825L, interval.getStartTime()); |
406 | ||
407 | int valueInt = interval.getStateValue().unboxInt(); | |
408 | assertEquals(1, valueInt); | |
edbdb7ea | 409 | |
07ec1591 | 410 | } catch (StateSystemDisposedException | AttributeNotFoundException e) { |
b9f6183a | 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 | } |