1 /*******************************************************************************
2 * Copyright (c) 2012, 2016 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
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
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.lttng2
.kernel
.core
.tests
.analysis
.kernel
.statesystem
;
15 import static org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
.INVALID_ATTRIBUTE
;
16 import static org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
.ROOT_ATTRIBUTE
;
17 import static org
.junit
.Assert
.assertEquals
;
18 import static org
.junit
.Assert
.assertNotEquals
;
19 import static org
.junit
.Assert
.assertNotNull
;
20 import static org
.junit
.Assert
.fail
;
22 import java
.util
.List
;
23 import java
.util
.concurrent
.TimeUnit
;
25 import org
.eclipse
.jdt
.annotation
.NonNull
;
26 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
27 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
28 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemUtils
;
29 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
30 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
31 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
32 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
33 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
34 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
35 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
36 import org
.junit
.Before
;
37 import org
.junit
.Rule
;
38 import org
.junit
.Test
;
39 import org
.junit
.rules
.TestRule
;
40 import org
.junit
.rules
.Timeout
;
43 * Base unit tests for the StateHistorySystem. Extension can be made to test
44 * different state back-end types or configurations.
46 * @author Alexandre Montplaisir
48 @SuppressWarnings("javadoc")
49 public abstract class StateSystemTest
{
51 /** Timeout the tests after 2 minutes */
53 public TestRule timeoutRule
= new Timeout(2, TimeUnit
.MINUTES
);
55 /** Test trace used for these tests */
56 protected static final @NonNull CtfTestTrace testTrace
= CtfTestTrace
.TRACE2
;
58 /** Expected start time of the test trace/state history */
59 protected static final long startTime
= 1331668247314038062L;
61 /** Expected end time of the state history built from the test trace */
62 protected static final long endTime
= 1331668259054285979L;
64 /** Offset in the trace + start time of the trace */
65 protected static final long interestingTimestamp1
= 18670067372290L + 1331649577946812237L;
67 /** Number of nanoseconds in one second */
68 private static final long NANOSECS_PER_SEC
= 1000000000L;
70 protected static ITmfStateSystem fixture
;
77 /* Subclasses should set-up 'fixture' */
78 assertNotNull(fixture
);
82 public void testFullQuery1() {
83 List
<ITmfStateInterval
> list
;
84 ITmfStateInterval interval
;
89 list
= fixture
.queryFullState(interestingTimestamp1
);
91 quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
92 interval
= list
.get(quark
);
93 valueInt
= interval
.getStateValue().unboxInt();
94 assertEquals(1397, valueInt
);
96 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
97 interval
= list
.get(quark
);
98 valueStr
= interval
.getStateValue().unboxStr();
99 assertEquals("gdbus", valueStr
);
101 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.SYSTEM_CALL
);
102 interval
= list
.get(quark
);
103 valueStr
= interval
.getStateValue().unboxStr();
104 assertEquals("sys_poll", valueStr
);
106 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
112 public void testSingleQuery1() {
113 long timestamp
= interestingTimestamp1
;
115 ITmfStateInterval interval
;
119 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
120 interval
= fixture
.querySingleState(timestamp
, quark
);
121 valueStr
= interval
.getStateValue().unboxStr();
122 assertEquals("gdbus", valueStr
);
124 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
130 * Test a range query (with no resolution parameter, so all intervals)
133 public void testRangeQuery1() {
134 long time1
= interestingTimestamp1
;
135 long time2
= time1
+ 1L * NANOSECS_PER_SEC
;
137 List
<ITmfStateInterval
> intervals
;
139 final ITmfStateSystem ss
= fixture
;
143 quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
144 intervals
= StateSystemUtils
.queryHistoryRange(ss
, quark
, time1
, time2
);
145 assertEquals(487, intervals
.size()); /* Number of context switches! */
146 assertEquals(1685, intervals
.get(100).getStateValue().unboxInt());
147 assertEquals(1331668248427681372L, intervals
.get(205).getEndTime());
149 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
155 * Range query, but with a t2 far off the end of the trace. The result
156 * should still be valid.
159 public void testRangeQuery2() {
160 List
<ITmfStateInterval
> intervals
;
162 final ITmfStateSystem ss
= fixture
;
166 int quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, Integer
.toString(0), Attributes
.IRQS
, "1");
167 long ts1
= ss
.getStartTime(); /* start of the trace */
168 long ts2
= startTime
+ 20L * NANOSECS_PER_SEC
; /* invalid, but ignored */
170 intervals
= StateSystemUtils
.queryHistoryRange(ss
, quark
, ts1
, ts2
);
172 /* Activity of IRQ 1 over the whole trace */
173 assertEquals(65, intervals
.size());
175 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
181 * Test a range query with a resolution
184 public void testRangeQuery3() {
185 long time1
= interestingTimestamp1
;
186 long time2
= time1
+ 1L * NANOSECS_PER_SEC
;
187 long resolution
= 1000000; /* One query every millisecond */
189 List
<ITmfStateInterval
> intervals
;
191 final ITmfStateSystem ss
= fixture
;
195 quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
196 intervals
= StateSystemUtils
.queryHistoryRange(ss
, 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());
201 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
207 * Ask for a time range outside of the trace's range
209 @Test(expected
= TimeRangeException
.class)
210 public void testFullQueryInvalidTime1() throws TimeRangeException
,
211 StateSystemDisposedException
{
212 long ts
= startTime
+ 20L * NANOSECS_PER_SEC
;
213 fixture
.queryFullState(ts
);
216 @Test(expected
= TimeRangeException
.class)
217 public void testFullQueryInvalidTime2() throws TimeRangeException
,
218 StateSystemDisposedException
{
219 long ts
= startTime
- 20L * NANOSECS_PER_SEC
;
220 fixture
.queryFullState(ts
);
223 @Test(expected
= TimeRangeException
.class)
224 public void testSingleQueryInvalidTime1() throws TimeRangeException
{
226 int quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
227 long ts
= startTime
+ 20L * NANOSECS_PER_SEC
;
228 fixture
.querySingleState(ts
, quark
);
230 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
235 @Test(expected
= TimeRangeException
.class)
236 public void testSingleQueryInvalidTime2() throws TimeRangeException
{
238 int quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
239 long ts
= startTime
- 20L * NANOSECS_PER_SEC
;
240 fixture
.querySingleState(ts
, quark
);
242 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
247 @Test(expected
= TimeRangeException
.class)
248 public void testRangeQueryInvalidTime1() throws TimeRangeException
{
249 final ITmfStateSystem ss
= fixture
;
253 int quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
254 long ts1
= startTime
- 20L * NANOSECS_PER_SEC
; /* invalid */
255 long ts2
= startTime
+ 1L * NANOSECS_PER_SEC
; /* valid */
256 StateSystemUtils
.queryHistoryRange(ss
, quark
, ts1
, ts2
);
258 } catch (AttributeNotFoundException e
) {
260 } catch (StateSystemDisposedException e
) {
265 @Test(expected
= TimeRangeException
.class)
266 public void testRangeQueryInvalidTime2() throws TimeRangeException
{
267 final ITmfStateSystem ss
= fixture
;
271 int quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
272 long ts1
= startTime
- 1L * NANOSECS_PER_SEC
; /* invalid */
273 long ts2
= startTime
+ 20L * NANOSECS_PER_SEC
; /* invalid */
274 StateSystemUtils
.queryHistoryRange(ss
, quark
, ts1
, ts2
);
276 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
282 * Ask for a non-existing attribute
284 * @throws AttributeNotFoundException
286 @Test(expected
= AttributeNotFoundException
.class)
287 public void testQueryInvalidAttribute() throws AttributeNotFoundException
{
288 fixture
.getQuarkAbsolute("There", "is", "no", "cow", "level");
292 * Query but with the wrong State Value type
294 @Test(expected
= StateValueTypeException
.class)
295 public void testQueryInvalidValuetype1() throws StateValueTypeException
{
296 List
<ITmfStateInterval
> list
;
297 ITmfStateInterval interval
;
301 list
= fixture
.queryFullState(interestingTimestamp1
);
302 quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
303 interval
= list
.get(quark
);
305 /* This is supposed to be an int value */
306 interval
.getStateValue().unboxStr();
308 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
313 @Test(expected
= StateValueTypeException
.class)
314 public void testQueryInvalidValuetype2() throws StateValueTypeException
{
315 List
<ITmfStateInterval
> list
;
316 ITmfStateInterval interval
;
320 list
= fixture
.queryFullState(interestingTimestamp1
);
321 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
322 interval
= list
.get(quark
);
324 /* This is supposed to be a String value */
325 interval
.getStateValue().unboxInt();
327 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
333 public void testOptQuarkAbsolute() {
334 int quark
= fixture
.optQuarkAbsolute();
335 assertEquals(ROOT_ATTRIBUTE
, quark
);
337 quark
= fixture
.optQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
338 assertNotEquals(INVALID_ATTRIBUTE
, quark
);
339 assertEquals(Attributes
.EXEC_NAME
, fixture
.getAttributeName(quark
));
341 quark
= fixture
.optQuarkAbsolute(Attributes
.THREADS
, "1432", "absent");
342 assertEquals(INVALID_ATTRIBUTE
, quark
);
344 quark
= fixture
.optQuarkAbsolute(Attributes
.THREADS
, "absent", Attributes
.EXEC_NAME
);
345 assertEquals(INVALID_ATTRIBUTE
, quark
);
347 quark
= fixture
.optQuarkAbsolute("absent", "1432", Attributes
.EXEC_NAME
);
348 assertEquals(INVALID_ATTRIBUTE
, quark
);
352 public void testOptQuarkRelative() {
353 int threadsQuark
= INVALID_ATTRIBUTE
;
355 threadsQuark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
);
356 } catch (AttributeNotFoundException e
) {
359 assertNotEquals(INVALID_ATTRIBUTE
, threadsQuark
);
361 int quark
= fixture
.optQuarkRelative(threadsQuark
);
362 assertEquals(threadsQuark
, quark
);
364 quark
= fixture
.optQuarkRelative(threadsQuark
, "1432", Attributes
.EXEC_NAME
);
365 assertNotEquals(INVALID_ATTRIBUTE
, quark
);
366 assertEquals(Attributes
.EXEC_NAME
, fixture
.getAttributeName(quark
));
368 quark
= fixture
.optQuarkRelative(threadsQuark
, "1432", "absent");
369 assertEquals(INVALID_ATTRIBUTE
, quark
);
371 quark
= fixture
.optQuarkRelative(threadsQuark
, "absent", Attributes
.EXEC_NAME
);
372 assertEquals(INVALID_ATTRIBUTE
, quark
);
376 public void testFullAttributeName() {
378 int quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
379 String name
= fixture
.getFullAttributePath(quark
);
380 assertEquals(name
, "CPUs/0/Current_thread");
382 } catch (AttributeNotFoundException e
) {
388 public void testGetQuarks_begin() {
389 List
<Integer
> list
= fixture
.getQuarks("*", "1577", Attributes
.EXEC_NAME
);
391 assertEquals(1, list
.size());
395 public void testGetQuarks_middle() {
396 List
<Integer
> list
= fixture
.getQuarks(Attributes
.THREADS
, "*", Attributes
.EXEC_NAME
);
398 /* Number of different kernel threads in the trace */
399 assertEquals(169, list
.size());
403 public void testGetQuarks_end() {
404 List
<Integer
> list
= fixture
.getQuarks(Attributes
.THREADS
, "1577", "*");
406 /* There should be 5 sub-attributes for each Thread node */
407 assertEquals(5, list
.size());
411 public void testGetQuarksNoMatch() {
412 List
<Integer
> list
= fixture
.getQuarks("invalid");
413 assertEquals(0, list
.size());
415 list
= fixture
.getQuarks("*", "invalid");
416 assertEquals(0, list
.size());
418 list
= fixture
.getQuarks("invalid", "*");
419 assertEquals(0, list
.size());
421 list
= fixture
.getQuarks(Attributes
.THREADS
, "*", "invalid");
422 assertEquals(0, list
.size());
425 // ------------------------------------------------------------------------
426 // Tests verifying the *complete* results of a full queries
427 // ------------------------------------------------------------------------
429 protected long getStartTimes(int idx
) {
430 return TestValues
.startTimes
[idx
];
433 protected long getEndTimes(int idx
) {
434 return TestValues
.endTimes
[idx
];
437 protected ITmfStateValue
getStateValues(int idx
) {
438 return TestValues
.values
[idx
];
442 public void testFullQueryThorough() {
444 List
<ITmfStateInterval
> state
= fixture
.queryFullState(interestingTimestamp1
);
445 assertEquals(TestValues
.size
, state
.size());
447 for (int i
= 0; i
< state
.size(); i
++) {
448 /* Test each component of the intervals */
449 assertEquals(getStartTimes(i
), state
.get(i
).getStartTime());
450 assertEquals(getEndTimes(i
), state
.get(i
).getEndTime());
451 assertEquals(i
, state
.get(i
).getAttribute());
452 assertEquals(getStateValues(i
), state
.get(i
).getStateValue());
455 } catch (StateSystemDisposedException e
) {
461 public void testFirstIntervalIsConsidered() {
463 int quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1397", Attributes
.STATUS
);
464 List
<ITmfStateInterval
> list
= fixture
.queryFullState(1331668248014135800L);
465 ITmfStateInterval interval
= list
.get(quark
);
466 assertEquals(1331668247516664825L, interval
.getStartTime());
468 int valueInt
= interval
.getStateValue().unboxInt();
469 assertEquals(1, valueInt
);
471 } catch (StateSystemDisposedException
| AttributeNotFoundException e
) {
477 public void testParentAttribute() {
478 String
[] path
= { "CPUs/0/Current_thread",
482 int q
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
483 for (int i
= 0; i
< path
.length
; i
++) {
484 String name
= fixture
.getFullAttributePath(q
);
485 assertEquals(path
[i
], name
);
486 q
= fixture
.getParentAttributeQuark(q
);
488 assertEquals(ROOT_ATTRIBUTE
, q
);
489 q
= fixture
.getParentAttributeQuark(q
);
490 assertEquals(ROOT_ATTRIBUTE
, q
);
491 } catch (AttributeNotFoundException e
) {