aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools/test/cprof_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tools/test/cprof_SUITE.erl')
-rw-r--r--lib/tools/test/cprof_SUITE.erl309
1 files changed, 309 insertions, 0 deletions
diff --git a/lib/tools/test/cprof_SUITE.erl b/lib/tools/test/cprof_SUITE.erl
new file mode 100644
index 0000000000..e697cc1571
--- /dev/null
+++ b/lib/tools/test/cprof_SUITE.erl
@@ -0,0 +1,309 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% Define to run outside of test server
+%%%
+%%% -define(STANDALONE,1).
+%%%
+%%%
+%%% Define for debug output
+%%%
+%%% -define(debug,1).
+
+-module(cprof_SUITE).
+
+%% Exported end user tests
+-export([basic_test/0, on_load_test/1, modules_test/1]).
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test server related stuff
+%%
+
+-ifdef(STANDALONE).
+-define(config(A,B),config(A,B)).
+-export([config/2]).
+-else.
+-include("test_server.hrl").
+-endif.
+
+-ifdef(debug).
+-ifdef(STANDALONE).
+-define(line, erlang:display({?MODULE,?LINE}), ).
+-endif.
+-define(dbgformat(A,B),io:format(A,B)).
+-else.
+-ifdef(STANDALONE).
+-define(line, noop, ).
+-endif.
+-define(dbgformat(A,B),noop).
+-endif.
+
+-ifdef(STANDALONE).
+config(priv_dir, _) ->
+ ".";
+config(data_dir, _) ->
+ "cprof_SUITE_data".
+-else.
+%% When run in test server.
+-export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([basic/1, on_load/1, modules/1]).
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(test_server:seconds(30)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_count]),
+ erlang:trace_pattern(on_load, false, [local,meta,call_count]),
+ erlang:trace(all, false, [all]),
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+all(doc) ->
+ ["Test the cprof profiling tool."];
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true -> [not_run];
+ false -> [basic, on_load, modules]
+%, on_and_off, info,
+% pause_and_restart, combo]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped,"Native code"}.
+
+basic(suite) ->
+ [];
+basic(doc) ->
+ ["Tests basic profiling"];
+basic(Config) when is_list(Config) ->
+ basic_test().
+
+on_load(suite) ->
+ [];
+on_load(doc) ->
+ ["Tests profiling of unloaded module"];
+on_load(Config) when is_list(Config) ->
+ on_load_test(Config).
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ ["Tests profiling of several modules"];
+modules(Config) when is_list(Config) ->
+ modules_test(Config).
+
+-endif. %-ifdef(STANDALONE). ... -else.
+
+%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% The Tests
+%%%
+
+basic_test() ->
+ ?line M = 1000,
+ %%
+ ?line M2 = M*2,
+ ?line M3 = M*3,
+ ?line M2__1 = M2 + 1,
+ ?line M3__1 = M3 + 1,
+ ?line N = cprof:stop(),
+ %%
+ ?line 2 = cprof:start(?MODULE, seq_r),
+ ?line 1 = cprof:start(?MODULE, seq, 3),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line L = lists:reverse(Lr),
+ %%
+ ?line io:format("~p~n~p~n~p~n",
+ [erlang:trace_info({?MODULE,sec_r,3}, all),
+ erlang:trace_info({?MODULE,sec_r,4}, all),
+ erlang:trace_info({?MODULE,sec,3}, all)]),
+ %%
+ ?line ModAna1 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,seq_r,3},1}]},
+ ?line ModAna1 = cprof:analyse(?MODULE,0),
+ ?line {M2__1, [ModAna1]} = cprof:analyse(),
+ ?line ModAna1 = cprof:analyse(?MODULE, 1),
+ ?line {M2__1, [ModAna1]} = cprof:analyse(1),
+ %%
+ ?line ModAna2 = {?MODULE,M2__1,[{{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M}]},
+ ?line ModAna2 = cprof:analyse(?MODULE, 2),
+ ?line {M2__1, [ModAna2]} = cprof:analyse(2),
+ %%
+ 2 = cprof:pause(?MODULE, seq_r),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line ModAna3 = {?MODULE,M3__1,[{{?MODULE,seq,3},M2},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq_r,3},1}]},
+ ?line ModAna3 = cprof:analyse(?MODULE),
+ %%
+ ?line N = cprof:pause(),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line {M3__1, [ModAna3]} = cprof:analyse(),
+ %%
+ ?line N = cprof:restart(),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ %%
+ ?line ModAna1 = cprof:analyse(?MODULE),
+ %%
+ ?line N = cprof:stop(),
+ ?line {?MODULE,0,[]} = cprof:analyse(?MODULE),
+ ?line {0,[]} = cprof:analyse(),
+ ok.
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+on_load_test(Config) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "cprof_SUITE_test"),
+ ?line Module = cprof_SUITE_test,
+ ?line M = 1000,
+ %%
+ ?line M2 = M*2,
+ ?line M2__1 = M2 + 1,
+ ?line N1 = cprof:start(),
+
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+
+ %% If this system is hipe-enabled, the loader may have called module_info/1
+ %% when Module was loaded above. Reset the call count to avoid seeing
+ %% the call in the analysis below.
+
+ ?line 1 = cprof:restart(Module, module_info, 1),
+
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line Lr = lists:reverse(L),
+ ?line N2 = cprof:pause(),
+ ?line N3 = cprof:pause(Module),
+ ?line {Module,M2__1,[{{Module,seq_r,4},M},
+ {{Module,seq,3},M},
+ {{Module,seq_r,3},1}]} = cprof:analyse(Module),
+ ?line io:format("~p ~p ~p~n", [N1, N2, N3]),
+ ?line code:purge(Module),
+ ?line code:delete(Module),
+ ?line N4 = N2 - N3,
+ %%
+ ?line N4 = cprof:restart(),
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line N2 = cprof:pause(),
+ ?line {Module,0,[]} = cprof:analyse(Module),
+ ?line M_1 = M - 1,
+ ?line M4__4 = M*4 - 4,
+ ?line M10_7 = M*10 - 7,
+ ?line {?MODULE,M10_7,[{{?MODULE,succ,1},M4__4},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,'-on_load_test/1-fun-5-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-4-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-3-',1},M_1},
+ {{?MODULE,'-on_load_test/1-fun-2-',1},M_1},
+ {{?MODULE,seq_r,3},1}]}
+ = cprof:analyse(?MODULE),
+ ?line N2 = cprof:stop(),
+ ok.
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules_test(Config) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "cprof_SUITE_test"),
+ ?line Module = cprof_SUITE_test,
+ ?line {ok,Module} = c:c(File, [{outdir,Priv}]),
+ ?line M = 10,
+ %%
+ ?line M2 = M*2,
+ ?line M2__1 = M2 + 1,
+ ?line erlang:yield(),
+ ?line N = cprof:start(),
+ ?line L = Module:seq(1, M, fun succ/1),
+ ?line Lr = Module:seq_r(1, M, fun succ/1),
+ ?line L = seq(1, M, fun succ/1),
+ ?line Lr = seq_r(1, M, fun succ/1),
+ ?line N = cprof:pause(),
+ ?line Lr = lists:reverse(L),
+ ?line M_1 = M - 1,
+ ?line M4_4 = M*4 - 4,
+ ?line M10_7 = M*10 - 7,
+ ?line M2__1 = M*2 + 1,
+ ?line {Tot,ModList} = cprof:analyse(),
+ ?line {value,{?MODULE,M10_7,[{{?MODULE,succ,1},M4_4},
+ {{?MODULE,seq_r,4},M},
+ {{?MODULE,seq,3},M},
+ {{?MODULE,'-modules_test/1-fun-3-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-2-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-1-',1},M_1},
+ {{?MODULE,'-modules_test/1-fun-0-',1},M_1},
+ {{?MODULE,seq_r,3},1}]}} =
+ lists:keysearch(?MODULE, 1, ModList),
+ ?line {value,{Module,M2__1,[{{Module,seq_r,4},M},
+ {{Module,seq,3},M},
+ {{Module,seq_r,3},1}]}} =
+ lists:keysearch(Module, 1, ModList),
+ ?line Tot = lists:foldl(fun ({_,C,_}, A) -> C+A end, 0, ModList),
+ ?line {cprof,_,Prof} = cprof:analyse(cprof),
+ ?line {value,{{cprof,pause,0},1}} =
+ lists:keysearch({cprof,pause,0}, 1, Prof),
+ ?line N = cprof:stop(),
+ ok.
+
+
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Local helpers
+
+
+
+%% Stack recursive seq
+seq(Stop, Stop, Succ) when is_function(Succ) ->
+ [Stop];
+seq(Start, Stop, Succ) when is_function(Succ) ->
+ [Start | seq(Succ(Start), Stop, Succ)].
+
+
+
+%% Tail recursive seq, result list is reversed
+seq_r(Start, Stop, Succ) when is_function(Succ) ->
+ seq_r(Start, Stop, Succ, []).
+
+seq_r(Stop, Stop, _, R) ->
+ [Stop | R];
+seq_r(Start, Stop, Succ, R) ->
+ seq_r(Succ(Start), Stop, Succ, [Start | R]).
+
+
+
+%% Successor
+succ(X) -> X+1.