diff options
Diffstat (limited to 'lib/sasl/test')
-rw-r--r-- | lib/sasl/test/installer.erl | 15 | ||||
-rw-r--r-- | lib/sasl/test/rb_SUITE.erl | 32 | ||||
-rw-r--r-- | lib/sasl/test/release_handler_SUITE.erl | 249 | ||||
-rwxr-xr-x | lib/sasl/test/release_handler_SUITE_data/start | 2 | ||||
-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 | 48 | ||||
-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 |
10 files changed, 524 insertions, 219 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/rb_SUITE.erl b/lib/sasl/test/rb_SUITE.erl index b0e43be3a2..453f992850 100644 --- a/lib/sasl/test/rb_SUITE.erl +++ b/lib/sasl/test/rb_SUITE.erl @@ -362,18 +362,48 @@ start_stop_log(Config) -> StdioResult = [_|_] = capture(fun() -> rb:show(1) end), {ok,<<>>} = file:read_file(OutFile), - %% Start log and check that show is printed to log and not to standad_io + %% Start log and check that show is printed to log and not to standard_io ok = rb:start_log(OutFile), [] = capture(fun() -> rb:show(1) end), {ok,Bin} = file:read_file(OutFile), true = (Bin =/= <<>>), + %% Start log with atom standard_io and check that show is printed to standard_io + ok = rb:stop_log(), + ok = file:write_file(OutFile,[]), + ok = rb:start_log(standard_io), + StdioResult = [_|_] = capture(fun() -> rb:show(1) end), + {ok,<<>>} = file:read_file(OutFile), + + %% Start log and check that show is printed to iodevice log and not to standard_io + ok = rb:stop_log(), + ok = file:write_file(OutFile,[]), + {ok, IoOutFile} = file:open(OutFile,[write]), + ok = rb:start_log(IoOutFile), + [] = capture(fun() -> rb:show(1) end), + {ok,Bin} = file:read_file(OutFile), + true = (Bin =/= <<>>), + ok = file:close(IoOutFile), + %% Stop log and check that show is printed to standard_io and not to log ok = rb:stop_log(), ok = file:write_file(OutFile,[]), StdioResult = capture(fun() -> rb:show(1) end), {ok,<<>>} = file:read_file(OutFile), + %% Start log and check that list is printed to log and not to standard_io + ok = file:write_file(OutFile,[]), + ok = rb:start_log(OutFile), + [] = capture(fun() -> rb:log_list() end), + {ok,Bin2} = file:read_file(OutFile), + true = (Bin2 =/= <<>>), + + %% Stop log and check that list is printed to standard_io and not to log + ok = rb:stop_log(), + ok = file:write_file(OutFile,[]), + StdioResult2 = capture(fun() -> rb:log_list() end), + {ok,<<>>} = file:read_file(OutFile), + %% Test that standard_io is used if log file can not be opened ok = rb:start_log(filename:join(nonexistingdir,"newfile.txt")), StdioResult = capture(fun() -> rb:show(1) end), diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index a56924d5ca..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()]. @@ -64,7 +65,7 @@ cases() -> supervisor_which_children_timeout, release_handler_which_releases, install_release_syntax_check, upgrade_supervisor, upgrade_supervisor_fail, otp_9864, - otp_10463_upgrade_script_regexp]. + otp_10463_upgrade_script_regexp, no_dot_erlang]. groups() -> [{release,[], @@ -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. @@ -1709,6 +1780,46 @@ otp_10463_upgrade_script_regexp(_Config) -> release_handler:upgrade_script(kernel,code:lib_dir(kernel)), ok. +no_dot_erlang(Conf) -> + PrivDir = ?config(data_dir,Conf), + {ok, OrigWd} = file:get_cwd(), + try + ok = file:set_cwd(PrivDir), + + {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">>), + + CMD1 = Quote ++ Erl ++ Quote ++ Args , + case os:cmd(CMD1) of + "DOT_ERLANG_READ" ++ _ -> ok; + Other1 -> + io:format("Failed: ~ts~n",[CMD1]), + io:format("Expected: ~s ++ _~n",["DOT_ERLANG_READ "]), + io:format("Got: ~ts~n",[Other1]), + exit({failed_to_start, test_error}) + end, + NO_DOT_ERL = " -boot no_dot_erlang", + 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: ~ts~n",[Other2]), + exit({failed_to_start, no_dot_erlang}) + end + after + _ = file:delete(".erlang"), + ok = file:set_cwd(OrigWd), + ok + end. + %%%================================================================= %%% Misceleaneous functions @@ -1852,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), @@ -1891,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). @@ -2012,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). @@ -2052,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). @@ -2087,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); @@ -2118,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 -> @@ -2511,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", @@ -2676,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/release_handler_SUITE_data/start b/lib/sasl/test/release_handler_SUITE_data/start index 45e526c15f..87275045b1 100755 --- a/lib/sasl/test/release_handler_SUITE_data/start +++ b/lib/sasl/test/release_handler_SUITE_data/start @@ -26,4 +26,4 @@ export HW_WD_DISABLE HEART_COMMAND START_ERL_DATA=${1:-$RELDIR/start_erl.data} -$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME" > $ROOTDIR/log/run_erl.out 2>&1 & +$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME -mode embedded" > $ROOTDIR/log/run_erl.out 2>&1 & 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 367cab1d77..e3f6933476 100644 --- a/lib/sasl/test/systools_SUITE.erl +++ b/lib/sasl/test/systools_SUITE.erl @@ -43,6 +43,7 @@ -export([script_options/1, normal_script/1, unicode_script/1, unicode_script/2, no_mod_vsn_script/1, wildcard_script/1, variable_script/1, no_sasl_script/1, + no_dot_erlang_script/1, 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, @@ -59,6 +60,7 @@ -export([otp_6226_outdir/1]). -export([init_per_suite/1, end_per_suite/1, init_per_testcase/2, end_per_testcase/2]). +-export([delete_tree/1]). -import(lists, [foldl/3]). @@ -78,7 +80,8 @@ groups() -> [{script, [], [script_options, normal_script, unicode_script, no_mod_vsn_script, wildcard_script, variable_script, abnormal_script, - no_sasl_script, src_tests_script, crazy_script, + no_sasl_script, no_dot_erlang_script, + src_tests_script, crazy_script, included_script, included_override_script, included_fail_script, included_bug_script, exref_script, otp_3065_circular_dependenies, included_and_used_sort_script]}, @@ -137,9 +140,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 @@ -299,6 +302,11 @@ unicode_script(Config) when is_list(Config) -> %% 3. path (directory name where unicode_app.tgz is extracted) true = lists:member({path,[P1]},Instr), + %% If all is good, delete the unicode dir to avoid lingering files + %% on windows. + rpc:call(Node,code,add_pathz,[filename:dirname(code:which(?MODULE))]), + rpc:call(Node,?MODULE,delete_tree,[UnicodeLibDir]), + ok. unicode_script(cleanup,Config) -> @@ -451,6 +459,34 @@ no_sasl_script(Config) when is_list(Config) -> ok = file:set_cwd(OldDir), ok. +%% make_script: Create script with no_dot_erlang. Check script contents. +no_dot_erlang_script(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), + + {LatestDir, LatestName} = create_script(latest1_no_sasl,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(LatestDir), + + {ok, _ , []} = + systools:make_script(LatestName,[{path, P},silent, no_warn_sasl]), + {ok, [{_, _, LoadDotErlang}]} = read_script_file(LatestName), + [erlangrc] = [E || {apply, {c, E, []}} <- LoadDotErlang], + + {ok, _ , []} = + systools:make_script(LatestName,[{path, P},silent, no_warn_sasl, no_dot_erlang]), + {ok, [{_, _, DoNotLoadDotErlang}]} = read_script_file(LatestName), + [] = [E || {apply, {c, E, []}} <- DoNotLoadDotErlang], + + ok = file:set_cwd(OldDir), + ok. + %% make_script: Do not check date of object file or that source code %% can be found. @@ -1924,12 +1960,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]), 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"). |