aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test/ram_file_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/test/ram_file_SUITE.erl')
-rw-r--r--lib/kernel/test/ram_file_SUITE.erl651
1 files changed, 651 insertions, 0 deletions
diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl
new file mode 100644
index 0000000000..55c9497670
--- /dev/null
+++ b/lib/kernel/test/ram_file_SUITE.erl
@@ -0,0 +1,651 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. 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(ram_file_SUITE).
+
+-export([all/1,
+ %% init/1, fini/1,
+ init_per_testcase/2, fin_per_testcase/2]).
+-export([open_modes/1, open_old_modes/1, pread_pwrite/1, position/1,
+ truncate/1, sync/1, get_set_file/1, compress/1, uuencode/1,
+ large_file_errors/1, large_file_light/1, large_file_heavy/1]).
+
+-include("test_server.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-define(FILE_MODULE, file). % Name of module to test
+-define(RAM_FILE_MODULE, ram_file). % Name of module to test
+
+%%--------------------------------------------------------------------------
+
+all(suite) ->
+ [open_modes, open_old_modes, pread_pwrite, position,
+ truncate, sync, get_set_file, compress, uuencode,
+ large_file_errors, large_file_light, large_file_heavy].
+
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Time =
+ case Func of
+ large_file_heavy ->
+ ?t:minutes(5);
+ _ ->
+ ?t:seconds(10)
+ end,
+ Dog = ?t:timetrap(Time),
+ %% error_logger:info_msg("~p:~p *****~n", [?MODULE, Func]),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Func, Config) ->
+ %% error_logger:info_msg("~p:~p END *****~n", [?MODULE, Func]),
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog).
+
+%%--------------------------------------------------------------------------
+%% Test suites
+
+open_modes(suite) ->
+ [];
+open_modes(doc) ->
+ ["Test that the basic read, write and binary options works for open/2."];
+open_modes(Config) when is_list(Config) ->
+ ?line Str1 = "The quick brown fox ",
+ ?line Str2 = "jumps over a lazy dog ",
+ ?line Str = Str1 ++ Str2,
+ ?line Bin1 = list_to_binary(Str1),
+ ?line Bin2 = list_to_binary(Str2),
+ ?line Bin = list_to_binary(Str),
+ %%
+ open_read_write(?FILE_MODULE, Str1, [ram, read, write], Str2),
+ open_read(?FILE_MODULE, Str, [ram]),
+ open_read_write(?FILE_MODULE, Bin1, [ram, binary, read, write], Bin2),
+ open_read(?FILE_MODULE, Bin, [ram, binary, read]),
+ %%
+ ok.
+
+open_old_modes(suite) ->
+ [];
+open_old_modes(doc) ->
+ ["Test that the old style read, write and binary options ",
+ "works for open/2."];
+open_old_modes(Config) when is_list(Config) ->
+ ?line Str1 = "The quick brown fox ",
+ ?line Str2 = "jumps over a lazy dog ",
+ ?line Str = Str1 ++ Str2,
+ ?line Bin1 = list_to_binary(Str1),
+ ?line Bin2 = list_to_binary(Str2),
+ ?line Bin = list_to_binary(Str),
+ %%
+ open_read_write(?RAM_FILE_MODULE, Str1, read_write, Str2),
+ open_read(?RAM_FILE_MODULE, Str, read),
+ open_read_write(?RAM_FILE_MODULE, Bin1, {binary, read_write}, Bin2),
+ open_read(?RAM_FILE_MODULE, Bin, {binary, read}),
+ %%
+ ok.
+
+open_read_write(Module, Data1, Options, Data2) ->
+ ?line io:format("~p:open_read_write(~p, ~p, ~p, ~p)~n",
+ [?MODULE, Module, Data1, Options, Data2]),
+ %%
+ ?line Size1 = sizeof(Data1),
+ ?line Size2 = sizeof(Data2),
+ ?line Data = append(Data1, Data2),
+ ?line Size = Size1 + Size2,
+ %%
+ ?line {ok, Fd} = Module:open(Data1, Options),
+ ?line {ok, Data1} = Module:read(Fd, Size1),
+ ?line eof = Module:read(Fd, 1),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ ?line 0 = sizeof(Zero),
+ ?line ok = Module:write(Fd, Data2),
+ ?line {ok, 0} = Module:position(Fd, bof),
+ ?line {ok, Data} = Module:read(Fd, Size),
+ ?line eof = Module:read(Fd, 1),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ ?line ok = Module:close(Fd),
+ %%
+ ?line ok.
+
+open_read(Module, Data, Options) ->
+ ?line io:format("~p:open_read(~p, ~p, ~p)~n",
+ [?MODULE, Module, Data, Options]),
+ %%
+ ?line Size = sizeof(Data),
+ %%
+ ?line {ok, Fd} = Module:open(Data, Options),
+ ?line {ok, Data} = Module:read(Fd, Size),
+ ?line eof = Module:read(Fd, 1),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ ?line 0 = sizeof(Zero),
+ ?line {error, ebadf} = Module:write(Fd, Data),
+ ?line {ok, 0} = Module:position(Fd, bof),
+ ?line {ok, Data} = Module:read(Fd, Size),
+ ?line eof = Module:read(Fd, 1),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ ?line ok = Module:close(Fd),
+ %%
+ ?line ok.
+
+
+
+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 Bin = list_to_binary(Str),
+ %%
+ pread_pwrite_test(?FILE_MODULE, Str, [ram, read, write]),
+ pread_pwrite_test(?FILE_MODULE, Bin, [ram, binary, read, write]),
+ pread_pwrite_test(?RAM_FILE_MODULE, Str, [read, write]),
+ pread_pwrite_test(?RAM_FILE_MODULE, Bin, {binary, read_write}),
+ %%
+ ok.
+
+pread_pwrite_test(Module, Data, Options) ->
+ ?line io:format("~p:pread_pwrite_test(~p, ~p, ~p)~n",
+ [?MODULE, Module, Data, Options]),
+ %%
+ ?line Size = sizeof(Data),
+ %%
+ ?line {ok, Fd} = Module:open([], Options),
+ ?line ok = Module:pwrite(Fd, 0, Data),
+ ?line {ok, Data} = Module:pread(Fd, 0, Size+1),
+ ?line eof = Module:pread(Fd, Size+1, 1),
+ ?line {ok, Zero} = Module:pread(Fd, Size+1, 0),
+ ?line 0 = sizeof(Zero),
+ ?line ok = Module:pwrite(Fd, [{0, Data}, {Size+17, Data}]),
+ ?line {ok, [Data,
+ eof,
+ Data,
+ Zero]} = Module:pread(Fd, [{Size+17, Size+1},
+ {2*Size+17+1, 1},
+ {0, Size},
+ {2*Size+17+1, 0}]),
+ ?line ok = Module:close(Fd),
+ %%
+ ?line ok.
+
+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 Bin = list_to_binary(Str),
+ %%
+ position_test(?FILE_MODULE, Str, [ram, read]),
+ position_test(?FILE_MODULE, Bin, [ram, binary]),
+ position_test(?RAM_FILE_MODULE, Str, [read]),
+ position_test(?RAM_FILE_MODULE, Bin, {binary, read}),
+ %%
+ ok.
+
+position_test(Module, Data, Options) ->
+ ?line io:format("~p:position_test(~p, ~p, ~p)~n",
+ [?MODULE, Module, Data, Options]),
+ %%
+ ?line Size = sizeof(Data),
+ ?line Size_7 = Size+7,
+ %%
+ ?line Slice_0_2 = slice(Data, 0, 2),
+ ?line Slice_0_3 = slice(Data, 0, 3),
+ ?line Slice_2_5 = slice(Data, 2, 5),
+ ?line Slice_3_4 = slice(Data, 3, 4),
+ ?line Slice_5 = slice(Data, 5, Size),
+ %%
+ ?line {ok, Fd} = Module:open(Data, Options),
+ %%
+ ?line io:format("CUR positions"),
+ ?line {ok, Slice_0_2} = Module:read(Fd, 2),
+ ?line {ok, 2} = Module:position(Fd, cur),
+ ?line {ok, Slice_2_5} = Module:read(Fd, 5),
+ ?line {ok, 3} = Module:position(Fd, {cur, -4}),
+ ?line {ok, Slice_3_4} = Module:read(Fd, 4),
+ ?line {ok, 0} = Module:position(Fd, {cur, -7}),
+ ?line {ok, Slice_0_3} = Module:read(Fd, 3),
+ ?line {ok, 0} = Module:position(Fd, {cur, -3}),
+ ?line {error, einval} = Module:position(Fd, {cur, -1}),
+ ?line {ok, 0} = Module:position(Fd, 0),
+ ?line {ok, 2} = Module:position(Fd, {cur, 2}),
+ ?line {ok, Slice_2_5} = Module:read(Fd, 5),
+ ?line {ok, Size_7} = Module:position(Fd, {cur, Size}),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ ?line 0 = sizeof(Zero),
+ ?line eof = Module:read(Fd, 1),
+ %%
+ ?line io:format("Absolute and BOF positions"),
+ ?line {ok, Size} = Module:position(Fd, Size),
+ ?line eof = Module:read(Fd, 1),
+ ?line {ok, 5} = Module:position(Fd, 5),
+ ?line {ok, Slice_5} = Module:read(Fd, Size),
+ ?line {ok, 2} = Module:position(Fd, {bof, 2}),
+ ?line {ok, Slice_2_5} = Module:read(Fd, 5),
+ ?line {ok, 3} = Module:position(Fd, 3),
+ ?line {ok, Slice_3_4} = Module:read(Fd, 4),
+ ?line {ok, 0} = Module:position(Fd, bof),
+ ?line {ok, Slice_0_2} = Module:read(Fd, 2),
+ ?line {ok, Size_7} = Module:position(Fd, {bof, Size_7}),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ %%
+ ?line io:format("EOF positions"),
+ ?line {ok, Size} = Module:position(Fd, eof),
+ ?line eof = Module:read(Fd, 1),
+ ?line {ok, 5} = Module:position(Fd, {eof, -Size+5}),
+ ?line {ok, Slice_5} = Module:read(Fd, Size),
+ ?line {ok, 2} = Module:position(Fd, {eof, -Size+2}),
+ ?line {ok, Slice_2_5} = Module:read(Fd, 5),
+ ?line {ok, 3} = Module:position(Fd, {eof, -Size+3}),
+ ?line {ok, Slice_3_4} = Module:read(Fd, 4),
+ ?line {ok, 0} = Module:position(Fd, {eof, -Size}),
+ ?line {ok, Slice_0_2} = Module:read(Fd, 2),
+ ?line {ok, Size_7} = Module:position(Fd, {eof, 7}),
+ ?line {ok, Zero} = Module:read(Fd, 0),
+ ?line eof = Module:read(Fd, 1),
+ %%
+ ?line ok.
+
+
+
+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 Bin = list_to_binary(Str),
+ %%
+ ok = truncate_test(?FILE_MODULE, Str, [ram, read, write]),
+ ok = truncate_test(?FILE_MODULE, Bin, [ram, binary, read, write]),
+ ok = truncate_test(?RAM_FILE_MODULE, Str, read_write),
+ ok = truncate_test(?RAM_FILE_MODULE, Bin, [binary, read, write]),
+ %%
+ {error, eacces} = truncate_test(?FILE_MODULE, Str, [ram]),
+ {error, eacces} = truncate_test(?FILE_MODULE, Bin, [ram, binary, read]),
+ {error, eacces} = truncate_test(?RAM_FILE_MODULE, Str, read),
+ {error, eacces} = truncate_test(?RAM_FILE_MODULE, Bin, {binary, read}),
+ %%
+ ok.
+
+truncate_test(Module, Data, Options) ->
+ ?line io:format("~p:truncate_test(~p, ~p, ~p)~n",
+ [?MODULE, Module, Data, Options]),
+ %%
+ ?line Size = sizeof(Data),
+ ?line Size1 = Size-2,
+ ?line Data1 = slice(Data, 0, Size1),
+ %%
+ ?line {ok, Fd} = Module:open(Data, Options),
+ ?line {ok, Size1} = Module:position(Fd, Size1),
+ ?line case Module:truncate(Fd) of
+ ok ->
+ ?line {ok, 0} = Module:position(Fd, 0),
+ ?line {ok, Data1} = Module:read(Fd, Size),
+ ?line ok = Module:close(Fd),
+ ?line ok;
+ Error ->
+ ?line ok = Module:close(Fd),
+ ?line Error
+ end.
+
+
+
+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 Bin = list_to_binary(Str),
+ %%
+ sync_test(?FILE_MODULE, Str, [ram, read, write]),
+ sync_test(?FILE_MODULE, Bin, [ram, binary, read, write]),
+ sync_test(?RAM_FILE_MODULE, Str, read_write),
+ sync_test(?RAM_FILE_MODULE, Bin, [binary, read, write]),
+ %%
+ sync_test(?FILE_MODULE, Str, [ram]),
+ sync_test(?FILE_MODULE, Bin, [ram, binary, read]),
+ sync_test(?RAM_FILE_MODULE, Str, read),
+ sync_test(?RAM_FILE_MODULE, Bin, {binary, read}),
+ %%
+ ok.
+
+sync_test(Module, Data, Options) ->
+ ?line io:format("~p:sync_test(~p, ~p, ~p)~n",
+ [?MODULE, Module, Data, Options]),
+ %%
+ ?line Size = sizeof(Data),
+ %%
+ ?line {ok, Fd} = Module:open(Data, Options),
+ ?line ok = Module:sync(Fd),
+ ?line {ok, Data} = Module:read(Fd, Size+1),
+ ?line ok.
+
+
+
+get_set_file(suite) ->
+ [];
+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 Bin = list_to_binary(Str),
+ ?line Bin2 = list_to_binary(Str2),
+ %%
+ ok = get_set_file_test(Str, read_write, Str2),
+ ok = get_set_file_test(Bin, [binary, read, write], Bin2),
+ ok = get_set_file_test(Str, read, Str2),
+ ok = get_set_file_test(Bin, [binary, read], Bin2),
+ %%
+ ok.
+
+get_set_file_test(Data, Options, Data2) ->
+ ?line io:format("~p:get_set_file_test(~p, ~p, ~p)~n",
+ [?MODULE, Data, Options, Data2]),
+ %%
+ ?line Size = sizeof(Data),
+ ?line Size2 = sizeof(Data2),
+ %%
+ ?line {ok, Fd} = ?RAM_FILE_MODULE:open(Data, Options),
+ ?line {ok, Size} = ?RAM_FILE_MODULE:get_size(Fd),
+ ?line {ok, Data} = ?RAM_FILE_MODULE:get_file(Fd),
+ ?line {ok, Data} = ?RAM_FILE_MODULE:get_file_close(Fd),
+ ?line {error, einval} = ?RAM_FILE_MODULE:get_size(Fd),
+ ?line {ok, Fd2} = ?RAM_FILE_MODULE:open(Data, Options),
+ ?line case ?RAM_FILE_MODULE:set_file(Fd2, Data2) of
+ {ok, Size2} ->
+ ?line {ok, Size2} = ?RAM_FILE_MODULE:get_size(Fd2),
+ ?line {ok, Data2} = ?RAM_FILE_MODULE:get_file(Fd2),
+ ?line {ok, Data2} = ?RAM_FILE_MODULE:get_file_close(Fd2),
+ ?line ok;
+ {error, _} = Error ->
+ ?line {ok, Data} = ?RAM_FILE_MODULE:get_file_close(Fd2),
+ ?line Error
+ end.
+
+
+
+compress(suite) ->
+ [];
+compress(doc) ->
+ ["Test that compress/1 and uncompress/1 works."];
+compress(Config) when is_list(Config) ->
+ ?line Data = ?config(data_dir, Config),
+ ?line Real = filename:join(Data, "realmen.html"),
+ ?line RealGz = filename:join(Data, "realmen.html.gz"),
+ %%
+ %% Uncompress test
+ %%
+ ?line {ok, FdReal} = ?FILE_MODULE:open(Real, []),
+ ?line {ok, Fd} = ?FILE_MODULE:open([], [ram, read, write]),
+ ?line {ok, FdRealGz} = ?FILE_MODULE:open(RealGz, []),
+ %%
+ ?line {ok, SzGz} = ?FILE_MODULE:copy(FdRealGz, Fd),
+ ?line {ok, Sz} = ?RAM_FILE_MODULE:uncompress(Fd),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line true = compare(FdReal, Fd),
+ %%
+ ?line true = (SzGz =< Sz),
+ %%
+ %% Compress and uncompress test
+ %%
+ ?line {ok, 0} = ?FILE_MODULE:position(FdReal, bof),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line ok = ?FILE_MODULE:truncate(Fd),
+ ?line {ok, Sz} = ?FILE_MODULE:copy(FdReal, Fd),
+ ?line {ok, SzGz} = ?RAM_FILE_MODULE:compress(Fd),
+ ?line {ok, Sz} = ?RAM_FILE_MODULE:uncompress(Fd),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line {ok, 0} = ?FILE_MODULE:position(FdReal, bof),
+ ?line true = compare(FdReal, Fd),
+ %%
+ ?line ok = ?FILE_MODULE:close(FdReal),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ ?line ok = ?FILE_MODULE:close(FdRealGz),
+
+
+ %% Test uncompressing data that will be expanded many times.
+ ?line Huge = iolist_to_binary(mk_42(18)),
+ ?line HugeSize = byte_size(Huge),
+ ?line HugeGz = zlib:gzip(Huge),
+
+ ?line {ok,HugeFd} = ?FILE_MODULE:open([], [ram,read,write,binary]),
+ ?line ok = ?FILE_MODULE:write(HugeFd, HugeGz),
+ ?line {ok,HugeSize} = ?RAM_FILE_MODULE:uncompress(HugeFd),
+ ?line {ok,0} = ?FILE_MODULE:position(HugeFd, bof),
+ ?line {ok,Huge} = ?FILE_MODULE:read(HugeFd, HugeSize),
+
+ %% Uncompressing again should do nothing.
+ ?line {ok,HugeSize} = ?RAM_FILE_MODULE:uncompress(HugeFd),
+ ?line {ok,0} = ?FILE_MODULE:position(HugeFd, bof),
+ ?line {ok,Huge} = ?FILE_MODULE:read(HugeFd, HugeSize),
+
+ ?line ok = ?FILE_MODULE:close(HugeFd),
+
+ ok.
+
+mk_42(0) ->
+ [42];
+mk_42(N) ->
+ B = mk_42(N-1),
+ [B|B].
+
+uuencode(suite) ->
+ [];
+uuencode(doc) ->
+ ["Test that uuencode/1 and uudecode/1 works."];
+uuencode(Config) when is_list(Config) ->
+ ?line Data = ?config(data_dir, Config),
+ ?line Real = filename:join(Data, "realmen.html"),
+ ?line RealUu = filename:join(Data, "realmen.html.uu"),
+ %%
+ %% Uudecode test
+ %%
+ ?line {ok, FdReal} = ?FILE_MODULE:open(Real, []),
+ ?line {ok, Fd} = ?FILE_MODULE:open([], [ram, read, write]),
+ ?line {ok, FdRealUu} = ?FILE_MODULE:open(RealUu, []),
+ %%
+ ?line {ok, SzUu} = ?FILE_MODULE:copy(FdRealUu, Fd),
+ ?line {ok, Sz} = ?RAM_FILE_MODULE:uudecode(Fd),
+ ?line true = (Sz =< SzUu),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line true = compare(FdReal, Fd),
+ %%
+ %% Uuencode and decode test
+ %%
+ ?line {ok, 0} = ?FILE_MODULE:position(FdReal, bof),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line ok = ?FILE_MODULE:truncate(Fd),
+ ?line {ok, Sz} = ?FILE_MODULE:copy(FdReal, Fd),
+ ?line {ok, SzUu} = ?RAM_FILE_MODULE:uuencode(Fd),
+ ?line true = (Sz =< SzUu),
+ ?line {ok, Sz } = ?RAM_FILE_MODULE:uudecode(Fd),
+ ?line {ok, 0} = ?FILE_MODULE:position(FdReal, bof),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line true = compare(FdReal, Fd),
+ %%
+ ?line ok = ?FILE_MODULE:close(FdReal),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ ?line ok = ?FILE_MODULE:close(FdRealUu),
+ ok.
+
+
+
+large_file_errors(suite) ->
+ [];
+large_file_errors(doc) ->
+ ["Test error checking of large file offsets."];
+large_file_errors(Config) when is_list(Config) ->
+ ?line TwoGig = 1 bsl 31,
+ ?line {ok,Fd} = ?RAM_FILE_MODULE:open("1234567890", [read,write]),
+ ?line {error, einval} = ?FILE_MODULE:read(Fd, TwoGig),
+ ?line {error, badarg} = ?FILE_MODULE:read(Fd, -1),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {bof,TwoGig}),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {bof,-TwoGig-1}),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {bof,-1}),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {cur,TwoGig}),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {cur,-TwoGig-1}),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {eof,TwoGig}),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {eof,-TwoGig-1}),
+ ?line {error, einval} = ?FILE_MODULE:pread(Fd, TwoGig, 1),
+ ?line {error, einval} = ?FILE_MODULE:pread(Fd, -TwoGig-1, 1),
+ ?line {error, einval} = ?FILE_MODULE:pread(Fd, -1, 1),
+ ?line {error, einval} = ?FILE_MODULE:pwrite(Fd, TwoGig, "@"),
+ ?line {error, einval} = ?FILE_MODULE:pwrite(Fd, -TwoGig-1, "@"),
+ ?line {error, einval} = ?FILE_MODULE:pwrite(Fd, -1, "@"),
+ ?line {error, einval} = ?FILE_MODULE:pread(Fd, TwoGig, 0),
+ ?line {error, einval} = ?FILE_MODULE:pread(Fd, -TwoGig-1, 0),
+ ?line {error, einval} = ?FILE_MODULE:pread(Fd, -1, 0),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ ok.
+
+
+
+large_file_light(suite) ->
+ [];
+large_file_light(doc) ->
+ ["Test light operations on a \"large\" ram_file."];
+large_file_light(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ %% Marker for next test case that is to heavy to run in a suite.
+ ?line ok = ?FILE_MODULE:write_file(
+ filename:join(PrivDir, large_file_light),
+ <<"TAG">>),
+ %%
+ ?line Data = "abcdefghijklmnopqrstuvwzyz",
+ ?line Size = sizeof(Data),
+ ?line Max = (1 bsl 31) - 1,
+ ?line Max__1 = Max - 1,
+ ?line {ok, Fd} = ?RAM_FILE_MODULE:open(Data, [read]),
+ ?line {ok, Data} = ?FILE_MODULE:read(Fd, Size+1),
+ ?line {ok, Max__1} = ?FILE_MODULE:position(Fd, {eof, Max-Size-1}),
+ ?line eof = ?FILE_MODULE:read(Fd, 1),
+ ?line {ok, Max} = ?FILE_MODULE:position(Fd, {bof, Max}),
+ ?line {ok, Zero} = ?FILE_MODULE:read(Fd, 0),
+ ?line 0 = sizeof(Zero),
+ ?line eof = ?FILE_MODULE:read(Fd, 1),
+ ?line eof = ?FILE_MODULE:pread(Fd, Max__1, 1),
+ ?line {ok, Zero} = ?FILE_MODULE:pread(Fd, Max, 0),
+ ?line eof = ?FILE_MODULE:pread(Fd, Max, 1),
+ ok.
+
+
+
+large_file_heavy(suite) ->
+ [];
+large_file_heavy(doc) ->
+ ["Test operations on a maximum size (2 GByte - 1) ram_file."];
+large_file_heavy(Config) when is_list(Config) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ %% Check previous test case marker.
+ case ?FILE_MODULE:read_file_info(
+ filename:join(PrivDir, large_file_light)) of
+ {ok,_} ->
+ {skipped,"Too heavy for casual testing!"};
+ _ ->
+ do_large_file_heavy(Config)
+ end.
+
+do_large_file_heavy(_Config) ->
+ ?line Data = "qwertyuiopasdfghjklzxcvbnm",
+ ?line Size = sizeof(Data),
+ ?line Max = (1 bsl 31) - 1,
+ ?line Max__1 = Max - 1,
+ ?line Max__3 = Max - 3,
+ ?line {ok, Fd} = ?RAM_FILE_MODULE:open(Data, [read,write]),
+ ?line {ok, Data} = ?FILE_MODULE:read(Fd, Size+1),
+ ?line {ok, Max} = ?FILE_MODULE:position(Fd, {eof, Max-Size}),
+ ?line eof = ?FILE_MODULE:read(Fd, 1),
+ ?line erlang:display({allocating,2,'GByte',please,be,patient,'...'}),
+ ?line ok = ?FILE_MODULE:write(Fd, ""),
+ ?line erlang:display({allocating,2,'GByte',succeeded}),
+ ?line {ok, Max__1} = ?FILE_MODULE:position(Fd, {eof, -1}),
+ ?line {ok, [0]} = ?FILE_MODULE:read(Fd, 1),
+ ?line {ok, []} = ?FILE_MODULE:read(Fd, 0),
+ ?line eof = ?FILE_MODULE:read(Fd, 1),
+ ?line ok = ?FILE_MODULE:pwrite(Fd, Max-3, "TAG"),
+ ?line {ok, Max} = ?FILE_MODULE:position(Fd, cur),
+ ?line {ok, Max__3} = ?FILE_MODULE:position(Fd, {eof, -3}),
+ ?line {ok, "TAG"} = ?FILE_MODULE:read(Fd, 3+1),
+ ?line {ok, Max__3} = ?FILE_MODULE:position(Fd, {cur, -3}),
+ ?line ok = ?FILE_MODULE:write(Fd, "tag"),
+ ?line {ok, Max} = ?FILE_MODULE:position(Fd, cur),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, bof),
+ ?line {ok, "tag"} = ?FILE_MODULE:pread(Fd, Max__3, 3+1),
+ ?line {ok, 0} = ?FILE_MODULE:position(Fd, cur),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ ok.
+
+%%--------------------------------------------------------------------------
+%% Utility functions
+
+compare(FdA, FdB) ->
+ Size = 65536,
+ case {?FILE_MODULE:read(FdA, Size), ?FILE_MODULE:read(FdB, Size)} of
+ {{error, _} = Error, _} ->
+ Error;
+ {_, {error, _} = Error} ->
+ Error;
+ {{ok, A}, {ok, B}} ->
+ case compare_data(A, B) of
+ true ->
+ compare(FdA, FdB);
+ false ->
+ false
+ end;
+ {eof, eof} ->
+ true;
+ _ ->
+ false
+ end.
+
+compare_data(A, B) when is_list(A), is_list(B) ->
+ list_to_binary(A) == list_to_binary(B);
+compare_data(A, B) when is_list(A), is_binary(B) ->
+ list_to_binary(A) == B;
+compare_data(A, B) when is_binary(A), is_list(B) ->
+ A == list_to_binary(B);
+compare_data(A, B) when is_binary(A), is_binary(B) ->
+ A == B.
+
+sizeof(Data) when is_list(Data) ->
+ length(Data);
+sizeof(Data) when is_binary(Data) ->
+ byte_size(Data).
+
+append(Data1, Data2) when is_list(Data1), is_list(Data2) ->
+ Data1 ++ Data2;
+append(Data1, Data2) when is_binary(Data1), is_binary(Data2) ->
+ list_to_binary([Data1 | Data2]).
+
+slice(Data, Start, Length) when is_list(Data) ->
+ lists:sublist(Data, Start+1, Length);
+slice(Data, Start, Length) when is_binary(Data) ->
+ {_, Bin} = split_binary(Data, Start),
+ if
+ Length >= byte_size(Bin) ->
+ Bin;
+ true ->
+ {B, _} = split_binary(Bin, Length),
+ B
+ end.
+