10 #include <sys/types.h>
12 #include <glib/gstdio.h>
15 #include <unittest-support.h>
16 #include <test-stuff.h>
17 #include <test-dbi-stuff.h>
18 #include <test-dbi-business-stuff.h>
32 #include "../gnc-backend-dbi-priv.h"
35 #include <qofsession-p.h>
37 #if LIBDBI_VERSION >= 900
38 #define HAVE_LIBDBI_R 1
39 static dbi_inst dbi_instance = NULL;
41 #define HAVE_LIBDBI_R 0
44 static const gchar* suitename =
"/backend/dbi";
45 void test_suite_gnc_backend_dbi (
void);
55 setup (
Fixture *fixture, gconstpointer pData)
57 gchar *url = (gchar *)pData;
58 fixture->session = qof_session_new();
67 qof_session_load (fixture->session, NULL);
69 if (g_strcmp0 (url,
"sqlite3") == 0)
70 fixture->filename = g_strdup_printf (
"/tmp/test-sqlite-%d", getpid());
72 fixture->filename = NULL;
76 setup_memory (
Fixture *fixture, gconstpointer pData)
79 gchar *url = (gchar*)pData;
88 session = qof_session_new();
90 root = gnc_book_get_root_account (book);
93 currency = gnc_commodity_table_lookup (table, GNC_COMMODITY_NS_CURRENCY,
"CAD");
100 frame = qof_instance_get_slots (QOF_INSTANCE(acct1));
125 fixture->session = session;
126 if (g_strcmp0 (url,
"sqlite3") == 0)
127 fixture->filename = g_strdup_printf (
"/tmp/test-sqlite-%d", getpid());
129 fixture->filename = NULL;
133 setup_business (
Fixture *fixture, gconstpointer pData)
136 gchar *url = (gchar*)pData;
138 Account* root = gnc_book_get_root_account (book);
150 currency = gnc_commodity_table_lookup (table, GNC_COMMODITY_NS_CURRENCY,
"CAD");
168 tt = gncTaxTableCreate (book);
169 gncTaxTableSetName (tt,
"tt");
170 tte = gncTaxTableEntryCreate();
171 gncTaxTableEntrySetAccount (tte, acct1);
173 gncTaxTableEntrySetAmount (tte, gnc_numeric_zero());
174 gncTaxTableAddEntry (tt, tte);
175 tte = gncTaxTableEntryCreate();
176 gncTaxTableEntrySetAccount (tte, acct2);
178 gncTaxTableEntrySetAmount (tte, gnc_numeric_zero());
179 gncTaxTableAddEntry (tt, tte);
181 cust = gncCustomerCreate (book);
182 gncCustomerSetID (cust,
"0001");
183 gncCustomerSetName (cust,
"MyCustomer");
184 gncCustomerSetNotes (cust,
"Here are some notes");
185 gncCustomerSetCurrency (cust, currency);
186 addr = gncAddressCreate (book, QOF_INSTANCE(cust));
187 gncAddressSetName (addr,
"theAddress");
188 gncAddressSetAddr1 (addr,
"Address line #1");
189 gncAddressSetAddr2 (addr,
"Address line #2");
190 gncAddressSetAddr3 (addr,
"Address line #3");
191 gncAddressSetAddr4 (addr,
"Address line #4");
192 gncAddressSetPhone (addr,
"(123) 555-1212");
193 gncAddressSetPhone (addr,
"(123) 555-2121");
196 emp = gncEmployeeCreate (book);
197 gncEmployeeSetID (emp,
"0001");
198 gncEmployeeSetUsername (emp,
"gnucash");
199 gncEmployeeSetLanguage (emp,
"english");
200 gncEmployeeSetCurrency (emp, currency);
202 fixture->session = session;
203 if (g_strcmp0 (url,
"sqlite3") == 0)
204 fixture->filename = g_strdup_printf (
"/tmp/test-sqlite-%d", getpid());
206 fixture->filename = NULL;
210 drop_table (gconstpointer tdata, gconstpointer cdata)
212 gchar *table = (gchar*)tdata;
213 dbi_conn conn = (dbi_conn)cdata;
214 gchar *query = g_strdup_printf (
"DROP TABLE %s", table);
215 dbi_result rslt = dbi_conn_query (conn, query);
220 destroy_database (gchar* url)
222 gchar *protocol = NULL;
224 gchar *dbname = NULL;
225 gchar *username = NULL;
226 gchar *password = NULL;
227 gchar *basename = NULL;
230 gchar *pgsql =
"pgsql";
231 dbi_conn conn = NULL;
232 gchar *errfmt =
"Unable to delete tables in %s: %s";
238 &username, &password, &dbname);
239 if (g_strcmp0 (protocol,
"postgres") == 0)
241 conn = dbi_conn_new_r( pgsql, dbi_instance );
243 conn = dbi_conn_new( pgsql );
247 conn = dbi_conn_new_r (protocol, dbi_instance);
249 conn = dbi_conn_new (protocol);
251 port = g_strdup_printf (
"%d", portnum);
254 g_printf (errfmt, url,
"failed to create connection");
257 fail = dbi_conn_set_option (conn,
"host", host);
258 if (!fail && portnum)
259 fail = dbi_conn_set_option (conn,
"port", port);
261 fail = dbi_conn_set_option (conn,
"dbname", dbname);
263 fail = dbi_conn_set_option (conn,
"username", username);
265 fail = dbi_conn_set_option (conn,
"password", password);
267 fail = dbi_conn_set_option (conn,
"encoding",
"UTF-8");
271 g_printf (errfmt, url,
"failed to set an option");
272 dbi_conn_close (conn);
275 fail = dbi_conn_connect (conn);
279 gint errnum = dbi_conn_error (conn, &error);
280 g_printf (errfmt, url, error);
281 dbi_conn_close (conn);
284 tables = dbi_conn_get_table_list (conn, dbname, NULL);
285 while (dbi_result_next_row (tables) != 0)
287 const gchar *table = dbi_result_get_string_idx (tables, 1);
288 list = g_slist_prepend (list, g_strdup (table));
290 dbi_result_free (tables);
291 g_slist_foreach (list, (GFunc)drop_table, (gpointer)conn);
292 g_slist_free_full (list, (GDestroyNotify)g_free);
296 teardown (
Fixture *fixture, gconstpointer pData)
298 gchar *lockfile = g_strdup_printf (
"%s/test-dbi.xml.LCK",
299 g_path_get_dirname (DBI_TEST_XML_FILENAME));
300 gchar *msg = g_strdup_printf (
"[xml_session_end()] Error on g_unlink(%s): 2: No such file or directory", lockfile);
301 gchar *logdomain =
"gnc.backend";
302 guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
303 TestErrorStruct *check = test_error_struct_new (logdomain, loglevel, msg);
304 fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
305 (GLogFunc)test_checked_handler);
307 qof_session_destroy (fixture->session);
308 if (fixture->filename)
310 g_unlink (fixture->filename);
311 g_free (fixture->filename);
314 destroy_database ((gchar*)pData);
318 g_slist_free_full (fixture->hdlrs, test_free_log_handler);
319 test_clear_error_list();
328 GSList *index_list, *iter;
330 index_list = conn->provider->get_index_list (be->conn);
331 g_test_message (
"Returned from index list\n");
332 g_assert (index_list != NULL);
333 g_assert_cmpint (g_slist_length (index_list), ==, 4);
334 for (iter = index_list; iter != NULL; iter = g_slist_next (iter))
337 conn->provider->drop_index (be->conn, iter->data);
338 g_assert (DBI_ERROR_NONE == dbi_conn_error (conn->conn, &errmsg));
341 g_slist_free (index_list);
348 test_dbi_store_and_reload (
Fixture *fixture, gconstpointer pData)
351 const gchar* url = (
const gchar*)pData;
356 gchar *msg =
"[gnc_dbi_unlock()] There was no lock entry in the Lock table";
357 gchar *log_domain =
"gnc.backend.dbi";
358 guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
359 TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg);
360 fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
361 (GLogFunc)test_checked_handler);
362 if (fixture->filename)
363 url = fixture->filename;
366 session_2 = qof_session_new();
368 g_assert (session_2 != NULL);
372 g_assert (session_2 != NULL);
376 session_3 = qof_session_new();
377 g_assert (session_3 != NULL);
379 g_assert (session_3 != NULL);
381 qof_session_load (session_3, NULL);
382 g_assert (session_3 != NULL);
389 qof_session_destroy (session_2);
391 qof_session_destroy (session_3);
402 test_dbi_safe_save (
Fixture *fixture, gconstpointer pData)
404 gchar *url = (gchar*)pData;
405 QofSession *session_1 = NULL, *session_2 = NULL;
408 gchar *msg =
"[gnc_dbi_unlock()] There was no lock entry in the Lock table";
409 gchar *log_domain =
"gnc.backend.dbi";
410 guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
411 TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg);
413 if (fixture->filename)
414 url = fixture->filename;
417 session_1 = qof_session_new ();
423 qof_session_get_error_message (session_1));
424 g_test_message (
"DB Session Creation Failed");
434 g_warning (
"Session Error: %s",
435 qof_session_get_error_message(session_1));
436 g_test_message (
"DB Session Safe Save Failed");
442 session_2 = qof_session_new ();
448 qof_session_get_error_message(session_2));
449 g_test_message (
"DB Session re-creation Failed");
453 qof_session_load (session_2, NULL);
457 test_conn_index_functions (be);
460 fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
461 (GLogFunc)test_checked_handler);
462 if (session_2 != NULL)
465 qof_session_destroy (session_2);
467 if (session_1 != NULL)
470 qof_session_destroy (session_1);
479 test_dbi_version_control (
Fixture *fixture, gconstpointer pData)
481 gchar *url = (gchar*)pData;
486 gint ourversion = gnc_prefs_get_long_version();
489 if (fixture->filename)
490 url = fixture->filename;
491 sess = qof_session_new();
496 qof_session_get_error_message(sess));
497 g_test_message (
"DB Session Creation Failed");
503 qbe = qof_session_get_backend (sess);
505 qof_book_begin_edit (book);
507 "Gnucash", GNUCASH_RESAVE_VERSION - 1);
508 qof_book_commit_edit (book);
510 qof_session_destroy (sess);
511 sess = qof_session_new();
513 qof_session_load (sess, NULL);
516 qbe = qof_session_get_backend (sess);
518 qof_book_begin_edit (book);
520 "Gnucash", ourversion);
522 "Gnucash-Resave", ourversion + 1);
523 qof_book_commit_edit (book);
525 qof_session_destroy (sess);
526 sess = qof_session_new();
528 qof_session_load (sess, NULL);
533 qbe = qof_session_get_backend (sess);
535 qof_book_begin_edit (book);
537 "Gnucash-Resave", GNUCASH_RESAVE_VERSION);
538 qof_book_commit_edit (book);
540 qof_session_destroy (sess);
544 test_dbi_business_store_and_reload (
Fixture *fixture, gconstpointer pData)
548 const gchar* url = (gchar*)pData;
550 gchar *msg =
"[gnc_dbi_unlock()] There was no lock entry in the Lock table";
551 gchar *log_domain =
"gnc.backend.dbi";
552 guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
553 TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg);
554 if (fixture->filename)
555 url = fixture->filename;
557 session_2 = qof_session_new();
563 session_3 = qof_session_new();
565 qof_session_load (session_3, NULL);
570 qof_session_destroy (session_2);
572 fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
573 (GLogFunc)test_checked_handler);
575 qof_session_destroy (session_3);
579 create_dbi_test_suite (gchar *dbm_name, gchar *url)
581 gchar *subsuite = g_strdup_printf (
"%s/%s", suitename, dbm_name);
582 GNC_TEST_ADD (subsuite,
"store_and_reload",
Fixture, url, setup,
583 test_dbi_store_and_reload, teardown);
584 GNC_TEST_ADD (subsuite,
"safe_save",
Fixture, url, setup_memory,
585 test_dbi_safe_save, teardown);
586 GNC_TEST_ADD (subsuite,
"version_control",
Fixture, url, setup_memory,
587 test_dbi_version_control, teardown);
588 GNC_TEST_ADD (subsuite,
"business_store_and_reload",
Fixture, url,
589 setup_business, test_dbi_version_control, teardown);
595 test_suite_gnc_backend_dbi (
void)
597 dbi_driver driver = NULL;
598 GList *drivers = NULL;
600 if (dbi_instance == NULL)
601 dbi_initialize_r (NULL, &dbi_instance);
602 while ((driver = dbi_driver_list_r (driver, dbi_instance)))
604 dbi_initialize (NULL);
605 while ((driver = dbi_driver_list (driver)))
608 drivers = g_list_prepend (drivers,
609 (gchar*)dbi_driver_get_name (driver));
611 if (g_list_find_custom (drivers,
"sqlite3", (GCompareFunc)g_strcmp0))
612 create_dbi_test_suite (
"sqlite3",
"sqlite3");
613 if (strlen (TEST_MYSQL_URL) > 0 &&
614 g_list_find_custom (drivers,
"mysql", (GCompareFunc)g_strcmp0))
615 create_dbi_test_suite (
"mysql", TEST_MYSQL_URL);
616 if (strlen (TEST_PGSQL_URL) > 0 &&
617 g_list_find_custom (drivers,
"pgsql", (GCompareFunc)g_strcmp0))
619 g_setenv (
"PGOPTIONS",
"-c client_min_messages=WARNING", FALSE);
620 create_dbi_test_suite (
"postgres", TEST_PGSQL_URL);
void xaccAccountSetType(Account *acc, GNCAccountType tip)
#define xaccTransAppendSplit(t, s)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Transaction * xaccMallocTransaction(QofBook *book)
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
void kvp_frame_set_timespec(KvpFrame *frame, const gchar *path, Timespec ts)
void gnc_account_append_child(Account *new_parent, Account *child)
const GncGUID * qof_instance_get_guid(gconstpointer)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
void qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
void kvp_frame_set_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
API for Transactions and Splits (journal entries)
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
QofBook * qof_session_get_book(const QofSession *session)
Account handling public routines.
void xaccAccountSetPlaceholder(Account *acc, gboolean val)
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
QofBackendError qof_session_pop_error(QofSession *session)
void gnc_uri_get_components(const gchar *uri, gchar **protocol, gchar **hostname, gint32 *port, gchar **username, gchar **password, gchar **path)
void kvp_frame_set_numeric(KvpFrame *frame, const gchar *path, gnc_numeric nval)
QofBackendError qof_session_get_error(QofSession *session)
void qof_session_swap_data(QofSession *session_1, QofSession *session_2)
void xaccTransCommitEdit(Transaction *trans)
void xaccTransBeginEdit(Transaction *trans)
Split * xaccMallocSplit(QofBook *book)
Generic api to store and retrieve preferences.
API for the transaction logger.
Business Invoice Interface.
void qof_session_begin(QofSession *session, const char *book_id, gboolean ignore_lock, gboolean create, gboolean force)
void kvp_frame_set_double(KvpFrame *frame, const gchar *path, double dval)
void xaccAccountSetHidden(Account *acc, gboolean val)
Timespec timespec_now(void)
void qof_session_ensure_all_data_loaded(QofSession *session)
struct KvpFrameImpl KvpFrame
Account * xaccMallocAccount(QofBook *book)
Utility functions for convert uri in separate components and back.
void qof_session_end(QofSession *session)
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
API for Transactions and Splits (journal entries)
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
void xaccAccountSetName(Account *acc, const char *str)
Commodity handling public routines.
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)