diff options
Diffstat (limited to 'lib/sasl/test')
-rw-r--r-- | lib/sasl/test/installer.erl | 15 | ||||
-rw-r--r-- | lib/sasl/test/release_handler_SUITE.erl | 244 | ||||
-rw-r--r-- | lib/sasl/test/rh_test_lib.erl | 64 | ||||
-rw-r--r-- | lib/sasl/test/sasl_SUITE.erl | 160 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE.erl | 44 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/ebin/app1.app | 7 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/src/myapp.erl | 2 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/ebin/app2.app | 7 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/src/myapp.erl | 2 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE_data/d_unicode/lib/ua-1.0/ebin/ua.app | 1 | ||||
-rw-r--r-- | lib/sasl/test/systools_rc_SUITE.erl | 168 | ||||
-rw-r--r-- | lib/sasl/test/test_lib.hrl | 4 |
12 files changed, 488 insertions, 230 deletions
diff --git a/lib/sasl/test/installer.erl b/lib/sasl/test/installer.erl index 709269a73c..fa404c8b7b 100644 --- a/lib/sasl/test/installer.erl +++ b/lib/sasl/test/installer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2012. All Rights Reserved. +%% Copyright Ericsson AB 2011-2013. 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 @@ -54,8 +54,12 @@ -export([reg_proc/1]). -export([registered_loop/1]). --define(print(List), {rh_print, TestNode} ! {print, {?MODULE, ?LINE}, List}). --define(print_line(Line,List), {rh_print, TestNode} ! {print, {?MODULE, Line}, List}). +-define(print(List), + io:format(user,"(~w:~w) ~tp~n",[?MODULE,?LINE,List]), + {rh_print, TestNode} ! {print, {?MODULE, ?LINE}, List}). +-define(print_line(Line,List), + io:format(user,"(~w:~w) ~tp~n",[?MODULE,Line,List]), + {rh_print, TestNode} ! {print, {?MODULE, Line}, List}). -define(fail(Term), exit({?MODULE, ?LINE, Term})). -define(fail_line(Line,Term), exit({?MODULE, Line, Term})). @@ -905,10 +909,9 @@ start_client(TestNode,Client,Sname) -> start_client_unix(TestNode,Sname,Node) -> Start = filename:join(["clients", "type1", Node, "bin", "start"]), - Cmd = lists:concat(["env NODENAME=",Sname," ", - filename:join(code:root_dir(), Start)]), + Cmd = filename:join(code:root_dir(), Start), ?print([{start_client,Sname},Cmd]), - Res = os:cmd(Cmd), + Res = rh_test_lib:cmd(Cmd,[],[{"NODENAME",atom_to_list(Sname)}]), ?print([{start_client,result},Res]). start_client_win32(TestNode,Client,ClientSname) -> diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index d7369b0ecf..ad2a8005b9 100644 --- a/lib/sasl/test/release_handler_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2014. 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 @@ -35,7 +35,8 @@ init_per_suite(Config) -> application:start(sasl), Config. -end_per_suite(_Config) -> +end_per_suite(Config) -> + clean_priv_dir(Config,true), ok. all() -> @@ -50,7 +51,7 @@ unix_cases() -> true -> [{group, release}]; false -> [no_run_erl] end, - [target_system] ++ RunErlCases ++ cases(). + [target_system, target_system_unicode] ++ RunErlCases ++ cases(). win32_cases() -> [{group,release} | cases()]. @@ -163,7 +164,6 @@ end_per_group(release, Config) -> {win32,_} -> delete_all_services(); _ -> ok end, - clean_priv_dir(Config,true), ?t:timetrap_cancel(Dog), Config; end_per_group(_GroupName, Config) -> @@ -1559,6 +1559,9 @@ eval_appup_with_restart(Conf) when is_list(Conf) -> %% Test the example/target_system.erl module target_system(Conf) when is_list(Conf) -> PrivDir = priv_dir(Conf), + target_system1(Conf,PrivDir). + +target_system1(Conf,PrivDir) -> DataDir = ?config(data_dir,Conf), TargetCreateDir = filename:join([PrivDir,"target_system","create"]), @@ -1567,7 +1570,6 @@ target_system(Conf) when is_list(Conf) -> ok = filelib:ensure_dir(filename:join(TargetCreateDir,"xx")), ok = filelib:ensure_dir(filename:join(TargetInstallDir,"xx")), - %% Create the .rel file RelName = filename:join(TargetCreateDir,"ts-1.0"), RelFile = RelName++".rel", @@ -1607,7 +1609,8 @@ target_system(Conf) when is_list(Conf) -> StdlibVsn = vsn(stdlib,current), SaslVsn = vsn(sasl,current), RelFileBasename = filename:basename(RelFile), - true = filelib:is_dir(filename:join(LibDir,"kernel-"++KernelVsn)), + KernelLibDir = filename:join(LibDir,"kernel-"++KernelVsn), + true = filelib:is_dir(KernelLibDir), true = filelib:is_dir(filename:join(LibDir,"stdlib-"++StdlibVsn)), true = filelib:is_dir(filename:join(LibDir,"sasl-"++SaslVsn)), true = filelib:is_dir(filename:join(LibDir,"a-1.0")), @@ -1616,11 +1619,13 @@ target_system(Conf) when is_list(Conf) -> true = filelib:is_regular(filename:join(RelDir,"start_erl.data")), true = filelib:is_regular(filename:join(RelDir,RelFileBasename)), true = filelib:is_dir(filename:join(RelDir,RelVsn)), - true = filelib:is_regular(filename:join([RelDir,RelVsn,"start.boot"])), + StartBoot = filename:join([RelDir,RelVsn,"start.boot"]), + true = filelib:is_regular(StartBoot), true = filelib:is_regular(filename:join([RelDir,RelVsn,RelFileBasename])), BinDir = filename:join(TargetInstallDir,bin), + Erl = filename:join(BinDir,erl), + true = filelib:is_regular(Erl), true = filelib:is_regular(filename:join(BinDir,"start.boot")), - true = filelib:is_regular(filename:join(BinDir,erl)), true = filelib:is_regular(filename:join(BinDir,start_erl)), true = filelib:is_regular(filename:join(BinDir,start)), true = filelib:is_regular(filename:join(BinDir,epmd)), @@ -1631,9 +1636,75 @@ target_system(Conf) when is_list(Conf) -> ErtsVsn = vsn(erts,current), {ok,SED} = file:read_file(filename:join(RelDir,"start_erl.data")), [ErtsVsn,RelVsn] = string:tokens(binary_to_list(SED),"\s\n"), + + %% Check that installation can be started + Sname = list_to_atom(atom_to_list(?MODULE) ++ "-target_system"), + {ok,Node} = start_target_node_with_erl(Erl,Sname,StartBoot), + + TargetInstallDir = rpc:call(Node,code,root_dir,[]), + KernelLibDir = rpc:call(Node,code,lib_dir,[kernel]), + [{RelName,RelVsn,_Apps,permanent}] = + rpc:call(Node,release_handler,which_releases,[]), + + ?t:format("Target node ok:~nRootDir: ~ts~nKernelLibDir: ~ts~nRelease: ~ts", + [TargetInstallDir,KernelLibDir,RelName]), + + ok. + +target_system(cleanup,_Conf) -> + Sname = list_to_atom(atom_to_list(?MODULE) ++ "-target_system"), + stop_target_node(node_name(Sname)), ok. +start_target_node_with_erl(Erl,Sname,Boot) -> + FullName = node_name(Sname), + FilenameMode = case file:native_name_encoding() of + latin1 -> "+fnl"; + utf8 -> "+fnui" + end, + Args = [FilenameMode,"-detached", "-noinput","-sname",atom_to_list(Sname), + "-boot",filename:rootname(Boot)], + ?t:format("Starting node ~p: ~ts~n", + [FullName, lists:flatten([[X," "] || X <- [Erl|Args]])]), + case rh_test_lib:cmd(Erl,Args,[]) of + ok -> + ok = wait_nodes_up([FullName],"target_system test node"), + {ok,FullName}; + Error -> + ?t:fail({failed_to_start_node, FullName, Error}) + end. +stop_target_node(Node) -> + monitor_node(Node, true), + _ = rpc:call(Node,erlang,halt,[]), + receive {nodedown, Node} -> ok end. + +%% Test that the example/target_system.erl module can create and +%% install under a path which includes unicode characters +target_system_unicode(Conf) when is_list(Conf) -> + PrivDir = priv_dir(Conf), + UnicodePrivDir = filename:join(PrivDir,"αβ"), + + PA = filename:dirname(code:which(?MODULE)), + + %% Make sure this runs on a node with unicode file name mode + Sname = list_to_atom(atom_to_list(?MODULE) ++ "-target_system_unicode"), + {ok,Node} = ?t:start_node(Sname,peer,[{args,"+fnui -pa " ++ PA}]), + ok = rpc:call(Node,file,make_dir,[UnicodePrivDir]), + case rpc:call(Node,application,start,[sasl]) of + ok -> ok; + {error,{already_started,sasl}} -> ok; + Error -> ?t:fail({failed_to_start_sasl_on_test_node,Node,Error}) + end, + ok = rpc:call(Node,?MODULE,target_system1,[Conf,UnicodePrivDir]), + ok. + +target_system_unicode(cleanup,Conf) -> + Sname = list_to_atom(atom_to_list(?MODULE) ++ "-target_system_unicode"), + Node = node_name(Sname), + _ = rpc:call(Node,?MODULE,target_system,[cleanup,Conf]), + _ = stop_node(Node), + ok. %%%================================================================= %%% Testing global groups. @@ -1710,37 +1781,46 @@ otp_10463_upgrade_script_regexp(_Config) -> ok. no_dot_erlang(Conf) -> - PrivDir = priv_dir(Conf), + PrivDir = ?config(data_dir,Conf), {ok, OrigWd} = file:get_cwd(), try ok = file:set_cwd(PrivDir), - Erl = filename:join([code:root_dir(),"bin","erl"]), - Args = " -noinput -run io put_chars \"TESTOK\" -run erlang halt", + {ok, Wd} = file:get_cwd(), + io:format("Dir ~ts~n", [Wd]), + + Erl0 = filename:join([code:root_dir(),"bin","erl"]), + Erl = filename:nativename(Erl0), + Quote = "\"", + Args = " -noinput -run c pwd -run erlang halt", ok = file:write_file(".erlang", <<"io:put_chars(\"DOT_ERLANG_READ\\n\").\n">>), - case os:cmd(Erl ++ Args) of + CMD1 = Quote ++ Erl ++ Quote ++ Args , + case os:cmd(CMD1) of "DOT_ERLANG_READ" ++ _ -> ok; Other1 -> - io:format("Failed: ~s~n",[Erl ++ Args]), + io:format("Failed: ~ts~n",[CMD1]), io:format("Expected: ~s ++ _~n",["DOT_ERLANG_READ "]), - io:format("Got: ~s~n",[Other1]), - exit(failed_to_start, test_error) + io:format("Got: ~ts~n",[Other1]), + exit({failed_to_start, test_error}) end, NO_DOT_ERL = " -boot no_dot_erlang", - case os:cmd(Erl ++ NO_DOT_ERL ++ Args) of - "TESTOK" ++ _ -> ok; - Other2 -> - io:format("Failed: ~s~n",[Erl ++ Args]), + CMD2 = Quote ++ Erl ++ Quote ++ NO_DOT_ERL ++ Args, + case lists:prefix(Wd, Other2 = os:cmd(CMD2)) of + true -> ok; + false -> + io:format("Failed: ~ts~n",[CMD2]), io:format("Expected: ~s~n",["TESTOK"]), - io:format("Got: ~s~n",[Other2]), - exit(failed_to_start, no_dot_erlang) + io:format("Got: ~ts~n",[Other2]), + exit({failed_to_start, no_dot_erlang}) end after _ = file:delete(".erlang"), - ok = file:set_cwd(OrigWd) + ok = file:set_cwd(OrigWd), + ok end. + %%%================================================================= %%% Misceleaneous functions %%%================================================================= @@ -1883,7 +1963,7 @@ stop_node(Node) -> copy_client(Conf,Master,Sname,Client) -> - io:format("copy_client(Conf)"), + ?t:format("copy_client(Conf)"), DataDir = ?config(data_dir, Conf), MasterDir = filename:join(priv_dir(Conf),Master), @@ -1922,82 +2002,12 @@ copy_client(Conf,Master,Sname,Client) -> clean_priv_dir(Conf,Save) -> PrivDir = priv_dir(Conf), - - {ok, OrigWd} = file:get_cwd(), - - ok = file:set_cwd(PrivDir), - ?t:format("======== current dir ~p~n",[PrivDir]), - {ok, Dirs} = file:list_dir(PrivDir), - ?t:format("======== deleting ~p~n",[Dirs]), - - ok = clean_dirs_os(Dirs,Save), - {ok,Remaining} = file:list_dir(PrivDir), - ?t:format("======== remaining ~p~n",[Remaining]), - - case Remaining of - [] -> - ok; - _ -> - clean_dirs_os(Remaining,Save), - Remaining2 = file:list_dir(PrivDir), - ?t:format("======== remaining after second try ~p~n",[Remaining2]) - end, - - ok = file:set_cwd(OrigWd), - ok. - - -clean_dirs_os(Dirs,Save) -> - case os:type() of - {unix, _} -> - clean_dirs_unix(Dirs,Save); - {win32, _} -> - clean_dirs_win32(Dirs,Save); - Os -> - test_server:fail({error, {not_yet_implemented_os, Os}}) + rh_test_lib:clean_dir(PrivDir,Save), + case file:list_dir(PrivDir) of + {ok,[]} -> _ = file:del_dir(PrivDir); + _ -> ok end. - -clean_dirs_unix([],_) -> - ok; -clean_dirs_unix(["save"|Dirs],Save) when Save -> - clean_dirs_unix(Dirs,Save); -clean_dirs_unix([Dir|Dirs],Save) -> - Rm = string:concat("rm -rf ", Dir), - ?t:format("============== COMMAND ~p~n",[Rm]), - case file:list_dir(Dir) of - {error, enotdir} -> - ok; - X -> - ?t:format("------- Dir ~p~n ~p~n",[Dir, X]) - end, - case os:cmd(Rm) of - [] -> - ?t:format("------- Result of COMMAND ~p~n",[ok]); - Y -> - ?t:format("!!!!!!! delete ERROR Dir ~p Error ~p~n",[Dir, Y]), - ?t:format("------- ls -al ~p~n",[os:cmd("ls -al " ++ Dir)]) - end, - - clean_dirs_unix(Dirs,Save). - -clean_dirs_win32([],_) -> - ok; -clean_dirs_win32(["save"|Dirs],Save) when Save -> - clean_dirs_win32(Dirs,Save); -clean_dirs_win32([Dir|Dirs],Save) -> - Rm = - case filelib:is_dir(Dir) of - true -> - string:concat("rmdir /s /q ", Dir); - false -> - string:concat("del /q ", Dir) - end, - ?t:format("============== COMMAND ~p~n",[Rm]), - [] = os:cmd(Rm), - clean_dirs_win32(Dirs,Save). - - node_name(Sname) when is_atom(Sname) -> {ok,Host} = inet:gethostname(), list_to_atom(atom_to_list(Sname) ++ "@" ++ Host). @@ -2043,7 +2053,7 @@ chmod(Dest,Opts) -> copy_error(Src, Dest, Reason) -> - io:format("Copy ~s to ~s failed: ~s\n", + ?t:format("Copy ~ts to ~ts failed: ~ts\n", [Src,Dest,file:format_error(Reason)]), ?t:fail(file_copy_failed). @@ -2083,9 +2093,11 @@ subst_file(Src, Dest, Vars) -> subst_file(Src, Dest, Vars, []). subst_file(Src, Dest, Vars, Opts) -> {ok, Bin} = file:read_file(Src), - Conts = binary_to_list(Bin), + Conts = binary_to_list(Bin), % The source will always be latin1 NConts = subst(Conts, Vars), - ok = file:write_file(Dest, NConts), + %% The destination must be utf8 if file name encoding is unicode + Enc = file:native_name_encoding(), + ok = file:write_file(Dest, unicode:characters_to_binary(NConts,Enc,Enc)), preserve(Src,Dest,Opts), chmod(Dest,Opts). @@ -2118,13 +2130,22 @@ subst_var([], Vars, Result, VarAcc) -> priv_dir(Conf) -> -%% filename:absname(?config(priv_dir, Conf)). % Get rid of trailing slash %% Due to problem with long paths on windows => creating a new %% priv_dir under data_dir - filename:absname(filename:join(?config(data_dir, Conf),priv_dir)). + %% And get rid of trailing slash (absname does that) + %% And if file name translation mode is utf8, use a path with + %% unicode characters + PrivDir = + case file:native_name_encoding() of + utf8 -> + "priv_dir_αβ"; + _ -> + "priv_dir" + end, + filename:absname(filename:join([?config(data_dir, Conf),PrivDir])). init_priv_dir(Conf) -> - Dir = filename:absname(filename:join(?config(data_dir, Conf),priv_dir)), + Dir = priv_dir(Conf), case filelib:is_dir(Dir) of true -> clean_priv_dir(Conf,false); @@ -2149,7 +2170,7 @@ rh_print() -> receive {print, {Module,Line}, [H|T]} -> ?t:format("=== ~p:~p - ~p",[Module,Line,H]), - lists:foreach(fun(Term) -> ?t:format(" ~p",[Term]) end, T), + lists:foreach(fun(Term) -> ?t:format(" ~tp",[Term]) end, T), ?t:format("",[]), rh_print(); kill -> @@ -2542,11 +2563,14 @@ start_nodes(Conf,Snames,Tag) -> start_node_unix(Sname,NodeDir) -> Script = filename:join([NodeDir,"bin","start"]), - Cmd = "env NODENAME="++atom_to_list(Sname) ++ " " ++ Script, - %% {ok,StartFile} = file:read_file(Cmd), - %% io:format("~s:\n~s~n~n",[Start,binary_to_list(StartFile)]), - Res = os:cmd(Cmd), - io:format("Start ~p: ~p~n=>\t~p~n", [Sname,Cmd,Res]). + ?t:format("Starting ~p: ~tp~n", [Sname,Script]), + case rh_test_lib:cmd(Script,[],[{"NODENAME",atom_to_list(Sname)}]) of + ok -> + {ok,node_name(Sname)}; + Error -> + ?t:fail({failed_to_start_node, Sname, Error}) + end. + start_node_win32(Sname,NodeDir) -> Name = atom_to_list(Sname) ++ "_P1G", @@ -2707,7 +2731,7 @@ rpc_inst(Node,Func,Args) -> delete_all_services() -> ErlSrv = erlsrv:erlsrv(erlang:system_info(version)), - [_|Serviceinfo] = string:tokens(os:cmd(ErlSrv ++ " list"),"\n"), + [_|Serviceinfo] = string:tokens(os:cmd("\"" ++ ErlSrv ++ "\" list"),"\n"), Services = [lists:takewhile(fun($\t) -> false; (_) -> true end,S) || S <- Serviceinfo], diff --git a/lib/sasl/test/rh_test_lib.erl b/lib/sasl/test/rh_test_lib.erl index 99a7f919a7..11935496d8 100644 --- a/lib/sasl/test/rh_test_lib.erl +++ b/lib/sasl/test/rh_test_lib.erl @@ -1,5 +1,6 @@ -module(rh_test_lib). +-export([cmd/3]). -export([erlsrv/3, erlsrv/4]). -export([get_service_args/3, @@ -8,12 +9,26 @@ get_start_erl_args/3, get_client_args/3, get_client_args/4]). +-export([clean_dir/1, + clean_dir/2]). +-include_lib("kernel/include/file.hrl"). + +cmd(Cmd,Args,Env) -> + case open_port({spawn_executable, Cmd}, [{args,Args},{env,Env}]) of + Port when is_port(Port) -> + unlink(Port), + erlang:port_close(Port), + ok; + Error -> + Error + end. erlsrv(Erlsrv,Action,Name) -> erlsrv(Erlsrv,Action,Name,""). erlsrv(Erlsrv,Action,Name,Rest) -> - Cmd = Erlsrv ++ " " ++ atom_to_list(Action) ++ " " ++ Name ++ " " ++ Rest, + Cmd = "\"" ++ Erlsrv ++ "\" " ++ atom_to_list(Action) ++ " " ++ + Name ++ " " ++ Rest, io:format("erlsrv cmd: ~p~n",[Cmd]), Port = open_port({spawn, Cmd}, [stream, {line, 100}, eof, in]), Res = recv_prog_output(Port), @@ -98,3 +113,50 @@ single_quote() -> _ -> "\\'" end. + +clean_dir(Dir) -> + clean_dir(Dir,false). +clean_dir(Dir,Save) -> + test_server:format("======== current dir ~tp~n",[Dir]), + Dirs = filelib:wildcard(filename:join(Dir,"*")), + test_server:format("======== deleting ~tp~n",[Dirs]), + + ok = rm_rf(Dirs,Save), + Remaining = filelib:wildcard(filename:join(Dir,"*")), + test_server:format("======== remaining ~tp~n",[Remaining]), + + case Remaining of + [] -> + ok; + _ -> + rm_rf(Remaining,Save), + Remaining2 = filelib:wildcard(filename:join(Dir,"*")), + test_server:format("======== remaining after second try ~tp~n", + [Remaining2]) + end, + + ok. + + +rm_rf([File|Files],Save) -> + case Save andalso filename:basename(File)=="save" of + true -> + rm_rf(Files,Save); + false -> + case file:read_link_info(File) of + {ok,#file_info{type=directory}} -> + MoreFiles = filelib:wildcard(filename:join(File,"*")), + rm_rf(MoreFiles,Save), + file:del_dir(File), + rm_rf(Files,Save); + {ok,#file_info{}} -> + file:delete(File), + rm_rf(Files,Save); + Other -> + test_server:format("======== could not delete file ~p~n" + "read_link_info -> ~p~n",[File,Other]), + rm_rf(Files,Save) + end + end; +rm_rf([],_) -> + ok. diff --git a/lib/sasl/test/sasl_SUITE.erl b/lib/sasl/test/sasl_SUITE.erl index b6eaf41323..f4455f7e9b 100644 --- a/lib/sasl/test/sasl_SUITE.erl +++ b/lib/sasl/test/sasl_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2014. 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 @@ -19,11 +19,6 @@ -module(sasl_SUITE). -include_lib("common_test/include/ct.hrl"). - -%% Default timetrap timeout (set in init_per_testcase). --define(default_timeout, ?t:minutes(1)). --define(application, sasl). - %% Test server specific exports -export([all/0,groups/0,init_per_group/2,end_per_group/2]). -export([init_per_testcase/2, end_per_testcase/2]). @@ -34,7 +29,7 @@ log_mf_h_env/1]). all() -> - [app_test, appup_test, log_mf_h_env]. + [log_mf_h_env, app_test, appup_test]. groups() -> []. @@ -47,102 +42,88 @@ end_per_group(_GroupName, Config) -> init_per_testcase(_Case, Config) -> - Dog=test_server:timetrap(?default_timeout), - [{watchdog, Dog}|Config]. -end_per_testcase(_Case, Config) -> - Dog=?config(watchdog, Config), - test_server:timetrap_cancel(Dog), + Config. +end_per_testcase(_Case, _Config) -> ok. app_test(Config) when is_list(Config) -> ?t:app_test(sasl, allow), ok. -%% Test that appup allows upgrade from/downgrade to a maximum of two -%% major releases back. +%% Test that appup allows upgrade from/downgrade to a maximum of one +%% major release back. appup_test(_Config) -> - application:load(sasl), - {sasl,_,SaslVsn} = lists:keyfind(sasl,1,application:loaded_applications()), - Ebin = filename:join(code:lib_dir(sasl),ebin), - {ok,[{SaslVsn,UpFrom,DownTo}=Appup]} = - file:consult(filename:join(Ebin,"sasl.appup")), - ct:log("~p~n",[Appup]), - {OkVsns,NokVsns} = create_test_vsns(SaslVsn), + appup_tests(sasl,create_test_vsns(sasl)). + +appup_tests(_App,{[],[]}) -> + {skip,"no previous releases available"}; +appup_tests(App,{OkVsns,NokVsns}) -> + application:load(App), + {_,_,Vsn} = lists:keyfind(App,1,application:loaded_applications()), + AppupFileName = atom_to_list(App) ++ ".appup", + AppupFile = filename:join([code:lib_dir(App),ebin,AppupFileName]), + {ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile), + ct:log("~p~n",[AppupScript]), + ct:log("Testing ok versions: ~p~n",[OkVsns]), check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}), check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}), + ct:log("Testing not ok versions: ~p~n",[NokVsns]), check_appup(NokVsns,UpFrom,error), check_appup(NokVsns,DownTo,error), ok. - -%% For sasl, the versions up to R14B03 were not according to the rule -%% used for other core applications - i.e. to change the second number -%% at major releases, the third at maintenance releases and the fourth -%% for patches - therefore test versions up to and including R16 are -%% hardcoded. -%% (All versions below are not necessarily existing.) --define(r12_vsns,["2.1.5"]). --define(r13_vsns,["2.1.6","2.1.7.1","2.1.9","2.1.9.1.2"]). --define(r14_vsns,["2.1.9.2","2.1.9.2.20","2.1.9.4","2.1.10"]). --define(r15_major,"2.2"). --define(r16_major,"2.3"). --define(r17_major,"2.4"). -create_test_vsns(?r15_major ++ Rest) -> - R15Vsns = - case string:tokens(Rest,".") of - [] -> []; - ["1"] -> [?r15_major]; - _ -> [?r15_major,?r15_major++".1"] - end, - OkVsns = ?r13_vsns ++ ?r14_vsns ++ R15Vsns, - NokVsns = ?r12_vsns ++ [?r15_major++",1", ?r16_major], - {OkVsns,NokVsns}; -create_test_vsns(?r16_major ++ Rest) -> - R16Vsns = - case string:tokens(Rest,".") of - [] -> []; - ["1"] -> [?r16_major]; - _ -> [?r16_major,?r16_major++".1"] +create_test_vsns(App) -> + This = erlang:system_info(otp_release), + FirstMajor = previous_major(This), + SecondMajor = previous_major(FirstMajor), + Ok = app_vsn(App,[FirstMajor]), + Nok0 = app_vsn(App,[SecondMajor]), + Nok = case Ok of + [Ok1|_] -> + [Ok1 ++ ",1" | Nok0]; % illegal + _ -> + Nok0 + end, + {Ok,Nok}. + +previous_major("17") -> + "r16"; +previous_major("r"++Rel) -> + "r"++previous_major(Rel); +previous_major(Rel) -> + integer_to_list(list_to_integer(Rel)-1). + +app_vsn(App,[R|Rs]) -> + OldRel = + case test_server:is_release_available(R) of + true -> + {release,R}; + false -> + case ct:get_config({otp_releases,list_to_atom(R)}) of + undefined -> + false; + Prog0 -> + case os:find_executable(Prog0) of + false -> + false; + Prog -> + {prog,Prog} + end + end end, - OkVsns = ?r14_vsns ++ [?r15_major, ?r15_major ++ ".1.4"] ++ R16Vsns, - NokVsns = ?r13_vsns ++ [?r16_major++",1", ?r17_major], - {OkVsns,NokVsns}; -%% Normal erts case - i.e. for versions that comply to the erts standard -create_test_vsns(Current) -> - [XStr,YStr|Rest] = string:tokens(Current,"."), - X = list_to_integer(XStr), - Y = list_to_integer(YStr), - SecondMajor = vsn(X,Y-2), - SecondMinor = SecondMajor ++ ".1.3", - FirstMajor = vsn(X,Y-1), - FirstMinor = FirstMajor ++ ".57", - ThisMajor = vsn(X,Y), - This = - case Rest of - [] -> - []; - ["1"] -> - [ThisMajor]; - _ -> - ThisMinor = ThisMajor ++ ".1", - [ThisMajor,ThisMinor] - end, - OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor], - - ThirdMajor = vsn(X,Y-3), - ThirdMinor = ThirdMajor ++ ".10.12", - Illegal = ThisMajor ++ ",1", - Newer1Major = vsn(X,Y+1), - Newer1Minor = Newer1Major ++ ".1", - Newer2Major = ThisMajor ++ "1", - NokVsns = [ThirdMajor,ThirdMinor, - Illegal, - Newer1Major,Newer1Minor, - Newer2Major], - {OkVsns,NokVsns}. - -vsn(X,Y) -> - integer_to_list(X) ++ "." ++ integer_to_list(Y). + case OldRel of + false -> + app_vsn(App,Rs); + _ -> + {ok,N} = test_server:start_node(prevrel,peer,[{erl,[OldRel]}]), + _ = rpc:call(N,application,load,[App]), + As = rpc:call(N,application,loaded_applications,[]), + {_,_,V} = lists:keyfind(App,1,As), + test_server:stop_node(N), + [V|app_vsn(App,Rs)] + end; +app_vsn(_App,[]) -> + []. check_appup([Vsn|Vsns],Instrs,Expected) -> case systools_relup:appup_search_for_version(Vsn, Instrs) of @@ -153,7 +134,6 @@ check_appup([],_,_) -> ok. - %% OTP-9185 - fail sasl start if some but not all log_mf_h env vars %% are given. log_mf_h_env(Config) -> diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl index 9efc8f8392..1d3a71e94e 100644 --- a/lib/sasl/test/systools_SUITE.erl +++ b/lib/sasl/test/systools_SUITE.erl @@ -47,6 +47,7 @@ abnormal_script/1, src_tests_script/1, crazy_script/1, included_script/1, included_override_script/1, included_fail_script/1, included_bug_script/1, exref_script/1, + duplicate_modules_script/1, otp_3065_circular_dependenies/1, included_and_used_sort_script/1]). -export([tar_options/1, normal_tar/1, no_mod_vsn_tar/1, system_files_tar/1, system_files_tar/2, invalid_system_files_tar/1, @@ -84,6 +85,7 @@ groups() -> src_tests_script, crazy_script, included_script, included_override_script, included_fail_script, included_bug_script, exref_script, + duplicate_modules_script, otp_3065_circular_dependenies, included_and_used_sort_script]}, {tar, [], [tar_options, normal_tar, no_mod_vsn_tar, system_files_tar, @@ -140,9 +142,9 @@ compile_source(File) -> ok = file:write_file(OutFileTemp, Code), file:rename(OutFileTemp, OutFile). -end_per_suite(Conf) when is_list(Conf) -> - %% Nothing. - Conf. +end_per_suite(Config) when is_list(Config) -> + rh_test_lib:clean_dir(?privdir), + Config. init_per_testcase(link_tar, Config) -> case os:type() of @@ -822,6 +824,33 @@ no_hipe({ok, Value}) -> {ok, Value} end. +%% duplicate_modules_script: Check that make_script rejects two +%% applications providing the same module. +duplicate_modules_script(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), + + {LatestDir, LatestName} = create_script(duplicate_modules,Config), + + DataDir = filename:absname(?copydir), + + ok = file:set_cwd(LatestDir), + LibDir = fname([DataDir, d_duplicate_modules, lib]), + P = [fname([LibDir, 'app1-1.0', ebin]), + fname([LibDir, 'app2-1.0', ebin])], + + %% Check wrong app vsn + error = systools:make_script(LatestName, [{path, P}]), + {error, + systools_make, + {duplicate_modules, [ + {{myapp,app1,_}, {myapp,app2,_}} + ] + } + } = systools:make_script(LatestName, [silent, {path, P}]), + + ok = file:set_cwd(OldDir), + ok. + %% tar_options: Check illegal tar options. tar_options(Config) when is_list(Config) -> {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = @@ -1960,12 +1989,12 @@ otp_6226_outdir(Config) when is_list(Config) -> ok = file:delete(Relup), %% d) absolute but incorrect path - {error,_,{file_problem,{"relup",enoent}}} = + {error,_,{file_problem,{"relup",{open,enoent}}}} = systools:make_relup(LatestName,[LatestName1],[LatestName1], [{outdir,Outdir2},{path,P},silent]), %% e) relative but incorrect path - {error,_,{file_problem,{"relup",enoent}}} = + {error,_,{file_problem,{"relup",{open,enoent}}}} = systools:make_relup(LatestName,[LatestName1],[LatestName1], [{outdir,"./outdir2"},{path,P},silent]), @@ -2186,7 +2215,10 @@ create_script(current_all_future_sasl,Config) -> do_create_script(current_all_future_sasl,Config,current,Apps); create_script({unicode,RelVsn},Config) -> Apps = core_apps(current) ++ [{ua,"1.0"}], - do_create_script(unicode,RelVsn,Config,current,Apps). + do_create_script(unicode,RelVsn,Config,current,Apps); +create_script(duplicate_modules,Config) -> + Apps = core_apps(current) ++ [{app1,"1.0"},{app2,"1.0"}], + do_create_script(duplicate_modules,Config,current,Apps). do_create_script(Id,Config,ErtsVsn,AppVsns) -> diff --git a/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/ebin/app1.app b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/ebin/app1.app new file mode 100644 index 0000000000..dea9257f2f --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/ebin/app1.app @@ -0,0 +1,7 @@ +{application, app1, + [{description, "Application 1"}, + {vsn, "1.0"}, + {modules, [myapp]}, + {registered, []}, + {applications, []}, + {env, []}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/src/myapp.erl b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/src/myapp.erl new file mode 100644 index 0000000000..bf2ab7c79c --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app1-1.0/src/myapp.erl @@ -0,0 +1,2 @@ +-module(myapp). +-vsn("1.0"). diff --git a/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/ebin/app2.app b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/ebin/app2.app new file mode 100644 index 0000000000..476750d8b2 --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/ebin/app2.app @@ -0,0 +1,7 @@ +{application, app2, + [{description, "Application 2"}, + {vsn, "1.0"}, + {modules, [myapp]}, + {registered, []}, + {applications, []}, + {env, []}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/src/myapp.erl b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/src/myapp.erl new file mode 100644 index 0000000000..bf2ab7c79c --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_duplicate_modules/lib/app2-1.0/src/myapp.erl @@ -0,0 +1,2 @@ +-module(myapp). +-vsn("1.0"). diff --git a/lib/sasl/test/systools_SUITE_data/d_unicode/lib/ua-1.0/ebin/ua.app b/lib/sasl/test/systools_SUITE_data/d_unicode/lib/ua-1.0/ebin/ua.app index 3d38a3dde4..7d56a298b8 100644 --- a/lib/sasl/test/systools_SUITE_data/d_unicode/lib/ua-1.0/ebin/ua.app +++ b/lib/sasl/test/systools_SUITE_data/d_unicode/lib/ua-1.0/ebin/ua.app @@ -1,4 +1,3 @@ -%% -*- coding: utf-8 -*- {application, ua, [{description, "αβ"}, {vsn, "1.0"}, diff --git a/lib/sasl/test/systools_rc_SUITE.erl b/lib/sasl/test/systools_rc_SUITE.erl index 0cb6e63cf3..5efab7c028 100644 --- a/lib/sasl/test/systools_rc_SUITE.erl +++ b/lib/sasl/test/systools_rc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2014. 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 @@ -436,25 +436,19 @@ translate(Config) when is_list(Config) -> translate_app(Config) when is_list(Config) -> PreApps = - [#application{name = test, - description = "TEST", - vsn = "1.0", - modules = [foo,bar,baz], - regs = [], - mod = {sasl, []}}, + [Test = #application{name = test, + description = "TEST", + vsn = "1.0", + modules = [foo,bar,baz], + regs = [], + mod = {sasl, []}}, #application{name = pelle, description = "PELLE", vsn = "1.0", modules = [pelle, kalle], regs = [], mod = {pelle, []}}], - Apps = - [#application{name = test, - description = "TEST", - vsn = "1.0", - modules = [foo,bar,baz], - regs = [], - mod = {sasl, []}}], + Apps = [Test], %% Simple translation (1) Up1 = [{add_module, foo}, {add_module, bar}], @@ -475,6 +469,56 @@ translate_app(Config) when is_list(Config) -> {load,{baz,brutal_purge,brutal_purge}}, {apply,{application,start,[test,permanent]}}] = X2, + %% Translate add_application with different restart types + %% permanent + Up2_1 = [{add_application, test, permanent}], + {ok, X2_1} = systools_rc:translate_scripts([Up2_1], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,permanent]}}] = X2_1, + + %% transient + Up2_2 = [{add_application, test, transient}], + {ok, X2_2} = systools_rc:translate_scripts([Up2_2], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,transient]}}] = X2_2, + + %% temporary + Up2_3 = [{add_application, test, temporary}], + {ok, X2_3} = systools_rc:translate_scripts([Up2_3], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,temporary]}}] = X2_3, + + %% load + Up2_4 = [{add_application, test, load}], + {ok, X2_4} = systools_rc:translate_scripts([Up2_4], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,load,[test]}}] = X2_4, + + %% none + Up2_5 = [{add_application, test, none}], + {ok, X2_5} = systools_rc:translate_scripts([Up2_5], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}] = X2_5, + %% Simple translation (3) Up3 = [{remove_application, pelle}], {ok, X3} = systools_rc:translate_scripts([Up3], Apps, PreApps), @@ -484,6 +528,102 @@ translate_app(Config) when is_list(Config) -> {remove,{kalle,brutal_purge,brutal_purge}}, {purge,[pelle,kalle]}, {apply,{application,unload,[pelle]}}] = X3, + + %% Simple translation (4) + Up4 = [{restart_application, test}], + {ok, X4} = systools_rc:translate_scripts([Up4], Apps, PreApps), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {apply,{application,stop,[test]}}, + {remove,{foo,brutal_purge,brutal_purge}}, + {remove,{bar,brutal_purge,brutal_purge}}, + {remove,{baz,brutal_purge,brutal_purge}}, + {purge,[foo,bar,baz]}, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,permanent]}}] = X4, + + %% Translate restart_application with different restart types + %% permanent + {ok, X4_1} = systools_rc:translate_scripts([Up4], + [Test#application{type=permanent}], + [Test]), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {apply,{application,stop,[test]}}, + {remove,{foo,brutal_purge,brutal_purge}}, + {remove,{bar,brutal_purge,brutal_purge}}, + {remove,{baz,brutal_purge,brutal_purge}}, + {purge,[foo,bar,baz]}, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,permanent]}}] = X4_1, + + %% transient + {ok, X4_2} = systools_rc:translate_scripts([Up4], + [Test#application{type=transient}], + [Test]), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {apply,{application,stop,[test]}}, + {remove,{foo,brutal_purge,brutal_purge}}, + {remove,{bar,brutal_purge,brutal_purge}}, + {remove,{baz,brutal_purge,brutal_purge}}, + {purge,[foo,bar,baz]}, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,transient]}}] = X4_2, + + %% temporary + {ok, X4_3} = systools_rc:translate_scripts([Up4], + [Test#application{type=temporary}], + [Test]), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {apply,{application,stop,[test]}}, + {remove,{foo,brutal_purge,brutal_purge}}, + {remove,{bar,brutal_purge,brutal_purge}}, + {remove,{baz,brutal_purge,brutal_purge}}, + {purge,[foo,bar,baz]}, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,temporary]}}] = X4_3, + + %% load + {ok, X4_4} = systools_rc:translate_scripts([Up4], + [Test#application{type=load}], + [Test]), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {apply,{application,stop,[test]}}, + {remove,{foo,brutal_purge,brutal_purge}}, + {remove,{bar,brutal_purge,brutal_purge}}, + {remove,{baz,brutal_purge,brutal_purge}}, + {purge,[foo,bar,baz]}, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,load,[test]}}] = X4_4, + + %% none + {ok, X4_5} = systools_rc:translate_scripts([Up4], + [Test#application{type=none}], + [Test]), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {apply,{application,stop,[test]}}, + {remove,{foo,brutal_purge,brutal_purge}}, + {remove,{bar,brutal_purge,brutal_purge}}, + {remove,{baz,brutal_purge,brutal_purge}}, + {purge,[foo,bar,baz]}, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}] = X4_5, + ok. diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl index eeef721647..c8a4e92f24 100644 --- a/lib/sasl/test/test_lib.hrl +++ b/lib/sasl/test/test_lib.hrl @@ -1,3 +1,3 @@ -define(ertsvsn,"4.4"). --define(kernelvsn,"2.14.3"). --define(stdlibvsn,"1.17.3"). +-define(kernelvsn,"2.16.4"). +-define(stdlibvsn,"1.19.4"). |