async+ounit or similar?

82 views
Skip to first unread message

Anil Madhavapeddy

unread,
Mar 26, 2014, 4:22:51 PM3/26/14
to ocaml...@googlegroups.com
I have this little TODO in the cohttp/async test cases:

let test_cases =
(* TODO: can multiple async tests run with separate Schedulers? Is there
* an Async-aware oUnit instead? *)
let _ = Scheduler.within' (
fun () ->
Monitor.try_with ( fun () ->
make_net_req ()
>>= make_net_post_req
>>= make_net_ssl_req
) >>=
function
|Error exn ->
Printf.fprintf stderr "err %s.\n%!" (Exn.to_string exn);
return ()
|Ok _ ->
Shutdown.exit 0
) in
Scheduler.go ()

Is there a better way to write these sort of Async tests available (in the style of Async.Std.Command)?

-anil

Sylvain Le Gall

unread,
Mar 26, 2014, 7:19:12 PM3/26/14
to ocaml...@googlegroups.com
I am not super familiar with Async and Scheduler, so excuse me if I am off-topic.

I suppose the Async Scheduler is a kind of singleton and you can run only a single test at once.

Basically what you have to do is, with OUnit2:

let scheduler_mutex = OUnitShared.Mutex.create OUnitShared.ScopeProcess

let test_with_scheduler name f = 
   name >::
   (fun test_ctxt ->
       OUnitShared.Mutex.with_lock test_ctxt.shared scheduler_mutex
          (fun () -> f test_ctxt))

and then you can use it safely. I suppose you will have to replace f with Scheduler + Monitor + Error catching and re-raise the exception generated to make it really safe.

When running in multiple processes, there will be multiple running scheduler in different processes.

Regards
Sylvain
       



-anil

--
You received this message because you are subscribed to the Google Groups "ocaml-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ocaml-core+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Stephen Weeks

unread,
Mar 26, 2014, 10:18:24 PM3/26/14
to ocaml...@googlegroups.com
> Is there a better way to write these sort of Async tests available
> (in the style of Async.Std.Command)?

An idiom that I've seen used a fair amount is:

TEST_UNIT =
Thread_safe.block_on_async_exn (fun () ->
... test stuff here ...)
;;

> I suppose the Async Scheduler is a kind of singleton and you can run
> only a single test at once.

Yeah, there is at most one Async scheduler per process.


The idiom above runs all tests in sequence in the same process, using
the same scheduler.

Yaron Minsky

unread,
Mar 26, 2014, 10:38:45 PM3/26/14
to ocaml...@googlegroups.com
There are really two suggestions here: one of which is to use
Thread_safe.block_on_async_exn, and the other is to use pa_test, which
I heartily recommend. Set up right, pa_test drives down the overhead
of adding a unit test to your system very low indeed. It's as simple
as just writing

TEST = (* some expression that returns true on success *)

or

TEST_UNIT = (* some expression that raises on error *)

or even

TEST_MODULE = struct (* some module containing tests that should
only execute when running unit tests *)

Writing unit tests is no fun, and dropping the overhead for doing so
to zero is quite helpful in getting people to actually write tests!

y

and...@subsis.com

unread,
Mar 27, 2014, 4:25:26 AM3/27/14
to ocaml...@googlegroups.com
I've been experimenting with an Async.Std.Command-inspired style of writing tests for async code. Here's a sample: https://gist.github.com/andreas/9802796 . The tests are run sequentially in the same scheduler. I'm not familiar with pa_test, it may solve the problem better.

Ben Millwood

unread,
Mar 27, 2014, 4:08:57 AM3/27/14
to ocaml...@googlegroups.com
On 27 March 2014 02:38, Yaron Minsky <ymi...@janestreet.com> wrote:
There are really two suggestions here: one of which is to use
Thread_safe.block_on_async_exn, and the other is to use pa_test, which
I heartily recommend.  Set up right, pa_test drives down the overhead
of adding a unit test to your system very low indeed.  It's as simple
as just writing

    TEST = (* some expression that returns true on success *)

or

    TEST_UNIT = (* some expression that raises on error *)

or even

   TEST_MODULE = struct (* some module containing tests that should
                           only execute when running unit tests *)

To be pedantic, TEST and TEST_UNIT are actually provided by pa_ounit. pa_test provides macro expanders <:test_eq< t >>, <:test_pred< t >>, <:test_result< t >> designed to make more informative error messages by using sexp converters to tell you what value failed your test. They're good too!

Writing unit tests is no fun, and dropping the overhead for doing so
to zero is quite helpful in getting people to actually write tests!

To be pedantic, writing unit tests is actually super fun and everyone should do it all the time.

Stephen Weeks

unread,
Mar 27, 2014, 7:31:57 AM3/27/14
to ocaml...@googlegroups.com
> To be pedantic, writing unit tests is actually super fun and
> everyone should do it all the time.

Personally, my enjoyment of writing unit tests improved immensely when
I switched from (mostly) writing explicit cases that pass to (mostly)
writing small programs that explore the input space to find cases that
might fail.

Rudi Grinberg

unread,
Apr 5, 2014, 9:18:34 PM4/5/14
to ocaml...@googlegroups.com
That looks useful. How do you actually run these tests though?

On Wed, 26 Mar 2014 22:38:45 -0400, Yaron Minsky <ymi...@janestreet.com>
wrote:

Jeremie Dimino

unread,
Apr 7, 2014, 11:08:06 AM4/7/14
to ocaml...@googlegroups.com
Hi Rudi,

All these tests are always included but are not run by default. To run them you have to pass `inline-test-runner` as first argument of any program using pa_ounit or linked with a library using pa_ounit. 

You can also use `Pa_ounit_lib.Runtime.summarize ()` to get a report after running the tests. So for instance, to run core tests:

    echo 'Pa_ounit_lib.Runtime.summarize ()' > test.ml
    ocamlfind ocamlopt -o test -linkall -linkpkg -package core -thread test.ml
   ./test inline-test-runner core -log -display

This is explained in the readme of pa_ounit:



To unsubscribe from this group and stop receiving emails from it, send an email to ocaml-core+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "ocaml-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ocaml-core+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Jeremie
Reply all
Reply to author
Forward
0 new messages