2001-10-16 Dave Peticolas <dave@krondo.com>

* src/engine/test-core/test-engine-stuff.c: work on test
	infrastructure for making changes to existing data

	* src/engine/gnc-book.c: keep backends up to date

	* src/engine/gnc-session.c: keep backends up to date

	* src/backend/postgres/test/db-control.sh: bring down postmaster
	on database create and destroy

	* src/backend/postgres/test/test-db.c: work on single-update
	test

	* src/backend/postgres/txn.c: fix bug -- when deleting splits
	from the database that aren't in the engine, can't use
	xaccSplitLookup.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5661 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2001-10-16 09:13:07 +00:00
parent b066e9cd63
commit 9afc2fc598
8 changed files with 459 additions and 27 deletions

View File

@ -1,3 +1,22 @@
2001-10-16 Dave Peticolas <dave@krondo.com>
* src/engine/test-core/test-engine-stuff.c: work on test
infrastructure for making changes to existing data
* src/engine/gnc-book.c: keep backends up to date
* src/engine/gnc-session.c: keep backends up to date
* src/backend/postgres/test/db-control.sh: bring down postmaster
on database create and destroy
* src/backend/postgres/test/test-db.c: work on single-update
test
* src/backend/postgres/txn.c: fix bug -- when deleting splits
from the database that aren't in the engine, can't use
xaccSplitLookup.
2001-10-14 Joshua Sled <jsled@asynchronous.org>
* src/gnome/dialog-scheduledxaction.c (delete_button_clicked):
@ -22,7 +41,6 @@
* src/app-utils/prefs.scm: Updates to wording, defaults for
Scheduled Transaction preferences.
2001-10-14 Rob Browning <rlb@defaultvalue.org>
* src/backend/file/test/Makefile.am

View File

@ -8,10 +8,12 @@ PG_CTL="pg_ctl -D $DB -o -p7777"
case $1 in
create)
$PG_CTL status | grep "pid" && $PG_CTL stop
rm -rf $DB
initdb $DB || EXIT_VALUE=1
;;
destroy)
$PG_CTL status | grep "pid" && $PG_CTL stop
rm -rf $DB
;;
start)

View File

