aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/common_test/src/ct_property_test.erl20
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl11
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl43
-rw-r--r--lib/dialyzer/test/dialyzer_SUITE.erl39
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server.erl5
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_encode_decode.erl16
-rw-r--r--lib/ssh/test/ssh_property_test_SUITE.erl6
7 files changed, 125 insertions, 15 deletions
diff --git a/lib/common_test/src/ct_property_test.erl b/lib/common_test/src/ct_property_test.erl
index e401fef669..39d089f04c 100644
--- a/lib/common_test/src/ct_property_test.erl
+++ b/lib/common_test/src/ct_property_test.erl
@@ -78,7 +78,8 @@
%%%
%%% @doc Initializes Config for property testing.
%%%
-%%% <p>The function investigates if support is available for either Quickcheck or PropEr.
+%%% <p>The function investigates if support is available for either Quickcheck, PropEr,
+%%% or Triq.
%%% The options <c>{property_dir,AbsPath}</c> and
%%% <c>{property_test_tool,Tool}</c> is set in the Config returned.</p>
%%% <p>The function is intended to be called in the init_per_suite in the test suite.</p>
@@ -86,7 +87,7 @@
%%% @end
init_per_suite(Config) ->
- case which_module_exists([eqc,proper]) of
+ case which_module_exists([eqc,proper,triq]) of
{ok,ToolModule} ->
ct:pal("Found property tester ~p",[ToolModule]),
Path = property_tests_path("property_test", Config),
@@ -114,7 +115,8 @@ init_per_suite(Config) ->
quickcheck(Property, Config) ->
Tool = proplists:get_value(property_test_tool,Config),
- mk_ct_return( Tool:quickcheck(Property) ).
+ F = function_name(quickcheck, Tool),
+ mk_ct_return( Tool:F(Property), Tool ).
%%%================================================================
@@ -123,10 +125,10 @@ quickcheck(Property, Config) ->
%%%
%%% Make return values back to the calling Common Test suite
-mk_ct_return(true) ->
+mk_ct_return(true, _Tool) ->
true;
-mk_ct_return(Other) ->
- try lists:last(hd(eqc:counterexample()))
+mk_ct_return(Other, Tool) ->
+ try lists:last(hd(Tool:counterexample()))
of
{set,{var,_},{call,M,F,Args}} ->
{fail, io_lib:format("~p:~p/~p returned bad result",[M,F,length(Args)])}
@@ -174,5 +176,9 @@ compile_tests(Path, ToolModule) ->
macro_def(eqc) -> [{d, 'EQC'}];
-macro_def(proper) -> [{d, 'PROPER'}].
+macro_def(proper) -> [{d, 'PROPER'}];
+macro_def(triq) -> [{d, 'TRIQ'}].
+
+function_name(quickcheck, triq) -> check;
+function_name(F, _) -> F.
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index 6a33a2acb3..af1c2b7e3a 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -373,7 +373,16 @@ compile_byte(File, Callgraph, CServer, UseContracts) ->
{error, " Could not get abstract code for: " ++ File ++ "\n" ++
" Recompile with +debug_info or analyze starting from source code"};
{ok, AbstrCode} ->
- compile_common(File, AbstrCode, [], Callgraph, CServer, UseContracts)
+ compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts)
+ end.
+
+compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts) ->
+ case dialyzer_utils:get_compile_options_from_beam(File) of
+ error ->
+ {error, " Could not get compile options for: " ++ File ++ "\n" ++
+ " Recompile or analyze starting from source code"};
+ {ok, CompOpts} ->
+ compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts)
end.
compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts) ->
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index e1bcd72c0b..4e2ec67b35 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -31,6 +31,7 @@
format_sig/1,
format_sig/2,
get_abstract_code_from_beam/1,
+ get_compile_options_from_beam/1,
get_abstract_code_from_src/1,
get_abstract_code_from_src/2,
get_core_from_abstract_code/1,
@@ -136,6 +137,26 @@ get_abstract_code_from_beam(File) ->
error
end.
+-spec get_compile_options_from_beam(file:filename()) -> 'error' | {'ok', [compile:option()]}.
+
+get_compile_options_from_beam(File) ->
+ case beam_lib:chunks(File, [compile_info]) of
+ {ok, {_, List}} ->
+ case lists:keyfind(compile_info, 1, List) of
+ {compile_info, CompInfo} -> compile_info_to_options(CompInfo);
+ _ -> error
+ end;
+ _ ->
+ %% No or unsuitable compile info.
+ error
+ end.
+
+compile_info_to_options(CompInfo) ->
+ case lists:keyfind(options, 1, CompInfo) of
+ {options, CompOpts} -> {ok, CompOpts};
+ _ -> error
+ end.
+
-type get_core_from_abs_ret() :: {'ok', cerl:c_module()} | 'error'.
-spec get_core_from_abstract_code(abstract_code()) -> get_core_from_abs_ret().
@@ -150,7 +171,9 @@ get_core_from_abstract_code(AbstrCode, Opts) ->
%% performed them. In some cases we end up in trouble when
%% performing them again.
AbstrCode1 = cleanup_parse_transforms(AbstrCode),
- try compile:forms(AbstrCode1, Opts ++ src_compiler_opts()) of
+ %% Remove parse_transforms (and other options) from compile options.
+ Opts2 = cleanup_compile_options(Opts),
+ try compile:forms(AbstrCode1, Opts2 ++ src_compiler_opts()) of
{ok, _, Core} -> {ok, Core};
_What -> error
catch
@@ -419,6 +442,24 @@ cleanup_parse_transforms([Other|Left]) ->
cleanup_parse_transforms([]) ->
[].
+-spec cleanup_compile_options([compile:option()]) -> [compile:option()].
+
+%% Using abstract, not asm or core.
+cleanup_compile_options([from_asm|Opts]) ->
+ Opts;
+cleanup_compile_options([asm|Opts]) ->
+ Opts;
+cleanup_compile_options([from_core|Opts]) ->
+ Opts;
+%% The parse transform will already have been applied, may cause problems if it
+%% is re-applied.
+cleanup_compile_options([{parse_transform, _}|Opts]) ->
+ Opts;
+cleanup_compile_options([Other|Opts]) ->
+ [Other|cleanup_compile_options(Opts)];
+cleanup_compile_options([]) ->
+ [].
+
-spec format_errors([{module(), string()}]) -> [string()].
format_errors([{Mod, Errors}|Left]) ->
diff --git a/lib/dialyzer/test/dialyzer_SUITE.erl b/lib/dialyzer/test/dialyzer_SUITE.erl
index 1b62291a00..8507525597 100644
--- a/lib/dialyzer/test/dialyzer_SUITE.erl
+++ b/lib/dialyzer/test/dialyzer_SUITE.erl
@@ -30,12 +30,12 @@
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
--export([app_test/1, appup_test/1]).
+-export([app_test/1, appup_test/1, beam_tests/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test, appup_test].
+ [app_test, appup_test, beam_tests].
groups() ->
[].
@@ -75,3 +75,38 @@ app_test(Config) when is_list(Config) ->
%% Test that the .appup file does not contain any `basic' errors
appup_test(Config) when is_list(Config) ->
ok = ?t:appup_test(dialyzer).
+
+beam_tests(Config) when is_list(Config) ->
+ Prog = <<"
+ -module(no_auto_import).
+
+ %% Copied from erl_lint_SUITE.erl, clash6
+
+ -export([size/1]).
+
+ size([]) ->
+ 0;
+ size({N,_}) ->
+ N;
+ size([_|T]) ->
+ 1+size(T).
+ ">>,
+ Opts = [no_auto_import],
+ {ok, BeamFile} = compile(Config, Prog, no_auto_import, Opts),
+ [] = run_dialyzer([BeamFile]),
+ ok.
+
+compile(Config, Prog, Module, CompileOpts) ->
+ Source = lists:concat([Module, ".erl"]),
+ PrivDir = ?config(priv_dir,Config),
+ Filename = filename:join([PrivDir, Source]),
+ ok = file:write_file(Filename, Prog),
+ Opts = [{outdir, PrivDir}, debug_info | CompileOpts],
+ {ok, Module} = compile:file(Filename, Opts),
+ {ok, filename:join([PrivDir, lists:concat([Module, ".beam"])])}.
+
+run_dialyzer(Files) ->
+ dialyzer:run([{analysis_type, plt_build},
+ {files, Files},
+ {from, byte_code},
+ {check_plt, false}]).
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server.erl b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
index 3a84acebb3..cf895ae85e 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_server.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
@@ -27,6 +27,10 @@
-ifdef(PROPER).
%% Proper is not supported.
-else.
+-ifdef(TRIQ).
+%% Proper is not supported.
+-else.
+
-include_lib("eqc/include/eqc.hrl").
-include_lib("eqc/include/eqc_statem.hrl").
@@ -600,3 +604,4 @@ erase_dir(Dir) ->
file:del_dir(Dir).
-endif.
+-endif.
diff --git a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
index 6ddf2c9972..34630bdc91 100644
--- a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
@@ -22,20 +22,36 @@
-compile(export_all).
+-proptest(eqc).
+-proptest([triq,proper]).
+
+-include_lib("ct_property_test.hrl").
+
-ifndef(EQC).
-ifndef(PROPER).
+-ifndef(TRIQ).
-define(EQC,true).
%%-define(PROPER,true).
+%%-define(TRIQ,true).
+-endif.
-endif.
-endif.
-ifdef(EQC).
-include_lib("eqc/include/eqc.hrl").
-define(MOD_eqc,eqc).
+
-else.
-ifdef(PROPER).
-include_lib("proper/include/proper.hrl").
-define(MOD_eqc,proper).
+
+-else.
+-ifdef(TRIQ).
+-define(MOD_eqc,triq).
+-include_lib("triq/include/triq.hrl").
+
+-endif.
-endif.
-endif.
diff --git a/lib/ssh/test/ssh_property_test_SUITE.erl b/lib/ssh/test/ssh_property_test_SUITE.erl
index c6c63d7367..ffad8ebbb7 100644
--- a/lib/ssh/test/ssh_property_test_SUITE.erl
+++ b/lib/ssh/test/ssh_property_test_SUITE.erl
@@ -57,10 +57,8 @@ init_per_suite(Config) ->
%%% if we run proper.
init_per_group(client_server, Config) ->
case ?config(property_test_tool,Config) of
- proper ->
- {skip, "PropEr is not supported"};
- eqc ->
- Config
+ eqc -> Config;
+ X -> {skip, lists:concat([X," is not supported"])}
end;
init_per_group(_, Config) ->
Config.