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
.Arrays
;
23 import java
.util
.List
;
24 import java
.util
.concurrent
.TimeUnit
;
26 import org
.eclipse
.jdt
.annotation
.NonNull
;
27 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.Attributes
;
28 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
29 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemUtils
;
30 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
31 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
32 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
33 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
34 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
35 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
36 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
37 import org
.junit
.Before
;
38 import org
.junit
.Rule
;
39 import org
.junit
.Test
;
40 import org
.junit
.rules
.TestRule
;
41 import org
.junit
.rules
.Timeout
;
44 * Base unit tests for the StateHistorySystem. Extension can be made to test
45 * different state back-end types or configurations.
47 * @author Alexandre Montplaisir
49 @SuppressWarnings("javadoc")
50 public abstract class StateSystemTest
{
52 /** Timeout the tests after 2 minutes */
54 public TestRule timeoutRule
= new Timeout(2, TimeUnit
.MINUTES
);
56 /** Test trace used for these tests */
57 protected static final @NonNull CtfTestTrace testTrace
= CtfTestTrace
.TRACE2
;
59 /** Expected start time of the test trace/state history */
60 protected static final long startTime
= 1331668247314038062L;
62 /** Expected end time of the state history built from the test trace */
63 protected static final long endTime
= 1331668259054285979L;
65 /** Offset in the trace + start time of the trace */
66 protected static final long interestingTimestamp1
= 18670067372290L + 1331649577946812237L;
68 /** Number of nanoseconds in one second */
69 private static final long NANOSECS_PER_SEC
= 1000000000L;
71 protected static ITmfStateSystem fixture
;
78 /* Subclasses should set-up 'fixture' */
79 assertNotNull(fixture
);
83 public void testFullQuery1() {
84 List
<ITmfStateInterval
> list
;
85 ITmfStateInterval interval
;
90 list
= fixture
.queryFullState(interestingTimestamp1
);
92 quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
93 interval
= list
.get(quark
);
94 valueInt
= interval
.getStateValue().unboxInt();
95 assertEquals(1397, valueInt
);
97 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
98 interval
= list
.get(quark
);
99 valueStr
= interval
.getStateValue().unboxStr();
100 assertEquals("gdbus", valueStr
);
102 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.SYSTEM_CALL
);
103 interval
= list
.get(quark
);
104 valueStr
= interval
.getStateValue().unboxStr();
105 assertEquals("sys_poll", valueStr
);
107 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
113 public void testSingleQuery1() {
114 long timestamp
= interestingTimestamp1
;
116 ITmfStateInterval interval
;
120 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
121 interval
= fixture
.querySingleState(timestamp
, quark
);
122 valueStr
= interval
.getStateValue().unboxStr();
123 assertEquals("gdbus", valueStr
);
125 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
131 * Test a range query (with no resolution parameter, so all intervals)
134 public void testRangeQuery1() {
135 long time1
= interestingTimestamp1
;
136 long time2
= time1
+ 1L * NANOSECS_PER_SEC
;
138 List
<ITmfStateInterval
> intervals
;
140 final ITmfStateSystem ss
= fixture
;
144 quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
145 intervals
= StateSystemUtils
.queryHistoryRange(ss
, quark
, time1
, time2
);
146 assertEquals(487, intervals
.size()); /* Number of context switches! */
147 assertEquals(1685, intervals
.get(100).getStateValue().unboxInt());
148 assertEquals(1331668248427681372L, intervals
.get(205).getEndTime());
150 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
156 * Range query, but with a t2 far off the end of the trace. The result
157 * should still be valid.
160 public void testRangeQuery2() {
161 List
<ITmfStateInterval
> intervals
;
163 final ITmfStateSystem ss
= fixture
;
167 int quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, Integer
.toString(0), Attributes
.IRQS
, "1");
168 long ts1
= ss
.getStartTime(); /* start of the trace */
169 long ts2
= startTime
+ 20L * NANOSECS_PER_SEC
; /* invalid, but ignored */
171 intervals
= StateSystemUtils
.queryHistoryRange(ss
, quark
, ts1
, ts2
);
173 /* Activity of IRQ 1 over the whole trace */
174 assertEquals(65, intervals
.size());
176 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
182 * Test a range query with a resolution
185 public void testRangeQuery3() {
186 long time1
= interestingTimestamp1
;
187 long time2
= time1
+ 1L * NANOSECS_PER_SEC
;
188 long resolution
= 1000000; /* One query every millisecond */
190 List
<ITmfStateInterval
> intervals
;
192 final ITmfStateSystem ss
= fixture
;
196 quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
197 intervals
= StateSystemUtils
.queryHistoryRange(ss
, quark
, time1
, time2
, resolution
, null);
198 assertEquals(126, intervals
.size()); /* Number of context switches! */
199 assertEquals(1452, intervals
.get(50).getStateValue().unboxInt());
200 assertEquals(1331668248815698779L, intervals
.get(100).getEndTime());
202 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
208 * Ask for a time range outside of the trace's range
210 @Test(expected
= TimeRangeException
.class)
211 public void testFullQueryInvalidTime1() throws TimeRangeException
,
212 StateSystemDisposedException
{
213 long ts
= startTime
+ 20L * NANOSECS_PER_SEC
;
214 fixture
.queryFullState(ts
);
217 @Test(expected
= TimeRangeException
.class)
218 public void testFullQueryInvalidTime2() throws TimeRangeException
,
219 StateSystemDisposedException
{
220 long ts
= startTime
- 20L * NANOSECS_PER_SEC
;
221 fixture
.queryFullState(ts
);
224 @Test(expected
= TimeRangeException
.class)
225 public void testSingleQueryInvalidTime1() throws TimeRangeException
{
227 int quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
228 long ts
= startTime
+ 20L * NANOSECS_PER_SEC
;
229 fixture
.querySingleState(ts
, quark
);
231 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
236 @Test(expected
= TimeRangeException
.class)
237 public void testSingleQueryInvalidTime2() throws TimeRangeException
{
239 int quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
240 long ts
= startTime
- 20L * NANOSECS_PER_SEC
;
241 fixture
.querySingleState(ts
, quark
);
243 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
248 @Test(expected
= TimeRangeException
.class)
249 public void testRangeQueryInvalidTime1() throws TimeRangeException
{
250 final ITmfStateSystem ss
= fixture
;
254 int quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
255 long ts1
= startTime
- 20L * NANOSECS_PER_SEC
; /* invalid */
256 long ts2
= startTime
+ 1L * NANOSECS_PER_SEC
; /* valid */
257 StateSystemUtils
.queryHistoryRange(ss
, quark
, ts1
, ts2
);
259 } catch (AttributeNotFoundException e
) {
261 } catch (StateSystemDisposedException e
) {
266 @Test(expected
= TimeRangeException
.class)
267 public void testRangeQueryInvalidTime2() throws TimeRangeException
{
268 final ITmfStateSystem ss
= fixture
;
272 int quark
= ss
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
273 long ts1
= startTime
- 1L * NANOSECS_PER_SEC
; /* invalid */
274 long ts2
= startTime
+ 20L * NANOSECS_PER_SEC
; /* invalid */
275 StateSystemUtils
.queryHistoryRange(ss
, quark
, ts1
, ts2
);
277 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
283 * Ask for a non-existing attribute
285 * @throws AttributeNotFoundException
287 @Test(expected
= AttributeNotFoundException
.class)
288 public void testQueryInvalidAttribute() throws AttributeNotFoundException
{
289 fixture
.getQuarkAbsolute("There", "is", "no", "cow", "level");
293 * Query but with the wrong State Value type
295 @Test(expected
= StateValueTypeException
.class)
296 public void testQueryInvalidValuetype1() throws StateValueTypeException
{
297 List
<ITmfStateInterval
> list
;
298 ITmfStateInterval interval
;
302 list
= fixture
.queryFullState(interestingTimestamp1
);
303 quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
304 interval
= list
.get(quark
);
306 /* This is supposed to be an int value */
307 interval
.getStateValue().unboxStr();
309 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
314 @Test(expected
= StateValueTypeException
.class)
315 public void testQueryInvalidValuetype2() throws StateValueTypeException
{
316 List
<ITmfStateInterval
> list
;
317 ITmfStateInterval interval
;
321 list
= fixture
.queryFullState(interestingTimestamp1
);
322 quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
323 interval
= list
.get(quark
);
325 /* This is supposed to be a String value */
326 interval
.getStateValue().unboxInt();
328 } catch (AttributeNotFoundException
| StateSystemDisposedException e
) {
334 public void testOptQuarkAbsolute() {
335 int quark
= fixture
.optQuarkAbsolute();
336 assertEquals(ROOT_ATTRIBUTE
, quark
);
338 quark
= fixture
.optQuarkAbsolute(Attributes
.THREADS
, "1432", Attributes
.EXEC_NAME
);
339 assertNotEquals(INVALID_ATTRIBUTE
, quark
);
340 assertEquals(Attributes
.EXEC_NAME
, fixture
.getAttributeName(quark
));
342 quark
= fixture
.optQuarkAbsolute(Attributes
.THREADS
, "1432", "absent");
343 assertEquals(INVALID_ATTRIBUTE
, quark
);
345 quark
= fixture
.optQuarkAbsolute(Attributes
.THREADS
, "absent", Attributes
.EXEC_NAME
);
346 assertEquals(INVALID_ATTRIBUTE
, quark
);
348 quark
= fixture
.optQuarkAbsolute("absent", "1432", Attributes
.EXEC_NAME
);
349 assertEquals(INVALID_ATTRIBUTE
, quark
);
353 public void testOptQuarkRelative() {
354 int threadsQuark
= INVALID_ATTRIBUTE
;
356 threadsQuark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
);
357 } catch (AttributeNotFoundException e
) {
360 assertNotEquals(INVALID_ATTRIBUTE
, threadsQuark
);
362 int quark
= fixture
.optQuarkRelative(threadsQuark
);
363 assertEquals(threadsQuark
, quark
);
365 quark
= fixture
.optQuarkRelative(threadsQuark
, "1432", Attributes
.EXEC_NAME
);
366 assertNotEquals(INVALID_ATTRIBUTE
, quark
);
367 assertEquals(Attributes
.EXEC_NAME
, fixture
.getAttributeName(quark
));
369 quark
= fixture
.optQuarkRelative(threadsQuark
, "1432", "absent");
370 assertEquals(INVALID_ATTRIBUTE
, quark
);
372 quark
= fixture
.optQuarkRelative(threadsQuark
, "absent", Attributes
.EXEC_NAME
);
373 assertEquals(INVALID_ATTRIBUTE
, quark
);
377 public void testFullAttributeName() {
379 int quark
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
380 String name
= fixture
.getFullAttributePath(quark
);
381 assertEquals(name
, "CPUs/0/Current_thread");
383 } catch (AttributeNotFoundException e
) {
389 public void testGetQuarks_begin() {
390 List
<Integer
> list
= fixture
.getQuarks("*", "1577", Attributes
.EXEC_NAME
);
392 assertEquals(1, list
.size());
396 public void testGetQuarks_middle() {
397 List
<Integer
> list
= fixture
.getQuarks(Attributes
.THREADS
, "*", Attributes
.EXEC_NAME
);
399 /* Number of different kernel threads in the trace */
400 assertEquals(169, list
.size());
404 public void testGetQuarks_end() {
405 List
<Integer
> list
= fixture
.getQuarks(Attributes
.THREADS
, "1577", "*");
407 /* There should be 5 sub-attributes for each Thread node */
408 assertEquals(5, list
.size());
412 public void testGetQuarks_middle_end() {
413 List
<Integer
> list
= fixture
.getQuarks(Attributes
.THREADS
, "*", "*");
415 /* There should be 169 threads and 5 sub-attributes per thread */
416 assertEquals(169 * 5, list
.size());
420 public void testGetQuarks_empty() {
421 List
<Integer
> list
= fixture
.getQuarks();
423 assertEquals(Arrays
.asList(ITmfStateSystem
.ROOT_ATTRIBUTE
), list
);
427 public void testGetQuarks_relative() {
428 int threadsQuark
= INVALID_ATTRIBUTE
;
430 threadsQuark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
);
431 } catch (AttributeNotFoundException e
) {
434 assertNotEquals(INVALID_ATTRIBUTE
, threadsQuark
);
436 List
<Integer
> list
= fixture
.getQuarks(threadsQuark
, "*", Attributes
.EXEC_NAME
);
438 /* Number of different kernel threads in the trace */
439 assertEquals(169, list
.size());
443 public void testGetQuarks_relative_up_wildcard() {
444 int threadsQuark
= INVALID_ATTRIBUTE
;
446 threadsQuark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
);
447 } catch (AttributeNotFoundException e
) {
450 assertNotEquals(INVALID_ATTRIBUTE
, threadsQuark
);
452 List
<Integer
> list
= fixture
.getQuarks(threadsQuark
, "..", Attributes
.CPUS
, "*");
454 /* There should be 2 CPUs */
455 assertEquals(2, list
.size());
459 public void testGetQuarks_relative_empty() {
460 int threadsQuark
= INVALID_ATTRIBUTE
;
462 threadsQuark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
);
463 } catch (AttributeNotFoundException e
) {
466 assertNotEquals(INVALID_ATTRIBUTE
, threadsQuark
);
468 List
<Integer
> list
= fixture
.getQuarks(threadsQuark
, new String
[0]);
469 assertEquals(Arrays
.asList(threadsQuark
), list
);
471 list
= fixture
.getQuarks(threadsQuark
);
472 assertEquals(Arrays
.asList(threadsQuark
), list
);
476 public void testGetQuarksNoMatch() {
477 List
<Integer
> list
= fixture
.getQuarks("invalid");
478 assertEquals(0, list
.size());
480 list
= fixture
.getQuarks("*", "invalid");
481 assertEquals(0, list
.size());
483 list
= fixture
.getQuarks("invalid", "*");
484 assertEquals(0, list
.size());
486 list
= fixture
.getQuarks(Attributes
.THREADS
, "*", "invalid");
487 assertEquals(0, list
.size());
490 // ------------------------------------------------------------------------
491 // Tests verifying the *complete* results of a full queries
492 // ------------------------------------------------------------------------
494 protected long getStartTimes(int idx
) {
495 return TestValues
.startTimes
[idx
];
498 protected long getEndTimes(int idx
) {
499 return TestValues
.endTimes
[idx
];
502 protected ITmfStateValue
getStateValues(int idx
) {
503 return TestValues
.values
[idx
];
507 public void testFullQueryThorough() {
509 List
<ITmfStateInterval
> state
= fixture
.queryFullState(interestingTimestamp1
);
510 assertEquals(TestValues
.size
, state
.size());
512 for (int i
= 0; i
< state
.size(); i
++) {
513 /* Test each component of the intervals */
514 assertEquals(getStartTimes(i
), state
.get(i
).getStartTime());
515 assertEquals(getEndTimes(i
), state
.get(i
).getEndTime());
516 assertEquals(i
, state
.get(i
).getAttribute());
517 assertEquals(getStateValues(i
), state
.get(i
).getStateValue());
520 } catch (StateSystemDisposedException e
) {
526 public void testFirstIntervalIsConsidered() {
528 int quark
= fixture
.getQuarkAbsolute(Attributes
.THREADS
, "1397", Attributes
.STATUS
);
529 List
<ITmfStateInterval
> list
= fixture
.queryFullState(1331668248014135800L);
530 ITmfStateInterval interval
= list
.get(quark
);
531 assertEquals(1331668247516664825L, interval
.getStartTime());
533 int valueInt
= interval
.getStateValue().unboxInt();
534 assertEquals(1, valueInt
);
536 } catch (StateSystemDisposedException
| AttributeNotFoundException e
) {
542 public void testParentAttribute() {
543 String
[] path
= { "CPUs/0/Current_thread",
547 int q
= fixture
.getQuarkAbsolute(Attributes
.CPUS
, "0", Attributes
.CURRENT_THREAD
);
548 for (int i
= 0; i
< path
.length
; i
++) {
549 String name
= fixture
.getFullAttributePath(q
);
550 assertEquals(path
[i
], name
);
551 q
= fixture
.getParentAttributeQuark(q
);
553 assertEquals(ROOT_ATTRIBUTE
, q
);
554 q
= fixture
.getParentAttributeQuark(q
);
555 assertEquals(ROOT_ATTRIBUTE
, q
);
556 } catch (AttributeNotFoundException e
) {