aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test/sendfile_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/test/sendfile_SUITE.erl')
-rw-r--r--lib/kernel/test/sendfile_SUITE.erl90
1 files changed, 74 insertions, 16 deletions
diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl
index 4cf4c6489d..2c741232c4 100644
--- a/lib/kernel/test/sendfile_SUITE.erl
+++ b/lib/kernel/test/sendfile_SUITE.erl
@@ -24,7 +24,14 @@
-compile(export_all).
-all() ->
+all() -> [{group,async_threads},
+ {group,no_async_threads}].
+
+groups() ->
+ [{async_threads,[],tcs()},
+ {no_async_threads,[],tcs()}].
+
+tcs() ->
[t_sendfile_small
,t_sendfile_big_all
,t_sendfile_big_size
@@ -33,6 +40,7 @@ all() ->
,t_sendfile_offset
,t_sendfile_sendafter
,t_sendfile_recvafter
+ ,t_sendfile_recvafter_remoteclose
,t_sendfile_sendduring
,t_sendfile_recvduring
,t_sendfile_closeduring
@@ -63,6 +71,14 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
file:delete(proplists:get_value(big_file, Config)).
+init_per_group(async_threads,Config) ->
+ [{sendfile_opts,[{use_threads,true}]}|Config];
+init_per_group(no_async_threads,Config) ->
+ [{sendfile_opts,[{use_threads,false}]}|Config].
+
+end_per_group(_,_Config) ->
+ ok.
+
init_per_testcase(TC,Config) when TC == t_sendfile_recvduring;
TC == t_sendfile_sendduring ->
Filename = proplists:get_value(small_file, Config),
@@ -71,7 +87,7 @@ init_per_testcase(TC,Config) when TC == t_sendfile_recvduring;
{_Size, Data} = sendfile_file_info(Filename),
{ok,D} = file:open(Filename, [raw,binary,read]),
prim_file:sendfile(D, Sock, 0, 0, 0,
- [],[],false,false,false),
+ [],[],[]),
Data
end,
@@ -92,6 +108,7 @@ t_sendfile_small(Config) when is_list(Config) ->
Send = fun(Sock) ->
{Size, Data} = sendfile_file_info(Filename),
+ %% Here we make sure to test the sendfile/2 api
{ok, Size} = file:sendfile(Filename, Sock),
Data
end,
@@ -101,6 +118,7 @@ t_sendfile_small(Config) when is_list(Config) ->
t_sendfile_many_small(Config) when is_list(Config) ->
Filename = proplists:get_value(small_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
error_logger:add_report_handler(?MODULE,[self()]),
@@ -109,7 +127,7 @@ t_sendfile_many_small(Config) when is_list(Config) ->
N = 10000,
{ok,D} = file:open(Filename,[read|FileOpts]),
[begin
- {ok,Size} = file:sendfile(D,Sock,0,0,[])
+ {ok,Size} = file:sendfile(D,Sock,0,0,SendfileOpts)
end || _I <- lists:seq(1,N)],
file:close(D),
Size*N
@@ -127,11 +145,12 @@ t_sendfile_many_small(Config) when is_list(Config) ->
t_sendfile_big_all(Config) when is_list(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{ok, #file_info{size = Size}} =
file:read_file_info(Filename),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
Size
end,
@@ -140,12 +159,13 @@ t_sendfile_big_all(Config) when is_list(Config) ->
t_sendfile_big_size(Config) ->
Filename = proplists:get_value(big_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
SendAll = fun(Sock) ->
{ok, #file_info{size = Size}} =
file:read_file_info(Filename),
{ok,D} = file:open(Filename,[read|FileOpts]),
- {ok, Size} = file:sendfile(D, Sock,0,Size,[]),
+ {ok, Size} = file:sendfile(D, Sock,0,Size,SendfileOpts),
Size
end,
@@ -154,12 +174,13 @@ t_sendfile_big_size(Config) ->
t_sendfile_partial(Config) ->
Filename = proplists:get_value(small_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
SendSingle = fun(Sock) ->
{_Size, <<Data:5/binary,_/binary>>} =
sendfile_file_info(Filename),
{ok,D} = file:open(Filename,[read|FileOpts]),
- {ok,5} = file:sendfile(D,Sock,0,5,[]),
+ {ok,5} = file:sendfile(D,Sock,0,5,SendfileOpts),
file:close(D),
Data
end,
@@ -170,14 +191,14 @@ t_sendfile_partial(Config) ->
{ok,D} = file:open(Filename,[read|FileOpts]),
{ok, <<FData/binary>>} = file:read(D,5),
FSend = fun(Sock) ->
- {ok,5} = file:sendfile(D,Sock,0,5,[]),
+ {ok,5} = file:sendfile(D,Sock,0,5,SendfileOpts),
FData
end,
ok = sendfile_send(FSend),
SSend = fun(Sock) ->
- {ok,3} = file:sendfile(D,Sock,5,3,[]),
+ {ok,3} = file:sendfile(D,Sock,5,3,SendfileOpts),
SData
end,
@@ -190,12 +211,13 @@ t_sendfile_partial(Config) ->
t_sendfile_offset(Config) ->
Filename = proplists:get_value(small_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{_Size, <<_:5/binary,Data:3/binary,_/binary>> = AllData} =
sendfile_file_info(Filename),
{ok,D} = file:open(Filename,[read|FileOpts]),
- {ok,3} = file:sendfile(D,Sock,5,3,[]),
+ {ok,3} = file:sendfile(D,Sock,5,3,SendfileOpts),
{ok, AllData} = file:read(D,100),
file:close(D),
Data
@@ -205,10 +227,11 @@ t_sendfile_offset(Config) ->
t_sendfile_sendafter(Config) ->
Filename = proplists:get_value(small_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{Size, Data} = sendfile_file_info(Filename),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
ok = gen_tcp:send(Sock, <<2>>),
<<Data/binary,2>>
end,
@@ -217,10 +240,11 @@ t_sendfile_sendafter(Config) ->
t_sendfile_recvafter(Config) ->
Filename = proplists:get_value(small_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{Size, Data} = sendfile_file_info(Filename),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
ok = gen_tcp:send(Sock, <<1>>),
{ok,<<1>>} = gen_tcp:recv(Sock, 1),
<<Data/binary,1>>
@@ -228,8 +252,28 @@ t_sendfile_recvafter(Config) ->
ok = sendfile_send(Send).
+%% This tests specifically for a bug fixed in 17.0
+t_sendfile_recvafter_remoteclose(Config) ->
+ Filename = proplists:get_value(small_file, Config),
+
+ Send = fun(Sock, SFServer) ->
+ {Size, _Data} = sendfile_file_info(Filename),
+ {ok, Size} = file:sendfile(Filename, Sock),
+
+ %% Make sure the remote end has been closed
+ SFServer ! stop,
+ timer:sleep(100),
+
+ %% In the bug this returned {error,ebadf}
+ {error,closed} = gen_tcp:recv(Sock, 1),
+ -1
+ end,
+
+ ok = sendfile_send({127,0,0,1},Send,0).
+
t_sendfile_sendduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{ok, #file_info{size = Size}} =
@@ -238,7 +282,7 @@ t_sendfile_sendduring(Config) ->
timer:sleep(50),
ok = gen_tcp:send(Sock, <<2>>)
end),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
Size+1
end,
@@ -246,6 +290,7 @@ t_sendfile_sendduring(Config) ->
t_sendfile_recvduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{ok, #file_info{size = Size}} =
@@ -255,7 +300,7 @@ t_sendfile_recvduring(Config) ->
ok = gen_tcp:send(Sock, <<1>>),
{ok,<<1>>} = gen_tcp:recv(Sock, 1)
end),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
timer:sleep(1000),
Size+1
end,
@@ -264,6 +309,7 @@ t_sendfile_recvduring(Config) ->
t_sendfile_closeduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock,SFServPid) ->
spawn_link(fun() ->
@@ -272,13 +318,14 @@ t_sendfile_closeduring(Config) ->
end),
case erlang:system_info(thread_pool_size) of
0 ->
- {error, closed} = file:sendfile(Filename, Sock);
+ {error, closed} = sendfile(Filename, Sock,
+ SendfileOpts);
_Else ->
%% This can return how much has been sent or
%% {error,closed} depending on OS.
%% How much is sent impossible to know as
%% the socket was closed mid sendfile
- case file:sendfile(Filename, Sock) of
+ case sendfile(Filename, Sock, SendfileOpts) of
{error, closed} ->
ok;
{ok, Size} when is_integer(Size) ->
@@ -292,6 +339,7 @@ t_sendfile_closeduring(Config) ->
t_sendfile_crashduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
error_logger:add_report_handler(?MODULE,[self()]),
@@ -300,7 +348,7 @@ t_sendfile_crashduring(Config) ->
timer:sleep(50),
exit(die)
end),
- {error, closed} = file:sendfile(Filename, Sock),
+ {error, closed} = sendfile(Filename, Sock, SendfileOpts),
-1
end,
process_flag(trap_exit,true),
@@ -395,6 +443,16 @@ sendfile_file_info(File) ->
{ok, Data} = file:read_file(File),
{Size, Data}.
+sendfile(Filename,Sock,Opts) ->
+ case file:open(Filename, [read, raw, binary]) of
+ {error, Reason} ->
+ {error, Reason};
+ {ok, Fd} ->
+ Res = file:sendfile(Fd, Sock, 0, 0, Opts),
+ _ = file:close(Fd),
+ Res
+ end.
+
%% Error handler