1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.lttng2
.ust
.core
.tests
.callstack
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
16 import static org
.junit
.Assert
.assertEquals
;
17 import static org
.junit
.Assert
.assertFalse
;
18 import static org
.junit
.Assert
.assertNotNull
;
19 import static org
.junit
.Assert
.assertTrue
;
20 import static org
.junit
.Assert
.fail
;
23 import java
.util
.List
;
24 import java
.util
.concurrent
.TimeUnit
;
26 import org
.eclipse
.jdt
.annotation
.NonNull
;
27 import org
.eclipse
.tracecompass
.internal
.lttng2
.ust
.core
.callstack
.LttngUstCallStackProvider
;
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
.interval
.ITmfStateInterval
;
33 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
34 import org
.eclipse
.tracecompass
.testtraces
.ctf
.CtfTestTrace
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfAnalysisException
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.ITmfStateProvider
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.TmfStateSystemAnalysisModule
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
39 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.tests
.shared
.CtfTmfTestTraceUtils
;
40 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.trace
.CtfTmfTrace
;
41 import org
.junit
.After
;
42 import org
.junit
.Before
;
43 import org
.junit
.Rule
;
44 import org
.junit
.Test
;
45 import org
.junit
.rules
.TestRule
;
46 import org
.junit
.rules
.Timeout
;
49 * Base class for the UST callstack state provider tests.
51 * @author Alexandre Montplaisir
53 public abstract class AbstractProviderTest
{
55 /** Time-out tests after 1 minute. */
57 public TestRule globalTimeout
= new Timeout(1, TimeUnit
.MINUTES
);
59 // ------------------------------------------------------------------------
61 // ------------------------------------------------------------------------
63 private static final @NonNull CtfTestTrace otherUstTrace
= CtfTestTrace
.HELLO_LOST
;
65 private CtfTmfTrace fTrace
= null;
66 private ITmfStateSystem fSS
= null;
67 private TestLttngCallStackModule fModule
;
70 // ------------------------------------------------------------------------
72 // ------------------------------------------------------------------------
75 * @return The test trace to use for this test
77 protected abstract @NonNull CtfTestTrace
getTestTrace();
80 * @return The ID of the process the desired thread belongs to
82 protected abstract int getProcessId();
85 * @return The name of the executable process in that particular trace
87 protected abstract String
getThreadName();
90 * Get the list of timestamps to query in that trace.
93 * Which of the test timestamps?
94 * @return That particular timestamp
96 protected abstract long getTestTimestamp(int index
);
98 // ------------------------------------------------------------------------
100 // ------------------------------------------------------------------------
103 * Perform pre-class initialization.
106 public void setUp() {
107 CtfTestTrace testTrace
= getTestTrace();
109 CtfTmfTrace trace
= CtfTmfTestTraceUtils
.getTrace(testTrace
);
111 fModule
= new TestLttngCallStackModule();
113 assertTrue(fModule
.setTrace(trace
));
114 } catch (TmfAnalysisException e
) {
118 assertTrue(fModule
.waitForCompletion());
120 fSS
= fModule
.getStateSystem();
125 * Perform post-class clean-up.
128 public void tearDown() {
130 if (fTrace
!= null) {
132 File suppDir
= new File(TmfTraceManager
.getSupplementaryFileDir(fTrace
));
133 deleteDirectory(suppDir
);
137 // ------------------------------------------------------------------------
139 // ------------------------------------------------------------------------
142 * Test the handling of generic UST traces who do not contain the required
146 public void testOtherUstTrace() {
147 /* Initialize the trace and analysis module */
149 CtfTmfTrace ustTrace
= CtfTmfTestTraceUtils
.getTrace(otherUstTrace
);
150 TestLttngCallStackModule module
= null;
152 module
= new TestLttngCallStackModule();
154 assertTrue(module
.setTrace(ustTrace
));
155 } catch (TmfAnalysisException e
) {
159 assertTrue(module
.waitForCompletion());
161 /* Make sure the generated state system exists, but is empty */
162 ITmfStateSystem ss
= module
.getStateSystem();
164 assertTrue(ss
.getStartTime() >= ustTrace
.getStartTime().toNanos());
165 assertEquals(0, ss
.getNbAttributes());
167 if (module
!= null) {
171 suppDir
= new File(TmfTraceManager
.getSupplementaryFileDir(ustTrace
));
174 deleteDirectory(suppDir
);
175 assertFalse(suppDir
.exists());
179 * Test that the callstack state system is there and contains data.
182 public void testConstruction() {
184 assertTrue(fSS
.getNbAttributes() > 0);
188 * Test the callstack at the beginning of the state system.
191 public void testCallStackBegin() {
192 long start
= fSS
.getStartTime();
193 String
[] cs
= getCallStack(fSS
, getProcessId(), getThreadName(), start
);
194 assertEquals(1, cs
.length
);
196 assertEquals("40472b", cs
[0]);
200 * Test the callstack somewhere in the trace.
203 public void testCallStack1() {
204 String
[] cs
= getCallStack(fSS
, getProcessId(), getThreadName(), getTestTimestamp(0));
205 assertEquals(2, cs
.length
);
207 assertEquals("40472b", cs
[0]);
208 assertEquals("403d60", cs
[1]);
212 * Test the callstack somewhere in the trace.
215 public void testCallStack2() {
216 String
[] cs
= getCallStack(fSS
, getProcessId(), getThreadName(), getTestTimestamp(1));
217 assertEquals(3, cs
.length
);
219 assertEquals("40472b", cs
[0]);
220 assertEquals("403b14", cs
[1]);
221 assertEquals("401b23", cs
[2]);
225 * Test the callstack somewhere in the trace.
228 public void testCallStack3() {
229 String
[] cs
= getCallStack(fSS
, getProcessId(), getThreadName(), getTestTimestamp(2));
230 assertEquals(4, cs
.length
);
232 assertEquals("40472b", cs
[0]);
233 assertEquals("4045c8", cs
[1]);
234 assertEquals("403760", cs
[2]);
235 assertEquals("401aac", cs
[3]);
239 * Test the callstack at the end of the trace/state system.
242 public void testCallStackEnd() {
243 long end
= fSS
.getCurrentEndTime();
244 String
[] cs
= getCallStack(fSS
, getProcessId(), getThreadName(), end
);
245 assertEquals(3, cs
.length
);
247 assertEquals("40472b", cs
[0]);
248 assertEquals("4045c8", cs
[1]);
249 assertEquals("403760", cs
[2]);
252 // ------------------------------------------------------------------------
254 // ------------------------------------------------------------------------
256 /** Empty and delete a directory */
257 private static void deleteDirectory(File dir
) {
258 /* Assuming the dir only contains file or empty directories */
259 for (File file
: dir
.listFiles()) {
265 /** Get the callstack for the given timestamp, for this particular trace */
266 private static String
[] getCallStack(ITmfStateSystem ss
, int pid
, String threadName
, long timestamp
) {
268 int stackAttribute
= ss
.getQuarkAbsolute("Processes", Integer
.toString(pid
), threadName
, "CallStack");
269 List
<ITmfStateInterval
> state
= ss
.queryFullState(timestamp
);
270 int depth
= state
.get(stackAttribute
).getStateValue().unboxInt();
272 int stackTop
= ss
.getQuarkRelative(stackAttribute
, String
.valueOf(depth
));
273 ITmfStateValue expectedValue
= state
.get(stackTop
).getStateValue();
274 ITmfStateInterval interval
= StateSystemUtils
.querySingleStackTop(ss
, timestamp
, stackAttribute
);
275 assertNotNull(interval
);
276 assertEquals(expectedValue
, interval
.getStateValue());
278 String
[] ret
= new String
[depth
];
279 for (int i
= 0; i
< depth
; i
++) {
280 int quark
= ss
.getQuarkRelative(stackAttribute
, String
.valueOf(i
+ 1));
281 ret
[i
] = state
.get(quark
).getStateValue().unboxStr();
285 } catch (AttributeNotFoundException e
) {
286 fail(e
.getMessage());
287 } catch (StateSystemDisposedException e
) {
288 fail(e
.getMessage());
294 private class TestLttngCallStackModule
extends TmfStateSystemAnalysisModule
{
297 protected ITmfStateProvider
createStateProvider() {
298 return new LttngUstCallStackProvider(checkNotNull(getTrace()));