diff options
Diffstat (limited to 'lib/kernel/test/ram_file_SUITE.erl')
-rw-r--r-- | lib/kernel/test/ram_file_SUITE.erl | 651 |
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. + |