GNOME Bugzilla – Bug 508394
g_test with mainloop integration and async signals
Last modified: 2018-05-24 11:11:23 UTC
This is a followup on a thread on gtk-devel: http://mail.gnome.org/archives/gtk-devel-list/2008-January/msg00009.html I often find it necessary to create tests that deal with asynchronous libraries. I suspect that I am not the only one (X, gio, libwnck, libbeagle, libdbus-glib, ad nauseum all use async communications in some way). It would be great to make this easy peasy to do with the g_test utilities. I attach a patch based on Scott Asofyet's work integrating two new concepts to the gtestutils family: 1) g_test_add_with_main_loop() in gtestutils.h: similar to g_test_add but runs fixture_test() as an idle handler in a GMainLoop. 2) g_object_test_wait_for_signal() in the gobject module : runs a mainloop until a specific signal is emitted on an object or until a timeout is reached. It will give back signal arguments as well. This makes it easy to support the following workflow: setup(): bla bla test(): send request, block for response, validate resp. Rinse repeat ad lib. teardown() alb alb
Created attachment 102494 [details] [review] patch against rev 6225 DISCLAIMER: This patch was cooked in a flu-induced haze.
i have to admit that i still find it hard to see the general usefullness in your main loop test cases. since g_object_test_wait_for_signal() opens up its own recursive main loop anyway, isn't that good enough if you want to wait for a signal being emitted while the main loop is running and don't need g_test_add_with_main_loop() that way? perhaps this will help, can you provide 2 real world test cases, one around g_object_test_wait_for_signal and one around g_test_add_with_main_loop, so i can get a better idea of the use cases you're trying to cover? and also to get a chance to understand if the suggested API is the best to solve your usage cases, or if alternatives are available (such as your test functions simply calling g_main_loop_run() themselves).
(In reply to comment #2) > i have to admit that i still find it hard to see the general usefulness in > your main loop test cases Some tests that extensively depend on main loops can be found here: http://svn.gnome.org/viewvc/libepc/trunk/tests/ Maybe instead of Mikkel's very specialized functions, something in the spirit of the functions found in that folder's framework.[ch] files should be implemented: - epc_test_init(): set's up an array of conditions that have to be meet (technically a bitmask here, but that's an implementation detail) - epc_test_run(): spins a main loop, until all conditions are meet, or until a timeout is reached - epc_test_pass_many(), epc_test_pass_once(): mark conditions as meet - epc_test_quit(): provides a quick exit from the test loop To convenintly test signals another function could be added, that connects a signal handler to some object. This signal handler would call epc_test_pass_many() or epc_test_pass_once() with the specified conditions.
From comment 2 : > i have to admit that i still find it hard to see the general usefullness in > your main loop test cases. since g_object_test_wait_for_signal() opens up its > own recursive main loop anyway, isn't that good enough if you want to wait for > a signal being emitted while the main loop is running and don't need > g_test_add_with_main_loop() that way? There are also async libs that use callbacks instead of signals... Fx dbus-glib. I'll attach a commented sample in a sec. While I could certainly call g_main_loop_run myself, it would require me to specify a few callbacks as well (at least for exiting the loop). In the case I am attaching I would need to create custom teardown methods to be run inside the main loop.
Created attachment 102636 [details] A small test that could be made smarter with mainloop integration This test would actually make best use of a mainloop in the teardown function... My patch does not provide that atm.
Just for the record. The wait_for_signal functionality is by far the most useful to me... I will probably survive if mainloop integration is not included. Without mainloop integration I will have to add some boilerplate code to all my tests though, and I really think that is a bad idea. Unit tests should be simple and expressive above all else IMHO.
(In reply to comment #6) > Without mainloop integration I will have to add some boilerplate code to all my > tests though, and I really think that is a bad idea. Unit tests should be > simple and expressive above all else IMHO. > Well, without mainloop integration you still can put your integration functions into some separate source file and link all test cases with that file. Same way as I did with framework.[ch] in libepc - so world will not vanish, if such functions aren't added. Nevertheless I consider addition of this kind of functions essential, since signals, GSources, GMainloop are essential for GNOME libraries and applications. Especially for libraries test for of features is important.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/118.