aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/src
diff options
context:
space:
mode:
authorAndrey Pampukha <andrey@erlang.org>2010-03-18 18:02:37 +0100
committerRaimo Niskanen <raimo@erlang.org>2010-06-09 16:19:14 +0200
commitdd67e73980ac0c8b601079c2e3f27701c367936c (patch)
treefabd8e5c7a1495d5140f378934a07f774c837f53 /lib/common_test/src
parentd7c10478a2287ce3f0c9ac077d835919e2745f91 (diff)
downloadotp-dd67e73980ac0c8b601079c2e3f27701c367936c.tar.gz
otp-dd67e73980ac0c8b601079c2e3f27701c367936c.tar.bz2
otp-dd67e73980ac0c8b601079c2e3f27701c367936c.zip
Fix problem with disappearing variables and aliases
Diffstat (limited to 'lib/common_test/src')
-rwxr-xr-xlib/common_test/src/ct_config.erl81
1 files changed, 62 insertions, 19 deletions
diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl
index 5623b80592..728dcde6af 100755
--- a/lib/common_test/src/ct_config.erl
+++ b/lib/common_test/src/ct_config.erl
@@ -242,27 +242,51 @@ store_config(Config, Callback, File)->
default=false}) ||
{Key,Val} <- Config].
+keyfindall(Key, N, List)->
+ keyfindall(Key, N, List, []).
+
+keyfindall(Key, N, List, Acc)->
+ case lists:keytake(Key, N, List) of
+ false->
+ Acc;
+ {value, Row, Rest}->
+ keyfindall(Key, N, Rest, [Row|Acc])
+ end.
+
rewrite_config(Config, Callback, File)->
- [begin
- Rows=case ets:match_object(?attr_table,
- #ct_conf{key=Key,
- handler=Callback,
- config=File,_='_'}) of
- []->
- [#ct_conf{default=false}];
- Elements->
- Elements
- end,
- lists:foreach(fun(Row)->
- ets:delete_object(?attr_table, Row),
- ets:insert(?attr_table,
- Row#ct_conf{key=Key,
- value=Val,
+ % 1) read the old config for this callback/file from the table
+ OldRows = ets:match_object(?attr_table,
+ #ct_conf{handler=Callback,
+ config=File,_='_'}),
+ % 2) remove all config data loaded from this callback/file
+ ets:match_delete(?attr_table,
+ #ct_conf{handler=Callback,
+ config=File,_='_'}),
+ % prepare function that will
+ % 1. find records with this key in the old config, including aliases
+ % 2. update values
+ % 3. put them back to the table
+ Updater = fun({Key, Value})->
+ case keyfindall(Key, #ct_conf.key, OldRows) of
+ []-> % if variable is new, just insert it
+ ets:insert(?attr_table,
+ #ct_conf{key=Key,
+ value=Value,
handler=Callback,
config=File,
- ref=ct_util:ct_make_ref()}) end,
- Rows)
- end || {Key,Val} <- Config].
+ ref=ct_util:ct_make_ref()});
+ RowsToUpdate -> % else update all occurrencies of the key
+ Inserter = fun(Row)->
+ ets:insert(?attr_table,
+ Row#ct_conf{value=Value,
+ ref=ct_util:ct_make_ref()})
+ end,
+ lists:foreach(Inserter, RowsToUpdate)
+ end
+ end,
+
+ % run it key-by-key from the new config
+ [Updater({Key, Value})||{Key, Value}<-Config].
set_config(Config,Default) ->
set_config('_UNDEF',Config,Default).
@@ -414,12 +438,31 @@ update_conf(Name, NewConfig) ->
end, Old),
ok.
+has_element(_, [])->
+ false;
+has_element(Element, [Element|_Rest])->
+ true;
+has_element(Element, [_|Rest])->
+ has_element(Element, Rest).
+
+remove_duplicates([], Acc)->
+ Acc;
+remove_duplicates([{Handler, File}|Rest], Acc)->
+ case has_element({Handler, File}, Acc) of
+ false->
+ remove_duplicates(Rest, [{Handler, File}|Acc]);
+ true->
+ remove_duplicates(Rest, Acc)
+ end.
+
reload_conf(KeyOrName) ->
case lookup_handler_for_config(KeyOrName) of
[]->
undefined;
HandlerList->
- read_config_files_int(HandlerList, fun rewrite_config/3),
+ % if aliases set, config will be reloaded several times
+ HandlerList2 = remove_duplicates(HandlerList, []),
+ read_config_files_int(HandlerList2, fun rewrite_config/3),
get_config(KeyOrName)
end.