[erlang-questions] PropEr after test clean up

Hynek Vychodil vychodil.hynek@REDACTED
Tue May 26 00:10:51 CEST 2015


Hi Robert,

I have used proper_statem and it has the same issue. You are not able to
make reliable clean up because there is zero support for it. Statefullness
has nothing with it. If there would be some hook or even if it does not run
all in one process. For example, property fragment from my
proper_statem module:

prop_xad_cpu() ->
    ?FORALL(Cmds, commands(?MODULE),
            ?TRAPEXIT(
            begin
                {ok, Pid1} = xad_cpu:start_link(),
                {ok, Pid2} = ?MODULE:start_link(),
                Mrefs = [monitor(process, X) || X <- [Pid1, Pid2]],
                Free = get_schedulers(),
                {History, State, Result} = run_commands(?MODULE, Cmds),
                Msgs = collect_messages(collect_processes(History)),
                timer:sleep(1),
                Free2 = get_schedulers(),
                xad_cpu:stop(),
                [receive {'DOWN', X, process, _, _} -> ok end || X <-
Mrefs],
                ?WHENFAIL(
                    io:format(
                        "History: ~p\nState: ~w\nResult: ~w\nMessages: ~w\n"
                        "Free: ~p =?= ~p~n",
                        [pp_history(Cmds, History), pp_state(State), Result,
                         Msgs, Free, Free2]),
                          aggregate(command_names(Cmds), Result =:= ok
                                    andalso Free =:= Free2))
            end
            )).

You can see, you have to make do all cleanup inside property but explicitly
before test() type itself as ?WHENFAIL in this case. It is defacto same
solution as I have used in
https://github.com/pichi/erlgt/commit/d470433dfb8859eaa05381eeba74511a2ff4f6e5
It doesn't allow me make any abstraction when writing property. See how I
had to move ?FORALL outside of ?WITH_G macro. If you would be able to make
something like proper:add_cleanup(fun()->ok) or if each test will run in
separate process, ets would clean up itself. It is erlang idiom: make
process and catch its exit.

On Mon, May 25, 2015 at 11:27 PM, Robert Raschke <rtrlists@REDACTED>
wrote:

> Hello Hynek,
>
> since you are testing something that has state, I think you probably need
> to look into the state based testing approach that is possible with PropEr.
> It's been a while since I looked into that, so I don't have a handy link at
> hand, sorry :-(
>
> Hope this helps a bit,
> Robby
> On May 25, 2015 4:11 PM, "Hynek Vychodil" <vychodil.hynek@REDACTED>
> wrote:
>
>> Hi,
>>
>> I bumped in the problem how clean up after property in PropEr. Let's have
>> simple property where I make ets table:
>>
>> prop_ets() ->
>>     ?FORALL(V, integer(),
>>         begin
>>             E = ets:new(),
>>             true = ets:insert(T, {V, ok}),
>>             equals([{V, ok}], ets:lookup(T, V))
>>         end
>>     ).
>>
>> How am I supposed to delete ets table? It is trickier than looks like.
>> The problem is when I want use another ?FORALL inside my property. The
>> conjunction/1 is the same problem. You can`t write
>>
>> prop_ets() ->
>>     ?FORALL(V, integer(),
>>         begin
>>             E = ets:new(),
>>             true = ets:insert(T, {V, ok}),
>>             Res = conjunction([{lookup, equals([{V, ok}], ets:lookup(T,
>> V))},
>>                               {lookup_element,
>> equals(ok, ets:lookup_element(T, V, 2))}]),
>>             ets:delete(T),
>>             Res
>>         end
>>     ).
>>
>> Because Res is test(). In this case, you can make calls to
>> the ets:lookup/2 and the ets:lookup_element/3 before conjunction/1 but it
>> doesn't solve properties like
>>
>> ?FORALL(L, list(...),
>>     begin
>>         T = ets:new(),
>>         ...
>>         ?FORALL(V, oneof(L),
>>               ...
>>         )
>>      end
>> )
>>
>> The solution would be simple is every test case would be run in a
>> separate process, but it is not! It is very unusual in Erlang word to make
>> such thing. Processes are cheap and I can they are in a defined state each
>> run for free. Why is it all running in the same process?
>>
>> Has anybody solved this problem somehouw?
>>
>> Hynek Vychodil
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150526/0e979429/attachment.htm>


More information about the erlang-questions mailing list