<div dir="ltr">Hi Robert,<div><br></div><div>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:</div><div><br></div><div><div>prop_xad_cpu() -></div><div>    ?FORALL(Cmds, commands(?MODULE),</div><div>            ?TRAPEXIT(</div><div>            begin</div><div>                {ok, Pid1} = xad_cpu:start_link(),</div><div>                {ok, Pid2} = ?MODULE:start_link(),</div><div>                Mrefs = [monitor(process, X) || X <- [Pid1, Pid2]],</div><div>                Free = get_schedulers(),</div><div>                {History, State, Result} = run_commands(?MODULE, Cmds),</div><div>                Msgs = collect_messages(collect_processes(History)),</div><div>                timer:sleep(1),</div><div>                Free2 = get_schedulers(),</div><div>                xad_cpu:stop(),</div><div>                [receive {'DOWN', X, process, _, _} -> ok end || X <- Mrefs],</div><div>                ?WHENFAIL(</div><div>                    io:format(</div><div>                        "History: ~p\nState: ~w\nResult: ~w\nMessages: ~w\n"</div><div>                        "Free: ~p =?= ~p~n",</div><div>                        [pp_history(Cmds, History), pp_state(State), Result,</div><div>                         Msgs, Free, Free2]),</div><div>                          aggregate(command_names(Cmds), Result =:= ok</div><div>                                    andalso Free =:= Free2))</div><div>            end</div><div>            )).</div></div><div><br></div><div>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 <a href="https://github.com/pichi/erlgt/commit/d470433dfb8859eaa05381eeba74511a2ff4f6e5">https://github.com/pichi/erlgt/commit/d470433dfb8859eaa05381eeba74511a2ff4f6e5</a></div><div>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.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 25, 2015 at 11:27 PM, Robert Raschke <span dir="ltr"><<a href="mailto:rtrlists@googlemail.com" target="_blank">rtrlists@googlemail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p>Hello Hynek,</p>
<p>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 :-(</p>
<p>Hope this helps a bit,<br>
Robby</p>
<div class="gmail_quote"><div><div class="h5">On May 25, 2015 4:11 PM, "Hynek Vychodil" <<a href="mailto:vychodil.hynek@gmail.com" target="_blank">vychodil.hynek@gmail.com</a>> wrote:<br type="attribution"></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr">Hi,<div><br></div><div>I bumped in the problem how clean up after property in PropEr. Let's have simple property where I make ets table:</div><div><br></div><div>prop_ets() -></div><div>    ?FORALL(V, integer(),</div><div>        begin</div><div>            E = ets:new(),</div><div>            true = ets:insert(T, {V, ok}),</div><div>            equals([{V, ok}], ets:lookup(T, V))</div><div>        end</div><div>    ).</div><div><br></div><div>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</div><div><br></div><div><div>prop_ets() -></div><div>    ?FORALL(V, integer(),</div><div>        begin</div><div>            E = ets:new(),</div><div>            true = ets:insert(T, {V, ok}),</div><div>            Res = conjunction([{lookup, equals([{V, ok}], ets:lookup(T, V))},</div><div>                              {lookup_element, equals(ok, ets:lookup_element(T, V, 2))}]),</div><div>            ets:delete(T),</div><div>            Res</div><div>        end</div><div>    ).</div></div><div><br></div><div>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</div><div><br></div><div>?FORALL(L, list(...),</div><div>    begin</div><div>        T = ets:new(),</div><div>        ...</div><div>        ?FORALL(V, oneof(L),</div><div>              ...</div><div>        )</div><div>     end</div><div>)</div><div><br></div><div>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?</div><div><br></div><div>Has anybody solved this problem somehouw?</div><div><br></div><div>Hynek Vychodil</div></div>
<br></div></div><span class="">_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></span></blockquote></div>
</blockquote></div><br></div>