aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test/ets_SUITE.erl
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2013-04-30 10:19:45 +0200
committerHans Bolinder <[email protected]>2013-05-06 12:14:14 +0200
commit9e75f186c50071557d1846cf7267edfc942acdfb (patch)
tree320988c91d6600f17628e6c3a073a5387b399fdd /lib/stdlib/test/ets_SUITE.erl
parentfa6ce2d4653bd7955c8c478a143119dbdd6b9d06 (diff)
downloadotp-9e75f186c50071557d1846cf7267edfc942acdfb.tar.gz
otp-9e75f186c50071557d1846cf7267edfc942acdfb.tar.bz2
otp-9e75f186c50071557d1846cf7267edfc942acdfb.zip
Fix a minor bug in ets:tabfile_info() and ets:file2tab()
Certain error conditions could leave an open file descriptor.
Diffstat (limited to 'lib/stdlib/test/ets_SUITE.erl')
-rw-r--r--lib/stdlib/test/ets_SUITE.erl53
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index af5d5a8f21..432ab19423 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -33,7 +33,7 @@
-export([ match1/1, match2/1, match_object/1, match_object2/1]).
-export([ dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]).
-export([ tab2file/1, tab2file2/1, tabfile_ext1/1,
- tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1]).
+ tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1, badfile/1]).
-export([ heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
-export([ lookup_element_mult/1]).
-export([]).
@@ -168,7 +168,7 @@ groups() ->
[misc1, safe_fixtable, info, dups, tab2list]},
{files, [],
[tab2file, tab2file2, tabfile_ext1,
- tabfile_ext2, tabfile_ext3, tabfile_ext4]},
+ tabfile_ext2, tabfile_ext3, tabfile_ext4, badfile]},
{heavy, [],
[heavy_lookup, heavy_lookup_element, heavy_concurrent]},
{fold, [],
@@ -4178,7 +4178,56 @@ tabfile_ext4(Config) when is_list(Config) ->
file:delete(FName),
ok.
+badfile(suite) ->
+ [];
+badfile(doc) ->
+ ["Tests that no disk_log is left open when file has been corrupted"];
+badfile(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ File = filename:join(PrivDir, "badfile"),
+ _ = file:delete(File),
+ T = ets:new(table, []),
+ true = ets:insert(T, [{a,1},{b,2}]),
+ ok = ets:tab2file(T, File, []),
+ true = ets:delete(T),
+ [H0 | Ts ] = get_all_terms(l, File),
+ H1 = tuple_to_list(H0),
+ H2 = [{K,V} || {K,V} <- H1, K =/= protection],
+ H = list_to_tuple(H2),
+ ok = file:delete(File),
+ write_terms(l, File, [H | Ts]),
+ %% All mandatory keys are no longer members of the header
+ {error, badfile} = ets:file2tab(File),
+ {error, badfile} = ets:tabfile_info(File),
+ file:delete(File),
+ {[],[]} = disk_log:accessible_logs(),
+ ok.
+
+get_all_terms(Log, File) ->
+ {ok, Log} = disk_log:open([{name,Log},
+ {file, File},
+ {mode, read_only}]),
+ Ts = get_all_terms(Log),
+ ok = disk_log:close(Log),
+ Ts.
+
+get_all_terms(Log) ->
+ get_all_terms1(Log, start, []).
+
+get_all_terms1(Log, Cont, Res) ->
+ case disk_log:chunk(Log, Cont) of
+ {error, _R} ->
+ throw(fel);
+ {Cont2, Terms} ->
+ get_all_terms1(Log, Cont2, Res ++ Terms);
+ eof ->
+ Res
+ end.
+write_terms(Log, File, Terms) ->
+ {ok, Log} = disk_log:open([{name,Log},{file, File},{mode,read_write}]),
+ ok = disk_log:log(Log, Terms),
+ ok = disk_log:close(Log).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%