releng: fix name in 4.7 target
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.core.tests / src / org / eclipse / tracecompass / analysis / timing / core / tests / callgraph / CallGraphAnalysisTest.java
CommitLineData
4cc15e51
SF
1/*******************************************************************************
2 * Copyright (c) 2016 Ericsson
3 *
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
8 *******************************************************************************/
9
10package org.eclipse.tracecompass.analysis.timing.core.tests.callgraph;
11
55f777f4
PT
12import static org.junit.Assert.assertEquals;
13import static org.junit.Assert.assertNotNull;
14import static org.junit.Assert.assertTrue;
4cc15e51
SF
15
16import java.util.Collections;
17import java.util.List;
18
19import org.eclipse.core.runtime.IProgressMonitor;
20import org.eclipse.core.runtime.NullProgressMonitor;
21import org.eclipse.jdt.annotation.NonNull;
22import org.eclipse.jdt.annotation.Nullable;
23import org.eclipse.tracecompass.common.core.NonNullUtils;
24import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.CallGraphAnalysis;
55f777f4 25import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.ICalledFunction;
4cc15e51
SF
26import org.eclipse.tracecompass.segmentstore.core.ISegment;
27import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
28import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
29import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
30import org.eclipse.tracecompass.statesystem.core.StateSystemFactory;
31import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
32import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
33import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
34import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
35import org.junit.Test;
36
37/**
38 * Test the CallGraphAnalysis.This creates a virtual state system in each test
39 * and tests the segment store returned by the CallGraphAnalysis.
40 *
41 * @author Sonia Farrah
42 *
43 */
44public class CallGraphAnalysisTest {
45
46 private static final @NonNull String PROCESS_PATH = "Processes";
47 private static final @NonNull String THREAD_PATH = "Thread";
48 private static final @NonNull String CALLSTACK_PATH = "CallStack";
49 private static final String QUARK_0 = "0";
50 private static final String QUARK_1 = "1";
51 private static final String QUARK_2 = "2";
52 private static final Integer SMALL_AMOUNT_OF_SEGMENT = 3;
53 private static final int LARGE_AMOUNT_OF_SEGMENTS = 1000;
54 private static final String @NonNull [] CSP = { CALLSTACK_PATH };
55 private static final String @NonNull [] PP = { PROCESS_PATH };
56 private static final String @NonNull [] TP = { THREAD_PATH };
57
58 /**
59 * This class is used to make the CallGraphAnalysis's method
60 * iterateOverStateSystem() visible to test
61 */
62 private class CGAnalysis extends CallGraphAnalysis {
63
64 @Override
65 protected boolean iterateOverStateSystem(@Nullable ITmfStateSystem ss, String[] threadsPattern, String[] processesPattern, String[] callStackPath, IProgressMonitor monitor) {
66 return super.iterateOverStateSystem(ss, threadsPattern, processesPattern, callStackPath, monitor);
67 }
68
69 @Override
70 public @NonNull Iterable<@NonNull ISegmentAspect> getSegmentAspects() {
71 return Collections.EMPTY_LIST;
72 }
73
74 }
75
76 private static ITmfStateSystemBuilder createFixture() {
77 IStateHistoryBackend backend;
78 backend = StateHistoryBackendFactory.createInMemoryBackend("Test", 0L);
79 ITmfStateSystemBuilder fixture = StateSystemFactory.newStateSystem(backend);
80 return fixture;
81 }
82
83 /**
84 * Test cascade state system. The call stack's structure used in this test
85 * is shown below:
86 *
87 * <pre>
88 * ________
89 * ______
90 * ____
91 *
92 * </pre>
93 */
94 @Test
95 public void CascadeTest() {
96 ITmfStateSystemBuilder fixture = createFixture();
97 // Build the state system
98 long start = 1;
99 long end = 1001;
100 int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH);
101 for (int i = 1; i <= SMALL_AMOUNT_OF_SEGMENT; i++) {
102 int quark = fixture.getQuarkRelativeAndAdd(parentQuark, Integer.toString(i));
103 TmfStateValue statev = TmfStateValue.newValueLong(i);
104 fixture.modifyAttribute(start, TmfStateValue.nullValue(), quark);
105 fixture.modifyAttribute(start + i, statev, quark);
106 fixture.modifyAttribute(end - i, TmfStateValue.nullValue(), quark);
107 }
108
109 fixture.closeHistory(1002);
110 // Execute the CallGraphAnalysis
111 CGAnalysis cga = new CGAnalysis();
112 assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor()));
113 ISegmentStore<@NonNull ISegment> segmentStore = cga.getSegmentStore();
114 // Test the segment store generated by the analysis
115 assertNotNull(segmentStore);
116 Object[] segments = segmentStore.toArray();
117 assertEquals("Number of segments Found", 3, segments.length);
55f777f4
PT
118 ICalledFunction f1 = (ICalledFunction) segments[0];
119 ICalledFunction f2 = (ICalledFunction) segments[1];
120 ICalledFunction f3 = (ICalledFunction) segments[2];
121 assertEquals("Test the parenthood", NonNullUtils.checkNotNull(f2.getParent()).getSymbol(), f1.getSymbol());
4cc15e51
SF
122 assertEquals("Children number:First parent", 1, f1.getChildren().size());
123 assertEquals("Children number:Second parent", 1, f2.getChildren().size());
124 assertTrue("Children number:Second parent", f3.getChildren().isEmpty());
55f777f4 125 assertTrue("Children number:Child(leaf)", ((ICalledFunction) segments[2]).getChildren().isEmpty());
4cc15e51
SF
126 assertEquals("Parent's self time", 2, f1.getSelfTime());
127 assertEquals("Child's self time", 2, f2.getSelfTime());
128 assertEquals("The leaf's self time", 994, f3.getSelfTime());
129 assertEquals("Test first function's duration", 998, f1.getLength());
130 assertEquals("Test second function's duration", 996, f2.getLength());
131 assertEquals("Test third function's duration", 994, f3.getLength());
132 assertEquals("Depth:First parent", 0, f1.getDepth());
133 assertEquals("Depth:Second parent", 1, f2.getDepth());
134 assertEquals("Depth:Last child", 2, f3.getDepth());
ded2b27f 135 cga.dispose();
4cc15e51
SF
136 }
137
138 /**
139 * Build a pyramid shaped call stack.This call stack contains three
140 * functions ,Its structure is shown below :
141 *
142 * <pre>
143 * __
144 * ____
145 * ______
146 * </pre>
147 */
148 private static void buildPyramidCallStack(ITmfStateSystemBuilder fixture) {
149 int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH);
150 // Create the first function
151 int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0);
152 TmfStateValue statev = TmfStateValue.newValueLong(0);
153 fixture.modifyAttribute(0, TmfStateValue.nullValue(), quark);
154 fixture.modifyAttribute(10, statev, quark);
155 fixture.modifyAttribute(20, TmfStateValue.nullValue(), quark);
156 // Create the second function
157 quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1);
158 statev = TmfStateValue.newValueLong(1);
159 fixture.modifyAttribute(0, TmfStateValue.nullValue(), quark);
160 fixture.modifyAttribute(5, statev, quark);
161 fixture.modifyAttribute(25, TmfStateValue.nullValue(), quark);
162 // Create the third function
163 quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_2);
164 statev = TmfStateValue.newValueLong(2);
165 fixture.modifyAttribute(0, statev, quark);
166 fixture.modifyAttribute(30, TmfStateValue.nullValue(), quark);
167
168 fixture.closeHistory(31);
169 }
170
171 /**
172 * Test pyramid state system. The call stack's structure used in this test
173 * is shown below:
174 *
175 * <pre>
176 * __
177 * ____
178 * ______
179 * </pre>
180 */
181 @Test
182 public void PyramidTest() {
183 ITmfStateSystemBuilder fixture = createFixture();
184 buildPyramidCallStack(fixture);
185 // Execute the callGraphAnalysis
186 CGAnalysis cga = new CGAnalysis();
187 assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor()));
188 ISegmentStore<@NonNull ISegment> segmentStore = cga.getSegmentStore();
189 assertNotNull(segmentStore);
190 Object[] segments = segmentStore.toArray();
55f777f4 191 ICalledFunction f1 = (ICalledFunction) segments[0];
4cc15e51
SF
192 assertEquals("Number of segments Found", 1, segments.length);
193 assertEquals("Callees number", 0, f1.getChildren().size());
194 assertEquals("Function's self time", 10, f1.getSelfTime());
195 assertEquals("Compare the function's self time and total time", f1.getLength(), f1.getSelfTime());
196 assertEquals("Function's depth", 0, f1.getDepth());
ded2b27f 197 cga.dispose();
4cc15e51
SF
198 }
199
200 /**
201 * Test mutliRoots state system. The call stack's structure used in this
202 * test is shown below:
203 *
204 * <pre>
205 * ___ ___
206 * _ _
207 * </pre>
208 */
209 @Test
210 public void multiFunctionRootsTest() {
211 ITmfStateSystemBuilder fixture = createFixture();
212 int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH);
213 // Create the first root function
214 int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0);
215 TmfStateValue statev = TmfStateValue.newValueLong(0);
216 fixture.modifyAttribute(0, statev, quark);
217 fixture.modifyAttribute(20, TmfStateValue.nullValue(), quark);
218 // Create the second root function
219 statev = TmfStateValue.newValueLong(1);
220 fixture.modifyAttribute(30, statev, quark);
221 fixture.modifyAttribute(50, TmfStateValue.nullValue(), quark);
222 // Create the first root function's callee
223 quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1);
224 statev = TmfStateValue.newValueLong(2);
225 fixture.modifyAttribute(0, statev, quark);
226 fixture.modifyAttribute(10, TmfStateValue.nullValue(), quark);
227 // Create the second root function's callee
228 statev = TmfStateValue.newValueLong(3);
229 fixture.modifyAttribute(30, statev, quark);
230 fixture.modifyAttribute(40, TmfStateValue.nullValue(), quark);
231 fixture.closeHistory(51);
232
233 // Execute the callGraphAnalysis
234 CGAnalysis cga = new CGAnalysis();
235 assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor()));
236 ISegmentStore<@NonNull ISegment> segmentStore = cga.getSegmentStore();
237 // Test the segment store
238 assertNotNull(segmentStore);
239 Object[] segments = segmentStore.toArray();
55f777f4 240 List<@NonNull ICalledFunction> threads = cga.getRootFunctions();
4cc15e51
SF
241 assertEquals("Number of root functions", 2, threads.size());
242 assertEquals("Number of children: first root function", 1, threads.get(0).getChildren().size());
243 assertEquals("Number of children: first root function", 1, threads.get(1).getChildren().size());
55f777f4
PT
244 ICalledFunction firstChild = threads.get(0).getChildren().get(0);
245 ICalledFunction secondChild = threads.get(1).getChildren().get(0);
4cc15e51
SF
246 assertEquals("Number of segments found", 4, segments.length);
247 assertNotNull(firstChild.getParent());
248 assertNotNull(secondChild.getParent());
249
55f777f4
PT
250 assertEquals("Test of parenthood", NonNullUtils.checkNotNull(firstChild.getParent()).getSymbol(), threads.get(0).getSymbol());
251 assertEquals("Test of parenthood", NonNullUtils.checkNotNull(secondChild.getParent()).getSymbol(), threads.get(1).getSymbol());
ded2b27f 252 cga.dispose();
4cc15e51
SF
253 }
254
255 /**
256 * Test state system with a Large amount of segments. All segments have the
257 * same length. The call stack's structure used in this test is shown below:
258 *
259 * <pre>
260 * _____
261 * _____
262 * _____
263 * .....
264 * </pre>
265 */
266 @Test
267 public void LargeTest() {
268 // Build the state system
269 ITmfStateSystemBuilder fixture = createFixture();
270 int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH);
271 for (int i = 0; i < LARGE_AMOUNT_OF_SEGMENTS; i++) {
272 int quark = fixture.getQuarkRelativeAndAdd(parentQuark, Integer.toString(i));
273 TmfStateValue statev = TmfStateValue.newValueLong(i);
274 fixture.pushAttribute(0, statev, quark);
275 }
276 for (int i = 0; i < LARGE_AMOUNT_OF_SEGMENTS; i++) {
277 int quark = fixture.getQuarkRelativeAndAdd(parentQuark, Integer.toString(i));
278 fixture.popAttribute(10, quark);
279 }
280 fixture.closeHistory(11);
281 // Execute the callGraphAnalysis
282 CGAnalysis cga = new CGAnalysis();
283 assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor()));
284 ISegmentStore<@NonNull ISegment> segmentStore = cga.getSegmentStore();
285 // Test segment store
286 assertNotNull(segmentStore);
287 Object[] segments = segmentStore.toArray();
288 assertEquals("Number of segments found", LARGE_AMOUNT_OF_SEGMENTS, segments.length);
289 for (int i = 1; i < LARGE_AMOUNT_OF_SEGMENTS; i++) {
55f777f4 290 assertEquals("Test parenthood", ((ICalledFunction) segments[i - 1]).getSymbol(), NonNullUtils.checkNotNull(((ICalledFunction) segments[i]).getParent()).getSymbol());
4cc15e51 291 }
ded2b27f 292 cga.dispose();
4cc15e51
SF
293 }
294
295 /**
296 * Test an empty state system
297 */
298 @Test
299 public void EmptyStateSystemTest() {
300 ITmfStateSystemBuilder fixture = createFixture();
301 fixture.closeHistory(1002);
302 CGAnalysis cga = new CGAnalysis();
303 assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor()));
304 ISegmentStore<@NonNull ISegment> segmentStore = cga.getSegmentStore();
305 assertNotNull(segmentStore);
306 Object[] segments = segmentStore.toArray();
307 assertEquals("Number of root functions", 0, segments.length);
ded2b27f 308 cga.dispose();
4cc15e51
SF
309 }
310
311 /**
312 * Test a tree shaped call stack. The root function calls the same function
313 * twice. The call stack's structure used in this test is shown below:
314 *
315 * <pre>
316 *---------1----------
317 * --2-- -3- -2-
318 * -3-
319 * </pre>
320 */
321 @Test
322 public void treeTest() {
323 // Build the state system
324 ITmfStateSystemBuilder fixture = createFixture();
325 int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH);
326 // Create the root function
327 int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0);
328 TmfStateValue statev = TmfStateValue.newValueLong(0);
329 fixture.modifyAttribute(0, statev, quark);
330 fixture.modifyAttribute(100, TmfStateValue.nullValue(), quark);
331 // Create the first child
332 quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1);
333 statev = TmfStateValue.newValueLong(1);
334 fixture.modifyAttribute(0, TmfStateValue.nullValue(), quark);
335 fixture.modifyAttribute(10, statev, quark);
336 fixture.modifyAttribute(40, TmfStateValue.nullValue(), quark);
337 // Create the second child
338 statev = TmfStateValue.newValueLong(2);
339 fixture.modifyAttribute(50, statev, quark);
340 fixture.modifyAttribute(70, TmfStateValue.nullValue(), quark);
341 // Create the third child
342 statev = TmfStateValue.newValueLong(1);
343 fixture.modifyAttribute(80, statev, quark);
344 fixture.modifyAttribute(100, TmfStateValue.nullValue(), quark);
345 // Create the leaf
346 quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_2);
347 statev = TmfStateValue.newValueLong(3);
348 fixture.modifyAttribute(0, TmfStateValue.nullValue(), quark);
349 fixture.modifyAttribute(15, statev, quark);
350 fixture.modifyAttribute(20, TmfStateValue.nullValue(), quark);
351 fixture.closeHistory(102);
352
353 // Execute the callGraphAnalysis
354 CGAnalysis cga = new CGAnalysis();
355 assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor()));
356 ISegmentStore<@NonNull ISegment> segmentStore = cga.getSegmentStore();
357 // Test segment store
358 assertNotNull(segmentStore);
359 Object[] segments = segmentStore.toArray();
360 assertEquals("Number of segments found", 5, segments.length);
55f777f4 361 List<@NonNull ICalledFunction> rootFunctions = cga.getRootFunctions();
4cc15e51 362 assertEquals("Test the number of root functions found", 1, rootFunctions.size());
55f777f4 363 ICalledFunction rootFunction = rootFunctions.get(0);
4cc15e51
SF
364
365 // Test the segments links
366 assertEquals("Children number:First parent", 3, rootFunction.getChildren().size());
55f777f4
PT
367 List<@NonNull ICalledFunction> firstDepthFunctions = rootFunctions.get(0).getChildren();
368 ICalledFunction firstChild = firstDepthFunctions.get(0);
369 ICalledFunction secondChild = firstDepthFunctions.get(1);
370 ICalledFunction thirdChild = firstDepthFunctions.get(2);
371 assertEquals("Test parenthood: First child", rootFunction.getSymbol(), NonNullUtils.checkNotNull(firstChild.getParent()).getSymbol());
372 assertEquals("Test parenthood: Second parent", rootFunction.getSymbol(), NonNullUtils.checkNotNull(secondChild.getParent()).getSymbol());
373 assertEquals("Test parenthood: Third parent", rootFunction.getSymbol(), NonNullUtils.checkNotNull(thirdChild.getParent()).getSymbol());
4cc15e51 374 assertEquals("Children number: First child", 1, firstChild.getChildren().size());
55f777f4
PT
375 ICalledFunction leaf = firstChild.getChildren().get(0);
376 assertEquals("Test parenthood: Third parent", firstChild.getSymbol(), NonNullUtils.checkNotNull(leaf.getParent()).getSymbol());
4cc15e51
SF
377 assertTrue("Children number:leaf", leaf.getChildren().isEmpty());
378
379 // Test the segments self time
380 assertEquals("Parent's self time", 30, rootFunction.getSelfTime());
381 assertEquals("First child's self time", 25, firstChild.getSelfTime());
382 assertEquals("Second child's self time", 20, secondChild.getSelfTime());
383 assertEquals("Third child's self time", 20, thirdChild.getSelfTime());
384 assertEquals("Leaf's self time", 5, leaf.getSelfTime());
385 // Test the segments duration
386 assertEquals("Test first function's duration", 100, rootFunction.getLength());
387 assertEquals("Test first child's duration", 30, firstChild.getLength());
388 assertEquals("Test second child's duration", 20, secondChild.getLength());
389 assertEquals("Test third child's duration", 20, thirdChild.getLength());
390 assertEquals("Test leaf's duration", 5, leaf.getLength());
391
392 // Test the segments Depth
393 assertEquals("Depth: Parent", 0, rootFunction.getDepth());
394 assertEquals("Depth: First child", 1, firstChild.getDepth());
395 assertEquals("Depth: Second child", 1, secondChild.getDepth());
396 assertEquals("Depth: Third child", 1, thirdChild.getDepth());
397 assertEquals("Depth: Leaf", 2, leaf.getDepth());
398
399 // Test if the first child and the third one have the same address
55f777f4 400 assertEquals("Test the address of two functions", firstChild.getSymbol(), thirdChild.getSymbol());
ded2b27f 401 cga.dispose();
4cc15e51
SF
402 }
403}
This page took 0.0472 seconds and 5 git commands to generate.