Skip to content

Commit 924eaf8

Browse files
committed
Give up on rebar
As far as I can tell it's impossible to get the eqc plugin to work for profiles other than eqc.
1 parent 6bd3600 commit 924eaf8

File tree

5 files changed

+53
-65
lines changed

5 files changed

+53
-65
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ _build/*
1111
.DS_Store
1212
/.eqc-info
1313
/current_counterexample.eqc
14+
.pulse

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@ eqc:
2222
xref:
2323
$(REBAR) xref
2424

25+
PULSE_TESTING_TIME ?= 30
26+
27+
pulse: compile
28+
mkdir -p .pulse
29+
cp eqc/pulse/Emakefile .pulse
30+
cp _build/default/lib/bitcask/ebin/bitcask.app .pulse
31+
(cd .pulse; \
32+
erl -make; \
33+
erl -noshell -s bitcask_pulse run_tests $(PULSE_TESTING_TIME))
34+
2535
check: test dialyzer xref

eqc/event_logger.erl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
%%% File : handle_errors.erl
1+
%%% File : event_logger.erl
22
%%% Author : Ulf Norell
3-
%%% Description :
3+
%%% Description :
44
%%% Created : 26 Mar 2012 by Ulf Norell
55
-module(event_logger).
66

77
-compile([export_all, nowarn_export_all]).
8+
-ifdef(PULSE).
9+
-compile({parse_transform, pulse_instrument}).
10+
-include_lib("pulse_otp/include/pulse_otp.hrl").
11+
-endif.
812

913
-behaviour(gen_server).
1014

eqc/pulse/Emakefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{"../test/token", [{parse_transform, eqc_cover}]}.
2+
{"../test/handle_errors", [{d, 'PULSE'}, {parse_transform, eqc_cover}]}.
3+
{"../src/*", [{d, 'PULSE'}, {parse_transform, eqc_cover}, {i, ".."}, {i, "../include"}, {d, namespaced_types}]}.
4+
{"../eqc/pulse/*", [{d, 'PULSE'}, {parse_transform, eqc_cover}, {i, ".."}, {i, "../include"}]}.
5+
{"../eqc/event_logger", [{d, 'PULSE'}, {i, ".."}, {i, "../include"}]}.
6+

eqc/bitcask_pulse.erl renamed to eqc/pulse/bitcask_pulse.erl

Lines changed: 30 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,27 @@
77
%% The while module is ifdef:ed, rebar should set PULSE
88
-ifdef(PULSE).
99

10-
-compile(export_all).
10+
-compile([export_all, nowarn_export_all]).
1111

1212
-include_lib("eqc/include/eqc.hrl").
1313
-include_lib("eqc/include/eqc_statem.hrl").
1414

1515
-include("../include/bitcask.hrl").
1616

17-
-include_lib("eunit/include/eunit.hrl").
18-
1917
-compile({parse_transform, pulse_instrument}).
2018
-include_lib("pulse_otp/include/pulse_otp.hrl").
2119
%% The following functions contains side_effects but are run outside
2220
%% PULSE, i.e. PULSE needs to leave them alone
23-
-compile({pulse_skip,[{prop_pulse_test_, 0},
24-
{really_delete_bitcask, 0},
21+
-compile({pulse_skip,[{really_delete_bitcask, 0},
2522
{copy_bitcask_app, 0},
2623
{get_errors, 0}]}).
2724
-compile({pulse_no_side_effect,[{file,'_','_'}, {erlang, now, 0}]}).
2825

29-
%% The token module keeps track of the currently used directory for
30-
%% bitcask. Each test uses a fresh directory!
26+
%% Each test uses a fresh directory!
3127
-define(BITCASK, token:get_name()).
28+
%% -define(BITCASK, filename:join(?TEST_FILEPATH, "bitcask.qc." ++ os:getpid())).
29+
%% -define(BITCASK, "bitcask.qc." ++ os:getpid()).
30+
3231
%% Number of keys used in the tests
3332
-define(NUM_KEYS, 50).
3433
%% max_file_size given to bitcask.
@@ -310,7 +309,7 @@ run_on_node(slave, Verbose, M, F, A) ->
310309

311310
%% Muting the QuickCheck license printout from the slave node
312311
mute(true, Fun) -> Fun();
313-
mute(false, Fun) -> mute:run(Fun).
312+
mute(false, Fun) -> Fun(). % mute:run(Fun).
314313

315314
%%
316315
%% The actual code of the property, run on remote node via rpc:call above
@@ -320,15 +319,15 @@ run_commands_on_node(LocalOrSlave, Cmds, Seed, Verbose, KeepFiles) ->
320319
AfterTime = if LocalOrSlave == local -> 50000;
321320
LocalOrSlave == slave -> 1000000
322321
end,
323-
event_logger:start_link(),
324322
pulse:start(),
325323
error_logger:tty(false),
326324
error_logger:add_report_handler(handle_errors),
327325
token:next_name(),
328-
event_logger:start_logging(),
329326
X =
330327
try
331328
{H, S, Res, PidRs, Trace} = pulse:run(fun() ->
329+
event_logger:start_link(),
330+
event_logger:start_logging(),
332331
application_controller:start({application, kernel, []}),
333332
application:start(bitcask),
334333
bitcask_time:test__set_fudge(10),
@@ -341,6 +340,7 @@ run_commands_on_node(LocalOrSlave, Cmds, Seed, Verbose, KeepFiles) ->
341340
pulse:verbose(OldVerbose),
342341
Trace = event_logger:get_events(),
343342
receive after AfterTime -> ok end,
343+
application:stop(bitcask),
344344
unlink(whereis(pulse_application_controller)),
345345
exit(pulse_application_controller, shutdown),
346346
receive after AfterTime -> ok end,
@@ -363,6 +363,19 @@ run_commands_on_node(LocalOrSlave, Cmds, Seed, Verbose, KeepFiles) ->
363363
get_errors() ->
364364
gen_event:call(error_logger, handle_errors, get_errors, 60*1000).
365365

366+
run_tests(Args) ->
367+
try list_to_integer(atom_to_list(hd(Args))) of
368+
N ->
369+
case quickcheck(eqc:testing_time(N, prop_pulse())) of
370+
true -> erlang:halt();
371+
false -> erlang:halt(1)
372+
end
373+
catch _:_ ->
374+
io:format("Bad arguments: ~p\n", [Args]),
375+
timer:sleep(10),
376+
erlang:halt(2)
377+
end.
378+
366379
prop_pulse() ->
367380
prop_pulse(local, false, false).
368381

@@ -388,8 +401,10 @@ prop_pulse(LocalOrSlave, Verbose0, KeepFiles) ->
388401
io:format(user, "GOT ~p, aborting. Stop PULSE and restart!\n", [Bad]),
389402
exit({stopping, Bad});
390403
{H, S, Res, PidRs, Trace, Schedule, Errors0} ->
391-
Errors = [E || E <- Errors0,
392-
re:run(element(2, E), "Invalid merge input") == nomatch],
404+
Errors = [E || is_list(Errors0),
405+
E <- Errors0,
406+
re:run(element(2, E), "Invalid merge input") == nomatch] ++
407+
[Errors0 || not is_list(Errors0)],
393408
?WHENFAIL(
394409
?QC_FMT("\nState: ~p\n", [S]),
395410
aggregate(zipwith(fun command_data/2, tl(Cmds), H),
@@ -414,56 +429,6 @@ prop_pulse(LocalOrSlave, Verbose0, KeepFiles) ->
414429
end
415430
end)))))).
416431

417-
%% A EUnit wrapper for the QuickCheck property
418-
prop_pulse_test_() ->
419-
Timeout = case os:getenv("PULSE_TIME") of
420-
false -> 60;
421-
Val -> list_to_integer(Val)
422-
end,
423-
ExtraTO = case os:getenv("PULSE_SHRINK_TIME") of
424-
false -> 0;
425-
Val2 -> list_to_integer(Val2)
426-
end,
427-
%% eqc has the irritating behavior of not asking for a license for
428-
%% its entire test time at the start of the test. the following
429-
%% code calulates the amount of time remaining and then reserves
430-
%% the license until then, so long running tests won't fail
431-
%% because the license server becomes unreachable sometime in the
432-
%% middle of the test.
433-
{D, {H, M0, S}} = calendar:time_difference(calendar:local_time(),
434-
eqc:reserved_until()),
435-
%% any minutes or seconds at all and we should just bump up to the
436-
%% next hour
437-
M =
438-
case (M0 + S) of
439-
0 ->
440-
0;
441-
_N ->
442-
1
443-
end,
444-
HoursLeft = (D * 24) + H + M,
445-
HoursAsked = trunc((Timeout + ExtraTO)/60/60),
446-
case HoursLeft < HoursAsked of
447-
true -> eqc:reserve({HoursAsked, hours});
448-
false -> ok
449-
end,
450-
io:format(user, "prop_pulse_test time: ~p + ~p seconds\n",
451-
[Timeout, ExtraTO]),
452-
{timeout, (Timeout+ExtraTO+120), % 120 = a bit more fudge time
453-
fun() ->
454-
copy_bitcask_app(),
455-
?assert(eqc:quickcheck(eqc:testing_time(Timeout,
456-
?QC_OUT(prop_pulse()))))
457-
end}.
458-
459-
%% Needed since rebar fails miserably in setting up the .eunit test directory
460-
copy_bitcask_app() ->
461-
try
462-
{ok, B} = file:read_file("../ebin/bitcask.app"),
463-
ok = file:write_file("./bitcask.app", B)
464-
catch _:_ -> ok end,
465-
ok.
466-
467432
%% Using eqc_temporal to keep track of possible values for keys.
468433
%%
469434
%% The Trace contains entries for start and finish of operations. For
@@ -1127,7 +1092,9 @@ really_delete_bitcask() ->
11271092
[file:delete(X) || X <- filelib:wildcard(?BITCASK ++ "/*")],
11281093
file:del_dir(?BITCASK),
11291094
case file:read_file_info(?BITCASK) of
1130-
{error, enoent} -> ok;
1095+
{error, enoent} ->
1096+
timer:sleep(10),
1097+
ok;
11311098
{ok, _} ->
11321099
timer:sleep(10),
11331100
really_delete_bitcask()

0 commit comments

Comments
 (0)