aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/src/ct_testspec.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common_test/src/ct_testspec.erl')
-rw-r--r--lib/common_test/src/ct_testspec.erl105
1 files changed, 92 insertions, 13 deletions
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index a0da079c54..db3efb16e8 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -270,33 +270,52 @@ collect_tests(Terms,TestSpec,Relaxed) ->
put(relaxed,Relaxed),
TestSpec1 = get_global(Terms,TestSpec),
TestSpec2 = get_all_nodes(Terms,TestSpec1),
- case catch evaluate(Terms,TestSpec2) of
+ % filter out node_start options and save them into the specification
+ {Terms2, TestSpec3} = filter_nodestart_specs(Terms, [], TestSpec2),
+ % only save the 'global' evals and evals for nodes which have no node_start
+ {Terms3, TestSpec4} = filter_evals(Terms2, [], TestSpec3),
+ % after evaluation, only valid terms exist in the specification list
+ Terms4 = case catch evaluate(Terms3, [], TestSpec4) of
{error,{Node,{M,F,A},Reason}} ->
io:format("Error! Common Test failed to evaluate ~w:~w/~w on ~w. "
- "Reason: ~p~n~n", [M,F,A,Node,Reason]);
- _ -> ok
+ "Reason: ~p~n~n", [M,F,A,Node,Reason]),
+ Terms3;
+ NewTerms -> NewTerms
end,
- add_tests(Terms,TestSpec2).
-
-evaluate([{eval,NodeRef,{M,F,Args}}|Ts],Spec) ->
- Node = ref2node(NodeRef,Spec#testspec.nodes),
+ add_tests(Terms4,TestSpec4).
+
+evaluate([{eval,Node,[{_,_,_}|_]=Mfas}|Ts],NewTerms,Spec)->
+ EvalTerms = lists:map(fun(Mfa)->
+ {eval, Node, Mfa}
+ end,
+ Mfas),
+ evaluate([EvalTerms|Ts], NewTerms, Spec);
+evaluate([{eval,[{_,_,_}|_]=Mfas}|Ts],NewTerms,Spec)->
+ EvalTerms = lists:map(fun(Mfa)->
+ {eval, Mfa}
+ end,
+ Mfas),
+ evaluate([EvalTerms|Ts], NewTerms, Spec);
+evaluate([{eval,Node,{M,F,Args}}|Ts],NewTerms,Spec) ->
case rpc:call(Node,M,F,Args) of
{badrpc,Reason} ->
throw({error,{Node,{M,F,length(Args)},Reason}});
_ ->
ok
end,
- evaluate(Ts,Spec);
-evaluate([{eval,{M,F,Args}}|Ts],Spec) ->
+ evaluate(Ts,NewTerms,Spec);
+evaluate([{eval,{M,F,Args}}|Ts],NewTerms,Spec) ->
case catch apply(M,F,Args) of
{'EXIT',Reason} ->
throw({error,{node(),{M,F,length(Args)},Reason}});
_ ->
ok
end,
- evaluate(Ts,Spec);
-evaluate([],_Spec) ->
- ok.
+ evaluate(Ts,NewTerms,Spec);
+evaluate([Term|Ts], NewTerms, Spec)->
+ evaluate(Ts, [Term|NewTerms], Spec);
+evaluate([], NewTerms, _Spec) ->
+ NewTerms.
get_global([{alias,Ref,Dir}|Ts],Spec=#testspec{alias=Refs}) ->
get_global(Ts,Spec#testspec{alias=[{Ref,get_absdir(Dir,Spec)}|Refs]});
@@ -373,6 +392,65 @@ get_all_nodes([_|Ts],Spec) ->
get_all_nodes([],Spec) ->
Spec.
+filter_nodestart_specs([{node_start, Options}|Ts], NewTerms, Spec) ->
+ filter_nodestart_specs([{node_start, list_nodes(Spec), Options}|Ts], NewTerms, Spec);
+filter_nodestart_specs([{node_start, NodeRef, Options}|Ts], NewTerms, Spec) when is_atom(NodeRef) ->
+ filter_nodestart_specs([{node_start, [NodeRef], Options}|Ts], NewTerms, Spec);
+filter_nodestart_specs([{node_start, NodeRefs, Options}|Ts], NewTerms, Spec=#testspec{node_start=NodeStart})->
+ Options2 = case lists:keyfind(callback_module, 1, Options) of
+ false->
+ [{callback_module, ct_slave}|Options];
+ {callback_module, _Callback}->
+ Options
+ end,
+ NSSAdder = fun(NodeRef, NodeStartAcc)->
+ Node=ref2node(NodeRef,Spec#testspec.nodes),
+ case lists:keyfind(Node, 1, NodeStartAcc) of
+ false->
+ [{Node, Options2}|NodeStartAcc];
+ {Node, OtherOptions}->
+ io:format("~nWarning: There are other options defined for node ~p:"
+ "~n~w, skipping ~n~w...~n", [Node, OtherOptions, Options2]),
+ NodeStartAcc
+ end
+ end,
+ NodeStart2 = lists:foldl(NSSAdder, NodeStart, NodeRefs),
+ filter_nodestart_specs(Ts, NewTerms, Spec#testspec{node_start=NodeStart2});
+filter_nodestart_specs([Term|Ts], NewTerms, Spec)->
+ filter_nodestart_specs(Ts, [Term|NewTerms], Spec);
+filter_nodestart_specs([], NewTerms, Spec) ->
+ {NewTerms, Spec}.
+
+filter_evals([{eval,NodeRefs,Mfa}|Ts], NewTerms, Spec) when is_list(NodeRefs)->
+ EvalTerms = lists:map(fun(NodeRef)->
+ {eval, NodeRef, Mfa}
+ end,
+ NodeRefs),
+ filter_evals(EvalTerms++Ts, NewTerms, Spec);
+filter_evals([{eval,NodeRef,{_,_,_}=Mfa}|Ts],NewTerms,Spec)->
+ filter_evals([{eval,NodeRef,[Mfa]}|Ts],NewTerms,Spec);
+filter_evals([{eval,NodeRef,[{_,_,_}|_]=Mfas}=EvalTerm|Ts],
+ NewTerms,Spec=#testspec{node_start=NodeStart})->
+ Node=ref2node(NodeRef,Spec#testspec.nodes),
+ case lists:keyfind(Node, 1, NodeStart) of
+ false->
+ filter_evals(Ts, [EvalTerm|NewTerms], Spec);
+ {Node, Options}->
+ Options2 = case lists:keyfind(startup_functions, 1, Options) of
+ false->
+ [{startup_functions, Mfas}|Options];
+ {startup_functions, StartupFunctions}->
+ lists:keyreplace(startup_functions, 1, Options,
+ {startup_functions, StartupFunctions ++ Mfas})
+ end,
+ NodeStart2 = lists:keyreplace(Node, 1, NodeStart, {Node, Options2}),
+ filter_evals(Ts, NewTerms, Spec#testspec{node_start=NodeStart2})
+ end;
+filter_evals([Term|Ts], NewTerms, Spec)->
+ filter_evals(Ts, [Term|NewTerms], Spec);
+filter_evals([], NewTerms, Spec)->
+ {NewTerms, Spec}.
+
save_nodes(Nodes,Spec=#testspec{nodes=NodeRefs}) ->
NodeRefs1 =
lists:foldr(fun(all_nodes,NR) ->
@@ -794,6 +872,8 @@ valid_terms() ->
{cover,3},
{config,2},
{config,3},
+ {userconfig, 2},
+ {userconfig, 3},
{alias,3},
{logdir,2},
{logdir,3},
@@ -802,7 +882,6 @@ valid_terms() ->
{event_handler,4},
{include,2},
{include,3},
-
{suites,3},
{suites,4},
{cases,4},