diff options
Diffstat (limited to 'lib/kernel/test')
| -rw-r--r-- | lib/kernel/test/file_SUITE.erl | 184 | ||||
| -rw-r--r-- | lib/kernel/test/gen_tcp_misc_SUITE.erl | 17 | ||||
| -rw-r--r-- | lib/kernel/test/gen_udp_SUITE.erl | 11 | ||||
| -rw-r--r-- | lib/kernel/test/global_SUITE.erl | 13 | ||||
| -rw-r--r-- | lib/kernel/test/interactive_shell_SUITE.erl | 60 | ||||
| -rw-r--r-- | lib/kernel/test/interactive_shell_SUITE_data/.gitignore | 1 | ||||
| -rw-r--r-- | lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl | 6 | ||||
| -rw-r--r-- | lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl | 6 |
8 files changed, 281 insertions, 17 deletions
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index 21aaefa654..9efe83d8b3 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -58,6 +58,8 @@ -export([ file_info_basic_file/1, file_info_basic_directory/1, file_info_bad/1, file_info_times/1, file_write_file_info/1, file_wfi_helpers/1]). +-export([ file_handle_info_basic_file/1, file_handle_info_basic_directory/1, + file_handle_info_times/1]). -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]). @@ -153,7 +155,10 @@ groups() -> {pos, [], [pos1, pos2, pos3]}, {file_info, [], [file_info_basic_file, file_info_basic_directory, - file_info_bad, file_info_times, file_write_file_info, + file_info_bad, file_info_times, + file_handle_info_basic_file, file_handle_info_basic_directory, + file_handle_info_times, + file_write_file_info, file_wfi_helpers]}, {consult, [], [consult1, path_consult]}, {eval, [], [eval1, path_eval]}, @@ -1417,7 +1422,8 @@ file_info_basic_directory(Config) when is_list(Config) -> {win32, _} -> test_directory("/", read_write), test_directory("c:/", read_write), - test_directory("c:\\", read_write); + test_directory("c:\\", read_write), + test_directory("\\\\localhost\\c$", read_write); _ -> test_directory("/", read) end, @@ -1549,6 +1555,180 @@ filter_atime(Atime, Config) -> Atime end. +%% Test read_file_info on I/O devices. + +file_handle_info_basic_file(Config) when is_list(Config) -> + RootDir = proplists:get_value(priv_dir, Config), + + %% Create a short file. + Name = filename:join(RootDir, + atom_to_list(?MODULE) + ++"_basic_test.fil"), + {ok,Fd1} = ?FILE_MODULE:open(Name, write), + io:put_chars(Fd1, "foo bar"), + ok = ?FILE_MODULE:close(Fd1), + + %% Test that the file has the expected attributes. + %% The times are tricky, so we will save them to a separate test case. + + {ok, Fd} = ?FILE_MODULE:open(Name, read), + {ok,FileInfo} = ?FILE_MODULE:read_file_info(Fd), + ok = ?FILE_MODULE:close(Fd), + + {ok, FdRaw} = ?FILE_MODULE:open(Name, [read, raw]), + {ok,FileInfoRaw} = ?FILE_MODULE:read_file_info(FdRaw), + ok = ?FILE_MODULE:close(FdRaw), + + #file_info{size=Size,type=Type,access=Access, + atime=AccessTime,mtime=ModifyTime} = FileInfo = FileInfoRaw, + io:format("Access ~p, Modify ~p", [AccessTime, ModifyTime]), + Size = 7, + Type = regular, + read_write = Access, + true = abs(time_dist(filter_atime(AccessTime, Config), + filter_atime(ModifyTime, + Config))) < 5, + all_integers(tuple_to_list(AccessTime) ++ tuple_to_list(ModifyTime)), + + [] = flush(), + ok. + +file_handle_info_basic_directory(Config) when is_list(Config) -> + %% Note: filename:join/1 removes any trailing slash, + %% which is essential for ?FILE_MODULE:file_info/1 to work on + %% platforms such as Windows95. + RootDir = filename:join([proplists:get_value(priv_dir, Config)]), + + %% Test that the RootDir directory has the expected attributes. + test_directory_handle(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. + case os:type() of + {win32, _} -> + test_directory_handle("/", read_write), + test_directory_handle("c:/", read_write), + test_directory_handle("c:\\", read_write), + test_directory_handle("\\\\localhost\\c$", read_write); + _ -> + test_directory_handle("/", read) + end, + ok. + +test_directory_handle(Name, ExpectedAccess) -> + {ok, DirFd} = file:open(Name, [read, directory]), + try + {ok,FileInfo} = ?FILE_MODULE:read_file_info(DirFd), + {ok,FileInfo} = ?FILE_MODULE:read_file_info(DirFd, [raw]), + #file_info{size=Size,type=Type,access=Access, + atime=AccessTime,mtime=ModifyTime} = FileInfo, + io:format("Testing directory ~s", [Name]), + io:format("Directory size is ~p", [Size]), + io:format("Access ~p", [Access]), + io:format("Access time ~p; Modify time~p", + [AccessTime, ModifyTime]), + Type = directory, + Access = ExpectedAccess, + all_integers(tuple_to_list(AccessTime) ++ tuple_to_list(ModifyTime)), + [] = flush(), + ok + after + file:close(DirFd) + end. + +%% Test that the file times behave as they should. + +file_handle_info_times(Config) when is_list(Config) -> + %% We have to try this twice, since if the test runs across the change + %% of a month the time diff calculations will fail. But it won't happen + %% if you run it twice in succession. + test_server:m_out_of_n( + 1,2, + fun() -> file_handle_info_int(Config) end), + ok. + +file_handle_info_int(Config) -> + %% Note: filename:join/1 removes any trailing slash, + %% which is essential for ?FILE_MODULE:file_info/1 to work on + %% platforms such as Windows95. + + RootDir = filename:join([proplists:get_value(priv_dir, Config)]), + io:format("RootDir = ~p", [RootDir]), + + Name = filename:join(RootDir, + atom_to_list(?MODULE) + ++"_file_info.fil"), + {ok,Fd1} = ?FILE_MODULE:open(Name, write), + io:put_chars(Fd1,"foo"), + {ok,FileInfo1} = ?FILE_MODULE:read_file_info(Fd1), + ok = ?FILE_MODULE:close(Fd1), + + {ok,Fd1Raw} = ?FILE_MODULE:open(Name, [read, raw]), + {ok,FileInfo1Raw} = ?FILE_MODULE:read_file_info(Fd1Raw), + ok = ?FILE_MODULE:close(Fd1Raw), + + %% We assert that everything but the size is the same, on some OSs the + %% size may not have been flushed to disc and we do not want to do a + %% sync to force it. + FileInfo1Raw = FileInfo1#file_info{ size = FileInfo1Raw#file_info.size }, + + #file_info{type=regular,atime=AccTime1,mtime=ModTime1} = FileInfo1, + + Now = erlang:localtime(), %??? + io:format("Now ~p",[Now]), + io:format("Open file Acc ~p Mod ~p",[AccTime1,ModTime1]), + true = abs(time_dist(filter_atime(Now, Config), + filter_atime(AccTime1, + Config))) < 8, + true = abs(time_dist(Now,ModTime1)) < 8, + + %% Sleep until we can be sure the seconds value has changed. + %% Note: FAT-based filesystem (like on Windows 95) have + %% a resolution of 2 seconds. + timer:sleep(2200), + + %% close the file, and watch the modify date change + + {ok,Fd2} = ?FILE_MODULE:open(Name, read), + {ok,FileInfo2} = ?FILE_MODULE:read_file_info(Fd2), + ok = ?FILE_MODULE:close(Fd2), + + {ok,Fd2Raw} = ?FILE_MODULE:open(Name, [read, raw]), + {ok,FileInfo2Raw} = ?FILE_MODULE:read_file_info(Fd2Raw), + ok = ?FILE_MODULE:close(Fd2Raw), + + #file_info{size=Size,type=regular,access=Access, + atime=AccTime2,mtime=ModTime2} = FileInfo2 = FileInfo2Raw, + io:format("Closed file Acc ~p Mod ~p",[AccTime2,ModTime2]), + true = time_dist(ModTime1,ModTime2) >= 0, + + %% this file is supposed to be binary, so it'd better keep it's size + Size = 3, + Access = read_write, + + %% Do some directory checking + + {ok,Fd3} = ?FILE_MODULE:open(RootDir, [read, directory]), + {ok,FileInfo3} = ?FILE_MODULE:read_file_info(Fd3), + ok = ?FILE_MODULE:close(Fd3), + + {ok,Fd3Raw} = ?FILE_MODULE:open(RootDir, [read, directory, raw]), + {ok,FileInfo3Raw} = ?FILE_MODULE:read_file_info(Fd3Raw), + ok = ?FILE_MODULE:close(Fd3Raw), + + #file_info{size=DSize,type=directory,access=DAccess, + atime=AccTime3,mtime=ModTime3} = FileInfo3 = FileInfo3Raw, + %% this dir was modified only a few secs ago + io:format("Dir Acc ~p; Mod ~p; Now ~p", [AccTime3, ModTime3, Now]), + true = abs(time_dist(Now,ModTime3)) < 5, + DAccess = read_write, + io:format("Dir size is ~p",[DSize]), + + [] = flush(), + ok. + %% Test the write_file_info/2 function. file_write_file_info(Config) when is_list(Config) -> diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index 421510f9d6..de87bd9472 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2018. All Rights Reserved. +%% Copyright Ericsson AB 1998-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -2019,7 +2019,7 @@ recvtclass(_Config) -> %% platforms - change {unix,_} to false? %% pktoptions is not supported for IPv4 -recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0}); +recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0}); recvtos_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0}); %% Using the option returns einval, so it is not implemented. recvtos_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0}); @@ -2031,7 +2031,7 @@ recvtos_ok({unix,_}, _) -> true; recvtos_ok(_, _) -> false. %% pktoptions is not supported for IPv4 -recvttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0}); +recvttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0}); recvttl_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0}); %% Using the option returns einval, so it is not implemented. recvttl_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0}); @@ -2043,7 +2043,7 @@ recvttl_ok({unix,_}, _) -> true; recvttl_ok(_, _) -> false. %% pktoptions is not supported for IPv6 -recvtclass_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0}); +recvtclass_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0}); recvtclass_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0}); recvtclass_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0}); %% Using the option returns einval, so it is not implemented. @@ -2224,18 +2224,19 @@ collect_accepts(N,Tmo) -> A = millis(), receive {accepted,P,Msg} -> - [{P,Msg}] ++ collect_accepts(N-1,Tmo-(millis() - A)) + NextN = if N =:= infinity -> N; true -> N - 1 end, + [{P,Msg}] ++ collect_accepts(NextN, Tmo - (millis()-A)) after Tmo -> [] end. -define(EXPECT_ACCEPTS(Pattern,N,Timeout), (fun() -> - case collect_accepts(if N =:= infinity -> -1; true -> N end,Timeout) of + case collect_accepts((N), (Timeout)) of Pattern -> ok; - Other -> - {error,{unexpected,{Other,process_info(self(),messages)}}} + Other__ -> + {error,{unexpected,{Other__,process_info(self(),messages)}}} end end)()). diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index 730886865c..70d8caf478 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2018. All Rights Reserved. +%% Copyright Ericsson AB 1998-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -646,7 +646,7 @@ sendtclass(_Config) -> %% Using the option returns einval, so it is not implemented. recvtos_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {17,6,0}); %% Using the option returns einval, so it is not implemented. -recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,4,0}); +recvtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0}); %% Using the option returns einval, so it is not implemented. recvtos_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0}); %% @@ -675,7 +675,7 @@ recvtclass_ok(_, _) -> false. %% Using the option returns einval, so it is not implemented. sendtos_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {19,0,0}); -sendtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,5,0}); +sendtos_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0}); sendtos_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0}); sendtos_ok({unix,linux}, OSVer) -> not semver_lt(OSVer, {4,0,0}); sendtos_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0}); @@ -689,7 +689,8 @@ sendttl_ok({unix,linux}, OSVer) -> not semver_lt(OSVer, {4,0,0}); %% Using the option returns enoprotoopt, so it is not implemented. sendttl_ok({unix,freebsd}, OSVer) -> not semver_lt(OSVer, {12,1,0}); %% Option has no effect -sendttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,5,0}); +sendttl_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0}); +sendttl_ok({unix,openbsd}, OSVer) -> not semver_lt(OSVer, {6,6,0}); %% sendttl_ok({unix,_}, _) -> true; sendttl_ok(_, _) -> false. @@ -697,6 +698,8 @@ sendttl_ok(_, _) -> false. %% Using the option returns einval, so it is not implemented. sendtclass_ok({unix,darwin}, OSVer) -> not semver_lt(OSVer, {9,9,0}); sendtclass_ok({unix,linux}, OSVer) -> not semver_lt(OSVer, {2,6,11}); +%% Option has no effect +sendtclass_ok({unix,sunos}, OSVer) -> not semver_lt(OSVer, {5,12,0}); %% sendtclass_ok({unix,_}, _) -> true; sendtclass_ok(_, _) -> false. diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl index 8eab36e308..5bff9cc292 100644 --- a/lib/kernel/test/global_SUITE.erl +++ b/lib/kernel/test/global_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2018. All Rights Reserved. +%% Copyright Ericsson AB 1997-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -2512,8 +2512,10 @@ re_register_name(Config) when is_list(Config) -> Me = self(), Pid1 = spawn(fun() -> proc(Me) end), yes = global:register_name(name, Pid1), + wait_for_monitor(Pid1), Pid2 = spawn(fun() -> proc(Me) end), _ = global:re_register_name(name, Pid2), + wait_for_monitor(Pid2), Pid2 ! die, Pid1 ! die, receive {Pid1, MonitoredBy1} -> [] = MonitoredBy1 end, @@ -2522,6 +2524,15 @@ re_register_name(Config) when is_list(Config) -> init_condition(Config), ok. +wait_for_monitor(Pid) -> + case process_info(Pid, monitored_by) of + {monitored_by, []} -> + timer:sleep(1), + wait_for_monitor(Pid); + {monitored_by, [_]} -> + ok + end. + proc(Parent) -> receive die -> ok end, {monitored_by, MonitoredBy} = process_info(self(), monitored_by), diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl index 298a364a91..173e25c520 100644 --- a/lib/kernel/test/interactive_shell_SUITE.erl +++ b/lib/kernel/test/interactive_shell_SUITE.erl @@ -23,7 +23,8 @@ init_per_group/2,end_per_group/2, get_columns_and_rows/1, exit_initial/1, job_control_local/1, job_control_remote/1, - job_control_remote_noshell/1,ctrl_keys/1]). + job_control_remote_noshell/1,ctrl_keys/1, + get_columns_and_rows_escript/1]). -export([init_per_testcase/2, end_per_testcase/2]). %% For spawn @@ -40,7 +41,8 @@ suite() -> {timetrap,{minutes,3}}]. all() -> - [get_columns_and_rows, exit_initial, job_control_local, + [get_columns_and_rows_escript,get_columns_and_rows, + exit_initial, job_control_local, job_control_remote, job_control_remote_noshell, ctrl_keys]. @@ -72,6 +74,60 @@ end_per_group(_GroupName, Config) -> -define(dbg(Data),noop). -endif. +string_to_term(Str) -> + {ok,Tokens,_EndLine} = erl_scan:string(Str ++ "."), + {ok,AbsForm} = erl_parse:parse_exprs(Tokens), + {value,Value,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()), + Value. + +run_unbuffer_escript(Rows, Columns, EScript, NoTermStdIn, NoTermStdOut) -> + DataDir = filename:join(filename:dirname(code:which(?MODULE)), "interactive_shell_SUITE_data"), + TmpFile = filename:join(DataDir, "tmp"), + ok = file:write_file(TmpFile, <<>>), + CommandModifier = + case {NoTermStdIn, NoTermStdOut} of + {false, false} -> ""; + {true, false} -> io_lib:format(" < ~s", [TmpFile]); + {false, true} -> io_lib:format(" > ~s ; cat ~s", [TmpFile, TmpFile]); + {true, true} -> io_lib:format(" > ~s < ~s ; cat ~s", [TmpFile, TmpFile, TmpFile]) + end, + Command = io_lib:format("unbuffer -p bash -c \"stty rows ~p; stty columns ~p; escript ~s ~s\"", + [Rows, Columns, EScript, CommandModifier]), + %% io:format("Command: ~s ~n", [Command]), + Out = os:cmd(Command), + %% io:format("Out: ~p ~n", [Out]), + string_to_term(Out). + +get_columns_and_rows_escript(Config) when is_list(Config) -> + ExpectUnbufferInstalled = + try + "79" = string:trim(os:cmd("unbuffer -p bash -c \"stty columns 79 ; tput cols\"")), + true + catch + _:_ -> false + end, + case ExpectUnbufferInstalled of + false -> + {skip, + "The unbuffer tool (https://core.tcl-lang.org/expect/index) does not seem to be installed.~n" + "On Ubuntu/Debian: \"sudo apt-get install expect\""}; + true -> + DataDir = filename:join(filename:dirname(code:which(?MODULE)), "interactive_shell_SUITE_data"), + IoColumnsErl = filename:join(DataDir, "io_columns.erl"), + IoRowsErl = filename:join(DataDir, "io_rows.erl"), + [ + begin + {ok, 42} = run_unbuffer_escript(99, 42, IoColumnsErl, NoTermStdIn, NoTermStdOut), + {ok, 99} = run_unbuffer_escript(99, 42, IoRowsErl, NoTermStdIn, NoTermStdOut) + end + || + {NoTermStdIn, NoTermStdOut} <- [{false, false}, {true, false}, {false, true}] + ], + {error,enotsup} = run_unbuffer_escript(99, 42, IoRowsErl, true, true), + {error,enotsup} = run_unbuffer_escript(99, 42, IoColumnsErl, true, true), + ok + end. + %% Test that the shell can access columns and rows. get_columns_and_rows(Config) when is_list(Config) -> case proplists:get_value(default_shell,Config) of diff --git a/lib/kernel/test/interactive_shell_SUITE_data/.gitignore b/lib/kernel/test/interactive_shell_SUITE_data/.gitignore new file mode 100644 index 0000000000..1c2f433de1 --- /dev/null +++ b/lib/kernel/test/interactive_shell_SUITE_data/.gitignore @@ -0,0 +1 @@ +tmp
\ No newline at end of file diff --git a/lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl b/lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl new file mode 100644 index 0000000000..32d0cf25df --- /dev/null +++ b/lib/kernel/test/interactive_shell_SUITE_data/io_columns.erl @@ -0,0 +1,6 @@ +-module(io_columns). + +-export([main/1]). + +main(_) -> + io:format("~p",[io:columns()]). diff --git a/lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl b/lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl new file mode 100644 index 0000000000..53ceb464b0 --- /dev/null +++ b/lib/kernel/test/interactive_shell_SUITE_data/io_rows.erl @@ -0,0 +1,6 @@ +-module(io_rows). + +-export([main/1]). + +main(_) -> + io:format("~p",[io:rows()]). |
