30 #include <unittest-support.h>
37 #include "../qofbackend-p.h"
38 #include "../qofsession-p.h"
39 #include "../qofclass-p.h"
41 static const gchar *suitename =
"/qof/qofsession";
42 void test_suite_qofsession (
void );
49 extern GHookList* get_session_closed_hooks (
void);
50 extern GSList* get_provider_list (
void);
51 extern gboolean get_qof_providers_initialized (
void);
52 extern void unregister_all_providers (
void);
54 extern void (*p_qof_session_load_backend) (
QofSession * session,
const char * access_method);
55 extern void (*p_qof_session_clear_error) (
QofSession * session);
56 extern void (*p_qof_session_destroy_backend) (
QofSession * session);
58 extern void init_static_qofsession_pointers (
void);
77 percentage_fn (
const char* message,
double percent )
79 g_print(
"%s %f complete", message, percent );
83 setup(
Fixture *fixture, gconstpointer pData )
85 fixture->session = qof_session_new();
86 init_static_qofsession_pointers ();
87 g_assert (p_qof_session_clear_error && p_qof_session_destroy_backend && p_qof_session_load_backend);
91 teardown(
Fixture *fixture, gconstpointer pData )
93 qof_session_destroy( fixture->session );
94 p_qof_session_clear_error = NULL;
95 p_qof_session_destroy_backend = NULL;
96 p_qof_session_load_backend = NULL;
100 test_qof_session_new_destroy (
void)
105 g_test_message (
"Test session initialization");
106 session = qof_session_new ();
108 g_assert_cmpstr (session->entity.
e_type, == , QOF_ID_SESSION);
109 g_assert (session->book);
110 book = (
QofBook*) session->book;
112 g_assert (QOF_IS_BOOK (book));
113 g_assert (!session->book_id);
114 g_assert (!session->backend);
115 g_assert_cmpint (session->lock, == , 1);
118 g_test_message (
"Test session destroy");
119 qof_session_destroy (session);
126 test_session_safe_save(
Fixture *fixture, gconstpointer pData )
128 fixture->session->backend = g_new0 (
QofBackend, 1);
129 fixture->session->backend->safe_sync = safe_sync;
133 g_assert( NULL == qof_session_get_url( fixture->session ));
139 gboolean data_compatible;
140 gboolean check_data_type_called;
141 gboolean backend_new_called;
142 } load_backend_struct;
145 mock_check_data_type (
const char* book_id)
148 g_assert_cmpstr (book_id, == ,
"my book");
149 load_backend_struct.check_data_type_called = TRUE;
150 return load_backend_struct.data_compatible;
154 mock_backend_new (
void)
160 load_backend_struct.be = be;
161 load_backend_struct.backend_new_called = TRUE;
166 test_qof_session_load_backend (
Fixture *fixture, gconstpointer pData)
174 g_test_message (
"Test when no provider is registered");
175 g_assert (!get_qof_providers_initialized ());
176 g_assert (get_provider_list () == NULL);
177 p_qof_session_load_backend (fixture->session,
"file");
178 g_assert (get_qof_providers_initialized ());
180 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load 'file' using access_method");
181 p_qof_session_clear_error (fixture->session);
183 g_test_message (
"Test with provider registered but access method not supported");
186 g_assert (get_provider_list ());
187 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 1);
188 p_qof_session_load_backend (fixture->session,
"file");
190 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load 'file' using access_method");
191 p_qof_session_clear_error (fixture->session);
193 g_test_message (
"Test with access method supported but type incompatible");
196 load_backend_struct.data_compatible = FALSE;
197 load_backend_struct.check_data_type_called = FALSE;
198 fixture->session->book_id = g_strdup (
"my book");
199 p_qof_session_load_backend (fixture->session,
"file");
200 g_assert (load_backend_struct.check_data_type_called);
202 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load 'file' using access_method");
203 p_qof_session_clear_error (fixture->session);
205 g_test_message (
"Test with type compatible but backend_new not set");
207 load_backend_struct.data_compatible = TRUE;
208 load_backend_struct.check_data_type_called = FALSE;
209 p_qof_session_load_backend (fixture->session,
"file");
210 g_assert (load_backend_struct.check_data_type_called);
212 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load 'file' using access_method");
213 p_qof_session_clear_error (fixture->session);
215 g_test_message (
"Test with type compatible backend_new set");
217 load_backend_struct.be = NULL;
218 load_backend_struct.data_compatible = TRUE;
219 load_backend_struct.check_data_type_called = FALSE;
220 load_backend_struct.backend_new_called = FALSE;
221 g_assert (fixture->session->backend == NULL);
225 p_qof_session_load_backend (fixture->session,
"file");
226 g_assert (load_backend_struct.check_data_type_called);
227 g_assert (load_backend_struct.backend_new_called);
228 g_assert (load_backend_struct.be);
229 g_assert (load_backend_struct.be == fixture->session->backend);
230 g_assert (prov == fixture->session->backend->provider);
234 unregister_all_providers ();
235 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 0);
243 gboolean load_called;
244 } load_session_struct;
251 g_assert (be == load_session_struct.be);
252 g_assert (book != load_session_struct.oldbook);
254 if (load_session_struct.error)
256 load_session_struct.load_called = TRUE;
260 test_qof_session_load (
Fixture *fixture, gconstpointer pData)
269 fixture->session->book_id = g_strdup (
"my book");
272 fixture->session->backend = be;
273 be->load = mock_load;
275 g_test_message (
"Test when no error is produced");
276 g_assert (be->percentage == NULL);
277 load_session_struct.be = be;
279 g_assert (fixture->session->book);
280 load_session_struct.error = FALSE;
281 load_session_struct.load_called = FALSE;
282 qof_session_load (fixture->session, percentage_fn);
285 g_assert (load_session_struct.oldbook != newbook);
286 g_assert (fixture->session->book);
287 g_assert (load_session_struct.load_called);
289 g_test_message (
"Test when no is produced");
291 g_assert (fixture->session->book);
292 load_session_struct.error = TRUE;
293 load_session_struct.load_called = FALSE;
294 qof_session_load (fixture->session, percentage_fn);
297 g_assert (load_session_struct.oldbook == newbook);
298 g_assert (fixture->session->book);
299 g_assert (load_session_struct.load_called);
307 gboolean backend_new_called;
308 gboolean session_begin_called;
309 gboolean produce_error;
310 } session_begin_struct;
314 gboolean ignore_lock, gboolean create, gboolean force)
317 g_assert (be == session_begin_struct.be);
319 g_assert (session == session_begin_struct.session);
321 g_assert_cmpstr (book_id, == , session_begin_struct.book_id);
322 g_assert (ignore_lock);
325 if (session_begin_struct.produce_error)
330 session_begin_struct.session_begin_called = TRUE;
334 mock_backend_new_for_begin (
void)
340 be->session_begin = mock_session_begin;
341 session_begin_struct.be = be;
342 session_begin_struct.backend_new_called = TRUE;
347 test_qof_session_begin (
Fixture *fixture, gconstpointer pData)
349 gboolean ignore_lock, create, force;
360 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 0);
365 g_test_message (
"Test when book_id is set backend is not changed");
366 fixture->session->backend = be;
367 fixture->session->book_id = g_strdup (
"my book");
369 g_assert (fixture->session->backend == be);
371 g_test_message (
"Test when session book_id is not set and book_id passed is null backend is not changed");
372 g_free (fixture->session->book_id);
373 fixture->session->book_id = NULL;
375 g_assert (fixture->session->backend == be);
377 g_test_message (
"Test default access_method parsing");
382 qof_session_begin (fixture->session,
"default_should_be_file", ignore_lock, create, force);
383 g_assert (fixture->session->backend == NULL);
384 g_assert (fixture->session->book_id == NULL);
386 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load 'file' using access_method");
388 g_test_message (
"Test access_method parsing");
389 qof_session_begin (fixture->session,
"postgres://localhost:8080", ignore_lock, create, force);
390 g_assert (fixture->session->backend == NULL);
391 g_assert (fixture->session->book_id == NULL);
393 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load 'postgres' using access_method");
395 g_test_message (
"Test with valid backend returned and session begin set; error is produced");
396 session_begin_struct.session = fixture->session;
397 session_begin_struct.book_id =
"postgres://localhost:8080";
398 session_begin_struct.backend_new_called = FALSE;
399 session_begin_struct.session_begin_called = FALSE;
400 session_begin_struct.produce_error = TRUE;
403 qof_session_begin (fixture->session,
"postgres://localhost:8080", ignore_lock, create, force);
404 g_assert (fixture->session->backend);
405 g_assert (session_begin_struct.be == fixture->session->backend);
406 g_assert (session_begin_struct.backend_new_called == TRUE);
407 g_assert (session_begin_struct.session_begin_called == TRUE);
408 g_assert (fixture->session->book_id == NULL);
410 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"push any error");
412 g_test_message (
"Test normal session_begin execution");
413 session_begin_struct.backend_new_called = FALSE;
414 session_begin_struct.session_begin_called = FALSE;
415 session_begin_struct.produce_error = FALSE;
416 qof_session_begin (fixture->session,
"postgres://localhost:8080", ignore_lock, create, force);
417 g_assert (fixture->session->backend);
418 g_assert (session_begin_struct.be == fixture->session->backend);
419 g_assert (session_begin_struct.backend_new_called == TRUE);
420 g_assert (session_begin_struct.session_begin_called == TRUE);
421 g_assert (fixture->session->book_id);
422 g_assert_cmpstr (fixture->session->book_id, == ,
"postgres://localhost:8080");
425 unregister_all_providers ();
434 gboolean sync_called;
435 gboolean backend_new_called;
436 gboolean session_begin_called;
437 } session_save_struct;
444 g_assert (be == session_save_struct.be);
445 g_assert (book == session_save_struct.book);
446 session_save_struct.sync_called = TRUE;
450 test_qof_session_save (
Fixture *fixture, gconstpointer pData)
456 g_test_message (
"Test when backend not set");
457 g_assert (fixture->session->backend == NULL);
461 g_assert_cmpint (fixture->session->lock, == , 1);
464 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"failed to load backend");
465 g_assert_cmpint (fixture->session->lock, == , 1);
467 g_test_message (
"Test when backend set; imitate error");
470 be->sync = mock_sync;
471 fixture->session->backend = be;
472 g_assert_cmpint (fixture->session->lock, == , 1);
473 session_save_struct.sync_called = FALSE;
474 session_save_struct.be = be;
475 session_save_struct.book = book;
480 g_assert (be->percentage == percentage_fn);
481 g_assert (session_save_struct.sync_called);
482 g_assert_cmpint (fixture->session->lock, == , 1);
484 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"");
486 g_test_message (
"Test when backend set; successful save");
487 g_assert_cmpint (fixture->session->lock, == , 1);
488 session_save_struct.sync_called = FALSE;
491 g_assert (be->percentage == percentage_fn);
492 g_assert (session_save_struct.sync_called);
493 g_assert_cmpint (fixture->session->lock, == , 1);
501 unregister_all_providers ();
509 } destroy_backend_struct;
515 g_assert (destroy_backend_struct.be == be);
516 destroy_backend_struct.called = TRUE;
520 test_qof_session_destroy_backend (
Fixture *fixture, gconstpointer pData)
524 g_test_message (
"Test with destroy backend callback not set");
527 fixture->session->backend = be;
528 p_qof_session_destroy_backend (fixture->session);
529 g_assert (!fixture->session->backend);
531 g_test_message (
"Test with destroy backend callback set");
534 be->destroy_backend = mock_destroy_backend;
535 fixture->session->backend = be;
536 destroy_backend_struct.called = FALSE;
537 destroy_backend_struct.be = be;
538 p_qof_session_destroy_backend (fixture->session);
539 g_assert (!fixture->session->backend);
540 g_assert (destroy_backend_struct.called);
547 } session_end_struct;
553 g_assert (session_end_struct.be == be);
554 session_end_struct.called = TRUE;
558 test_qof_session_end (
Fixture *fixture, gconstpointer pData)
562 g_test_message (
"Test backend is closed, errors cleared and book_id removed");
565 be->session_end = mock_session_end;
566 fixture->session->backend = be;
568 fixture->session->book_id = g_strdup (
"my book");
569 session_end_struct.called = FALSE;
570 session_end_struct.be = be;
572 g_assert (session_end_struct.called);
574 g_assert (!fixture->session->book_id);
582 } session_export_struct;
588 g_assert (session_export_struct.be == be);
590 g_assert (session_export_struct.book == book);
591 session_export_struct.called = TRUE;
595 test_qof_session_export (
Fixture *fixture, gconstpointer pData)
598 QofBook *tmp_book = NULL, *real_book = NULL;
601 real_session = qof_session_new ();
602 g_assert (real_session);
604 g_test_message (
"Test null checks");
605 g_assert (!qof_session_export (NULL, real_session, percentage_fn));
606 g_assert (!qof_session_export (fixture->session, NULL, percentage_fn));
608 g_test_message (
"Test with backend not set");
613 g_assert (!qof_session_export (fixture->session, real_session, percentage_fn));
615 g_test_message (
"Test with backend set");
618 fixture->session->backend = be;
619 qof_book_set_backend (tmp_book, be);
620 g_assert (!be->percentage);
621 g_assert (qof_session_export (fixture->session, real_session, percentage_fn));
622 g_assert (be->percentage == percentage_fn);
624 g_test_message (
"Test with backend export function set and error is produced");
628 session_export_struct.called = FALSE;
630 g_assert (real_book);
631 session_export_struct.be = be;
632 session_export_struct.book = real_book;
633 g_assert (!qof_session_export (fixture->session, real_session, percentage_fn));
634 g_assert (session_export_struct.called);
636 g_test_message (
"Test with backend export function set and no error produced");
637 p_qof_session_clear_error (fixture->session);
638 session_export_struct.called = FALSE;
639 g_assert (qof_session_export (fixture->session, real_session, percentage_fn));
640 g_assert (session_export_struct.called);
642 qof_session_destroy (real_session);
646 test_qof_session_swap_data (
Fixture *fixture, gconstpointer pData)
650 QofBook *book1 = NULL, *book2 = NULL;
653 g_assert (fixture->session);
654 session2 = qof_session_new ();
656 g_assert (fixture->session != session2);
661 fixture->session->backend = be1;
662 session2->backend = be2;
663 book1 = fixture->session->book;
664 book2 = session2->book;
667 qof_book_set_backend (book1, fixture->session->backend);
668 qof_book_set_backend (book2, session2->backend);
671 g_test_message (
"Test book lists are swapped and backend for each book is swapped");
673 g_assert (fixture->session->book == book2);
674 g_assert (session2->book == book1);
676 qof_session_destroy (session2);
689 g_assert (be == events_struct.be);
690 events_struct.called = TRUE;
695 test_qof_session_events (
Fixture *fixture, gconstpointer pData)
699 g_test_message (
"Test pending events null checks");
701 g_assert (!fixture->session->backend);
705 be->events_pending = NULL;
706 fixture->session->backend = be;
709 g_test_message (
"Test pending events callback");
710 be->events_pending = mock_events_fn;
711 events_struct.called = FALSE;
712 events_struct.be = be;
714 g_assert (events_struct.called);
716 g_test_message (
"Test process events null checks");
718 fixture->session->backend = NULL;
720 be->process_events = NULL;
721 fixture->session->backend = be;
724 g_test_message (
"Test process events callback");
725 be->process_events = mock_events_fn;
726 events_struct.called = FALSE;
727 events_struct.be = be;
729 g_assert (events_struct.called);
744 g_assert (be == data_load_struct.be);
745 g_assert (book == data_load_struct.book);
746 g_assert_cmpint (type, == , LOAD_TYPE_LOAD_ALL);
748 data_load_struct.called = TRUE;
752 test_qof_session_data_loaded (
Fixture *fixture, gconstpointer pData)
758 be->load = mock_all_data_load;
759 fixture->session->backend = be;
761 g_test_message (
"Test load callback and artificial error");
762 data_load_struct.be = be;
764 data_load_struct.called = FALSE;
766 g_assert (data_load_struct.called);
768 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"");
772 test_qof_backend_get_access_method_list (
Fixture *fixture, gconstpointer pData)
775 const char *access_methods[4] = {
"file",
"http",
"postgres",
"sqlite" };
778 for (i = 0; i < 4; i++)
784 g_assert_cmpint (g_slist_length (get_provider_list ()), == , (i + 1));
786 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 4);
788 g_test_message (
"Test list of access methods is returned");
791 g_assert_cmpint (g_list_length (list), == , 4);
792 g_assert_cmpstr (g_list_nth_data (list, 0), == ,
"file");
793 g_assert_cmpstr (g_list_nth_data (list, 1), == ,
"http");
794 g_assert_cmpstr (g_list_nth_data (list, 2), == ,
"postgres");
795 g_assert_cmpstr (g_list_nth_data (list, 3), == ,
"sqlite");
798 unregister_all_providers ();
803 test_qof_session_get_book (
Fixture *fixture, gconstpointer pData)
807 g_test_message (
"Test null check");
810 g_test_message (
"Test open book is returned");
811 g_assert (fixture->session->book);
814 g_assert_cmpuint (book->book_open, == ,
'y');
816 g_test_message (
"Test when book is closed null returned");
823 test_qof_session_get_error (
Fixture *fixture, gconstpointer pData)
827 g_test_message (
"Test if session is null");
830 g_test_message (
"Test when there is a local error");
834 g_test_message (
"Test if session backend is null");
835 g_assert (!fixture->session->backend);
836 fixture->session->last_err = ERR_BACKEND_NO_ERR;
839 g_test_message (
"Test for backend error");
843 fixture->session->backend = be;
848 test_qof_session_clear_error (
Fixture *fixture, gconstpointer pData)
855 g_test_message (
"Test session and backend errors are cleared");
857 fixture->session->backend = be;
859 p_qof_session_clear_error (fixture->session);
861 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == ,
"");
862 g_assert (!fixture->session->error_message);
876 mock_hook_fn (gpointer data, gpointer user_data)
881 g_assert (user_data);
883 g_assert (session == hooks_struct.session);
884 if (hooks_struct.call_count == 0)
885 g_assert (hooks_struct.data1 == user_data);
886 if (hooks_struct.call_count == 1)
887 g_assert (hooks_struct.data2 == user_data);
888 if (hooks_struct.call_count == 2)
889 g_assert (hooks_struct.data3 == user_data);
890 hooks_struct.call_count++;
894 test_qof_session_close_hooks (
Fixture *fixture, gconstpointer pData)
896 gint data1, data2, data3;
898 g_test_message (
"Test hooks list is initialized and hooks are added");
899 g_assert (!get_session_closed_hooks ());
901 g_assert (get_session_closed_hooks ());
902 g_assert (g_hook_find_func_data (get_session_closed_hooks (), FALSE, mock_hook_fn, (gpointer) &data1));
904 g_assert (g_hook_find_func_data (get_session_closed_hooks (), FALSE, mock_hook_fn, (gpointer) &data2));
906 g_assert (g_hook_find_func_data (get_session_closed_hooks (), FALSE, mock_hook_fn, (gpointer) &data3));
908 g_test_message (
"Test all close hooks are called");
909 hooks_struct.session = fixture->session;
910 hooks_struct.data1 = (gpointer) &data1;
911 hooks_struct.data2 = (gpointer) &data2;
912 hooks_struct.data3 = (gpointer) &data3;
913 hooks_struct.call_count = 0;
915 g_assert_cmpuint (hooks_struct.call_count, == , 3);
921 g_hook_list_clear (get_session_closed_hooks ());
925 test_suite_qofsession (
void )
927 GNC_TEST_ADD_FUNC (suitename,
"qof session new and destroy", test_qof_session_new_destroy);
928 GNC_TEST_ADD (suitename,
"qof session safe save",
Fixture, NULL, setup, test_session_safe_save, teardown);
929 GNC_TEST_ADD (suitename,
"qof session load backend",
Fixture, NULL, setup, test_qof_session_load_backend, teardown);
930 GNC_TEST_ADD (suitename,
"qof session load",
Fixture, NULL, setup, test_qof_session_load, teardown);
931 GNC_TEST_ADD (suitename,
"qof session begin",
Fixture, NULL, setup, test_qof_session_begin, teardown);
932 GNC_TEST_ADD (suitename,
"qof session save",
Fixture, NULL, setup, test_qof_session_save, teardown);
933 GNC_TEST_ADD (suitename,
"qof session destroy backend",
Fixture, NULL, setup, test_qof_session_destroy_backend, teardown);
934 GNC_TEST_ADD (suitename,
"qof session end",
Fixture, NULL, setup, test_qof_session_end, teardown);
935 GNC_TEST_ADD (suitename,
"qof session export",
Fixture, NULL, setup, test_qof_session_export, teardown);
936 GNC_TEST_ADD (suitename,
"qof session swap data",
Fixture, NULL, setup, test_qof_session_swap_data, teardown);
937 GNC_TEST_ADD (suitename,
"qof session events",
Fixture, NULL, setup, test_qof_session_events, teardown);
938 GNC_TEST_ADD (suitename,
"qof session data loaded",
Fixture, NULL, setup, test_qof_session_data_loaded, teardown);
939 GNC_TEST_ADD (suitename,
"qof backend access method list",
Fixture, NULL, setup, test_qof_backend_get_access_method_list, teardown);
940 GNC_TEST_ADD (suitename,
"qof session get book",
Fixture, NULL, setup, test_qof_session_get_book, teardown);
941 GNC_TEST_ADD (suitename,
"qof session get error",
Fixture, NULL, setup, test_qof_session_get_error, teardown);
942 GNC_TEST_ADD (suitename,
"qof session clear error",
Fixture, NULL, setup, test_qof_session_clear_error, teardown);
943 GNC_TEST_ADD (suitename,
"qof session close hooks",
Fixture, NULL, setup, test_qof_session_close_hooks, teardown);
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
QofBackend *(* backend_new)(void)
void qof_backend_set_error(QofBackend *be, QofBackendError err)
void qof_backend_register_provider(QofBackendProvider *)
void qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
void qof_book_mark_closed(QofBook *book)
gboolean qof_session_events_pending(const QofSession *session)
void(* export_fn)(QofBackend *, QofBook *)
QofBook * qof_session_get_book(const QofSession *session)
void qof_backend_set_message(QofBackend *be, const char *format,...)
void qof_session_call_close_hooks(QofSession *session)
void qof_session_add_close_hook(GFunc fn, gpointer data)
QofBackendError qof_session_get_error(QofSession *session)
gboolean(* check_data_type)(const char *)
Distinguish two providers with same access method.
void qof_session_swap_data(QofSession *session_1, QofSession *session_2)
QofBackendError qof_backend_get_error(QofBackend *be)
void qof_session_begin(QofSession *session, const char *book_id, gboolean ignore_lock, gboolean create, gboolean force)
gboolean qof_session_process_events(QofSession *session)
const char * access_method
void qof_session_ensure_all_data_loaded(QofSession *session)
GList * qof_backend_get_registered_access_method_list(void)
void qof_session_end(QofSession *session)
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.