|
GnuCash 2.4.99
|
00001 /******************************************************************** 00002 * test_qofsession.c: GLib g_test test suite for qofsession. * 00003 * Copyright 2011 John Ralls <jralls@ceridwen.us> * 00004 * * 00005 * This program is free software; you can redistribute it and/or * 00006 * modify it under the terms of the GNU General Public License as * 00007 * published by the Free Software Foundation; either version 2 of * 00008 * the License, or (at your option) any later version. * 00009 * * 00010 * This program is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00013 * GNU General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU General Public License* 00016 * along with this program; if not, contact: * 00017 * * 00018 * Free Software Foundation Voice: +1-617-542-5942 * 00019 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00020 * Boston, MA 02110-1301, USA gnu@gnu.org * 00021 \********************************************************************/ 00022 00023 #include "config.h" 00024 #include <glib.h> 00025 #include <unittest-support.h> 00026 #include "../qof.h" 00027 #include "../qofbackend-p.h" 00028 #include "../qofsession-p.h" 00029 #include "../qofclass-p.h" 00030 00031 static const gchar *suitename = "/qof/qofsession"; 00032 void test_suite_qofsession ( void ); 00033 00034 extern GHookList* get_session_closed_hooks (void); 00035 extern GSList* get_provider_list (void); 00036 extern gboolean get_qof_providers_initialized (void); 00037 extern void unregister_all_providers (void); 00038 00039 extern void (*p_qof_session_load_backend) (QofSession * session, const char * access_method); 00040 extern void (*p_qof_session_clear_error) (QofSession * session); 00041 extern void (*p_qof_session_destroy_backend) (QofSession * session); 00042 00043 extern void init_static_qofsession_pointers (void); 00044 00045 typedef struct 00046 { 00047 QofSession *session; 00048 } Fixture; 00049 00050 static void 00051 safe_sync( QofBackend *be, QofBook *book ) 00052 { 00053 qof_backend_set_error( be, ERR_BACKEND_DATA_CORRUPT ); 00054 qof_backend_set_message( be, "Just Kidding!" ); 00055 } 00056 00057 static void 00058 percentage_fn ( const char* message, double percent ) 00059 { 00060 g_print( "%s %f complete", message, percent ); 00061 } 00062 00063 static void 00064 setup( Fixture *fixture, gconstpointer pData ) 00065 { 00066 fixture->session = qof_session_new(); 00067 init_static_qofsession_pointers (); 00068 g_assert (p_qof_session_clear_error && p_qof_session_destroy_backend && p_qof_session_load_backend); 00069 } 00070 00071 static void 00072 teardown( Fixture *fixture, gconstpointer pData ) 00073 { 00074 qof_session_destroy( fixture->session ); 00075 p_qof_session_clear_error = NULL; 00076 p_qof_session_destroy_backend = NULL; 00077 p_qof_session_load_backend = NULL; 00078 } 00079 00080 static void 00081 test_qof_session_new_destroy (void) 00082 { 00083 QofSession *session = NULL; 00084 QofBook *book = NULL; 00085 00086 g_test_message ("Test session initialization"); 00087 session = qof_session_new (); 00088 g_assert (session); 00089 g_assert_cmpstr (session->entity.e_type, == , QOF_ID_SESSION); 00090 g_assert (session->book); 00091 book = (QofBook*) session->book; 00092 g_assert (book); 00093 g_assert (QOF_IS_BOOK (book)); 00094 g_assert (!session->book_id); 00095 g_assert (!session->backend); 00096 g_assert_cmpint (session->lock, == , 1); 00097 g_assert_cmpint (qof_session_get_error (session), == , ERR_BACKEND_NO_ERR); 00098 00099 g_test_message ("Test session destroy"); 00100 qof_session_destroy (session); 00101 /* all data structures of session get deallocated so we can't really test this place 00102 * instead qof_session_destroy_backend and qof_session_end are tested 00103 */ 00104 } 00105 00106 static void 00107 test_session_safe_save( Fixture *fixture, gconstpointer pData ) 00108 { 00109 fixture->session->backend = g_new0 (QofBackend, 1); 00110 fixture->session->backend->safe_sync = safe_sync; 00111 qof_session_safe_save( fixture->session, percentage_fn ); 00112 g_assert_cmpint( ERR_BACKEND_DATA_CORRUPT, == , 00113 qof_session_get_error( fixture->session )); 00114 g_assert( NULL == qof_session_get_url( fixture->session )); 00115 } 00116 00117 static struct 00118 { 00119 QofBackend *be; 00120 gboolean data_compatible; 00121 gboolean check_data_type_called; 00122 gboolean backend_new_called; 00123 } load_backend_struct; 00124 00125 static gboolean 00126 mock_check_data_type (const char* book_id) 00127 { 00128 g_assert (book_id); 00129 g_assert_cmpstr (book_id, == , "my book"); 00130 load_backend_struct.check_data_type_called = TRUE; 00131 return load_backend_struct.data_compatible; 00132 } 00133 00134 static QofBackend* 00135 mock_backend_new (void) 00136 { 00137 QofBackend *be = NULL; 00138 00139 be = g_new0 (QofBackend, 1); 00140 g_assert (be); 00141 load_backend_struct.be = be; 00142 load_backend_struct.backend_new_called = TRUE; 00143 return be; 00144 } 00145 00146 static void 00147 test_qof_session_load_backend (Fixture *fixture, gconstpointer pData) 00148 { 00149 QofBackendProvider *prov = NULL; 00150 QofBook *book = NULL; 00151 00152 /* init */ 00153 prov = g_new0 (QofBackendProvider, 1); 00154 00155 g_test_message ("Test when no provider is registered"); 00156 g_assert (!get_qof_providers_initialized ()); 00157 g_assert (get_provider_list () == NULL); 00158 p_qof_session_load_backend (fixture->session, "file"); 00159 g_assert (get_qof_providers_initialized ()); 00160 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00161 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load 'file' using access_method"); 00162 p_qof_session_clear_error (fixture->session); 00163 00164 g_test_message ("Test with provider registered but access method not supported"); 00165 prov->access_method = "unsupported"; 00166 qof_backend_register_provider (prov); 00167 g_assert (get_provider_list ()); 00168 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 1); 00169 p_qof_session_load_backend (fixture->session, "file"); 00170 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00171 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load 'file' using access_method"); 00172 p_qof_session_clear_error (fixture->session); 00173 00174 g_test_message ("Test with access method supported but type incompatible"); 00175 prov->access_method = "file"; 00176 prov->check_data_type = mock_check_data_type; 00177 load_backend_struct.data_compatible = FALSE; 00178 load_backend_struct.check_data_type_called = FALSE; 00179 fixture->session->book_id = g_strdup ("my book"); 00180 p_qof_session_load_backend (fixture->session, "file"); 00181 g_assert (load_backend_struct.check_data_type_called); 00182 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00183 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load 'file' using access_method"); 00184 p_qof_session_clear_error (fixture->session); 00185 00186 g_test_message ("Test with type compatible but backend_new not set"); 00187 prov->backend_new = NULL; 00188 load_backend_struct.data_compatible = TRUE; 00189 load_backend_struct.check_data_type_called = FALSE; 00190 p_qof_session_load_backend (fixture->session, "file"); 00191 g_assert (load_backend_struct.check_data_type_called); 00192 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00193 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load 'file' using access_method"); 00194 p_qof_session_clear_error (fixture->session); 00195 00196 g_test_message ("Test with type compatible backend_new set"); 00197 prov->backend_new = mock_backend_new; 00198 load_backend_struct.be = NULL; 00199 load_backend_struct.data_compatible = TRUE; 00200 load_backend_struct.check_data_type_called = FALSE; 00201 load_backend_struct.backend_new_called = FALSE; 00202 g_assert (fixture->session->backend == NULL); 00203 book = qof_session_get_book (fixture->session); 00204 g_assert (book); 00205 g_assert (qof_book_get_backend (book) == NULL); 00206 p_qof_session_load_backend (fixture->session, "file"); 00207 g_assert (load_backend_struct.check_data_type_called); 00208 g_assert (load_backend_struct.backend_new_called); 00209 g_assert (load_backend_struct.be); 00210 g_assert (load_backend_struct.be == fixture->session->backend); 00211 g_assert (prov == fixture->session->backend->provider); 00212 g_assert (qof_book_get_backend (book) == load_backend_struct.be); 00213 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00214 00215 unregister_all_providers (); 00216 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 0); 00217 } 00218 00219 static struct 00220 { 00221 QofBackend *be; 00222 QofBook *oldbook; 00223 gboolean error; 00224 gboolean load_called; 00225 } load_session_struct; 00226 00227 static void 00228 mock_load (QofBackend *be, QofBook *book, QofBackendLoadType type) 00229 { 00230 g_assert (be); 00231 g_assert (book); 00232 g_assert (be == load_session_struct.be); 00233 g_assert (book != load_session_struct.oldbook); 00234 g_assert (qof_book_get_backend (book) == be); 00235 if (load_session_struct.error) 00236 qof_backend_set_error (be, ERR_BACKEND_DATA_CORRUPT); /* just any valid error */ 00237 load_session_struct.load_called = TRUE; 00238 } 00239 00240 static void 00241 test_qof_session_load (Fixture *fixture, gconstpointer pData) 00242 { 00243 /* Method initializes a new book and loads data into it 00244 * if load fails old books are restored 00245 */ 00246 QofBackend *be = NULL; 00247 QofBook *newbook = NULL; 00248 00249 /* init */ 00250 fixture->session->book_id = g_strdup ("my book"); 00251 be = g_new0 (QofBackend, 1); 00252 g_assert (be); 00253 fixture->session->backend = be; 00254 be->load = mock_load; 00255 00256 g_test_message ("Test when no error is produced"); 00257 g_assert (be->percentage == NULL); 00258 load_session_struct.be = be; 00259 load_session_struct.oldbook = qof_session_get_book (fixture->session); 00260 g_assert (fixture->session->book); 00261 load_session_struct.error = FALSE; 00262 load_session_struct.load_called = FALSE; 00263 qof_session_load (fixture->session, percentage_fn); 00264 newbook = qof_session_get_book (fixture->session); 00265 g_assert (newbook); 00266 g_assert (load_session_struct.oldbook != newbook); 00267 g_assert (fixture->session->book); 00268 g_assert (load_session_struct.load_called); 00269 00270 g_test_message ("Test when no is produced"); 00271 load_session_struct.oldbook = qof_session_get_book (fixture->session); 00272 g_assert (fixture->session->book); 00273 load_session_struct.error = TRUE; 00274 load_session_struct.load_called = FALSE; 00275 qof_session_load (fixture->session, percentage_fn); 00276 newbook = qof_session_get_book (fixture->session); 00277 g_assert (newbook); 00278 g_assert (load_session_struct.oldbook == newbook); 00279 g_assert (fixture->session->book); 00280 g_assert (load_session_struct.load_called); 00281 } 00282 00283 static struct 00284 { 00285 QofBackend *be; 00286 QofSession *session; 00287 const char *book_id; 00288 gboolean backend_new_called; 00289 gboolean session_begin_called; 00290 gboolean produce_error; 00291 } session_begin_struct; 00292 00293 static void 00294 mock_session_begin (QofBackend *be, QofSession *session, const char *book_id, 00295 gboolean ignore_lock, gboolean create, gboolean force) 00296 { 00297 g_assert (be); 00298 g_assert (be == session_begin_struct.be); 00299 g_assert (session); 00300 g_assert (session == session_begin_struct.session); 00301 g_assert (book_id); 00302 g_assert_cmpstr (book_id, == , session_begin_struct.book_id); 00303 g_assert (ignore_lock); 00304 g_assert (!create); 00305 g_assert (force); 00306 if (session_begin_struct.produce_error) 00307 { 00308 qof_backend_set_error (be, ERR_BACKEND_DATA_CORRUPT); 00309 qof_backend_set_message (be, "push any error"); 00310 } 00311 session_begin_struct.session_begin_called = TRUE; 00312 } 00313 00314 static QofBackend* 00315 mock_backend_new_for_begin (void) 00316 { 00317 QofBackend *be = NULL; 00318 00319 be = g_new0 (QofBackend, 1); 00320 g_assert (be); 00321 be->session_begin = mock_session_begin; 00322 session_begin_struct.be = be; 00323 session_begin_struct.backend_new_called = TRUE; 00324 return be; 00325 } 00326 00327 static void 00328 test_qof_session_begin (Fixture *fixture, gconstpointer pData) 00329 { 00330 gboolean ignore_lock, create, force; 00331 QofBackend *be = NULL; 00332 QofBackendProvider *prov = NULL; 00333 00334 /* setup */ 00335 ignore_lock = TRUE; 00336 create = FALSE; 00337 force = TRUE; 00338 00339 be = g_new0 (QofBackend, 1); 00340 g_assert (be); 00341 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 0); 00342 prov = g_new0 (QofBackendProvider, 1); 00343 prov->backend_new = mock_backend_new_for_begin; 00344 00345 /* run tests */ 00346 g_test_message ("Test when book_id is set backend is not changed"); 00347 fixture->session->backend = be; 00348 fixture->session->book_id = g_strdup ("my book"); 00349 qof_session_begin (fixture->session, "my book", ignore_lock, create, force); 00350 g_assert (fixture->session->backend == be); 00351 00352 g_test_message ("Test when session book_id is not set and book_id passed is null backend is not changed"); 00353 g_free (fixture->session->book_id); 00354 fixture->session->book_id = NULL; 00355 qof_session_begin (fixture->session, NULL, ignore_lock, create, force); 00356 g_assert (fixture->session->backend == be); 00357 00358 g_test_message ("Test default access_method parsing"); 00359 /* routine will destroy old backend 00360 * parse access_method as 'file' and try to find backend 00361 * as there is no backend registered error will be raised 00362 */ 00363 qof_session_begin (fixture->session, "default_should_be_file", ignore_lock, create, force); 00364 g_assert (fixture->session->backend == NULL); 00365 g_assert (fixture->session->book_id == NULL); 00366 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00367 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load 'file' using access_method"); 00368 00369 g_test_message ("Test access_method parsing"); 00370 qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force); 00371 g_assert (fixture->session->backend == NULL); 00372 g_assert (fixture->session->book_id == NULL); 00373 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00374 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load 'postgres' using access_method"); 00375 00376 g_test_message ("Test with valid backend returned and session begin set; error is produced"); 00377 session_begin_struct.session = fixture->session; 00378 session_begin_struct.book_id = "postgres://localhost:8080"; 00379 session_begin_struct.backend_new_called = FALSE; 00380 session_begin_struct.session_begin_called = FALSE; 00381 session_begin_struct.produce_error = TRUE; 00382 prov->access_method = "postgres"; 00383 qof_backend_register_provider (prov); 00384 qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force); 00385 g_assert (fixture->session->backend); 00386 g_assert (session_begin_struct.be == fixture->session->backend); 00387 g_assert (session_begin_struct.backend_new_called == TRUE); 00388 g_assert (session_begin_struct.session_begin_called == TRUE); 00389 g_assert (fixture->session->book_id == NULL); 00390 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT); 00391 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "push any error"); 00392 00393 g_test_message ("Test normal session_begin execution"); 00394 session_begin_struct.backend_new_called = FALSE; 00395 session_begin_struct.session_begin_called = FALSE; 00396 session_begin_struct.produce_error = FALSE; 00397 qof_session_begin (fixture->session, "postgres://localhost:8080", ignore_lock, create, force); 00398 g_assert (fixture->session->backend); 00399 g_assert (session_begin_struct.be == fixture->session->backend); 00400 g_assert (session_begin_struct.backend_new_called == TRUE); 00401 g_assert (session_begin_struct.session_begin_called == TRUE); 00402 g_assert (fixture->session->book_id); 00403 g_assert_cmpstr (fixture->session->book_id, == , "postgres://localhost:8080"); 00404 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00405 00406 unregister_all_providers (); 00407 } 00408 00409 static struct 00410 { 00411 QofBackend *be; 00412 QofBook *book; 00413 QofSession *session; 00414 const char *book_id; 00415 gboolean sync_called; 00416 gboolean backend_new_called; 00417 gboolean session_begin_called; 00418 } session_save_struct; 00419 00420 static void 00421 mock_sync (QofBackend *be, QofBook *book) 00422 { 00423 g_assert (be); 00424 g_assert (book); 00425 g_assert (be == session_save_struct.be); 00426 g_assert (book == session_save_struct.book); 00427 session_save_struct.sync_called = TRUE; 00428 } 00429 00430 static void 00431 mock_session_begin_for_save (QofBackend *be, QofSession *session, const char *book_id, 00432 gboolean ignore_lock, gboolean create, gboolean force) 00433 { 00434 g_assert (be); 00435 g_assert (be == session_save_struct.be); 00436 g_assert (session); 00437 g_assert (session == session_save_struct.session); 00438 g_assert (book_id); 00439 g_assert_cmpstr (book_id, == , session_save_struct.book_id); 00440 g_assert (ignore_lock); 00441 g_assert (create); 00442 g_assert (force); 00443 session_save_struct.session_begin_called = TRUE; 00444 } 00445 00446 static QofBackend* 00447 mock_backend_new_for_save (void) 00448 { 00449 QofBackend *be = NULL; 00450 00451 be = g_new0 (QofBackend, 1); 00452 g_assert (be); 00453 be->session_begin = mock_session_begin_for_save; 00454 be->sync = mock_sync; 00455 session_save_struct.be = be; 00456 session_save_struct.backend_new_called = TRUE; 00457 return be; 00458 } 00459 00460 static void 00461 test_qof_session_save (Fixture *fixture, gconstpointer pData) 00462 { 00463 QofBook *book = NULL; 00464 QofBackend *be = NULL; 00465 QofBackendProvider *prov = NULL, *reg_prov = NULL; 00466 00467 g_test_message ("Test when book not partial and backend not set"); 00468 g_assert (fixture->session->backend == NULL); 00469 book = qof_session_get_book (fixture->session); 00470 g_assert (book); 00471 qof_book_set_data (book, PARTIAL_QOFBOOK, GINT_TO_POINTER (FALSE)); 00472 qof_session_push_error (fixture->session, ERR_BACKEND_DATA_CORRUPT, "push any error"); 00473 g_assert_cmpint (fixture->session->lock, == , 1); 00474 qof_session_save (fixture->session, NULL); 00475 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_HANDLER); 00476 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , "failed to load backend"); 00477 g_assert_cmpint (fixture->session->lock, == , 1); 00478 00479 g_test_message ("Test when book not partial and backend set; imitate error"); 00480 be = g_new0 (QofBackend, 1); 00481 g_assert (be); 00482 be->sync = mock_sync; 00483 fixture->session->backend = be; 00484 g_assert_cmpint (fixture->session->lock, == , 1); 00485 session_save_struct.sync_called = FALSE; 00486 session_save_struct.be = be; 00487 session_save_struct.book = book; 00488 qof_backend_set_error (be, ERR_BACKEND_DATA_CORRUPT); 00489 qof_backend_set_message (be, "push any error"); 00490 qof_session_save (fixture->session, percentage_fn); 00491 g_assert (qof_book_get_backend (book) == be); 00492 g_assert (be->percentage == percentage_fn); 00493 g_assert (session_save_struct.sync_called); 00494 g_assert_cmpint (fixture->session->lock, == , 1); 00495 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT); 00496 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , ""); 00497 00498 g_test_message ("Test when book not partial and backend set; successful save"); 00499 g_assert_cmpint (fixture->session->lock, == , 1); 00500 session_save_struct.sync_called = FALSE; 00501 qof_session_save (fixture->session, percentage_fn); 00502 g_assert (qof_book_get_backend (book) == be); 00503 g_assert (be->percentage == percentage_fn); 00504 g_assert (session_save_struct.sync_called); 00505 g_assert_cmpint (fixture->session->lock, == , 1); 00506 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00507 00508 /* change backend testing 00509 * code probably should be moved to separate routine or some existing code can be reused 00510 * for example: qof_session_load_backend 00511 */ 00512 g_test_message ("Test when book is partial and current backend supports it; successful save backend not changed"); 00513 prov = g_new0 (QofBackendProvider, 1); 00514 prov->partial_book_supported = TRUE; 00515 fixture->session->backend->provider = prov; 00516 g_assert_cmpint (fixture->session->lock, == , 1); 00517 qof_book_set_data (book, PARTIAL_QOFBOOK, GINT_TO_POINTER (TRUE)); 00518 session_save_struct.sync_called = FALSE; 00519 qof_session_save (fixture->session, percentage_fn); 00520 g_assert (fixture->session->backend == be); 00521 g_assert (fixture->session->backend->provider == prov); 00522 g_assert (qof_book_get_backend (book) == be); 00523 g_assert (be->percentage == percentage_fn); 00524 g_assert (session_save_struct.sync_called); 00525 g_assert_cmpint (fixture->session->lock, == , 1); 00526 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00527 00528 g_test_message ("Test when book is partial and current backend does not support it; backend should be changed"); 00529 prov->partial_book_supported = FALSE; 00530 g_assert_cmpint (fixture->session->lock, == , 1); 00531 reg_prov = g_new0 (QofBackendProvider, 1); 00532 reg_prov->partial_book_supported = TRUE; 00533 reg_prov->backend_new = mock_backend_new_for_save; 00534 qof_backend_register_provider (reg_prov); 00535 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 1); 00536 session_save_struct.book = book; 00537 session_save_struct.session = fixture->session; 00538 fixture->session->book_id = g_strdup ("my book"); 00539 session_save_struct.book_id = "my book"; 00540 session_save_struct.sync_called = FALSE; 00541 session_save_struct.backend_new_called = FALSE; 00542 session_save_struct.session_begin_called = FALSE; 00543 00544 qof_session_save (fixture->session, percentage_fn); 00545 00546 g_assert (session_save_struct.backend_new_called); 00547 g_assert (fixture->session->backend == session_save_struct.be); 00548 g_assert (fixture->session->backend->provider == reg_prov); 00549 g_assert (fixture->session->book_id == NULL); 00550 g_assert (session_save_struct.session_begin_called); 00551 g_assert (qof_book_get_backend (book) == session_save_struct.be); 00552 g_assert (session_save_struct.sync_called); 00553 g_assert_cmpint (fixture->session->lock, == , 1); 00554 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00555 00556 unregister_all_providers (); 00557 g_free (prov); 00558 } 00559 00560 static struct 00561 { 00562 QofBackend *be; 00563 gboolean called; 00564 } destroy_backend_struct; 00565 00566 static void 00567 mock_destroy_backend (QofBackend *be) 00568 { 00569 g_assert (be); 00570 g_assert (destroy_backend_struct.be == be); 00571 destroy_backend_struct.called = TRUE; 00572 } 00573 00574 static void 00575 test_qof_session_destroy_backend (Fixture *fixture, gconstpointer pData) 00576 { 00577 QofBackend *be = NULL; 00578 00579 g_test_message ("Test with destroy backend callback not set"); 00580 be = g_new0 (QofBackend, 1); 00581 g_assert (be); 00582 fixture->session->backend = be; 00583 p_qof_session_destroy_backend (fixture->session); 00584 g_assert (!fixture->session->backend); 00585 00586 g_test_message ("Test with destroy backend callback set"); 00587 be = g_new0 (QofBackend, 1); 00588 g_assert (be); 00589 be->destroy_backend = mock_destroy_backend; 00590 fixture->session->backend = be; 00591 destroy_backend_struct.called = FALSE; 00592 destroy_backend_struct.be = be; 00593 p_qof_session_destroy_backend (fixture->session); 00594 g_assert (!fixture->session->backend); 00595 g_assert (destroy_backend_struct.called); 00596 } 00597 00598 static struct 00599 { 00600 QofBackend *be; 00601 gboolean called; 00602 } session_end_struct; 00603 00604 static void 00605 mock_session_end (QofBackend *be) 00606 { 00607 g_assert (be); 00608 g_assert (session_end_struct.be == be); 00609 session_end_struct.called = TRUE; 00610 } 00611 00612 static void 00613 test_qof_session_end (Fixture *fixture, gconstpointer pData) 00614 { 00615 QofBackend *be = NULL; 00616 00617 g_test_message ("Test backend is closed, errors cleared and book_id removed"); 00618 be = g_new0 (QofBackend, 1); 00619 g_assert (be); 00620 be->session_end = mock_session_end; 00621 fixture->session->backend = be; 00622 qof_session_push_error (fixture->session, ERR_BACKEND_DATA_CORRUPT, "push any error"); 00623 fixture->session->book_id = g_strdup ("my book"); 00624 session_end_struct.called = FALSE; 00625 session_end_struct.be = be; 00626 qof_session_end (fixture->session); 00627 g_assert (session_end_struct.called); 00628 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00629 g_assert (!fixture->session->book_id); 00630 } 00631 00632 static struct 00633 { 00634 QofBackend *be; 00635 QofBook *book; 00636 gboolean called; 00637 } session_export_struct; 00638 00639 static void 00640 mock_export (QofBackend *be, QofBook *book) 00641 { 00642 g_assert (be); 00643 g_assert (session_export_struct.be == be); 00644 g_assert (book); 00645 g_assert (session_export_struct.book == book); 00646 session_export_struct.called = TRUE; 00647 } 00648 00649 static void 00650 test_qof_session_export (Fixture *fixture, gconstpointer pData) 00651 { 00652 QofSession *real_session = NULL; 00653 QofBook *tmp_book = NULL, *real_book = NULL; 00654 QofBackend *be = NULL; 00655 00656 real_session = qof_session_new (); 00657 g_assert (real_session); 00658 00659 g_test_message ("Test null checks"); 00660 g_assert (!qof_session_export (NULL, real_session, percentage_fn)); 00661 g_assert (!qof_session_export (fixture->session, NULL, percentage_fn)); 00662 00663 g_test_message ("Test with backend not set"); 00664 tmp_book = qof_session_get_book (fixture->session); 00665 g_assert (tmp_book); 00666 be = qof_book_get_backend (tmp_book); 00667 g_assert (!be); 00668 g_assert (!qof_session_export (fixture->session, real_session, percentage_fn)); 00669 00670 g_test_message ("Test with backend set"); 00671 be = g_new0 (QofBackend, 1); 00672 g_assert (be); 00673 fixture->session->backend = be; 00674 qof_book_set_backend (tmp_book, be); 00675 g_assert (!be->percentage); 00676 g_assert (qof_session_export (fixture->session, real_session, percentage_fn)); 00677 g_assert (be->percentage == percentage_fn); 00678 00679 g_test_message ("Test with backend export function set and error is produced"); 00680 be->export_fn = mock_export; 00681 qof_backend_set_error (be, ERR_BACKEND_DATA_CORRUPT); 00682 qof_backend_set_message (be, "push any error"); 00683 session_export_struct.called = FALSE; 00684 real_book = qof_session_get_book (real_session); 00685 g_assert (real_book); 00686 session_export_struct.be = be; 00687 session_export_struct.book = real_book; 00688 g_assert (!qof_session_export (fixture->session, real_session, percentage_fn)); 00689 g_assert (session_export_struct.called); 00690 00691 g_test_message ("Test with backend export function set and no error produced"); 00692 p_qof_session_clear_error (fixture->session); 00693 session_export_struct.called = FALSE; 00694 g_assert (qof_session_export (fixture->session, real_session, percentage_fn)); 00695 g_assert (session_export_struct.called); 00696 00697 qof_session_destroy (real_session); 00698 } 00699 00700 static void 00701 test_qof_session_swap_data (Fixture *fixture, gconstpointer pData) 00702 { 00703 QofSession *session2 = NULL; 00704 QofBackend *be1 = NULL, *be2 = NULL; 00705 QofBook *book1 = NULL, *book2 = NULL; 00706 GList *node; 00707 00708 /* init */ 00709 g_assert (fixture->session); 00710 session2 = qof_session_new (); 00711 g_assert (session2); 00712 g_assert (fixture->session != session2); 00713 be1 = g_new0 (QofBackend, 1); 00714 g_assert (be1); 00715 be2 = g_new0 (QofBackend, 1); 00716 g_assert (be2); 00717 fixture->session->backend = be1; 00718 session2->backend = be2; 00719 book1 = fixture->session->book; 00720 book2 = session2->book; 00721 g_assert (book1); 00722 g_assert (book2); 00723 qof_book_set_backend (book1, fixture->session->backend); 00724 qof_book_set_backend (book2, session2->backend); 00725 00726 00727 g_test_message ("Test book lists are swapped and backend for each book is swapped"); 00728 qof_session_swap_data (fixture->session, session2); 00729 g_assert (fixture->session->book == book2); 00730 g_assert (session2->book == book1); 00731 00732 qof_session_destroy (session2); 00733 } 00734 00735 static struct 00736 { 00737 QofBackend *be; 00738 gboolean called; 00739 } events_struct; 00740 00741 static gboolean 00742 mock_events_fn (QofBackend *be) 00743 { 00744 g_assert (be); 00745 g_assert (be == events_struct.be); 00746 events_struct.called = TRUE; 00747 return TRUE; 00748 } 00749 00750 static void 00751 test_qof_session_events (Fixture *fixture, gconstpointer pData) 00752 { 00753 QofBackend *be = NULL; 00754 00755 g_test_message ("Test pending events null checks"); 00756 g_assert (!qof_session_events_pending (NULL)); 00757 g_assert (!fixture->session->backend); 00758 g_assert (!qof_session_events_pending (fixture->session)); 00759 be = g_new0 (QofBackend, 1); 00760 g_assert (be); 00761 be->events_pending = NULL; 00762 fixture->session->backend = be; 00763 g_assert (!qof_session_events_pending (fixture->session)); 00764 00765 g_test_message ("Test pending events callback"); 00766 be->events_pending = mock_events_fn; 00767 events_struct.called = FALSE; 00768 events_struct.be = be; 00769 g_assert (qof_session_events_pending (fixture->session)); 00770 g_assert (events_struct.called); 00771 00772 g_test_message ("Test process events null checks"); 00773 g_assert (!qof_session_process_events (NULL)); 00774 fixture->session->backend = NULL; 00775 g_assert (!qof_session_process_events (fixture->session)); 00776 be->process_events = NULL; 00777 fixture->session->backend = be; 00778 g_assert (!qof_session_process_events (fixture->session)); 00779 00780 g_test_message ("Test process events callback"); 00781 be->process_events = mock_events_fn; 00782 events_struct.called = FALSE; 00783 events_struct.be = be; 00784 g_assert (qof_session_process_events (fixture->session)); 00785 g_assert (events_struct.called); 00786 } 00787 00788 static struct 00789 { 00790 QofBackend *be; 00791 QofBook *book; 00792 gboolean called; 00793 } data_load_struct; 00794 00795 static void 00796 mock_all_data_load (QofBackend *be, QofBook *book, QofBackendLoadType type) 00797 { 00798 g_assert (be); 00799 g_assert (book); 00800 g_assert (be == data_load_struct.be); 00801 g_assert (book == data_load_struct.book); 00802 g_assert_cmpint (type, == , LOAD_TYPE_LOAD_ALL); 00803 qof_backend_set_error (be, ERR_BACKEND_DATA_CORRUPT); 00804 data_load_struct.called = TRUE; 00805 } 00806 00807 static void 00808 test_qof_session_data_loaded (Fixture *fixture, gconstpointer pData) 00809 { 00810 QofBackend *be = NULL; 00811 00812 be = g_new0 (QofBackend, 1); 00813 g_assert (be); 00814 be->load = mock_all_data_load; 00815 fixture->session->backend = be; 00816 00817 g_test_message ("Test load callback and artificial error"); 00818 data_load_struct.be = be; 00819 data_load_struct.book = qof_session_get_book (fixture->session); 00820 data_load_struct.called = FALSE; 00821 qof_session_ensure_all_data_loaded (fixture->session); 00822 g_assert (data_load_struct.called); 00823 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT); 00824 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , ""); 00825 } 00826 00827 static void 00828 test_qof_backend_get_access_method_list (Fixture *fixture, gconstpointer pData) 00829 { 00830 GList *list = NULL; 00831 const char *access_methods[4] = { "file", "http", "postgres", "sqlite" }; 00832 int i; 00833 00834 for (i = 0; i < 4; i++) 00835 { 00836 QofBackendProvider *prov = g_new0 (QofBackendProvider, 1); 00837 g_assert (prov); 00838 prov->access_method = access_methods[ i ]; 00839 qof_backend_register_provider (prov); 00840 g_assert_cmpint (g_slist_length (get_provider_list ()), == , (i + 1)); 00841 } 00842 g_assert_cmpint (g_slist_length (get_provider_list ()), == , 4); 00843 00844 g_test_message ("Test list of access methods is returned"); 00845 list = qof_backend_get_registered_access_method_list (); 00846 g_assert (list); 00847 g_assert_cmpint (g_list_length (list), == , 4); 00848 g_assert_cmpstr (g_list_nth_data (list, 0), == , "file"); 00849 g_assert_cmpstr (g_list_nth_data (list, 1), == , "http"); 00850 g_assert_cmpstr (g_list_nth_data (list, 2), == , "postgres"); 00851 g_assert_cmpstr (g_list_nth_data (list, 3), == , "sqlite"); 00852 00853 g_list_free (list); 00854 unregister_all_providers (); 00855 } 00856 00857 00858 static void 00859 test_qof_session_get_book (Fixture *fixture, gconstpointer pData) 00860 { 00861 QofBook *book = NULL; 00862 00863 g_test_message ("Test null check"); 00864 g_assert (!qof_session_get_book (NULL)); 00865 00866 g_test_message ("Test open book is returned"); 00867 g_assert (fixture->session->book); 00868 book = qof_session_get_book (fixture->session); 00869 g_assert (book); 00870 g_assert_cmpuint (book->book_open, == , 'y'); 00871 00872 g_test_message ("Test when book is closed null returned"); 00873 qof_book_mark_closed (book); 00874 g_assert (!qof_session_get_book (fixture->session)); 00875 00876 } 00877 00878 static void 00879 test_qof_session_get_error (Fixture *fixture, gconstpointer pData) 00880 { 00881 QofBackend *be = NULL; 00882 00883 g_test_message ("Test if session is null"); 00884 g_assert_cmpint (qof_session_get_error (NULL), == , ERR_BACKEND_NO_BACKEND); 00885 00886 g_test_message ("Test when there is a local error"); 00887 fixture->session->last_err = ERR_BACKEND_DATA_CORRUPT; /* just any error */ 00888 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_DATA_CORRUPT); 00889 00890 g_test_message ("Test if session backend is null"); 00891 g_assert (!fixture->session->backend); 00892 fixture->session->last_err = ERR_BACKEND_NO_ERR; 00893 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00894 00895 g_test_message ("Test for backend error"); 00896 be = g_new0 (QofBackend, 1); 00897 g_assert (be); 00898 qof_backend_set_error (be, ERR_BACKEND_CANT_CONNECT); 00899 fixture->session->backend = be; 00900 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_CANT_CONNECT); 00901 } 00902 00903 static void 00904 test_qof_session_clear_error (Fixture *fixture, gconstpointer pData) 00905 { 00906 QofBackend *be = NULL; 00907 00908 be = g_new0 (QofBackend, 1); 00909 g_assert (be); 00910 00911 g_test_message ("Test session and backend errors are cleared"); 00912 qof_session_push_error (fixture->session, ERR_BACKEND_NO_SUCH_DB, "push any error"); 00913 fixture->session->backend = be; 00914 qof_backend_set_error (be, ERR_BACKEND_CANT_CONNECT); 00915 p_qof_session_clear_error (fixture->session); 00916 g_assert_cmpint (qof_session_get_error (fixture->session), == , ERR_BACKEND_NO_ERR); 00917 g_assert_cmpstr (qof_session_get_error_message (fixture->session), == , ""); 00918 g_assert (!fixture->session->error_message); 00919 g_assert_cmpint (qof_backend_get_error (be), == , ERR_BACKEND_NO_ERR); 00920 } 00921 00922 static struct 00923 { 00924 QofSession *session; 00925 gpointer data1; 00926 gpointer data2; 00927 gpointer data3; 00928 guint call_count; 00929 } hooks_struct; 00930 00931 static void 00932 mock_hook_fn (gpointer data, gpointer user_data) 00933 { 00934 QofSession *session; 00935 00936 g_assert (data); 00937 g_assert (user_data); 00938 session = (QofSession*) data; 00939 g_assert (session == hooks_struct.session); 00940 if (hooks_struct.call_count == 0) 00941 g_assert (hooks_struct.data1 == user_data); 00942 if (hooks_struct.call_count == 1) 00943 g_assert (hooks_struct.data2 == user_data); 00944 if (hooks_struct.call_count == 2) 00945 g_assert (hooks_struct.data3 == user_data); 00946 hooks_struct.call_count++; 00947 } 00948 00949 static void 00950 test_qof_session_close_hooks (Fixture *fixture, gconstpointer pData) 00951 { 00952 gint data1, data2, data3; 00953 00954 g_test_message ("Test hooks list is initialized and hooks are added"); 00955 g_assert (!get_session_closed_hooks ()); 00956 qof_session_add_close_hook (mock_hook_fn, (gpointer) &data1); 00957 g_assert (get_session_closed_hooks ()); 00958 g_assert (g_hook_find_func_data (get_session_closed_hooks (), FALSE, mock_hook_fn, (gpointer) &data1)); 00959 qof_session_add_close_hook (mock_hook_fn, (gpointer) &data2); 00960 g_assert (g_hook_find_func_data (get_session_closed_hooks (), FALSE, mock_hook_fn, (gpointer) &data2)); 00961 qof_session_add_close_hook (mock_hook_fn, (gpointer) &data3); 00962 g_assert (g_hook_find_func_data (get_session_closed_hooks (), FALSE, mock_hook_fn, (gpointer) &data3)); 00963 00964 g_test_message ("Test all close hooks are called"); 00965 hooks_struct.session = fixture->session; 00966 hooks_struct.data1 = (gpointer) &data1; 00967 hooks_struct.data2 = (gpointer) &data2; 00968 hooks_struct.data3 = (gpointer) &data3; 00969 hooks_struct.call_count = 0; 00970 qof_session_call_close_hooks (fixture->session); 00971 g_assert_cmpuint (hooks_struct.call_count, == , 3); 00972 00973 /* currently qofsession does not provide a way to clear hooks list 00974 * g_hook_list_clear is used to destroy list and all of it's elements 00975 * though i' not sure if it frees all the memory allocated 00976 */ 00977 g_hook_list_clear (get_session_closed_hooks ()); 00978 } 00979 00980 void 00981 test_suite_qofsession ( void ) 00982 { 00983 GNC_TEST_ADD_FUNC (suitename, "qof session new and destroy", test_qof_session_new_destroy); 00984 GNC_TEST_ADD (suitename, "qof session safe save", Fixture, NULL, setup, test_session_safe_save, teardown); 00985 GNC_TEST_ADD (suitename, "qof session load backend", Fixture, NULL, setup, test_qof_session_load_backend, teardown); 00986 GNC_TEST_ADD (suitename, "qof session load", Fixture, NULL, setup, test_qof_session_load, teardown); 00987 GNC_TEST_ADD (suitename, "qof session begin", Fixture, NULL, setup, test_qof_session_begin, teardown); 00988 GNC_TEST_ADD (suitename, "qof session save", Fixture, NULL, setup, test_qof_session_save, teardown); 00989 GNC_TEST_ADD (suitename, "qof session destroy backend", Fixture, NULL, setup, test_qof_session_destroy_backend, teardown); 00990 GNC_TEST_ADD (suitename, "qof session end", Fixture, NULL, setup, test_qof_session_end, teardown); 00991 GNC_TEST_ADD (suitename, "qof session export", Fixture, NULL, setup, test_qof_session_export, teardown); 00992 GNC_TEST_ADD (suitename, "qof session swap data", Fixture, NULL, setup, test_qof_session_swap_data, teardown); 00993 GNC_TEST_ADD (suitename, "qof session events", Fixture, NULL, setup, test_qof_session_events, teardown); 00994 GNC_TEST_ADD (suitename, "qof session data loaded", Fixture, NULL, setup, test_qof_session_data_loaded, teardown); 00995 GNC_TEST_ADD (suitename, "qof backend access method list", Fixture, NULL, setup, test_qof_backend_get_access_method_list, teardown); 00996 GNC_TEST_ADD (suitename, "qof session get book", Fixture, NULL, setup, test_qof_session_get_book, teardown); 00997 GNC_TEST_ADD (suitename, "qof session get error", Fixture, NULL, setup, test_qof_session_get_error, teardown); 00998 GNC_TEST_ADD (suitename, "qof session clear error", Fixture, NULL, setup, test_qof_session_clear_error, teardown); 00999 GNC_TEST_ADD (suitename, "qof session close hooks", Fixture, NULL, setup, test_qof_session_close_hooks, teardown); 01000 }
1.7.4