Commit | Line | Data |
---|---|---|
3ef48ce1 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 | ||
10 | package org.eclipse.tracecompass.analysis.timing.core.tests.flamegraph; | |
11 | ||
12 | import static org.junit.Assert.assertEquals; | |
13 | import static org.junit.Assert.assertNotNull; | |
14 | import static org.junit.Assert.assertTrue; | |
15 | ||
16 | import java.util.Collections; | |
17 | import java.util.List; | |
18 | ||
19 | import org.eclipse.core.runtime.IProgressMonitor; | |
20 | import org.eclipse.core.runtime.NullProgressMonitor; | |
21 | import org.eclipse.jdt.annotation.NonNull; | |
22 | import org.eclipse.jdt.annotation.Nullable; | |
23 | import org.eclipse.tracecompass.common.core.NonNullUtils; | |
24 | import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.AggregatedCalledFunction; | |
25 | import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.CallGraphAnalysis; | |
26 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; | |
27 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; | |
28 | import org.eclipse.tracecompass.statesystem.core.StateSystemFactory; | |
29 | import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend; | |
30 | import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory; | |
31 | import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; | |
32 | import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect; | |
33 | import org.junit.Test; | |
34 | ||
35 | /** | |
36 | * Test the CallGraphAnalysis.This creates a virtual state system in each test | |
37 | * and tests the aggregation tree returned by the CallGraphAnalysis. | |
38 | * | |
39 | * @author Sonia Farrah | |
40 | * | |
41 | */ | |
42 | public class AggregationTreeTest { | |
43 | ||
44 | private static final @NonNull String PROCESS_PATH = "Processes"; | |
45 | private static final @NonNull String THREAD_PATH = "Thread"; | |
46 | private static final @NonNull String CALLSTACK_PATH = "CallStack"; | |
47 | private static final String QUARK_0 = "0"; | |
48 | private static final String QUARK_1 = "1"; | |
49 | private static final String QUARK_2 = "2"; | |
50 | private static final String QUARK_3 = "3"; | |
51 | private static final Integer SMALL_AMOUNT_OF_SEGMENT = 3; | |
52 | private static final int LARGE_AMOUNT_OF_SEGMENTS = 1000; | |
53 | private static final String @NonNull [] CSP = { CALLSTACK_PATH }; | |
54 | private static final String @NonNull [] PP = { PROCESS_PATH }; | |
55 | private static final String @NonNull [] TP = { THREAD_PATH }; | |
56 | ||
57 | /** | |
58 | * This class is used to make the CallGraphAnalysis's method | |
59 | * iterateOverStateSystem() visible to test | |
60 | */ | |
61 | private class CGAnalysis extends CallGraphAnalysis { | |
62 | ||
63 | @Override | |
64 | protected boolean iterateOverStateSystem(@Nullable ITmfStateSystem ss, String[] threadsPattern, String[] processesPattern, String[] callStackPath, IProgressMonitor monitor) { | |
65 | return super.iterateOverStateSystem(ss, threadsPattern, processesPattern, callStackPath, monitor); | |
66 | } | |
67 | ||
68 | @Override | |
69 | public @NonNull Iterable<@NonNull ISegmentAspect> getSegmentAspects() { | |
70 | return Collections.EMPTY_LIST; | |
71 | } | |
72 | ||
73 | } | |
74 | ||
75 | private static ITmfStateSystemBuilder createFixture() { | |
76 | IStateHistoryBackend backend; | |
77 | backend = StateHistoryBackendFactory.createInMemoryBackend("Test", 0L); | |
78 | ITmfStateSystemBuilder fixture = StateSystemFactory.newStateSystem(backend); | |
79 | return fixture; | |
80 | } | |
81 | ||
82 | /** | |
83 | * Test an empty state system. | |
84 | */ | |
85 | @Test | |
86 | public void emptyStateSystemTest() { | |
87 | ITmfStateSystemBuilder fixture = createFixture(); | |
88 | fixture.closeHistory(1002); | |
89 | CGAnalysis cga = new CGAnalysis(); | |
90 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
91 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
92 | assertNotNull(threads); | |
93 | assertEquals("Number of threads found", 0, threads.size()); | |
94 | } | |
95 | ||
96 | /** | |
97 | * Test cascade state system. The call stack's structure used in this test | |
98 | * is shown below: | |
99 | * | |
100 | * <pre> | |
101 | * ________ | |
102 | * ______ | |
103 | * ____ | |
104 | * | |
105 | * </pre> | |
106 | */ | |
107 | @Test | |
108 | public void cascadeTest() { | |
109 | ITmfStateSystemBuilder fixture = createFixture(); | |
110 | // Build the state system | |
111 | long start = 1; | |
112 | long end = 1001; | |
113 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
114 | for (int i = 1; i <= SMALL_AMOUNT_OF_SEGMENT; i++) { | |
115 | int quark = fixture.getQuarkRelativeAndAdd(parentQuark, Integer.toString(i)); | |
116 | TmfStateValue statev = TmfStateValue.newValueLong(i); | |
117 | fixture.modifyAttribute(start, TmfStateValue.nullValue(), quark); | |
118 | fixture.modifyAttribute(start + i, statev, quark); | |
119 | fixture.modifyAttribute(end - i, TmfStateValue.nullValue(), quark); | |
120 | } | |
121 | ||
122 | fixture.closeHistory(1002); | |
123 | // Execute the CallGraphAnalysis | |
124 | CGAnalysis cga = new CGAnalysis(); | |
125 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
126 | @NonNull | |
127 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
128 | // Test the threads generated by the analysis | |
129 | assertNotNull(threads); | |
130 | assertEquals("Number of thread nodes Found", 1, threads.size()); | |
131 | assertEquals("Number of root functions ", 1, threads.get(0).getChildren().size()); | |
132 | Object[] children = threads.get(0).getChildren().toArray(); | |
133 | AggregatedCalledFunction firstFunction = (AggregatedCalledFunction) children[0]; | |
134 | assertEquals("Children number: First function", 1, firstFunction.getChildren().size()); | |
135 | Object @NonNull [] firstFunctionChildren = firstFunction.getChildren().toArray(); | |
136 | AggregatedCalledFunction secondFunction = (AggregatedCalledFunction) firstFunctionChildren[0]; | |
137 | assertEquals("Children number: Second function", 1, secondFunction.getChildren().size()); | |
138 | Object @NonNull [] secondFunctionChildren = secondFunction.getChildren().toArray(); | |
139 | AggregatedCalledFunction thirdFunction = (AggregatedCalledFunction) secondFunctionChildren[0]; | |
140 | assertEquals("Children number: Third function", 0, thirdFunction.getChildren().size()); | |
141 | // Test links | |
142 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(secondFunction.getParent()).getSymbol(), firstFunction.getSymbol()); | |
143 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(thirdFunction.getParent()).getSymbol(), secondFunction.getSymbol()); | |
144 | // Test duration | |
145 | assertEquals("Test first function's duration", 998, firstFunction.getDuration()); | |
146 | assertEquals("Test second function's duration", 996, secondFunction.getDuration()); | |
147 | assertEquals("Test third function's duration", 994, thirdFunction.getDuration()); | |
148 | // Test self time | |
149 | assertEquals("Test first function's self time", 2, firstFunction.getSelfTime()); | |
150 | assertEquals("Test second function's self time", 2, secondFunction.getSelfTime()); | |
151 | assertEquals("Test third function's self time", 994, thirdFunction.getSelfTime()); | |
152 | // Test depth | |
153 | assertEquals("Test first function's depth", 0, firstFunction.getDepth()); | |
154 | assertEquals("Test second function's depth", 1, secondFunction.getDepth()); | |
155 | assertEquals("Test third function's depth", 2, thirdFunction.getDepth()); | |
156 | // Test number of calls | |
157 | assertEquals("Test first function's nombre of calls", 1, firstFunction.getNbCalls()); | |
158 | assertEquals("Test second function's nombre of calls", 1, secondFunction.getNbCalls()); | |
159 | assertEquals("Test third function's nombre of calls", 1, thirdFunction.getNbCalls()); | |
160 | } | |
161 | ||
162 | /** | |
163 | * Test a state system with a two calls for the same function. The call | |
164 | * stack's structure used in this test is shown below: | |
165 | * | |
166 | * <pre> | |
167 | * Aggregated tree | |
168 | * ___ main___ ___ main___ | |
169 | * _1_ _1_ => _1_ | |
170 | * _1_ _1_ | |
171 | * </pre> | |
172 | */ | |
173 | @Test | |
174 | public void treeTest() { | |
175 | ITmfStateSystemBuilder fixture = createFixture(); | |
176 | // Build the state system | |
177 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
178 | int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0); | |
179 | TmfStateValue statev = TmfStateValue.newValueLong(0); | |
180 | fixture.modifyAttribute(0, statev, quark); | |
181 | fixture.modifyAttribute(100, TmfStateValue.nullValue(), quark); | |
182 | ||
183 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1); | |
184 | statev = TmfStateValue.newValueLong(1); | |
185 | fixture.modifyAttribute(0, statev, quark); | |
186 | fixture.modifyAttribute(50, TmfStateValue.nullValue(), quark); | |
187 | fixture.modifyAttribute(60, statev, quark); | |
188 | fixture.modifyAttribute(90, TmfStateValue.nullValue(), quark); | |
189 | ||
190 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_2); | |
191 | fixture.modifyAttribute(0, statev, quark); | |
192 | fixture.modifyAttribute(30, TmfStateValue.nullValue(), quark); | |
193 | fixture.closeHistory(102); | |
194 | ||
195 | // Execute the CallGraphAnalysis | |
196 | CGAnalysis cga = new CGAnalysis(); | |
197 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
198 | @NonNull | |
199 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
200 | // Test the threads generated by the analysis | |
201 | assertNotNull(threads); | |
202 | assertEquals("Number of thread nodes Found", 1, threads.size()); | |
203 | Object[] children = threads.get(0).getChildren().toArray(); | |
204 | AggregatedCalledFunction firstFunction = (AggregatedCalledFunction) children[0]; | |
205 | assertEquals("Children number: First function", 1, firstFunction.getChildren().size()); | |
206 | Object[] firstFunctionChildren = firstFunction.getChildren().toArray(); | |
207 | AggregatedCalledFunction secondFunction = (AggregatedCalledFunction) firstFunctionChildren[0]; | |
208 | assertEquals("Children number: Second function", 1, secondFunction.getChildren().size()); | |
209 | Object[] secondFunctionChildren = secondFunction.getChildren().toArray(); | |
210 | AggregatedCalledFunction thirdFunction = (AggregatedCalledFunction) secondFunctionChildren[0]; | |
211 | assertEquals("Children number: Third function", 0, thirdFunction.getChildren().size()); | |
212 | // Test links | |
213 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(secondFunction.getParent()).getSymbol(), firstFunction.getSymbol()); | |
214 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(thirdFunction.getParent()).getSymbol(), secondFunction.getSymbol()); | |
215 | // Test duration | |
216 | assertEquals("Test first function's duration", 100, firstFunction.getDuration()); | |
217 | assertEquals("Test second function's duration", 80, secondFunction.getDuration()); | |
218 | assertEquals("Test third function's duration", 30, thirdFunction.getDuration()); | |
219 | // Test self time | |
220 | assertEquals("Test first function's self time", 20, firstFunction.getSelfTime()); | |
221 | assertEquals("Test second function's self time", 50, secondFunction.getSelfTime()); | |
222 | assertEquals("Test third function's self time", 30, thirdFunction.getSelfTime()); | |
223 | // Test depth | |
224 | assertEquals("Test first function's depth", 0, firstFunction.getDepth()); | |
225 | assertEquals("Test second function's depth", 1, secondFunction.getDepth()); | |
226 | assertEquals("Test third function's depth", 2, thirdFunction.getDepth()); | |
227 | // Test number of calls | |
228 | assertEquals("Test first function's number of calls", 1, firstFunction.getNbCalls()); | |
229 | assertEquals("Test second function's number of calls", 2, secondFunction.getNbCalls()); | |
230 | assertEquals("Test third function's number of calls", 1, thirdFunction.getNbCalls()); | |
231 | } | |
232 | ||
233 | /** | |
234 | * Test the callees merge. The call stack's structure used in this test is | |
235 | * shown below: | |
236 | * | |
237 | * <pre> | |
238 | * Aggregated tree | |
239 | * ___ main___ ___ main___ | |
240 | * _1_ _1_ => _1_ | |
241 | * _2_ _3_ _2_ _3_ | |
242 | * </pre> | |
243 | */ | |
244 | @Test | |
245 | public void mergeFirstLevelCalleesTest() { | |
246 | ITmfStateSystemBuilder fixture = createFixture(); | |
247 | // Build the state system | |
248 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
249 | int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0); | |
250 | TmfStateValue statev = TmfStateValue.newValueLong(0); | |
251 | fixture.modifyAttribute(0, statev, quark); | |
252 | fixture.modifyAttribute(100, TmfStateValue.nullValue(), quark); | |
253 | ||
254 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1); | |
255 | statev = TmfStateValue.newValueLong(1); | |
256 | fixture.modifyAttribute(0, statev, quark); | |
257 | fixture.modifyAttribute(50, TmfStateValue.nullValue(), quark); | |
258 | fixture.modifyAttribute(60, statev, quark); | |
259 | fixture.modifyAttribute(90, TmfStateValue.nullValue(), quark); | |
260 | ||
261 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_2); | |
262 | statev = TmfStateValue.newValueLong(2); | |
263 | fixture.modifyAttribute(0, statev, quark); | |
264 | fixture.modifyAttribute(30, TmfStateValue.nullValue(), quark); | |
265 | statev = TmfStateValue.newValueLong(3); | |
266 | fixture.modifyAttribute(60, statev, quark); | |
267 | fixture.modifyAttribute(80, TmfStateValue.nullValue(), quark); | |
268 | fixture.closeHistory(102); | |
269 | ||
270 | // Execute the CallGraphAnalysis | |
271 | CGAnalysis cga = new CGAnalysis(); | |
272 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
273 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
274 | // Test the threads generated by the analysis | |
275 | assertNotNull(threads); | |
276 | assertEquals("Number of thread nodes Found", 1, threads.size()); | |
277 | assertEquals("Number of root functions ", 1, threads.get(0).getChildren().size()); | |
278 | Object[] children = threads.get(0).getChildren().toArray(); | |
279 | ||
280 | AggregatedCalledFunction firstFunction = (AggregatedCalledFunction) children[0]; | |
281 | assertEquals("Children number: First function", 1, firstFunction.getChildren().size()); | |
282 | Object[] firstFunctionChildren = firstFunction.getChildren().toArray(); | |
283 | AggregatedCalledFunction secondFunction = (AggregatedCalledFunction) firstFunctionChildren[0]; | |
284 | assertEquals("Children number: Second function", 2, secondFunction.getChildren().size()); | |
285 | Object[] secondFunctionChildren = secondFunction.getChildren().toArray(); | |
286 | AggregatedCalledFunction leaf1 = (AggregatedCalledFunction) secondFunctionChildren[0]; | |
287 | AggregatedCalledFunction leaf2 = (AggregatedCalledFunction) secondFunctionChildren[1]; | |
288 | assertEquals("Children number: First leaf function", 0, leaf1.getChildren().size()); | |
289 | assertEquals("Children number: Second leaf function", 0, leaf2.getChildren().size()); | |
290 | // Test links | |
291 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(secondFunction.getParent()).getSymbol(), firstFunction.getSymbol()); | |
292 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(leaf1.getParent()).getSymbol(), secondFunction.getSymbol()); | |
293 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(leaf2.getParent()).getSymbol(), secondFunction.getSymbol()); | |
294 | // Test duration | |
295 | assertEquals("Test first function's duration", 100, firstFunction.getDuration()); | |
296 | assertEquals("Test second function's duration", 80, secondFunction.getDuration()); | |
297 | assertEquals("Test first leaf's duration", 30, leaf1.getDuration()); | |
298 | assertEquals("Test second leaf's duration", 20, leaf2.getDuration()); | |
299 | // Test self time | |
300 | assertEquals("Test first function's self time", 20, firstFunction.getSelfTime()); | |
301 | assertEquals("Test second function's self time", 30, secondFunction.getSelfTime()); | |
302 | assertEquals("Test first leaf's self time", 30, leaf1.getSelfTime()); | |
303 | assertEquals("Test second leaf's self time", 20, leaf2.getSelfTime()); | |
304 | // Test depth | |
305 | assertEquals("Test first function's depth", 0, firstFunction.getDepth()); | |
306 | assertEquals("Test second function's depth", 1, secondFunction.getDepth()); | |
307 | assertEquals("Test first leaf's depth", 2, leaf1.getDepth()); | |
308 | assertEquals("Test second leaf's depth", 2, leaf2.getDepth()); | |
309 | // Test number of calls | |
310 | assertEquals("Test first function's number of calls", 1, firstFunction.getNbCalls()); | |
311 | assertEquals("Test second function's number of calls", 2, secondFunction.getNbCalls()); | |
312 | assertEquals("Test first leaf's number of calls", 1, leaf1.getNbCalls()); | |
313 | assertEquals("Test second leaf's number of calls", 1, leaf2.getNbCalls()); | |
314 | } | |
315 | ||
316 | /** | |
317 | * Build a call stack example.This call stack's structure is shown below : | |
318 | * | |
319 | * <pre> | |
320 | * ___ main____ | |
321 | * ___1___ _1_ | |
322 | * _2_ _3_ _2_ | |
323 | * _4_ _4_ | |
324 | * </pre> | |
325 | */ | |
326 | private static void buildCallStack(ITmfStateSystemBuilder fixture) { | |
327 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
328 | // Create the first function | |
329 | int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0); | |
330 | TmfStateValue statev = TmfStateValue.newValueLong(0); | |
331 | fixture.modifyAttribute(0, statev, quark); | |
332 | fixture.modifyAttribute(100, TmfStateValue.nullValue(), quark); | |
333 | // Create the first level functions | |
334 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1); | |
335 | statev = TmfStateValue.newValueLong(1); | |
336 | fixture.modifyAttribute(0, statev, quark); | |
337 | fixture.modifyAttribute(50, TmfStateValue.nullValue(), quark); | |
338 | fixture.modifyAttribute(60, statev, quark); | |
339 | fixture.modifyAttribute(100, TmfStateValue.nullValue(), quark); | |
340 | // Create the third function | |
341 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_2); | |
342 | statev = TmfStateValue.newValueLong(2); | |
343 | fixture.modifyAttribute(0, statev, quark); | |
344 | fixture.modifyAttribute(10, TmfStateValue.nullValue(), quark); | |
345 | ||
346 | statev = TmfStateValue.newValueLong(3); | |
347 | fixture.modifyAttribute(20, statev, quark); | |
348 | fixture.modifyAttribute(30, TmfStateValue.nullValue(), quark); | |
349 | ||
350 | statev = TmfStateValue.newValueLong(2); | |
351 | fixture.modifyAttribute(60, statev, quark); | |
352 | fixture.modifyAttribute(90, TmfStateValue.nullValue(), quark); | |
353 | ||
354 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_3); | |
355 | statev = TmfStateValue.newValueLong(4); | |
356 | fixture.modifyAttribute(0, statev, quark); | |
357 | fixture.modifyAttribute(10, TmfStateValue.nullValue(), quark); | |
358 | ||
359 | fixture.modifyAttribute(60, statev, quark); | |
360 | fixture.modifyAttribute(80, TmfStateValue.nullValue(), quark); | |
361 | fixture.closeHistory(102); | |
362 | } | |
363 | ||
364 | /** | |
365 | * Test the merge of The callees children. The call stack's structure used | |
366 | * in this test is shown below: | |
367 | * | |
368 | * <pre> | |
369 | * Aggregated tree | |
370 | * ___ main____ ____ main____ | |
371 | * ___1___ _1_ _1_ | |
372 | * _2_ _3_ _2_ => _2_ _3_ | |
373 | * _4_ _4_ _4_ | |
374 | * </pre> | |
375 | */ | |
376 | @Test | |
377 | public void mergeSecondLevelCalleesTest() { | |
378 | ITmfStateSystemBuilder fixture = createFixture(); | |
379 | buildCallStack(fixture); | |
380 | // Execute the CallGraphAnalysis | |
381 | CGAnalysis cga = new CGAnalysis(); | |
382 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
383 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
384 | // Test the threads generated by the analysis | |
385 | assertNotNull(threads); | |
386 | assertEquals("Number of thread nodes Found", 1, threads.size()); | |
387 | assertEquals("Number of root functions ", 1, threads.get(0).getChildren().size()); | |
388 | Object[] children = threads.get(0).getChildren().toArray(); | |
389 | AggregatedCalledFunction main = (AggregatedCalledFunction) children[0]; | |
390 | assertEquals("Children number: main", 1, main.getChildren().size()); | |
391 | Object[] mainChildren = main.getChildren().toArray(); | |
392 | AggregatedCalledFunction function1 = (AggregatedCalledFunction) mainChildren[0]; | |
393 | assertEquals("Children number: first function", 2, function1.getChildren().size()); | |
394 | Object[] firstFunctionChildren = function1.getChildren().toArray(); | |
395 | AggregatedCalledFunction function2 = (AggregatedCalledFunction) firstFunctionChildren[0]; | |
396 | AggregatedCalledFunction function3 = (AggregatedCalledFunction) firstFunctionChildren[1]; | |
397 | assertEquals("Children number: First child", 1, function2.getChildren().size()); | |
398 | assertEquals("Children number: Second child", 0, function3.getChildren().size()); | |
399 | Object[] firstChildCallee = function2.getChildren().toArray(); | |
400 | AggregatedCalledFunction function4 = (AggregatedCalledFunction) firstChildCallee[0]; | |
401 | assertEquals("Children number: leaf function", 0, function4.getChildren().size()); | |
402 | // Test links | |
403 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function1.getParent()).getSymbol(), main.getSymbol()); | |
404 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function2.getParent()).getSymbol(), function1.getSymbol()); | |
405 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function3.getParent()).getSymbol(), function1.getSymbol()); | |
406 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function4.getParent()).getSymbol(), function2.getSymbol()); | |
407 | // Test duration | |
408 | assertEquals("Test main's duration", 100, main.getDuration()); | |
409 | assertEquals("Test first function's duration", 90, function1.getDuration()); | |
410 | assertEquals("Test first child's duration", 40, function2.getDuration()); | |
411 | assertEquals("Test second child's duration", 10, function3.getDuration()); | |
412 | assertEquals("Test leaf's duration", 30, function4.getDuration()); | |
413 | // Test self time | |
414 | assertEquals("Test main's self time", 10, main.getSelfTime()); | |
415 | assertEquals("Test first function's self time", 40, function1.getSelfTime()); | |
416 | assertEquals("Test first child's self time", 10, | |
417 | function2.getSelfTime()); | |
418 | assertEquals("Test second child's self time", 10, function3.getSelfTime()); | |
419 | assertEquals("Test leaf's self time", 30, function4.getSelfTime()); | |
420 | // Test depth | |
421 | assertEquals("Test main function's depth", 0, main.getDepth()); | |
422 | assertEquals("Test first function's depth", 1, function1.getDepth()); | |
423 | assertEquals("Test first child's depth", 2, function2.getDepth()); | |
424 | assertEquals("Test second child's depth", 2, function3.getDepth()); | |
425 | assertEquals("Test leaf's depth", 3, function4.getDepth()); | |
426 | // Test number of calls | |
427 | assertEquals("Test main's number of calls", 1, main.getNbCalls()); | |
428 | assertEquals("Test first function's number of calls", 2, function1.getNbCalls()); | |
429 | assertEquals("Test first child's number of calls", 2, function2.getNbCalls()); | |
430 | assertEquals("Test second child's number of calls", 1, function3.getNbCalls()); | |
431 | assertEquals("Test leaf's number of calls", 2, function4.getNbCalls()); | |
432 | } | |
433 | ||
434 | /** | |
435 | * Test state system with a large amount of segments. All segments have the | |
436 | * same length. The call stack's structure used in this test is shown below: | |
437 | * | |
438 | * <pre> | |
439 | * _____ | |
440 | * _____ | |
441 | * _____ | |
442 | * ..... | |
443 | * </pre> | |
444 | */ | |
445 | @Test | |
446 | public void largeTest() { | |
447 | ITmfStateSystemBuilder fixture = createFixture(); | |
448 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
449 | for (int i = 0; i < LARGE_AMOUNT_OF_SEGMENTS; i++) { | |
450 | TmfStateValue statev = TmfStateValue.newValueLong(i); | |
451 | fixture.pushAttribute(0, statev, parentQuark); | |
452 | } | |
453 | for (int i = 0; i < LARGE_AMOUNT_OF_SEGMENTS; i++) { | |
454 | fixture.popAttribute(10, parentQuark); | |
455 | } | |
456 | fixture.closeHistory(11); | |
457 | // Execute the callGraphAnalysis | |
458 | CGAnalysis cga = new CGAnalysis(); | |
459 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
460 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
461 | // Test the threads generated by the analysis | |
462 | assertNotNull(threads); | |
463 | Object[] children = threads.get(0).getChildren().toArray(); | |
464 | AggregatedCalledFunction parent = (AggregatedCalledFunction) children[0]; | |
465 | for (int i = 1; i < LARGE_AMOUNT_OF_SEGMENTS; i++) { | |
466 | children = parent.getChildren().toArray(); | |
467 | AggregatedCalledFunction child = (AggregatedCalledFunction) children[0]; | |
468 | assertEquals("Test parenthood", NonNullUtils.checkNotNull(child.getParent()).getSymbol(), NonNullUtils.checkNotNull(parent.getSymbol())); | |
469 | parent = child; | |
470 | } | |
471 | } | |
472 | ||
473 | /** | |
474 | * Test mutliRoots state system.This tests if a root function called twice | |
475 | * will be merged into one function or not. The call stack's structure used | |
476 | * in this test is shown below: | |
477 | * | |
478 | * <pre> | |
479 | * Aggregated tree | |
480 | * _1_ _1_ => _1_ | |
481 | * _2_ _3_ _2_ _3_ | |
482 | * </pre> | |
483 | */ | |
484 | @Test | |
485 | public void multiFunctionRootsTest() { | |
486 | ITmfStateSystemBuilder fixture = createFixture(); | |
487 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
488 | // Create the first root function | |
489 | int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0); | |
490 | TmfStateValue statev = TmfStateValue.newValueLong(1); | |
491 | fixture.modifyAttribute(0, statev, quark); | |
492 | fixture.modifyAttribute(20, TmfStateValue.nullValue(), quark); | |
493 | // Create the second root function | |
494 | fixture.modifyAttribute(30, statev, quark); | |
495 | fixture.modifyAttribute(50, TmfStateValue.nullValue(), quark); | |
496 | // Create the first root function's callee | |
497 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1); | |
498 | statev = TmfStateValue.newValueLong(2); | |
499 | fixture.modifyAttribute(0, statev, quark); | |
500 | fixture.modifyAttribute(10, TmfStateValue.nullValue(), quark); | |
501 | // Create the second root function's callee | |
502 | statev = TmfStateValue.newValueLong(3); | |
503 | fixture.modifyAttribute(30, statev, quark); | |
504 | fixture.modifyAttribute(40, TmfStateValue.nullValue(), quark); | |
505 | fixture.closeHistory(51); | |
506 | ||
507 | // Execute the callGraphAnalysis | |
508 | CGAnalysis cga = new CGAnalysis(); | |
509 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
510 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
511 | // Test the threads generated by the analysis | |
512 | assertNotNull(threads); | |
513 | assertEquals("Number of thread nodes Found", 1, threads.size()); | |
514 | assertEquals("Number of root functions ", 1, threads.get(0).getChildren().size()); | |
515 | Object[] children = threads.get(0).getChildren().toArray(); | |
516 | AggregatedCalledFunction firstFunction = (AggregatedCalledFunction) children[0]; | |
517 | assertEquals("Children number: First function", 2, firstFunction.getChildren().size()); | |
518 | Object[] firstFunctionChildren = firstFunction.getChildren().toArray(); | |
519 | AggregatedCalledFunction function2 = (AggregatedCalledFunction) firstFunctionChildren[0]; | |
520 | AggregatedCalledFunction function3 = (AggregatedCalledFunction) firstFunctionChildren[1]; | |
521 | assertEquals("Children number: Second function", 0, function2.getChildren().size()); | |
522 | assertEquals("Children number: Third function", 0, function3.getChildren().size()); | |
523 | // Test links | |
524 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function2.getParent()).getSymbol(), firstFunction.getSymbol()); | |
525 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function3.getParent()).getSymbol(), firstFunction.getSymbol()); | |
526 | // Test duration | |
527 | assertEquals("Test first function's duration", 40, firstFunction.getDuration()); | |
528 | assertEquals("Test second function's duration", 10, function2.getDuration()); | |
529 | assertEquals("Test third function's duration", 10, function3.getDuration()); | |
530 | // Test self time | |
531 | assertEquals("Test first function's self time", 20, firstFunction.getSelfTime()); | |
532 | assertEquals("Test second function's self time", 10, function2.getSelfTime()); | |
533 | assertEquals("Test third function's self time", 10, function2.getSelfTime()); | |
534 | // Test depth | |
535 | assertEquals("Test first function's depth", 0, firstFunction.getDepth()); | |
536 | assertEquals("Test second function's depth", 1, function2.getDepth()); | |
537 | assertEquals("Test third function's depth", 1, function3.getDepth()); | |
538 | // Test number of calls | |
539 | assertEquals("Test first function's number of calls", 2, firstFunction.getNbCalls()); | |
540 | assertEquals("Test second function's number of calls", 1, function2.getNbCalls()); | |
541 | assertEquals("Test third function's number of calls", 1, function3.getNbCalls()); | |
542 | ||
543 | } | |
544 | ||
545 | /** | |
546 | * Test mutliRoots state system. The call stack's structure used in this | |
547 | * test is shown below: | |
548 | * | |
549 | * <pre> | |
550 | * Aggregated tree | |
551 | * _0_ _1_ => _0_ _1_ | |
552 | * _2_ _2_ _2_ _2_ | |
553 | * | |
554 | * </pre> | |
555 | */ | |
556 | @Test | |
557 | public void multiFunctionRootsSecondTest() { | |
558 | ITmfStateSystemBuilder fixture = createFixture(); | |
559 | int parentQuark = fixture.getQuarkAbsoluteAndAdd(PROCESS_PATH, THREAD_PATH, CALLSTACK_PATH); | |
560 | // Create the first root function | |
561 | int quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_0); | |
562 | TmfStateValue statev = TmfStateValue.newValueLong(0); | |
563 | fixture.modifyAttribute(0, statev, quark); | |
564 | fixture.modifyAttribute(20, TmfStateValue.nullValue(), quark); | |
565 | // Create the second root function | |
566 | statev = TmfStateValue.newValueLong(1); | |
567 | fixture.modifyAttribute(30, statev, quark); | |
568 | fixture.modifyAttribute(50, TmfStateValue.nullValue(), quark); | |
569 | // Create the first root function's callee | |
570 | quark = fixture.getQuarkRelativeAndAdd(parentQuark, QUARK_1); | |
571 | statev = TmfStateValue.newValueLong(2); | |
572 | fixture.modifyAttribute(0, statev, quark); | |
573 | fixture.modifyAttribute(10, TmfStateValue.nullValue(), quark); | |
574 | // Create the second root function's callee | |
575 | fixture.modifyAttribute(30, statev, quark); | |
576 | fixture.modifyAttribute(40, TmfStateValue.nullValue(), quark); | |
577 | fixture.closeHistory(51); | |
578 | ||
579 | // Execute the callGraphAnalysis | |
580 | CGAnalysis cga = new CGAnalysis(); | |
581 | assertTrue(cga.iterateOverStateSystem(fixture, TP, PP, CSP, new NullProgressMonitor())); | |
582 | List<AggregatedCalledFunction> threads = cga.getThreadNodes(); | |
583 | // Test the threads generated by the analysis | |
584 | assertNotNull(threads); | |
585 | assertEquals("Number of thread nodes Found", 1, threads.size()); | |
586 | assertEquals("Number of root functions ", 2, threads.get(0).getChildren().size()); | |
587 | Object[] children = threads.get(0).getChildren().toArray(); | |
588 | AggregatedCalledFunction firstFunction = (AggregatedCalledFunction) children[0]; | |
589 | AggregatedCalledFunction secondFunction = (AggregatedCalledFunction) children[1]; | |
590 | ||
591 | assertEquals("Children number: First function", 1, firstFunction.getChildren().size()); | |
592 | assertEquals("Children number: Second function", 1, secondFunction.getChildren().size()); | |
593 | Object[] firstFunctionChildren = firstFunction.getChildren().toArray(); | |
594 | Object[] secondFunctionChildren = secondFunction.getChildren().toArray(); | |
595 | AggregatedCalledFunction function3 = (AggregatedCalledFunction) firstFunctionChildren[0]; | |
596 | AggregatedCalledFunction function4 = (AggregatedCalledFunction) secondFunctionChildren[0]; | |
597 | ||
598 | assertEquals("Children number: third function", 0, function3.getChildren().size()); | |
599 | assertEquals("Children number: fourth function", 0, function4.getChildren().size()); | |
600 | // Test links | |
601 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function3.getParent()).getSymbol(), firstFunction.getSymbol()); | |
602 | assertEquals("Test parenthood ", NonNullUtils.checkNotNull(function4.getParent()).getSymbol(), secondFunction.getSymbol()); | |
603 | // Test duration | |
604 | assertEquals("Test second function's duration", 20, firstFunction.getDuration()); | |
605 | assertEquals("Test second function's duration", 20, secondFunction.getDuration()); | |
606 | assertEquals("Test first leaf's duration", 10, function3.getDuration()); | |
607 | assertEquals("Test second leaf's duration", 10, function4.getDuration()); | |
608 | // Test self time | |
609 | assertEquals("Test first function's self time", 10, firstFunction.getSelfTime()); | |
610 | assertEquals("Test second function's duration", 10, secondFunction.getSelfTime()); | |
611 | assertEquals("Test second function's self time", 10, function3.getSelfTime()); | |
612 | assertEquals("Test second function's self time", 10, function4.getSelfTime()); | |
613 | // Test depth | |
614 | assertEquals("Test first function's depth", 0, firstFunction.getDepth()); | |
615 | assertEquals("Test first function's depth", 0, secondFunction.getDepth()); | |
616 | assertEquals("Test third function's depth", 1, function3.getDepth()); | |
617 | assertEquals("Test third function's depth", 1, function4.getDepth()); | |
618 | // Test number of calls | |
619 | assertEquals("Test first function's number of calls", 1, firstFunction.getNbCalls()); | |
620 | assertEquals("Test first function's number of calls", 1, secondFunction.getNbCalls()); | |
621 | assertEquals("Test third function's number of calls", 1, function3.getNbCalls()); | |
622 | assertEquals("Test third function's number of calls", 1, function4.getNbCalls()); | |
623 | ||
624 | } | |
625 | } |