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