aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorEric <[email protected]>2012-09-12 16:27:41 -0500
committerEric <[email protected]>2012-09-12 16:27:41 -0500
commit2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb (patch)
tree6356c02752681f522fae2d843d0a97151e6af7bf /test
parent152a385e6cc6de064e2a0f1b1ef3061826598180 (diff)
downloadrelx-2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb.tar.gz
relx-2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb.tar.bz2
relx-2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb.zip
support OTP App discovery in the system
Diffstat (limited to 'test')
-rw-r--r--test/rclt_discover_SUITE.erl194
1 files changed, 194 insertions, 0 deletions
diff --git a/test/rclt_discover_SUITE.erl b/test/rclt_discover_SUITE.erl
new file mode 100644
index 0000000..718fd03
--- /dev/null
+++ b/test/rclt_discover_SUITE.erl
@@ -0,0 +1,194 @@
+%%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
+%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
+%%%
+%%% This file is provided to you under the Apache License,
+%%% Version 2.0 (the "License"); you may not use this file
+%%% except in compliance with the License. You may obtain
+%%% a copy of the License at
+%%%
+%%% http://www.apache.org/licenses/LICENSE-2.0
+%%%
+%%% Unless required by applicable law or agreed to in writing,
+%%% software distributed under the License is distributed on an
+%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%%% KIND, either express or implied. See the License for the
+%%% specific language governing permissions and limitations
+%%% under the License.
+%%%-------------------------------------------------------------------
+%%% @author Eric Merrit <[email protected]>
+%%% @copyright (C) 2012, Eric Merrit
+-module(rclt_discover_SUITE).
+
+-export([suite/0,
+ init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ all/0,
+ normal_case/1,
+ no_beam_case/1,
+ bad_ebin_case/1]).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ LibDir1 = filename:join([DataDir, create_random_name("lib_dir1_")]),
+ LibDir2 = filename:join([DataDir, create_random_name("lib_dir2_")]),
+ ok = rcl_util:mkdir_p(LibDir1),
+ ok = rcl_util:mkdir_p(LibDir2),
+ State = rcl_state:new([{lib_dirs, [LibDir1, LibDir2]}], []),
+ [{lib1, LibDir1},
+ {lib2, LibDir2},
+ {state, State} | Config].
+
+
+all() ->
+ [normal_case, no_beam_case, bad_ebin_case].
+
+normal_case(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+ Apps1 = [(fun({Name, Vsn}) ->
+ create_app(LibDir1, Name, Vsn)
+ end)(App)
+ ||
+ App <-
+ [{create_random_name("lib_app1_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ LibDir2 = proplists:get_value(lib2, Config),
+ Apps2 = [(fun({Name, Vsn}) ->
+ create_app(LibDir2, Name, Vsn)
+ end)(App)
+ || App <-
+ [{create_random_name("lib_app2_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+ State0 = proplists:get_value(state, Config),
+ {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0),
+ {ok, State2} = rcl_provider:do(DiscoverProvider, State1),
+ lists:foreach(fun(App) ->
+ ?assertMatch(true, lists:member(App, rcl_state:available_apps(State2)))
+ end, Apps1),
+
+ lists:foreach(fun(App) ->
+ ?assertMatch(true, lists:member(App, rcl_state:available_apps(State2)))
+ end, Apps2),
+ Length = erlang:length(Apps2) +
+ erlang:length(Apps2),
+ ?assertMatch(Length, erlang:length(rcl_state:available_apps(State2))).
+
+no_beam_case(Config) ->
+ %% We silently ignore apps with no beams
+ LibDir1 = proplists:get_value(lib1, Config),
+ _Apps1 = [(fun({Name, Vsn}) ->
+ create_app(LibDir1, Name, Vsn)
+ end)(App)
+ ||
+ App <-
+ [{create_random_name("lib_app1_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ LibDir2 = proplists:get_value(lib2, Config),
+ _Apps2 = [(fun({Name, Vsn}) ->
+ create_app(LibDir2, Name, Vsn)
+ end)(App)
+ || App <-
+ [{create_random_name("lib_app2_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+ BadName = create_random_name("error_bad"),
+ BadVsn = create_random_vsn(),
+ AppDir = filename:join([LibDir2, BadName]),
+ write_app_file(AppDir, BadName, BadVsn),
+ State0 = proplists:get_value(state, Config),
+ {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0),
+ EbinDir = filename:join([LibDir2, BadName, "ebin"]),
+ %% Ignore apps that do not contain any beam files
+ ?assertMatch({error, [{no_beam_files, EbinDir}]},
+ rcl_provider:do(DiscoverProvider, State1)).
+
+bad_ebin_case(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+ _Apps1 = [(fun({Name, Vsn}) ->
+ create_app(LibDir1, Name, Vsn)
+ end)(App)
+ ||
+ App <-
+ [{create_random_name("lib_app1_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ LibDir2 = proplists:get_value(lib2, Config),
+ _Apps2 = [(fun({Name, Vsn}) ->
+ create_app(LibDir2, Name, Vsn)
+ end)(App)
+ || App <-
+ [{create_random_name("lib_app2_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+ BadName = create_random_name("error_bad"),
+ BadVsn = create_random_vsn(),
+ AppDir = filename:join([LibDir2, BadName]),
+ Filename = filename:join([AppDir, "ebin", BadName ++ ".app"]),
+ io:format("BAD -> ~p~n", [Filename]),
+ ok = filelib:ensure_dir(Filename),
+ ok = ec_file:write_term(Filename, get_bad_app_metadata(BadName, BadVsn)),
+ write_beam_file(AppDir, BadName),
+ State0 = proplists:get_value(state, Config),
+ {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0),
+
+ %% Ignore apps that do not contain any beam files
+ ?assertMatch({error, [{invalid_app_file, Filename}]},
+ rcl_provider:do(DiscoverProvider, State1)).
+
+
+
+%%% API
+%%%===================================================================
+create_app(Dir, Name, Vsn) ->
+ AppDir = filename:join([Dir, Name]),
+ write_app_file(AppDir, Name, Vsn),
+ write_beam_file(AppDir, Name),
+ rcl_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
+ [kernel, stdlib], []).
+
+write_beam_file(Dir, Name) ->
+ Beam = filename:join([Dir, "ebin", "not_a_real_beam" ++ Name ++ ".beam"]),
+ ok = filelib:ensure_dir(Beam),
+ ok = ec_file:write_term(Beam, testing_purposes_only).
+
+write_app_file(Dir, Name, Version) ->
+ Filename = filename:join([Dir, "ebin", Name ++ ".app"]),
+ ok = filelib:ensure_dir(Filename),
+ ok = ec_file:write_term(Filename, get_app_metadata(Name, Version)).
+
+get_app_metadata(Name, Vsn) ->
+ {application, erlang:list_to_atom(Name),
+ [{description, ""},
+ {vsn, Vsn},
+ {modules, []},
+ {applications, [kernel, stdlib]}]}.
+
+get_bad_app_metadata(Name, Vsn) ->
+ ["{application, ", Name, ",
+ [{description, \"\"},
+ {vsn, \"", Vsn, "\"},
+ {modules, [],
+ {applications, [kernel, stdlib]}]}."].
+
+
+create_random_name(Name) ->
+ random:seed(erlang:now()),
+ Name ++ erlang:integer_to_list(random:uniform(1000000)).
+
+create_random_vsn() ->
+ random:seed(erlang:now()),
+ lists:flatten([erlang:integer_to_list(random:uniform(100)),
+ ".", erlang:integer_to_list(random:uniform(100)),
+ ".", erlang:integer_to_list(random:uniform(100))]).