aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tools/test')
-rw-r--r--lib/tools/test/Makefile6
-rw-r--r--lib/tools/test/fprof_SUITE.erl17
-rw-r--r--lib/tools/test/fprof_SUITE_data/fprof_unicode.erl36
-rw-r--r--lib/tools/test/lcnt_SUITE.erl86
-rw-r--r--lib/tools/test/make_SUITE.erl101
-rw-r--r--lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl9
-rw-r--r--lib/tools/test/make_SUITE_data/test_incl.hrl1
-rw-r--r--lib/tools/test/make_SUITE_data/test_incl1.erl9
-rw-r--r--lib/tools/test/xref_SUITE.erl81
9 files changed, 321 insertions, 25 deletions
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
index 84c4e56aff..2b7b17afb3 100644
--- a/lib/tools/test/Makefile
+++ b/lib/tools/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -52,8 +52,8 @@ RELSYSDIR = $(RELEASE_PATH)/tools_test
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/percept/include
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS +=
EBIN = .
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
index affb45b7a6..8fd164a4b3 100644
--- a/lib/tools/test/fprof_SUITE.erl
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
%% Test suites
-export([stack_seq/1, tail_seq/1, create_file_slow/1, spawn_simple/1,
imm_tail_seq/1, imm_create_file_slow/1, imm_compile/1,
- cpu_create_file_slow/1]).
+ cpu_create_file_slow/1, unicode/1]).
%% Other exports
-export([create_file_slow/2]).
@@ -59,7 +59,7 @@ all() ->
false ->
[stack_seq, tail_seq, create_file_slow, spawn_simple,
imm_tail_seq, imm_create_file_slow, imm_compile,
- cpu_create_file_slow]
+ cpu_create_file_slow, unicode]
end.
@@ -533,6 +533,17 @@ cpu_create_file_slow(Config) when is_list(Config) ->
TestResult.
+unicode(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ SourceFile = filename:join(DataDir, "fprof_unicode.erl"),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ AnalysisFile = filename:join(PrivDir, "fprof_unicode.analysis"),
+ {ok, fprof_unicode} = compile:file(SourceFile, [{outdir, PrivDir}]),
+ true = code:add_path(PrivDir),
+ fprof:apply(fprof_unicode, t, []),
+ ok = fprof:profile(dump, AnalysisFile),
+ ok = fprof:analyse(dest, AnalysisFile).
+
%%%---------------------------------------------------------------------
%%% Functions to test
%%%---------------------------------------------------------------------
diff --git a/lib/tools/test/fprof_SUITE_data/fprof_unicode.erl b/lib/tools/test/fprof_SUITE_data/fprof_unicode.erl
new file mode 100644
index 0000000000..8b58efc5fe
--- /dev/null
+++ b/lib/tools/test/fprof_SUITE_data/fprof_unicode.erl
@@ -0,0 +1,36 @@
+-module(fprof_unicode).
+
+-export([t/0, 'кирилли́ческий атом'/0, annan/0, c_break/1,
+ 'кирилли́ческий атомB'/1]).
+
+t() ->
+ _Atom = 'кирилли́ческий атом',
+ 'кирилли́ческий атом'().
+
+'кирилли́ческий атом'() ->
+ 'кирилли́ческий атом'('кирилли́ческий атом').
+
+'кирилли́ческий атом'(_Atom) ->
+ self() ! 'кирилли́ческий атом',
+ G = fun (X) ->
+ catch foo:bar()
+ end,
+ G("кирилли́ческий атом"), % line 17
+ Pid = spawn_link(fun() -> waiting() end),
+ true = register('кирилли́ческий атом', Pid),
+ F = fun() -> 'кирилли́ческий атом' end,
+ F().
+
+annan() ->
+ foo.
+
+waiting() ->
+ receive
+ X -> X
+ end.
+
+c_break(_B) ->
+ true.
+
+'кирилли́ческий атомB'(_B) ->
+ true.
diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl
index d39a5deeab..146c915087 100644
--- a/lib/tools/test/lcnt_SUITE.erl
+++ b/lib/tools/test/lcnt_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@
-export([t_load/1,
t_conflicts/1,
t_locations/1,
- t_swap_keys/1]).
+ t_swap_keys/1,
+ smoke_lcnt/1]).
init_per_testcase(_Case, Config) ->
Config.
@@ -43,7 +44,8 @@ suite() ->
{timetrap,{minutes,4}}].
all() ->
- [t_load, t_conflicts, t_locations, t_swap_keys].
+ [t_load, t_conflicts, t_locations, t_swap_keys,
+ smoke_lcnt].
%%----------------------------------------------------------------------
%% Tests
@@ -146,3 +148,81 @@ t_swap_keys_file([File|Files]) ->
ok = lcnt:conflicts(),
ok = lcnt:stop(),
t_swap_keys_file(Files).
+
+%% Simple smoke test of actual lock-counting, if running on
+%% a run-time with lock-counting enabled.
+smoke_lcnt(Config) ->
+ case catch erlang:system_info(lock_counting) of
+ true ->
+ do_smoke_lcnt(Config);
+ _ ->
+ {skip,"Lock counting is not enabled"}
+ end.
+
+do_smoke_lcnt(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ SaveFile = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME)),
+ {Time,ok} = timer:tc(fun() -> lcnt:apply(fun() -> big_bang(200) end) end),
+ io:format("~p ms\n", [Time]),
+ ok = lcnt:conflicts(),
+ ok = lcnt:save(SaveFile),
+ ok = lcnt:load(SaveFile),
+ ok = lcnt:conflicts(),
+ lcnt:stop().
+
+
+%%%
+%%% A slightly modified version of Rickard Green's Big Bang benchmark.
+%%%
+
+big_bang(N) when is_integer(N) ->
+ Procs = spawn_procs(N),
+ RMsgs = lists:map(fun (P) -> {done, P} end, Procs),
+ send_procs(Procs, {procs, Procs, self()}),
+ receive_msgs(RMsgs),
+ lists:foreach(fun (P) -> exit(P, normal) end, Procs).
+
+pinger([], [], true) ->
+ receive
+ {procs, Procs, ReportTo} ->
+ pinger(Procs, [], ReportTo)
+ end;
+pinger([], [], false) ->
+ receive {ping, From} -> From ! {pong, self()} end,
+ pinger([],[],false);
+pinger([], [], ReportTo) ->
+ ReportTo ! {done, self()},
+ pinger([],[],false);
+pinger([],[Po|Pos] = Pongers, ReportTo) ->
+ receive
+ {ping, From} ->
+ From ! {pong, self()},
+ pinger([], Pongers, ReportTo);
+ {pong, Po} ->
+ pinger([], Pos, ReportTo)
+ end;
+pinger([Pi|Pis], Pongers, ReportTo) ->
+ receive {ping, From} -> From ! {pong, self()}
+ after 0 -> ok
+ end,
+ Pi ! {ping, self()},
+ pinger(Pis, [Pi|Pongers], ReportTo).
+
+spawn_procs(N) when N =< 0 ->
+ [];
+spawn_procs(N) ->
+ [spawn_link(fun () -> pinger([], [], true) end) | spawn_procs(N-1)].
+
+send_procs([], Msg) ->
+ Msg;
+send_procs([P|Ps], Msg) ->
+ P ! Msg,
+ send_procs(Ps, Msg).
+
+receive_msgs([]) ->
+ ok;
+receive_msgs([M|Ms]) ->
+ receive
+ M ->
+ receive_msgs(Ms)
+ end.
diff --git a/lib/tools/test/make_SUITE.erl b/lib/tools/test/make_SUITE.erl
index e6284db8b8..02da4f4ace 100644
--- a/lib/tools/test/make_SUITE.erl
+++ b/lib/tools/test/make_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,11 +19,7 @@
%%
-module(make_SUITE).
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2, make_all/1, make_files/1]).
--export([otp_6057_init/1,
- otp_6057_a/1, otp_6057_b/1, otp_6057_c/1,
- otp_6057_end/1]).
+-compile(export_all).
-include_lib("common_test/include/ct.hrl").
@@ -40,7 +36,8 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [make_all, make_files, {group, otp_6057}].
+ [make_all, make_files, load, netload, recompile_on_changed_include,
+ emake_opts, {group, otp_6057}].
groups() ->
[{otp_6057,[],[otp_6057_a, otp_6057_b,
@@ -58,6 +55,21 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
otp_6057_end(Config).
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(netload,_Config) ->
+ %% Stop slave - in case of failure
+ Nodes = nodes(),
+ case [N || N <- Nodes,
+ "make_SUITE_netload" == hd(string:lexemes(atom_to_list(N),"@"))] of
+ [Node] ->
+ ct_slave:stop(Node);
+ _ ->
+ ok
+ end;
+end_per_testcase(_,_Config) ->
+ ok.
test_files() -> ["test1", "test2", "test3", "test4"].
@@ -86,6 +98,81 @@ make_files(Config) when is_list(Config) ->
ensure_no_messages(),
ok.
+load(Config) ->
+ Current = prepare_data_dir(Config),
+ code:purge(test1),
+ code:delete(test1),
+ false = code:is_loaded(test1),
+ up_to_date = make:files([test1], [load]),
+ {file,_} = code:is_loaded(test1),
+ file:set_cwd(Current),
+ ensure_no_messages(),
+ ok.
+
+netload(Config) ->
+ Current = prepare_data_dir(Config),
+ code:purge(test1),
+ code:delete(test1),
+ false = code:is_loaded(test1),
+ {ok,Node} = ct_slave:start(make_SUITE_netload),
+ up_to_date = make:files([test1], [netload]),
+ timer:sleep(1000), % async, so give some time
+ {file,F} = code:is_loaded(test1),
+ {file,F} = rpc:call(Node,code,is_loaded,[test1]),
+ ct_slave:stop(Node),
+ file:set_cwd(Current),
+ ensure_no_messages(),
+ ok.
+
+recompile_on_changed_include(Config) ->
+ Current = prepare_data_dir(Config),
+
+ Files = [test_incl1,"incl_src/test_incl2"],
+ up_to_date = make:files(Files),
+ ok = ensure_exists([test_incl1,test_incl2]),
+
+ {ok, FileInfo11} = file:read_file_info("test_incl1.beam"),
+ Date11 = FileInfo11#file_info.mtime,
+ {ok, FileInfo21} = file:read_file_info("test_incl2.beam"),
+ Date21 = FileInfo21#file_info.mtime,
+ timer:sleep(2000),
+
+ %% Touch the include file
+ {ok,Bin} = file:read_file("test_incl.hrl"),
+ ok = file:delete("test_incl.hrl"),
+ ok = file:write_file("test_incl.hrl",Bin),
+
+ up_to_date = make:files(Files),
+
+ {ok, FileInfo12} = file:read_file_info("test_incl1.beam"),
+ case FileInfo12#file_info.mtime of
+ Date11 -> ct:fail({"file not recompiled", "test_incl1.beam"});
+ _Date12 -> ok
+ end,
+ {ok, FileInfo22} = file:read_file_info("test_incl2.beam"),
+ case FileInfo22#file_info.mtime of
+ Date21 -> ct:fail({"file not recompiled", "test_incl2.beam"});
+ _Date22 -> ok
+ end,
+
+ file:set_cwd(Current),
+ ensure_no_messages(),
+ ok.
+
+emake_opts(Config) when is_list(Config) ->
+ Current = prepare_data_dir(Config),
+
+ %% prove that emake is used in opts instead of local Emakefile
+ Opts = [{emake, [test8, test9]}],
+ error = make:all(Opts),
+ error = make:files([test9], Opts),
+ "test8.beam" = ensure_exists([test8]),
+ "test9.beam" = ensure_exists([test9]),
+ "test5.S" = ensure_exists(["test5"],".S"),
+
+ file:set_cwd(Current),
+ ensure_no_messages(),
+ ok.
%% Moves to the data directory of this suite, clean it from any object
%% files (*.jam for a JAM emulator). Returns the previous directory.
diff --git a/lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl b/lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl
new file mode 100644
index 0000000000..d0db98c19a
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl
@@ -0,0 +1,9 @@
+-module(test_incl2).
+-compile(export_all).
+-include("test_incl.hrl").
+
+f1() ->
+ ?d.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test_incl.hrl b/lib/tools/test/make_SUITE_data/test_incl.hrl
new file mode 100644
index 0000000000..3a1bcfadd0
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test_incl.hrl
@@ -0,0 +1 @@
+-define(d,"defined").
diff --git a/lib/tools/test/make_SUITE_data/test_incl1.erl b/lib/tools/test/make_SUITE_data/test_incl1.erl
new file mode 100644
index 0000000000..4a1dd0e73d
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test_incl1.erl
@@ -0,0 +1,9 @@
+-module(test_incl1).
+-compile(export_all).
+-include("test_incl.hrl").
+
+f1() ->
+ ?d.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index 01dbac6ecb..d651cbcfee 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,7 +50,8 @@
-export([analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]).
--export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1, otp_13708/1]).
+-export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1, otp_13708/1,
+ otp_14464/1, otp_14344/1]).
-import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]).
@@ -81,19 +82,21 @@ groups() ->
update, deprecated, trycatch, fun_mfa,
fun_mfa_r14, fun_mfa_vars, qlc]},
{analyses, [],
+
[analyze, basic, md, q, variables, unused_locals]},
- {misc, [], [format_error, otp_7423, otp_7831, otp_10192, otp_13708]}].
+ {misc, [], [format_error, otp_7423, otp_7831, otp_10192, otp_13708,
+ otp_14464, otp_14344]}].
init_per_suite(Conf) when is_list(Conf) ->
DataDir = ?datadir,
PrivDir = ?privdir,
CopyDir = fname(PrivDir, "datacopy"),
+ ok = file:make_dir(CopyDir),
TarFile = fname(PrivDir, "datacopy.tgz"),
- {ok, Tar} = erl_tar:open(TarFile, [write, compressed]),
- ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]),
- ok = erl_tar:close(Tar),
- ok = erl_tar:extract(TarFile, [compressed]),
+ ok = file:set_cwd(DataDir),
+ ok = erl_tar:create(TarFile, ["."], [compressed]),
+ ok = erl_tar:extract(TarFile, [compressed, {cwd,CopyDir}]),
ok = file:delete(TarFile),
[{copy_dir, CopyDir}|Conf].
@@ -1222,6 +1225,9 @@ read2(Conf) when is_list(Conf) ->
f() ->
%% Duplicated unresolved calls are ignored:
(f())(foo,bar),(f())(foo,bar). % POS1
+
+ %% Warning forms must be ignored.
+ -warning(must_not_crash).
">>,
ok = file:write_file(File, Test),
{ok, read2} = compile:file(File, [debug_info,{outdir,Dir}]),
@@ -2393,7 +2399,6 @@ otp_10192(Conf) when is_list(Conf) ->
xref:stop(s),
ok.
-%% OTP-10192. Allow filenames with character codes greater than 126.
otp_13708(Conf) when is_list(Conf) ->
{ok, _} = start(s),
ok = xref:set_default(s, [{verbose, true}]),
@@ -2406,6 +2411,60 @@ otp_13708(Conf) when is_list(Conf) ->
ok = xref:set_library_path(s, [Dir], [{verbose, true}]),
xref:stop(s).
+%% OTP-14464. Unicode atoms.
+otp_14464(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+
+ File1 = fname(Dir, "a.erl"),
+ MFile1 = fname(Dir, "a"),
+ Beam1 = fname(Dir, "a.beam"),
+ Test1 = "-module(a).
+ -export([ärlig/0, 'кlирилли́ческий атомB'/0]).
+
+ ärlig() ->
+ 'кlирилли́ческий атомB'.
+
+ 'кlирилли́ческий атомB'() ->
+ foo.
+ ",
+ ok = file:write_file(File1, unicode:characters_to_binary(Test1)),
+ {ok, a} = compile:file(File1, [debug_info,{outdir,Dir}]),
+
+ {ok, _} = xref:start(s),
+ {ok, a} = xref:add_module(s, MFile1),
+
+ {ok, [{a,ärlig,0}]} = xref:q(s, 'a:"ärlig"/0'),
+ {ok, [{a,'кlирилли́ческий атомB',0}]} =
+ xref:q(s, 'a:"кlирилли́ческий атомB"/0'),
+
+ xref:stop(s),
+ ok = file:delete(File1),
+ ok = file:delete(Beam1).
+
+%% OTP-14344. -on_load() attribute.
+otp_14344(Conf) when is_list(Conf) ->
+ Dir = ?copydir,
+
+ File1 = fname(Dir, "a.erl"),
+ MFile1 = fname(Dir, "a"),
+ Beam1 = fname(Dir, "a.beam"),
+ Test1 = <<"-module(a).
+ -on_load(doit/0).
+ doit() -> ok.
+ ">>,
+ ok = file:write_file(File1, Test1),
+ {ok, a} = compile:file(File1, [debug_info,{outdir,Dir}]),
+
+ {ok, _} = xref:start(s),
+ {ok, a} = xref:add_module(s, MFile1),
+
+ {ok, [{a,doit,0}]} = xref:q(s, "OL"),
+ {ok, []} = xref:analyze(s, locals_not_used),
+
+ xref:stop(s),
+ ok = file:delete(File1),
+ ok = file:delete(Beam1).
+
%%%
%%% Utilities
%%%
@@ -2480,7 +2539,8 @@ add_module(S, XMod, DefAt, X, LCallAt, XCallAt, XC, LC) ->
Depr0 = {[], [], [], []},
DBad = [],
Depr = {Depr0,DBad},
- Data = {DefAt, LCallAt, XCallAt, LC, XC, X, Attr, Depr},
+ OL = [],
+ Data = {DefAt, LCallAt, XCallAt, LC, XC, X, Attr, Depr, OL},
Unres = [],
{ok, _Module, _Bad, State} =
xref_base:do_add_module(S, XMod, Unres, Data),
@@ -2561,6 +2621,9 @@ functions_mode_check(S, Info) ->
%% UU subset F
{ok, []} = xref:q(S, "UU - F"),
+ %% OL subset F
+ {ok, []} = xref:q(S, "OL - F"),
+
%% ME = (Mod) E
{ok, ME} = xref:q(S, "ME"),
{ok, ME} = xref:q(S, "(Mod) E"),