aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Pampukha <[email protected]>2010-02-19 14:59:39 +0100
committerRaimo Niskanen <[email protected]>2010-06-09 16:19:07 +0200
commitc9c5497f7e7665b49062c33253c6d693e2a5e654 (patch)
tree07608577d89bd6cad5803afca5499691e4bdf8ce
parentbc82340d83d71999239f875f5685ece777f04f01 (diff)
downloadotp-c9c5497f7e7665b49062c33253c6d693e2a5e654.tar.gz
otp-c9c5497f7e7665b49062c33253c6d693e2a5e654.tar.bz2
otp-c9c5497f7e7665b49062c33253c6d693e2a5e654.zip
Add support for user config in common_test
Added: 1. ct_config, ct_config_plain and ct_config_xml modules. 2. support for {userconfig, {Callback, ConfigFiles}} parameter to ct:run_test/1 3. support for "-userconfig Callback ConfigFiles and OtherCallback ConfigFiles" parameter to the run_test script
-rw-r--r--lib/common_test/src/Makefile7
-rw-r--r--lib/common_test/src/common_test.app.src7
-rwxr-xr-xlib/common_test/src/ct_config.erl117
-rwxr-xr-xlib/common_test/src/ct_config_plain.erl100
-rwxr-xr-xlib/common_test/src/ct_config_xml.erl96
-rw-r--r--lib/common_test/src/ct_run.erl156
-rw-r--r--lib/common_test/src/ct_util.erl112
7 files changed, 434 insertions, 161 deletions
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index e7e2d1275d..4c4382b705 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+# Copyright Ericsson AB 2003-2010. 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
@@ -63,7 +63,10 @@ MODULES= \
ct_telnet_client \
ct_make \
vts \
- unix_telnet
+ unix_telnet \
+ ct_config \
+ ct_config_plain \
+ ct_config_xml
TARGET_MODULES= $(MODULES:%=$(EBIN)/%)
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src
index 7b72932ad4..2f599a7e30 100644
--- a/lib/common_test/src/common_test.app.src
+++ b/lib/common_test/src/common_test.app.src
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% Copyright Ericsson AB 2010. 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
@@ -42,7 +42,10 @@
ct_testspec,
ct_util,
unix_telnet,
- vts
+ vts,
+ ct_config,
+ ct_config_plain,
+ ct_config_xml
]},
{registered, [ct_logs,
ct_util_server,
diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl
new file mode 100755
index 0000000000..f344813128
--- /dev/null
+++ b/lib/common_test/src/ct_config.erl
@@ -0,0 +1,117 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. 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%
+%%----------------------------------------------------------------------
+%% File : ct_config.erl
+%% Description : CT module for reading and manipulating of configuration
+%% data
+%%
+%% Created : 15 February 2010
+%%----------------------------------------------------------------------
+-module(ct_config).
+
+-export([read_config_files/1,
+ set_config/1, set_config/2, set_config/3,
+ delete_config/1,
+ get_config_file_list/1]).
+
+-include("ct_event.hrl").
+-include("ct_util.hrl").
+
+-record(ct_conf,{key,value,ref,name='_UNDEF',default=false}).
+%% default = {true,suite} | {true,testcase} | false
+
+read_config_files(Opts) ->
+ AddCallback = fun(CallBack, Files)->
+ lists:map(fun(X)-> {CallBack, X} end, Files)
+ end,
+ ConfigFiles = case lists:keyfind(config, 1, Opts) of
+ {config, ConfigLists}->
+ lists:foldr(fun({Callback,Files}, Acc)->
+ AddCallback(Callback,Files) ++ Acc
+ end,
+ [],
+ ConfigLists);
+ false->
+ []
+ end,
+ read_config_files_int(ConfigFiles).
+
+read_config_files_int([{Callback, File}|Files])->
+ case Callback:read_config_file(File) of
+ {ok, Config}->
+ set_config(Config),
+ read_config_files_int(Files);
+ {error, ErrorName, ErrorDetail}->
+ {user_error, {ErrorName, File, ErrorDetail}}
+ end;
+read_config_files_int([])->
+ ok.
+
+set_config(Config) ->
+ set_config('_UNDEF',Config,false).
+
+set_config(Config,Default) ->
+ set_config('_UNDEF',Config,Default).
+
+set_config(Name,Config,Default) ->
+ [ets:insert(?attr_table,
+ #ct_conf{key=Key,value=Val,ref=ct_util:ct_make_ref(),
+ name=Name,default=Default}) ||
+ {Key,Val} <- Config].
+
+delete_config(Default) ->
+ ets:match_delete(?attr_table,#ct_conf{default=Default,_='_'}),
+ ok.
+
+process_user_configs(Opts, Acc)->
+ case lists:keytake(userconfig, 1, Opts) of
+ false->
+ Acc;
+ {value, {userconfig, {Callback, Files=[File|_]}}, NewOpts} when
+ is_list(File)->
+ process_user_configs(NewOpts, [{Callback, Files} | Acc]);
+ {value, {userconfig, {Callback, File=[C|_]}}, NewOpts} when
+ is_integer(C)->
+ process_user_configs(NewOpts, [{Callback, [File]} | Acc]);
+ {value, {userconfig, {_Callback, []}}, NewOpts}->
+ process_user_configs(NewOpts, Acc)
+ end.
+
+process_default_configs(Opts)->
+ case lists:keysearch(config, 1, Opts) of
+ {value,{_,Files=[File|_]}} when is_list(File) ->
+ Files;
+ {value,{_,File=[C|_]}} when is_integer(C) ->
+ [File];
+ {value,{_,[]}} ->
+ [];
+ false ->
+ []
+ end.
+
+get_config_file_list(Opts)->
+ DefaultConfigs = process_default_configs(Opts),
+ CfgFiles =
+ if
+ DefaultConfigs == []->
+ [];
+ true->
+ [{ct_config_plain, DefaultConfigs}]
+ end ++
+ process_user_configs(Opts, []),
+ CfgFiles.
diff --git a/lib/common_test/src/ct_config_plain.erl b/lib/common_test/src/ct_config_plain.erl
new file mode 100755
index 0000000000..a5947cafef
--- /dev/null
+++ b/lib/common_test/src/ct_config_plain.erl
@@ -0,0 +1,100 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. 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%
+%%----------------------------------------------------------------------
+%% File : ct_config_plain.erl
+%% Description : CT callback module for reading configs from text files
+%%
+%% Created : 15 February 2010
+%%----------------------------------------------------------------------
+-module(ct_config_plain).
+-export([read_config_file/1]).
+
+read_config_file(ConfigFile) ->
+ case file:consult(ConfigFile) of
+ {ok,Config} ->
+ {ok, Config};
+ {error,enoent} ->
+ {error, config_file_error, enoent};
+ {error,Reason} ->
+ Key =
+ case application:get_env(common_test, decrypt) of
+ {ok,KeyOrFile} ->
+ case KeyOrFile of
+ {key,K} ->
+ K;
+ {file,F} ->
+ ct_util:get_crypt_key_from_file(F)
+ end;
+ _ ->
+ ct_util:get_crypt_key_from_file()
+ end,
+ case Key of
+ {error,no_crypt_file} ->
+ {error, config_file_error, Reason};
+ {error,CryptError} ->
+ {error, decrypt_file_error, CryptError};
+ _ when is_list(Key) ->
+ case ct_util:decrypt_config_file(ConfigFile, undefined, {key,Key}) of
+ {ok,CfgBin} ->
+ case read_config_terms(CfgBin) of
+ {error,ReadFail} ->
+ {error, config_file_error, ReadFail};
+ Config ->
+ {ok, Config}
+ end;
+ {error,DecryptFail} ->
+ {error, decrypt_config_error, DecryptFail}
+ end;
+ _ ->
+ {error, bad_decrypt_key, Key}
+ end
+ end.
+
+read_config_terms(Bin) when is_binary(Bin) ->
+ case catch binary_to_list(Bin) of
+ {'EXIT',_} ->
+ {error,invalid_textfile};
+ Lines ->
+ read_config_terms(Lines)
+ end;
+read_config_terms(Lines) when is_list(Lines) ->
+ read_config_terms1(erl_scan:tokens([], Lines, 0), 1, [], []).
+
+read_config_terms1({done,{ok,Ts,EL},Rest}, L, Terms, _) ->
+ case erl_parse:parse_term(Ts) of
+ {ok,Term} when Rest == [] ->
+ lists:reverse([Term|Terms]);
+ {ok,Term} ->
+ read_config_terms1(erl_scan:tokens([], Rest, 0),
+ EL+1, [Term|Terms], Rest);
+ _ ->
+ {error,{bad_term,{L,EL}}}
+ end;
+read_config_terms1({done,{eof,_},_}, _, Terms, Rest) when Rest == [] ->
+ lists:reverse(Terms);
+read_config_terms1({done,{eof,EL},_}, L, _, _) ->
+ {error,{bad_term,{L,EL}}};
+read_config_terms1({done,{error,Info,EL},_}, L, _, _) ->
+ {error,{Info,{L,EL}}};
+read_config_terms1({more,_}, L, Terms, Rest) ->
+ case string:tokens(Rest, [$\n,$\r,$\t]) of
+ [] ->
+ lists:reverse(Terms);
+ _ ->
+ {error,{bad_term,L}}
+ end.
diff --git a/lib/common_test/src/ct_config_xml.erl b/lib/common_test/src/ct_config_xml.erl
new file mode 100755
index 0000000000..ef991123f3
--- /dev/null
+++ b/lib/common_test/src/ct_config_xml.erl
@@ -0,0 +1,96 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. 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%
+%%----------------------------------------------------------------------
+%% File : ct_config_xml.erl
+%% Description : CT callback module for reading configs from XML files
+%%
+%% Created : 16 February 2010
+%%----------------------------------------------------------------------
+-module(ct_config_xml).
+-export([read_config_file/1, list_to_term/1]).
+
+read_config_file(ConfigFile) ->
+ case catch do_read_xml_config(ConfigFile) of
+ {ok, Config}->
+ {ok, Config};
+ {error, Error, ErroneousString}->
+ {error, Error, ErroneousString}
+ end.
+
+do_read_xml_config(ConfigFile)->
+ {ok, EntityList, _}=
+ xmerl_sax_parser:file(ConfigFile,
+ [{event_fun, fun event/3},
+ {event_state, initial_state()}]),
+ {ok, transform_entity_list(EntityList)}.
+
+
+initial_state() ->
+ [].
+
+event(Event, _LineNo, State) ->
+ tag(Event, State).
+
+tag(startDocument, State) ->
+ State;
+
+tag(endDocument, {_Tags, Result}) ->
+ Result;
+
+tag({startElement, _Uri, "config", _QName, _Attributes}, []) ->
+ [{"config", []}];
+
+tag({endElement, _Uri, "config", _QName}, [{"config", Config}]) ->
+ Config;
+
+tag({startElement, _Uri, Name, _QName, _Attributes}, Tags) ->
+ [{Name, []}|Tags];
+
+tag({endElement, _Uri, _Name, _QName},
+ [Entity, {PrevEntityTag, PrevEntityValue}|Tags]) ->
+ NewHead = {PrevEntityTag, [Entity|PrevEntityValue]},
+ [NewHead|Tags];
+
+tag({characters, String}, [{Tag, _Value}|Tags]) ->
+ [{Tag, String}|Tags];
+
+tag(_El, State) ->
+ State.
+
+transform_entity_list(EntityList)->
+ lists:map(fun transform_entity/1, EntityList).
+
+transform_entity({Tag, [Value|Rest]}) when
+ is_tuple(Value)->
+ {list_to_atom(Tag), transform_entity_list([Value|Rest])};
+transform_entity({Tag, String})->
+ case list_to_term(String) of
+ {ok, Value}->
+ {list_to_atom(Tag), Value};
+ Error->
+ throw(Error)
+ end.
+
+list_to_term(String) ->
+ {ok, T, _} = erl_scan:string(String++"."),
+ case erl_parse:parse_term(T) of
+ {ok, Term} ->
+ {ok, Term};
+ Error ->
+ {error, Error, String}
+ end.
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index 6b1063f74c..b86dd8fe2f 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -208,47 +208,95 @@ script_start1(Parent, Args) ->
end
end;
false ->
- case lists:keysearch(ct_config, 1, Args) of
- {value,{ct_config,ConfigFiles}} ->
+ ConfigFiles = case lists:keysearch(ct_config, 1, Args) of
+ {value,{ct_config,Files}}->
+ [{ct_config_plain, Files}];
+ false->
+ []
+ end,
+ UserConfigs = case lists:keysearch(userconfig, 1, Args) of
+ {value,{userconfig,UserConfigFiles}}->
+ prepare_user_configs(UserConfigFiles, [], new);
+ false->
+ []
+ end,
+ Config = ConfigFiles ++ UserConfigs,
+ case Config of
+ false ->
+ case install([{config,[]},
+ {event_handler,EvHandlers}],
+ LogDir) of
+ ok ->
+ script_start2(VtsOrShell, [], EvHandlers,
+ Args, LogDir, Cover);
+ Error ->
+ Error
+ end;
+ Config ->
case lists:keysearch(spec, 1, Args) of
false ->
- case get_configfiles(ConfigFiles, [], LogDir,
- EvHandlers) of
+ case check_and_install_configfiles(Config,
+ LogDir, EvHandlers) of
ok ->
- script_start2(VtsOrShell, ConfigFiles,
+ script_start2(VtsOrShell, Config,
EvHandlers, Args, LogDir,
Cover);
Error ->
Error
end;
_ ->
- script_start2(VtsOrShell, ConfigFiles,
+ script_start2(VtsOrShell, Config,
EvHandlers, Args, LogDir, Cover)
- end;
- false ->
- case install([{config,[]},
- {event_handler,EvHandlers}],
- LogDir) of
- ok ->
- script_start2(VtsOrShell, [], EvHandlers,
- Args, LogDir, Cover);
- Error ->
- Error
end
end
end,
Parent ! {self(), Result}.
-get_configfiles([File|Files], Acc, LogDir, EvHandlers) ->
- case filelib:is_file(File) of
- true ->
- get_configfiles(Files, [?abs(File)|Acc],
- LogDir, EvHandlers);
- false ->
- {error,{cant_read_config_file,File}}
- end;
-get_configfiles([], Acc, LogDir, EvHandlers) ->
- install([{config,lists:reverse(Acc)}, {event_handler,EvHandlers}], LogDir).
+prepare_user_configs([ConfigString|UserConfigs], Acc, new)->
+ prepare_user_configs(UserConfigs,
+ [{list_to_atom(ConfigString), []}|Acc],
+ cur);
+prepare_user_configs(["and"|UserConfigs], Acc, _)->
+ prepare_user_configs(UserConfigs, Acc, new);
+prepare_user_configs([ConfigString|UserConfigs], [{LastMod, LastList}|Acc], cur)->
+ prepare_user_configs(UserConfigs,
+ [{LastMod, [ConfigString|LastList]}|Acc],
+ cur);
+prepare_user_configs([], Acc, _)->
+ Acc.
+
+check_and_install_configfiles(Configs, LogDir, EvHandlers) ->
+ % Configs is list of tuples such as {Callback=atom(), Files=list()}
+ % The ugly code below checks:
+ % 1. that all config files are present
+ % 2. thar all callback modules are loadable
+ case lists:keysearch(nok, 1,
+ lists:flatten(
+ lists:map(fun({Callback, Files})->
+ case code:load_file(Callback) of
+ {module, Callback}->
+ lists:map(fun(File)->
+ case filelib:is_file(File) of
+ true->
+ {ok, File};
+ false->
+ {nok, {config, File}}
+ end
+ end,
+ Files);
+ {error, _}->
+ {nok, {callback, Callback}}
+ end
+ end,
+ Configs))) of
+ false->
+ install([{config,Configs},
+ {event_handler,EvHandlers}], LogDir);
+ {value, {nok, {config, File}}} ->
+ {error,{cant_read_config_file,File}};
+ {value, {nok, {callback, File}}} ->
+ {error,{cant_load_callback_module,File}}
+ end.
script_start2(false, ConfigFiles, EvHandlers, Args, LogDir, Cover) ->
case lists:keysearch(spec, 1, Args) of
@@ -275,8 +323,8 @@ script_start2(false, ConfigFiles, EvHandlers, Args, LogDir, Cover) ->
{_,undef} -> [Cover];
{false,_} -> [{cover,TSCoverFile}]
end,
- case get_configfiles(ConfigFiles++ConfigFiles1,
- [], LogDir2,
+ case check_and_install_configfiles(
+ ConfigFiles++ConfigFiles1, LogDir2,
EvHandlers++EvHandlers1) of
ok ->
{Run,Skip} = ct_testspec:prepare_tests(TS, node()),
@@ -404,6 +452,7 @@ script_usage() ->
"\n\t[-suite Suite1 Suite2 .. SuiteN [-case Case1 Case2 .. CaseN]]"
"\n\t[-step [config | keep_inactive]]"
"\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
+ "\n\t[-userconfig CallbackModule ConfigFile1 .. ConfigFileN]"
"\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]"
"\n\t[-logdir LogDir]"
"\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]"
@@ -534,17 +583,7 @@ run_test1(Opts) ->
{value,{_,LD}} when is_list(LD) -> LD;
false -> "."
end,
- CfgFiles =
- case lists:keysearch(config, 1, Opts) of
- {value,{_,Files=[File|_]}} when is_list(File) ->
- Files;
- {value,{_,File=[C|_]}} when is_integer(C) ->
- [File];
- {value,{_,[]}} ->
- [];
- false ->
- []
- end,
+ CfgFiles = ct_config:get_config_file_list(Opts),
EvHandlers =
case lists:keysearch(event_handler, 1, Opts) of
{value,{_,H}} when is_atom(H) ->
@@ -681,7 +720,7 @@ run_spec_file(LogDir, CfgFiles, EvHandlers, Include, Specs, Relaxed, Cover, Opts
{_,undef} -> Cover;
{[],_} -> [{cover,TSCoverFile}]
end,
- case get_configfiles(CfgFiles++CfgFiles1, [], LogDir2,
+ case check_and_install_configfiles(CfgFiles++CfgFiles1, LogDir2,
EvHandlers++EvHandlers1) of
ok ->
{Run,Skip} = ct_testspec:prepare_tests(TS, node()),
@@ -694,23 +733,40 @@ run_spec_file(LogDir, CfgFiles, EvHandlers, Include, Specs, Relaxed, Cover, Opts
end.
run_prepared(LogDir, CfgFiles, EvHandlers, Run, Skip, Cover, Opts) ->
- case get_configfiles(CfgFiles, [], LogDir, EvHandlers) of
+ case check_and_install_configfiles(CfgFiles, LogDir, EvHandlers) of
ok ->
do_run(Run, Skip, Cover, Opts, LogDir);
{error,Reason} ->
exit(Reason)
end.
+check_config_file(File)->
+ AbsName = ?abs(File),
+ case filelib:is_file(AbsName) of
+ true -> AbsName;
+ false -> exit({no_such_file,AbsName})
+ end.
+
run_dir(LogDir, CfgFiles, EvHandlers, StepOrCover, Opts) ->
AbsCfgFiles =
- lists:map(fun(F) ->
- AbsName = ?abs(F),
- case filelib:is_file(AbsName) of
- true -> AbsName;
- false -> exit({no_such_file,AbsName})
- end
- end, CfgFiles),
-
+ lists:map(fun({Callback, FileList})->
+ case code:is_loaded(Callback) of
+ {file, _Path}->
+ ok;
+ false->
+ case code:load_file(Callback) of
+ {module, Callback}->
+ ok;
+ {error, _}->
+ exit({no_such_module, Callback})
+ end
+ end,
+ {Callback,
+ lists:map(fun(File)->
+ check_config_file(File)
+ end, FileList)}
+ end,
+ CfgFiles),
case install([{config,AbsCfgFiles},{event_handler,EvHandlers}], LogDir) of
ok -> ok;
{error,IReason} -> exit(IReason)
@@ -799,7 +855,7 @@ run_testspec1(TestSpec) ->
CoverOpt = if TSCoverFile == undef -> [];
true -> [{cover,TSCoverFile}]
end,
- case get_configfiles(CfgFiles,[],LogDir,EvHandlers) of
+ case check_and_install_configfiles(CfgFiles,LogDir,EvHandlers) of
ok ->
{Run,Skip} = ct_testspec:prepare_tests(TS,node()),
do_run(Run,Skip,CoverOpt,[],LogDir);
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index ba3d789f8d..814bd97840 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -59,7 +59,7 @@
-export([encrypt_config_file/2, encrypt_config_file/3,
decrypt_config_file/2, decrypt_config_file/3]).
--export([kill_attached/2, get_attached/1]).
+-export([kill_attached/2, get_attached/1, ct_make_ref/0]).
-export([warn_duplicates/1]).
@@ -148,7 +148,7 @@ do_start(Parent,Mode,LogDir) ->
ct_event:add_handler([{vts,VtsPid}])
end
end,
- case read_config_files(Opts) of
+ case ct_config:read_config_files(Opts) of
ok ->
%% add user handlers
case lists:keysearch(event_handler,1,Opts) of
@@ -197,94 +197,6 @@ read_opts() ->
{error,{bad_installation,Error}}
end.
-read_config_files(Opts) ->
- ConfigFiles =
- lists:foldl(fun({config,Files},Acc) ->
- Acc ++ Files;
- (_,Acc) ->
- Acc
- end,[],Opts),
- read_config_files1(ConfigFiles).
-
-read_config_files1([ConfigFile|Files]) ->
- case file:consult(ConfigFile) of
- {ok,Config} ->
- set_config(Config),
- read_config_files1(Files);
- {error,enoent} ->
- {user_error,{config_file_error,ConfigFile,enoent}};
- {error,Reason} ->
- Key =
- case application:get_env(common_test, decrypt) of
- {ok,KeyOrFile} ->
- case KeyOrFile of
- {key,K} ->
- K;
- {file,F} ->
- get_crypt_key_from_file(F)
- end;
- _ ->
- get_crypt_key_from_file()
- end,
- case Key of
- {error,no_crypt_file} ->
- {user_error,{config_file_error,ConfigFile,Reason}};
- {error,CryptError} ->
- {user_error,{decrypt_file_error,ConfigFile,CryptError}};
- _ when is_list(Key) ->
- case decrypt_config_file(ConfigFile, undefined, {key,Key}) of
- {ok,CfgBin} ->
- case read_config_terms(CfgBin) of
- {error,ReadFail} ->
- {user_error,{config_file_error,ConfigFile,ReadFail}};
- Config ->
- set_config(Config),
- read_config_files1(Files)
- end;
- {error,DecryptFail} ->
- {user_error,{decrypt_config_error,ConfigFile,DecryptFail}}
- end;
- _ ->
- {user_error,{bad_decrypt_key,ConfigFile,Key}}
- end
- end;
-read_config_files1([]) ->
- ok.
-
-read_config_terms(Bin) when is_binary(Bin) ->
- case catch binary_to_list(Bin) of
- {'EXIT',_} ->
- {error,invalid_textfile};
- Lines ->
- read_config_terms(Lines)
- end;
-read_config_terms(Lines) when is_list(Lines) ->
- read_config_terms1(erl_scan:tokens([], Lines, 0), 1, [], []).
-
-read_config_terms1({done,{ok,Ts,EL},Rest}, L, Terms, _) ->
- case erl_parse:parse_term(Ts) of
- {ok,Term} when Rest == [] ->
- lists:reverse([Term|Terms]);
- {ok,Term} ->
- read_config_terms1(erl_scan:tokens([], Rest, 0),
- EL+1, [Term|Terms], Rest);
- _ ->
- {error,{bad_term,{L,EL}}}
- end;
-read_config_terms1({done,{eof,_},_}, _, Terms, Rest) when Rest == [] ->
- lists:reverse(Terms);
-read_config_terms1({done,{eof,EL},_}, L, _, _) ->
- {error,{bad_term,{L,EL}}};
-read_config_terms1({done,{error,Info,EL},_}, L, _, _) ->
- {error,{Info,{L,EL}}};
-read_config_terms1({more,_}, L, Terms, Rest) ->
- case string:tokens(Rest, [$\n,$\r,$\t]) of
- [] ->
- lists:reverse(Terms);
- _ ->
- {error,{bad_term,L}}
- end.
-
set_default_config(NewConfig, Scope) ->
call({set_default_config, {NewConfig, Scope}}).
@@ -347,15 +259,15 @@ loop(Mode,TestData,StartDir) ->
return(From,Result),
loop(Mode,TestData,StartDir);
{{set_default_config,{Config,Scope}},From} ->
- set_config(Config,{true,Scope}),
+ ct_config:set_config(Config,{true,Scope}),
return(From,ok),
loop(Mode,TestData,StartDir);
{{set_default_config,{Name,Config,Scope}},From} ->
- set_config(Name,Config,{true,Scope}),
+ ct_config:set_config(Name,Config,{true,Scope}),
return(From,ok),
loop(Mode,TestData,StartDir);
{{delete_default_config,Scope},From} ->
- delete_config({true,Scope}),
+ ct_config:delete_config({true,Scope}),
return(From,ok),
loop(Mode,TestData,StartDir);
{{update_config,{Name,NewConfig}},From} ->
@@ -765,21 +677,7 @@ lookup_key(Key) ->
[],
[{{'$1','$2'}}]}]).
-set_config(Config) ->
- set_config('_UNDEF',Config,false).
-
-set_config(Config,Default) ->
- set_config('_UNDEF',Config,Default).
-set_config(Name,Config,Default) ->
- [ets:insert(?attr_table,
- #ct_conf{key=Key,value=Val,ref=ct_make_ref(),
- name=Name,default=Default}) ||
- {Key,Val} <- Config].
-
-delete_config(Default) ->
- ets:match_delete(?attr_table,#ct_conf{default=Default,_='_'}),
- ok.
%%%-----------------------------------------------------------------