@ -201,6 +201,100 @@ test_access (const char *db_name, const char *mode, gboolean multi_user)
return TRUE;
}
static gboolean
test_updates (GNCSession *session, const char *db_name, const char *mode,
gboolean multi_user)
{
GNCBackendError io_err;
GNCSession *session_2;
char *filename;
gboolean ok;
g_return_val_if_fail (session && db_name && mode, FALSE);
filename = db_file_url (db_name, mode);
gnc_session_begin (session, filename, FALSE, FALSE);
io_err = gnc_session_get_error (session);
if (!do_test_args (io_err == ERR_BACKEND_NO_ERR,
"Beginning db update session",
__FILE__, __LINE__,
"can't begin session for %s in mode %s",
db_name, mode))
return FALSE;
/* make_random_changes_to_session (session); */
{
Account *account;
account = xaccGroupGetAccount (gnc_book_get_group (gnc_session_get_book (session)), 0);
if (account)
{
xaccAccountBeginEdit (account);
switch (xaccAccountGetType (account))
{
case BANK:
xaccAccountSetType (account, CHECKING);
break;
default:
xaccAccountSetType (account, BANK);
break;
}
xaccAccountCommitEdit (account);
}
else
failure ("no account");
}
if (!multi_user)
{
gnc_session_end (session);
io_err = gnc_session_get_error (session);
if (!do_test_args (io_err == ERR_BACKEND_NO_ERR,
"Ending db session",
__FILE__, __LINE__,
"can't end session for %s in mode %s",
db_name, mode))
return FALSE;
}
session_2 = gnc_session_new ();
if (!load_db_file (session_2, db_name, mode))
return FALSE;
ok = gnc_book_equal (gnc_session_get_book (session),
gnc_session_get_book (session_2));
do_test_args (ok, "Books equal after update", __FILE__, __LINE__,
"Books not equal for session %s in mode %s",
db_name, mode);
if (!ok)
{
save_xml_files (session, session_2);
return FALSE;
}
if (multi_user)
{
gnc_session_end (session);
io_err = gnc_session_get_error (session);
if (!do_test_args (io_err == ERR_BACKEND_NO_ERR,
"Ending db session",
__FILE__, __LINE__,
"can't end session for %s in mode %s",
db_name, mode))
return FALSE;
}
gnc_session_destroy (session_2);
g_free (filename);
}
static gboolean
test_mode (const char *db_name, const char *mode,
gboolean updates, gboolean multi_user)
@ -237,6 +331,9 @@ test_mode (const char *db_name, const char *mode,
ok = test_access (db_name, mode, multi_user);
if (updates && !test_updates (session_db, db_name, mode, multi_user))
return FALSE;
gnc_session_destroy (session);
gnc_session_destroy (session_db);
@ -249,7 +346,7 @@ run_test (void)
if (!test_mode ("single_file", "single-file", FALSE, FALSE))
return;
if (!test_mode ("single_update", "single-update", FALSE, FALSE))
if (!test_mode ("single_update", "single-update", TRUE, FALSE))
return;
}
@ -259,7 +356,7 @@ guile_main (int argc, char **argv)
gnc_module_system_init ();
gnc_module_load ("gnucash/engine", 0);
g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
/* g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); */
glist_exclude_type (KVP_TYPE_BINARY);
glist_exclude_type (KVP_TYPE_GLIST);
@ -287,8 +384,6 @@ guile_main (int argc, char **argv)
int
main (int argc, char ** argv)
{
/* getchar (); */
gh_enter (argc, argv, guile_main);
return 0;

View File

@ -97,6 +97,13 @@ is_trans_empty (Transaction *trans)
* it locks the tables appropriately.
*/
typedef struct
{
GUID guid;
char *guid_str;
guint32 iguid;
} DeleteTransInfo;
static gpointer
delete_list_cb (PGBackend *be, PGresult *result, int j, gpointer data)
{
@ -104,13 +111,22 @@ delete_list_cb (PGBackend *be, PGresult *result, int j, gpointer data)
GUID guid = nullguid;
string_to_guid (DB_GET_VAL ("entryGuid", j), &guid);
/* If the database has splits that the engine doesn't,
* collect 'em up & we'll have to delete em */
if (NULL == xaccSplitLookup (&guid, be->session))
{
deletelist = g_list_prepend (deletelist,
g_strdup(DB_GET_VAL ("entryGuid", j)));
DeleteTransInfo *dti;
dti = g_new (DeleteTransInfo, 1);
dti->guid = guid;
dti->guid_str = g_strdup (DB_GET_VAL ("entryGuid", j));
dti->iguid = atoi (DB_GET_VAL ("iguid", j));
deletelist = g_list_prepend (deletelist, dti);
}
return deletelist;
}
@ -136,7 +152,7 @@ pgendStoreTransactionNoLock (PGBackend *be, Transaction *trans,
* since what is there may not match what we have cached in
* the engine. */
p = be->buff; *p = 0;
p = stpcpy (p, "SELECT entryGuid FROM gncEntry WHERE transGuid='");
p = stpcpy (p, "SELECT entryGuid, iguid FROM gncEntry WHERE transGuid='");
p = guid_to_string_buff(xaccTransGetGUID(trans), p);
p = stpcpy (p, "';");
@ -147,16 +163,28 @@ pgendStoreTransactionNoLock (PGBackend *be, Transaction *trans,
p = be->buff; *p = 0;
for (node=deletelist; node; node=node->next)
{
Split *s;
GUID guid;
string_to_guid ((char *)(node->data), &guid);
s = xaccSplitLookup(&guid, be->session);
pgendStoreAuditSplit (be, s, SQL_DELETE);
DeleteTransInfo *dti = node->data;
GList *split_node;
/* find the old split in the saved original */
if (trans->orig && trans->orig->splits)
for (split_node = trans->orig->splits; split_node;
split_node = split_node->next)
{
Split *s = split_node->data;
if (s && guid_equal (&s->guid, &dti->guid))
{
pgendStoreAuditSplit (be, s, SQL_DELETE);
break;
}
}
p = stpcpy (p, "DELETE FROM gncEntry WHERE entryGuid='");
p = stpcpy (p, node->data);
p = stpcpy (p, dti->guid_str);
p = stpcpy (p, "';\n");
}
if (p != be->buff)
{
PINFO ("%s", be->buff ? be->buff : "(null)");
@ -166,15 +194,22 @@ pgendStoreTransactionNoLock (PGBackend *be, Transaction *trans,
/* destroy any associated kvp data as well */
for (node=deletelist; node; node=node->next)
{
Split *s;
GUID guid;
string_to_guid ((char *)(node->data), &guid);
s = xaccSplitLookup(&guid, be->session);
pgendKVPDelete (be, s->idata);
g_free (node->data);
DeleteTransInfo *dti = node->data;
pgendKVPDelete (be, dti->iguid);
}
}
for (node = deletelist; node; node = node->next)
{
DeleteTransInfo *dti = node->data;
g_free (dti->guid_str);
g_free (dti);
}
g_list_free (deletelist);
deletelist = NULL;
/* Update the rest */
start = xaccTransGetSplitList(trans);

View File

@ -126,6 +126,8 @@ gnc_book_set_group (GNCBook *book, AccountGroup *grp)
xaccGroupSetBook (grp, book);
book->topgroup = grp;
xaccGroupSetBackend (grp, book->backend);
}
void
@ -133,6 +135,7 @@ gnc_book_set_backend (GNCBook *book, Backend *be)
{
if (!book) return;
book->backend = be;
xaccGroupSetBackend (book->topgroup, be);
xaccPriceDBSetBackend (book->pricedb, be);
}
@ -168,7 +171,9 @@ void
gnc_book_set_pricedb(GNCBook *book, GNCPriceDB *db)
{
if(!book) return;
book->pricedb = db;
xaccPriceDBSetBackend (db, book->backend);
}
/* ---------------------------------------------------------------------- */
@ -184,6 +189,7 @@ void
gnc_book_set_schedxactions( GNCBook *book, GList *newList )
{
if ( book == NULL ) return;
book->sched_xactions = newList;
book->sx_notsaved = TRUE;
}
@ -207,6 +213,8 @@ gnc_book_set_template_group (GNCBook *book, AccountGroup *templateGroup)
xaccGroupSetBook (templateGroup, book);
book->template_group = templateGroup;
xaccGroupSetBackend (templateGroup, book->backend);
}
Backend *
@ -241,7 +249,7 @@ gnc_book_mark_saved(GNCBook *book)
xaccGroupMarkSaved(gnc_book_get_group(book));
gnc_pricedb_mark_clean(gnc_book_get_pricedb(book));
xaccGroupMarkSaved(gnc_book_get_template_group(book));
book_sxns_mark_saved(book);
}

View File

@ -156,6 +156,8 @@ gnc_session_set_book (GNCSession *session, GNCBook *book)
return;
session->book = book;
gnc_book_set_backend (book, session->backend);
}
GNCEntityTable *
@ -215,24 +217,30 @@ gnc_session_load_backend(GNCSession * session, char * backend_name)
/* FIXME: this needs to be smarter with version numbers. */
mod = gnc_module_load(mod_name, 0);
if(mod)
if (mod)
{
be_new_func = gnc_module_lookup(mod, "gnc_backend_new");
if(be_new_func)
{
session->backend = be_new_func();
gnc_book_set_backend (session->book, session->backend);
}
else
else
{
gnc_session_int_backend_load_error(session, " can't find backend_new ",
"");
"");
}
}
else
else
{
gnc_session_int_backend_load_error(session, " failed to load '%s' backend",
backend_name);
gnc_session_int_backend_load_error(session,
" failed to load '%s' backend",
backend_name);
}
g_free(mod_name);
}
@ -615,6 +623,9 @@ gnc_session_swap_data (GNCSession *session_1, GNCSession *session_2)
session_2->book = book_1;
session_2->entity_table = entity_table_1;
gnc_book_set_backend (book_1, session_2->backend);
gnc_book_set_backend (book_2, session_1->backend);
}
gboolean

