diff options
Diffstat (limited to 'lib/kernel/test')
33 files changed, 2129 insertions, 1107 deletions
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 8eca37029d..cb11d4e899 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# Copyright Ericsson AB 1997-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 @@ -48,6 +48,7 @@ MODULES= \ erl_distribution_SUITE \ erl_distribution_wb_SUITE \ erl_prim_loader_SUITE \ + error_handler_SUITE \ error_logger_SUITE \ error_logger_warn_SUITE \ file_SUITE \ @@ -73,6 +74,7 @@ MODULES= \ seq_trace_SUITE \ wrap_log_reader_SUITE \ cleanup \ + ignore_cores \ zlib_SUITE \ loose_node \ sendfile_SUITE diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl index f469a0af98..0452202467 100644 --- a/lib/kernel/test/application_SUITE.erl +++ b/lib/kernel/test/application_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -27,7 +27,7 @@ otp_1586/1, otp_2078/1, otp_2012/1, otp_2718/1, otp_2973/1, otp_3002/1, otp_3184/1, otp_4066/1, otp_4227/1, otp_5363/1, otp_5606/1, - start_phases/1, get_key/1, + start_phases/1, get_key/1, get_env/1, permit_false_start_local/1, permit_false_start_dist/1, script_start/1, nodedown_start/1, init2973/0, loop2973/0, loop5606/1]). @@ -49,7 +49,7 @@ all() -> [failover, failover_comp, permissions, load, load_use_cache, {group, reported_bugs}, start_phases, script_start, nodedown_start, permit_false_start_local, - permit_false_start_dist, get_key, + permit_false_start_dist, get_key, get_env, {group, distr_changed}, config_change, shutdown_func, shutdown_timeout]. groups() -> @@ -1503,6 +1503,15 @@ loop5606(Pid) -> Pid ! {self(), Res} end. +get_env(suite) -> []; +get_env(doc) -> + ["Tests get_env/* functions"]; +get_env(Conf) when is_list(Conf) -> + {ok, _} = application:get_env(kernel, error_logger), + undefined = application:get_env(undefined_app, a), + undefined = application:get_env(kernel, error_logger_xyz), + default = application:get_env(kernel, error_logger_xyz, default), + ok. %%----------------------------------------------------------------- %% Should be started in a CC view with: diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index 827208b048..fc17db2745 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -25,6 +25,7 @@ replace_path/1, load_file/1, load_abs/1, ensure_loaded/1, delete/1, purge/1, soft_purge/1, is_loaded/1, all_loaded/1, load_binary/1, dir_req/1, object_code/1, set_path_file/1, + upgrade/1, sticky_dir/1, pa_pz_option/1, add_del_path/1, dir_disappeared/1, ext_mod_dep/1, clash/1, load_cached/1, start_node_with_cache/1, add_and_rehash/1, @@ -32,7 +33,7 @@ purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1, code_archive/1, code_archive2/1, on_load/1, on_load_binary/1, on_load_embedded/1, on_load_errors/1, big_boot_embedded/1, - native_early_modules/1]). + native_early_modules/1, get_mode/1]). -export([init_per_testcase/2, end_per_testcase/2, init_per_suite/1, end_per_suite/1, @@ -43,6 +44,8 @@ handle_event/2, handle_call/2, handle_info/2, terminate/2]). +-export([compile_load/4]). + suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> @@ -50,13 +53,14 @@ all() -> replace_path, load_file, load_abs, ensure_loaded, delete, purge, soft_purge, is_loaded, all_loaded, load_binary, dir_req, object_code, set_path_file, + upgrade, pa_pz_option, add_del_path, dir_disappeared, ext_mod_dep, clash, load_cached, start_node_with_cache, add_and_rehash, where_is_file_no_cache, where_is_file_cached, purge_stacktrace, mult_lib_roots, bad_erl_libs, code_archive, code_archive2, on_load, on_load_binary, on_load_embedded, on_load_errors, - big_boot_embedded, native_early_modules]. + big_boot_embedded, native_early_modules, get_mode]. groups() -> []. @@ -450,6 +454,46 @@ load_binary(Config) when is_list(Config) -> code:delete(code_b_test), ok. +upgrade(Config) -> + DataDir = ?config(data_dir, Config), + + %%T = [beam, hipe], + T = [beam], + + [upgrade_do(DataDir, Client, U1, U2, O1, O2) + || Client<-T, U1<-T, U2<-T, O1<-T, O2<-T], + + ok. + +upgrade_do(DataDir, Client, U1, U2, O1, O2) -> + compile_load(upgrade_client, DataDir, undefined, Client), + upgrade_client:run(DataDir, U1, U2, O1, O2), + ok. + +compile_load(Mod, Dir, Ver, CodeType) -> + Version = case Ver of + undefined -> + io:format("Compiling '~p' as ~p\n", [Mod, CodeType]), + []; + _ -> + io:format("Compiling version ~p of '~p' as ~p\n", + [Ver, Mod, CodeType]), + [{d,list_to_atom("VERSION_" ++ integer_to_list(Ver))}] + end, + Target = case CodeType of + beam -> []; + hipe -> [native] + end, + CompOpts = [binary, report] ++ Target ++ Version, + + Src = filename:join(Dir, atom_to_list(Mod) ++ ".erl"), + %io:format("compile:file(~p,~p)\n", [Src, CompOpts]), + {ok,Mod,Code} = compile:file(Src, CompOpts), + ObjFile = filename:basename(Src,".erl") ++ ".beam", + {module,Mod} = code:load_binary(Mod, ObjFile, Code), + %IsNative = code:is_module_native(Mod), + ok. + dir_req(suite) -> []; dir_req(doc) -> []; dir_req(Config) when is_list(Config) -> @@ -535,30 +579,25 @@ sticky_compiler(File) -> pa_pz_option(suite) -> []; pa_pz_option(doc) -> ["Test that the -pa and -pz options work as expected"]; pa_pz_option(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "Slave nodes not supported on VxWorks"}; - _ -> - DDir = ?config(data_dir,Config), - PaDir = filename:join(DDir,"pa"), - PzDir = filename:join(DDir,"pz"), - ?line {ok, Node}=?t:start_node(pa_pz1, slave, - [{args, - "-pa " ++ PaDir - ++ " -pz " ++ PzDir}]), - ?line Ret=rpc:call(Node, code, get_path, []), - ?line [PaDir|Paths] = Ret, - ?line [PzDir|_] = lists:reverse(Paths), - ?t:stop_node(Node), - ?line {ok, Node2}=?t:start_node(pa_pz2, slave, - [{args, - "-mode embedded " ++ "-pa " - ++ PaDir ++ " -pz " ++ PzDir}]), - ?line Ret2=rpc:call(Node2, code, get_path, []), - ?line [PaDir|Paths2] = Ret2, - ?line [PzDir|_] = lists:reverse(Paths2), - ?t:stop_node(Node2) - end. + DDir = ?config(data_dir,Config), + PaDir = filename:join(DDir,"pa"), + PzDir = filename:join(DDir,"pz"), + {ok, Node}=?t:start_node(pa_pz1, slave, + [{args, + "-pa " ++ PaDir + ++ " -pz " ++ PzDir}]), + Ret=rpc:call(Node, code, get_path, []), + [PaDir|Paths] = Ret, + [PzDir|_] = lists:reverse(Paths), + ?t:stop_node(Node), + {ok, Node2}=?t:start_node(pa_pz2, slave, + [{args, + "-mode embedded " ++ "-pa " + ++ PaDir ++ " -pz " ++ PzDir}]), + Ret2=rpc:call(Node2, code, get_path, []), + [PaDir|Paths2] = Ret2, + [PzDir|_] = lists:reverse(Paths2), + ?t:stop_node(Node2). add_del_path(suite) -> []; @@ -645,8 +684,8 @@ ext_mod_dep(Config) when is_list(Config) -> xref:set_default(s, [{verbose,false},{warnings,false}, {builtins,true},{recurse,true}]), xref:set_library_path(s, code:get_path()), - xref:add_directory(s, filename:dirname(code:which(kernel))), - xref:add_directory(s, filename:dirname(code:which(lists))), + xref:add_directory(s, filename:join(code:lib_dir(kernel),"ebin")), + xref:add_directory(s, filename:join(code:lib_dir(stdlib),"ebin")), case catch ext_mod_dep2() of {'EXIT', Reason} -> xref:stop(s), @@ -677,7 +716,7 @@ analyse([], [This={M,F,A}|Path], Visited, ErrCnt0) -> %% These modules should be loaded by code.erl before %% the code_server is started. OK = [erlang, os, prim_file, erl_prim_loader, init, ets, - code_server, lists, lists_sort, unicode, binary, filename, packages, + code_server, lists, lists_sort, unicode, binary, filename, gb_sets, gb_trees, hipe_unified_loader, hipe_bifs, prim_zip, zlib], ErrCnt1 = @@ -783,6 +822,10 @@ check_funs({'$M_EXPR','$F_EXPR',2}, check_funs({'$M_EXPR','$F_EXPR',1}, [{lists,foreach,2}, {hipe_unified_loader,patch_consts,3} | _]) -> 0; +check_funs({'$M_EXPR','$F_EXPR',1}, + [{lists,foreach,2}, + {hipe_unified_loader,mark_referred_from,1}, + {hipe_unified_loader,get_refs_from,2}| _]) -> 0; check_funs({'$M_EXPR',warning_msg,2}, [{code_server,finish_on_load_report,2} | _]) -> 0; %% This is cheating! /raimo @@ -1551,10 +1594,15 @@ native_early_modules_1(Architecture) -> ?line true = lists:all(fun code:is_module_native/1, [ets,file,filename,gb_sets,gb_trees, %%hipe_unified_loader, no_native as workaround - lists,os,packages]), + lists,os]), ok end. +get_mode(suite) -> []; +get_mode(doc) -> ["Test that the mode of the code server is properly retrieved"]; +get_mode(Config) when is_list(Config) -> + interactive = code:get_mode(). + %%----------------------------------------------------------------- %% error_logger handler. %% (Copied from stdlib/test/proc_lib_SUITE.erl.) diff --git a/lib/kernel/test/code_SUITE_data/other.erl b/lib/kernel/test/code_SUITE_data/other.erl new file mode 100644 index 0000000000..58ce87f222 --- /dev/null +++ b/lib/kernel/test/code_SUITE_data/other.erl @@ -0,0 +1,38 @@ +-module(other). + +-ifdef(VERSION_1). +-define(VERSION,1). +-export([exp1/0]). +-export([exp1loc2/0]). +-export([exp1exp2/0]). +exp1() -> check([loc1(),exp1loc2(),exp1exp2(),loc1exp2(),loc1loc2()]). +loc1() -> check([exp1loc2(),exp1exp2(),loc1exp2(),loc1loc2()]). +exp1loc2() -> check([exp1exp2(),loc1exp2(),loc1loc2()]). +exp1exp2() -> check([loc1exp2(),loc1loc2()]). +loc1exp2() -> check([loc1loc2()]). +-endif. % VERSION_1 + +-ifdef(VERSION_2). +-define(VERSION,2). +-export([exp2/0]). +-export([loc1exp2/0]). +-export([exp1exp2/0]). +loc1exp2() -> check([exp1exp2(),exp1loc2(),loc2(),exp2(),loc1loc2()]). +exp1exp2() -> check([exp1loc2(),loc2(),exp2(),loc1loc2()]). +exp1loc2() -> check([loc2(),exp2(),loc1loc2()]). +loc2() -> check([exp2(),loc1loc2()]). +exp2() -> check([loc1loc2()]). + +-endif. % VERSION_2 + +loc1loc2() -> ?VERSION. + + +check(VerList) -> + case lists:all(fun(?VERSION) -> true; (_) -> false end, + VerList) of + true -> + ?VERSION; + false -> + VerList + end. diff --git a/lib/kernel/test/code_SUITE_data/upgrade_client.erl b/lib/kernel/test/code_SUITE_data/upgrade_client.erl new file mode 100644 index 0000000000..bb655e01d3 --- /dev/null +++ b/lib/kernel/test/code_SUITE_data/upgrade_client.erl @@ -0,0 +1,259 @@ +-module(upgrade_client). + +-export([run/5]). + +%%-define(line, io:format("~s:~p\n", [?MODULE,?LINE]),). +-define(line,). + +run(Dir, Upgradee1, Upgradee2, Other1, Other2) -> + %% Load version 1 of upgradee + code_SUITE:compile_load(upgradee, Dir, 1, Upgradee1), + + ?line 1 = upgradee:exp1(), + ?line 1 = upgradee:exp1exp2(), + ?line 1 = upgradee:exp1loc2(), + + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:exp2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1exp2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1loc2()), + + P = spawn_link(upgradee,dispatch_loop,[]), + + ?line 1 = proxy_call(P, local, exp1), + ?line 1 = proxy_call(P, local, loc1), + ?line 1 = proxy_call(P, local, exp1exp2), + ?line 1 = proxy_call(P, local, exp1loc2), + ?line 1 = proxy_call(P, local, loc1exp2), + ?line 1 = proxy_call(P, local, loc1loc2), + ?line 1 = proxy_call(P, external, exp1), + ?line 1 = proxy_call(P, external, exp1exp2), + ?line 1 = proxy_call(P, external, exp1loc2), + + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc2), + ?line {cannot_compile,1} = proxy_call(P, local, exp2), + ?line {cannot_compile,1} = proxy_call(P, local, loc2), + + ?line {'EXIT',{undef,_}} = (catch other:exp1()), + ?line {'EXIT',{undef,_}} = (catch other:loc1()), + ?line {'EXIT',{undef,_}} = (catch other:exp1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:exp1exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc11exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc2()), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2), + + %% + %% Load version 1 of other + %% + code_SUITE:compile_load(other, Dir, 1, Other1), + ?line 1 = other:exp1(), + ?line 1 = other:exp1loc2(), + ?line 1 = other:exp1exp2(), + ?line {'EXIT',{undef,_}} = (catch other:loc1()), + ?line {'EXIT',{undef,_}} = (catch other:loc1exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc2()), + + ?line 1 = proxy_call(P, other, exp1), + ?line 1 = proxy_call(P, other, exp1loc2), + ?line 1 = proxy_call(P, other, exp1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2), + + %% + %% Load version 2 of upgradee + %% + code_SUITE:compile_load(upgradee, Dir, 2, Upgradee2), + + ?line 2 = upgradee:exp2(), + ?line 2 = upgradee:exp1exp2(), + ?line 2 = upgradee:loc1exp2(), + + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc2()), + + ?line 1 = proxy_call(P, local, exp1), + ?line 1 = proxy_call(P, local, loc1), + ?line 1 = proxy_call(P, local, exp1exp2), + ?line 1 = proxy_call(P, local, exp1loc2), + ?line 1 = proxy_call(P, local, loc1exp2), + ?line 1 = proxy_call(P, local, loc1loc2), + ?line {cannot_compile,1} = proxy_call(P, local, exp2), + ?line {cannot_compile,1} = proxy_call(P, local, loc2), + + ?line 2 = proxy_call(P, external, exp1exp2), + ?line 2 = proxy_call(P, external, loc1exp2), + ?line 2 = proxy_call(P, external, exp2), + + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc2), + + ?line 1 = other:exp1(), + ?line 1 = other:exp1loc2(), + ?line 1 = other:exp1exp2(), + ?line {'EXIT',{undef,_}} = (catch other:loc1()), + ?line {'EXIT',{undef,_}} = (catch other:loc1exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:exp2()), + ?line {'EXIT',{undef,_}} = (catch other:loc2()), + + ?line 1 = proxy_call(P, other, exp1), + ?line 1 = proxy_call(P, other, exp1loc2), + ?line 1 = proxy_call(P, other, exp1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2), + + %% + %% Load version 2 of other + %% + code_SUITE:compile_load(other, Dir, 2, Other2), + + ?line 2 = upgradee:exp2(), + ?line 2 = upgradee:exp1exp2(), + ?line 2 = upgradee:loc1exp2(), + + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc2()), + + ?line 1 = proxy_call(P, local, exp1), + ?line 1 = proxy_call(P, local, loc1), + ?line 1 = proxy_call(P, local, exp1exp2), + ?line 1 = proxy_call(P, local, exp1loc2), + ?line 1 = proxy_call(P, local, loc1exp2), + ?line 1 = proxy_call(P, local, loc1loc2), + ?line {cannot_compile,1} = proxy_call(P, local, exp2), + ?line {cannot_compile,1} = proxy_call(P, local, loc2), + + ?line 2 = proxy_call(P, external, exp1exp2), + ?line 2 = proxy_call(P, external, loc1exp2), + ?line 2 = proxy_call(P, external, exp2), + + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc2), + + ?line 2 = other:exp2(), + ?line 2 = other:loc1exp2(), + ?line 2 = other:exp1exp2(), + ?line {'EXIT',{undef,_}} = (catch other:exp1()), + ?line {'EXIT',{undef,_}} = (catch other:loc1()), + ?line {'EXIT',{undef,_}} = (catch other:exp1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:loc2()), + + ?line 2 = proxy_call(P, other, exp2), + ?line 2 = proxy_call(P, other, loc1exp2), + ?line 2 = proxy_call(P, other, exp1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2), + + + %% + %% Upgrade proxy to version 2 + %% + P ! upgrade_order, + + + %% + io:format("Delete version 2 of 'upgradee'\n",[]), + %% + code:purge(upgradee), + code:delete(upgradee), + + ?line {'EXIT',{undef,_}} = (catch upgradee:exp2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1exp2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1exp2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1()), + ?line {'EXIT',{undef,_}} = (catch upgradee:exp1loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch upgradee:loc2()), + + ?line 2 = proxy_call(P, local, exp2), + ?line 2 = proxy_call(P, local, loc2), + ?line 2 = proxy_call(P, local, exp1exp2), + ?line 2 = proxy_call(P, local, exp1loc2), + ?line 2 = proxy_call(P, local, loc1exp2), + ?line 2 = proxy_call(P, local, loc1loc2), + ?line {cannot_compile,2} = proxy_call(P, local, exp1), + ?line {cannot_compile,2} = proxy_call(P, local, loc1), + + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, exp1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, external, loc2), + + ?line 2 = other:exp2(), + ?line 2 = other:loc1exp2(), + ?line 2 = other:exp1exp2(), + ?line {'EXIT',{undef,_}} = (catch other:exp1()), + ?line {'EXIT',{undef,_}} = (catch other:loc1()), + ?line {'EXIT',{undef,_}} = (catch other:exp1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:loc1loc2()), + ?line {'EXIT',{undef,_}} = (catch other:loc2()), + + ?line 2 = proxy_call(P, other, exp2), + ?line 2 = proxy_call(P, other, loc1exp2), + ?line 2 = proxy_call(P, other, exp1exp2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2), + ?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2), + + unlink(P), + exit(P, die_please), + + io:format("Purge 'upgradee'\n",[]), + code:purge(upgradee), + + io:format("Delete and purge 'other'\n",[]), + code:purge(other), + code:delete(other), + code:purge(other), + ok. + +proxy_call(Pid, CallType, Func) -> + Pid ! {self(), CallType, Func}, + receive + {Pid, call_result, Func, Ret} -> Ret + end. diff --git a/lib/kernel/test/code_SUITE_data/upgradee.erl b/lib/kernel/test/code_SUITE_data/upgradee.erl new file mode 100644 index 0000000000..62b1d95e30 --- /dev/null +++ b/lib/kernel/test/code_SUITE_data/upgradee.erl @@ -0,0 +1,123 @@ +-module(upgradee). + +-export([dispatch_loop/0]). + +-ifdef(VERSION_1). +-define(VERSION,1). + +-export([exp1/0]). % only exported in v1 +-export([exp1loc2/0]). % exported in v1, local in v2 +-export([exp1exp2/0]). % exported in v1 and v2 + +exp1() -> ?VERSION. +loc1() -> ?VERSION. + +-endif. % VERSION_1 + +-ifdef(VERSION_2). +-define(VERSION,2). + +-export([exp2/0]). +-export([loc1exp2/0]). +-export([exp1exp2/0]). + +exp2() -> ?VERSION. +loc2() -> ?VERSION. + +-endif. % VERSION_2 + +exp1exp2() -> ?VERSION. +exp1loc2() -> ?VERSION. +loc1exp2() -> ?VERSION. +loc1loc2() -> ?VERSION. + +dispatch_loop() -> + receive + upgrade_order -> + %%erlang:display({"upgradee version", ?VERSION, "got upgrade_order"}), + ?MODULE:dispatch_loop(); + + Msg -> + %%erlang:display({"upgradee version", ?VERSION, "got msg", Msg}), + {Func,Ret} = case Msg of + %% Local calls + {Pid, local, F=exp1} -> + {F, local_exp1()}; + {Pid, local, F=loc1} -> + {F, local_loc1()}; + {Pid, local, F=exp1exp2} -> + {F, catch exp1exp2()}; + {Pid, local, F=exp1loc2} -> + {F, catch exp1loc2()}; + {Pid, local, F=loc1exp2} -> + {F, catch loc1exp2()}; + {Pid, local, F=loc1loc2} -> + {F, catch loc1loc2()}; + {Pid, local, F=exp2} -> + {F, local_exp2()}; + {Pid, local, F=loc2} -> + {F, local_loc2()}; + + %% Extern calls to own module + {Pid, external, F=exp1} -> + {F, catch ?MODULE:exp1()}; + {Pid, external, F=loc1} -> + {F, catch ?MODULE:loc1()}; + {Pid, external, F=exp1exp2} -> + {F, catch ?MODULE:exp1exp2()}; + {Pid, external, F=exp1loc2} -> + {F, catch ?MODULE:exp1loc2()}; + {Pid, external, F=loc1exp2} -> + {F, catch ?MODULE:loc1exp2()}; + {Pid, external, F=loc1loc2} -> + {F, catch ?MODULE:loc1loc2()}; + {Pid, external, F=exp2} -> + {F, catch ?MODULE:exp2()}; + {Pid, external, F=loc2} -> + {F, catch ?MODULE:loc2()}; + + %% External calls to other module + {Pid, other, F=exp1} -> + {F, catch other:exp1()}; + {Pid, other, F=loc1} -> + {F, catch other:loc1()}; + {Pid, other, F=exp1exp2} -> + {F, catch other:exp1exp2()}; + {Pid, other, F=exp1loc2} -> + {F, catch other:exp1loc2()}; + {Pid, other, F=loc1exp2} -> + {F, catch other:loc1exp2()}; + {Pid, other, F=loc1loc2} -> + {F, catch other:loc1loc2()}; + {Pid, other, F=exp2} -> + {F, catch other:exp2()}; + {Pid, other, F=loc2} -> + {F, catch other:loc2()} + end, + Pid ! {self(), call_result, Func, Ret}, + + dispatch_loop() % A local call, we don't want to upgrade the dispatcher + end. + + + +-ifdef(VERSION_1). +local_exp1() -> catch exp1(). +local_loc1() -> catch loc1(). +-else. +local_exp1() -> + %%erlang:display({"upgradee:local_exp1 in version", ?VERSION}), + {cannot_compile,?VERSION}. +local_loc1() -> {cannot_compile,?VERSION}. +-endif. + +-ifdef(VERSION_2). +local_exp2() -> catch exp2(). +local_loc2() -> catch loc2(). +-else. +local_exp2() -> + %%erlang:display({"upgradee:local_exp2 in version", ?VERSION}), + {cannot_compile,?VERSION}. +local_loc2() -> + {cannot_compile,?VERSION}. +-endif. diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl index 0c3f5c3514..0f811b8f73 100644 --- a/lib/kernel/test/disk_log_SUITE.erl +++ b/lib/kernel/test/disk_log_SUITE.erl @@ -126,11 +126,6 @@ error, chunk, truncate, many_users, info, change_size, change_attribute, distribution, evil, otp_6278, otp_10131]). -%% The following two lists should be mutually exclusive. To skip a case -%% on VxWorks altogether, use the kernel.spec.vxworks file instead. -%% PLEASE don't skip out of laziness, the goal is to make every -%% testcase runnable on VxWorks. - %% These test cases should be skipped if the VxWorks card is %% configured without NFS cache. -define(SKIP_NO_CACHE,[distribution]). @@ -5126,33 +5121,8 @@ stop_node(Node) -> %% If the board is configured without NFS, the port program will fail to load %% and this will return 0, which may or may not be the wrong thing to do. -check_nfs(Config) -> - case (catch check_cache(Config)) of - N when is_integer(N) -> - N; - _ -> - 0 - end. - -check_cache(Config) -> - ?line Check = filename:join(?datadir(Config), "nfs_check"), - ?line P = open_port({spawn, Check}, [{line,100}, eof]), - ?line Size = receive - {P,{data,{eol,S}}} -> - list_to_integer(S) - after 1000 -> - erlang:display(got_timeout), - exit(timeout) - end, - ?line receive - {P, eof} -> - ok - end, - ?line P ! {self(), close}, - ?line receive - {P, closed} -> ok - end, - Size. +check_nfs(_Config) -> + 0. skip_expand([]) -> []; @@ -5175,13 +5145,8 @@ skip_list(Config) -> skip_expand(?SKIP_LARGE_CACHE) end. -should_skip(Test,Config) -> - case os:type() of - vxworks -> - lists:member(Test, skip_list(Config)); - _ -> - false - end. +should_skip(_Test,_Config) -> + false. %%----------------------------------------------------------------- %% The error_logger handler used. diff --git a/lib/kernel/test/disk_log_SUITE_data/Makefile.src b/lib/kernel/test/disk_log_SUITE_data/Makefile.src deleted file mode 100644 index cae2f23d29..0000000000 --- a/lib/kernel/test/disk_log_SUITE_data/Makefile.src +++ /dev/null @@ -1,15 +0,0 @@ -CC = @CC@ -LD = @LD@ -CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@ -CROSSLDFLAGS = @CROSSLDFLAGS@ - -PROGS = nfs_check@exe@ - -all: $(PROGS) - -nfs_check@exe@: nfs_check@obj@ - $(LD) $(CROSSLDFLAGS) -o nfs_check nfs_check@obj@ @LIBS@ - -nfs_check@obj@: nfs_check.c - $(CC) -c -o nfs_check@obj@ $(CFLAGS) nfs_check.c - diff --git a/lib/kernel/test/disk_log_SUITE_data/nfs_check.c b/lib/kernel/test/disk_log_SUITE_data/nfs_check.c deleted file mode 100644 index 31e9ba8190..0000000000 --- a/lib/kernel/test/disk_log_SUITE_data/nfs_check.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Author: Patrik Nyblom - * Purpose: A port program to check the NFS cache size on VxWorks (returns 0 - * for other platforms). - */ - -#ifdef VXWORKS -#include <vxWorks.h> -#include <taskVarLib.h> -#include <taskLib.h> -#include <sysLib.h> -#include <string.h> -#include <ioLib.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#ifdef VXWORKS -extern unsigned nfsCacheSize; -#define MAIN(argc, argv) nfs_check(argc, argv) -#else -#define MAIN(argc, argv) main(argc, argv) -#endif - - -MAIN(argc, argv) -int argc; -char *argv[]; -{ -#ifdef VXWORKS - char str[100]; - sprintf(str,"%d\n", nfsCacheSize); - write(1, str, strlen(str)); -#else - fprintf(stdout,"0"); - fflush(stdout); -#endif - return 0; -} - diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl index 72239641e9..35502a1d27 100644 --- a/lib/kernel/test/erl_prim_loader_SUITE.erl +++ b/lib/kernel/test/erl_prim_loader_SUITE.erl @@ -110,56 +110,46 @@ get_file(Config) when is_list(Config) -> inet_existing(doc) -> ["Start a node using the 'inet' loading method, ", "from an already started boot server."]; inet_existing(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "VxWorks: tested separately"}; - _ -> - ?line Name = erl_prim_test_inet_existing, - ?line Host = host(), - ?line Cookie = atom_to_list(erlang:get_cookie()), - ?line IpStr = ip_str(Host), - ?line LFlag = get_loader_flag(os:type()), - ?line Args = LFlag ++ " -hosts " ++ IpStr ++ - " -setcookie " ++ Cookie, - ?line {ok, BootPid} = erl_boot_server:start_link([Host]), - ?line {ok, Node} = start_node(Name, Args), - ?line {ok,[["inet"]]} = rpc:call(Node, init, get_argument, [loader]), - ?line stop_node(Node), - ?line unlink(BootPid), - ?line exit(BootPid, kill), - ok - end. + Name = erl_prim_test_inet_existing, + Host = host(), + Cookie = atom_to_list(erlang:get_cookie()), + IpStr = ip_str(Host), + LFlag = get_loader_flag(os:type()), + Args = LFlag ++ " -hosts " ++ IpStr ++ + " -setcookie " ++ Cookie, + {ok, BootPid} = erl_boot_server:start_link([Host]), + {ok, Node} = start_node(Name, Args), + {ok,[["inet"]]} = rpc:call(Node, init, get_argument, [loader]), + stop_node(Node), + unlink(BootPid), + exit(BootPid, kill), + ok. inet_coming_up(doc) -> ["Start a node using the 'inet' loading method, ", "but start the boot server afterwards."]; inet_coming_up(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "VxWorks: tested separately"}; - _ -> - ?line Name = erl_prim_test_inet_coming_up, - ?line Cookie = atom_to_list(erlang:get_cookie()), - ?line Host = host(), - ?line IpStr = ip_str(Host), - ?line LFlag = get_loader_flag(os:type()), - ?line Args = LFlag ++ - " -hosts " ++ IpStr ++ - " -setcookie " ++ Cookie, - ?line {ok, Node} = start_node(Name, Args, [{wait, false}]), - - %% Wait a while, then start boot server, and wait for node to start. - ?line test_server:sleep(test_server:seconds(6)), - io:format("erl_boot_server:start_link([~p]).", [Host]), - ?line {ok, BootPid} = erl_boot_server:start_link([Host]), - ?line wait_really_started(Node, 25), - - %% Check loader argument, then cleanup. - ?line {ok,[["inet"]]} = rpc:call(Node, init, get_argument, [loader]), - ?line stop_node(Node), - ?line unlink(BootPid), - ?line exit(BootPid, kill), - ok - end. + Name = erl_prim_test_inet_coming_up, + Cookie = atom_to_list(erlang:get_cookie()), + Host = host(), + IpStr = ip_str(Host), + LFlag = get_loader_flag(os:type()), + Args = LFlag ++ + " -hosts " ++ IpStr ++ + " -setcookie " ++ Cookie, + {ok, Node} = start_node(Name, Args, [{wait, false}]), + + %% Wait a while, then start boot server, and wait for node to start. + test_server:sleep(test_server:seconds(6)), + io:format("erl_boot_server:start_link([~p]).", [Host]), + {ok, BootPid} = erl_boot_server:start_link([Host]), + wait_really_started(Node, 25), + + %% Check loader argument, then cleanup. + {ok,[["inet"]]} = rpc:call(Node, init, get_argument, [loader]), + stop_node(Node), + unlink(BootPid), + exit(BootPid, kill), + ok. wait_really_started(Node, 0) -> test_server:fail({not_booted,Node}); @@ -249,8 +239,6 @@ multiple_slaves(doc) -> "verify that the boot server manages"]; multiple_slaves(Config) when is_list(Config) -> case os:type() of - vxworks -> - {comment, "VxWorks: tested separately"}; {ose,_} -> {comment, "OSE: multiple nodes not supported"}; _ -> diff --git a/lib/kernel/test/error_handler_SUITE.erl b/lib/kernel/test/error_handler_SUITE.erl new file mode 100644 index 0000000000..2a86d39b74 --- /dev/null +++ b/lib/kernel/test/error_handler_SUITE.erl @@ -0,0 +1,68 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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 +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(error_handler_SUITE). + +-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, + init_per_group/2,end_per_group/2, + undefined_function_handler/1]). + +%% Callback from error_handler. +-export(['$handle_undefined_function'/2]). + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [undefined_function_handler]. + +groups() -> + []. + +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + + +%%----------------------------------------------------------------- + +undefined_function_handler(_) -> + 42 = ?MODULE:forty_two(), + 42 = (id(?MODULE)):forty_two(), + {ok,{a,b,c}} = ?MODULE:one_arg({a,b,c}), + {ok,{a,b,c}} = (id(?MODULE)):one_arg({a,b,c}), + {'EXIT',{undef,[{?MODULE,undef_and_not_handled,[[1,2,3]],[]}|_]}} = + (catch ?MODULE:undef_and_not_handled([1,2,3])), + ok. + +'$handle_undefined_function'(forty_two, []) -> + 42; +'$handle_undefined_function'(one_arg, [Arg]) -> + {ok,Arg}; +'$handle_undefined_function'(Func, Args) -> + error_handler:raise_undef_exception(?MODULE, Func, Args). + +id(I) -> + I. diff --git a/lib/kernel/test/error_logger_warn_SUITE.erl b/lib/kernel/test/error_logger_warn_SUITE.erl index 265e1ae4c8..2bf467610e 100644 --- a/lib/kernel/test/error_logger_warn_SUITE.erl +++ b/lib/kernel/test/error_logger_warn_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2011. All Rights Reserved. +%% Copyright Ericsson AB 2003-2012. 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 @@ -310,7 +310,7 @@ nice_stop_node(Name) -> {nodedown,Name} -> ok end. -%rensa rd() f�re varje rapport-test s� man bara f�r en fil... +%clean out rd() before each report test in order to get only one file... clean_rd() -> {ok,L} = file:list_dir(rd()), lists:foreach(fun(F) -> diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index 848db06e82..c604e7073f 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -45,6 +45,8 @@ init_per_testcase/2, end_per_testcase/2, read_write_file/1, names/1]). -export([cur_dir_0/1, cur_dir_1/1, make_del_dir/1, + list_dir/1,list_dir_error/1, + untranslatable_names/1, untranslatable_names_error/1, pos1/1, pos2/1]). -export([close/1, consult1/1, path_consult/1, delete/1]). -export([ eval1/1, path_eval/1, script1/1, path_script/1, @@ -55,12 +57,13 @@ -export([rename/1, access/1, truncate/1, datasync/1, sync/1, read_write/1, pread_write/1, append/1, exclusive/1]). -export([ e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]). --export([otp_5814/1]). +-export([otp_5814/1, otp_10852/1]). -export([ read_not_really_compressed/1, read_compressed_cooked/1, read_compressed_cooked_binary/1, read_cooked_tar_problem/1, - write_compressed/1, compress_errors/1, catenated_gzips/1]). + write_compressed/1, compress_errors/1, catenated_gzips/1, + compress_async_crash/1]). -export([ make_link/1, read_link_info_for_non_link/1, symlinks/1]). @@ -84,6 +87,8 @@ -export([advise/1]). +-export([allocate/1]). + -export([standard_io/1,mini_server/1]). %% Debug exports @@ -107,16 +112,18 @@ all() -> {group, files}, delete, rename, names, {group, errors}, {group, compression}, {group, links}, copy, delayed_write, read_ahead, segment_read, segment_write, - ipread, pid2name, interleaved_read_write, otp_5814, + ipread, pid2name, interleaved_read_write, otp_5814, otp_10852, large_file, large_write, read_line_1, read_line_2, read_line_3, read_line_4, standard_io]. groups() -> - [{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1]}, + [{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1, + list_dir, list_dir_error, untranslatable_names, + untranslatable_names_error]}, {files, [], [{group, open}, {group, pos}, {group, file_info}, {group, consult}, {group, eval}, {group, script}, - truncate, sync, datasync, advise]}, + truncate, sync, datasync, advise, allocate]}, {open, [], [open1, old_modes, new_modes, path_open, close, access, read_write, pread_write, append, open_errors, @@ -133,7 +140,8 @@ groups() -> {compression, [], [read_compressed_cooked, read_compressed_cooked_binary, read_cooked_tar_problem, read_not_really_compressed, - write_compressed, compress_errors, catenated_gzips]}, + write_compressed, compress_errors, catenated_gzips, + compress_async_crash]}, {links, [], [make_link, read_link_info_for_non_link, symlinks]}]. @@ -228,7 +236,7 @@ mini_server(Parent) -> receive die -> ok; - {io_request,From,To,{put_chars,Data}} -> + {io_request,From,To,{put_chars,_Encoding,Data}} -> Parent ! {io_request,From,To,{put_chars,Data}}, From ! {io_reply, To, ok}, mini_server(Parent); @@ -492,8 +500,6 @@ cur_dir_1(Config) when is_list(Config) -> ?line case os:type() of {unix, _} -> ?line {error, enotsup} = ?FILE_MODULE:get_cwd("d:"); - vxworks -> - ?line {error, enotsup} = ?FILE_MODULE:get_cwd("d:"); {win32, _} -> win_cur_dir_1(Config) end, @@ -517,6 +523,148 @@ win_cur_dir_1(_Config) -> ok. + +%%% +%%% Test list_dir() on a non-existing pathname. +%%% + +list_dir_error(Config) -> + Priv = ?config(priv_dir, Config), + NonExisting = filename:join(Priv, "non-existing-dir"), + {error,enoent} = ?FILE_MODULE:list_dir(NonExisting), + ok. + +%%% +%%% Test list_dir() and list_dir_all(). +%%% + +list_dir(Config) -> + RootDir = ?config(priv_dir, Config), + TestDir = filename:join(RootDir, ?MODULE_STRING++"_list_dir"), + ?FILE_MODULE:make_dir(TestDir), + list_dir_1(TestDir, 42, []). + +list_dir_1(TestDir, 0, Sorted) -> + [ok = ?FILE_MODULE:delete(filename:join(TestDir, F)) || + F <- Sorted], + ok = ?FILE_MODULE:del_dir(TestDir); +list_dir_1(TestDir, Cnt, Sorted0) -> + Base = "file" ++ integer_to_list(Cnt), + Name = filename:join(TestDir, Base), + ok = ?FILE_MODULE:write_file(Name, Base), + Sorted = lists:merge([Base], Sorted0), + {ok,DirList0} = ?FILE_MODULE:list_dir(TestDir), + {ok,DirList1} = ?FILE_MODULE:list_dir_all(TestDir), + Sorted = lists:sort(DirList0), + Sorted = lists:sort(DirList1), + list_dir_1(TestDir, Cnt-1, Sorted). + +untranslatable_names(Config) -> + case no_untranslatable_names() of + true -> + {skip,"Not a problem on this OS"}; + false -> + untranslatable_names_1(Config) + end. + +untranslatable_names_1(Config) -> + {ok,OldCwd} = file:get_cwd(), + PrivDir = ?config(priv_dir, Config), + Dir = filename:join(PrivDir, "untranslatable_names"), + ok = file:make_dir(Dir), + Node = start_node(untranslatable_names, "+fnu"), + try + ok = file:set_cwd(Dir), + [ok = file:write_file(F, F) || {_,F} <- untranslatable_names()], + + ExpectedListDir0 = [unicode:characters_to_list(N, utf8) || + {utf8,N} <- untranslatable_names()], + ExpectedListDir = lists:sort(ExpectedListDir0), + io:format("ExpectedListDir: ~p\n", [ExpectedListDir]), + ExpectedListDir = call_and_sort(Node, file, list_dir, [Dir]), + + ExpectedListDirAll0 = [case Enc of + utf8 -> + unicode:characters_to_list(N, utf8); + latin1 -> + N + end || {Enc,N} <- untranslatable_names()], + ExpectedListDirAll = lists:sort(ExpectedListDirAll0), + io:format("ExpectedListDirAll: ~p\n", [ExpectedListDirAll]), + ExpectedListDirAll = call_and_sort(Node, file, list_dir_all, [Dir]) + after + catch test_server:stop_node(Node), + file:set_cwd(OldCwd), + [file:delete(F) || {_,F} <- untranslatable_names()], + file:del_dir(Dir) + end, + ok. + +untranslatable_names_error(Config) -> + case no_untranslatable_names() of + true -> + {skip,"Not a problem on this OS"}; + false -> + untranslatable_names_error_1(Config) + end. + +untranslatable_names_error_1(Config) -> + {ok,OldCwd} = file:get_cwd(), + PrivDir = ?config(priv_dir, Config), + Dir = filename:join(PrivDir, "untranslatable_names_error"), + ok = file:make_dir(Dir), + Node = start_node(untranslatable_names, "+fnue"), + try + ok = file:set_cwd(Dir), + [ok = file:write_file(F, F) || {_,F} <- untranslatable_names()], + + ExpectedListDir0 = [unicode:characters_to_list(N, utf8) || + {utf8,N} <- untranslatable_names()], + ExpectedListDir = lists:sort(ExpectedListDir0), + io:format("ExpectedListDir: ~p\n", [ExpectedListDir]), + {error,{no_translation,BadFile}} = + rpc:call(Node, file, list_dir, [Dir]), + true = lists:keymember(BadFile, 2, untranslatable_names()) + + after + catch test_server:stop_node(Node), + file:set_cwd(OldCwd), + [file:delete(F) || {_,F} <- untranslatable_names()], + file:del_dir(Dir) + end, + ok. + +untranslatable_names() -> + [{utf8,<<"abc">>}, + {utf8,<<"def">>}, + {utf8,<<"Lagerl",195,182,"f">>}, + {utf8,<<195,150,"stra Emterwik">>}, + {latin1,<<"M",229,"rbacka">>}, + {latin1,<<"V",228,"rmland">>}]. + +call_and_sort(Node, M, F, A) -> + {ok,Res} = rpc:call(Node, M, F, A), + lists:sort(Res). + +no_untranslatable_names() -> + case os:type() of + {unix,darwin} -> true; + {win32,_} -> true; + _ -> false + end. + +start_node(Name, Args) -> + [_,Host] = string:tokens(atom_to_list(node()), "@"), + ct:log("Trying to start ~w@~s~n", [Name,Host]), + case test_server:start_node(Name, peer, [{args,Args}]) of + {error,Reason} -> + test_server:fail(Reason); + {ok,Node} -> + ct:log("Node ~p started~n", [Node]), + Node + end. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1038,32 +1186,29 @@ file_info_basic_file(Config) when is_list(Config) -> file_info_basic_directory(suite) -> []; file_info_basic_directory(doc) -> []; file_info_basic_directory(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(5)), + Dog = test_server:timetrap(test_server:seconds(5)), %% Note: filename:join/1 removes any trailing slash, %% which is essential for ?FILE_MODULE:file_info/1 to work on %% platforms such as Windows95. - ?line RootDir = filename:join([?config(priv_dir, Config)]), + RootDir = filename:join([?config(priv_dir, Config)]), %% Test that the RootDir directory has the expected attributes. - ?line test_directory(RootDir, read_write), + test_directory(RootDir, read_write), %% Note that on Windows file systems, %% "/" or "c:/" are *NOT* directories. %% Therefore, test that ?FILE_MODULE:file_info/1 behaves as if they were %% directories. - ?line case os:type() of - {win32, _} -> - ?line test_directory("/", read_write), - ?line test_directory("c:/", read_write), - ?line test_directory("c:\\", read_write); - {unix, _} -> - ?line test_directory("/", read); - vxworks -> - %% Check is just done for owner - ?line test_directory("/", read_write) - end, - ?line test_server:timetrap_cancel(Dog). + case os:type() of + {win32, _} -> + ?line test_directory("/", read_write), + ?line test_directory("c:/", read_write), + ?line test_directory("c:\\", read_write); + {unix, _} -> + ?line test_directory("/", read) + end, + test_server:timetrap_cancel(Dog). test_directory(Name, ExpectedAccess) -> ?line {ok,#file_info{size=Size,type=Type,access=Access, @@ -1622,6 +1767,74 @@ advise(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +allocate(suite) -> []; +allocate(doc) -> "Tests that ?FILE_MODULE:allocate/3 at least doesn't crash."; +allocate(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line PrivDir = ?config(priv_dir, Config), + ?line Allocate = filename:join(PrivDir, + atom_to_list(?MODULE) + ++"_allocate.fil"), + + Line1 = "Hello\n", + Line2 = "World!\n", + + ?line {ok, Fd} = ?FILE_MODULE:open(Allocate, [write, binary]), + allocate_and_assert(Fd, 1, iolist_size([Line1, Line2])), + ?line ok = io:format(Fd, "~s", [Line1]), + ?line ok = io:format(Fd, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd), + + ?line {ok, Fd2} = ?FILE_MODULE:open(Allocate, [write, binary]), + allocate_and_assert(Fd2, 1, iolist_size(Line1)), + ?line ok = io:format(Fd2, "~s", [Line1]), + ?line ok = io:format(Fd2, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd2), + + ?line {ok, Fd3} = ?FILE_MODULE:open(Allocate, [write, binary]), + allocate_and_assert(Fd3, 1, iolist_size(Line1) + 1), + ?line ok = io:format(Fd3, "~s", [Line1]), + ?line ok = io:format(Fd3, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd3), + + ?line {ok, Fd4} = ?FILE_MODULE:open(Allocate, [write, binary]), + allocate_and_assert(Fd4, 1, 4 * iolist_size([Line1, Line2])), + ?line ok = io:format(Fd4, "~s", [Line1]), + ?line ok = io:format(Fd4, "~s", [Line2]), + ?line ok = ?FILE_MODULE:close(Fd4), + + ?line [] = flush(), + ?line test_server:timetrap_cancel(Dog), + ok. + +allocate_and_assert(Fd, Offset, Length) -> + % Just verify that calls to ?PRIM_FILE:allocate/3 don't crash or have + % any other negative side effect. We can't really asssert against a + % specific return value, because support for file space pre-allocation + % depends on the OS, OS version and underlying filesystem. + % + % The Linux kernel added support for fallocate() in version 2.6.23, + % which currently works only for the ext4, ocfs2, xfs and btrfs file + % systems. posix_fallocate() is available in glibc as of version + % 2.1.94, but it was buggy until glibc version 2.7. + % + % Mac OS X, as of version 10.3, supports the fcntl operation F_PREALLOCATE. + % + % Solaris supports posix_fallocate() but only for the UFS file system + % apparently (not supported for ZFS). + % + % FreeBSD 9.0 is the first FreeBSD release supporting posix_fallocate(). + % + % For Windows there's apparently no way to pre-allocate file space, at + % least with same semantics as posix_fallocate(), fallocate() and + % fcntl F_PREALLOCATE. + Result = ?FILE_MODULE:allocate(Fd, Offset, Length), + case os:type() of + {win32, _} -> + ?line {error, enotsup} = Result; + _ -> + ?line _ = Result + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1784,9 +1997,7 @@ e_delete(Config) when is_list(Config) -> Base, #file_info {mode=8#600}); {win32, _} -> %% Remove a character device. - ?line {error, eacces} = ?FILE_MODULE:delete("nul"); - vxworks -> - ok + ?line {error, eacces} = ?FILE_MODULE:delete("nul") end, ?line [] = flush(), @@ -1801,148 +2012,133 @@ e_delete(Config) when is_list(Config) -> e_rename(suite) -> []; e_rename(doc) -> []; e_rename(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "Windriver: dosFs must be fixed first!"}; - _ -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line RootDir = ?config(priv_dir, Config), - ?line Base = filename:join(RootDir, - atom_to_list(?MODULE)++"_e_rename"), - ?line ok = ?FILE_MODULE:make_dir(Base), - - %% Create an empty directory. - ?line EmptyDir = filename:join(Base, "empty_dir"), - ?line ok = ?FILE_MODULE:make_dir(EmptyDir), - - %% Create a non-empty directory. - ?line NonEmptyDir = filename:join(Base, "non_empty_dir"), - ?line ok = ?FILE_MODULE:make_dir(NonEmptyDir), - ?line ok = ?FILE_MODULE:write_file( - filename:join(NonEmptyDir, "a_file"), - "hello\n"), - - %% Create another non-empty directory. - ?line ADirectory = filename:join(Base, "a_directory"), - ?line ok = ?FILE_MODULE:make_dir(ADirectory), - ?line ok = ?FILE_MODULE:write_file( - filename:join(ADirectory, "a_file"), - "howdy\n\n"), - - %% Create a data file. - ?line File = filename:join(Base, "just_a_file"), - ?line ok = ?FILE_MODULE:write_file(File, "anything goes\n\n"), - - %% Move an existing directory to a non-empty directory. - ?line {error, eexist} = - ?FILE_MODULE:rename(ADirectory, NonEmptyDir), - - %% Move a root directory. - ?line {error, einval} = ?FILE_MODULE:rename("/", "arne"), - - %% Move Base into Base/new_name. - ?line {error, einval} = - ?FILE_MODULE:rename(Base, filename:join(Base, "new_name")), - - %% Overwrite a directory with a file. - ?line expect({error, eexist}, %FreeBSD (?) - {error, eisdir}, - ?FILE_MODULE:rename(File, EmptyDir)), - ?line expect({error, eexist}, %FreeBSD (?) - {error, eisdir}, - ?FILE_MODULE:rename(File, NonEmptyDir)), - - %% Move a non-existing file. - ?line NonExistingFile = - filename:join(Base, "non_existing_file"), - ?line {error, enoent} = - ?FILE_MODULE:rename(NonExistingFile, NonEmptyDir), - - %% Overwrite a file with a directory. - ?line expect({error, eexist}, %FreeBSD (?) - {error, enotdir}, - ?FILE_MODULE:rename(ADirectory, File)), - - %% Move a file to another filesystem. - %% XXX - This test case is bogus. We cannot be guaranteed that - %% the source and destination are on - %% different filesystems. - %% - %% XXX - Gross hack! - ?line Comment = - case os:type() of - {unix, _} -> - OtherFs = "/tmp", - ?line NameOnOtherFs = - filename:join(OtherFs, filename:basename(File)), - ?line {ok, Com} = - case ?FILE_MODULE:rename(File, NameOnOtherFs) of - {error, exdev} -> - %% The file could be in - %% the same filesystem! - {ok, ok}; - ok -> - {ok, {comment, - "Moving between filesystems " - "suceeded, files are probably " - "in the same filesystem!"}}; - {error, eperm} -> - {ok, {comment, "SBS! You don't " - "have the permission to do " - "this test!"}}; - Else -> - Else - end, - Com; - {win32, _} -> - %% At least Windows NT can - %% successfully move a file to - %% another drive. - ok - end, - ?line [] = flush(), - ?line test_server:timetrap_cancel(Dog), - Comment - end. + Dog = test_server:timetrap(test_server:seconds(10)), + RootDir = ?config(priv_dir, Config), + Base = filename:join(RootDir, + atom_to_list(?MODULE)++"_e_rename"), + ok = ?FILE_MODULE:make_dir(Base), + + %% Create an empty directory. + EmptyDir = filename:join(Base, "empty_dir"), + ok = ?FILE_MODULE:make_dir(EmptyDir), + + %% Create a non-empty directory. + NonEmptyDir = filename:join(Base, "non_empty_dir"), + ok = ?FILE_MODULE:make_dir(NonEmptyDir), + ok = ?FILE_MODULE:write_file( + filename:join(NonEmptyDir, "a_file"), + "hello\n"), + + %% Create another non-empty directory. + ADirectory = filename:join(Base, "a_directory"), + ok = ?FILE_MODULE:make_dir(ADirectory), + ok = ?FILE_MODULE:write_file( + filename:join(ADirectory, "a_file"), + "howdy\n\n"), + + %% Create a data file. + File = filename:join(Base, "just_a_file"), + ok = ?FILE_MODULE:write_file(File, "anything goes\n\n"), + + %% Move an existing directory to a non-empty directory. + {error, eexist} = ?FILE_MODULE:rename(ADirectory, NonEmptyDir), + + %% Move a root directory. + {error, einval} = ?FILE_MODULE:rename("/", "arne"), + + %% Move Base into Base/new_name. + {error, einval} = + ?FILE_MODULE:rename(Base, filename:join(Base, "new_name")), + + %% Overwrite a directory with a file. + expect({error, eexist}, %FreeBSD (?) + {error, eisdir}, + ?FILE_MODULE:rename(File, EmptyDir)), + expect({error, eexist}, %FreeBSD (?) + {error, eisdir}, + ?FILE_MODULE:rename(File, NonEmptyDir)), + + %% Move a non-existing file. + NonExistingFile = filename:join(Base, "non_existing_file"), + {error, enoent} = ?FILE_MODULE:rename(NonExistingFile, NonEmptyDir), + + %% Overwrite a file with a directory. + expect({error, eexist}, %FreeBSD (?) + {error, enotdir}, + ?FILE_MODULE:rename(ADirectory, File)), + + %% Move a file to another filesystem. + %% XXX - This test case is bogus. We cannot be guaranteed that + %% the source and destination are on + %% different filesystems. + %% + %% XXX - Gross hack! + Comment = case os:type() of + {unix, _} -> + OtherFs = "/tmp", + NameOnOtherFs = filename:join(OtherFs, filename:basename(File)), + {ok, Com} = case ?FILE_MODULE:rename(File, NameOnOtherFs) of + {error, exdev} -> + %% The file could be in + %% the same filesystem! + {ok, ok}; + ok -> + {ok, {comment, + "Moving between filesystems " + "suceeded, files are probably " + "in the same filesystem!"}}; + {error, eperm} -> + {ok, {comment, "SBS! You don't " + "have the permission to do " + "this test!"}}; + Else -> + Else + end, + Com; + {win32, _} -> + %% At least Windows NT can + %% successfully move a file to + %% another drive. + ok + end, + [] = flush(), + test_server:timetrap_cancel(Dog), + Comment. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% e_make_dir(suite) -> []; e_make_dir(doc) -> []; e_make_dir(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line RootDir = ?config(priv_dir, Config), - ?line Base = filename:join(RootDir, - atom_to_list(?MODULE)++"_e_make_dir"), - ?line ok = ?FILE_MODULE:make_dir(Base), + Dog = test_server:timetrap(test_server:seconds(10)), + RootDir = ?config(priv_dir, Config), + Base = filename:join(RootDir, + atom_to_list(?MODULE)++"_e_make_dir"), + ok = ?FILE_MODULE:make_dir(Base), %% A component of the path does not exist. - ?line {error, enoent} = - ?FILE_MODULE:make_dir(filename:join([Base, "a", "b"])), + {error, enoent} = ?FILE_MODULE:make_dir(filename:join([Base, "a", "b"])), %% Use a path-name with a non-directory component. - ?line Afile = filename:join(Base, "a_directory"), - ?line ok = ?FILE_MODULE:write_file(Afile, "hello\n"), - ?line case ?FILE_MODULE:make_dir( - filename:join(Afile, "another_directory")) of - {error, enotdir} -> io:format("Result: enotdir"); - {error, enoent} -> io:format("Result: enoent") - end, + Afile = filename:join(Base, "a_directory"), + ok = ?FILE_MODULE:write_file(Afile, "hello\n"), + case ?FILE_MODULE:make_dir( + filename:join(Afile, "another_directory")) of + {error, enotdir} -> io:format("Result: enotdir"); + {error, enoent} -> io:format("Result: enoent") + end, %% No permission (on Unix only). case os:type() of {unix, _} -> - ?line ?FILE_MODULE:write_file_info(Base, #file_info {mode=0}), - ?line {error, eacces} = - ?FILE_MODULE:make_dir(filename:join(Base, "xxxx")), - ?line ?FILE_MODULE:write_file_info( + ?FILE_MODULE:write_file_info(Base, #file_info {mode=0}), + {error, eacces} = ?FILE_MODULE:make_dir(filename:join(Base, "xxxx")), + ?FILE_MODULE:write_file_info( Base, #file_info {mode=8#600}); {win32, _} -> - ok; - vxworks -> ok end, - ?line test_server:timetrap_cancel(Dog), + test_server:timetrap_cancel(Dog), ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1950,57 +2146,50 @@ e_make_dir(Config) when is_list(Config) -> e_del_dir(suite) -> []; e_del_dir(doc) -> []; e_del_dir(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line RootDir = ?config(priv_dir, Config), - ?line Base = test_server:temp_name(filename:join(RootDir, "e_del_dir")), - ?line io:format("Base: ~p", [Base]), - ?line ok = ?FILE_MODULE:make_dir(Base), + Dog = test_server:timetrap(test_server:seconds(10)), + RootDir = ?config(priv_dir, Config), + Base = test_server:temp_name(filename:join(RootDir, "e_del_dir")), + io:format("Base: ~p", [Base]), + ok = ?FILE_MODULE:make_dir(Base), %% Delete a non-existent directory. - ?line {error, enoent} = + {error, enoent} = ?FILE_MODULE:del_dir(filename:join(Base, "non_existing")), %% Use a path-name with a non-directory component. - ?line Afile = filename:join(Base, "a_directory"), - ?line ok = ?FILE_MODULE:write_file(Afile, "hello\n"), - ?line {error, E1} = - expect({error, enotdir}, {error, enoent}, - ?FILE_MODULE:del_dir( - filename:join(Afile, "another_directory"))), - ?line io:format("Result: ~p", [E1]), + Afile = filename:join(Base, "a_directory"), + ok = ?FILE_MODULE:write_file(Afile, "hello\n"), + {error, E1} = expect({error, enotdir}, {error, enoent}, + ?FILE_MODULE:del_dir( + filename:join(Afile, "another_directory"))), + io:format("Result: ~p", [E1]), %% Delete a non-empty directory. - ?line {error, E2} = - expect({error, enotempty}, {error, eexist}, {error, eacces}, + {error, E2} = expect({error, enotempty}, {error, eexist}, {error, eacces}, ?FILE_MODULE:del_dir(Base)), - ?line io:format("Result: ~p", [E2]), + io:format("Result: ~p", [E2]), %% Remove the current directory. - ?line {error, E3} = - expect({error, einval}, + {error, E3} = expect({error, einval}, {error, eperm}, % Linux and DUX {error, eacces}, {error, ebusy}, ?FILE_MODULE:del_dir(".")), - ?line io:format("Result: ~p", [E3]), + io:format("Result: ~p", [E3]), %% No permission. case os:type() of {unix, _} -> - ?line ADirectory = filename:join(Base, "no_perm"), - ?line ok = ?FILE_MODULE:make_dir(ADirectory), - ?line ?FILE_MODULE:write_file_info( - Base, #file_info {mode=0}), - ?line {error, eacces} = ?FILE_MODULE:del_dir(ADirectory), - ?line ?FILE_MODULE:write_file_info( - Base, #file_info {mode=8#600}); + ADirectory = filename:join(Base, "no_perm"), + ok = ?FILE_MODULE:make_dir(ADirectory), + ?FILE_MODULE:write_file_info( Base, #file_info {mode=0}), + {error, eacces} = ?FILE_MODULE:del_dir(ADirectory), + ?FILE_MODULE:write_file_info( Base, #file_info {mode=8#600}); {win32, _} -> - ok; - vxworks -> ok end, - ?line [] = flush(), - ?line test_server:timetrap_cancel(Dog), + [] = flush(), + test_server:timetrap_cancel(Dog), ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2271,6 +2460,57 @@ compress_errors(Config) when is_list(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +compress_async_crash(suite) -> []; +compress_async_crash(doc) -> []; +compress_async_crash(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line Path = filename:join(DataDir, "test.gz"), + ExpectedData = <<"qwerty">>, + + ?line _ = ?FILE_MODULE:delete(Path), + ?line {ok, Fd} = ?FILE_MODULE:open(Path, [write, binary, compressed]), + ?line ok = ?FILE_MODULE:write(Fd, ExpectedData), + ?line ok = ?FILE_MODULE:close(Fd), + + % Test that when using async thread pool, the emulator doesn't crash + % when the efile port driver is stopped while a compressed file operation + % is in progress (being carried by an async thread). + ?line ok = compress_async_crash_loop(10000, Path, ExpectedData), + ?line ok = ?FILE_MODULE:delete(Path), + ok. + +compress_async_crash_loop(0, _Path, _ExpectedData) -> + ok; +compress_async_crash_loop(N, Path, ExpectedData) -> + Parent = self(), + {Pid, Ref} = spawn_monitor( + fun() -> + ?line {ok, Fd} = ?FILE_MODULE:open( + Path, [read, compressed, raw, binary]), + Len = byte_size(ExpectedData), + Parent ! {self(), continue}, + ?line {ok, ExpectedData} = ?FILE_MODULE:read(Fd, Len), + ?line ok = ?FILE_MODULE:close(Fd), + receive foobar -> ok end + end), + receive + {Pid, continue} -> + exit(Pid, shutdown), + receive + {'DOWN', Ref, _, _, Reason} -> + ?line shutdown = Reason + end; + {'DOWN', Ref, _, _, Reason2} -> + test_server:fail({worker_exited, Reason2}) + after 60000 -> + exit(Pid, shutdown), + erlang:demonitor(Ref, [flush]), + test_server:fail(worker_timeout) + end, + compress_async_crash_loop(N - 1, Path, ExpectedData). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + altname(doc) -> "Test the file:altname/1 function"; altname(suite) -> @@ -2359,6 +2599,7 @@ symlinks(suite) -> []; symlinks(Config) when is_list(Config) -> ?line Dog = test_server:timetrap(test_server:seconds(10)), ?line {error, _} = ?FILE_MODULE:read_link(lists:duplicate(10000,$a)), + {error, _} = ?FILE_MODULE:read_link_all(lists:duplicate(10000,$a)), ?line RootDir = ?config(priv_dir, Config), ?line NewDir = filename:join(RootDir, atom_to_list(?MODULE) @@ -2382,6 +2623,7 @@ symlinks(Config) when is_list(Config) -> ?line {ok, Info2} = ?FILE_MODULE:read_link_info(Alias), ?line #file_info{links=1, type=symlink} = Info2, ?line {ok, Name} = ?FILE_MODULE:read_link(Alias), + {ok, Name} = ?FILE_MODULE:read_link_all(Alias), ok end, @@ -2564,147 +2806,123 @@ delayed_write(doc) -> ["Tests the file open option {delayed_write, Size, Delay}"]; delayed_write(Config) when is_list(Config) -> - ?line Dog = ?t:timetrap(?t:seconds(20)), - %% - ?line RootDir = ?config(priv_dir, Config), - ?line File = filename:join(RootDir, - atom_to_list(?MODULE)++"_delayed_write.txt"), - ?line Data1 = "asdfghjkl", - ?line Data2 = "qwertyuio", - ?line Data3 = "zxcvbnm,.", - ?line Size = length(Data1), - ?line Size = length(Data2), - ?line Size = length(Data3), - ?line Data1Data1 = Data1++Data1, - ?line Data1Data1Data1 = Data1Data1++Data1, - ?line Data1Data1Data1Data1 = Data1Data1++Data1Data1, + Dog = ?t:timetrap(?t:seconds(20)), + + RootDir = ?config(priv_dir, Config), + File = filename:join(RootDir, + atom_to_list(?MODULE)++"_delayed_write.txt"), + Data1 = "asdfghjkl", + Data2 = "qwertyuio", + Data3 = "zxcvbnm,.", + Size = length(Data1), + Size = length(Data2), + Size = length(Data3), + Data1Data1 = Data1++Data1, + Data1Data1Data1 = Data1Data1++Data1, + Data1Data1Data1Data1 = Data1Data1++Data1Data1, %% %% Test caching and normal close of non-raw file - ?line {ok, Fd1} = + {ok, Fd1} = ?FILE_MODULE:open(File, [write, {delayed_write, Size+1, 2000}]), - ?line ok = ?FILE_MODULE:write(Fd1, Data1), - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line {ok, Fd2} = ?FILE_MODULE:open(File, [read]), - ?line case os:type() of - vxworks -> - io:format("Line ~p skipped on vxworks", [?LINE]); - _ -> - ?line eof = ?FILE_MODULE:read(Fd2, 1) - end, - ?line ok = ?FILE_MODULE:write(Fd1, Data1), % Data flush on size - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line {ok, Data1Data1} = ?FILE_MODULE:pread(Fd2, bof, 2*Size+1), - ?line ok = ?FILE_MODULE:write(Fd1, Data1), - ?line ?t:sleep(3000), % Wait until data flush on timeout - ?line {ok, Data1Data1Data1} = ?FILE_MODULE:pread(Fd2, bof, 3*Size+1), - ?line ok = ?FILE_MODULE:write(Fd1, Data1), - ?line ok = ?FILE_MODULE:close(Fd1), % Data flush on close - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line {ok, Data1Data1Data1Data1} = ?FILE_MODULE:pread(Fd2, bof, 4*Size+1), - ?line ok = ?FILE_MODULE:close(Fd2), + ok = ?FILE_MODULE:write(Fd1, Data1), + ?t:sleep(1000), % Just in case the file system is slow + {ok, Fd2} = ?FILE_MODULE:open(File, [read]), + eof = ?FILE_MODULE:read(Fd2, 1), + ok = ?FILE_MODULE:write(Fd1, Data1), % Data flush on size + ?t:sleep(1000), % Just in case the file system is slow + {ok, Data1Data1} = ?FILE_MODULE:pread(Fd2, bof, 2*Size+1), + ok = ?FILE_MODULE:write(Fd1, Data1), + ?t:sleep(3000), % Wait until data flush on timeout + {ok, Data1Data1Data1} = ?FILE_MODULE:pread(Fd2, bof, 3*Size+1), + ok = ?FILE_MODULE:write(Fd1, Data1), + ok = ?FILE_MODULE:close(Fd1), % Data flush on close + ?t:sleep(1000), % Just in case the file system is slow + {ok, Data1Data1Data1Data1} = ?FILE_MODULE:pread(Fd2, bof, 4*Size+1), + ok = ?FILE_MODULE:close(Fd2), %% %% Test implicit close through exit by file owning process, %% raw file, default parameters. - ?line Parent = self(), - ?line Fun = - fun () -> - Child = self(), - Test = - fun () -> - ?line {ok, Fd} = - ?FILE_MODULE:open(File, - [raw, write, - delayed_write]), - ?line ok = ?FILE_MODULE:write(Fd, Data1), - ?line Parent ! {Child, wrote}, - ?line receive - {Parent, continue, Reason} -> - {ok, Reason} - end - end, - case (catch Test()) of - {ok, Reason} -> - exit(Reason); - Unknown -> - exit({Unknown, get(test_server_loc)}) - end - end, - ?line Child1 = spawn(Fun), - ?line Mref1 = erlang:monitor(process, Child1), - ?line receive - {Child1, wrote} -> - ok; - {'DOWN', Mref1, _, _, _} = Down1a -> - ?t:fail(Down1a) - end, - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line {ok, Fd3} = ?FILE_MODULE:open(File, [read]), - ?line case os:type() of - vxworks -> - io:format("Line ~p skipped on vxworks", [?LINE]); - _ -> - ?line eof = ?FILE_MODULE:read(Fd3, 1) - end, - ?line Child1 ! {Parent, continue, normal}, - ?line receive - {'DOWN', Mref1, process, Child1, normal} -> - ok; - {'DOWN', Mref1, _, _, _} = Down1b -> - ?t:fail(Down1b) - end, - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line {ok, Data1} = ?FILE_MODULE:pread(Fd3, bof, Size+1), - ?line ok = ?FILE_MODULE:close(Fd3), + Parent = self(), + Fun = fun() -> + Child = self(), + Test = + fun () -> + {ok, Fd} = ?FILE_MODULE:open(File, + [raw, write, delayed_write]), + ok = ?FILE_MODULE:write(Fd, Data1), + Parent ! {Child, wrote}, + receive + {Parent, continue, Reason} -> + {ok, Reason} + end + end, + case (catch Test()) of + {ok, Reason} -> exit(Reason); + Unknown -> + exit({Unknown, get(test_server_loc)}) + end + end, + Child1 = spawn(Fun), + Mref1 = erlang:monitor(process, Child1), + receive + {Child1, wrote} -> + ok; + {'DOWN', Mref1, _, _, _} = Down1a -> + ?t:fail(Down1a) + end, + ?t:sleep(1000), % Just in case the file system is slow + {ok, Fd3} = ?FILE_MODULE:open(File, [read]), + eof = ?FILE_MODULE:read(Fd3, 1), + Child1 ! {Parent, continue, normal}, + receive + {'DOWN', Mref1, process, Child1, normal} -> + ok; + {'DOWN', Mref1, _, _, _} = Down1b -> + ?t:fail(Down1b) + end, + ?t:sleep(1000), % Just in case the file system is slow + {ok, Data1} = ?FILE_MODULE:pread(Fd3, bof, Size+1), + ok = ?FILE_MODULE:close(Fd3), %% %% The same again, but this time with reason 'kill'. - ?line Child2 = spawn(Fun), - ?line Mref2 = erlang:monitor(process, Child2), - ?line receive - {Child2, wrote} -> - ok; - {'DOWN', Mref2, _, _, _} = Down2a -> - ?t:fail(Down2a) - end, - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line {ok, Fd4} = ?FILE_MODULE:open(File, [read]), - ?line case os:type() of - vxworks -> - io:format("Line ~p skipped on vxworks", [?LINE]); - _ -> - ?line eof = ?FILE_MODULE:read(Fd4, 1) - end, - ?line Child2 ! {Parent, continue, kill}, - ?line receive - {'DOWN', Mref2, process, Child2, kill} -> - ok; - {'DOWN', Mref2, _, _, _} = Down2b -> - ?t:fail(Down2b) - end, - ?line ?t:sleep(1000), % Just in case the file system is slow - ?line eof = ?FILE_MODULE:pread(Fd4, bof, 1), - ?line ok = ?FILE_MODULE:close(Fd4), + Child2 = spawn(Fun), + Mref2 = erlang:monitor(process, Child2), + receive + {Child2, wrote} -> + ok; + {'DOWN', Mref2, _, _, _} = Down2a -> + ?t:fail(Down2a) + end, + ?t:sleep(1000), % Just in case the file system is slow + {ok, Fd4} = ?FILE_MODULE:open(File, [read]), + eof = ?FILE_MODULE:read(Fd4, 1), + Child2 ! {Parent, continue, kill}, + receive + {'DOWN', Mref2, process, Child2, kill} -> + ok; + {'DOWN', Mref2, _, _, _} = Down2b -> + ?t:fail(Down2b) + end, + ?t:sleep(1000), % Just in case the file system is slow + eof = ?FILE_MODULE:pread(Fd4, bof, 1), + ok = ?FILE_MODULE:close(Fd4), %% %% Test if file position works with delayed_write - ?line {ok, Fd5} = ?FILE_MODULE:open(File, [raw, read, write, - delayed_write]), - ?line ok = ?FILE_MODULE:truncate(Fd5), - ?line ok = ?FILE_MODULE:write(Fd5, [Data1|Data2]), - ?line {ok, 0} = ?FILE_MODULE:position(Fd5, bof), - ?line ok = ?FILE_MODULE:write(Fd5, [Data3]), - ?line {ok, Data2} = ?FILE_MODULE:read(Fd5, Size+1), - ?line {ok, 0} = ?FILE_MODULE:position(Fd5, bof), - ?line Data3Data2 = Data3++Data2, - ?line {ok, Data3Data2} = ?FILE_MODULE:read(Fd5, 2*Size+1), - ?line ok = ?FILE_MODULE:close(Fd5), + {ok, Fd5} = ?FILE_MODULE:open(File, [raw, read, write, + delayed_write]), + ok = ?FILE_MODULE:truncate(Fd5), + ok = ?FILE_MODULE:write(Fd5, [Data1|Data2]), + {ok, 0} = ?FILE_MODULE:position(Fd5, bof), + ok = ?FILE_MODULE:write(Fd5, [Data3]), + {ok, Data2} = ?FILE_MODULE:read(Fd5, Size+1), + {ok, 0} = ?FILE_MODULE:position(Fd5, bof), + Data3Data2 = Data3++Data2, + {ok, Data3Data2} = ?FILE_MODULE:read(Fd5, 2*Size+1), + ok = ?FILE_MODULE:close(Fd5), %% - ?line [] = flush(), - ?line ?t:timetrap_cancel(Dog), - ?line case os:type() of - vxworks -> - {comment, "Some lines skipped on vxworks"}; - _ -> - ok - end. + [] = flush(), + ?t:timetrap_cancel(Dog), + ok. pid2name(doc) -> "Tests file:pid2name/1."; @@ -3300,6 +3518,49 @@ otp_5814(Config) when is_list(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +otp_10852(suite) -> + []; +otp_10852(doc) -> + ["OTP-10852. +fnu and latin1 filenames"]; +otp_10852(Config) when is_list(Config) -> + Node = start_node(erl_pp_helper, "+fnu"), + Dir = ?config(priv_dir, Config), + B = filename:join(Dir, <<"\xE4">>), + ok = rpc_call(Node, get_cwd, [B]), + {error, no_translation} = rpc_call(Node, set_cwd, [B]), + ok = rpc_call(Node, delete, [B]), + ok = rpc_call(Node, rename, [B, B]), + ok = rpc_call(Node, read_file_info, [B]), + ok = rpc_call(Node, read_link_info, [B]), + ok = rpc_call(Node, read_link, [B]), + ok = rpc_call(Node, write_file_info, [B,#file_info{}]), + ok = rpc_call(Node, list_dir, [B]), + ok = rpc_call(Node, list_dir_all, [B]), + ok = rpc_call(Node, read_file, [B]), + ok = rpc_call(Node, make_link, [B,B]), + ok = rpc_call(Node, make_symlink, [B,B]), + ok = rpc_call(Node, delete, [B]), + ok = rpc_call(Node, make_dir, [B]), + ok = rpc_call(Node, del_dir, [B]), + ok = rpc_call(Node, write_file, [B,B]), + {ok, Fd} = rpc_call(Node, open, [B,[read]]), + ok = rpc_call(Node, close, [Fd]), + {ok,0} = rpc_call(Node, copy, [B,B]), + {ok, Fd2, B} = rpc_call(Node, path_open, [["."], B, [read]]), + ok = rpc_call(Node, close, [Fd2]), + true = test_server:stop_node(Node), + ok. + +rpc_call(N, F, As) -> + case rpc:call(N, ?FILE_MODULE, F, As) of + {error, enotsup} -> ok; + {error, enoent} -> ok; + {error, badarg} -> ok; + Else -> Else + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + large_file(suite) -> []; large_file(doc) -> diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl index 3aa010a708..a6728564e4 100644 --- a/lib/kernel/test/file_name_SUITE.erl +++ b/lib/kernel/test/file_name_SUITE.erl @@ -1,8 +1,9 @@ -module(file_name_SUITE). +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -336,12 +337,12 @@ check_normal(Mod) -> check_icky(Mod) -> {ok,Dir} = Mod:get_cwd(), try - ?line true=(length("���") =:= 3), + ?line true=(length("åäö") =:= 3), ?line UniMode = file:native_name_encoding() =/= latin1, ?line make_icky_dir(Mod), - ?line {ok, L0} = Mod:list_dir("."), + {ok, L0} = Mod:list_dir_all("."), ?line L1 = lists:sort(L0), - io:format("~p ~p~n",[L1,list(icky_dir())]), + io:format("~p~n~p~n~n",[L1,lists:sort(list(icky_dir()))]), ?line L1 = lists:sort(convlist(list(icky_dir()))), ?line {ok,D2} = Mod:get_cwd(), ?line true = is_list(D2), @@ -356,66 +357,59 @@ check_icky(Mod) -> ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,icky_dir()))} || {T,S,Targ} <- icky_dir(), T =:= symlink ], ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], - ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], - ?line chk_cre_dir(Mod,[{directory,"���_dir",icky_dir()}]), + [ {ok, Targ} = fixlink(Mod:read_link_all(SymL)) || + {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,"åäö_dir",icky_dir()}]), ?line {ok,BeginAt} = Mod:get_cwd(), ?line true = is_list(BeginAt), - ?line {error,enoent} = Mod:set_cwd("��_dir"), - ?line ok = Mod:set_cwd("���_dir"), + ?line {error,enoent} = Mod:set_cwd("åä_dir"), + ?line ok = Mod:set_cwd("åäö_dir"), ?line {ok, NowAt} = Mod:get_cwd(), ?line true = is_list(NowAt), ?line true = BeginAt =/= NowAt, ?line ok = Mod:set_cwd(".."), ?line {ok,BeginAt} = Mod:get_cwd(), - ?line rm_r2(Mod,"���_dir"), - {OS,TYPE} = os:type(), + ?line rm_r2(Mod,"åäö_dir"), + {OS,_} = os:type(), % Check that treat_icky really converts to the same as the OS case UniMode of true -> - ?line chk_cre_dir(Mod,[{directory,"���_dir",[]}]), - ?line ok = Mod:set_cwd("���_dir"), - ?line ok = Mod:write_file(<<"���">>,<<"hello">>), - ?line Treated = treat_icky(<<"���">>), - ?line {ok,[Treated]} = Mod:list_dir("."), - ?line ok = Mod:delete(<<"���">>), + ?line chk_cre_dir(Mod,[{directory,"åäö_dir",[]}]), + ?line ok = Mod:set_cwd("åäö_dir"), + ?line ok = Mod:write_file(<<"ååå">>,<<"hello">>), + ?line Treated = treat_icky(<<"ååå">>), + {ok,[Treated]} = Mod:list_dir_all("."), + ?line ok = Mod:delete(<<"ååå">>), ?line {ok,[]} = Mod:list_dir("."), ?line ok = Mod:set_cwd(".."), - ?line rm_r2(Mod,"���_dir"); + ?line rm_r2(Mod,"åäö_dir"); false -> ok end, - ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"���_dir">>),icky_dir()}]), + ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"åäö_dir">>),icky_dir()}]), if UniMode and (OS =/= win32) -> - ?line {error,enoent} = Mod:set_cwd("���_dir"); + ?line {error,enoent} = Mod:set_cwd("åäö_dir"); true -> ok end, - ?line ok = Mod:set_cwd(treat_icky(<<"���_dir">>)), - ?line {ok, NowAt2} = Mod:get_cwd(), - io:format("~p~n",[NowAt2]), - % Cannot create raw unicode-breaking filenames on windows or macos - ?line true = ((((not UniMode) or (OS =:= win32) or (TYPE=:=darwin)) and is_list(NowAt2)) orelse ((UniMode) and is_binary(NowAt2))), - ?line true = BeginAt =/= NowAt2, - ?line ok = Mod:set_cwd(".."), ?line {ok,BeginAt} = Mod:get_cwd(), - ?line rm_r2(Mod,conv(treat_icky(<<"���_dir">>))), case has_links() of true -> - ?line ok = Mod:make_link("fil1","nisse�"), - ?line {ok, <<"fil1">>} = Mod:read_file("nisse�"), - ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse�"), - ?line ok = Mod:delete("nisse�"), - ?line ok = Mod:make_link("fil1",treat_icky(<<"nisse�">>)), - ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisse�">>)), - ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisse�">>)), - ?line ok = Mod:delete(treat_icky(<<"nisse�">>)), + ?line ok = Mod:make_link("fil1","nisseö"), + ?line {ok, <<"fil1">>} = Mod:read_file("nisseö"), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisseö"), + ?line ok = Mod:delete("nisseö"), + ?line ok = Mod:make_link("fil1",treat_icky(<<"nisseö">>)), + ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisseö">>)), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisseö">>)), + ?line ok = Mod:delete(treat_icky(<<"nisseö">>)), ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), - ?line {error,enoent} = Mod:read_file("nisse�"), - ?line {error,enoent} = Mod:read_link_info("nisse�"), - ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisse�">>)), - ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisse�">>)); + ?line {error,enoent} = Mod:read_file("nisseö"), + ?line {error,enoent} = Mod:read_link_info("nisseö"), + ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisseö">>)), + ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisseö">>)); false -> ok end, @@ -430,42 +424,42 @@ check_icky(Mod) -> ?line {ok, BC} = Mod:read(FD,1024), ?line ok = file:close(FD) end || {regular,Name,Content} <- icky_dir() ], - ?line Mod:rename("���2","���_fil1"), - ?line {ok, <<"���2">>} = Mod:read_file("���_fil1"), - ?line {error,enoent} = Mod:read_file("���2"), - ?line Mod:rename("���_fil1","���2"), - ?line {ok, <<"���2">>} = Mod:read_file("���2"), - ?line {error,enoent} = Mod:read_file("���_fil1"), + ?line Mod:rename("åäö2","åäö_fil1"), + ?line {ok, <<"åäö2">>} = Mod:read_file("åäö_fil1"), + ?line {error,enoent} = Mod:read_file("åäö2"), + ?line Mod:rename("åäö_fil1","åäö2"), + ?line {ok, <<"åäö2">>} = Mod:read_file("åäö2"), + ?line {error,enoent} = Mod:read_file("åäö_fil1"), - ?line Mod:rename("���2",treat_icky(<<"���_fil1">>)), - ?line {ok, <<"���2">>} = Mod:read_file(treat_icky(<<"���_fil1">>)), + ?line Mod:rename("åäö2",treat_icky(<<"åäö_fil1">>)), + ?line {ok, <<"åäö2">>} = Mod:read_file(treat_icky(<<"åäö_fil1">>)), if UniMode and (OS =/= win32) -> - {error,enoent} = Mod:read_file("���_fil1"); + {error,enoent} = Mod:read_file("åäö_fil1"); true -> ok end, - ?line {error,enoent} = Mod:read_file("���2"), - ?line Mod:rename(treat_icky(<<"���_fil1">>),"���2"), - ?line {ok, <<"���2">>} = Mod:read_file("���2"), - ?line {error,enoent} = Mod:read_file("���_fil1"), - ?line {error,enoent} = Mod:read_file(treat_icky(<<"���_fil1">>)), + ?line {error,enoent} = Mod:read_file("åäö2"), + ?line Mod:rename(treat_icky(<<"åäö_fil1">>),"åäö2"), + ?line {ok, <<"åäö2">>} = Mod:read_file("åäö2"), + ?line {error,enoent} = Mod:read_file("åäö_fil1"), + ?line {error,enoent} = Mod:read_file(treat_icky(<<"åäö_fil1">>)), - ?line {ok,FI} = Mod:read_file_info("���2"), + ?line {ok,FI} = Mod:read_file_info("åäö2"), ?line NewMode = FI#file_info.mode band (bnot 8#333), ?line NewMode2 = NewMode bor 8#222, ?line true = NewMode2 =/= NewMode, - ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode}), - ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("���2"), - ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode2}), - ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("���2"), + ?line ok = Mod:write_file_info("åäö2",FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("åäö2"), + ?line ok = Mod:write_file_info("åäö2",FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("åäö2"), - ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"���5">>)), + ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"åäö5">>)), ?line true = NewMode2 =/= NewMode, - ?line ok = Mod:write_file_info(treat_icky(<<"���5">>),FII#file_info{mode = NewMode}), - ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"���5">>)), - ?line ok = Mod:write_file_info(<<"���5">>,FII#file_info{mode = NewMode2}), - ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"���5">>)), + ?line ok = Mod:write_file_info(treat_icky(<<"åäö5">>),FII#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"åäö5">>)), + ?line ok = Mod:write_file_info(<<"åäö5">>,FII#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"åäö5">>)), ok after Mod:set_cwd(Dir), @@ -475,7 +469,7 @@ check_icky(Mod) -> check_very_icky(Mod) -> {ok,Dir} = Mod:get_cwd(), try - ?line true=(length("���") =:= 3), + ?line true=(length("åäö") =:= 3), ?line UniMode = file:native_name_encoding() =/= latin1, if not UniMode -> @@ -484,7 +478,7 @@ check_very_icky(Mod) -> ok end, ?line make_very_icky_dir(Mod), - ?line {ok, L0} = Mod:list_dir("."), + {ok, L0} = Mod:list_dir_all("."), ?line L1 = lists:sort(L0), ?line L1 = lists:sort(convlist(list(very_icky_dir()))), ?line {ok,D2} = Mod:get_cwd(), @@ -493,11 +487,12 @@ check_very_icky(Mod) -> ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,very_icky_dir()))} || {T,S,Targ} <- very_icky_dir(), T =:= symlink ], ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], - ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link_all(SymL)) || + {SymL,Targ,_} <- Syms ], ?line chk_cre_dir(Mod,[{directory,[1088,1079,1091]++"_dir",very_icky_dir()}]), ?line {ok,BeginAt} = Mod:get_cwd(), ?line true = is_list(BeginAt), - ?line {error,enoent} = Mod:set_cwd("��_dir"), + ?line {error,enoent} = Mod:set_cwd("åä_dir"), ?line ok = Mod:set_cwd([1088,1079,1091]++"_dir"), ?line {ok, NowAt} = Mod:get_cwd(), ?line true = is_list(NowAt), @@ -514,16 +509,16 @@ check_very_icky(Mod) -> ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse"++[1088,1079,1091]), ?line ok = Mod:delete("nisse"++[1088,1079,1091]), - ?line ok = Mod:make_link("fil1",<<"nisse�">>), - ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisse�">>), + ?line ok = Mod:make_link("fil1",<<"nisseö">>), + ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisseö">>), ?line {ok, #file_info{type = regular}} = - Mod:read_link_info(<<"nisse�">>), - ?line ok = Mod:delete(<<"nisse�">>), + Mod:read_link_info(<<"nisseö">>), + ?line ok = Mod:delete(<<"nisseö">>), ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), ?line {error,enoent} = Mod:read_file("nisse"++[1088,1079,1091]), ?line {error,enoent} = Mod:read_link_info("nisse"++[1088,1079,1091]), - ?line {error,enoent} = Mod:read_file(<<"nisse�">>), - ?line {error,enoent} = Mod:read_link_info(<<"nisse�">>); + ?line {error,enoent} = Mod:read_file(<<"nisseö">>), + ?line {error,enoent} = Mod:read_link_info(<<"nisseö">>); false -> ok end, @@ -540,10 +535,10 @@ check_very_icky(Mod) -> end || {regular,Name,Content} <- very_icky_dir() ], ?line Mod:rename([956,965,963,954,959,49], [956,965,963,954,959]++"_fil1"), - ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"), + ?line {ok, <<"åäö2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"), ?line {error,enoent} = Mod:read_file([956,965,963,954,959,49]), ?line Mod:rename([956,965,963,954,959]++"_fil1",[956,965,963,954,959,49]), - ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959,49]), + ?line {ok, <<"åäö2">>} = Mod:read_file([956,965,963,954,959,49]), ?line {error,enoent} = Mod:read_file([956,965,963,954,959]++"_fil1"), ?line {ok,FI} = Mod:read_file_info([956,965,963,954,959,49]), @@ -558,33 +553,6 @@ check_very_icky(Mod) -> FI#file_info{mode = NewMode2}), ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info([956,965,963,954,959,49]), - ?line NumOK0 = case has_links() of - true -> 5; - false -> 3 - end, - ?line NumNOK0 = case has_links() of - true -> 4; - false -> 3 - end, - ?line {NumOK,NumNOK} = case is_binary(treat_icky(<<"foo">>)) of - false -> - {NumOK0+NumNOK0,0}; - true -> - {NumOK0,NumNOK0} - end, - ?line {NumOK,NumNOK} = filelib:fold_files(".",".*",true,fun(_F,{N,M}) when is_list(_F) -> io:format("~ts~n",[_F]),{N+1,M}; (_F,{N,M}) -> io:format("~p~n",[_F]),{N,M+1} end,{0,0}), - ?line ok = filelib:fold_files(".",[1076,1089,1072,124,46,42],true,fun(_F,_) -> ok end,false), - ?line SF3 = unicode:characters_to_binary("���subfil3", - file:native_name_encoding()), - ?line SF2 = case treat_icky(<<"���subfil2">>) of - LF2 when is_list(LF2) -> - unicode:characters_to_binary(LF2, - file:native_name_encoding()); - BF2 -> - BF2 - end, - ?line Sorted = lists:sort([SF3,SF2]), - ?line Sorted = lists:sort(filelib:wildcard("*",<<"���subdir2">>)), ok catch throw:need_unicode_mode -> @@ -603,7 +571,7 @@ check_very_icky(Mod) -> rm_rf(Mod,Dir) -> case Mod:read_link_info(Dir) of {ok, #file_info{type = directory}} -> - {ok, Content} = Mod:list_dir(Dir), + {ok, Content} = Mod:list_dir_all(Dir), [ rm_rf(Mod,filename:join(Dir,C)) || C <- Content ], Mod:del_dir(Dir), ok; @@ -618,7 +586,7 @@ rm_r(Mod,Dir) -> case Mod:read_link_info(Dir) of {ok, #file_info{type = directory}} -> {ok,#file_info{type = directory}} = Mod:read_file_info(Dir), - {ok, Content} = Mod:list_dir(Dir), + {ok, Content} = Mod:list_dir_all(Dir), [ true = is_list(Part) || Part <- Content ], [ true = is_list(filename:join(Dir,Part)) || Part <- Content ], [ rm_r(Mod,filename:join(Dir,C)) || C <- Content ], @@ -636,7 +604,7 @@ rm_r2(Mod,Dir) -> case Mod:read_link_info(Dir) of {ok, #file_info{type = directory}} -> {ok,#file_info{type = directory}} = Mod:read_file_info(Dir), - {ok, Content} = Mod:list_dir(Dir), + {ok, Content} = Mod:list_dir_all(Dir), UniMode = file:native_name_encoding() =/= latin1, [ true = (is_list(Part) orelse UniMode) || Part <- Content ], [ true = (is_list(filename:join(Dir,Part)) orelse UniMode) || Part <- Content ], @@ -744,26 +712,26 @@ hopeless_darwin() -> icky_dir() -> [{regular,"fil1","fil1"}, - {regular,"���2","���2"}] ++ + {regular,"åäö2","åäö2"}] ++ case has_links() of true -> - [{regular,"���3","���2"}, - {symlink,"���4","���2"}]; + [{regular,"åäö3","åäö2"}, + {symlink,"åäö4","åäö2"}]; false -> [] end ++ - [{regular,treat_icky(<<"���5">>),"���5"}] ++ + [{regular,treat_icky(<<"åäö5">>),"åäö5"}] ++ case has_links() of true -> - [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}]; + [{symlink,treat_icky(<<"åäö6">>),treat_icky(<<"åäö5">>)}]; false -> [] end ++ - [{directory,treat_icky(<<"���subdir2">>), - [{regular,treat_icky(<<"���subfil2">>),"���subfil12"}, - {regular,"���subfil3","���subfil13"}]}, - {directory,"���subdir", - [{regular,"���subfil1","���subfil1"}]}]. + [{directory,treat_icky(<<"åäösubdir2">>), + [{regular,treat_icky(<<"åäösubfil2">>),"åäösubfil12"}, + {regular,"åäösubfil3","åäösubfil13"}]}, + {directory,"åäösubdir", + [{regular,"åäösubfil1","åäösubfil1"}]}]. make_very_icky_dir(Mod) -> rm_rf(Mod,"very_icky_dir"), @@ -774,26 +742,26 @@ make_very_icky_dir(Mod) -> very_icky_dir() -> [{regular,"fil1","fil1"}, - {regular,[956,965,963,954,959,49],"���2"}] ++ + {regular,[956,965,963,954,959,49],"åäö2"}] ++ case has_links() of true -> - [{regular,[956,965,963,954,959,50],"���2"}, + [{regular,[956,965,963,954,959,50],"åäö2"}, {symlink,[956,965,963,954,959,51],[956,965,963,954,959,49]}]; false -> [] end ++ - [{regular,treat_icky(<<"���5">>),"���5"}] ++ + [{regular,treat_icky(<<"åäö5">>),"åäö5"}] ++ case has_links() of true -> - [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}]; + [{symlink,treat_icky(<<"åäö6">>),treat_icky(<<"åäö5">>)}]; false -> [] end ++ - [{directory,treat_icky(<<"���subdir2">>), - [{regular,treat_icky(<<"���subfil2">>),"���subfil12"}, - {regular,"���subfil3","���subfil13"}]}, + [{directory,treat_icky(<<"åäösubdir2">>), + [{regular,treat_icky(<<"åäösubfil2">>),"åäösubfil12"}, + {regular,"åäösubfil3","åäösubfil13"}]}, {directory,[956,965,963,954,959]++"subdir1", - [{regular,[956,965,963,954,959]++"subfil1","���subfil1"}]}]. + [{regular,[956,965,963,954,959]++"subfil1","åäösubfil1"}]}]. %% Some OS'es simply do not allow non UTF8 filenames treat_icky(Bin) -> diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index bcc2f0b840..2a886b2efc 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -31,22 +31,24 @@ [basic/1, api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1, xfer_min/1,xfer_active/1,def_sndrcvinfo/1,implicit_inet6/1, - basic_stream/1, xfer_stream_min/1, peeloff/1, buffers/1, open_multihoming_ipv4_socket/1, open_unihoming_ipv6_socket/1, open_multihoming_ipv6_socket/1, - open_multihoming_ipv4_and_ipv6_socket/1]). + open_multihoming_ipv4_and_ipv6_socket/1, + basic_stream/1, xfer_stream_min/1, peeloff_active_once/1, + peeloff_active_true/1, buffers/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [basic, api_open_close, api_listen, api_connect_init, api_opts, xfer_min, xfer_active, def_sndrcvinfo, implicit_inet6, - basic_stream, xfer_stream_min, peeloff, buffers, open_multihoming_ipv4_socket, open_unihoming_ipv6_socket, open_multihoming_ipv6_socket, - open_multihoming_ipv4_and_ipv6_socket]. + open_multihoming_ipv4_and_ipv6_socket, + basic_stream, xfer_stream_min, peeloff_active_once, + peeloff_active_true, buffers]. groups() -> []. @@ -923,23 +925,34 @@ do_from_other_process(Fun) -> end. +peeloff_active_once(doc) -> + "Peel off an SCTP stream socket ({active,once})"; +peeloff_active_once(suite) -> + []; + +peeloff_active_once(Config) -> + peeloff(Config, [{active,once}]). -peeloff(doc) -> - "Peel off an SCTP stream socket"; -peeloff(suite) -> +peeloff_active_true(doc) -> + "Peel off an SCTP stream socket ({active,true})"; +peeloff_active_true(suite) -> []; -peeloff(Config) when is_list(Config) -> + +peeloff_active_true(Config) -> + peeloff(Config, [{active,true}]). + +peeloff(Config, SockOpts) when is_list(Config) -> ?line Addr = {127,0,0,1}, ?line Stream = 0, ?line Timeout = 333, - ?line S1 = socket_open([{ifaddr,Addr}], Timeout), + ?line S1 = socket_open([{ifaddr,Addr}|SockOpts], Timeout), ?line ?LOGVAR(S1), ?line P1 = socket_call(S1, get_port), ?line ?LOGVAR(P1), ?line Socket1 = socket_call(S1, get_socket), ?line ?LOGVAR(Socket1), ?line socket_call(S1, {listen,true}), - ?line S2 = socket_open([{ifaddr,Addr}], Timeout), + ?line S2 = socket_open([{ifaddr,Addr}|SockOpts], Timeout), ?line ?LOGVAR(S2), ?line P2 = socket_call(S2, get_port), ?line ?LOGVAR(P2), @@ -983,7 +996,7 @@ peeloff(Config) when is_list(Config) -> socket_bailout([S1,S2]) end, %% - ?line S3 = socket_peeloff(Socket1, S1Ai, Timeout), + ?line S3 = socket_peeloff(Socket1, S1Ai, SockOpts, Timeout), ?line ?LOGVAR(S3), ?line P3_X = socket_call(S3, get_port), ?line ?LOGVAR(P3_X), @@ -1302,8 +1315,15 @@ recv_comm_up_eventually(S) -> %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% socket gen_server ultra light -socket_open(SocketOpts, Timeout) -> - Opts = [{type,seqpacket},{active,once},binary|SocketOpts], +socket_open(SockOpts0, Timeout) -> + SockOpts = + case lists:keyfind(active,1,SockOpts0) of + false -> + [{active,once}|SockOpts0]; + _ -> + SockOpts0 + end, + Opts = [{type,seqpacket},binary|SockOpts], Starter = fun () -> {ok,Socket} = @@ -1312,8 +1332,8 @@ socket_open(SocketOpts, Timeout) -> end, s_start(Starter, Timeout). -socket_peeloff(Socket, AssocId, Timeout) -> - Opts = [{active,once},binary], +socket_peeloff(Socket, AssocId, SocketOpts, Timeout) -> + Opts = [binary|SocketOpts], Starter = fun () -> {ok,NewSocket} = diff --git a/lib/kernel/test/gen_tcp_echo_SUITE.erl b/lib/kernel/test/gen_tcp_echo_SUITE.erl index 5bbaeb02ad..9bc66dbae0 100644 --- a/lib/kernel/test/gen_tcp_echo_SUITE.erl +++ b/lib/kernel/test/gen_tcp_echo_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-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 @@ -190,24 +190,19 @@ echo_test_1(SockOpts, EchoFun, Config0) -> ok. echo_packet(SockOpts, EchoFun, Opts) -> - ?line Type = - case lists:keysearch(type, 1, Opts) of - {value, {type, T}} -> - T; - _ -> - {value, {packet, T}} = lists:keysearch(packet, 1, SockOpts), - T - end, + Type = case lists:keysearch(type, 1, Opts) of + {value, {type, T}} -> + T; + _ -> + {value, {packet, T}} = lists:keysearch(packet, 1, SockOpts), + T + end, %% Connect to the echo server. - ?line EchoPort = ?config(echo_port, Opts), - ?line {ok, Echo} = gen_tcp:connect(localhost, EchoPort, SockOpts), + EchoPort = ?config(echo_port, Opts), + {ok, Echo} = gen_tcp:connect(localhost, EchoPort, SockOpts), - ?line SlowEcho = - case os:type() of - vxworks -> true; - _ -> lists:member(slow_echo, Opts) - end, + SlowEcho = lists:member(slow_echo, Opts), case Type of http -> diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index 1592399996..6b672004ec 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -42,13 +42,22 @@ killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1, several_accepts_in_one_go/1, accept_system_limit/1, active_once_closed/1, send_timeout/1, send_timeout_active/1, - otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, + otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, wrapping_oct/1, otp_9389/1]). %% Internal exports. -export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1, - otp_7731_server/1, zombie_server/2]). - + oct_acceptor/1, + otp_7731_server/1, zombie_server/2, do_iter_max_socks/2]). + +init_per_testcase(iter_max_socks, Config) when is_list(Config) -> + Dog = case os:type() of + {win32,_} -> + test_server:timetrap(test_server:minutes(30)); + _Else -> + test_server:timetrap(test_server:seconds(240)) + end, + [{watchdog, Dog}|Config]; init_per_testcase(_Func, Config) when is_list(Config) -> Dog = test_server:timetrap(test_server:seconds(240)), [{watchdog, Dog}|Config]. @@ -75,6 +84,7 @@ all() -> killing_acceptor, killing_multi_acceptors, killing_multi_acceptors2, several_accepts_in_one_go, accept_system_limit, active_once_closed, send_timeout, send_timeout_active, otp_7731, + wrapping_oct, zombie_sockets, otp_7816, otp_8102, otp_9389]. groups() -> @@ -340,39 +350,23 @@ no_accept(doc) -> "a tcp_closed message."]; no_accept(suite) -> []; no_accept(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {skip,"Too tough for vxworks"}; - _ -> - no_accept2() + {ok, L} = gen_tcp:listen(0, []), + {ok, {_, Port}} = inet:sockname(L), + {ok, Client} = gen_tcp:connect(localhost, Port, []), + ok = gen_tcp:close(L), + receive + {tcp_closed, Client} -> + ok + after 5000 -> + ?line test_server:fail(never_closed) + end. -no_accept2() -> - ?line {ok, L} = gen_tcp:listen(0, []), - ?line {ok, {_, Port}} = inet:sockname(L), - ?line {ok, Client} = gen_tcp:connect(localhost, Port, []), - ?line ok = gen_tcp:close(L), - ?line receive - {tcp_closed, Client} -> - ok - after 5000 -> - ?line test_server:fail(never_closed) - - end. - close_with_pending_output(doc) -> ["Send several packets to a socket and close it. All packets should arrive ", "to the other end."]; close_with_pending_output(suite) -> []; close_with_pending_output(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {skipped,"Too tough for vxworks"}; - _ -> - close_with_pending_output2() - end. - -close_with_pending_output2() -> ?line {ok, L} = gen_tcp:listen(0, [binary, {active, false}]), ?line {ok, {_, Port}} = inet:sockname(L), ?line Packets = 16, @@ -423,22 +417,16 @@ otp_3924(doc) -> otp_3924(suite) -> []; otp_3924(Config) when is_list(Config) -> MaxDelay = (case has_superfluous_schedulers() of - true -> 4; - false -> 1 - end - * case {erlang:system_info(debug_compiled), - erlang:system_info(lock_checking)} of - {true, _} -> 6; - {_, true} -> 2; - _ -> 1 - end * ?OTP_3924_MAX_DELAY), - case os:type() of - vxworks -> -%% {skip,"Too tough for vxworks"}; - otp_3924_1(MaxDelay); - _ -> - otp_3924_1(MaxDelay) - end. + true -> 4; + false -> 1 + end + * case {erlang:system_info(debug_compiled), + erlang:system_info(lock_checking)} of + {true, _} -> 6; + {_, true} -> 2; + _ -> 1 + end * ?OTP_3924_MAX_DELAY), + otp_3924_1(MaxDelay). otp_3924_1(MaxDelay) -> Dog = test_server:timetrap(test_server:seconds(240)), @@ -559,26 +547,18 @@ otp_3924_sender(Receiver, Host, Port, Data) -> data_before_close(doc) -> ["Tests that a huge amount of data can be received before a close."]; data_before_close(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {skip,"Too tough for vxworks"}; - _ -> - data_before_close2() - end. - -data_before_close2() -> - ?line {ok, L} = gen_tcp:listen(0, [binary]), - ?line {ok, {_, TcpPort}} = inet:sockname(L), - ?line Bytes = 256*1024, - ?line spawn_link(fun() -> huge_sender(TcpPort, Bytes) end), - ?line {ok, A} = gen_tcp:accept(L), - ?line case count_bytes_recv(A, 0) of - {Bytes, Result} -> - io:format("Result: ~p", [Result]); - {Wrong, Result} -> - io:format("Result: ~p", [Result]), - test_server:fail({wrong_count, Wrong}) - end, + {ok, L} = gen_tcp:listen(0, [binary]), + {ok, {_, TcpPort}} = inet:sockname(L), + Bytes = 256*1024, + spawn_link(fun() -> huge_sender(TcpPort, Bytes) end), + {ok, A} = gen_tcp:accept(L), + case count_bytes_recv(A, 0) of + {Bytes, Result} -> + io:format("Result: ~p", [Result]); + {Wrong, Result} -> + io:format("Result: ~p", [Result]), + test_server:fail({wrong_count, Wrong}) + end, ok. count_bytes_recv(Sock, Total) -> @@ -611,32 +591,24 @@ get_status(Config) when is_list(Config) -> ?line {ok,{socket,Pid,_,_}} = gen_tcp:listen(5678,[]), ?line {status,Pid,_,_} = sys:get_status(Pid). +-define(RECOVER_SLEEP, 60000). +-define(RETRY_SLEEP, 15000). + iter_max_socks(doc) -> ["Open as many sockets as possible. Do this several times and check ", "that we get the same number of sockets every time."]; iter_max_socks(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {skip,"Too tough for vxworks"}; - _ -> - iter_max_socks2() - end. - --define(RECOVER_SLEEP, 60000). --define(RETRY_SLEEP, 15000). + N = case os:type() of {win32,_} -> 10; _ -> 20 end, + %% Run on a different node in order to limit the effect if this test fails. + Dir = filename:dirname(code:which(?MODULE)), + {ok,Node} = test_server:start_node(test_iter_max_socks,slave, + [{args,"-pa " ++ Dir}]), + L = rpc:call(Node,?MODULE,do_iter_max_socks,[N, initalize]), + test_server:stop_node(Node), -iter_max_socks2() -> - ?line N = - case os:type() of - vxworks -> - 10; - _ -> - 20 - end, - L = do_iter_max_socks(N, initalize), - ?line io:format("Result: ~p",[L]), - ?line all_equal(L), - ?line {comment, "Max sockets: " ++ integer_to_list(hd(L))}. + io:format("Result: ~p",[L]), + all_equal(L), + {comment, "Max sockets: " ++ integer_to_list(hd(L))}. do_iter_max_socks(0, _) -> []; @@ -2619,3 +2591,71 @@ otp_9389_loop(S, OrigLinkHdr, State) -> 3000 -> ?line error({timeout,header}) end. + +wrapping_oct(doc) -> + "Check that 64bit octet counters work."; +wrapping_oct(suite) -> + []; +wrapping_oct(Config) when is_list(Config) -> + Dog = test_server:timetrap(test_server:seconds(600)), + {ok,Sock} = gen_tcp:listen(0,[{active,false},{mode,binary}]), + {ok,Port} = inet:port(Sock), + spawn_link(?MODULE,oct_acceptor,[Sock]), + Res = oct_datapump(Port,16#1FFFFFFFF), + gen_tcp:close(Sock), + test_server:timetrap_cancel(Dog), + ok = Res, + ok. + +oct_datapump(Port,N) -> + {ok,Sock} = gen_tcp:connect("localhost",Port, + [{active,false},{mode,binary}]), + oct_pump(Sock,N,binary:copy(<<$a:8>>,100000),0). + +oct_pump(S,N,_,_) when N =< 0 -> + gen_tcp:close(S), + ok; +oct_pump(S,N,Bin,Last) -> + case gen_tcp:send(S,Bin) of + ok -> + {ok,Stat}=inet:getstat(S), + {_,R}=lists:keyfind(send_oct,1,Stat), + case (R < Last) of + true -> + io:format("ERROR (output) ~p < ~p~n",[R,Last]), + output_counter_error; + false -> + oct_pump(S,N-byte_size(Bin),Bin,R) + end; + _ -> + input_counter_error + end. + + +oct_acceptor(Sock) -> + {ok,Data} = gen_tcp:accept(Sock), + oct_aloop(Data,0,0). + +oct_aloop(S,X,Times) -> + case gen_tcp:recv(S,0) of + {ok,_} -> + {ok,Stat}=inet:getstat(S), + {_,R}=lists:keyfind(recv_oct,1,Stat), + case (R < X) of + true -> + io:format("ERROR ~p < ~p~n",[R,X]), + gen_tcp:close(S), + input_counter_error; + false -> + case Times rem 16#FFFFF of + 0 -> + io:format("Read: ~p~n",[R]); + _ -> + ok + end, + oct_aloop(S,R,Times+1) + end; + _ -> + gen_tcp:close(S), + closed + end. diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index 2354f8accd..cd768813cf 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2011. All Rights Reserved. +%% Copyright Ericsson AB 1998-2012. 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 @@ -442,7 +443,7 @@ open_fd(suite) -> open_fd(doc) -> ["Test that the 'fd' option works"]; open_fd(Config) when is_list(Config) -> - Msg = "Det g�r ont n�r knoppar brista. Varf�r skulle annars v�ren tveka?", + Msg = "Det gör ont när knoppar brista. Varför skulle annars våren tveka?", Addr = {127,0,0,1}, {ok,S1} = gen_udp:open(0), {ok,P2} = inet:port(S1), diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl index 1cc3eb7c79..9428a38660 100644 --- a/lib/kernel/test/global_SUITE.erl +++ b/lib/kernel/test/global_SUITE.erl @@ -91,27 +91,9 @@ end_per_group(_GroupName, Config) -> Config. init_per_suite(Config) -> - - %% Copied from test_server_ctrl ln 647, we have to do this here as - %% the test_server only does this when run without common_test - global:sync(), - case global:whereis_name(test_server) of - undefined -> - io:format(user, "Registering test_server globally!~n",[]), - global:register_name(test_server, whereis(test_server_ctrl)); - Pid -> - case node() of - N when N == node(Pid) -> - io:format(user, "Warning: test_server already running!\n", []), - global:re_register_name(test_server,self()); - _ -> - ok - end - end, Config. end_per_suite(_Config) -> - global:unregister_name(test_server), ok. @@ -135,8 +117,7 @@ end_per_testcase(_Case, Config) -> ?line write_high_level_trace(Config), ?line _ = gen_server:call(global_name_server, high_level_trace_stop, infinity), - ?line[global:unregister_name(N) || N <- global:registered_names(), - N =/= test_server], + [global:unregister_name(N) || N <- global:registered_names()], ?line InitRegistered = ?registered, ?line Registered = registered(), ?line [io:format("~s local names: ~p~n", [What, N]) || @@ -1840,16 +1821,16 @@ do_otp_3162(StartFun, Config) -> ?line ?UNTIL ([Cp3] =:= lists:sort(rpc:call(Cp1, erlang, nodes, [])) -- [node()]), - ?line ?UNTIL([kalle, test_server, vera] =:= + ?UNTIL([kalle, vera] =:= lists:sort(rpc:call(Cp1, global, registered_names, []))), ?line ?UNTIL ([Cp3] =:= lists:sort(rpc:call(Cp2, erlang, nodes, [])) -- [node()]), - ?line ?UNTIL([stina, test_server, vera] =:= + ?UNTIL([stina, vera] =:= lists:sort(rpc:call(Cp2, global, registered_names, []))), ?line ?UNTIL ([Cp1, Cp2] =:= lists:sort(rpc:call(Cp3, erlang, nodes, [])) -- [node()]), - ?line ?UNTIL([kalle, stina, test_server, vera] =:= + ?UNTIL([kalle, stina, vera] =:= lists:sort(rpc:call(Cp3, global, registered_names, []))), ?line pong = rpc:call(Cp2, net_adm, ping, [Cp1]), @@ -1860,17 +1841,17 @@ do_otp_3162(StartFun, Config) -> ?line ?UNTIL(begin NN = lists:sort(rpc:call(Cp1, global, registered_names, [])), - [kalle, stina, test_server, vera] =:= NN + [kalle, stina, vera] =:= NN end), ?line ?UNTIL ([Cp1, Cp3] =:= lists:sort(rpc:call(Cp2, erlang, nodes, [])) -- [node()]), - ?line ?UNTIL([kalle, stina, test_server, vera] =:= + ?UNTIL([kalle, stina, vera] =:= lists:sort(rpc:call(Cp2, global, registered_names, []))), ?line ?UNTIL ([Cp1, Cp2] =:= lists:sort(rpc:call(Cp3, erlang, nodes, [])) -- [node()]), - ?line ?UNTIL([kalle, stina, test_server, vera] =:= + ?UNTIL([kalle, stina, vera] =:= lists:sort(rpc:call(Cp3, global, registered_names, []))), write_high_level_trace(Config), @@ -3821,7 +3802,7 @@ start_node_rel(Name0, Rel, Config) -> Name = node_name(Name0, Config), {Release, Compat} = case Rel of this -> - {[this], "+R8"}; + {[this], ""}; Rel when is_atom(Rel) -> {[{release, atom_to_list(Rel)}], ""}; RelList -> @@ -4154,7 +4135,7 @@ init_condition(Config) -> {"Global Locks (ETS)", global_locks}, {"Global Pid Names (ETS)", global_pid_names}, {"Global Pid Ids (ETS)", global_pid_ids}]], - ?UNTIL([test_server] =:= global:registered_names()), + ?UNTIL([] =:= global:registered_names()), ?UNTIL([] =:= nodes()), ?UNTIL([node()] =:= get_known(node())), ok. diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl index 4a8033e3a3..320b23bea1 100644 --- a/lib/kernel/test/heart_SUITE.erl +++ b/lib/kernel/test/heart_SUITE.erl @@ -83,10 +83,10 @@ init_per_suite(Config) when is_list(Config) -> {win32, windows} -> {skipped, "No use to run on Windows 95/98"}; _ -> - Config + ignore_cores:init(Config) end. end_per_suite(Config) when is_list(Config) -> - Config. + ignore_cores:fini(Config). start_check(Type, Name) -> @@ -188,8 +188,20 @@ reboot(Config) when is_list(Config) -> %% Check that a node is up and running after a crash. %% This test exhausts the atom table on the remote node. %% ERL_CRASH_DUMP_SECONDS=0 will force beam not to dump an erl_crash.dump. +%% May currently dump core in beam debug build due to lock-order violation +%% This should be removed when a non-lockad information retriever is implemented +%% for crash dumps node_start_immediately_after_crash(suite) -> {req, [{time, 10}]}; node_start_immediately_after_crash(Config) when is_list(Config) -> + Config2 = ignore_cores:setup(?MODULE, node_start_immediately_after_crash, Config, true), + try + node_start_immediately_after_crash_test(Config2) + after + ignore_cores:restore(Config2) + end. + + +node_start_immediately_after_crash_test(Config) when is_list(Config) -> {ok, Node} = start_check(loose, heart_test_imm, [{"ERL_CRASH_DUMP_SECONDS", "0"}]), ok = rpc:call(Node, heart, set_cmd, @@ -228,8 +240,19 @@ node_start_immediately_after_crash(Config) when is_list(Config) -> %% This test exhausts the atom table on the remote node. %% ERL_CRASH_DUMP_SECONDS=10 will force beam %% to only dump an erl_crash.dump for 10 seconds. +%% May currently dump core in beam debug build due to lock-order violation +%% This should be removed when a non-lockad information retriever is implemented +%% for crash dumps node_start_soon_after_crash(suite) -> {req, [{time, 10}]}; node_start_soon_after_crash(Config) when is_list(Config) -> + Config2 = ignore_cores:setup(?MODULE, node_start_soon_after_crash, Config, true), + try + node_start_soon_after_crash_test(Config2) + after + ignore_cores:restore(Config2) + end. + +node_start_soon_after_crash_test(Config) when is_list(Config) -> {ok, Node} = start_check(loose, heart_test_soon, [{"ERL_CRASH_DUMP_SECONDS", "10"}]), ok = rpc:call(Node, heart, set_cmd, @@ -345,13 +368,8 @@ dont_drop(doc) -> "set just before halt on very high I/O load."]; dont_drop(Config) when is_list(Config) -> %%% Have to do it some times to make it happen... - case os:type() of - vxworks -> - {comment, "No use to run with slaves on other nodes..."}; - _ -> - [ok,ok,ok,ok,ok,ok,ok,ok,ok,ok] = do_dont_drop(Config,10), - ok - end. + [ok,ok,ok,ok,ok,ok,ok,ok,ok,ok] = do_dont_drop(Config,10), + ok. do_dont_drop(_,0) -> []; do_dont_drop(Config,N) -> @@ -408,13 +426,7 @@ kill_pid(doc) -> ["Tests that heart kills the old erlang node before executing ", "heart command."]; kill_pid(Config) when is_list(Config) -> - %%% Have to do it some times to make it happen... - case os:type() of - vxworks -> - {comment, "No use to run with slaves on other nodes..."}; - _ -> - ok = do_kill_pid(Config) - end. + ok = do_kill_pid(Config). do_kill_pid(_Config) -> Name = heart_test, diff --git a/lib/kernel/test/heart_SUITE_data/simple_echo.c b/lib/kernel/test/heart_SUITE_data/simple_echo.c index 0093dbce9b..a92bb8af95 100644 --- a/lib/kernel/test/heart_SUITE_data/simple_echo.c +++ b/lib/kernel/test/heart_SUITE_data/simple_echo.c @@ -2,11 +2,7 @@ #include <stdlib.h> #include <string.h> -#ifdef VXWORKS -int simple_echo(void){ -#else int main(void){ -#endif int x; while((x = getchar()) != EOF){ putchar(x); @@ -14,4 +10,3 @@ int main(void){ } return 0; } - diff --git a/lib/kernel/test/ignore_cores.erl b/lib/kernel/test/ignore_cores.erl new file mode 100644 index 0000000000..d4bb02df3f --- /dev/null +++ b/lib/kernel/test/ignore_cores.erl @@ -0,0 +1,158 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-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 +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%%%------------------------------------------------------------------- +%%% File : ignore_cores.erl +%%% Author : Rickard Green <[email protected]> +%%% Description : +%%% +%%% Created : 11 Feb 2008 by Rickard Green <[email protected]> +%%%------------------------------------------------------------------- + +-module(ignore_cores). + +-include_lib("test_server/include/test_server.hrl"). + +-export([init/1, fini/1, setup/3, setup/4, restore/1, dir/1]). + +-record(ignore_cores, {org_cwd, + org_path, + org_pwd_env, + ign_dir = false, + cores_dir = false}). + +%% +%% Takes a testcase config +%% + +init(Config) -> + {ok, OrgCWD} = file:get_cwd(), + [{ignore_cores, + #ignore_cores{org_cwd = OrgCWD, + org_path = code:get_path(), + org_pwd_env = os:getenv("PWD")}} + | lists:keydelete(ignore_cores, 1, Config)]. + +fini(Config) -> + #ignore_cores{org_cwd = OrgCWD, + org_path = OrgPath, + org_pwd_env = OrgPWD} = ?config(ignore_cores, Config), + ok = file:set_cwd(OrgCWD), + true = code:set_path(OrgPath), + case OrgPWD of + false -> ok; + _ -> true = os:putenv("PWD", OrgPWD) + end, + lists:keydelete(ignore_cores, 1, Config). + +setup(Suite, Testcase, Config) -> + setup(Suite, Testcase, Config, false). + +setup(Suite, Testcase, Config, SetCwd) when is_atom(Suite), + is_atom(Testcase), + is_list(Config) -> + #ignore_cores{org_cwd = OrgCWD, + org_path = OrgPath, + org_pwd_env = OrgPWD} = ?config(ignore_cores, Config), + Path = lists:map(fun (".") -> OrgCWD; (Dir) -> Dir end, OrgPath), + true = code:set_path(Path), + PrivDir = ?config(priv_dir, Config), + IgnDir = filename:join([PrivDir, + atom_to_list(Suite) + ++ "_" + ++ atom_to_list(Testcase) + ++ "_wd"]), + ok = file:make_dir(IgnDir), + case SetCwd of + false -> + ok; + _ -> + ok = file:set_cwd(IgnDir), + OrgPWD = case os:getenv("PWD") of + false -> false; + PWD -> + os:putenv("PWD", IgnDir), + PWD + end + end, + ok = file:write_file(filename:join([IgnDir, "ignore_core_files"]), <<>>), + %% cores are dumped in /cores on MacOS X + CoresDir = case {?t:os_type(), filelib:is_dir("/cores")} of + {{unix,darwin}, true} -> + filelib:fold_files("/cores", + "^core.*$", + false, + fun (C,Cs) -> [C|Cs] end, + []); + _ -> + false + end, + lists:keyreplace(ignore_cores, + 1, + Config, + {ignore_cores, + #ignore_cores{org_cwd = OrgCWD, + org_path = OrgPath, + org_pwd_env = OrgPWD, + ign_dir = IgnDir, + cores_dir = CoresDir}}). + +restore(Config) -> + #ignore_cores{org_cwd = OrgCWD, + org_path = OrgPath, + org_pwd_env = OrgPWD, + ign_dir = IgnDir, + cores_dir = CoresDir} = ?config(ignore_cores, Config), + try + case CoresDir of + false -> + ok; + _ -> + %% Move cores dumped by these testcases in /cores + %% to cwd. + lists:foreach(fun (C) -> + case lists:member(C, CoresDir) of + true -> ok; + _ -> + Dst = filename:join( + [IgnDir, + filename:basename(C)]), + {ok, _} = file:copy(C, Dst), + file:delete(C) + end + end, + filelib:fold_files("/cores", + "^core.*$", + false, + fun (C,Cs) -> [C|Cs] end, + [])) + end + after + catch file:set_cwd(OrgCWD), + catch code:set_path(OrgPath), + case OrgPWD of + false -> ok; + _ -> catch os:putenv("PWD", OrgPWD) + end + end. + + +dir(Config) -> + #ignore_cores{ign_dir = Dir} = ?config(ignore_cores, Config), + Dir. diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index 7241b093d0..1f7724d0dc 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-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 @@ -37,7 +37,8 @@ gethostnative_soft_restart/0, gethostnative_soft_restart/1, gethostnative_debug_level/0, gethostnative_debug_level/1, getif/1, - getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1]). + getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1, + parse_strict_address/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, kill_gethost/0, parallell_gethost/0]). @@ -52,7 +53,7 @@ all() -> t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level, gethostnative_soft_restart, getif, getif_ifr_name_overflow, getservbyname_overflow, - getifaddrs]. + getifaddrs, parse_strict_address]. groups() -> [{parse, [], [parse_hosts, parse_address]}]. @@ -66,7 +67,7 @@ required(v6) -> {require, test_dummy_ipv6_host}]; required(hosts) -> case os:type() of - {OS, _} when OS =:= win32; OS =:= vxworks -> + {OS, _} when OS =:= win32 -> [{require, hardcoded_hosts}, {require, hardcoded_ipv6_hosts}]; _Else -> @@ -582,16 +583,16 @@ parse_address(Config) when is_list(Config) -> "fe80::198.168.0.", "fec0::fFfF:127.0.0.1."], t_parse_address - (ipv6_address, + (parse_ipv6_address, V6Strict++V6Sloppy++V6Err++V4Err), t_parse_address - (ipv6strict_address, + (parse_ipv6strict_address, V6Strict++V6Err++V4Err++[S || {_,S} <- V6Sloppy]), t_parse_address - (ipv4_address, + (parse_ipv4_address, V4Strict++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Strict]), t_parse_address - (ipv4strict_address, + (parse_ipv4strict_address, V4Strict++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Strict]). t_parse_address(Func, []) -> @@ -599,14 +600,16 @@ t_parse_address(Func, []) -> ok; t_parse_address(Func, [{Addr,String}|L]) -> io:format("~p = ~p.~n", [Addr,String]), - {ok,Addr} = inet_parse:Func(String), + {ok,Addr} = inet:Func(String), t_parse_address(Func, L); t_parse_address(Func, [String|L]) -> io:format("~p.~n", [String]), - {error,einval} = inet_parse:Func(String), + {error,einval} = inet:Func(String), t_parse_address(Func, L). - +parse_strict_address(Config) when is_list(Config) -> + {ok, Ipv4} = inet:parse_strict_address("127.0.0.1"), + {ok, Ipv6} = inet:parse_strict_address("c11:0c22:5c33:c440:55c0:c66c:77:0088"). t_gethostnative(suite) ->[]; t_gethostnative(doc) ->[]; @@ -614,17 +617,12 @@ t_gethostnative(Config) when is_list(Config) -> %% this will result in 26 bytes sent which causes problem in Windows %% if the port-program has not assured stdin to be read in BINARY mode %% OTP-2555 - case os:type() of - vxworks -> - {skipped, "VxWorks has no native gethostbyname()"}; - _ -> - ?line case inet_gethost_native:gethostbyname( - "a23456789012345678901234") of - {error,notfound} -> - ?line ok; - {error,no_data} -> - ?line ok - end + ?line case inet_gethost_native:gethostbyname( + "a23456789012345678901234") of + {error,notfound} -> + ?line ok; + {error,no_data} -> + ?line ok end. gethostnative_parallell(suite) -> diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl index 0c63a6d653..75496ce745 100644 --- a/lib/kernel/test/inet_sockopt_SUITE.erl +++ b/lib/kernel/test/inet_sockopt_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. 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 @@ -53,6 +53,8 @@ simple/1, loop_all/1, simple_raw/1, simple_raw_getbin/1, doc_examples_raw/1,doc_examples_raw_getbin/1, large_raw/1,large_raw_getbin/1,combined/1,combined_getbin/1, + ipv6_v6only_udp/1, ipv6_v6only_tcp/1, ipv6_v6only_sctp/1, + use_ipv6_v6only_udp/1, type_errors/1]). -export([init_per_testcase/2, end_per_testcase/2]). @@ -64,6 +66,8 @@ all() -> [simple, loop_all, simple_raw, simple_raw_getbin, doc_examples_raw, doc_examples_raw_getbin, large_raw, large_raw_getbin, combined, combined_getbin, + ipv6_v6only_udp, ipv6_v6only_tcp, ipv6_v6only_sctp, + use_ipv6_v6only_udp, type_errors]. groups() -> @@ -127,7 +131,7 @@ loop_all(Config) when is_list(Config) -> io_lib:format("Non mandatory failed:~w", [Failed]))} end. - + simple_raw(suite) -> []; @@ -461,6 +465,153 @@ do_combined(Config,Binary) when is_list(Config) -> ok end. + + +ipv6_v6only_udp(suite) -> []; +ipv6_v6only_udp(doc) -> "Test socket option ipv6_v6only for UDP"; +ipv6_v6only_udp(Config) when is_list(Config) -> + ipv6_v6only(Config, gen_udp). + +ipv6_v6only_tcp(suite) -> []; +ipv6_v6only_tcp(doc) -> "Test socket option ipv6_v6only for TCP"; +ipv6_v6only_tcp(Config) when is_list(Config) -> + ipv6_v6only(Config, gen_tcp). + +ipv6_v6only_sctp(suite) -> []; +ipv6_v6only_sctp(doc) -> "Test socket option ipv6_v6only for SCTP"; +ipv6_v6only_sctp(Config) when is_list(Config) -> + ipv6_v6only(Config, gen_sctp). + +ipv6_v6only(Config, Module) when is_list(Config) -> + ?line case ipv6_v6only_open(Module, []) of + {ok,S1} -> + ?line case inet:getopts(S1, [ipv6_v6only]) of + {ok,[{ipv6_v6only,Default}]} + when is_boolean(Default) -> + ?line ok = + ipv6_v6only_close(Module, S1), + ?line ipv6_v6only(Config, Module, Default); + {ok,[]} -> + ?line io:format("Not implemented.~n", []), + %% This list of OS:es where the option is + %% supposed to be not implemented is just + %% a guess, and may grow with time. + ?line case {os:type(),os:version()} of + {{unix,linux},{2,M,_}} + when M =< 4 -> ok + end, + %% At least this should work + ?line {ok,S2} = + ipv6_v6only_open( + Module, + [{ipv6_v6only,true}]), + ?line ok = + ipv6_v6only_close(Module, S2) + end; + {error,_} -> + {skipped,"Socket type not supported"} + end. + +ipv6_v6only(Config, Module, Default) when is_list(Config) -> + ?line io:format("Default ~w.~n", [Default]), + ?line {ok,S1} = + ipv6_v6only_open(Module, [{ipv6_v6only,Default}]), + ?line {ok,[{ipv6_v6only,Default}]} = + inet:getopts(S1, [ipv6_v6only]), + ?line ok = + ipv6_v6only_close(Module, S1), + ?line NotDefault = not Default, + ?line case ipv6_v6only_open(Module, [{ipv6_v6only,NotDefault}]) of + {ok,S2} -> + ?line io:format("Read-write.~n", []), + ?line {ok,[{ipv6_v6only,NotDefault}]} = + inet:getopts(S2, [ipv6_v6only]), + ok; + {error,einval} -> + ?line io:format("Read-only.~n", []), + %% This option is known to be read-only and true + %% on Windows and OpenBSD + ?line case os:type() of + {unix,openbsd} when Default =:= true -> ok; + {win32,_} when Default =:= true -> ok + end + end. + +ipv6_v6only_open(Module, Opts) -> + Module:case Module of + gen_tcp -> listen; + _ -> open + end(0, [inet6|Opts]). + +ipv6_v6only_close(Module, Socket) -> + Module:close(Socket). + + +use_ipv6_v6only_udp(suite) -> []; +use_ipv6_v6only_udp(doc) -> "Test using socket option ipv6_v6only for UDP"; +use_ipv6_v6only_udp(Config) when is_list(Config) -> + ?line case gen_udp:open(0, [inet6,{ipv6_v6only,true}]) of + {ok,S6} -> + ?line case inet:getopts(S6, [ipv6_v6only]) of + {ok,[{ipv6_v6only,true}]} -> + use_ipv6_v6only_udp(Config, S6); + {ok,Other} -> + {skipped,{getopts,Other}} + end; + {error,_} -> + {skipped,"Socket type not supported"} + end. + +use_ipv6_v6only_udp(_Config, S6) -> + ?line {ok,Port} = inet:port(S6), + ?line {ok,S4} = gen_udp:open(Port, [inet]), + ?line E6 = " IPv6-echo.", + ?line E4 = " IPv4-echo.", + ?line Sender = + spawn_link(fun () -> use_ipv6_v6only_udp_sender(Port, E6, E4) end), + ?line use_ipv6_v6only_udp_listener( + S6, S4, E6, E4, monitor(process, Sender)). + +use_ipv6_v6only_udp_listener(S6, S4, E6, E4, Mref) -> + ?line receive + {udp,S6,IP,P,Data} -> + ?line ok = gen_udp:send(S6, IP, P, [Data|E6]), + ?line use_ipv6_v6only_udp_listener(S6, S4, E6, E4, Mref); + {udp,S4,IP,P,Data} -> + ?line ok = gen_udp:send(S4, IP, P, [Data|E4]), + ?line use_ipv6_v6only_udp_listener(S6, S4, E6, E4, Mref); + {'DOWN',Mref,_,_,normal} -> + ok; + {'DOWN',Mref,_,_,Result} -> + %% Since we are linked we will never arrive here + Result; + Other -> + ?line exit({failed,{listener_unexpected,Other}}) + end. + +use_ipv6_v6only_udp_sender(Port, E6, E4) -> + D6 = "IPv6-send.", + D4 = "IPv4-send.", + R6 = D6 ++ E6, + R4 = D4 ++ E4, + R6 = sndrcv({0,0,0,0,0,0,0,1}, Port, [inet6], D6), + R4 = sndrcv({127,0,0,1}, Port, [inet], D4), + ok. + +sndrcv(Ip, Port, Opts, Data) -> + {ok,S} = gen_udp:open(0, Opts), + io:format("[~w:~w] ! ~s~n", [Ip,Port,Data]), + ok = gen_udp:send(S, Ip, Port, Data), + receive + {udp,S,Ip,Port,RecData} -> + io:format("[~w:~w] : ~s~n", [Ip,Port,RecData]), + RecData; + Other -> + exit({failed,{sndrcv_unexpectec,Other}}) + end. + + + type_errors(suite) -> []; type_errors(doc) -> @@ -623,7 +774,6 @@ all_listen_options() -> {exit_on_close, true, false, true, true}, %{high_watermark,4096,8192,true,true}, %{low_watermark,2048,4096,true,true}, - {bit8,on,off,true,true}, {send_timeout,infinity,1000,true,true}, {send_timeout_close,false,true,true,true}, {delay_send,false,true,true,true}, @@ -647,7 +797,6 @@ all_connect_options() -> {exit_on_close, true, false, true, true}, {high_watermark,4096,8192,false,true}, {low_watermark,2048,4096,false,true}, - {bit8,on,off,true,true}, {send_timeout,infinity,1000,true,true}, {send_timeout_close,false,true,true,true}, {delay_send,false,true,true,true}, diff --git a/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c b/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c index f24c93edf5..9c8f8eb91a 100644 --- a/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c +++ b/lib/kernel/test/inet_sockopt_SUITE_data/sockopt_helper.c @@ -1,12 +1,3 @@ -#if defined(VXWORKS) -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int sockopt_helper(void){ - return 0; -} -#else - #if defined(__WIN32__) #define WIN32_LEAN_AND_MEAN #include <winsock2.h> @@ -215,5 +206,3 @@ int main(void){ } while (x != C_QUIT); return 0; } -#endif - diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl index e0b90c5214..6fe97ed04f 100644 --- a/lib/kernel/test/init_SUITE.erl +++ b/lib/kernel/test/init_SUITE.erl @@ -256,47 +256,42 @@ get_plain_arguments(Config) when is_list(Config) -> boot_var(doc) -> []; boot_var(suite) -> {req, [distribution, {local_slave_nodes, 1}]}; boot_var(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "Not run on VxWorks"}; + ?line Dog = ?t:timetrap(?t:seconds(100)), + + {BootScript, TEST_VAR, KernelVsn, StdlibVsn} = create_boot(Config), + + %% Should fail as we have not given -boot_var TEST_VAR + ?line {error, timeout} = + start_node(init_test, "-boot " ++ BootScript), + + case is_real_system(KernelVsn, StdlibVsn) of + true -> + %% Now it should work !! + ?line {ok, Node} = + start_node(init_test, + "-boot " ++ BootScript ++ + " -boot_var TEST_VAR " ++ TEST_VAR), + stop_node(Node), + Res = ok; _ -> - ?line Dog = ?t:timetrap(?t:seconds(100)), - - {BootScript, TEST_VAR, KernelVsn, StdlibVsn} = create_boot(Config), - - %% Should fail as we have not given -boot_var TEST_VAR - ?line {error, timeout} = - start_node(init_test, "-boot " ++ BootScript), - - case is_real_system(KernelVsn, StdlibVsn) of - true -> - %% Now it should work !! - ?line {ok, Node} = - start_node(init_test, - "-boot " ++ BootScript ++ - " -boot_var TEST_VAR " ++ TEST_VAR), - stop_node(Node), - Res = ok; - _ -> -%% What we need is not so much version numbers on the directories, but -%% for the boot var TEST_VAR to appear in the boot script, and it doesn't -%% if we give the 'local' option to systools:make_script. - ?t:format( - "Test case not complete as we are not~n" - "running in a real system!~n" - "Probably this test is performed in a " - "clearcase view or source tree.~n" - "Need version numbers on the kernel and " - "stdlib directories!~n", - []), - Res = {skip, - "Test case only partially run since it is run " - "in a clearcase view or in a source tree. " - "Need an installed system to complete this test."} - end, - ?line ?t:timetrap_cancel(Dog), - Res - end. + %% What we need is not so much version numbers on the directories, but + %% for the boot var TEST_VAR to appear in the boot script, and it doesn't + %% if we give the 'local' option to systools:make_script. + ?t:format( + "Test case not complete as we are not~n" + "running in a real system!~n" + "Probably this test is performed in a " + "clearcase view or source tree.~n" + "Need version numbers on the kernel and " + "stdlib directories!~n", + []), + Res = {skip, + "Test case only partially run since it is run " + "in a clearcase view or in a source tree. " + "Need an installed system to complete this test."} + end, + ?line ?t:timetrap_cancel(Dog), + Res. create_boot(Config) -> ?line {ok, OldDir} = file:get_cwd(), @@ -579,55 +574,47 @@ script_id(Config) when is_list(Config) -> boot1(doc) -> []; boot1(suite) -> {req, [distribution, {local_slave_nodes, 1}, {time, 35}]}; boot1(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "Not run on VxWorks"}; - _ -> - ?line Dog = ?t:timetrap(?t:seconds(80)), - Args = args() ++ " -boot start_sasl", - ?line {ok, Node} = start_node(init_test, Args), - ?line stop_node(Node), - - %% Try to start with non existing boot file. - Args1 = args() ++ " -boot dummy_script", - ?line {error, timeout} = start_node(init_test, Args1), - - ?line ?t:timetrap_cancel(Dog), - ok - end. + ?line Dog = ?t:timetrap(?t:seconds(80)), + Args = args() ++ " -boot start_sasl", + ?line {ok, Node} = start_node(init_test, Args), + ?line stop_node(Node), + + %% Try to start with non existing boot file. + Args1 = args() ++ " -boot dummy_script", + ?line {error, timeout} = start_node(init_test, Args1), + + ?line ?t:timetrap_cancel(Dog), + ok. boot2(doc) -> []; boot2(suite) -> {req, [distribution, {local_slave_nodes, 1}, {time, 35}]}; boot2(Config) when is_list(Config) -> + Dog = ?t:timetrap(?t:seconds(80)), + + %% Absolute boot file name + Boot = filename:join([code:root_dir(), "bin", "start_sasl"]), + + Args = args() ++ " -boot \"" ++ Boot++"\"", + {ok, Node} = start_node(init_test, Args), + stop_node(Node), + case os:type() of - vxworks -> - {comment, "Not run on VxWorks"}; + {win32, _} -> + %% Absolute boot file name for Windows -- all slashes are + %% converted to backslashes. + Win_boot = lists:map(fun + ($/) -> $\\; + (C) -> C + end, Boot), + Args2 = args() ++ " -boot \"" ++ Win_boot ++ "\"", + {ok, Node2} = start_node(init_test, Args2), + stop_node(Node2); _ -> - ?line Dog = ?t:timetrap(?t:seconds(80)), - - %% Absolute boot file name - Boot = filename:join([code:root_dir(), "bin", "start_sasl"]), - - Args = args() ++ " -boot \"" ++ Boot++"\"", - ?line {ok, Node} = start_node(init_test, Args), - ?line stop_node(Node), - - case os:type() of - {win32, _} -> - %% Absolute boot file name for Windows -- all slashes are - %% converted to backslashes. - Win_boot = lists:map(fun($/) -> $\\; (C) -> C end, - Boot), - Args2 = args() ++ " -boot \"" ++ Win_boot ++ "\"", - ?line {ok, Node2} = start_node(init_test, Args2), - ?line stop_node(Node2); - _ -> - ok - end, - - ?line ?t:timetrap_cancel(Dog), ok - end. + end, + + ?t:timetrap_cancel(Dog), + ok. %% Misc. functions diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl index 7549e2c83e..36e13cec26 100644 --- a/lib/kernel/test/interactive_shell_SUITE.erl +++ b/lib/kernel/test/interactive_shell_SUITE.erl @@ -29,7 +29,7 @@ -export([toerl_server/3]). init_per_testcase(_Func, Config) -> - Dog = test_server:timetrap(test_server:seconds(60)), + Dog = test_server:timetrap(test_server:minutes(3)), [{watchdog,Dog}|Config]. end_per_testcase(_Func, Config) -> diff --git a/lib/kernel/test/kernel.cover b/lib/kernel/test/kernel.cover index f6967ca651..af1dd7eaad 100644 --- a/lib/kernel/test/kernel.cover +++ b/lib/kernel/test/kernel.cover @@ -1,3 +1,3 @@ %% -*- erlang -*- -{incl_mods,[gen_udp,inet6_udp,inet_res,inet_dns]}. +{incl_app,kernel,details}. diff --git a/lib/kernel/test/kernel.spec.wxworks b/lib/kernel/test/kernel.spec.wxworks deleted file mode 100644 index 370e474e64..0000000000 --- a/lib/kernel/test/kernel.spec.wxworks +++ /dev/null @@ -1,63 +0,0 @@ -%% -*- erlang -*- -{suites,"kernel_test",all}. -{skip_cases,"kernel_test",bif_SUITE,[spawn_link_race1],"Known bug."}. -{skip_cases,"kernel_test",file_SUITE, - [read_write_file], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [cur_dir_0], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [open1], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [file_info_times], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [file_write_file_info], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [truncate], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [rename], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [e_delete], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [e_rename], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [delayed_write], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [read_ahead], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",file_SUITE, - [segment_write], - "VxWorks filesystem would overload"}. -{skip_cases,"kernel_test",file_SUITE, - [segment_read], - "VxWorks filesystem would overload"}. -{skip_cases,"kernel_test",file_SUITE, - [compress_errors], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",init_SUITE,[restart],"Uses peer nodes"}. -{skip_cases,"kernel_test",os_SUITE,[space_in_cwd],"VxWorks can't handle this"}. -{skip_cases,"kernel_test",os_SUITE, - [space_in_name], - "VxWorks can't handle this"}. -{skip_cases,"kernel_test",os_SUITE,[quoting],"VxWorks can't handle this"}. -{skip_cases,"kernel_test",prim_file_SUITE, - [open1], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",prim_file_SUITE, - [compress_errors], - "VxWorks filesystem can't handle this"}. -{skip_cases,"kernel_test",seq_trace_SUITE, - [distributed_recv], - "Test not adopted to slaves on different machine"}. -{skip_cases,"kernel_test",seq_trace_SUITE, - [distributed_exit], - "Test not adopted to slaves on different machine"}. diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index ae3410d13f..382fd6f6a9 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-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 @@ -202,8 +202,6 @@ find_executable(Config) when is_list(Config) -> %% Never return a directory name. ?line false = os:find_executable("unix", [DataDir]), - ok; - vxworks -> ok end. diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl index 8afdfc8a47..98cff0222e 100644 --- a/lib/kernel/test/pdict_SUITE.erl +++ b/lib/kernel/test/pdict_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -152,7 +152,6 @@ heavy(Config) when is_list(Config) -> time(5000), ?M([],get()), case {os:type(),?t:is_debug()} of - {vxworks,_} -> ok; {_,true} -> ok; _ -> time(50000), diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl index 3e2202922c..ac75037536 100644 --- a/lib/kernel/test/prim_file_SUITE.erl +++ b/lib/kernel/test/prim_file_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2011. All Rights Reserved. +%% Copyright Ericsson AB 2000-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 @@ -49,7 +49,9 @@ make_link_a/1, make_link_b/1, read_link_info_for_non_link/1, symlinks_a/1, symlinks_b/1, - list_dir_limit/1]). + list_dir_limit/1, + list_dir_error/1, + list_dir/1]). -export([advise/1]). -export([large_write/1]). @@ -57,6 +59,8 @@ %% System probe functions that might be handy to check from the shell -export([unix_free/1]). +-export([allocate/1]). + -include_lib("test_server/include/test_server.hrl"). -include_lib("kernel/include/file.hrl"). @@ -79,7 +83,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [read_write_file, {group, dirs}, {group, files}, delete_a, delete_b, rename_a, rename_b, {group, errors}, - {group, compression}, {group, links}, list_dir_limit]. + {group, compression}, {group, links}, list_dir_limit, list_dir]. groups() -> [{dirs, [], @@ -87,7 +91,7 @@ groups() -> cur_dir_1a, cur_dir_1b]}, {files, [], [{group, open}, {group, pos}, {group, file_info}, - truncate, sync, datasync, advise, large_write]}, + truncate, sync, datasync, advise, large_write, allocate]}, {open, [], [open1, modes, close, access, read_write, pread_write, append, exclusive]}, @@ -108,7 +112,7 @@ groups() -> write_compressed, compress_errors]}, {links, [], [make_link_a, make_link_b, read_link_info_for_non_link, - symlinks_a, symlinks_b]}]. + symlinks_a, symlinks_b, list_dir_error]}]. init_per_group(_GroupName, Config) -> Config. @@ -406,9 +410,6 @@ cur_dir_1(Config, Handle) -> {unix, _} -> ?line {error, enotsup} = ?PRIM_FILE_call(get_cwd, Handle, ["d:"]); - vxworks -> - ?line {error, enotsup} = - ?PRIM_FILE_call(get_cwd, Handle, ["d:"]); {win32, _} -> win_cur_dir_1(Config, Handle) end, @@ -843,10 +844,7 @@ file_info_basic_directory(Config, Handle) -> ?line test_directory("c:/", read_write, Handle), ?line test_directory("c:\\", read_write, Handle); {unix, _} -> - ?line test_directory("/", read, Handle); - vxworks -> - %% Check is just done for owner - ?line test_directory("/", read_write, Handle) + ?line test_directory("/", read, Handle) end, ?line test_server:timetrap_cancel(Dog). @@ -1365,6 +1363,76 @@ check_large_write(Dog, Fd, _, _, []) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +allocate(suite) -> []; +allocate(doc) -> "Tests that ?PRIM_FILE:allocate/3 at least doesn't crash."; +allocate(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(5)), + ?line PrivDir = ?config(priv_dir, Config), + ?line Allocate = filename:join(PrivDir, + atom_to_list(?MODULE) + ++"_allocate.fil"), + + Line1 = "Hello\n", + Line2 = "World!\n", + + ?line {ok, Fd} = ?PRIM_FILE:open(Allocate, [write, binary]), + allocate_and_assert(Fd, 1, iolist_size([Line1, Line2])), + ?line ok = ?PRIM_FILE:write(Fd, Line1), + ?line ok = ?PRIM_FILE:write(Fd, Line2), + ?line ok = ?PRIM_FILE:close(Fd), + + ?line {ok, Fd2} = ?PRIM_FILE:open(Allocate, [write, binary]), + allocate_and_assert(Fd2, 1, iolist_size(Line1)), + ?line ok = ?PRIM_FILE:write(Fd2, Line1), + ?line ok = ?PRIM_FILE:write(Fd2, Line2), + ?line ok = ?PRIM_FILE:close(Fd2), + + ?line {ok, Fd3} = ?PRIM_FILE:open(Allocate, [write, binary]), + allocate_and_assert(Fd3, 1, iolist_size(Line1) + 1), + ?line ok = ?PRIM_FILE:write(Fd3, Line1), + ?line ok = ?PRIM_FILE:write(Fd3, Line2), + ?line ok = ?PRIM_FILE:close(Fd3), + + ?line {ok, Fd4} = ?PRIM_FILE:open(Allocate, [write, binary]), + allocate_and_assert(Fd4, 1, 4 * iolist_size([Line1, Line2])), + ?line ok = ?PRIM_FILE:write(Fd4, Line1), + ?line ok = ?PRIM_FILE:write(Fd4, Line2), + ?line ok = ?PRIM_FILE:close(Fd4), + + ?line test_server:timetrap_cancel(Dog), + ok. + +allocate_and_assert(Fd, Offset, Length) -> + % Just verify that calls to ?PRIM_FILE:allocate/3 don't crash or have + % any other negative side effect. We can't really asssert against a + % specific return value, because support for file space pre-allocation + % depends on the OS, OS version and underlying filesystem. + % + % The Linux kernel added support for fallocate() in version 2.6.23, + % which currently works only for the ext4, ocfs2, xfs and btrfs file + % systems. posix_fallocate() is available in glibc as of version + % 2.1.94, but it was buggy until glibc version 2.7. + % + % Mac OS X, as of version 10.3, supports the fcntl operation F_PREALLOCATE. + % + % Solaris supports posix_fallocate() but only for the UFS file system + % apparently (not supported for ZFS). + % + % FreeBSD 9.0 is the first FreeBSD release supporting posix_fallocate(). + % + % For Windows there's apparently no way to pre-allocate file space, at + % least with similar API/semantics as posix_fallocate(), fallocate() or + % fcntl F_PREALLOCATE. + Result = ?PRIM_FILE:allocate(Fd, Offset, Length), + case os:type() of + {win32, _} -> + ?line {error, enotsup} = Result; + _ -> + ?line _ = Result + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + delete_a(suite) -> []; delete_a(doc) -> []; delete_a(Config) when is_list(Config) -> @@ -1508,9 +1576,7 @@ e_delete(Config) when is_list(Config) -> Base, #file_info {mode=8#600}); {win32, _} -> %% Remove a character device. - ?line {error, eacces} = ?PRIM_FILE:delete("nul"); - vxworks -> - ok + ?line {error, eacces} = ?PRIM_FILE:delete("nul") end, ?line test_server:timetrap_cancel(Dog), @@ -1524,110 +1590,105 @@ e_delete(Config) when is_list(Config) -> e_rename(suite) -> []; e_rename(doc) -> []; e_rename(Config) when is_list(Config) -> - case os:type() of - vxworks -> - {comment, "Windriver: dosFs must be fixed first!"}; - _ -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line RootDir = ?config(priv_dir, Config), - ?line Base = filename:join(RootDir, - atom_to_list(?MODULE)++"_e_rename"), - ?line ok = ?PRIM_FILE:make_dir(Base), - - %% Create an empty directory. - ?line EmptyDir = filename:join(Base, "empty_dir"), - ?line ok = ?PRIM_FILE:make_dir(EmptyDir), - - %% Create a non-empty directory. - ?line NonEmptyDir = filename:join(Base, "non_empty_dir"), - ?line ok = ?PRIM_FILE:make_dir(NonEmptyDir), - ?line ok = ?PRIM_FILE:write_file( - filename:join(NonEmptyDir, "a_file"), - "hello\n"), - - %% Create another non-empty directory. - ?line ADirectory = filename:join(Base, "a_directory"), - ?line ok = ?PRIM_FILE:make_dir(ADirectory), - ?line ok = ?PRIM_FILE:write_file( - filename:join(ADirectory, "a_file"), - "howdy\n\n"), + ?line Dog = test_server:timetrap(test_server:seconds(10)), + ?line RootDir = ?config(priv_dir, Config), + ?line Base = filename:join(RootDir, + atom_to_list(?MODULE)++"_e_rename"), + ?line ok = ?PRIM_FILE:make_dir(Base), - %% Create a data file. - ?line File = filename:join(Base, "just_a_file"), - ?line ok = ?PRIM_FILE:write_file(File, "anything goes\n\n"), - - %% Move an existing directory to a non-empty directory. - ?line {error, eexist} = - ?PRIM_FILE:rename(ADirectory, NonEmptyDir), - - %% Move a root directory. - ?line {error, einval} = ?PRIM_FILE:rename("/", "arne"), - - %% Move Base into Base/new_name. - ?line {error, einval} = - ?PRIM_FILE:rename(Base, filename:join(Base, "new_name")), - - %% Overwrite a directory with a file. - ?line expect({error, eexist}, % FreeBSD (?) - {error, eisdir}, - ?PRIM_FILE:rename(File, EmptyDir)), - ?line expect({error, eexist}, % FreeBSD (?) - {error, eisdir}, - ?PRIM_FILE:rename(File, NonEmptyDir)), - - %% Move a non-existing file. - ?line NonExistingFile = filename:join( - Base, "non_existing_file"), - ?line {error, enoent} = - ?PRIM_FILE:rename(NonExistingFile, NonEmptyDir), - - %% Overwrite a file with a directory. - ?line expect({error, eexist}, % FreeBSD (?) - {error, enotdir}, - ?PRIM_FILE:rename(ADirectory, File)), - - %% Move a file to another filesystem. - %% XXX - This test case is bogus. We cannot be guaranteed that - %% the source and destination are on - %% different filesystems. - %% - %% XXX - Gross hack! - ?line Comment = - case os:type() of - {unix, _} -> - OtherFs = "/tmp", - ?line NameOnOtherFs = - filename:join(OtherFs, - filename:basename(File)), - ?line {ok, Com} = - case ?PRIM_FILE:rename( - File, NameOnOtherFs) of - {error, exdev} -> - %% The file could be in - %% the same filesystem! - {ok, ok}; - ok -> - {ok, {comment, - "Moving between filesystems " - "suceeded, files are probably " - "in the same filesystem!"}}; - {error, eperm} -> - {ok, {comment, "SBS! You don't " - "have the permission to do " - "this test!"}}; - Else -> - Else - end, - Com; - {win32, _} -> - %% At least Windows NT can - %% successfully move a file to - %% another drive. - ok - end, - ?line test_server:timetrap_cancel(Dog), - Comment - end. + %% Create an empty directory. + ?line EmptyDir = filename:join(Base, "empty_dir"), + ?line ok = ?PRIM_FILE:make_dir(EmptyDir), + + %% Create a non-empty directory. + ?line NonEmptyDir = filename:join(Base, "non_empty_dir"), + ?line ok = ?PRIM_FILE:make_dir(NonEmptyDir), + ?line ok = ?PRIM_FILE:write_file( + filename:join(NonEmptyDir, "a_file"), + "hello\n"), + + %% Create another non-empty directory. + ?line ADirectory = filename:join(Base, "a_directory"), + ?line ok = ?PRIM_FILE:make_dir(ADirectory), + ?line ok = ?PRIM_FILE:write_file( + filename:join(ADirectory, "a_file"), + "howdy\n\n"), + + %% Create a data file. + ?line File = filename:join(Base, "just_a_file"), + ?line ok = ?PRIM_FILE:write_file(File, "anything goes\n\n"), + + %% Move an existing directory to a non-empty directory. + ?line {error, eexist} = + ?PRIM_FILE:rename(ADirectory, NonEmptyDir), + + %% Move a root directory. + ?line {error, einval} = ?PRIM_FILE:rename("/", "arne"), + + %% Move Base into Base/new_name. + ?line {error, einval} = + ?PRIM_FILE:rename(Base, filename:join(Base, "new_name")), + + %% Overwrite a directory with a file. + ?line expect({error, eexist}, % FreeBSD (?) + {error, eisdir}, + ?PRIM_FILE:rename(File, EmptyDir)), + ?line expect({error, eexist}, % FreeBSD (?) + {error, eisdir}, + ?PRIM_FILE:rename(File, NonEmptyDir)), + + %% Move a non-existing file. + ?line NonExistingFile = filename:join( + Base, "non_existing_file"), + ?line {error, enoent} = + ?PRIM_FILE:rename(NonExistingFile, NonEmptyDir), + + %% Overwrite a file with a directory. + ?line expect({error, eexist}, % FreeBSD (?) + {error, enotdir}, + ?PRIM_FILE:rename(ADirectory, File)), + + %% Move a file to another filesystem. + %% XXX - This test case is bogus. We cannot be guaranteed that + %% the source and destination are on + %% different filesystems. + %% + %% XXX - Gross hack! + ?line Comment = + case os:type() of + {unix, _} -> + OtherFs = "/tmp", + ?line NameOnOtherFs = + filename:join(OtherFs, + filename:basename(File)), + ?line {ok, Com} = + case ?PRIM_FILE:rename( + File, NameOnOtherFs) of + {error, exdev} -> + %% The file could be in + %% the same filesystem! + {ok, ok}; + ok -> + {ok, {comment, + "Moving between filesystems " + "suceeded, files are probably " + "in the same filesystem!"}}; + {error, eperm} -> + {ok, {comment, "SBS! You don't " + "have the permission to do " + "this test!"}}; + Else -> + Else + end, + Com; + {win32, _} -> + %% At least Windows NT can + %% successfully move a file to + %% another drive. + ok + end, + ?line test_server:timetrap_cancel(Dog), + Comment. e_make_dir(suite) -> []; e_make_dir(doc) -> []; @@ -1660,8 +1721,6 @@ e_make_dir(Config) when is_list(Config) -> ?line ?PRIM_FILE:write_file_info(Base, #file_info {mode=8#600}); {win32, _} -> - ok; - vxworks -> ok end, ?line test_server:timetrap_cancel(Dog), @@ -1716,8 +1775,6 @@ e_del_dir(Config) when is_list(Config) -> ?line ?PRIM_FILE:write_file_info( Base, #file_info {mode=8#600}); {win32, _} -> - ok; - vxworks -> ok end, ?line test_server:timetrap_cancel(Dog), @@ -1980,6 +2037,8 @@ symlinks(Config, Handle, Suffix) -> ?line #file_info{links=1, type=symlink} = Info2, ?line {ok, Name} = ?PRIM_FILE_call(read_link, Handle, [Alias]), + {ok, Name} = + ?PRIM_FILE_call(read_link_all, Handle, [Alias]), ok end, @@ -2085,6 +2144,41 @@ list_dir_limit_cleanup(Dir, Handle, N, Cnt) -> list_dir_limit_cleanup(Dir, Handle, N, Cnt+1). %%% +%%% Test list_dir() on a non-existing pathname. +%%% + +list_dir_error(Config) -> + Priv = ?config(priv_dir, Config), + NonExisting = filename:join(Priv, "non-existing-dir"), + {error,enoent} = prim_file:list_dir(NonExisting), + ok. + +%%% +%%% Test list_dir() and list_dir_all(). +%%% + +list_dir(Config) -> + RootDir = ?config(priv_dir, Config), + TestDir = filename:join(RootDir, ?MODULE_STRING++"_list_dir"), + ?PRIM_FILE:make_dir(TestDir), + list_dir_1(TestDir, 42, []). + +list_dir_1(TestDir, 0, Sorted) -> + [ok = ?PRIM_FILE:delete(filename:join(TestDir, F)) || + F <- Sorted], + ok = ?PRIM_FILE:del_dir(TestDir); +list_dir_1(TestDir, Cnt, Sorted0) -> + Base = "file" ++ integer_to_list(Cnt), + Name = filename:join(TestDir, Base), + ok = ?PRIM_FILE:write_file(Name, Base), + Sorted = lists:merge([Base], Sorted0), + {ok,DirList0} = ?PRIM_FILE:list_dir(TestDir), + {ok,DirList1} = ?PRIM_FILE:list_dir_all(TestDir), + Sorted = lists:sort(DirList0), + Sorted = lists:sort(DirList1), + list_dir_1(TestDir, Cnt-1, Sorted). + +%%% %%% Support for testing large files. %%% diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl index ab95a3ff5f..5c4437d4d3 100644 --- a/lib/kernel/test/ram_file_SUITE.erl +++ b/lib/kernel/test/ram_file_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% Copyright Ericsson AB 2001-2012. 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 @@ -167,7 +168,7 @@ pread_pwrite(suite) -> pread_pwrite(doc) -> ["Test that pread/2,3 and pwrite/2,3 works."]; pread_pwrite(Config) when is_list(Config) -> - ?line Str = "Flygande b�ckaziner s�ka hwila p� mjuqa tuvor x", + ?line Str = "Flygande bäckaziner söka hwila på mjuqa tuvor x", ?line Bin = list_to_binary(Str), %% pread_pwrite_test(?FILE_MODULE, Str, [ram, read, write]), @@ -206,7 +207,7 @@ position(suite) -> position(doc) -> ["Test that position/2 works."]; position(Config) when is_list(Config) -> - ?line Str = "Att vara eller icke vara, det �r fr�gan. ", + ?line Str = "Att vara eller icke vara, det är frågan. ", ?line Bin = list_to_binary(Str), %% position_test(?FILE_MODULE, Str, [ram, read]), @@ -287,8 +288,8 @@ truncate(suite) -> truncate(doc) -> ["Test that truncate/1 works."]; truncate(Config) when is_list(Config) -> - ?line Str = "M�n �dlare att lida och f�rdraga " - ++ "ett bittert �des stygn av pilar, ", + ?line Str = "Mån ädlare att lida och fördraga " + ++ "ett bittert ödes stygn av pilar, ", ?line Bin = list_to_binary(Str), %% ok = truncate_test(?FILE_MODULE, Str, [ram, read, write]), @@ -331,7 +332,7 @@ sync(suite) -> sync(doc) -> ["Test that sync/1 at least does not crash."]; sync(Config) when is_list(Config) -> - ?line Str = "�n att ta till vapen mot ett hav av kval. ", + ?line Str = "än att ta till vapen mot ett hav av kval. ", ?line Bin = list_to_binary(Str), %% sync_test(?FILE_MODULE, Str, [ram, read, write]), @@ -365,8 +366,8 @@ get_set_file(doc) -> ["Tests get_file/1, set_file/2, get_file_close/1 and get_size/1."]; get_set_file(Config) when is_list(Config) -> %% These two strings should not be of equal length. - ?line Str = "N�r h�gan nord blir sn�bet�ckt, ", - ?line Str2 = "f�r alla harar byta dr�kt. ", + ?line Str = "När högan nord blir snöbetäckt, ", + ?line Str2 = "får alla harar byta dräkt. ", ?line Bin = list_to_binary(Str), ?line Bin2 = list_to_binary(Str2), %% |