4
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
20
%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
%%% Define to run outside of test server
24
%%% -define(STANDALONE,1).
27
%%% Define for debug output
33
%% Exported end user tests
34
-export([basic_test/0, on_load_test/1, modules_test/1]).
36
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37
%% Test server related stuff
41
-define(config(A,B),config(A,B)).
44
-include("test_server.hrl").
49
-define(line, erlang:display({?MODULE,?LINE}), ).
51
-define(dbgformat(A,B),io:format(A,B)).
54
-define(line, noop, ).
56
-define(dbgformat(A,B),noop).
60
config(priv_dir, _) ->
62
config(data_dir, _) ->
65
%% When run in test server.
66
-export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
67
-export([basic/1, on_load/1, modules/1]).
69
init_per_testcase(_Case, Config) ->
70
?line Dog=test_server:timetrap(test_server:seconds(30)),
71
[{watchdog, Dog}|Config].
73
fin_per_testcase(_Case, Config) ->
74
erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_count]),
75
erlang:trace_pattern(on_load, false, [local,meta,call_count]),
76
erlang:trace(all, false, [all]),
77
Dog=?config(watchdog, Config),
78
test_server:timetrap_cancel(Dog),
82
["Test the cprof profiling tool."];
84
case test_server:is_native(?MODULE) of
86
false -> [basic, on_load, modules]
88
% pause_and_restart, combo]
91
not_run(Config) when is_list(Config) ->
92
{skipped,"Native code"}.
97
["Tests basic profiling"];
98
basic(Config) when is_list(Config) ->
104
["Tests profiling of unloaded module"];
105
on_load(Config) when is_list(Config) ->
106
on_load_test(Config).
111
["Tests profiling of several modules"];
112
modules(Config) when is_list(Config) ->
113
modules_test(Config).
115
-endif. %-ifdef(STANDALONE). ... -else.
117
%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126
?line M2__1 = M2 + 1,
127
?line M3__1 = M3 + 1,
128
?line N = cprof:stop(),
130
?line 2 = cprof:start(?MODULE, seq_r),
131
?line 1 = cprof:start(?MODULE, seq, 3),
132
?line L = seq(1, M, fun succ/1),
133
?line Lr = seq_r(1, M, fun succ/1),
134
?line L = lists:reverse(Lr),
136
?line io:format("~p~n~p~n~p~n",
137
[erlang:trace_info({?MODULE,sec_r,3}, all),
138
erlang:trace_info({?MODULE,sec_r,4}, all),
139
erlang:trace_info({?MODULE,sec,3}, all)]),
141
?line ModAna1 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
143
{{?MODULE,seq_r,3},1}]},
144
?line ModAna1 = cprof:analyse(?MODULE,0),
145
?line {M2__1, [ModAna1]} = cprof:analyse(),
146
?line ModAna1 = cprof:analyse(?MODULE, 1),
147
?line {M2__1, [ModAna1]} = cprof:analyse(1),
149
?line ModAna2 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
150
{{?MODULE,seq,3},M}]},
151
?line ModAna2 = cprof:analyse(?MODULE, 2),
152
?line {M2__1, [ModAna2]} = cprof:analyse(2),
154
2 = cprof:pause(?MODULE, seq_r),
155
?line L = seq(1, M, fun succ/1),
156
?line Lr = seq_r(1, M, fun succ/1),
158
?line ModAna3 = {?MODULE,M3__1,[{{?MODULE,seq,3},M2},
159
{{?MODULE,seq_r,4},M},
160
{{?MODULE,seq_r,3},1}]},
161
?line ModAna3 = cprof:analyse(?MODULE),
163
?line N = cprof:pause(),
164
?line L = seq(1, M, fun succ/1),
165
?line Lr = seq_r(1, M, fun succ/1),
167
?line {M3__1, [ModAna3]} = cprof:analyse(),
169
?line N = cprof:restart(),
170
?line L = seq(1, M, fun succ/1),
171
?line Lr = seq_r(1, M, fun succ/1),
173
?line ModAna1 = cprof:analyse(?MODULE),
175
?line N = cprof:stop(),
176
?line {?MODULE,0,[]} = cprof:analyse(?MODULE),
177
?line {0,[]} = cprof:analyse(),
180
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182
on_load_test(Config) ->
183
?line Priv = ?config(priv_dir, Config),
184
?line Data = ?config(data_dir, Config),
185
?line File = filename:join(Data, "cprof_SUITE_test"),
186
?line Module = cprof_SUITE_test,
190
?line M2__1 = M2 + 1,
191
?line N1 = cprof:start(),
193
?line {ok,Module} = c:c(File, [{outdir,Priv}]),
195
%% If this system is hipe-enabled, the loader may have called module_info/1
196
%% when Module was loaded above. Reset the call count to avoid seeing
197
%% the call in the analysis below.
199
?line 1 = cprof:restart(Module, module_info, 1),
201
?line L = Module:seq(1, M, fun succ/1),
202
?line Lr = Module:seq_r(1, M, fun succ/1),
203
?line Lr = lists:reverse(L),
204
?line N2 = cprof:pause(),
205
?line N3 = cprof:pause(Module),
206
?line {Module,M2__1,[{{Module,seq_r,4},M},
208
{{Module,seq_r,3},1}]} = cprof:analyse(Module),
209
?line io:format("~p ~p ~p~n", [N1, N2, N3]),
210
?line code:purge(Module),
211
?line code:delete(Module),
214
?line N4 = cprof:restart(),
215
?line {ok,Module} = c:c(File, [{outdir,Priv}]),
216
?line L = Module:seq(1, M, fun succ/1),
217
?line Lr = Module:seq_r(1, M, fun succ/1),
218
?line L = seq(1, M, fun succ/1),
219
?line Lr = seq_r(1, M, fun succ/1),
220
?line N2 = cprof:pause(),
221
?line {Module,0,[]} = cprof:analyse(Module),
223
?line M4__4 = M*4 - 4,
224
?line M10_7 = M*10 - 7,
225
?line {?MODULE,M10_7,[{{?MODULE,succ,1},M4__4},
226
{{?MODULE,seq_r,4},M},
228
{{?MODULE,'-on_load_test/1-fun-5-',1},M_1},
229
{{?MODULE,'-on_load_test/1-fun-4-',1},M_1},
230
{{?MODULE,'-on_load_test/1-fun-3-',1},M_1},
231
{{?MODULE,'-on_load_test/1-fun-2-',1},M_1},
232
{{?MODULE,seq_r,3},1}]}
233
= cprof:analyse(?MODULE),
234
?line N2 = cprof:stop(),
237
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239
modules_test(Config) ->
240
?line Priv = ?config(priv_dir, Config),
241
?line Data = ?config(data_dir, Config),
242
?line File = filename:join(Data, "cprof_SUITE_test"),
243
?line Module = cprof_SUITE_test,
244
?line {ok,Module} = c:c(File, [{outdir,Priv}]),
248
?line M2__1 = M2 + 1,
249
?line erlang:yield(),
250
?line N = cprof:start(),
251
?line L = Module:seq(1, M, fun succ/1),
252
?line Lr = Module:seq_r(1, M, fun succ/1),
253
?line L = seq(1, M, fun succ/1),
254
?line Lr = seq_r(1, M, fun succ/1),
255
?line N = cprof:pause(),
256
?line Lr = lists:reverse(L),
258
?line M4_4 = M*4 - 4,
259
?line M10_7 = M*10 - 7,
260
?line M2__1 = M*2 + 1,
261
?line {Tot,ModList} = cprof:analyse(),
262
?line {value,{?MODULE,M10_7,[{{?MODULE,succ,1},M4_4},
263
{{?MODULE,seq_r,4},M},
265
{{?MODULE,'-modules_test/1-fun-3-',1},M_1},
266
{{?MODULE,'-modules_test/1-fun-2-',1},M_1},
267
{{?MODULE,'-modules_test/1-fun-1-',1},M_1},
268
{{?MODULE,'-modules_test/1-fun-0-',1},M_1},
269
{{?MODULE,seq_r,3},1}]}} =
270
lists:keysearch(?MODULE, 1, ModList),
271
?line {value,{Module,M2__1,[{{Module,seq_r,4},M},
273
{{Module,seq_r,3},1}]}} =
274
lists:keysearch(Module, 1, ModList),
275
?line Tot = lists:foldl(fun ({_,C,_}, A) -> C+A end, 0, ModList),
276
?line {cprof,_,Prof} = cprof:analyse(cprof),
277
?line {value,{{cprof,pause,0},1}} =
278
lists:keysearch({cprof,pause,0}, 1, Prof),
279
?line N = cprof:stop(),
284
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289
%% Stack recursive seq
290
seq(Stop, Stop, Succ) when is_function(Succ) ->
292
seq(Start, Stop, Succ) when is_function(Succ) ->
293
[Start | seq(Succ(Start), Stop, Succ)].
297
%% Tail recursive seq, result list is reversed
298
seq_r(Start, Stop, Succ) when is_function(Succ) ->
299
seq_r(Start, Stop, Succ, []).
301
seq_r(Stop, Stop, _, R) ->
303
seq_r(Start, Stop, Succ, R) ->
304
seq_r(Succ(Start), Stop, Succ, [Start | R]).