aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/etc/win32/Install.c5
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl92
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl37
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl21
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl10
-rw-r--r--lib/odbc/test/odbc_test.hrl7
-rw-r--r--lib/odbc/test/odbc_test_lib.erl21
-rw-r--r--lib/parsetools/src/leex.erl97
-rw-r--r--lib/sasl/src/erlsrv.erl31
-rw-r--r--lib/sasl/src/release_handler.erl151
-rw-r--r--lib/sasl/test/Makefile3
-rw-r--r--lib/sasl/test/installer.erl80
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl283
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/clients/start_cli138
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/erl.ini.src4
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/heart_restart.bat3
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app2
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/start_client (renamed from lib/sasl/test/release_handler_SUITE_data/clients/start_cli2)2
-rw-r--r--lib/sasl/test/rh_test_lib.erl100
-rw-r--r--lib/stdlib/src/erl_tar.erl30
20 files changed, 663 insertions, 354 deletions
diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c
index 6e60512f6d..d680b67dd6 100644
--- a/erts/etc/win32/Install.c
+++ b/erts/etc/win32/Install.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2003-2011. 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
@@ -213,6 +213,9 @@ int main(int argc, char **argv)
fprintf(stderr,"Cannot continue installation, bailing out.\n");
exit(1);
}
+
+ /* OBS!!! If the format of the init file is changed, do not forget
+ to update release_handler:write_ini_file(...) */
ini_file = create_init_file();
ini_section = create_init_section("erlang");
add_init_section(ini_file,ini_section);
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 6eaf3a81c4..e59be772e3 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -80,7 +80,7 @@ init_per_suite(Config) ->
case (catch odbc:start()) of
ok ->
case catch odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]) of
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()) of
{ok, Ref} ->
odbc:disconnect(Ref),
[{tableName, odbc_test_lib:unique_table_name()} | Config];
@@ -116,12 +116,6 @@ init_per_testcase(_TestCase, Config) ->
Dog = test_server:timetrap(?default_timeout),
Temp = lists:keydelete(connection_ref, 1, Config),
NewConfig = lists:keydelete(watchdog, 1, Temp),
- %% Clean up if needed
- Table = ?config(tableName, Config),
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
- Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
- io:format("Drop table: ~p ~p~n", [Table, Result]),
- odbc:disconnect(Ref),
[{watchdog, Dog} | NewConfig].
%%--------------------------------------------------------------------
@@ -133,6 +127,11 @@ init_per_testcase(_TestCase, Config) ->
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
end_per_testcase(_TestCase, Config) ->
+ Table = ?config(tableName, Config),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
+ Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+ io:format("Drop table: ~p ~p~n", [Table, Result]),
+ odbc:disconnect(Ref),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
@@ -144,7 +143,7 @@ commit(doc)->
commit(suite) -> [];
commit(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
@@ -184,8 +183,11 @@ rollback(doc)->
["Test the use of explicit rollback"];
rollback(suite) -> [];
rollback(Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), [{auto_commit, off}]),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
+
Table = ?config(tableName, Config),
+
TransStr = transaction_support_str(?RDBMS),
{updated, _} =
@@ -222,7 +224,8 @@ not_explicit_commit(doc) ->
not_explicit_commit(suite) -> [];
not_explicit_commit(_Config) ->
{ok, Ref} =
- odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}]),
+ odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}] ++
+ odbc_test_lib:platform_options()),
{error, _} = odbc:commit(Ref, commit),
ok = odbc:disconnect(Ref).
@@ -231,7 +234,8 @@ not_exist_db(doc) ->
["Tests valid data format but invalid data in the connection parameters."];
not_exist_db(suite) -> [];
not_exist_db(_Config) ->
- {error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar", []),
+ {error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar",
+ odbc_test_lib:platform_options()),
%% So that the odbc control server can be stoped "in the correct way"
test_server:sleep(100).
@@ -248,7 +252,8 @@ no_c_node(_Config) ->
FileName2 = filename:nativename(filename:join(Dir, "odbcsrv")),
ok = file:rename(FileName1, FileName2),
Result =
- case catch odbc:connect(?RDBMS:connection_string(), []) of
+ case catch odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()) of
{error, port_program_executable_not_found} ->
ok;
Else ->
@@ -263,7 +268,7 @@ port_dies(doc) ->
"Tests what happens if the port program dies";
port_dies(suite) -> [];
port_dies(_Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
{status, _} = process_info(Ref, status),
process_flag(trap_exit, true),
Port = lists:last(erlang:ports()),
@@ -279,7 +284,7 @@ control_process_dies(doc) ->
"Tests what happens if the Erlang control process dies";
control_process_dies(suite) -> [];
control_process_dies(_Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
process_flag(trap_exit, true),
Port = lists:last(erlang:ports()),
{connected, Ref} = erlang:port_info(Port, connected),
@@ -312,7 +317,7 @@ client_dies_normal(Config) when is_list(Config) ->
end.
client_normal(Pid) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Pid ! {dbRef, Ref},
receive
continue ->
@@ -344,7 +349,7 @@ client_dies_timeout(Config) when is_list(Config) ->
end.
client_timeout(Pid) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Pid ! {dbRef, Ref},
receive
continue ->
@@ -376,7 +381,7 @@ client_dies_error(Config) when is_list(Config) ->
end.
client_error(Pid) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Pid ! {dbRef, Ref},
receive
continue ->
@@ -391,7 +396,8 @@ connect_timeout(doc) ->
connect_timeout(suite) -> [];
connect_timeout(Config) when is_list(Config) ->
{'EXIT',timeout} = (catch odbc:connect(?RDBMS:connection_string(),
- [{timeout, 0}])),
+ [{timeout, 0}] ++
+ odbc_test_lib:platform_options())),
%% Need to return ok here "{'EXIT',timeout} return value" will
%% be interpreted as that the testcase has timed out.
ok.
@@ -448,7 +454,7 @@ timeout(Config) when is_list(Config) ->
update_table_timeout(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
@@ -486,7 +492,7 @@ many_timeouts(doc) ->
many_timeouts(suite) -> [];
many_timeouts(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
@@ -520,7 +526,7 @@ many_timeouts(Config) when is_list(Config) ->
update_table_many_timeouts(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
ok = loop_many_timouts(Ref, UpdateQuery, TimeOut),
@@ -546,7 +552,7 @@ timeout_reset(doc) ->
timeout_reset(suite) -> [];
timeout_reset(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
@@ -594,7 +600,7 @@ timeout_reset(Config) when is_list(Config) ->
update_table_timeout_reset(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
ok = loop_timout_reset(Ref, UpdateQuery, TimeOut,
@@ -644,7 +650,7 @@ disconnect_on_timeout(suite) -> [];
disconnect_on_timeout(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
@@ -675,7 +681,7 @@ disconnect_on_timeout(Config) when is_list(Config) ->
update_table_disconnect_on_timeout(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
@@ -692,7 +698,7 @@ connection_closed(doc) ->
" use a connection that has been closed"];
connection_closed(suite) -> [];
connection_closed(Config) when is_list(Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
{updated, _} =
@@ -758,7 +764,7 @@ return_rows_as_lists(doc)->
return_rows_as_lists(suite) -> [];
return_rows_as_lists(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{tuple_row, off}]),
+ [{tuple_row, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
@@ -779,15 +785,21 @@ return_rows_as_lists(Config) when is_list(Config) ->
{ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
- First = ?RDBMS:first_list_rows(),
- Last = ?RDBMS:last_list_rows(),
- Prev = ?RDBMS:prev_list_rows(),
- Next = ?RDBMS:next_list_rows(),
-
- Last = odbc:last(Ref),
- Prev = odbc:prev(Ref),
- First = odbc:first(Ref),
- Next = odbc:next(Ref).
+ case proplists:get_value(scrollable_cursors, odbc_test_lib:platform_options()) of
+ off ->
+ Next = ?RDBMS:next_list_rows(),
+ Next = odbc:next(Ref);
+ _ ->
+ First = ?RDBMS:first_list_rows(),
+ Last = ?RDBMS:last_list_rows(),
+ Prev = ?RDBMS:prev_list_rows(),
+ Next = ?RDBMS:next_list_rows(),
+
+ Last = odbc:last(Ref),
+ Prev = odbc:prev(Ref),
+ First = odbc:first(Ref),
+ Next = odbc:next(Ref)
+ end.
%%-------------------------------------------------------------------------
@@ -796,19 +808,21 @@ api_missuse(doc)->
api_missuse(suite) -> [];
api_missuse(Config) when is_list(Config)->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
%% Serious programming fault, connetion will be shut down
gen_server:call(Ref, {self(), foobar, 10}, infinity),
test_server:sleep(10),
undefined = process_info(Ref, status),
- {ok, Ref2} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref2} = odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()),
%% Serious programming fault, connetion will be shut down
gen_server:cast(Ref2, {self(), foobar, 10}),
test_server:sleep(10),
undefined = process_info(Ref2, status),
- {ok, Ref3} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref3} = odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()),
%% Could be an innocent misstake the connection lives.
Ref3 ! foobar,
test_server:sleep(10),
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
index 3585446ec8..84c99e183b 100644
--- a/lib/odbc/test/odbc_data_type_SUITE.erl
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -167,31 +167,17 @@ init_per_testcase(param_insert_tiny_int = Case, Config) ->
init_per_testcase(Case, Config) ->
common_init_per_testcase(Case, Config).
-is_supported_tinyint(sqlserver) ->
- true;
-is_supported_tinyint(_) ->
- false.
-
-is_supported_bit(sqlserver) ->
- true;
-is_supported_bit(_) ->
- false.
-
-is_fixed_upper_limit(mysql) ->
- false;
-is_fixed_upper_limit(_) ->
- true.
-
common_init_per_testcase(Case, Config) ->
+ PlatformOptions = odbc_test_lib:platform_options(),
case atom_to_list(Case) of
"binary" ++ _ ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{binary_strings, on}]);
+ [{binary_strings, on}] ++ PlatformOptions);
"unicode" ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{binary_strings, on}]);
+ [{binary_strings, on}] ++ PlatformOptions);
_ ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), [])
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), PlatformOptions)
end,
odbc_test_lib:strict(Ref, ?RDBMS),
Dog = test_server:timetrap(?default_timeout),
@@ -199,6 +185,19 @@ common_init_per_testcase(Case, Config) ->
NewConfig = lists:keydelete(watchdog, 1, Temp),
[{watchdog, Dog}, {connection_ref, Ref} | NewConfig].
+is_fixed_upper_limit(mysql) ->
+ false;
+is_fixed_upper_limit(_) ->
+ true.
+is_supported_tinyint(sqlserver) ->
+ true;
+is_supported_tinyint(_) ->
+ false.
+is_supported_bit(sqlserver) ->
+ true;
+is_supported_bit(_) ->
+ false.
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
%% Case - atom()
@@ -212,7 +211,7 @@ end_per_testcase(_TestCase, Config) ->
ok = odbc:disconnect(Ref),
%% Clean up if needed
Table = ?config(tableName, Config),
- {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
odbc:disconnect(NewRef),
Dog = ?config(watchdog, Config),
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
index 6dee588076..76a214d553 100644
--- a/lib/odbc/test/odbc_query_SUITE.erl
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
case odbc_test_lib:odbc_check() of
ok ->
- [sql_query, first, last, next, prev, select_count,
+ [sql_query, next, {group, scrollable_cursors}, select_count,
select_next, select_relative, select_absolute,
create_table_twice, delete_table_twice, duplicate_key,
not_connection_owner, no_result_set, query_error,
@@ -55,8 +55,9 @@ all() ->
groups() ->
[{multiple_result_sets, [], [multiple_select_result_sets,
- multiple_mix_result_sets,
- multiple_result_sets_error]},
+ multiple_mix_result_sets,
+ multiple_result_sets_error]},
+ {scrollable_cursors, [], [first, last, prev]},
{parameterized_queries, [],
[{group, param_integers}, param_insert_decimal,
param_insert_numeric, {group, param_insert_string},
@@ -81,8 +82,16 @@ init_per_group(multiple_result_sets, Config) ->
false ->
{skip, "Not supported by " ++ atom_to_list(?RDBMS) ++ "driver"}
end;
-init_per_group(_, Config) ->
+init_per_group(scrollable_cursors, Config) ->
+ case proplists:get_value(scrollable_cursors, odbc_test_lib:platform_options()) of
+ off ->
+ {skip, "Not supported by driver"};
+ _ ->
+ Config
+ end;
+init_per_group(_,Config) ->
Config.
+
end_per_group(_GroupName, Config) ->
Config.
@@ -126,7 +135,7 @@ end_per_suite(_Config) ->
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_testcase(_Case, Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc_test_lib:strict(Ref, ?RDBMS),
Dog = test_server:timetrap(?default_timeout),
Temp = lists:keydelete(connection_ref, 1, Config),
@@ -146,7 +155,7 @@ end_per_testcase(_Case, Config) ->
ok = odbc:disconnect(Ref),
%% Clean up if needed
Table = ?config(tableName, Config),
- {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
odbc:disconnect(NewRef),
Dog = ?config(watchdog, Config),
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
index 65b990133f..440c0ca921 100644
--- a/lib/odbc/test/odbc_start_SUITE.erl
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -125,14 +125,16 @@ start(doc) ->
start(suite) ->
[];
start(Config) when is_list(Config) ->
- {error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(), []),
+ PlatformOptions = odbc_test_lib:platform_options(),
+ {error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(),
+ PlatformOptions),
odbc:start(),
- case odbc:connect(?RDBMS:connection_string(), []) of
+ case odbc:connect(?RDBMS:connection_string(), PlatformOptions) of
{ok, Ref0} ->
ok = odbc:disconnect(Ref0),
odbc:stop(),
{error,odbc_not_started} =
- odbc:connect(?RDBMS:connection_string(), []),
+ odbc:connect(?RDBMS:connection_string(), PlatformOptions),
start_odbc(transient),
start_odbc(permanent);
{error, odbc_not_started} ->
@@ -144,7 +146,7 @@ start(Config) when is_list(Config) ->
start_odbc(Type) ->
ok = odbc:start(Type),
- case odbc:connect(?RDBMS:connection_string(), []) of
+ case odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()) of
{ok, Ref} ->
ok = odbc:disconnect(Ref),
odbc:stop();
diff --git a/lib/odbc/test/odbc_test.hrl b/lib/odbc/test/odbc_test.hrl
index 7d2522d667..397d04756b 100644
--- a/lib/odbc/test/odbc_test.hrl
+++ b/lib/odbc/test/odbc_test.hrl
@@ -27,7 +27,12 @@
{unix, sunos} ->
postgres;
{unix,linux} ->
- mysql;
+ case erlang:system_info(wordsize) of
+ 4 ->
+ mysql;
+ _ ->
+ postgres
+ end;
{win32, _} ->
sqlserver
end).
diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl
index 9956d74d24..3e78105cf3 100644
--- a/lib/odbc/test/odbc_test_lib.erl
+++ b/lib/odbc/test/odbc_test_lib.erl
@@ -38,18 +38,7 @@ match_float(Float, Match, Delta) ->
odbc_check() ->
case erlang:system_info(wordsize) of
4 ->
- case test_server:os_type() of
- {unix, sunos} ->
- ok;
- {unix, linux} ->
- ok;
- {win32, _} ->
- ok;
- Other ->
- lists:flatten(
- io_lib:format("Platform not supported: ~w",
- [Other]))
- end;
+ ok;
Other ->
case os:type() of
{unix, linux} ->
@@ -80,3 +69,11 @@ strict(Ref, mysql) ->
odbc:sql_query(Ref, "SET sql_mode='STRICT_ALL_TABLES,STRICT_TRANS_TABLES';");
strict(_,_) ->
ok.
+
+platform_options() ->
+ case os:type() of
+ {unix, sunos} ->
+ [{scrollable_cursors, off}];
+ _ ->
+ []
+ end.
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index e49032ebe4..942e9928b1 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -35,7 +35,7 @@
-export([compile/3,file/1,file/2,format_error/1]).
-import(lists, [member/2,reverse/1,sort/1,delete/2,
- keysort/2,keydelete/3,keyfind/3,
+ keysort/2,keydelete/3,
map/2,foldl/3,foreach/2,flatmap/2]).
-import(string, [substr/2,substr/3,span/2]).
-import(ordsets, [is_element/2,add_element/2,union/2]).
@@ -58,7 +58,7 @@
gfile=[], % Graph file
module, % Module name
opts=[], % Options
- posix=false, % POSIX regular expressions
+ % posix=false, % POSIX regular expressions
errors=[],
warnings=[]
}).
@@ -136,8 +136,8 @@ format_error({regexp,E})->
"unterminated " ++ Cs;
{illegal_char,Cs} ->
"illegal character " ++ Cs;
- {posix_cc,What} ->
- ["illegal POSIX character class ",io_lib:write_string(What)];
+%% {posix_cc,What} ->
+%% ["illegal POSIX character class ",io_lib:write_string(What)];
{char_class,What} ->
["illegal character class ",io_lib:write_string(What)]
end,
@@ -314,6 +314,7 @@ report_warnings(St) ->
end, sort(St#leex.warnings))
end, report_warnings, St#leex.opts).
+-spec add_error(_, #leex{}) -> no_return().
add_error(E, St) ->
add_error(St#leex.xfile, E, St).
@@ -662,14 +663,14 @@ re_repeat1([$*|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {kclosure,S}, St);
re_repeat1([$+|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {pclosure,S}, St);
re_repeat1([$?|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {optional,S}, St);
%% { only starts interval when ere is true, otherwise normal character.
-re_repeat1([${|Cs0], Sn, S, #leex{posix=true}=St) -> % $}
- case re_interval_range(Cs0) of
- {Min,Max,[$}|Cs1]} when is_integer(Min), is_integer(Max), Min =< Max ->
- re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
- {Min,Max,[$}|Cs1]} when is_integer(Min), is_atom(Max) ->
- re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
- {_,_,Cs1} -> parse_error({interval_range,string_between([${|Cs0], Cs1)})
- end;
+%% re_repeat1([${|Cs0], Sn, S, #leex{posix=true}=St) -> % $}
+%% case re_interval_range(Cs0) of
+%% {Min,Max,[$}|Cs1]} when is_integer(Min), is_integer(Max), Min =< Max ->
+%% re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
+%% {Min,Max,[$}|Cs1]} when is_integer(Min), is_atom(Max) ->
+%% re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
+%% {_,_,Cs1} -> parse_error({interval_range,string_between([${|Cs0], Cs1)})
+%% end;
re_repeat1(Cs, Sn, S, _) -> {S,Sn,Cs}.
%% re_single(Chars, SubNumber, State) -> {RegExp,SubNumber,Chars}.
@@ -751,7 +752,7 @@ special_char($|, _) -> true;
special_char($*, _) -> true;
special_char($+, _) -> true;
special_char($?, _) -> true;
-special_char(${, #leex{posix=true}) -> true; % Only when POSIX set
+%% special_char(${, #leex{posix=true}) -> true; % Only when POSIX set
special_char($\\, _) -> true;
special_char(_, _) -> false.
@@ -762,12 +763,12 @@ re_char_class([$]|Cs], St) -> % Must special case this.
re_char_class(Cs, [$]], St);
re_char_class(Cs, St) -> re_char_class(Cs, [], St).
-re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
- %% POSIX char class only.
- case posix_cc(Cs0) of
- {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
- {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
- end;
+%% re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
+%% %% POSIX char class only.
+%% case posix_cc(Cs0) of
+%% {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
+%% {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
+%% end;
re_char_class([C1|Cs0], Cc, St) when C1 =/= $] ->
case re_char(C1, Cs0) of
{Cf,[$-,C2|Cs1]} when C2 =/= $] ->
@@ -784,19 +785,19 @@ re_char_class(Cs, Cc, _) -> {reverse(Cc),Cs}. % Preserve order
%% posix_cc(String) -> {PosixClass,RestString}.
%% Handle POSIX character classes.
-posix_cc("alnum" ++ Cs) -> {alnum,Cs};
-posix_cc("alpha" ++ Cs) -> {alpha,Cs};
-posix_cc("blank" ++ Cs) -> {blank,Cs};
-posix_cc("cntrl" ++ Cs) -> {cntrl,Cs};
-posix_cc("digit" ++ Cs) -> {digit,Cs};
-posix_cc("graph" ++ Cs) -> {graph,Cs};
-posix_cc("lower" ++ Cs) -> {lower,Cs};
-posix_cc("print" ++ Cs) -> {print,Cs};
-posix_cc("punct" ++ Cs) -> {punct,Cs};
-posix_cc("space" ++ Cs) -> {space,Cs};
-posix_cc("upper" ++ Cs) -> {upper,Cs};
-posix_cc("xdigit" ++ Cs) -> {xdigit,Cs};
-posix_cc(Cs) -> parse_error({posix_cc,substr(Cs, 1, 5)}).
+%% posix_cc("alnum" ++ Cs) -> {alnum,Cs};
+%% posix_cc("alpha" ++ Cs) -> {alpha,Cs};
+%% posix_cc("blank" ++ Cs) -> {blank,Cs};
+%% posix_cc("cntrl" ++ Cs) -> {cntrl,Cs};
+%% posix_cc("digit" ++ Cs) -> {digit,Cs};
+%% posix_cc("graph" ++ Cs) -> {graph,Cs};
+%% posix_cc("lower" ++ Cs) -> {lower,Cs};
+%% posix_cc("print" ++ Cs) -> {print,Cs};
+%% posix_cc("punct" ++ Cs) -> {punct,Cs};
+%% posix_cc("space" ++ Cs) -> {space,Cs};
+%% posix_cc("upper" ++ Cs) -> {upper,Cs};
+%% posix_cc("xdigit" ++ Cs) -> {xdigit,Cs};
+%% posix_cc(Cs) -> parse_error({posix_cc,substr(Cs, 1, 5)}).
escape_char($n) -> $\n; % \n = LF
escape_char($r) -> $\r; % \r = CR
@@ -815,24 +816,24 @@ escape_char(C) -> C. % Pass it straight through
%% Int, -> Int,any
%% Int1,Int2 -> Int1,Int2
-re_interval_range(Cs0) ->
- case re_number(Cs0) of
- {none,Cs1} -> {none,none,Cs1};
- {N,[$,|Cs1]} ->
- case re_number(Cs1) of
- {none,Cs2} -> {N,any,Cs2};
- {M,Cs2} -> {N,M,Cs2}
- end;
- {N,Cs1} -> {N,none,Cs1}
- end.
+%% re_interval_range(Cs0) ->
+%% case re_number(Cs0) of
+%% {none,Cs1} -> {none,none,Cs1};
+%% {N,[$,|Cs1]} ->
+%% case re_number(Cs1) of
+%% {none,Cs2} -> {N,any,Cs2};
+%% {M,Cs2} -> {N,M,Cs2}
+%% end;
+%% {N,Cs1} -> {N,none,Cs1}
+%% end.
-re_number([C|Cs]) when C >= $0, C =< $9 ->
- re_number(Cs, C - $0);
-re_number(Cs) -> {none,Cs}.
+%% re_number([C|Cs]) when C >= $0, C =< $9 ->
+%% re_number(Cs, C - $0);
+%% re_number(Cs) -> {none,Cs}.
-re_number([C|Cs], Acc) when C >= $0, C =< $9 ->
- re_number(Cs, 10*Acc + (C - $0));
-re_number(Cs, Acc) -> {Acc,Cs}.
+%% re_number([C|Cs], Acc) when C >= $0, C =< $9 ->
+%% re_number(Cs, 10*Acc + (C - $0));
+%% re_number(Cs, Acc) -> {Acc,Cs}.
string_between(Cs1, Cs2) ->
substr(Cs1, 1, length(Cs1)-length(Cs2)).
diff --git a/lib/sasl/src/erlsrv.erl b/lib/sasl/src/erlsrv.erl
index f9804c41dc..086dc7c651 100644
--- a/lib/sasl/src/erlsrv.erl
+++ b/lib/sasl/src/erlsrv.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. 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
@@ -75,14 +75,21 @@ write_all_data(Port,[H|T]) ->
write_all_data(Port,T).
read_all_data(Port) ->
+ lists:reverse(read_all_data(Port,[],[])).
+read_all_data(Port,Line,Lines) ->
receive
+ {Port, {data, {noeol,Data}}} ->
+ read_all_data(Port,Line++Data,Lines);
{Port, {data, {eol,Data}}} ->
- [ Data | read_all_data(Port)];
- _ ->
+ read_all_data(Port,[],[Line++Data|Lines]);
+ {Port,_Other} ->
Port ! {self(), close},
receive
{Port, closed} ->
- []
+ case Line of
+ [] -> Lines;
+ _ -> [Line|Lines]
+ end
end
end.
@@ -208,7 +215,7 @@ store_service(EmulatorVersion,Service) ->
false ->
{error, no_servicename};
{value, {_,Name}} ->
- {Action,Service1} = case get_service(Name) of
+ {Action,Service1} = case get_service(EmulatorVersion,Name) of
{error, no_such_service} ->
{"add",Service};
_ ->
@@ -377,8 +384,14 @@ pick_argument(_,[],Acc) ->
{Acc, ""};
pick_argument(normal,[$ |T],Acc) ->
{Acc,T};
+pick_argument(normal,[$\\|T],Acc) ->
+ pick_argument(normal_escaped,T,[$\\|Acc]);
pick_argument(normal,[$"|T],Acc) ->
pick_argument(quoted,T,[$"|Acc]);
+pick_argument(normal_escaped,[$"|T],Acc) ->
+ pick_argument(bquoted,T,[$"|Acc]);
+pick_argument(normal_escaped,[A|T],Acc) ->
+ pick_argument(normal,T,[A|Acc]);
pick_argument(quoted_escaped,[H|T],Acc) ->
pick_argument(quoted,T,[H|Acc]);
pick_argument(quoted,[$"|T],Acc) ->
@@ -387,6 +400,14 @@ pick_argument(quoted,[$\\|T],Acc) ->
pick_argument(quoted_escaped,T,[$\\|Acc]);
pick_argument(quoted,[H|T],Acc) ->
pick_argument(quoted,T,[H|Acc]);
+pick_argument(bquoted_escaped,[$"|T],Acc) ->
+ pick_argument(normal,T,[$"|Acc]);
+pick_argument(bquoted_escaped,[H|T],Acc) ->
+ pick_argument(bquoted,T,[H|Acc]);
+pick_argument(bquoted,[$\\|T],Acc) ->
+ pick_argument(bquoted_escaped,T,[$\\|Acc]);
+pick_argument(bquoted,[H|T],Acc) ->
+ pick_argument(bquoted,T,[H|Acc]);
pick_argument(normal,[H|T],Acc) ->
pick_argument(normal,T,[H|Acc]).
diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl
index b60aa847df..eb29787103 100644
--- a/lib/sasl/src/release_handler.erl
+++ b/lib/sasl/src/release_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -890,6 +890,7 @@ do_check_install_release(RelDir, Vsn, Releases, Masters) ->
end.
do_install_release(#state{start_prg = StartPrg,
+ root = RootDir,
rel_dir = RelDir, releases = Releases,
masters = Masters,
static_emulator = Static},
@@ -926,8 +927,8 @@ do_install_release(#state{start_prg = StartPrg,
NReleases = set_status(Vsn, current, Releases),
NReleases2 = set_status(Vsn,tmp_current,NReleases),
write_releases(RelDir, NReleases2, Masters),
- prepare_restart_new_emulator(StartPrg, RelDir,
- Release,
+ prepare_restart_new_emulator(StartPrg, RootDir,
+ RelDir, Release,
PermanentRelease,
Masters),
{restart_new_emulator, CurrentVsn, Descr};
@@ -997,7 +998,7 @@ do_make_services_permanent(PermanentVsn,Vsn, PermanentEVsn, EVsn) ->
throw(Error4)
end
end.
-
+
do_make_permanent(#state{releases = Releases,
rel_dir = RelDir, unpurged = Unpurged,
masters = Masters,
@@ -1409,8 +1410,8 @@ prepare_restart_nt(#release{erts_vsn = EVsn, vsn = Vsn},
FutureServiceName = hd(string:tokens(atom_to_list(node()),"@"))
++ "_" ++ Vsn,
CurrentService = case erlsrv:get_service(PermEVsn,CurrentServiceName) of
- {error, Reason} ->
- throw({error, Reason});
+ {error, _} = Error1 ->
+ throw(Error1);
CS ->
CS
end,
@@ -1425,37 +1426,33 @@ prepare_restart_nt(#release{erts_vsn = EVsn, vsn = Vsn},
CurrentServiceName),
case erlsrv:store_service(EVsn, FutureService) of
- {error, Rison} ->
- throw({error,Rison});
- _ ->
+ {error, _} = Error2 ->
+ throw(Error2);
+ _X ->
erlsrv:disable_service(EVsn, FutureServiceName),
ErlSrv = filename:nativename(erlsrv:erlsrv(EVsn)),
- case heart:set_cmd(ErlSrv ++ " enable " ++ FutureServiceName ++
- " & " ++ ErlSrv ++ " start " ++
- FutureServiceName ++
- " & " ++ ErlSrv ++ " disable " ++
- FutureServiceName) of
+ StartDisabled = ErlSrv ++ " start_disabled " ++ FutureServiceName,
+ case heart:set_cmd(StartDisabled) of
ok ->
ok;
- Error ->
- throw({error, {'heart:set_cmd() error', Error}})
+ Error3 ->
+ throw({error, {'heart:set_cmd() error', Error3}})
end
end.
-
%%-----------------------------------------------------------------
%% Set things up for restarting the new emulator. The actual
%% restart is performed by calling init:reboot() higher up.
%%-----------------------------------------------------------------
-prepare_restart_new_emulator(StartPrg, RelDir,
- Release, PRelease,
- Masters) ->
+prepare_restart_new_emulator(StartPrg, RootDir, RelDir,
+ Release, PRelease, Masters) ->
#release{erts_vsn = EVsn, vsn = Vsn} = Release,
Data = EVsn ++ " " ++ Vsn,
DataFile = write_new_start_erl(Data, RelDir, Masters),
%% Tell heart to use DataFile instead of start_erl.data
case os:type() of
{win32,nt} ->
+ write_ini_file(RootDir,EVsn,Masters),
prepare_restart_nt(Release,PRelease,DataFile);
{unix,_} ->
StartP = check_start_prg(StartPrg, Masters),
@@ -1832,50 +1829,10 @@ write_start(File, Data, false) ->
end;
write_start(File, Data, Masters) ->
all_masters(Masters),
- write_start_m(File, Data, Masters).
+ safe_write_file_m(File, Data, Masters).
%%-----------------------------------------------------------------
-%% Write the "start_erl.data" file at all master nodes.
-%% 1. Save "start_erl.backup" at all nodes.
-%% 2. Write the "start_erl.change" file at all nodes.
-%% 3. Move "start_erl.change" to "start_erl.data".
-%% 4. Remove "start_erl.backup" at all nodes.
-%%
-%% If one of the steps above fails, all steps is recovered from
-%% (as long as possible), except for 4 which is allowed to fail.
-%%-----------------------------------------------------------------
-write_start_m(File, Data, Masters) ->
- Dir = filename:dirname(File),
- Backup = filename:join(Dir, "start_erl.backup"),
- Change = filename:join(Dir, "start_erl.change"),
- case at_all_masters(Masters, ?MODULE, do_copy_files,
- [File, [Backup]]) of
- ok ->
- case at_all_masters(Masters, ?MODULE, do_write_file,
- [Change, Data]) of
- ok ->
- case at_all_masters(Masters, file, rename,
- [Change, File]) of
- ok ->
- remove_files(all, [Backup, Change], Masters),
- ok;
- {error, {Master, R}} ->
- takewhile(Master, Masters, file, rename,
- [Backup, File]),
- remove_files(all, [Backup, Change], Masters),
- throw({error, {Master, R, move_start_erl}})
- end;
- {error, {Master, R}} ->
- remove_files(all, [Backup, Change], Masters),
- throw({error, {Master, R, write_start_erl}})
- end;
- {error, {Master, R}} ->
- remove_files(Master, [Backup], Masters),
- throw({error, {Master, R, backup_start_erl}})
- end.
-
-%%-----------------------------------------------------------------
%% Copy the "start.boot" and "sys.config" from SrcDir to DestDir at all
%% master nodes.
%% 1. Save DestDir/"start.backup" and DestDir/"sys.backup" at all nodes.
@@ -1917,3 +1874,75 @@ set_static_files(SrcDir, DestDir, Masters) ->
remove_files(Master, [BackupBoot, BackupConf], Masters),
throw({error, {Master, R, backup_start_config}})
end.
+
+%%-----------------------------------------------------------------
+%% Write erl.ini
+%% Writes the erl.ini file used by erl.exe when (re)starting the erlang node.
+%% At first installation, this is done by Install.exe, which means that if
+%% the format of this file for some reason is changed, then Install.c must
+%% also be updated (and probably some other c-files which read erl.ini)
+%%-----------------------------------------------------------------
+write_ini_file(RootDir,EVsn,Masters) ->
+ BinDir = filename:join([RootDir,"erts-"++EVsn,"bin"]),
+ Str0 = io_lib:format("[erlang]~n"
+ "Bindir=~s~n"
+ "Progname=erl~n"
+ "Rootdir=~s~n",
+ [filename:nativename(BinDir),
+ filename:nativename(RootDir)]),
+ Str = re:replace(Str0,"\\\\","\\\\\\\\",[{return,list},global]),
+ IniFile = filename:join(BinDir,"erl.ini"),
+ do_write_ini_file(IniFile,Str,Masters).
+
+do_write_ini_file(File,Data,false) ->
+ case do_write_file(File, Data) of
+ ok -> ok;
+ Error -> throw(Error)
+ end;
+do_write_ini_file(File,Data,Masters) ->
+ all_masters(Masters),
+ safe_write_file_m(File, Data, Masters).
+
+
+%%-----------------------------------------------------------------
+%% Write the given file at all master nodes.
+%% 1. Save <File>.backup at all nodes.
+%% 2. Write <File>.change at all nodes.
+%% 3. Move <File>.change to <File>
+%% 4. Remove <File>.backup at all nodes.
+%%
+%% If one of the steps above fails, all steps are recovered from
+%% (as long as possible), except for 4 which is allowed to fail.
+%%-----------------------------------------------------------------
+safe_write_file_m(File, Data, Masters) ->
+ Backup = File ++ ".backup",
+ Change = File ++ ".change",
+ case at_all_masters(Masters, ?MODULE, do_copy_files,
+ [File, [Backup]]) of
+ ok ->
+ case at_all_masters(Masters, ?MODULE, do_write_file,
+ [Change, Data]) of
+ ok ->
+ case at_all_masters(Masters, file, rename,
+ [Change, File]) of
+ ok ->
+ remove_files(all, [Backup, Change], Masters),
+ ok;
+ {error, {Master, R}} ->
+ takewhile(Master, Masters, file, rename,
+ [Backup, File]),
+ remove_files(all, [Backup, Change], Masters),
+ throw({error, {Master, R, rename,
+ filename:basename(Change),
+ filename:basename(File)}})
+ end;
+ {error, {Master, R}} ->
+ remove_files(all, [Backup, Change], Masters),
+ throw({error, {Master, R, write, filename:basename(Change)}})
+ end;
+ {error, {Master, R}} ->
+ remove_files(Master, [Backup], Masters),
+ throw({error, {Master, R, backup,
+ filename:basename(File),
+ filename:basename(Backup)}})
+ end.
diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile
index ad08c8136b..0bdb79a06a 100644
--- a/lib/sasl/test/Makefile
+++ b/lib/sasl/test/Makefile
@@ -31,7 +31,8 @@ MODULES= \
systools_SUITE \
systools_rc_SUITE \
overload_SUITE \
- rb_SUITE
+ rb_SUITE \
+ rh_test_lib
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/sasl/test/installer.erl b/lib/sasl/test/installer.erl
index a114c4b5c9..f5ceab0dc4 100644
--- a/lib/sasl/test/installer.erl
+++ b/lib/sasl/test/installer.erl
@@ -119,6 +119,7 @@ install_3(TestNode,PrivDir) ->
?print(["install_3 unpack_release P2A ok"]),
?check_release("P2A",unpacked,["a-1.1"]),
{ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"),
+ ?print(["install_3 check_install_release P2A ok"]),
ok = release_handler:make_permanent("P1I"),
?print(["install_3 make_permanent P1I ok"]),
?check_release("P1I",permanent,["a-1.1"]),
@@ -268,23 +269,30 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) ->
erl_boot_server:start([IP]),
ok = net_kernel:monitor_nodes(true),
- Node = start_client(TestNode,ClientSname),
+ Node = start_client(TestNode,client1,ClientSname),
trace_disallowed_calls(Node),
%% Check env var for SASL on client node
SaslEnv = rpc:call(Node, application, get_all_env, [sasl]),
+ ?print([{client1_1,sasl_env},SaslEnv]),
{_,CliDir} = lists:keyfind(client_directory,1,SaslEnv),
{_,[Master]} = lists:keyfind(masters,1,SaslEnv),
{_,StartCli} = lists:keyfind(start_prg,1,SaslEnv),
- Root = code:root_dir(),
- true = (CliDir =:= filename:join([Root,"clients","type1",Node])),
- true = (StartCli =:= filename:join([CliDir,"bin","start"])),
+ NodeStr = atom_to_list(Node),
+ [NodeStr,"type1","clients"|_] = lists:reverse(filename:split(CliDir)),
true = (Master =:= node()),
+ case os:type() of
+ {unix,_} ->
+ true = (StartCli =:= filename:join([CliDir,"bin","start"]));
+ _ ->
+ ok
+ end,
%% Unpack P1H on master
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
%% Unpack and install P1H on client
+ Root = code:root_dir(),
P1HDir = filename:join([Root, "releases", "P1H"]),
%% The AppDirs argument (last arg to set_unpacked) below is really
@@ -339,6 +347,7 @@ client1_2(TestNode,PrivDir,Node) ->
?check_running_app_client(Node,a,"1.0"),
ok = rpc:call(Node, release_handler, make_permanent, ["P1H"]),
+ ?check_release_client(Node,"P1H",permanent,["a-1.0"]),
check_disallowed_calls(),
reboot(TestNode,Node),
@@ -584,7 +593,7 @@ trace_disallowed_calls(Node) ->
MasterProc = self(),
rpc:call(Node,dbg,tracer,[process,{fun(T,_) -> MasterProc ! T end,[]}]),
rpc:call(Node,dbg,p,[all,call]),
- rpc:call(Node,dbg,tp,[file,[]]).
+ rpc:call(Node,dbg,tp,[file,[{'_',[],[{message,{caller}}]}]]).
check_disallowed_calls() ->
receive
@@ -594,13 +603,12 @@ check_disallowed_calls() ->
ok
end.
-start_client(TestNode,Client) ->
- {Start, Node} = do_start_client(Client,test_host()),
- Cmd = lists:concat(["env NODENAME=",Client," ",
- filename:join(code:root_dir(), Start)]),
- ?print([{start_client,Client},Cmd]),
- Res = os:cmd(Cmd),
- ?print([{start_client,result},Res]),
+start_client(TestNode,Client,Sname) ->
+ Node = list_to_atom(lists:concat([Sname,"@",test_host()])),
+ case os:type() of
+ {unix,_} -> start_client_unix(TestNode,Sname,Node);
+ {win32,_} -> start_client_win32(TestNode,Client,Sname)
+ end,
receive
{nodeup, Node} ->
wait_started(TestNode,Node)
@@ -609,10 +617,34 @@ start_client(TestNode,Client) ->
?fail({"can not start", Node})
end.
-do_start_client(Client, Host) ->
- Node = list_to_atom(lists:concat([Client,"@",Host])),
+start_client_unix(TestNode,Sname,Node) ->
Start = filename:join(["clients", "type1", Node, "bin", "start"]),
- {Start, Node}.
+ Cmd = lists:concat(["env NODENAME=",Sname," ",
+ filename:join(code:root_dir(), Start)]),
+ ?print([{start_client,Sname},Cmd]),
+ Res = os:cmd(Cmd),
+ ?print([{start_client,result},Res]).
+
+start_client_win32(TestNode,Client,ClientSname) ->
+ Name = atom_to_list(ClientSname) ++ "_P1G",
+ RootDir = code:root_dir(),
+ ErtsBinDir = filename:join(RootDir,"erts-4.4/bin"),
+
+ {ClientArgs,RelClientDir} = rh_test_lib:get_client_args(Client,ClientSname,
+ RootDir),
+ StartErlArgs = rh_test_lib:get_start_erl_args(RootDir,RelClientDir,
+ ClientArgs),
+ ServiceArgs = rh_test_lib:get_service_args(RootDir, RelClientDir,
+ ClientSname, StartErlArgs),
+
+ ?print([{start_client,ClientSname},ServiceArgs]),
+ Erlsrv = filename:nativename(filename:join(ErtsBinDir,"erlsrv")),
+ rh_test_lib:erlsrv(Erlsrv,stop,Name),
+ rh_test_lib:erlsrv(Erlsrv,remove,Name),
+ ok = rh_test_lib:erlsrv(Erlsrv,add,Name,ServiceArgs),
+ ok = rh_test_lib:erlsrv(Erlsrv,start,Name),
+ ?print([{start_client,result},ok]),
+ ok.
reboot(TestNode,Node) ->
cover_client(TestNode,Node,stop_cover),
@@ -628,7 +660,7 @@ check_reboot(TestNode,Node) ->
receive
{nodeup, Node} -> wait_started(TestNode,Node)
after 30000 ->
- ?fail({Node, "not rebooted",net_adm:ping(Node)})
+ ?fail({Node, "not rebooted",net_adm:ping(Node)})
end
after 30000 ->
?fail({Node, "not closing down",net_adm:ping(Node)})
@@ -678,22 +710,28 @@ client2(TestNode,PrivDir,ClientSname) ->
release_handler:remove_release("P1H"),
ok = net_kernel:monitor_nodes(true),
- Node = start_client(TestNode,ClientSname),
+ Node = start_client(TestNode,client2,ClientSname),
%% Check env var for SASL on client node
- ?print([{sasl_env, Node}, rpc:call(Node, application, get_all_env, [sasl])]),
SaslEnv = rpc:call(Node, application, get_all_env, [sasl]),
+ ?print([{client1_1,sasl_env},SaslEnv]),
{_,CliDir} = lists:keyfind(client_directory,1,SaslEnv),
{_,[Master,Master2]} = lists:keyfind(masters,1,SaslEnv),
{_,StartCli} = lists:keyfind(start_prg,1,SaslEnv),
- Root = code:root_dir(),
- true = (CliDir =:= filename:join([Root,"clients","type1",Node])),
- true = (StartCli =:= filename:join([CliDir,"bin","start"])),
+ NodeStr = atom_to_list(Node),
+ [NodeStr,"type1","clients"|_] = lists:reverse(filename:split(CliDir)),
true = (Master =:= node()),
true = (Master2 =:= list_to_atom("master2@"++TestHost)),
+ case os:type() of
+ {unix,_} ->
+ true = (StartCli =:= filename:join([CliDir,"bin","start"]));
+ _ ->
+ ok
+ end,
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
+ Root = code:root_dir(),
{error,{bad_masters,[Master2]}} =
rpc:call(Node, release_handler, set_unpacked,
[filename:join([Root, "releases", "P1H", "rel1.rel"]),[]]),
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index efa775f344..16267ba0d4 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -51,7 +51,7 @@ unix_cases() ->
[target_system] ++ RunErlCases ++ cases().
win32_cases() ->
- cases().
+ [{group,release} | cases()].
%% Cases that can be run on all platforms
cases() ->
@@ -148,6 +148,10 @@ init_per_group(release_gg, Config0) ->
end_per_group(release, Config) ->
Dog = ?t:timetrap(?default_timeout),
stop_print_proc(),
+ case os:type() of
+ {win32,_} -> delete_all_services();
+ _ -> ok
+ end,
delete_release(Config),
?t:timetrap_cancel(Dog),
Config;
@@ -169,6 +173,10 @@ end_per_testcase(Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
+ try apply(?MODULE,Case,[cleanup,Config])
+ catch error:undef -> ok
+ end,
+
%% DEBUG
case ?config(tc_status,Config) of
ok ->
@@ -206,10 +214,6 @@ end_per_testcase(Case, Config) ->
%% immediately restarted by heart and the test cases wait until
%% the node is actually up and running -- see wait_nodes_up/2)
file:delete("sasl_erl_crash.dump"),
-
- try apply(?MODULE,Case,[cleanup,Config])
- catch error:undef -> ok
- end,
ok.
gg_node_snames(Config) ->
@@ -224,7 +228,10 @@ gg_node_snames(Config) ->
no_run_erl(Config) when is_list(Config) ->
{comment, "No run_erl program"}.
-
+break(Config) ->
+ erlang:display(test_break),
+ ?t:break(priv_dir(Config)),
+ ok.
%% Test upgrade and downgrade of erts
upgrade(Conf) when is_list(Conf) ->
@@ -323,7 +330,7 @@ client1(Conf) when is_list(Conf) ->
%% Copy the P1G release to a directory for use in this testcase
ok = copy_installed(Conf,p1g_install,[Master]),
- ok = copy_client(Conf,Master,Client,"start_cli1"),
+ ok = copy_client(Conf,Master,Client,client1),
%% start the master node
[TestNode] = start_nodes(Conf,[Master],"client1"),
@@ -348,7 +355,7 @@ client2(Conf) when is_list(Conf) ->
%% Copy the P1G release to a directory for use in this testcase
ok = copy_installed(Conf,p1g_install,[Master]),
- ok = copy_client(Conf,Master,Client,"start_cli2"),
+ ok = copy_client(Conf,Master,Client,client2),
%% start the master node
[TestNode] = start_nodes(Conf,[Master],"client2"),
@@ -983,19 +990,16 @@ stop_node(Node) ->
?t:stop_node(Node).
-copy_client(Conf,Master,Sname,StartScript) ->
+copy_client(Conf,Master,Sname,Client) ->
io:format("copy_client(Conf)"),
DataDir = ?config(data_dir, Conf),
MasterDir = filename:join(priv_dir(Conf),Master),
- {ok,Host} = inet:gethostname(),
- {ok,IpTuple} = inet:getaddr(Host,inet),
- IpAddr = inet_parse:ntoa(IpTuple),
-
- CliNode = node_name(Sname),
+ {ClientArgs,RelCliDir} = rh_test_lib:get_client_args(Client,Sname,MasterDir,
+ node_name(Master)),
- Cli = filename:join([MasterDir, "clients", "type1", CliNode]),
+ Cli = filename:join([MasterDir, RelCliDir]),
ok = filelib:ensure_dir(filename:join([Cli,"bin","."])),
ok = filelib:ensure_dir(filename:join([Cli,"releases","."])),
ok = filelib:ensure_dir(filename:join([Cli,"log","."])),
@@ -1003,12 +1007,16 @@ copy_client(Conf,Master,Sname,StartScript) ->
P1GOrig = filename:join([MasterDir, "releases", "P1G"]),
ok = copy_tree(Conf,P1GOrig,filename:join(Cli,"releases")),
- ok = subst_file(filename:join([DataDir, "clients", StartScript]),
- filename:join([Cli,"bin","start"]),
- [{"ROOT",MasterDir},
- {"MASTER",atom_to_list(Master)},
- {"IPADDR",IpAddr}],
- [{chmod,8#0755}]),
+ case os:type() of
+ {unix,_} ->
+ ok = subst_file(filename:join([DataDir, "start_client"]),
+ filename:join([Cli,"bin","start"]),
+ [{"ROOT",MasterDir},
+ {"CLIENTARGS",ClientArgs}],
+ [{chmod,8#0755}]);
+ _ ->
+ ok
+ end,
StartErlData = filename:join([MasterDir, "releases", "start_erl.data"]),
CliRelDir = filename:join([Cli, "releases"]),
@@ -1030,21 +1038,32 @@ delete_release(Conf) ->
{ok, Dirs} = file:list_dir(PrivDir),
?t:format("======== deleting ~p~n",[Dirs]),
- ok = delete_release_os(Dirs),
- ?t:format("======== remaining ~p~n",[file:list_dir(PrivDir)]),
+ ok = delete_release_os(Dirs--["save"]),
+ {ok,Remaining} = file:list_dir(PrivDir),
+ ?t:format("======== remaining ~p~n",[Remaining]),
+
+ case Remaining of
+ [] ->
+ ok;
+ _ ->
+ delete_release_os(Remaining),
+ Remaining2 = file:list_dir(PrivDir),
+ ?t:format("======== remaining after second try ~p~n",[Remaining2])
+ end,
+
ok = file:set_cwd(OrigWd),
ok.
delete_release_os(Dirs) ->
case os:type() of
- {unix, _} ->
- delete_release_unix(Dirs);
- {win32, _} ->
- delete_release_win32(Dirs);
- Os ->
- test_server:fail({error, {not_yet_implemented_os, Os}})
- end.
+ {unix, _} ->
+ delete_release_unix(Dirs);
+ {win32, _} ->
+ delete_release_win32(Dirs);
+ Os ->
+ test_server:fail({error, {not_yet_implemented_os, Os}})
+ end.
delete_release_unix([]) ->
@@ -1075,7 +1094,14 @@ delete_release_win32([]) ->
delete_release_win32(["save"|Dirs]) ->
delete_release_win32(Dirs);
delete_release_win32([Dir|Dirs]) ->
- Rm = string:concat("rmdir /s ", Dir),
+ 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),
delete_release_win32(Dirs).
@@ -1200,7 +1226,12 @@ subst_var([], Vars, Result, VarAcc) ->
priv_dir(Conf) ->
- filename:absname(?config(priv_dir, Conf)). % Get rid of trailing slash
+%% 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
+ Dir = filename:absname(filename:join(?config(data_dir, Conf),priv_dir)),
+ filelib:ensure_dir(filename:join(Dir,"*")),
+ Dir.
latest_version(Dir) ->
List = filelib:wildcard(Dir ++ "*"),
@@ -1256,12 +1287,28 @@ do_create_p1g(Conf,TargetDir) ->
ErtsLatest = latest_version(filename:join(code:root_dir(),"erts")),
ok = copy_tree(Conf, ErtsLatest, ErtsDir, TargetDir),
ErtsBinDir = filename:join([TargetDir,ErtsDir,bin]),
- copy_file(filename:join([ErtsBinDir, "epmd"]), BinDir, [preserve]),
- copy_file(filename:join([ErtsBinDir, "run_erl"]), BinDir, [preserve]),
- copy_file(filename:join([ErtsBinDir, "to_erl"]), BinDir, [preserve]),
+
+ case os:type() of
+ {unix, _} ->
+ copy_file(filename:join([ErtsBinDir, "epmd"]), BinDir, [preserve]),
+ copy_file(filename:join([ErtsBinDir, "run_erl"]), BinDir, [preserve]),
+ copy_file(filename:join([ErtsBinDir, "to_erl"]), BinDir, [preserve]),
+
+ %% Create the start_erl shell script
+ ok = subst_file(filename:join([ErtsBinDir,"start_erl.src"]),
+ filename:join([BinDir,"start_erl"]),
+ [{"EMU","beam"}],
+ [{chmod,8#0755}]);
+ {win32,_} ->
+ %% Add a batch file to use as HEART_COMMAND
+ ok = copy_file(filename:join(DataDir, "heart_restart.bat"),
+ ErtsBinDir,[preserve])
+ end,
copy_file(filename:join(DataDir, "../installer.beam"),
filename:join([DataDir,lib,"installer-1.0",ebin])),
+ copy_file(filename:join(DataDir, "../rh_test_lib.beam"),
+ filename:join([DataDir,lib,"installer-1.0",ebin])),
%% Create .rel, .script and .boot files
RelName = "rel0",
@@ -1272,7 +1319,7 @@ do_create_p1g(Conf,TargetDir) ->
ok = filelib:ensure_dir(RelFile),
LibPath = filename:join([DataDir,lib,"*",ebin]),
- TarFile = create_basic_release(RelFile, RelVsn, {ErtsVsn,false},
+ TarFile = create_basic_release(Conf, RelFile, RelVsn, {ErtsVsn,false},
LibPath, [], [], [], []),
%% Extract tar file in target directory (i.e. same directory as erts etc.)
@@ -1286,20 +1333,6 @@ do_create_p1g(Conf,TargetDir) ->
%% Create RELEASES
ok = release_handler:create_RELEASES(TargetDir,ReleasesDir,RelFile,[]),
- %% Create start_erl
- ok = subst_file(filename:join([ErtsBinDir,"start_erl.src"]),
- filename:join([BinDir,"start_erl"]),
- [{"EMU","beam"}],
- [{chmod,8#0755}]),
-
- %% Create start script
- %% Using a customized start script from DataDir where some options
- %% (heart and nodename) are added compared to the start.src in the
- %% erlang distribution.
- ok = subst_file(filename:join(DataDir, "start"),
- filename:join([BinDir, "start"]),
- [{"ROOT",TargetDir}],
- [preserve]),
ok.
%% Create version P1H - which is P1G + a-1.0
@@ -1336,12 +1369,12 @@ create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,{UpFromName,Descr})
UpFrom = [{filename:join([PrivDir,UpFromName,UpFromName]),Descr}],
- create_basic_release(RelFile, RelVsn, Erts, LibPath,
+ create_basic_release(Conf, RelFile, RelVsn, Erts, LibPath,
Apps, Config, UpFrom, []),
ok.
%% Create .rel, .script, .boot, sys.config and tar
-create_basic_release(RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,UpFrom,DownTo) ->
+create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,UpFrom,DownTo) ->
RelDir = filename:dirname(RelFile),
RelFileName = filename:rootname(RelFile),
@@ -1370,7 +1403,14 @@ create_basic_release(RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,U
_ -> [{erts,ErtsDir}]
end]),
- RelFileName ++ ".tar.gz".
+ TarFileName = RelFileName ++ ".tar.gz",
+
+ case os:type() of
+ {win32,_} when ErtsDir=/=false -> modify_tar_win32(Conf, TarFileName);
+ _ -> ok
+ end,
+
+ TarFileName.
%% Create a .rel file
create_installer_rel_file(RelFile,RelVsn,ErtsVsn,ExtraApps) ->
@@ -1470,21 +1510,70 @@ permanent_p1h(Node) ->
copy_installed(Conf,FromNode,ToNodes) ->
PrivDir = priv_dir(Conf),
DataDir = ?config(data_dir,Conf),
+
+ %% Instead of using copy_tree on the complete node directory, I'm
+ %% splitting this in separate tar files per subdirectory so the
+ %% log directory can be completely skipped. The reason for this is
+ %% that the tar file might become faulty if the node is alive and
+ %% writing to the log while the tar is created.
+ FromDir = filename:join(PrivDir,FromNode),
+ {ok,FromDirNames} = file:list_dir(FromDir),
+ TempTarFiles =
+ [begin
+ TempTarFile = filename:join(PrivDir,"temp_" ++ FDN ++ ".tar"),
+ {ok,Tar} = erl_tar:open(TempTarFile,[write]),
+ ok = erl_tar:add(Tar,filename:join(FromDir,FDN),FDN,[]),
+ ok = erl_tar:close(Tar),
+ TempTarFile
+ end || FDN <- FromDirNames, FDN=/="log"],
lists:foreach(
fun(Node) ->
- ok = copy_tree(Conf,filename:join(PrivDir,FromNode),Node,PrivDir),
NodeDir = filename:join(PrivDir,Node),
- ok = subst_file(filename:join(DataDir, "start"),
- filename:join([NodeDir, "bin", "start"]),
- [{"ROOT",NodeDir}]),
- LogDir = filename:join(NodeDir,log),
- {ok,Logs} = file:list_dir(LogDir),
- lists:foreach(fun(Log) ->
- file:delete(filename:join(LogDir,Log))
- end,
- Logs)
+ ok = filelib:ensure_dir(filename:join([NodeDir,"log","*"])),
+ lists:foreach(
+ fun(TempTarFile) ->
+ ok = erl_tar:extract(TempTarFile,[{cwd,NodeDir}])
+ end, TempTarFiles),
+ case os:type() of
+ {unix,_} ->
+ %% Create start script
+ %% Using a customized start script from DataDir
+ %% where some options (heart and nodename) are
+ %% added compared to the start.src in the erlang
+ %% distribution.
+ ok = subst_file(filename:join(DataDir, "start"),
+ filename:join([NodeDir, "bin", "start"]),
+ [{"ROOT",NodeDir}],
+ [preserve]);
+ {win32,_} ->
+ %% Write erl.ini
+ ErtsDirs =
+ filelib:wildcard(filename:join(NodeDir,"erts-*")),
+ lists:foreach(
+ fun(ErtsDir) ->
+ ok = subst_file(
+ filename:join(DataDir, "erl.ini.src"),
+ filename:join([ErtsDir, "bin", "erl.ini"]),
+ [{"ROOTDIR",NodeDir},
+ {"BINDIR",filename:join(ErtsDir,"bin")}])
+ end,
+ ErtsDirs),
+
+ %% The service on windows runs as local
+ %% administrator (not otptest user), so we need
+ %% to chmod the release in order to allow the
+ %% executing node to install releases, write
+ %% logs etc.
+ chmod_release_win32(NodeDir)
+ end
end,
- ToNodes).
+ ToNodes),
+
+ lists:foreach(fun(TempTarFile) -> file:delete(TempTarFile) end, TempTarFiles),
+ ok.
+
+chmod_release_win32(Dir) ->
+ os:cmd("echo y|cacls " ++ Dir ++ " /T /E /G Administrators:F").
start_nodes(Conf,Snames,Tag) ->
PrivDir = priv_dir(Conf),
@@ -1493,19 +1582,42 @@ start_nodes(Conf,Snames,Tag) ->
fun(Sname) ->
NodeDir = filename:join(PrivDir,Sname),
Node = node_name(Sname),
-
- 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]),
+
+ case os:type() of
+ {unix,_} ->
+ start_node_unix(Sname,NodeDir);
+ {win32,_} ->
+ start_node_win32(Sname,NodeDir)
+ end,
Node
end,
Snames),
wait_nodes_up(Nodes,Tag),
Nodes.
+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]).
+
+start_node_win32(Sname,NodeDir) ->
+ Name = atom_to_list(Sname) ++ "_P1G",
+ ErtsBinDir = filename:join(NodeDir,"erts-4.4/bin"),
+
+ StartErlArgs = rh_test_lib:get_start_erl_args(NodeDir),
+ ServiceArgs = rh_test_lib:get_service_args(NodeDir, Sname, StartErlArgs),
+
+ Erlsrv = filename:nativename(filename:join(ErtsBinDir,"erlsrv")),
+ rh_test_lib:erlsrv(Erlsrv,stop,Name),
+ rh_test_lib:erlsrv(Erlsrv,remove,Name),
+ ok = rh_test_lib:erlsrv(Erlsrv,add,Name,ServiceArgs),
+ ok = rh_test_lib:erlsrv(Erlsrv,start,Name),
+ ok.
+
+%% Create a unique node name for each test case
tc_sname(Config) ->
tc_sname(Config,"").
tc_sname(Config,Fix) when is_atom(Fix) ->
@@ -1649,3 +1761,32 @@ create_fake_release(Dir,RelName,RelVsn,AppDirs) ->
rpc_inst(Node,Func,Args) ->
rpc:call(Node,installer,Func,[node()|Args]).
+
+delete_all_services() ->
+ ErlSrv = erlsrv:erlsrv(erlang:system_info(version)),
+ [_|Serviceinfo] = string:tokens(os:cmd(ErlSrv ++ " list"),"\n"),
+ Services =
+ [lists:takewhile(fun($\t) -> false; (_) -> true end,S)
+ || S <- Serviceinfo],
+ ?t:format("Services to remove: ~p~n",[Services]),
+ lists:foreach(fun(S) ->
+ rh_test_lib:erlsrv(ErlSrv,stop,S),
+ rh_test_lib:erlsrv(ErlSrv,remove,S)
+ end,
+ Services).
+
+modify_tar_win32(Conf, TarFileName) ->
+ DataDir = ?config(data_dir,Conf),
+ PrivDir = priv_dir(Conf),
+ TmpDir = filename:join(PrivDir,"tmp_modify_tar_win32"),
+ ok = erl_tar:extract(TarFileName,[{cwd,TmpDir},compressed]),
+
+ ErtsBinDir = filelib:wildcard(filename:join([TmpDir,"erts-*","bin"])),
+ ok = copy_file(filename:join(DataDir, "heart_restart.bat"),
+ ErtsBinDir,[preserve]),
+
+ {ok,Fs} = file:list_dir(TmpDir),
+ {ok,T} = erl_tar:open(TarFileName,[write,compressed]),
+ [ok = erl_tar:add(T,filename:join(TmpDir,F),F,[]) || F <- Fs],
+ ok = erl_tar:close(T),
+ ok.
diff --git a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli1 b/lib/sasl/test/release_handler_SUITE_data/clients/start_cli1
deleted file mode 100755
index ee3d8c97cf..0000000000
--- a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli1
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-#
-# This program invokes the erlang emulator by calling run_erl.
-# It should only be used at an embedded target system.
-# It should be modified to give the correct flags to erl (via start_erl),
-# e.g -mode embedded -sname XXX
-#
-# Usage: start [Data]
-#
-
-if [ "x${NODENAME}" = "x" ]
-then
- echo "ERROR: Variable \$NODENAME is not set!!"
- exit 1
-fi
-
-TESTHOST=`hostname | sed 's/[.].*//'`
-IPADDR=%IPADDR%
-
-ROOTDIR=%ROOT%
-CLIENTDIR=$ROOTDIR/clients/type1/$NODENAME@$TESTHOST
-
-RELDIR=$CLIENTDIR/releases
-
-# Note that this scripts is modified an copied to $CLIENTDIR/bin/start
-# in release_handler_SUITE:copy_client - therefore HEART_COMMAND is as follows:
-HEART_COMMAND=$CLIENTDIR/bin/start
-HW_WD_DISABLE=true
-export HW_WD_DISABLE HEART_COMMAND
-
-START_ERL_DATA=${1:-$RELDIR/start_erl.data}
-
-if [ ! -d /tmp/$NODENAME@$TESTHOST ]
-then
- mkdir /tmp/$NODENAME@$TESTHOST
-fi
-
-$ROOTDIR/bin/run_erl /tmp/$NODENAME@$TESTHOST/ $CLIENTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME -sasl start_prg \\\"$CLIENTDIR/bin/start\\\" masters \[\\'%MASTER%@$TESTHOST\\'\] client_directory \\\"$CLIENTDIR\\\" -loader inet -id $NODENAME -hosts $IPADDR" > $CLIENTDIR/log/run_erl.out 2>&1 &
diff --git a/lib/sasl/test/release_handler_SUITE_data/erl.ini.src b/lib/sasl/test/release_handler_SUITE_data/erl.ini.src
new file mode 100644
index 0000000000..b8791e75a5
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/erl.ini.src
@@ -0,0 +1,4 @@
+[erlang]
+Bindir=%BINDIR%
+Progname=erl
+Rootdir=%ROOTDIR%
diff --git a/lib/sasl/test/release_handler_SUITE_data/heart_restart.bat b/lib/sasl/test/release_handler_SUITE_data/heart_restart.bat
new file mode 100755
index 0000000000..ede1ad4ff3
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/heart_restart.bat
@@ -0,0 +1,3 @@
+@echo off
+%ERLSRV_EXECUTABLE% stop %ERLSRV_SERVICE_NAME%
+%ERLSRV_EXECUTABLE% start %ERLSRV_SERVICE_NAME% \ No newline at end of file
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app b/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app
index 6f77317f6a..e1391c0605 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app
@@ -1,6 +1,6 @@
{application, installer,
[{description, "Installer application"},
{vsn, "1.0"},
- {modules, [{installer, 1}]},
+ {modules, [installer,rh_test_lib]},
{registered, []},
{applications, [kernel, stdlib, sasl]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli2 b/lib/sasl/test/release_handler_SUITE_data/start_client
index 88912cf884..5ea94d6f7c 100755
--- a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli2
+++ b/lib/sasl/test/release_handler_SUITE_data/start_client
@@ -34,4 +34,4 @@ then
mkdir /tmp/$NODENAME@$TESTHOST
fi
-$ROOTDIR/bin/run_erl /tmp/$NODENAME@$TESTHOST/ $CLIENTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME -sasl start_prg \\\"$CLIENTDIR/bin/start\\\" masters \[\\'%MASTER%@$TESTHOST\\',\\'master2@$TESTHOST\\'\] client_directory \\\"$CLIENTDIR\\\"" > /dev/null 2>&1 &
+$ROOTDIR/bin/run_erl /tmp/$NODENAME@$TESTHOST/ $CLIENTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME %CLIENTARGS%" > $CLIENTDIR/log/run_erl.out 2>&1 &
diff --git a/lib/sasl/test/rh_test_lib.erl b/lib/sasl/test/rh_test_lib.erl
new file mode 100644
index 0000000000..99a7f919a7
--- /dev/null
+++ b/lib/sasl/test/rh_test_lib.erl
@@ -0,0 +1,100 @@
+-module(rh_test_lib).
+
+-export([erlsrv/3,
+ erlsrv/4]).
+-export([get_service_args/3,
+ get_service_args/4,
+ get_start_erl_args/1,
+ get_start_erl_args/3,
+ get_client_args/3,
+ get_client_args/4]).
+
+
+erlsrv(Erlsrv,Action,Name) ->
+ erlsrv(Erlsrv,Action,Name,"").
+erlsrv(Erlsrv,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),
+ case Res of
+ [] ->
+ failed;
+ _Y ->
+ io:format("erlsrv res: ~p~n",[_Y]),
+ ok
+ end.
+
+recv_prog_output(Port) ->
+ receive
+ {Port, {data, {eol,Data}}} ->
+ %%io:format("Got data: ~s~n", [Data]),
+ [ Data, "\n" | recv_prog_output(Port)];
+ {Port, {data, {noeol,Data}}} ->
+ %%io:format("Got data: ~s~n", [Data]),
+ [ Data | recv_prog_output(Port)];
+ {Port, _Other} ->
+ %%io:format("Got ~p from port~n", [_Other]),
+ Port ! {self(), close},
+ receive
+ {Port,closed} ->
+ []
+ end
+ end.
+
+get_service_args(RootDir, Sname, StartErlArgs) ->
+ get_service_args(RootDir, "", Sname, StartErlArgs).
+get_service_args(RootDir, RelClientDir, Sname, StartErlArgs) ->
+ LogDir = filename:nativename(filename:join([RootDir,RelClientDir,"log"])),
+ %% start_erl.exe will be found since it is in the same directory as erlsrv.exe
+ %% And heart_restart.bat will be found since the erts bin dir is
+ %% always in the path for the erlang virtual machine.
+ " -machine start_erl.exe -workdir " ++ LogDir ++
+ " -debugtype new -sname " ++ atom_to_list(Sname) ++
+ " -env HEART_COMMAND=heart_restart.bat -args \"" ++ StartErlArgs ++ "\"".
+
+get_start_erl_args(RootDir) ->
+ get_start_erl_args(RootDir,"","").
+get_start_erl_args(RootDir,RelClientDir,ExtraArgs) ->
+ Cookie = atom_to_list(erlang:get_cookie()),
+ RelDir = filename:join([RootDir,RelClientDir,"releases"]),
+ ExtraArgs ++ " -setcookie " ++ Cookie ++
+ " -heart ++ -rootdir " ++ filename:nativename(RootDir) ++
+ " -reldir " ++ filename:nativename(RelDir).
+
+%% Must be called on the master node
+get_client_args(Client,Sname,RootDir) ->
+ get_client_args(Client,Sname,RootDir,node()).
+get_client_args(Client,Sname,RootDir,Master) ->
+ {ok,Host} = inet:gethostname(),
+ Node = atom_to_list(Sname) ++ "@" ++ Host,
+ RelClientDir = filename:join(["clients","type1",Node]),
+ ClientDir = filename:join([RootDir,RelClientDir]),
+ StartPrg = filename:join([ClientDir,"bin","start"]),
+ {" -sasl start_prg \\\\\\\"" ++ StartPrg ++ "\\\\\\\" masters \[" ++
+ single_quote() ++ atom_to_list(Master) ++ single_quote() ++
+ get_client_extra_master(Client,Host) ++
+ "\] client_directory \\\\\\\"" ++ ClientDir ++ "\\\\\\\"" ++
+ get_client_loader_args(Client,Sname,Host),
+ RelClientDir}.
+
+get_client_loader_args(client1,Sname,Host) ->
+ {ok,IpTuple} = inet:getaddr(Host,inet),
+ IpAddr = inet_parse:ntoa(IpTuple),
+ " -loader inet -id " ++
+ atom_to_list(Sname) ++ " -hosts " ++ IpAddr;
+get_client_loader_args(_,_,_) ->
+ "".
+
+get_client_extra_master(client2,Host) ->
+ "," ++ single_quote() ++ "master2@" ++ Host ++ single_quote();
+get_client_extra_master(_,_) ->
+ "".
+
+single_quote() ->
+ case os:type() of
+ {win32,_} ->
+ "\'";
+ _ ->
+ "\\'"
+ end.
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index fd85c7aef5..306834e845 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -798,30 +798,10 @@ set_extracted_file_info(Name, #tar_header{mode=Mode, mtime=Mtime}) ->
%% Makes all directories leading up to the file.
-make_dirs(Name, Type) ->
- make_dirs1(filename:split(Name), Type).
-
-make_dirs1([Dir, Next|Rest], Type) ->
- case file:read_file_info(Dir) of
- {ok, #file_info{type=directory}} ->
- make_dirs1([filename:join(Dir, Next)|Rest], Type);
- {ok, #file_info{}} ->
- throw({error, enotdir});
- {error, _} ->
- case file:make_dir(Dir) of
- ok ->
- make_dirs1([filename:join(Dir, Next)|Rest], Type);
- {error, Reason} ->
- throw({error, Reason})
- end
- end;
-make_dirs1([_], file) -> ok;
-make_dirs1([Dir], dir) ->
- file:make_dir(Dir);
-make_dirs1([], _) ->
- %% There must be something wrong here. The list was not supposed
- %% to be empty.
- throw({error, enoent}).
+make_dirs(Name, file) ->
+ filelib:ensure_dir(Name);
+make_dirs(Name, dir) ->
+ filelib:ensure_dir(filename:join(Name,"*")).
%% Prints the message on if the verbose option is given (for reading).