View File

@ -26,6 +26,8 @@ static gint max_group_depth = 4;
static gint max_group_accounts = 10;
static kvp_value* get_random_kvp_value_depth (int type, gint depth);
static gpointer get_random_list_element (GList *list);
static void add_random_splits(GNCSession *session, Transaction *trn);
/***********************************************************************/
@ -481,6 +483,174 @@ get_random_group (GNCSession *session)
return get_random_group_depth (session, depth);
}
typedef struct
{
GUID guid;
} TransInfo;
static void
change_trans_helper (GNCSession *session, Transaction *trans, GList *accounts)
{
GList *splits;
GList *node;
Split *split;
xaccTransBeginEdit (trans);
make_random_changes_to_transaction (session, trans);
switch (get_random_int_in_range (0, 6))
{
case 0: /* delete some splits, add some more */
do
{
split = xaccTransGetSplit (trans, 0);
xaccSplitDestroy (split);
} while (split);
add_random_splits (session, trans);
/* fall through */
case 1: /* move the splits around */
splits = xaccTransGetSplitList (trans);
for (node = splits; node; node = node->next)
{
Split *split = node->data;
Account *account;
account = get_random_list_element (accounts);
xaccAccountInsertSplit (account, split);
}
break;
case 2: /* destroy the transaction */
xaccTransDestroy (trans);
xaccTransCommitEdit (trans);
return;
default: /* do nothing */
break;
}
/* mess with the splits */
splits = xaccTransGetSplitList (trans);
for (node = splits; node; node = node->next)
{
Split *split = node->data;
if (get_random_boolean ())
make_random_changes_to_split (split);
}
xaccTransCommitEdit (trans);
}
static gboolean
add_trans_helper (Transaction *trans, gpointer data)
{
TransInfo *ti;
GList **list = data;
ti = g_new (TransInfo, 1);
ti->guid = *xaccTransGetGUID (trans);
*list = g_list_prepend (*list, ti);
return TRUE;
}
void
make_random_changes_to_group (GNCSession *session, AccountGroup *group)
{
Account *new_account;
Account *account;
GList *accounts;
GList *transes;
GList *splits;
GList *node;
g_return_if_fail (group && session);
accounts = xaccGroupGetSubAccounts (group);
/* Add a new account */
new_account = get_random_account (session);
if (get_random_boolean ())
xaccGroupInsertAccount (group, new_account);
else
{
account = get_random_list_element (accounts);
xaccAccountInsertSubAccount (account, new_account);
}
/* Mess with the accounts */
for (node = accounts; node; node = node->next)
{
Account *account = node->data;
if (get_random_boolean ())
make_random_changes_to_account (session, account);
}
/* Mess with the transactions & splits */
transes = NULL;
xaccGroupForEachTransaction (group, add_trans_helper, &transes);
for (node = transes; node; node = node->next)
{
TransInfo *ti = node->data;
Transaction *trans = xaccTransLookup (&ti->guid, session);
if (!trans)
continue;
g_warning ("got one");
change_trans_helper (session, trans, accounts);
}
for (node = transes; node; node = node->next)
{
TransInfo *ti = node->data;
g_free (ti);
}
g_list_free (transes);
transes = NULL;
/* delete an account */
account = get_random_list_element (accounts);
splits = xaccAccountGetSplitList (account);
splits = g_list_copy (splits);
for (node = splits; node; node = node->next)
{
Split *split = node->data;
do
{
new_account = get_random_list_element (accounts);
} while (new_account == account);
xaccAccountInsertSplit (new_account, split);
}
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
g_list_free (splits);
g_list_free (accounts);
/* TODO: move some accounts around */
}
Account*
get_random_account(GNCSession *session)
{
@ -508,6 +678,30 @@ get_random_account(GNCSession *session)
return ret;
}
void
make_random_changes_to_account (GNCSession *session, Account *account)
{
int tmp_int;
g_return_if_fail (account);
xaccAccountBeginEdit (account);
set_account_random_string (account, xaccAccountSetName);
tmp_int = get_random_int_in_range (BANK, CREDITLINE);
xaccAccountSetType (account, tmp_int);
set_account_random_string (account, xaccAccountSetCode);
set_account_random_string (account, xaccAccountSetDescription);
xaccAccountSetCommodity (account, get_random_commodity(session));
xaccAccountSetSlots_nc (account, get_random_kvp_frame());
xaccAccountCommitEdit (account);
}
static void
set_split_random_string(Split *spl,
void(*func)(Split *act, const gchar*str))
@ -557,7 +751,28 @@ get_random_split(GNCSession *session, gnc_numeric num)
void
make_random_changes_to_split (Split *split)
{
Transaction *trans;
g_return_if_fail (split);
trans = xaccSplitGetParent (split);
xaccTransBeginEdit (trans);
set_split_random_string (split, xaccSplitSetMemo);
set_split_random_string (split, xaccSplitSetAction);
xaccSplitSetReconcile (split, possible_chars[get_random_int_in_range(0, 4)]);
xaccSplitSetDateReconciledTS (split, get_random_timespec());
xaccSplitSetSlots_nc (split, get_random_kvp_frame());
/* Don't change share values/prices here, since that would
* throw transactions out of balance. Do that in the corresponding
* change transaction function. */
xaccTransCommitEdit (trans);
}
static void
@ -629,6 +844,32 @@ get_random_transaction (GNCSession *session)
return get_random_transaction_with_currency (session, NULL);
}
void
make_random_changes_to_transaction (GNCSession *session, Transaction *trans)
{
GList *list;
GList *node;
g_return_if_fail (trans && session);
xaccTransBeginEdit (trans);
xaccTransSetCurrency (trans, get_random_commodity (session));
set_tran_random_string (trans, xaccTransSetNum);
trn_add_ran_timespec (trans, xaccTransSetDatePostedTS);
trn_add_ran_timespec (trans, xaccTransSetDateEnteredTS);
set_tran_random_string (trans, xaccTransSetDescription);
xaccTransSetSlots_nc (trans, get_random_kvp_frame());
/* Do split manipulations in higher-level functions */
xaccTransCommitEdit (trans);
}
static gpointer
get_random_list_element (GList *list)
{
@ -986,3 +1227,19 @@ add_random_transactions_to_session (GNCSession *session, gint num_transactions)
g_list_free (accounts);
}
void
make_random_changes_to_book (GNCSession *session, GNCBook *book)
{
g_return_if_fail (session && book);
make_random_changes_to_group (session, gnc_book_get_group (book));
}
void
make_random_changes_to_session (GNCSession *session)
{
g_return_if_fail (session);
make_random_changes_to_book (session, gnc_session_get_book (session));
}

View File

@ -60,5 +60,11 @@ void add_random_transactions_to_session (GNCSession *session,
gint num_transactions);
void make_random_changes_to_split (Split *split);
void make_random_changes_to_transaction (GNCSession *session,
Transaction *trans);
void make_random_changes_to_account (GNCSession *session, Account *account);
void make_random_changes_to_group (GNCSession *session, AccountGroup *group);
void make_random_changes_to_book (GNCSession *session, GNCBook *book);
void make_random_changes_to_session (GNCSession *session);
#endif