Ensuring a process is crashed with raise/3 in a Common_Test case

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Ensuring a process is crashed with raise/3 in a Common_Test case

Jared Davison
Hi,

Could you please assist me in using common test.

I'm trying to ensure that a gen_statem:call/3 raises a {timeout, _} in a common test case.

At first I tried a catch because I thought it would be a throw but it catches nothing. 

Digging into the gen_statem:call/3 code it appears that it uses erlang:raise/3 which stops the execution of the process, so that makes sense that catch does nothing.

I want to be sure that the process was stopped with the a particular reason, and pass the test if it does. 

Is this possible in Common Test?

Thanks

Jared



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Ensuring a process is crashed with raise/3 in a Common_Test case

Edmond Begumisa
On Wed, 15 Aug 2018 14:17:40 +1000, Jared Davison  
<[hidden email]> wrote:

> Hi,
>
> Could you please assist me in using common test.
>
> I'm trying to ensure that a gen_statem:call/3 raises a {timeout, _} in a  
> common test case.
>
> At first I tried a catch because I thought it would be a throw but it  
> catches nothing.

Sounds like you're catching the wrong exception class. For gen_* timeouts,  
I believe the exception class is 'exit' rather than 'throw'.


> Digging into the gen_statem:call/3 code it appears that it uses  
> erlang:raise/3 which stops the >execution of the process, so that makes  
> sense that catch does nothing.

Catch should do something if you're catching the right exception class  
('exit') or matching any exception class ('_'). It is still possible to  
catch exceptions generated using erlang:raise/3 for any class  
('error'|'throw'|'exit'). E.g from an erlang shell ...

     $ try erlang:raise(exit, foo, []) catch exit:foo -> yep end.
     
... returns 'yep'. As do...

     $ try erlang:raise(throw, foo, []) catch throw:foo -> yep end.
     $ try erlang:raise(error, foo, []) catch error:foo -> yep end.

... so do...

     $ try exit(foo) catch exit:foo -> yep end.
     $ try throw(foo) catch throw:foo -> yep end.
     $ try error(foo) catch error:foo -> yep end.

... and also ...

     $ try erlang:raise(exit, foo, []) catch _:foo -> yep end.
     $ try erlang:raise(error, foo, []) catch _:foo -> yep end.
     $ try erlang:raise(throw, foo, []) catch _:foo -> yep end.
     $ try exit(foo) catch _:foo -> yep end.
     $ try throw(foo) catch _:foo -> yep end.
     $ try error(foo) catch _:foo -> yep end.

> I want to be sure that the process was stopped with the a particular  
> reason, and pass the test if >it does.
> Is this possible in Common Test?

Should be. My guess is that your test case is catching something like so...

     <snip>

     try gen_statem:call(foo, bar, 5000)
     catch throw:{timeout,_} -> ..
     end.

     </snip>

Try changing that to...

     <snip>

     try gen_statem:call(foo, bar, 5000)
     catch exit:{timeout,_} -> ..
     end.

     </snip>

- Edmond -

>
> Thanks
>
> Jared
>
>
>



--
Using Opera's mail client: http://www.opera.com/mail/
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Ensuring a process is crashed with raise/3 in a Common_Test case

Jared Davison
Hi Edmond,

Thanks for your reply, it was very helpful.

I had something like:

    ?assertMatch({timeout,_}, 
        try
            gen_statem:call(foo, bar, 5000),
            timeout_was_not_thrown
        catch
            A -> A
        end).

Adding the exit class as you have suggested in the catch pattern match seems to do the trick:

    ?assertMatch({timeout,_}, 
        try
            gen_statem:call(foo, bar, 5000),
            timeout_was_not_thrown
        catch
            exit:A -> A
        end).

Thanks again.

Jared

On Wed, Aug 15, 2018 at 10:40 PM, Edmond Begumisa <[hidden email]> wrote:
On Wed, 15 Aug 2018 14:17:40 +1000, Jared Davison <[hidden email]> wrote:

Hi,

Could you please assist me in using common test.

I'm trying to ensure that a gen_statem:call/3 raises a {timeout, _} in a common test case.

At first I tried a catch because I thought it would be a throw but it catches nothing.

Sounds like you're catching the wrong exception class. For gen_* timeouts, I believe the exception class is 'exit' rather than 'throw'.


Digging into the gen_statem:call/3 code it appears that it uses erlang:raise/3 which stops the >execution of the process, so that makes sense that catch does nothing.

Catch should do something if you're catching the right exception class ('exit') or matching any exception class ('_'). It is still possible to catch exceptions generated using erlang:raise/3 for any class ('error'|'throw'|'exit'). E.g from an erlang shell ...

    $ try erlang:raise(exit, foo, []) catch exit:foo -> yep end.
       
... returns 'yep'. As do...

    $ try erlang:raise(throw, foo, []) catch throw:foo -> yep end.
    $ try erlang:raise(error, foo, []) catch error:foo -> yep end.

... so do...

    $ try exit(foo) catch exit:foo -> yep end.
    $ try throw(foo) catch throw:foo -> yep end.
    $ try error(foo) catch error:foo -> yep end.

... and also ...

    $ try erlang:raise(exit, foo, []) catch _:foo -> yep end.
    $ try erlang:raise(error, foo, []) catch _:foo -> yep end.
    $ try erlang:raise(throw, foo, []) catch _:foo -> yep end.
    $ try exit(foo) catch _:foo -> yep end.
    $ try throw(foo) catch _:foo -> yep end.
    $ try error(foo) catch _:foo -> yep end.

I want to be sure that the process was stopped with the a particular reason, and pass the test if >it does.
Is this possible in Common Test?

Should be. My guess is that your test case is catching something like so...

    <snip>

    try gen_statem:call(foo, bar, 5000)
    catch throw:{timeout,_} -> ..
    end.

    </snip>

Try changing that to...

    <snip>

    try gen_statem:call(foo, bar, 5000)
    catch exit:{timeout,_} -> ..
    end.

    </snip>

- Edmond -


Thanks

Jared






--
Using Opera's mail client: http://www.opera.com/mail/


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions