Skip to content

Commit 0604560

Browse files
author
Brett Hazen
committed
Initial introduction of rt_test_plan record to wrap tests
1 parent 867228e commit 0604560

File tree

10 files changed

+915
-104
lines changed

10 files changed

+915
-104
lines changed

src/giddyup.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ get_schema(Platform) ->
5858

5959
get_schema(Platform, Retries) ->
6060
Host = rt_config:get(giddyup_host),
61-
Project = rt_config:get(rt_project),
61+
Project = rt_config:get(giddyup_project),
6262
Version = rt:get_version(),
6363
URL = lists:flatten(io_lib:format("http://~s/projects/~s?platform=~s&version=~s", [Host, Project, Platform, Version])),
6464
lager:info("giddyup url: ~s", [URL]),

src/riak_test_escript.erl

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -44,38 +44,37 @@ main(Args) ->
4444
finalize(Results, ParsedArgs).
4545

4646
prepare(ParsedArgs, Tests, NonTests) ->
47-
lager:notice("Tests to run: ~p~n", [Tests]),
47+
lager:notice("Test to run: ~p", [[rt_test_plan:get_module(Test) || Test <- Tests]]),
4848
case NonTests of
4949
[] ->
5050
ok;
5151
_ ->
52-
lager:notice("These modules are not runnable tests: ~p~n",
53-
[[NTMod || {NTMod, _} <- NonTests]])
52+
lager:notice("Test not to run: ~p", [[rt_test_plan:get_module(Test) || Test <- NonTests]])
5453
end,
5554
ok = erlang_setup(ParsedArgs),
5655
test_setup().
5756

58-
execute(Tests, ParsedArgs, _HarnessArgs) ->
57+
execute(TestPlans, ParsedArgs, _HarnessArgs) ->
5958
OutDir = proplists:get_value(outdir, ParsedArgs),
6059
Report = report(ParsedArgs),
6160
UpgradeList = upgrade_list(
6261
proplists:get_value(upgrade_path, ParsedArgs)),
63-
Backend = proplists:get_value(backend, ParsedArgs, bitcask),
6462

65-
{ok, Executor} = riak_test_executor:start_link(Tests,
66-
Backend,
63+
{ok, Executor} = riak_test_executor:start_link(TestPlans,
6764
OutDir,
6865
Report,
6966
UpgradeList,
7067
self()),
71-
wait_for_results(Executor, [], length(Tests), 0).
68+
wait_for_results(Executor, [], length(TestPlans), 0).
7269

7370

7471
report_results(Results, Verbose) ->
7572
%% TODO: Good place to also do giddyup reporting and provide a
7673
%% place for extending to any other reporting sources that might
7774
%% be useful.
78-
print_summary(Results, undefined, Verbose),
75+
76+
ModuleResults = [{rt_test_plan:get_module(TestPlan), PassFail, Duration} || {TestPlan, PassFail, Duration} <- Results],
77+
print_summary(ModuleResults, undefined, Verbose),
7978
ok.
8079

8180
%% TestResults = run_tests(Tests, Outdir, Report, HarnessArgs),
@@ -121,6 +120,7 @@ finalize(TestResults, Args) ->
121120
Teardown = not proplists:get_value(keep, Args, false),
122121
maybe_teardown(Teardown, TestResults),
123122
ok.
123+
124124
%% Option Name, Short Code, Long Code, Argument Spec, Help Message
125125
cli_options() ->
126126
[
@@ -184,7 +184,7 @@ report(ParsedArgs) ->
184184
undefined ->
185185
undefined;
186186
"config" ->
187-
rt_config:get(platform, undefined);
187+
rt_config:get(giddyup_platform, undefined);
188188
R ->
189189
R
190190
end.
@@ -212,7 +212,8 @@ help_or_parse_tests(ParsedArgs, HarnessArgs, false) ->
212212
maybe_override_setting(continue_on_fail, true, ParsedArgs),
213213

214214
TestData = compose_test_data(ParsedArgs),
215-
{Tests, NonTests} = which_tests_to_run(report(ParsedArgs), TestData),
215+
Backend = proplists:get_value(backend, ParsedArgs, bitcask),
216+
{Tests, NonTests} = wrap_test_in_test_plan(report(ParsedArgs), Backend, TestData),
216217
Offset = rt_config:get(offset, undefined),
217218
Workers = rt_config:get(workers, undefined),
218219
shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, Offset, Workers).
@@ -235,6 +236,7 @@ load_initial_config(ParsedArgs) ->
235236
proplists:get_value(file, ParsedArgs)).
236237

