%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2009-2013. 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_testspec_2_SUITE
%%%
%%% Description:
%%% Test test specifications
%%%
%%% The suites used for the test are located in the data directory.
%%%-------------------------------------------------------------------
-module(ct_testspec_2_SUITE).
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/src/ct_util.hrl").
%%--------------------------------------------------------------------
%% TEST SERVER CALLBACK FUNCTIONS
%%--------------------------------------------------------------------
init_per_suite(Config) ->
Config.
end_per_suite(_Config) ->
ok.
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(_TestCase, _Config) ->
ok.
%% suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic_compatible_no_nodes,
basic_compatible_nodes,
unknown_terms,
no_merging,
multiple_specs,
misc_config_terms,
define_names_1].
%%--------------------------------------------------------------------
%% VALID TEST SPEC TERMS (R15B02):
%%
%% {node,3}
%% {cover,2}
%% {cover,3}
%% {config,2}
%% {config,3}
%% {config,4}
%% {userconfig,2}
%% {userconfig,3}
%% {alias,3}
%% {merge_tests,2}
%% {logdir,2}
%% {logdir,3}
%% {logopts,2}
%% {logopts,3}
%% {basic_html,2}
%% {basic_html,3}
%% {verbosity,2}
%% {verbosity,3}
%% {silent_connections,2}
%% {silent_connections,3}
%% {label,2}
%% {label,3}
%% {event_handler,2}
%% {event_handler,3}
%% {event_handler,4}
%% {ct_hooks,2}
%% {ct_hooks,3}
%% {enable_builtin_hooks,2}
%% {release_shell,2}
%% {multiply_timetraps,2}
%% {multiply_timetraps,3}
%% {scale_timetraps,2}
%% {scale_timetraps,3}
%% {include,2}
%% {include,3}
%% {auto_compile,2}
%% {auto_compile,3}
%% {stylesheet,2}
%% {stylesheet,3}
%% {suites,3}
%% {suites,4}
%% {groups,4}
%% {groups,5}
%% {groups,6}
%% {cases,4}
%% {cases,5}
%% {skip_suites,4}
%% {skip_suites,5}
%% {skip_groups,5}
%% {skip_groups,6}
%% {skip_groups,7}
%% {skip_cases,5}
%% {skip_cases,6}
%% {create_priv_dir,2}
%%
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------
%%%-----------------------------------------------------------------
%%%
basic_compatible_no_nodes(_Config) ->
AliasDir1 = "../tests/to1",
AliasDir2 = "../tests/to2",
CfgDir1 = "../cfgs/to1/x.cfg",
CfgDir2 = ["../cfgs/to2/x.cfg","../cfgs/to2/y.cfg"],
LogDir = "../logs",
IncludeDir1 = "../../include",
IncludeDir2 = ["../tests/to1/include","../tests/to2/include"],
Spec =
[
{label,"basic_compatible_no_nodes"},
{alias,to1,AliasDir1},
{alias,to2,AliasDir2},
{config,CfgDir1},
{config,CfgDir2},
{userconfig,{?MODULE,"cfg_str1"}},
{userconfig,{?MODULE,"cfg_str2"}},
{logdir,LogDir},
{logopts,[no_nl]},
{event_handler,evh1,[1]},
{event_handler,[evh2,evh3],[[2,3]]},
{ct_hooks,[{cth_mod1,[]}]},
{ct_hooks,[{cth_mod2,[]}]},
{multiply_timetraps,2},
{include,IncludeDir1},
{include,IncludeDir2},
{suites,to1,[x_SUITE]},
{groups,to1,y_SUITE,[g1,g2]},
{cases,to1,y_SUITE,[tc1,tc2]},
{skip_suites,to1,z_SUITE,"skipped"},
{suites,to2,[x_SUITE,y_SUITE]},
{skip_groups,to2,x_SUITE,[g1,g2],"skipped"},
{skip_cases,to2,y_SUITE,[tc1,tc2],"skipped"}
],
{ok,SpecDir} = file:get_cwd(),
ListResult = ct_testspec:collect_tests_from_list(Spec, false),
ct:pal("TESTSPEC RECORD FROM LIST:~n~p~n", [rec2proplist(ListResult)]),
SpecFile = ct_test_support:write_testspec(Spec,SpecDir,
"basic_compatible_no_nodes.spec"),
FileResult = ct_testspec:collect_tests_from_file([SpecFile], false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
Node = node(),
LogDirV = get_absdir(filename:join(SpecDir,"../logs")),
Alias1V = get_absdir(filename:join(SpecDir,AliasDir1)),
Alias2V = get_absdir(filename:join(SpecDir,AliasDir2)),
CFGs = [{Node,get_absdir(filename:join(SpecDir,CfgDir))} ||
CfgDir <- [CfgDir1 | CfgDir2]],
Incls = [{Node,get_absdir(filename:join(SpecDir,IncludeDir))} ||
IncludeDir <- [IncludeDir1 | IncludeDir2]],
Verify = #testspec{spec_dir = SpecDir,
nodes = [{undefined,Node}],
init = [],
label = [{Node,"basic_compatible_no_nodes"}],
logdir = [{Node,LogDirV},"."],
logopts = [{Node,[no_nl]}],
basic_html = [],
cover = [],
config = CFGs,
userconfig = [{Node,{?MODULE,"cfg_str1"}},
{Node,{?MODULE,"cfg_str2"}}],
event_handler = [{Node,evh1,[1]},
{Node,evh2,[[2,3]]},
{Node,evh3,[[2,3]]}],
ct_hooks = [{Node,{cth_mod1,[]}},
{Node,{cth_mod2,[]}}],
enable_builtin_hooks = true,
release_shell = false,
include = Incls,
auto_compile = [],
stylesheet = [],
multiply_timetraps = [{Node,2}],
scale_timetraps = [],
create_priv_dir = [],
alias = [{to1,Alias1V},{to2,Alias2V}],
tests = [{{Node,Alias1V},
[{x_SUITE,[all]},
{y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
{z_SUITE,[{all,{skip,"skipped"}}]}]},
{{Node,Alias2V},
[{x_SUITE,[all,
{{g1,all},{skip,"skipped"}},
{{g2,all},{skip,"skipped"}}]},
{y_SUITE,[all,
{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}],
merge_tests = true},
verify_result(Verify,ListResult,FileResult).
%%%-----------------------------------------------------------------
%%%
basic_compatible_nodes(_Config) ->
Node1 = node1@host1,
Node2 = node2@host2,
TODir1 = "../tests/to1",
TODir2 = "../tests/to2",
CfgDir1 = "../cfgs/to1/x.cfg",
CfgDir2 = ["../cfgs/to2/x.cfg","../cfgs/to2/y.cfg"],
LogDir = "../logs",
MasterLogDir = "../master_logs",
IncludeDir1 = "../../include",
IncludeDir2 = ["../tests/to1/include","../tests/to2/include"],
Spec =
[
{node,n1,Node1},
{node,n2,Node2},
{init,[n1],[{node_start,[{callback_module,cbm}]}]},
{init,n2,[{node_start,[]}]},
{init,all_nodes,{eval,{mod,func,[]}}},
{label,"basic_compatible_nodes"},
{label,n1,basic_compatible_nodes_1},
{config,n1,CfgDir1},
{config,n2,CfgDir2},
{userconfig,{?MODULE,"cfg_str1"}},
{userconfig,{?MODULE,"cfg_str2"}},
{logdir,all_nodes,LogDir},
{logdir,master,MasterLogDir},
{logopts,node2@host2,[no_nl]},
{event_handler,master,evh1,[1]},
{event_handler,[n1,n2],[evh2,evh3],[[2,3]]},
{ct_hooks,all_nodes,[{cth_mod1,[]}]},
{ct_hooks,[{cth_mod2,[]}]},
{multiply_timetraps,node1@host1,2},
{include,n1,IncludeDir1},
{include,[n1,n2],IncludeDir2},
{suites,n1,TODir1,[x_SUITE]},
{groups,n1,TODir1,y_SUITE,[g1,g2]},
{cases,n1,TODir1,y_SUITE,[tc1,tc2]},
{skip_suites,n1,TODir1,z_SUITE,"skipped"},
{suites,n2,TODir2,[x_SUITE,y_SUITE]},
{skip_groups,n2,TODir2,x_SUITE,[g1,g2],"skipped"},
{skip_cases,n2,TODir2,y_SUITE,[tc1,tc2],"skipped"}
],
{ok,SpecDir} = file:get_cwd(),
ListResult = ct_testspec:collect_tests_from_list(Spec, false),
ct:pal("TESTSPEC RECORD FROM LIST:~n~p~n", [rec2proplist(ListResult)]),
SpecFile = ct_test_support:write_testspec(Spec,SpecDir,
"basic_compatible_nodes.spec"),
FileResult = ct_testspec:collect_tests_from_file([SpecFile], false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
Node = node(),
LogDirV = get_absdir(filename:join(SpecDir,"../logs")),
MasterLogDirV = get_absdir(filename:join(SpecDir,"../master_logs")),
TO1V = get_absdir(filename:join(SpecDir,TODir1)),
TO2V = get_absdir(filename:join(SpecDir,TODir2)),
CFGs = [{Node1,get_absdir(filename:join(SpecDir,CfgDir1))} |
[{Node2,get_absdir(filename:join(SpecDir,CfgDir))} || CfgDir <- CfgDir2]],
Incls = [{Node1,get_absdir(filename:join(SpecDir,IncludeDir1))} |
[{Node1,get_absdir(filename:join(SpecDir,IncludeDir))} ||
IncludeDir <- IncludeDir2] ++
[{Node2,get_absdir(filename:join(SpecDir,IncludeDir))} ||
IncludeDir <- IncludeDir2]],
Verify = #testspec{spec_dir = SpecDir,
nodes = [{undefined,Node},{n1,Node1},{n2,Node2}],
init = [{Node1,[{node_start,[{callback_module,cbm}]},
{eval,[{mod,func,[]}]}]},
{Node2,[{node_start,[{callback_module,ct_slave}]},
{eval,[{mod,func,[]}]}]},
{Node,[{node_start,[]},
{eval,[{mod,func,[]}]}]}],
label = [{Node,"basic_compatible_nodes"},
{Node2,"basic_compatible_nodes"},
{Node1,basic_compatible_nodes_1}],
logdir = [{Node,LogDirV},{Node1,LogDirV},{Node2,LogDirV},
{master,MasterLogDirV},"."],
logopts = [{Node2,[no_nl]}],
basic_html = [],
cover = [],
config = CFGs,
userconfig = [{Node,{?MODULE,"cfg_str1"}},
{Node1,{?MODULE,"cfg_str1"}},
{Node2,{?MODULE,"cfg_str1"}},
{Node,{?MODULE,"cfg_str2"}},
{Node1,{?MODULE,"cfg_str2"}},
{Node2,{?MODULE,"cfg_str2"}}],
event_handler = [{master,evh1,[1]},
{Node1,evh2,[[2,3]]},
{Node1,evh3,[[2,3]]},
{Node2,evh2,[[2,3]]},
{Node2,evh3,[[2,3]]}],
ct_hooks = [{Node,{cth_mod1,[]}},
{Node1,{cth_mod1,[]}},
{Node2,{cth_mod1,[]}},
{Node,{cth_mod2,[]}},
{Node1,{cth_mod2,[]}},
{Node2,{cth_mod2,[]}}],
enable_builtin_hooks = true,
release_shell = false,
include = Incls,
auto_compile = [],
stylesheet = [],
multiply_timetraps = [{Node1,2}],
scale_timetraps = [],
create_priv_dir = [],
tests = [{{Node1,TO1V},
[{x_SUITE,[all]},
{y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
{z_SUITE,[{all,{skip,"skipped"}}]}]},
{{Node2,TO2V},
[{x_SUITE,[all,
{{g1,all},{skip,"skipped"}},
{{g2,all},{skip,"skipped"}}]},
{y_SUITE,[all,
{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}],
merge_tests = true},
verify_result(Verify,ListResult,FileResult).
%%%-----------------------------------------------------------------
%%%
unknown_terms(Config) ->
PrivDir = ?config(priv_dir, Config),
Spec1 = [{suites,PrivDir,all},
{userdata,"I've got news for you"}],
{error,{undefined_term_in_spec,{userdata,_}}} =
(catch ct_testspec:collect_tests_from_list(Spec1, false)),
true = is_record(ct_testspec:collect_tests_from_list(Spec1, true),
testspec),
Spec2 = [{logdir,{logdir,PrivDir}}],
{error,{invalid_directory_name,_}} =
(catch ct_testspec:collect_tests_from_list(Spec2, false)),
Spec3 = [{suite,PrivDir,all}],
{error,{undefined_term_in_spec,{suite,_,_}}} =
(catch ct_testspec:collect_tests_from_list(Spec3, false)),
true = is_record(ct_testspec:collect_tests_from_list(Spec3, true), testspec),
Spec4 = [{suites,PrivDir,all},
{skip_suites,PrivDir,x_SUITE}],
{error,{bad_term_in_spec,{skip_suites,_,_}}} =
(catch ct_testspec:collect_tests_from_list(Spec4, false)),
{error,{bad_term_in_spec,{skip_suites,_,_}}} =
(catch ct_testspec:collect_tests_from_list(Spec4, true)),
Spec5 = [{configs,all_nodes,PrivDir}],
{error,{undefined_term_in_spec,{configs,_,_}}} =
(catch ct_testspec:collect_tests_from_list(Spec5, false)),
true = is_record(ct_testspec:collect_tests_from_list(Spec5, true), testspec),
ok.
%%%-----------------------------------------------------------------
%%%
no_merging(_Config) ->
Node1 = node1@host1,
Node2 = node2@host2,
TODir1 = "../tests/to1",
TODir2 = "../tests/to2",
Spec =
[
{merge_tests,false},
{node,n1,Node1},
{node,n2,Node2},
{suites,n1,TODir1,[x_SUITE]},
{groups,n1,TODir1,y_SUITE,[g1,g2]},
{cases,n1,TODir1,y_SUITE,[tc1,tc2]},
{skip_suites,n1,TODir1,z_SUITE,"skipped"},
{suites,n2,TODir2,[x_SUITE,y_SUITE]},
{skip_groups,n2,TODir2,x_SUITE,[g1,g2],"skipped"},
{skip_cases,n2,TODir2,y_SUITE,[tc1,tc2],"skipped"}
],
{ok,SpecDir} = file:get_cwd(),
ListResult = ct_testspec:collect_tests_from_list(Spec, false),
ct:pal("TESTSPEC RECORD FROM LIST:~n~p~n", [rec2proplist(ListResult)]),
SpecFile = ct_test_support:write_testspec(Spec,SpecDir,
"no_merging.spec"),
FileResult = ct_testspec:collect_tests_from_file([SpecFile], false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
Node = node(),
TO1V = get_absdir(filename:join(SpecDir,TODir1)),
TO2V = get_absdir(filename:join(SpecDir,TODir2)),
Verify = #testspec{merge_tests = false,
spec_dir = SpecDir,
nodes = [{undefined,Node},{n1,Node1},{n2,Node2}],
tests = [{{Node1,TO1V},
[{x_SUITE,[all]}]},
{{Node1,TO1V},
[{y_SUITE,[{g1,all},{g2,all}]}]},
{{Node1,TO1V},
[{y_SUITE,[tc1,tc2]}]},
{{Node1,TO1V},
[{z_SUITE,[{all,{skip,"skipped"}}]}]},
{{Node2,TO2V},
[{x_SUITE,[all]}]},
{{Node2,TO2V},
[{y_SUITE,[all]}]},
{{Node2,TO2V},
[{x_SUITE,[{{g1,all},{skip,"skipped"}},
{{g2,all},{skip,"skipped"}}]}]},
{{Node2,TO2V},
[{y_SUITE,[{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}]},
verify_result(Verify,ListResult,FileResult).
%%%-----------------------------------------------------------------
%%%
multiple_specs(_Config) ->
Node1 = node1@host1,
Node2 = node2@host2,
TODir1 = "../tests/to1",
TODir2 = "../tests/to2",
CfgDir1 = "../cfgs/to1/x.cfg",
CfgDir2 = ["../cfgs/to2/x.cfg","../cfgs/to2/y.cfg"],
LogDir = "../logs",
Spec1 =
[
{node,n1,Node1},
{node,n2,Node2},
{alias,to1,TODir1},
{alias,to2,TODir2},
{label,"multiple_specs1"},
{config,n1,CfgDir1},
{config,n2,CfgDir2},
{logdir,all_nodes,LogDir}
],
Spec2 =
[
{merge_tests,false},
{label,"multiple_specs2"},
{suites,n1,TODir1,[x_SUITE]},
{groups,n1,TODir1,y_SUITE,[g1,g2]},
{cases,n1,TODir1,y_SUITE,[tc1,tc2]},
{skip_suites,n1,TODir1,z_SUITE,"skipped"},
{suites,n2,TODir2,[x_SUITE,y_SUITE]},
{skip_groups,n2,TODir2,x_SUITE,[g1,g2],"skipped"},
{skip_cases,n2,TODir2,y_SUITE,[tc1,tc2],"skipped"}
],
{ok,SpecDir} = file:get_cwd(),
SpecFile1 = ct_test_support:write_testspec(Spec1,SpecDir,
"multiple_specs.1.spec"),
SpecFile2 = ct_test_support:write_testspec(Spec2,SpecDir,
"multiple_specs.2.spec"),
FileResult = ct_testspec:collect_tests_from_file([[SpecFile1,SpecFile2]],
false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
Node = node(),
TO1V = get_absdir(filename:join(SpecDir,TODir1)),
TO2V = get_absdir(filename:join(SpecDir,TODir2)),
CFGs = [{Node1,get_absdir(filename:join(SpecDir,CfgDir1))} |
[{Node2,get_absdir(filename:join(SpecDir,CfgDir))} || CfgDir <- CfgDir2]],
LogDirV = get_absdir(filename:join(SpecDir,"../logs")),
Verify = #testspec{merge_tests = true,
spec_dir = SpecDir,
nodes = [{undefined,Node},{n1,Node1},{n2,Node2}],
alias = [{to1,TO1V},{to2,TO2V}],
label = [{Node,"multiple_specs1"},
{Node1,"multiple_specs1"},
{Node2,"multiple_specs1"}],
logdir = [{Node,LogDirV},{Node1,LogDirV},{Node2,LogDirV},"."],
config = CFGs,
tests = [{{Node1,TO1V},
[{x_SUITE,[all]},
{y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
{z_SUITE,[{all,{skip,"skipped"}}]}]},
{{Node2,TO2V},
[{x_SUITE,[all,{{g1,all},{skip,"skipped"}},
{{g2,all},{skip,"skipped"}}]},
{y_SUITE,[all,{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}]},
verify_result(Verify,FileResult,FileResult).
%%%-----------------------------------------------------------------
%%%
misc_config_terms(_Config) ->
CfgDir = "../cfgs/to1",
TODir = "../tests/to1",
Spec =
[{node,x,n1@h1},{node,y,n2@h2},
{config,CfgDir,"a.cfg"},
{config,n1@h1,CfgDir,"b.cfg"},
{config,all_nodes,CfgDir,"c.cfg"},
{config,all_nodes,filename:join(CfgDir,"d.cfg")},
{basic_html,true},
{basic_html,n1@h1,false},
{basic_html,n2@h2,true},
{silent_connections,n1@h1,all},
{silent_connections,n2@h2,[ssh]},
{enable_builtin_hooks,false},
{release_shell,true},
{auto_compile,false},
{auto_compile,n1@h1,true},
{auto_compile,n2@h2,false},
{stylesheet,"../css"},
{stylesheet,n1@h1,"./n1/css"},
{stylesheet,n2@h2,"./n2/css"},
{create_priv_dir,[auto_per_tc]},
{create_priv_dir,n1@h1,[manual_per_tc]},
{create_priv_dir,n2@h2,[auto_per_run]},
{suites,n1@h1,TODir,[x_SUITE]}
],
{ok,SpecDir} = file:get_cwd(),
ListResult = ct_testspec:collect_tests_from_list(Spec, false),
ct:pal("TESTSPEC RECORD FROM LIST:~n~p~n", [rec2proplist(ListResult)]),
SpecFile = ct_test_support:write_testspec(Spec,SpecDir,
"misc_config_terms.spec"),
FileResult = ct_testspec:collect_tests_from_file([SpecFile], false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
Node = node(),
CfgA = get_absdir(filename:join(filename:join(SpecDir,CfgDir), "a.cfg")),
CfgB = get_absdir(filename:join(filename:join(SpecDir,CfgDir), "b.cfg")),
CfgC = get_absdir(filename:join(filename:join(SpecDir,CfgDir), "c.cfg")),
CfgD = get_absdir(filename:join(filename:join(SpecDir,CfgDir), "d.cfg")),
CSS = get_absdir(filename:join(SpecDir,"../css")),
CSS1 = get_absdir(filename:join(SpecDir,"./n1/css")),
CSS2 = get_absdir(filename:join(SpecDir,"./n2/css")),
Verify = #testspec{spec_dir = SpecDir,
nodes = [{undefined,Node},{x,n1@h1},{y,n2@h2}],
basic_html = [{Node,true},{n1@h1,false},{n2@h2,true}],
silent_connections = [{n1@h1,[all]},{n2@h2,[ssh]}],
config = [{Node,CfgA},
{n1@h1,CfgA},
{n2@h2,CfgA},
{n1@h1,CfgB},
{Node,CfgC},
{n1@h1,CfgC},
{n2@h2,CfgC},
{Node,CfgD},
{n1@h1,CfgD},
{n2@h2,CfgD}],
enable_builtin_hooks = false,
release_shell = true,
auto_compile = [{Node,false},
{n1@h1,true},
{n2@h2,false}],
stylesheet = [{Node,CSS},
{n1@h1,CSS1},
{n2@h2,CSS2}],
create_priv_dir = [{Node,[auto_per_tc]},
{n1@h1,[manual_per_tc]},
{n2@h2,[auto_per_run]}],
tests = [{{n1@h1,get_absdir(filename:join(SpecDir,TODir))},
[{x_SUITE,[all]}]}]
},
verify_result(Verify,ListResult,FileResult).
%%%-----------------------------------------------------------------
%%%
define_names_1(_Config) ->
Spec =
[
{define,'HOST','eniac'},
{define,'NODE1',testnode1},
{define,'NODE2',testnode2},
{define,'NODES',['NODE1@HOST',
'NODE2@HOST']},
{define,'TOPDIR',".."},
{define,'TO1',"to1"},
{define,'TO2',"to2"},
{define,'LOGDIR',"'TOPDIR'/logdir"},
{define,'LOGDIR1',"'TOPDIR'/logdir1"},
{define,'LOGDIR2',"'TOPDIR'/logdir2"},
{define,'CFGDIR',"'TOPDIR'/cfgs"},
{define,'CFGFILES',["cfgX","cfgY"]},
{define,'TESTDIR',"'TOPDIR'/test"},
{define,'TO1DIR',"'TESTDIR'/'TO1'"},
{define,'TO2DIR',"'TESTDIR'/'TO2'"},
{define,'EXSUITE',ex_SUITE},
{define,'EXGRS',[g1,g2]},
{logdir,'LOGDIR'},
{logdir,'NODE1@HOST','LOGDIR1'},
{logdir,'NODE2@HOST','LOGDIR2'},
{config,["a.cfg","b.cfg"]},
{config,'NODES',"./'CFGDIR'/c.cfg"},
{config,'CFGDIR',["d.cfg","e.cfg"]},
{config,'NODE2@HOST','CFGDIR','CFGFILES'},
{suites,'NODE1@HOST','TO1DIR',all},
{suites,'NODES','TO2DIR',all},
{groups,'TO1DIR','EXSUITE','EXGRS'}
],
{ok,SpecDir} = file:get_cwd(),
ListResult = ct_testspec:collect_tests_from_list(Spec, false),
ct:pal("TESTSPEC RECORD FROM LIST:~n~p~n", [rec2proplist(ListResult)]),
SpecFile = ct_test_support:write_testspec(Spec,SpecDir,
"define_names_1.spec"),
FileResult = ct_testspec:collect_tests_from_file([SpecFile], false),
ct:pal("TESTSPEC RECORD FROM FILE:~n~p~n", [rec2proplist(FileResult)]),
N = node(),
N1 = testnode1@eniac,
N2 = testnode2@eniac,
Join = fun(Dir) -> shorten_path(filename:join(SpecDir,Dir),SpecDir) end,
Verify = #testspec{spec_dir = SpecDir,
nodes = [{undefined,N2},
{undefined,N1},
{undefined,N}],
config = [{N2,Join("a.cfg")},{N2,Join("b.cfg")},
{N1,Join("a.cfg")},{N1,Join("b.cfg")},
{N,Join("a.cfg")},{N,Join("b.cfg")},
{N1,Join("../cfgs/c.cfg")},{N2,Join("../cfgs/c.cfg")},
{N2,Join("../cfgs/d.cfg")},{N2,Join("../cfgs/e.cfg")},
{N1,Join("../cfgs/d.cfg")},{N1,Join("../cfgs/e.cfg")},
{N,Join("../cfgs/d.cfg")},{N,Join("../cfgs/e.cfg")},
{N2,Join("../cfgs/cfgX")},{N2,Join("../cfgs/cfgY")}],
logdir = [{N,Join("../logdir")},
{N1,Join("../logdir1")},
{N2,Join("../logdir2")},
"."],
tests = [{{N1,Join("../test/to1")},[{all,[all]}]},
{{N1,Join("../test/to2")},[{all,[all]}]},
{{N2,Join("../test/to2")},[{all,[all]}]},
{{N2,Join("../test/to1")},
[{ex_SUITE,[{g1,all},{g2,all}]}]},
{{N,Join("../test/to1")},
[{ex_SUITE,[{g1,all},{g2,all}]}]}]
},
verify_result(Verify,ListResult,FileResult).
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
verify_result(VerificationRec,ListResult,FileResult) ->
{_,TSLTuples} = rec2proplist(ListResult),
{_,TSFTuples} = rec2proplist(FileResult),
{_,VTuples} = rec2proplist(VerificationRec),
VResult =
(catch lists:foldl(fun({Tag,Val},{[{Tag,Val}|TSL],[{Tag,Val}|TSF]}) ->
{TSL,TSF};
({Tag,Val},{[{_Tag,TSLVal}|_TSL],[{Tag,Val}|_TSF]}) ->
exit({ts_list_mismatch,Tag,Val,TSLVal});
({Tag,Val},{[{Tag,Val}|_TSL],[{_Tag,TSFVal}|_TSF]}) ->
exit({ts_file_mismatch,Tag,Val,TSFVal});
({Tag,Val},{_,[{_Tag,TSFVal}|_TSF]}) ->
exit({ts_mismatch,Tag,Val,TSFVal})
end, {TSLTuples,TSFTuples}, VTuples)),
case VResult of
{'EXIT',Reason} ->
ct:fail(Reason);
_ ->
ok
end,
ok.
check_parameter(S="cfg_str1") ->
{ok,{config,S}};
check_parameter(S="cfg_str2") ->
{ok,{config,S}}.
read_config(S) ->
{ok,[{cfg,S}]}.
rec2proplist(E={error,_What}) ->
exit({invalid_testspec_record,E});
rec2proplist([{Specs,Rec}]) when is_list(Specs) ->
rec2proplist(Rec);
rec2proplist(Rec) ->
[RecName|RecList] = tuple_to_list(Rec),
FieldNames =
if RecName == testspec ->
record_info(fields, testspec);
true ->
undefined
end,
{RecName,combine_names_and_vals(FieldNames,RecList)}.
combine_names_and_vals([FN|FNs], [V|Vs]) ->
[{FN,V} | combine_names_and_vals(FNs, Vs)];
combine_names_and_vals([], []) ->
[];
combine_names_and_vals(_, _) ->
[].
get_absdir(Dir) ->
shorten_path(filename:absname(Dir),Dir).
shorten_path(Path,SpecDir) ->
case shorten_split_path(filename:split(Path),[]) of
[] ->
[Root|_] = filename:split(SpecDir),
Root;
Short ->
filename:join(Short)
end.
shorten_split_path([".."|Path],SoFar) ->
shorten_split_path(Path,tl(SoFar));
shorten_split_path(["."|Path],SoFar) ->
shorten_split_path(Path,SoFar);
shorten_split_path([Dir|Path],SoFar) ->
shorten_split_path(Path,[Dir|SoFar]);
shorten_split_path([],SoFar) ->
lists:reverse(SoFar).