|
|
- -module(rebar_dialyzer_SUITE).
-
- -export([suite/0,
- init_per_suite/1,
- end_per_suite/1,
- init_per_group/2,
- end_per_group/2,
- init_per_testcase/2,
- all/0,
- groups/0,
- empty_base_plt/1,
- empty_app_plt/1,
- empty_app_succ_typings/1,
- update_base_plt/1,
- update_app_plt/1,
- build_release_plt/1,
- plt_apps_option/1,
- exclude_and_extra/1]).
-
- -include_lib("common_test/include/ct.hrl").
- -include_lib("eunit/include/eunit.hrl").
- -include_lib("kernel/include/file.hrl").
-
- suite() ->
- [].
-
- init_per_suite(Config) ->
- Config.
-
- end_per_suite(_Config) ->
- ok.
-
- init_per_group(empty, Config) ->
- [{base_plt_apps, []} | Config];
- init_per_group(_Group, Config) ->
- [{base_plt_apps, [erts]} | Config].
-
- end_per_group(_Group, _Config) ->
- ok.
-
- init_per_testcase(Testcase, Config) ->
- PrivDir = ?config(priv_dir, Config),
- Prefix = ec_cnv:to_list(Testcase),
- BasePrefix = Prefix ++ "_base",
- Opts = [{plt_prefix, Prefix},
- {plt_location, PrivDir},
- {base_plt_prefix, BasePrefix},
- {base_plt_location, PrivDir},
- {base_plt_apps, ?config(base_plt_apps, Config)}],
- Suffix = "_" ++ rebar_utils:otp_release() ++ "_plt",
- [{plt, filename:join(PrivDir, Prefix ++ Suffix)},
- {base_plt, filename:join(PrivDir, BasePrefix ++ Suffix)},
- {rebar_config, [{dialyzer, Opts}]} |
- rebar_test_utils:init_rebar_state(Config)].
-
- all() ->
- [{group, empty}, {group, build_and_check}, {group, update}].
-
- groups() ->
- [{empty, [empty_base_plt, empty_app_plt, empty_app_succ_typings]},
- {build_and_check, [build_release_plt, plt_apps_option, exclude_and_extra]},
- {update, [update_base_plt, update_app_plt]}].
-
- empty_base_plt(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- BasePlt = ?config(base_plt, Config),
- Plt = ?config(plt, Config),
-
- Name = rebar_test_utils:create_random_name("app1_"),
- Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(AppDir, Name, Vsn, [erts]),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, BasePltFiles} = plt_files(BasePlt),
- ?assertEqual([], BasePltFiles),
-
- ErtsFiles = erts_files(),
- {ok, PltFiles} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles),
-
- ok.
-
- empty_app_plt(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- BasePlt = ?config(base_plt, Config),
- Plt = ?config(plt, Config),
-
- Name = rebar_test_utils:create_random_name("app1_"),
- Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(AppDir, Name, Vsn, []),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, BasePltFiles} = plt_files(BasePlt),
- ?assertEqual([], BasePltFiles),
-
- {ok, PltFiles} = plt_files(Plt),
- ?assertEqual([], PltFiles),
-
- ok.
-
- empty_app_succ_typings(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
-
- Name = rebar_test_utils:create_random_name("app1_"),
- Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_empty_app(AppDir, Name, Vsn, []),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- ok.
-
- update_base_plt(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- BasePlt = ?config(base_plt, Config),
- Plt = ?config(plt, Config),
-
- Name = rebar_test_utils:create_random_name("app1_"),
- Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(AppDir, Name, Vsn, [erts]),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- ErtsFiles = erts_files(),
-
- {ok, BasePltFiles} = plt_files(BasePlt),
- ?assertEqual(ErtsFiles, BasePltFiles),
-
- alter_plt(BasePlt),
- ok = file:delete(Plt),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, BasePltFiles2} = plt_files(BasePlt),
- ?assertEqual(ErtsFiles, BasePltFiles2),
-
- {ok, PltFiles} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles),
-
- add_missing_file(BasePlt),
- ok = file:delete(Plt),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, BasePltFiles3} = plt_files(BasePlt),
- ?assertEqual(ErtsFiles, BasePltFiles3).
-
-
- update_app_plt(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- Plt = ?config(plt, Config),
-
- Name = rebar_test_utils:create_random_name("app1_"),
- Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(AppDir, Name, Vsn, [erts]),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- ErtsFiles = erts_files(),
-
- {ok, PltFiles} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles),
-
- alter_plt(Plt),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, PltFiles2} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles2),
-
- ok = file:delete(Plt),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, PltFiles3} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles3),
-
- add_missing_file(Plt),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- {ok, PltFiles4} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles4).
-
- build_release_plt(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- BasePlt = ?config(base_plt, Config),
- Plt = ?config(plt, Config),
-
- Name1 = rebar_test_utils:create_random_name("relapp1_"),
- Vsn1 = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(filename:join([AppDir,"apps",Name1]), Name1, Vsn1,
- [erts]),
- Name2 = rebar_test_utils:create_random_name("relapp2_"),
- Vsn2 = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(filename:join([AppDir,"apps",Name2]), Name2, Vsn2,
- [erts, ec_cnv:to_atom(Name1)]),
-
- rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"],
- {ok, [{app, Name1}, {app, Name2}]}),
-
- ErtsFiles = erts_files(),
-
- {ok, BasePltFiles} = plt_files(BasePlt),
- ?assertEqual(ErtsFiles, BasePltFiles),
-
- {ok, PltFiles} = plt_files(Plt),
- ?assertEqual(ErtsFiles, PltFiles).
-
- plt_apps_option(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- Plt = ?config(plt, Config),
- State = ?config(state, Config),
-
- %% Create applications
- Name1 = rebar_test_utils:create_random_name("app1_"),
- Vsn1 = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(filename:join([AppDir,"deps",Name1]), Name1, Vsn1,
- []),
- App1 = ec_cnv:to_atom(Name1),
-
- Name2 = rebar_test_utils:create_random_name("app2_"),
- Vsn2 = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(filename:join([AppDir,"deps",Name2]), Name2, Vsn2,
- [App1]), % App2 depends on App1
- App2 = ec_cnv:to_atom(Name2),
-
- Name3 = rebar_test_utils:create_random_name("app3_"), % the project application
- Vsn3 = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(AppDir, Name3, Vsn3,
- [App2]), % App3 depends on App2
-
- %% Dependencies settings
- State1 = rebar_state:add_resource(State, {localfs, rebar_localfs_resource}),
- Config1 = [{state, State1} | Config],
- RebarConfig1 = merge_config(
- [{deps,
- [
- {App1, {localfs, filename:join([AppDir,"deps",Name1])}},
- {App2, {localfs, filename:join([AppDir,"deps",Name2])}}
- ]}],
- RebarConfig),
-
- %% Dialyzer: plt_apps = top_level_deps (default)
- rebar_test_utils:run_and_check(Config1, RebarConfig1, ["dialyzer"],
- {ok, [{app, Name3}]}),
-
- %% NOTE: `erts` is included in `base_plt_apps`
- {ok, PltFiles1} = plt_files(Plt),
- ?assertEqual([App2, erts], get_apps_from_beam_files(PltFiles1)),
-
- %% Dialyzer: plt_apps = all_deps
- RebarConfig2 = merge_config([{dialyzer, [{plt_apps, all_deps}]}],
- RebarConfig1),
- rebar_test_utils:run_and_check(Config1, RebarConfig2, ["dialyzer"],
- {ok, [{app, Name3}]}),
-
- {ok, PltFiles2} = plt_files(Plt),
- ?assertEqual([App1, App2, erts], get_apps_from_beam_files(PltFiles2)).
-
- exclude_and_extra(Config) ->
- AppDir = ?config(apps, Config),
- RebarConfig = ?config(rebar_config, Config),
- BasePlt = ?config(base_plt, Config),
- Plt = ?config(plt, Config),
-
- {value, {dialyzer, Opts}, Rest} = lists:keytake(dialyzer, 1, RebarConfig),
- % Remove erts => []
- % Add erlang+zlib => [erlang, zlib],
- % Add erl_prim_loader+init => [erl_prim_loader, init, erlang, zlib]
- % Remove zlib+init => [erl_prim_loader, erlang]
- Opts2 = [{exclude_apps, [erts]},
- {base_plt_mods, [erlang, zlib]},
- {plt_extra_mods, [erl_prim_loader, init]},
- {exclude_mods, [zlib, init]} |
- Opts],
- RebarConfig2 = [{dialyzer, Opts2} | Rest],
-
- Name = rebar_test_utils:create_random_name("app1_"),
- Vsn = rebar_test_utils:create_random_vsn(),
- rebar_test_utils:create_app(AppDir, Name, Vsn, [erts]),
-
- rebar_test_utils:run_and_check(Config, RebarConfig2, ["dialyzer"],
- {ok, [{app, Name}]}),
-
- Erlang = code:where_is_file("erlang.beam"),
- {ok, BasePltFiles} = plt_files(BasePlt),
- ?assertEqual([Erlang], BasePltFiles),
-
- Pair = lists:sort([Erlang, code:where_is_file("erl_prim_loader.beam")]),
- {ok, PltFiles} = plt_files(Plt),
- ?assertEqual(Pair, PltFiles).
-
- %% Helpers
-
- erts_files() ->
- ErtsDir = code:lib_dir(erts, ebin),
- ErtsBeams = filelib:wildcard("*.beam", ErtsDir),
- ErtsFiles = lists:map(fun(Beam) -> filename:join(ErtsDir, Beam) end,
- ErtsBeams),
- lists:sort(ErtsFiles).
-
- plt_files(Plt) ->
- case dialyzer:plt_info(Plt) of
- {ok, Info} ->
- Files = proplists:get_value(files, Info),
- {ok, lists:sort(Files)};
- Other ->
- Other
- end.
-
- alter_plt(Plt) ->
- {ok, Files} = plt_files(Plt),
- _ = dialyzer:run([{analysis_type, plt_remove},
- {init_plt, Plt},
- {files, [hd(Files)]}]),
- _ = dialyzer:run([{analysis_type, plt_add},
- {init_plt, Plt},
- {files, [code:which(dialyzer)]}]),
- ok.
-
- add_missing_file(Plt) ->
- Source = code:which(dialyzer),
- Dest = filename:join(filename:dirname(Plt), "dialyzer.beam"),
- {ok, _} = file:copy(Source, Dest),
- _ = try
- dialyzer:run([{analysis_type, plt_add},
- {init_plt, Plt},
- {files, [Dest]}])
- after
- ok = file:delete(Dest)
- end,
- ok.
-
- -spec merge_config(Config, Config) -> Config when
- Config :: [{term(), term()}].
- merge_config(NewConfig, OldConfig) ->
- dict:to_list(
- rebar_opts:merge_opts(dict:from_list(NewConfig),
- dict:from_list(OldConfig))).
-
- -spec get_apps_from_beam_files(string()) -> [atom()].
- get_apps_from_beam_files(BeamFiles) ->
- lists:usort(
- [begin
- AppNameVsn = filename:basename(filename:dirname(filename:dirname(File))),
- [AppName | _] = string:tokens(AppNameVsn ++ "-", "-"),
- ec_cnv:to_atom(AppName)
- end || File <- BeamFiles]).
|