237238
shuffle_tests(_, _, [], _, _, _) ->
239+
io:format("No tests are scheduled to run~n"),
238240
lager:error("No tests are scheduled to run~n"),
239241
halt(1);
240242
shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, undefined, _) ->
@@ -364,49 +366,41 @@ extract_test_names(Test, {CodePaths, TestNames}) ->
364366
{[filename:dirname(Test) | CodePaths],
365367
[list_to_atom(filename:rootname(filename:basename(Test))) | TestNames]}.
366368

367-
which_tests_to_run(undefined, CommandLineTests) ->
368-
lists:partition(fun is_runnable_test/1, CommandLineTests);
369-
which_tests_to_run(Platform, []) ->
370-
giddyup:get_suite(Platform);
371-
which_tests_to_run(Platform, CommandLineTests) ->
372-
Suite = filter_zip_suite(Platform, CommandLineTests),
373-
lists:partition(fun is_runnable_test/1,
374-
lists:foldr(fun filter_merge_tests/2, [], Suite)).
375-
376-
filter_zip_suite(Platform, CommandLineTests) ->
377-
[ {SModule, SMeta, CMeta} || {SModule, SMeta} <- giddyup:get_suite(Platform),
378-
{CModule, CMeta} <- CommandLineTests,
379-
SModule =:= CModule].
380-
381-
filter_merge_tests({Module, SMeta, CMeta}, Tests) ->
382-
case filter_merge_meta(SMeta, CMeta, [backend, upgrade_version]) of
383-
false ->
384-
Tests;
385-
Meta ->
386-
[{Module, Meta}|Tests]
387-
end.
388-
389-
filter_merge_meta(SMeta, _CMeta, []) ->
390-
SMeta;
391-
filter_merge_meta(SMeta, CMeta, [Field|Rest]) ->
392-
case {kvc:value(Field, SMeta, undefined), kvc:value(Field, CMeta, undefined)} of
393-
{X, X} ->
394-
filter_merge_meta(SMeta, CMeta, Rest);
395-
{_, undefined} ->
396-
filter_merge_meta(SMeta, CMeta, Rest);
397-
{undefined, X} ->
398-
filter_merge_meta(lists:keystore(Field, 1, SMeta, {Field, X}), CMeta, Rest);
369+
%% @doc Determine which tests to run based on command-line argument
370+
%% If the platform is defined, consult GiddyUp, otherwise just shovel
371+
%% the whole thing into the Planner
372+
-spec(load_up_test_planner(string() | undefined, string(), list()) -> list()).
373+
load_up_test_planner(undefined, Backend, CommandLineTests) ->
374+
[rt_planner:add_test_plan(Name, undefined, Backend, undefined, undefined) || Name <- CommandLineTests];
375+
%% GiddyUp Flavor
376+
load_up_test_planner(Platform, Backend, CommandLineTests) ->
377+
rt_planner:load_from_giddyup(Platform, Backend, CommandLineTests).
378+
379+
%% @doc Push all of the test into the Planner for now and wrap them in an `rt_test_plan'
380+
%% TODO: Let the Planner do the work, not the riak_test_executor
381+
-spec(wrap_test_in_test_plan(string(), string(), [atom()]) -> {list(), list()}).
382+
wrap_test_in_test_plan(Platform, Backend, CommandLineTests) ->
383+
%% ibrowse neededfor GiddyUp
384+
load_and_start(ibrowse),
385+
{ok, _Pid} = rt_planner:start_link(),
386+
load_up_test_planner(Platform, Backend, CommandLineTests),
387+
TestPlans = [rt_planner:fetch_test_plan() || _ <- lists:seq(1, rt_planner:number_of_plans())],
388+
NonRunnableTestPlans = [rt_planner:fetch_test_non_runnable_plan() || _ <- lists:seq(1, rt_planner:number_of_non_runable_plans())],
389+
rt_planner:stop(),
390+
{TestPlans, NonRunnableTestPlans}.
391+
392+
%% @doc Pull all jobs from the Planner
393+
%% Better than using rt_planner:number_of_plans/0
394+
-spec(fetch_all_test_plans(list()) -> list()).
395+
fetch_all_test_plans(Acc) ->
396+
Plan = rt_planner:fetch_test_plan(),
397+
case Plan of
398+
empty ->
399+
Acc;
399400
_ ->
400-
false
401+
fetch_all_test_plans([Plan|Acc])
401402
end.
402403

403-
%% Check for api compatibility
404-
is_runnable_test(TestModule) ->
405-
{Mod, Fun} = riak_test_runner:function_name(confirm, TestModule),
406-
code:ensure_loaded(Mod),
407-
erlang:function_exported(Mod, Fun, 0) orelse
408-
erlang:function_exported(Mod, Fun, 1).
409-
410404
get_group_tests(Tests, Groups) ->
411405
lists:filter(fun(Test) ->
412406
Mod = list_to_atom(Test),
@@ -546,6 +540,8 @@ print_summary(TestResults, _CoverResult, Verbose) ->
546540
true ->
547541
Rows =
548542
[format_test_row(Result, Width) || Result <- TestResults],
543+
%% TODO: Remove once clique table is fixed
544+
[lager:debug("ROW ~p", [Row]) || Row <- Rows],
549545
Table = clique_table:autosize_create_table(?HEADER, Rows),
550546
io:format("~ts~n", [Table]);
551547
false ->

src/riak_test_executor.erl

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
-behavior(gen_fsm).
44

55
%% API
6-
-export([start_link/6,
6+
-export([start_link/5,
77
send_event/1,
88
stop/0]).
99

@@ -28,7 +28,6 @@
2828
running_tests=[] :: [atom()],
2929
waiting_tests=[] :: [atom()],
3030
notify_pid :: pid(),
31-
backend :: atom(),
3231
upgrade_list :: [string()],
3332
test_properties :: [proplists:proplist()],
3433
runner_pids=[] :: [pid()],
@@ -42,9 +41,9 @@
4241
%%%===================================================================
4342

4443
%% @doc Start the test executor
45-
-spec start_link(atom(), atom(), string(), string(), [string()], pid()) -> {ok, pid()} | ignore | {error, term()}.
46-
start_link(Tests, Backend, LogDir, ReportInfo, UpgradeList, NotifyPid) ->
47-
Args = [Tests, Backend, LogDir, ReportInfo, UpgradeList, NotifyPid],
44+
-spec start_link(atom(), string(), string(), [string()], pid()) -> {ok, pid()} | ignore | {error, term()}.
45+
start_link(Tests, LogDir, ReportInfo, UpgradeList, NotifyPid) ->
46+
Args = [Tests, LogDir, ReportInfo, UpgradeList, NotifyPid],
4847
gen_fsm:start_link({local, ?MODULE}, ?MODULE, Args, []).
4948

5049
send_event(Msg) ->
@@ -59,19 +58,14 @@ stop() ->
5958
%%% gen_fsm callbacks
6059
%%%===================================================================
6160

62-
init([Tests, Backend, LogDir, ReportInfo, UpgradeList, NotifyPid]) ->
61+
init([Tests, LogDir, ReportInfo, UpgradeList, NotifyPid]) ->
6362
%% TODO Change the default when parallel execution support is implemented -jsb
6463
ExecutionMode = rt_config:get(rt_execution_mode, serial),
6564

66-
%% TODO: Remove after all tests ported 2.0 -- workaround to support
67-
%% backend command line argument fo v1 cluster provisioning -jsb
68-
rt_config:set(rt_backend, Backend),
69-
7065
ContinueOnFail = rt_config:get(continue_on_fail),
7166

7267
lager:notice("Starting the Riak Test executor in ~p execution mode", [ExecutionMode]),
7368
State = #state{pending_tests=Tests,
74-
backend=Backend,
7569
log_dir=LogDir,
7670
report_info=ReportInfo,
7771
upgrade_list=UpgradeList,
@@ -165,34 +159,34 @@ launch_test({nodes, Nodes, NodeMap}, State) ->
165159
%% Spawn a test runner for the head of pending. If pending is now
166160
%% empty transition to `wait_for_completion'; otherwise,
167161
%% transition to `request_nodes'.
168-
#state{pending_tests=[NextTest | RestPending],
162+
#state{pending_tests=[NextTestPlan | RestPending],
169163
execution_mode=ExecutionMode,
170-
backend=Backend,
171164
test_properties=PropertiesList,
172165
runner_pids=Pids,
173166
running_tests=Running,
174167
continue_on_fail=ContinueOnFail} = State,
175-
lager:debug("Executing test ~p in mode ~p", [NextTest, ExecutionMode]),
176-
{NextTest, TestProps} = lists:keyfind(NextTest, 1, PropertiesList),
168+
NextTestModule = rt_test_plan:get_module(NextTestPlan),
169+
lager:debug("Executing test ~p in mode ~p", [NextTestModule, ExecutionMode]),
170+
{NextTestPlan, TestProps} = lists:keyfind(NextTestPlan, 1, PropertiesList),
177171
UpdTestProps = rt_properties:set([{node_map, NodeMap}, {node_ids, Nodes}],
178172
TestProps),
179-
{RunnerPids, RunningTests} = run_test(ExecutionMode, NextTest, Backend, UpdTestProps,
173+
{RunnerPids, RunningTests} = run_test(ExecutionMode, NextTestPlan, UpdTestProps,
180174
Pids, Running, ContinueOnFail),
181175
UpdState = State#state{pending_tests=RestPending,
182176
execution_mode=ExecutionMode,
183177
runner_pids=RunnerPids,
184178
running_tests=RunningTests},
185179

186180
launch_test_transition(UpdState);
187-
launch_test({test_complete, Test, Pid, Results, Duration}, State) ->
181+
launch_test({test_complete, TestPlan, Pid, Results, Duration}, State) ->
188182
#state{pending_tests=Pending,
189183
waiting_tests=Waiting,
190184
running_tests=Running,
191185
runner_pids=Pids,
192186
execution_mode=ExecutionMode} = State,
193187
%% Report results
194-
report_results(Test, Results, Duration, State),
195-
UpdState = State#state{running_tests=lists:delete(Test, Running),
188+
report_results(TestPlan, Results, Duration, State),
189+
UpdState = State#state{running_tests=lists:delete(TestPlan, Running),
196190
runner_pids=lists:delete(Pid, Pids),
197191
pending_tests=Pending++Waiting,
198192
waiting_tests=[],
@@ -202,26 +196,26 @@ launch_test(Event, State) ->
202196
lager:error("Unknown event ~p with state ~p.", [Event, State]),
203197
ok.
204198

205-
maybe_reserve_nodes(NextTest, TestProps) ->
199+
maybe_reserve_nodes(NextTestPlan, TestProps) ->
206200
VersionsToTest = versions_to_test(TestProps),
207-
maybe_reserve_nodes(erlang:function_exported(NextTest, confirm, 1),
208-
NextTest, VersionsToTest, TestProps).
201+
maybe_reserve_nodes(erlang:function_exported(rt_test_plan:get_module(NextTestPlan), confirm, 1),
202+
NextTestPlan, VersionsToTest, TestProps).
209203

210204
maybe_reserve_nodes(true, NextTest, VersionsToTest, TestProps) ->
211205
NodeCount = rt_properties:get(node_count, TestProps),
212206

213207
%% Send async request to node manager
214-
lager:notice("Requesting ~p nodes for the next test, ~p", [NodeCount, NextTest]),
208+
lager:notice("Requesting ~p nodes for the next test, ~p", [NodeCount, rt_test_plan:get_module(NextTest)]),
215209
node_manager:reserve_nodes(NodeCount,
216210
VersionsToTest,
217211
reservation_notify_fun());
218212
maybe_reserve_nodes(false, NextTest, VersionsToTest, _TestProps) ->
219-
lager:warning("~p is an old style test that requires conversion.", [NextTest]),
213+
lager:warning("~p is an old style test that requires conversion.", [rt_test_plan:get_module(NextTest)]),
220214
node_manager:reserve_nodes(0, VersionsToTest, reservation_notify_fun()),
221215
ok.
222216

223217
wait_for_completion({test_complete, Test, Pid, Results, Duration}, State) ->
224-
lager:debug("Test ~p complete", [Test]),
218+
lager:debug("Test ~p complete", [rt_test_plan:get_module(Test)]),
225219
#state{pending_tests=Pending,
226220
waiting_tests=Waiting,
227221
running_tests=Running,
@@ -256,8 +250,8 @@ wait_for_completion(_Event, _From, _State) ->
256250
%%% Internal functions
257251
%%%===================================================================
258252

259-
report_results(Test, Results, Duration, #state{notify_pid=NotifyPid}) ->
260-
NotifyPid ! {self(), {test_result, {Test, Results, Duration}}},
253+
report_results(TestPlan, Results, Duration, #state{notify_pid=NotifyPid}) ->
254+
NotifyPid ! {self(), {test_result, {TestPlan, Results, Duration}}},
261255
ok.
262256

263257
report_done(#state{notify_pid=NotifyPid}) ->
@@ -276,7 +270,8 @@ wait_for_completion_transition(_Result, State) ->
276270

277271
launch_test_transition(State=#state{pending_tests=PendingTests,
278272
execution_mode=ExecutionMode}) when PendingTests == [] orelse ExecutionMode == serial ->
279-
lager:debug("Waiting for completion: execution mode ~p with pending tests ~p", [ExecutionMode, PendingTests]),
273+
PendingModules = [rt_test_plan:get_module(Test) || Test <- PendingTests],
274+
lager:debug("Waiting for completion: execution mode ~p with pending tests ~p", [ExecutionMode, PendingModules]),
280275
{next_state, wait_for_completion, State};
281276
launch_test_transition(State) ->
282277
{next_state, request_nodes, State, 0}.
@@ -293,13 +288,13 @@ test_properties(Tests, OverriddenProps) ->
293288
lists:foldl(test_property_fun(OverriddenProps), [], Tests).
294289

295290
test_property_fun(OverrideProps) ->
296-
fun(TestModule, Acc) ->
291+
fun(TestPlan, Acc) ->
297292
{PropsMod, PropsFun} = riak_test_runner:function_name(properties,
298-
TestModule,
293+
rt_test_plan:get_module(TestPlan),
299294
0,
300295
rt_cluster),
301296
Properties = rt_properties:set(OverrideProps, PropsMod:PropsFun()),
302-
[{TestModule, Properties} | Acc]
297+
[{TestPlan, Properties} | Acc]
303298
end.
304299

305300
versions_to_test(Properties) ->
@@ -330,11 +325,11 @@ override_props(State) ->
330325
[{upgrade_path, UpgradeList}]
331326
end.
332327

333-
-spec run_test(parallel | serial, atom(), atom(), proplists:proplist(), [pid()], [atom()], boolean()) -> {[pid()], [atom()]}.
334-
run_test(parallel, Test, Backend, Properties, RunningPids, RunningTests, ContinueOnFail) ->
335-
Pid = spawn_link(riak_test_runner, start, [Test, Backend, Properties, ContinueOnFail]),
336-
{[Pid | RunningPids], [Test | RunningTests]};
337-
run_test(serial, Test, Backend, Properties, RunningPids, RunningTests, ContinueOnFail) ->
338-
riak_test_runner:start(Test, Backend, Properties, ContinueOnFail),
328+
-spec run_test(parallel | serial, atom(), proplists:proplist(), [pid()], [atom()], boolean()) -> {[pid()], [atom()]}.
329+
run_test(parallel, TestPlan, Properties, RunningPids, RunningTests, ContinueOnFail) ->
330+
Pid = spawn_link(riak_test_runner, start, [TestPlan, Properties, ContinueOnFail]),
331+
{[Pid | RunningPids], [TestPlan | RunningTests]};
332+
run_test(serial, TestPlan, Properties, RunningPids, RunningTests, ContinueOnFail) ->
333+
riak_test_runner:start(TestPlan, Properties, ContinueOnFail),
339334
{RunningPids, RunningTests}.
340335

0 commit comments

Comments
 (0)