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