2004-07-03 10:29:39 -05:00
|
|
|
/**
|
|
|
|
* @file test-engine-stuff.c
|
|
|
|
* @brief tools to set up random, but finanically consistent books.
|
|
|
|
* Create transactions with random values, random accounts, random
|
|
|
|
* account heirarchies, etc.
|
|
|
|
*
|
2004-07-06 21:42:44 -05:00
|
|
|
* XXX We should modify routines to create really, ugly, dirty
|
2010-02-17 23:31:54 -06:00
|
|
|
* transactions
|
|
|
|
* -- 3 or more splits (TBD)
|
2004-07-06 21:42:44 -05:00
|
|
|
* -- splits without parent accounts (done)
|
|
|
|
* -- splits that have accounts but aren't in a transaction (TBD)
|
|
|
|
* -- splits that share a currency with the transaction, but whose
|
|
|
|
* value doesn't equal amount (done)
|
2004-07-05 22:46:41 -05:00
|
|
|
*
|
2004-07-03 10:29:39 -05:00
|
|
|
* Created by Linux Developers Group, 2001
|
|
|
|
* Updates Linas Vepstas July 2004
|
|
|
|
*/
|
2001-08-17 19:13:45 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
2002-01-30 01:38:35 -06:00
|
|
|
#include <sys/types.h>
|
2001-08-17 19:13:45 -05:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
#include "Account.h"
|
2003-10-16 23:25:53 -05:00
|
|
|
#include "AccountP.h"
|
2001-08-23 20:13:04 -05:00
|
|
|
#include "gnc-engine.h"
|
2007-01-19 17:45:45 -06:00
|
|
|
#include "gnc-session.h"
|
2002-01-02 14:53:29 -06:00
|
|
|
#include "Transaction.h"
|
2003-10-16 23:25:53 -05:00
|
|
|
#include "TransactionP.h"
|
2007-02-18 18:14:53 -06:00
|
|
|
#include "Recurrence.h"
|
2007-01-19 17:45:45 -06:00
|
|
|
#include "SchedXaction.h"
|
|
|
|
#include "SX-book.h"
|
2001-11-25 03:10:17 -06:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
#include "test-engine-stuff.h"
|
|
|
|
#include "test-stuff.h"
|
2005-12-29 22:36:38 -06:00
|
|
|
#include "test-engine-strings.h"
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2001-09-28 19:08:44 -05:00
|
|
|
static gboolean glist_strings_only = FALSE;
|
2001-09-27 19:15:49 -05:00
|
|
|
|
2001-09-29 05:03:38 -05:00
|
|
|
static GHashTable *exclude_kvp_types = NULL;
|
2001-10-15 19:50:01 -05:00
|
|
|
static gint kvp_max_depth = 5;
|
2001-09-29 05:03:38 -05:00
|
|
|
static gint kvp_frame_max_elements = 10;
|
|
|
|
|
2007-02-22 19:23:31 -06:00
|
|
|
static gint max_tree_depth = 1;
|
|
|
|
static gint max_level_accounts = 3;
|
2005-12-29 22:36:38 -06:00
|
|
|
static gint max_total_accounts = 10;
|
|
|
|
static gint max_trans_num = 1000;
|
2004-06-06 22:05:35 -05:00
|
|
|
static gint total_num_accounts = 0;
|
2005-12-29 22:36:38 -06:00
|
|
|
/* SCU == smallest currency unit -- the value of the denominator */
|
|
|
|
static gint max_scu = 100; //6000;
|
|
|
|
static gint min_scu = 100; //1;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* The inverse fraction of split/transaction data that should
|
|
|
|
* contain invalid/inconsistent fields/values. Thus,
|
2004-07-06 09:24:09 -05:00
|
|
|
* if borked==1000, then one in 1000 fields will have bad data.
|
2010-02-17 23:31:54 -06:00
|
|
|
* This is used to test the data integrity scrubbers, which are
|
2004-07-06 09:24:09 -05:00
|
|
|
* supposed to clean up any crud they find.
|
|
|
|
*/
|
2004-07-06 21:42:44 -05:00
|
|
|
static gint borked = 80;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2003-09-09 19:01:54 -05:00
|
|
|
gboolean gnc_engine_debug_random = FALSE;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
/* ========================================================== */
|
|
|
|
/* Set control parameters governing the run. */
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2001-10-01 03:24:07 -05:00
|
|
|
void
|
2007-02-22 19:23:31 -06:00
|
|
|
set_max_account_tree_depth (gint max_tree_depth_in)
|
2001-10-01 03:24:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
max_tree_depth = MAX (max_tree_depth_in, 1);
|
2001-10-01 03:24:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-02-22 19:23:31 -06:00
|
|
|
set_max_accounts_per_level (gint max_level_accounts_in)
|
2001-10-01 03:24:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
max_level_accounts = MAX (max_level_accounts_in, 1);
|
2001-10-01 03:24:07 -05:00
|
|
|
}
|
|
|
|
|
2001-09-29 05:03:38 -05:00
|
|
|
void
|
|
|
|
set_max_kvp_depth (gint max_kvp_depth)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
kvp_max_depth = MAX (max_kvp_depth, 1);
|
2001-09-29 05:03:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
set_max_kvp_frame_elements (gint max_kvp_frame_elements)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
kvp_frame_max_elements = MAX (max_kvp_frame_elements, 1);
|
2001-09-29 05:03:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-27 18:33:00 -05:00
|
|
|
kvp_exclude_type (KvpValueType kvp_type)
|
2001-09-29 05:03:38 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
gint *key;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!exclude_kvp_types)
|
|
|
|
exclude_kvp_types = g_hash_table_new (g_int_hash, g_int_equal);
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
key = g_new (gint, 1);
|
|
|
|
*key = kvp_type;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_hash_table_insert (exclude_kvp_types, key, exclude_kvp_types);
|
2001-09-29 05:03:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2003-06-27 18:33:00 -05:00
|
|
|
kvp_type_excluded (KvpValueType kvp_type)
|
2001-09-29 05:03:38 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
gint key = kvp_type;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!exclude_kvp_types)
|
|
|
|
return FALSE;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (g_hash_table_lookup (exclude_kvp_types, &key))
|
|
|
|
return TRUE;
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return FALSE;
|
2001-09-29 05:03:38 -05:00
|
|
|
}
|
|
|
|
|
2001-09-28 19:08:44 -05:00
|
|
|
void
|
|
|
|
random_glist_strings_only (gboolean strings_only)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
glist_strings_only = strings_only;
|
2001-09-28 19:08:44 -05:00
|
|
|
}
|
|
|
|
|
2001-10-13 03:09:30 -05:00
|
|
|
static gboolean zero_nsec = FALSE;
|
|
|
|
|
|
|
|
void
|
|
|
|
random_timespec_zero_nsec (gboolean zero_nsec_in)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
zero_nsec = zero_nsec_in;
|
2001-10-13 03:09:30 -05:00
|
|
|
}
|
|
|
|
|
2001-11-23 17:45:45 -06:00
|
|
|
static gboolean usec_resolution = FALSE;
|
|
|
|
|
|
|
|
void
|
|
|
|
random_timespec_usec_resolution (gboolean usec_resolution_in)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
usec_resolution = usec_resolution_in;
|
2001-11-23 17:45:45 -06:00
|
|
|
}
|
|
|
|
|
2004-07-06 21:42:44 -05:00
|
|
|
/* ========================================================== */
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
do_bork (void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
if (1 == get_random_int_in_range (0, borked))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
2004-07-06 21:42:44 -05:00
|
|
|
}
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
/* ========================================================== */
|
|
|
|
/* GList stuff */
|
|
|
|
|
|
|
|
static gpointer
|
|
|
|
get_random_list_element (GList *list)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_val_if_fail (list, NULL);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return g_list_nth_data (list,
|
|
|
|
get_random_int_in_range (0,
|
|
|
|
g_list_length (list) - 1));
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static kvp_value* get_random_kvp_value_depth (int type, gint depth);
|
|
|
|
|
|
|
|
static GList*
|
|
|
|
get_random_glist_depth (gint depth)
|
|
|
|
{
|
|
|
|
GList *ret = NULL;
|
|
|
|
int count = get_random_int_in_range(1, 5);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (depth >= kvp_max_depth)
|
2010-02-17 23:31:54 -06:00
|
|
|
return NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
KvpValueType kvpt;
|
2004-07-08 22:07:34 -05:00
|
|
|
KvpValue *value;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
kvpt = glist_strings_only ? KVP_TYPE_STRING : -2;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
value = get_random_kvp_value_depth (kvpt, depth + 1);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
while (!value);
|
|
|
|
|
|
|
|
ret = g_list_prepend(ret, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
GList*
|
|
|
|
get_random_glist(void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
return get_random_glist_depth (0);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ========================================================== */
|
2010-03-27 16:01:21 -05:00
|
|
|
/* Time/Date, GncGUID, binary data stuff */
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
Timespec*
|
|
|
|
get_random_timespec(void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Timespec *ret;
|
2001-11-23 17:45:45 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
ret = g_new0(Timespec, 1);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (ret->tv_sec <= 0)
|
|
|
|
ret->tv_sec = rand();
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (zero_nsec)
|
|
|
|
ret->tv_nsec = 0;
|
|
|
|
else
|
2001-11-23 17:45:45 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
ret->tv_nsec = rand();
|
|
|
|
|
|
|
|
if (usec_resolution)
|
|
|
|
{
|
|
|
|
ret->tv_nsec = MIN (ret->tv_nsec, 999999999);
|
|
|
|
ret->tv_nsec /= 1000;
|
|
|
|
ret->tv_nsec *= 1000;
|
|
|
|
}
|
2001-11-23 17:45:45 -06:00
|
|
|
}
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return ret;
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2010-03-27 16:01:21 -05:00
|
|
|
GncGUID*
|
2004-07-06 09:24:09 -05:00
|
|
|
get_random_guid(void)
|
|
|
|
{
|
2010-03-27 16:01:21 -05:00
|
|
|
GncGUID *ret;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-03-27 16:01:21 -05:00
|
|
|
ret = g_new(GncGUID, 1);
|
2004-07-06 09:24:09 -05:00
|
|
|
guid_new(ret);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bin_data*
|
|
|
|
get_random_binary_data(void)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
bin_data *ret;
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
len = get_random_int_in_range(20, 100);
|
2004-07-06 09:24:09 -05:00
|
|
|
ret = g_new(bin_data, 1);
|
2005-11-01 21:32:36 -06:00
|
|
|
ret->data = g_new(guchar, len);
|
2004-07-06 09:24:09 -05:00
|
|
|
ret->len = len;
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (len--; len >= 0; len--)
|
2004-07-06 09:24:09 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
ret->data[len] = (guchar)get_random_int_in_range(0, 255);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ========================================================== */
|
|
|
|
/* KVP stuff */
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
static KvpFrame* get_random_kvp_frame_depth (gint depth);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
static KvpValue*
|
2004-07-06 09:24:09 -05:00
|
|
|
get_random_kvp_value_depth (int type, gint depth)
|
|
|
|
{
|
|
|
|
int datype = type;
|
2005-11-01 21:32:36 -06:00
|
|
|
KvpValue *ret;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
if (datype == -1)
|
|
|
|
{
|
|
|
|
datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (datype == -2)
|
|
|
|
{
|
|
|
|
datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth)
|
2010-02-17 23:31:54 -06:00
|
|
|
return NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth)
|
2010-02-17 23:31:54 -06:00
|
|
|
return NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
if (kvp_type_excluded (datype))
|
2010-02-17 23:31:54 -06:00
|
|
|
return NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (datype)
|
2004-07-06 09:24:09 -05:00
|
|
|
{
|
|
|
|
case KVP_TYPE_GINT64:
|
2005-11-01 21:32:36 -06:00
|
|
|
ret = kvp_value_new_gint64(get_random_gint64());
|
2004-07-06 09:24:09 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KVP_TYPE_DOUBLE:
|
2005-11-01 21:32:36 -06:00
|
|
|
ret = NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KVP_TYPE_NUMERIC:
|
2005-11-01 21:32:36 -06:00
|
|
|
ret = kvp_value_new_gnc_numeric(get_random_gnc_numeric());
|
2004-07-06 09:24:09 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KVP_TYPE_STRING:
|
|
|
|
{
|
|
|
|
gchar *tmp_str;
|
|
|
|
tmp_str = get_random_string();
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!tmp_str)
|
|
|
|
return NULL;
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
ret = kvp_value_new_string(tmp_str);
|
|
|
|
g_free(tmp_str);
|
|
|
|
}
|
2010-02-17 23:31:54 -06:00
|
|
|
break;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
case KVP_TYPE_GUID:
|
|
|
|
{
|
2010-03-27 16:01:21 -05:00
|
|
|
GncGUID *tmp_guid;
|
2004-07-06 09:24:09 -05:00
|
|
|
tmp_guid = get_random_guid();
|
|
|
|
ret = kvp_value_new_guid(tmp_guid);
|
|
|
|
g_free(tmp_guid);
|
|
|
|
}
|
2010-02-17 23:31:54 -06:00
|
|
|
break;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
case KVP_TYPE_TIMESPEC:
|
|
|
|
{
|
|
|
|
Timespec *ts = get_random_timespec();
|
2005-11-01 21:32:36 -06:00
|
|
|
ret = kvp_value_new_timespec (*ts);
|
|
|
|
g_free(ts);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
2010-02-17 23:31:54 -06:00
|
|
|
break;
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
case KVP_TYPE_BINARY:
|
|
|
|
{
|
|
|
|
bin_data *tmp_data;
|
|
|
|
tmp_data = get_random_binary_data();
|
|
|
|
ret = kvp_value_new_binary(tmp_data->data, tmp_data->len);
|
|
|
|
g_free(tmp_data->data);
|
|
|
|
g_free(tmp_data);
|
|
|
|
}
|
2010-02-17 23:31:54 -06:00
|
|
|
break;
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
case KVP_TYPE_GLIST:
|
2005-11-01 21:32:36 -06:00
|
|
|
ret = kvp_value_new_glist_nc(get_random_glist_depth (depth + 1));
|
2004-07-06 09:24:09 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KVP_TYPE_FRAME:
|
|
|
|
{
|
2004-07-08 22:07:34 -05:00
|
|
|
KvpFrame *tmp_frame;
|
2004-07-06 09:24:09 -05:00
|
|
|
tmp_frame = get_random_kvp_frame_depth(depth + 1);
|
|
|
|
ret = kvp_value_new_frame(tmp_frame);
|
|
|
|
kvp_frame_delete(tmp_frame);
|
|
|
|
}
|
2010-02-17 23:31:54 -06:00
|
|
|
break;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
default:
|
2005-11-01 21:32:36 -06:00
|
|
|
ret = NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
break;
|
|
|
|
}
|
2005-11-01 21:32:36 -06:00
|
|
|
return ret;
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
static KvpFrame*
|
2004-07-06 09:24:09 -05:00
|
|
|
get_random_kvp_frame_depth (gint depth)
|
|
|
|
{
|
2004-07-08 22:07:34 -05:00
|
|
|
KvpFrame *ret;
|
2004-07-06 09:24:09 -05:00
|
|
|
int vals_to_add;
|
|
|
|
gboolean val_added;
|
|
|
|
|
|
|
|
if (depth >= kvp_max_depth)
|
2010-02-17 23:31:54 -06:00
|
|
|
return NULL;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
ret = kvp_frame_new();
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
vals_to_add = get_random_int_in_range(1, kvp_frame_max_elements);
|
2004-07-06 09:24:09 -05:00
|
|
|
val_added = FALSE;
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (; vals_to_add > 0; vals_to_add--)
|
2004-07-06 09:24:09 -05:00
|
|
|
{
|
|
|
|
gchar *key;
|
2004-07-08 22:07:34 -05:00
|
|
|
KvpValue *val;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
key = NULL;
|
|
|
|
while (key == NULL)
|
|
|
|
{
|
|
|
|
key = get_random_string_without("/");
|
|
|
|
if (*key == '\0')
|
|
|
|
{
|
|
|
|
g_free(key);
|
|
|
|
key = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
val = get_random_kvp_value_depth (-1, depth + 1);
|
|
|
|
if (!val)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
g_free(key);
|
|
|
|
if (!val_added)
|
|
|
|
vals_to_add++;
|
|
|
|
continue;
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
val_added = TRUE;
|
|
|
|
|
|
|
|
kvp_frame_set_slot_nc(ret, key, val);
|
|
|
|
|
|
|
|
g_free(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
KvpFrame *
|
2004-07-06 09:24:09 -05:00
|
|
|
get_random_kvp_frame (void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
return get_random_kvp_frame_depth (0);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
KvpValue *
|
2004-07-06 09:24:09 -05:00
|
|
|
get_random_kvp_value(int type)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
return get_random_kvp_value_depth (type, 0);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ================================================================= */
|
|
|
|
/* Numeric stuff */
|
|
|
|
|
2004-07-02 20:24:01 -05:00
|
|
|
#define RAND_IN_RANGE(X) (((X)*((gint64) (rand()+1)))/RAND_MAX)
|
2004-06-27 12:39:24 -05:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
gnc_numeric
|
|
|
|
get_random_gnc_numeric(void)
|
|
|
|
{
|
2004-07-02 20:24:01 -05:00
|
|
|
gint64 numer;
|
2004-06-27 12:39:24 -05:00
|
|
|
gint64 deno;
|
2004-06-06 22:05:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (RAND_MAX / 8 > rand())
|
2004-06-06 22:05:35 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Random number between 1 and 6000 */
|
|
|
|
deno = RAND_IN_RANGE(6000ULL);
|
2004-06-06 22:05:35 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
gint64 norm = RAND_IN_RANGE (7ULL);
|
2004-06-27 12:39:24 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* multiple of 10, between 1 and 1 million */
|
|
|
|
deno = 1;
|
|
|
|
while (norm)
|
|
|
|
{
|
|
|
|
deno *= 10;
|
|
|
|
norm --;
|
|
|
|
}
|
2004-06-06 22:05:35 -05:00
|
|
|
}
|
2004-07-02 20:24:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Arbitrary random numbers can cause pointless overflow
|
|
|
|
* during calculations. Limit dynamic range in hopes
|
2007-12-24 15:18:09 -06:00
|
|
|
* of avoiding overflow. Right now limit it to approx 2^48.
|
|
|
|
* The initial division is to help us down towards the range.
|
|
|
|
* The loop is to "make sure" we get there. We might
|
|
|
|
* want to make this dependent on "deno" in the future.
|
|
|
|
*/
|
2010-02-17 23:31:54 -06:00
|
|
|
do
|
|
|
|
{
|
|
|
|
numer = get_random_gint64() / 1000000;
|
|
|
|
}
|
|
|
|
while ((numer >> 31) > 0x1FFFF);
|
2004-07-03 10:29:39 -05:00
|
|
|
if (0 == numer) numer = 1;
|
2006-02-19 13:29:51 -06:00
|
|
|
/* Make sure we have a non-zero denominator */
|
|
|
|
if (0 == deno) deno = 1;
|
2004-06-06 22:05:35 -05:00
|
|
|
return gnc_numeric_create(numer, deno);
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
/* ================================================================= */
|
|
|
|
/* Commodity stuff */
|
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
const char *types[] =
|
|
|
|
{
|
|
|
|
"NASDAQ",
|
|
|
|
"NYSE",
|
|
|
|
"EUREX",
|
|
|
|
"FUND",
|
|
|
|
"AMEX",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
const char*
|
|
|
|
get_random_commodity_namespace(void)
|
|
|
|
{
|
|
|
|
return get_random_string_in_array(types);
|
|
|
|
}
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
static gnc_commodity *
|
|
|
|
get_random_commodity_from_table (gnc_commodity_table *table)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList *namespaces;
|
|
|
|
gnc_commodity *com = NULL;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_val_if_fail (table, NULL);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
namespaces = gnc_commodity_table_get_namespaces (table);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
do
|
|
|
|
{
|
|
|
|
GList *commodities;
|
|
|
|
char *namespace;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
namespace = get_random_list_element (namespaces);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
commodities = gnc_commodity_table_get_commodities (table, namespace);
|
|
|
|
if (!commodities)
|
|
|
|
continue;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
com = get_random_list_element (commodities);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (commodities);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
}
|
|
|
|
while (!com);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (namespaces);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return com;
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
gnc_commodity*
|
|
|
|
get_random_commodity (QofBook *book)
|
|
|
|
{
|
|
|
|
gnc_commodity *ret;
|
|
|
|
gchar *name;
|
|
|
|
const gchar *space;
|
|
|
|
gchar *mn;
|
2006-03-30 19:43:16 -06:00
|
|
|
gchar *cusip;
|
2004-07-06 09:24:09 -05:00
|
|
|
int ran_int;
|
|
|
|
gnc_commodity_table *table;
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
table = gnc_commodity_table_get_table (book);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (table &&
|
2010-02-17 23:31:54 -06:00
|
|
|
(gnc_commodity_table_get_size (table) > 0) &&
|
|
|
|
get_random_int_in_range (1, 5) < 5)
|
|
|
|
return get_random_commodity_from_table (table);
|
2004-07-06 09:24:09 -05:00
|
|
|
#endif
|
|
|
|
|
2006-03-30 19:43:16 -06:00
|
|
|
mn = get_random_string_length_in_range(1, 3);
|
2004-07-06 09:24:09 -05:00
|
|
|
space = get_random_commodity_namespace();
|
|
|
|
|
|
|
|
if (table)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
ret = gnc_commodity_table_lookup (table, space, mn);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
g_free (mn);
|
|
|
|
return ret;
|
|
|
|
}
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
name = get_random_string();
|
2006-03-30 19:43:16 -06:00
|
|
|
cusip = get_random_string();
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
ran_int = get_random_int_in_range(min_scu, max_scu);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2006-03-30 19:43:16 -06:00
|
|
|
ret = gnc_commodity_new(book, name, space, mn, cusip, ran_int);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
g_free(mn);
|
|
|
|
g_free(name);
|
2006-03-30 19:43:16 -06:00
|
|
|
g_free(cusip);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
if (table)
|
2010-02-17 23:31:54 -06:00
|
|
|
ret = gnc_commodity_table_insert (table, ret);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
make_random_changes_to_commodity (gnc_commodity *com)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
char *str;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (com);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
str = get_random_string ();
|
|
|
|
gnc_commodity_set_namespace (com, str);
|
|
|
|
g_free (str);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
str = get_random_string ();
|
|
|
|
gnc_commodity_set_mnemonic (com, str);
|
|
|
|
g_free (str);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
str = get_random_string ();
|
|
|
|
gnc_commodity_set_fullname (com, str);
|
|
|
|
g_free (str);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
str = get_random_string ();
|
|
|
|
gnc_commodity_set_cusip (com, str);
|
|
|
|
g_free (str);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_commodity_set_fraction (com, get_random_int_in_range (1, 100000));
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
make_random_changes_to_commodity_table (gnc_commodity_table *table)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList *namespaces;
|
|
|
|
GList *node;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (table);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
namespaces = gnc_commodity_table_get_namespaces (table);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = namespaces; node; node = node->next)
|
|
|
|
{
|
|
|
|
const char *ns = node->data;
|
|
|
|
GList *commodities;
|
|
|
|
GList *com_node;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (gnc_commodity_namespace_is_iso (ns))
|
|
|
|
continue;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
commodities = gnc_commodity_table_get_commodities (table, ns);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (com_node = commodities; com_node; com_node = com_node->next)
|
|
|
|
{
|
|
|
|
gnc_commodity *com = com_node->data;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_commodity_table_remove (table, com);
|
|
|
|
make_random_changes_to_commodity (com);
|
|
|
|
gnc_commodity_table_insert (table, com);
|
|
|
|
}
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (commodities);
|
|
|
|
}
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (namespaces);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
/* ================================================================= */
|
|
|
|
/* Price stuff */
|
|
|
|
|
|
|
|
void
|
|
|
|
make_random_changes_to_price (QofBook *book, GNCPrice *p)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Timespec *ts;
|
|
|
|
char *string;
|
|
|
|
gnc_commodity *c;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (book && p);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_price_begin_edit (p);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
c = get_random_commodity (book);
|
|
|
|
gnc_price_set_commodity (p, c);
|
2001-08-23 20:13:04 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
c = get_random_commodity (book);
|
|
|
|
gnc_price_set_currency (p, c);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
ts = get_random_timespec ();
|
|
|
|
gnc_price_set_time (p, *ts);
|
|
|
|
g_free (ts);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
string = get_random_string ();
|
|
|
|
gnc_price_set_source (p, string);
|
|
|
|
g_free (string);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
string = get_random_string ();
|
|
|
|
gnc_price_set_typestr (p, string);
|
|
|
|
g_free (string);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_price_set_value (p, get_random_gnc_numeric ());
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_price_commit_edit (p);
|
2001-10-18 04:33:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
GNCPrice *
|
2003-06-26 21:51:10 -05:00
|
|
|
get_random_price(QofBook *book)
|
2001-10-18 04:33:01 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GNCPrice *p;
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
p = gnc_price_create (book);
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"get_random_price failed");
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_changes_to_price (book, p);
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"make_random_changes_to_price failed");
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return p;
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2005-11-01 21:32:36 -06:00
|
|
|
gboolean
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_pricedb (QofBook *book, GNCPriceDB *db)
|
2001-08-23 20:13:04 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
int num_prices;
|
|
|
|
gboolean check;
|
2001-08-23 20:13:04 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
num_prices = get_random_int_in_range (1, 41);
|
|
|
|
if (num_prices < 1) /* should be impossible */
|
2005-11-01 21:32:36 -06:00
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
2010-02-17 23:31:54 -06:00
|
|
|
"get_random_int_in_range failed");
|
|
|
|
return FALSE;
|
2005-11-01 21:32:36 -06:00
|
|
|
}
|
2001-08-23 20:13:04 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (num_prices-- > 0)
|
|
|
|
{
|
|
|
|
GNCPrice *p;
|
|
|
|
|
|
|
|
p = get_random_price (book);
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"get_random_price failed");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-11-01 21:32:36 -06:00
|
|
|
check = gnc_pricedb_add_price (db, p);
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!check)
|
|
|
|
{
|
|
|
|
return check;
|
|
|
|
}
|
2001-08-23 20:13:04 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_price_unref (p);
|
|
|
|
}
|
|
|
|
return TRUE;
|
2001-09-27 19:15:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
GNCPriceDB *
|
2003-06-26 21:51:10 -05:00
|
|
|
get_random_pricedb(QofBook *book)
|
2001-09-27 19:15:49 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GNCPriceDB *db;
|
2001-09-27 19:15:49 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
db = gnc_pricedb_get_db (book);
|
|
|
|
if (!db)
|
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"gnc_pricedb_get_db failed");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!make_random_pricedb (book, db))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-08-23 20:13:04 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return db;
|
2001-08-23 20:13:04 -05:00
|
|
|
}
|
|
|
|
|
2001-10-18 04:33:01 -05:00
|
|
|
static gboolean
|
|
|
|
price_accumulator (GNCPrice *p, gpointer data)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList **list = data;
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
*list = g_list_prepend (*list, p);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return TRUE;
|
2001-10-18 04:33:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_changes_to_pricedb (QofBook *book, GNCPriceDB *pdb)
|
2001-10-18 04:33:01 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList *list = NULL;
|
|
|
|
GList *node;
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (pdb);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_pricedb_foreach_price (pdb, price_accumulator, &list, FALSE);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = list; node; node = node->next)
|
2001-10-18 04:33:01 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GNCPrice *p = node->data;
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (get_random_int_in_range (0, 5))
|
|
|
|
{
|
|
|
|
case 0: /* Delete */
|
|
|
|
gnc_pricedb_remove_price (pdb, p);
|
|
|
|
break;
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
case 1:
|
|
|
|
case 2: /* Change */
|
|
|
|
make_random_changes_to_price (book, p);
|
|
|
|
break;
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
default: /* nothing */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (list);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Add a few new ones */
|
2001-10-18 04:33:01 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
int i = get_random_int_in_range (1, 5);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (i--)
|
|
|
|
{
|
|
|
|
GNCPrice *p = get_random_price (book);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_pricedb_add_price (pdb, p);
|
|
|
|
|
|
|
|
gnc_price_unref (p);
|
|
|
|
}
|
2001-10-18 04:33:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
/* ================================================================= */
|
|
|
|
/* Account stuff */
|
2001-09-29 05:03:38 -05:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
static void
|
|
|
|
set_account_random_string(Account* act,
|
|
|
|
void(*func)(Account *act, const gchar*str))
|
|
|
|
{
|
|
|
|
gchar *tmp_str = get_random_string();
|
2010-02-17 23:31:54 -06:00
|
|
|
if (tmp_str)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
|
|
|
(func)(act, tmp_str);
|
|
|
|
g_free(tmp_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
static void
|
|
|
|
set_account_random_string_from_array(
|
|
|
|
Account* act, void(*func)(Account *act, const gchar*str),
|
|
|
|
const gchar *list[])
|
|
|
|
{
|
|
|
|
const gchar *tmp_str = get_random_string_in_array(list);
|
2010-02-17 23:31:54 -06:00
|
|
|
if (tmp_str)
|
2005-12-29 22:36:38 -06:00
|
|
|
(func)(act, tmp_str);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2001-08-20 18:25:39 -05:00
|
|
|
static void
|
2003-06-26 21:51:10 -05:00
|
|
|
account_add_subaccounts (QofBook *book, Account *account, int depth)
|
2001-08-20 18:25:39 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
int num_accounts;
|
2001-08-20 18:25:39 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (depth == 0)
|
|
|
|
return;
|
2001-08-20 18:25:39 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
num_accounts = get_random_int_in_range (1, 10);
|
|
|
|
while (num_accounts-- > 0)
|
|
|
|
{
|
|
|
|
Account *sub = get_random_account (book);
|
2001-08-20 18:25:39 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_account_append_child (account, sub);
|
2001-08-20 18:25:39 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
total_num_accounts ++;
|
|
|
|
if (total_num_accounts > max_total_accounts) return;
|
2004-06-06 22:05:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
account_add_subaccounts (book, sub, depth - 1);
|
|
|
|
}
|
2001-08-20 18:25:39 -05:00
|
|
|
}
|
|
|
|
|
2001-11-25 03:05:23 -06:00
|
|
|
static void
|
2007-02-22 19:23:31 -06:00
|
|
|
make_random_account_tree (QofBook *book, Account *root)
|
2001-11-25 03:05:23 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
int depth;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (book);
|
|
|
|
g_return_if_fail (root);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
total_num_accounts = 0;
|
|
|
|
depth = get_random_int_in_range (1, max_tree_depth);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
account_add_subaccounts (book, root, depth);
|
2006-02-05 14:38:46 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Make sure we have at least two accounts! */
|
|
|
|
if (total_num_accounts <= 1)
|
|
|
|
account_add_subaccounts (book, root, 1);
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
2007-02-22 19:23:31 -06:00
|
|
|
Account *
|
|
|
|
get_random_account_tree (QofBook *book)
|
2004-07-06 09:24:09 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Account * root;
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_val_if_fail (book, NULL);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
root = gnc_book_get_root_account (book);
|
|
|
|
if (!root)
|
|
|
|
{
|
|
|
|
root = xaccMallocAccount (book);
|
|
|
|
gnc_book_set_root_account (book, root);
|
|
|
|
}
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_account_tree (book, root);
|
2004-07-06 09:24:09 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return root;
|
2004-07-06 09:24:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ================================================================= */
|
|
|
|
/* transaction stuff */
|
|
|
|
|
2004-07-06 21:42:44 -05:00
|
|
|
/** This routine creates a random, but otherwise self-consistent,
|
|
|
|
* 'legal' transaction. It's been modified to occasionally build
|
2010-02-17 23:31:54 -06:00
|
|
|
* cruddy, inconsistent transactions, so that the engine 'scrub'
|
2004-07-06 21:42:44 -05:00
|
|
|
* routines get tested.
|
2004-07-06 09:24:09 -05:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
add_random_splits(QofBook *book, Transaction *trn, GList *account_list)
|
|
|
|
{
|
|
|
|
Account *acc, *bcc;
|
|
|
|
Split *s;
|
2012-05-26 18:47:34 -05:00
|
|
|
gnc_numeric val;
|
2001-11-25 03:05:23 -06:00
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
/* Gotta have at least two different accounts */
|
|
|
|
if (1 >= g_list_length (account_list)) return;
|
2001-11-25 03:05:23 -06:00
|
|
|
|
2004-07-06 09:24:09 -05:00
|
|
|
acc = get_random_list_element (account_list);
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransBeginEdit(trn);
|
2005-11-01 21:32:36 -06:00
|
|
|
s = get_random_split(book, acc, trn);
|
2001-08-20 18:25:39 -05:00
|
|
|
|
2004-07-06 21:42:44 -05:00
|
|
|
bcc = get_random_list_element (account_list);
|
|
|
|
if ((bcc == acc) && (!do_bork()))
|
2010-02-17 23:31:54 -06:00
|
|
|
{
|
|
|
|
/* Make sure that each side of the transaction is in
|
|
|
|
* a different account; otherwise get weirdness in lot
|
|
|
|
* calculcations. ... Hmm maybe should fix lots in
|
|
|
|
* this case? */
|
|
|
|
while (bcc == acc)
|
|
|
|
{
|
|
|
|
bcc = get_random_list_element (account_list);
|
|
|
|
}
|
2004-07-06 21:42:44 -05:00
|
|
|
}
|
2001-08-20 18:25:39 -05:00
|
|
|
|
2006-02-21 13:43:00 -06:00
|
|
|
/* Set up two splits whose values really are opposites. */
|
2006-03-30 19:43:16 -06:00
|
|
|
val = xaccSplitGetValue(s);
|
2005-11-01 21:32:36 -06:00
|
|
|
s = get_random_split(book, bcc, trn);
|
2004-07-06 21:42:44 -05:00
|
|
|
|
|
|
|
/* Other split should have equal and opposite value */
|
2010-02-17 23:31:54 -06:00
|
|
|
if (do_bork())
|
2004-07-06 21:42:44 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
val = get_random_gnc_numeric();
|
2006-03-30 19:43:16 -06:00
|
|
|
}
|
|
|
|
val = gnc_numeric_neg(val);
|
|
|
|
xaccSplitSetValue(s, val);
|
|
|
|
xaccSplitSetAmount(s, val);
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransCommitEdit(trn);
|
2001-08-20 18:25:39 -05:00
|
|
|
}
|
|
|
|
|
2001-10-16 04:13:07 -05:00
|
|
|
typedef struct
|
|
|
|
{
|
2010-03-27 16:01:21 -05:00
|
|
|
GncGUID guid;
|
2001-10-16 04:13:07 -05:00
|
|
|
} TransInfo;
|
|
|
|
|
2001-12-26 01:14:44 -06:00
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_changes_to_transaction_and_splits (QofBook *book,
|
2010-02-17 23:31:54 -06:00
|
|
|
Transaction *trans,
|
|
|
|
GList *accounts)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList *splits;
|
|
|
|
GList *node;
|
|
|
|
Split *split;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (book);
|
|
|
|
g_return_if_fail (trans);
|
|
|
|
g_return_if_fail (accounts);
|
2001-12-26 01:14:44 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransBeginEdit (trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_changes_to_transaction (book, trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (get_random_int_in_range (0, 3))
|
|
|
|
{
|
2001-10-16 04:13:07 -05:00
|
|
|
case 0: /* delete some splits, add some more */
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccTransGetVoidStatus (trans))
|
|
|
|
break;
|
2001-11-07 02:59:30 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
do
|
|
|
|
{
|
|
|
|
split = xaccTransGetSplit (trans, 0);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccSplitDestroy (split);
|
|
|
|
}
|
|
|
|
while (split);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
add_random_splits (book, trans, accounts);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* fall through */
|
2001-10-16 04:13:07 -05:00
|
|
|
|
|
|
|
case 1: /* move the splits around */
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccTransGetVoidStatus (trans))
|
|
|
|
break;
|
2001-11-07 02:59:30 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
splits = xaccTransGetSplitList (trans);
|
|
|
|
for (node = splits; node; node = node->next)
|
|
|
|
{
|
|
|
|
Split *split = node->data;
|
|
|
|
Account *account;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
account = get_random_list_element (accounts);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccAccountInsertSplit (account, split);
|
|
|
|
}
|
|
|
|
break;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
|
|
|
case 2: /* destroy the transaction */
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransDestroy (trans);
|
|
|
|
xaccTransCommitEdit (trans);
|
|
|
|
return;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
|
|
|
default: /* do nothing */
|
2010-02-17 23:31:54 -06:00
|
|
|
break;
|
|
|
|
}
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccTransGetVoidStatus (trans))
|
|
|
|
{
|
|
|
|
xaccTransCommitEdit (trans);
|
|
|
|
return;
|
|
|
|
}
|
2001-11-07 02:59:30 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* mess with the splits */
|
|
|
|
splits = xaccTransGetSplitList (trans);
|
|
|
|
for (node = splits; node; node = node->next)
|
|
|
|
{
|
|
|
|
Split *split = node->data;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (get_random_boolean ())
|
|
|
|
make_random_changes_to_split (split);
|
|
|
|
}
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (get_random_boolean ())
|
|
|
|
xaccTransCommitEdit (trans);
|
|
|
|
else
|
|
|
|
xaccTransRollbackEdit (trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
}
|
|
|
|
|
2003-08-16 16:13:31 -05:00
|
|
|
static int
|
2001-10-16 04:13:07 -05:00
|
|
|
add_trans_helper (Transaction *trans, gpointer data)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
TransInfo *ti;
|
|
|
|
GList **list = data;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
ti = g_new (TransInfo, 1);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
ti->guid = *xaccTransGetGUID (trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
*list = g_list_prepend (*list, ti);
|
|
|
|
return 0;
|
2001-10-16 04:13:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-02-22 19:23:31 -06:00
|
|
|
make_random_changes_to_level (QofBook *book, Account *parent)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Account *new_account;
|
|
|
|
Account *account;
|
|
|
|
GList *accounts;
|
|
|
|
GList *transes;
|
|
|
|
GList *splits;
|
|
|
|
GList *node;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (parent && book);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
accounts = gnc_account_get_descendants (parent);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Add a new account */
|
|
|
|
new_account = get_random_account (book);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (get_random_boolean () || !accounts)
|
|
|
|
gnc_account_append_child (parent, new_account);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
account = get_random_list_element (accounts);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_account_append_child (account, new_account);
|
|
|
|
}
|
2001-10-17 18:35:52 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (accounts);
|
|
|
|
accounts = gnc_account_get_descendants (parent);
|
2001-10-17 18:35:52 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Add some new transactions */
|
|
|
|
add_random_transactions_to_book (book, get_random_int_in_range (1, 6));
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Mess with the accounts */
|
|
|
|
for (node = accounts; node; node = node->next)
|
|
|
|
{
|
|
|
|
Account *account = node->data;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (get_random_boolean ())
|
|
|
|
make_random_changes_to_account (book, account);
|
|
|
|
}
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Mess with the transactions & splits */
|
|
|
|
transes = NULL;
|
|
|
|
xaccAccountTreeForEachTransaction (parent, add_trans_helper, &transes);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = transes; node; node = node->next)
|
|
|
|
{
|
|
|
|
TransInfo *ti = node->data;
|
|
|
|
Transaction *trans = xaccTransLookup (&ti->guid, book);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!trans)
|
|
|
|
continue;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_changes_to_transaction_and_splits (book, trans, accounts);
|
|
|
|
}
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = transes; node; node = node->next)
|
|
|
|
{
|
|
|
|
TransInfo *ti = node->data;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_free (ti);
|
|
|
|
}
|
|
|
|
g_list_free (transes);
|
|
|
|
transes = NULL;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* delete an account */
|
|
|
|
account = get_random_list_element (accounts);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
splits = xaccAccountGetSplitList (account);
|
|
|
|
splits = g_list_copy (splits);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = splits; node; node = node->next)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Split *split = node->data;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
do
|
|
|
|
{
|
|
|
|
new_account = get_random_list_element (accounts);
|
|
|
|
}
|
|
|
|
while (new_account == account);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccAccountInsertSplit (new_account, split);
|
|
|
|
}
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccAccountBeginEdit (account);
|
|
|
|
xaccAccountDestroy (account);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (splits);
|
|
|
|
g_list_free (accounts);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
accounts = gnc_account_get_descendants (parent);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* move some accounts around */
|
|
|
|
if (accounts && (g_list_length (accounts) > 1))
|
2001-10-18 04:33:01 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
int i = get_random_int_in_range (1, 4);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (i--)
|
|
|
|
{
|
|
|
|
Account *a1, *a2;
|
|
|
|
|
|
|
|
a1 = get_random_list_element (accounts);
|
|
|
|
|
|
|
|
if (get_random_boolean ())
|
|
|
|
a2 = get_random_list_element (accounts);
|
|
|
|
else
|
|
|
|
a2 = NULL;
|
|
|
|
|
|
|
|
if (!a2)
|
|
|
|
{
|
|
|
|
gnc_account_append_child (parent, a1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (a1 == a2 ||
|
|
|
|
xaccAccountHasAncestor (a1, a2) ||
|
|
|
|
xaccAccountHasAncestor (a2, a1))
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_account_append_child (a2, a1);
|
|
|
|
}
|
2001-10-18 04:33:01 -05:00
|
|
|
}
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (accounts);
|
2001-10-16 04:13:07 -05:00
|
|
|
}
|
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
Account*
|
2003-06-26 21:51:10 -05:00
|
|
|
get_random_account(QofBook *book)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
2007-02-22 19:23:31 -06:00
|
|
|
Account *root, *ret;
|
2001-08-17 19:13:45 -05:00
|
|
|
int tmp_int;
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2001-11-24 06:10:42 -06:00
|
|
|
ret = xaccMallocAccount(book);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
|
|
|
xaccAccountBeginEdit(ret);
|
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
set_account_random_string_from_array(ret, xaccAccountSetName,
|
|
|
|
sane_account_names);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2006-08-06 17:07:12 -05:00
|
|
|
tmp_int = get_random_int_in_range(ACCT_TYPE_BANK, NUM_ACCOUNT_TYPES - 1);
|
2001-08-17 19:13:45 -05:00
|
|
|
xaccAccountSetType(ret, tmp_int);
|
|
|
|
|
|
|
|
set_account_random_string(ret, xaccAccountSetCode);
|
|
|
|
set_account_random_string(ret, xaccAccountSetDescription);
|
|
|
|
|
2001-11-24 06:10:42 -06:00
|
|
|
xaccAccountSetCommodity(ret, get_random_commodity(book));
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2007-04-19 00:09:34 -05:00
|
|
|
qof_instance_set_slots(QOF_INSTANCE(ret), get_random_kvp_frame());
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2007-02-22 19:23:31 -06:00
|
|
|
root = gnc_book_get_root_account (book);
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!root)
|
2004-07-08 22:07:34 -05:00
|
|
|
{
|
2007-02-22 19:23:31 -06:00
|
|
|
root = xaccMallocAccount (book);
|
|
|
|
gnc_book_set_root_account (book, root);
|
2004-07-08 22:07:34 -05:00
|
|
|
}
|
2007-02-22 19:23:31 -06:00
|
|
|
gnc_account_append_child (root, ret);
|
2001-08-17 19:13:45 -05:00
|
|
|
xaccAccountCommitEdit(ret);
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2001-10-16 04:13:07 -05:00
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_changes_to_account (QofBook *book, Account *account)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
|
|
|
int tmp_int;
|
|
|
|
|
|
|
|
g_return_if_fail (account);
|
|
|
|
|
|
|
|
xaccAccountBeginEdit (account);
|
|
|
|
|
|
|
|
set_account_random_string (account, xaccAccountSetName);
|
|
|
|
|
2011-09-06 02:21:04 -05:00
|
|
|
tmp_int = get_random_int_in_range (ACCT_TYPE_BANK, NUM_ACCOUNT_TYPES - 1);
|
2001-10-16 04:13:07 -05:00
|
|
|
xaccAccountSetType (account, tmp_int);
|
|
|
|
|
|
|
|
set_account_random_string (account, xaccAccountSetCode);
|
|
|
|
set_account_random_string (account, xaccAccountSetDescription);
|
|
|
|
|
2001-11-24 06:10:42 -06:00
|
|
|
xaccAccountSetCommodity (account, get_random_commodity(book));
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2007-04-19 00:09:34 -05:00
|
|
|
qof_instance_set_slots(QOF_INSTANCE(account), get_random_kvp_frame());
|
2001-10-16 04:13:07 -05:00
|
|
|
|
|
|
|
xaccAccountCommitEdit (account);
|
|
|
|
}
|
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
static void
|
|
|
|
set_split_random_string(Split *spl,
|
2010-02-17 23:31:54 -06:00
|
|
|
void(*func)(Split *act, const gchar*str))
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
|
|
|
gchar *tmp_str = get_random_string();
|
2010-02-17 23:31:54 -06:00
|
|
|
if (tmp_str)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
|
|
|
(func)(spl, tmp_str);
|
|
|
|
g_free(tmp_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-11-07 02:59:30 -06:00
|
|
|
/* Don't do voiding here, it should be done by xaccTransVoid */
|
2001-11-07 03:56:15 -06:00
|
|
|
static char possible_chars[] = { NREC, CREC, YREC, FREC };
|
2001-08-17 19:13:45 -05:00
|
|
|
|
|
|
|
Split*
|
2005-11-01 21:32:36 -06:00
|
|
|
get_random_split(QofBook *book, Account *acct, Transaction *trn)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
|
|
|
Split *ret;
|
2006-03-30 19:43:16 -06:00
|
|
|
gnc_numeric amt, val, rate;
|
2005-12-29 22:36:38 -06:00
|
|
|
const gchar *str;
|
2006-02-21 13:43:00 -06:00
|
|
|
gnc_commodity *com;
|
2006-03-30 19:43:16 -06:00
|
|
|
int scu, denom;
|
2006-03-03 18:09:31 -06:00
|
|
|
Timespec *ts;
|
2006-02-21 13:43:00 -06:00
|
|
|
|
|
|
|
com = xaccTransGetCurrency (trn);
|
|
|
|
scu = gnc_commodity_get_fraction(com);
|
2001-10-05 03:35:04 -05:00
|
|
|
|
2001-11-24 06:10:42 -06:00
|
|
|
ret = xaccMallocSplit(book);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
str = get_random_string_in_array(sane_descriptions);
|
|
|
|
xaccSplitSetMemo(ret, str);
|
|
|
|
str = get_random_string_in_array(sane_actions);
|
|
|
|
xaccSplitSetAction(ret, str);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2001-11-07 02:59:30 -06:00
|
|
|
xaccSplitSetReconcile(ret, possible_chars[get_random_int_in_range(0, 3)]);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2006-03-03 18:09:31 -06:00
|
|
|
ts = get_random_timespec();
|
|
|
|
xaccSplitSetDateReconciledTS(ret, ts);
|
|
|
|
g_free(ts);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2004-07-03 10:29:39 -05:00
|
|
|
/* Split must be in an account before we can set an amount */
|
2005-11-01 21:32:36 -06:00
|
|
|
/* and in a transaction before it can be added to an account. */
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransBeginEdit(trn);
|
2006-03-30 19:43:16 -06:00
|
|
|
xaccSplitSetParent(ret, trn);
|
|
|
|
xaccSplitSetAccount(ret, acct);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
do
|
|
|
|
{
|
2006-02-21 13:43:00 -06:00
|
|
|
val = get_random_gnc_numeric ();
|
|
|
|
if (val.num == 0)
|
|
|
|
fprintf(stderr, "get_random_split: Created split with zero value: %p\n", ret);
|
2004-12-17 09:56:30 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!do_bork())
|
2006-03-30 19:43:16 -06:00
|
|
|
val.denom = scu;
|
2010-02-17 23:31:54 -06:00
|
|
|
}
|
|
|
|
while (gnc_numeric_check(val) != GNC_ERROR_OK);
|
2006-02-21 13:43:00 -06:00
|
|
|
xaccSplitSetValue(ret, val);
|
2005-12-29 22:36:38 -06:00
|
|
|
|
2006-02-21 13:43:00 -06:00
|
|
|
/* If the currencies are the same, the split amount should equal
|
|
|
|
* the split value (unless we bork it on purpose) */
|
2010-02-17 23:31:54 -06:00
|
|
|
if (gnc_commodity_equal (xaccTransGetCurrency(trn),
|
2006-02-21 13:43:00 -06:00
|
|
|
xaccAccountGetCommodity(acct)) &&
|
2010-02-17 23:31:54 -06:00
|
|
|
(!do_bork()))
|
|
|
|
{
|
2006-02-21 13:43:00 -06:00
|
|
|
amt = val;
|
2010-02-17 23:31:54 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-03-30 19:43:16 -06:00
|
|
|
denom = gnc_commodity_get_fraction(xaccAccountGetCommodity(
|
|
|
|
xaccSplitGetAccount(ret)));
|
2010-02-17 23:31:54 -06:00
|
|
|
do
|
|
|
|
{
|
2006-03-30 19:43:16 -06:00
|
|
|
rate = gnc_numeric_abs(get_random_gnc_numeric());
|
2010-02-17 23:31:54 -06:00
|
|
|
amt = gnc_numeric_mul(val, rate,
|
2006-03-30 19:43:16 -06:00
|
|
|
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
|
2010-10-23 05:38:48 -05:00
|
|
|
amt = gnc_numeric_convert(amt, denom, GNC_HOW_RND_ROUND_HALF_UP);
|
2010-02-17 23:31:54 -06:00
|
|
|
}
|
|
|
|
while (gnc_numeric_check(amt) != GNC_ERROR_OK);
|
2006-02-21 13:43:00 -06:00
|
|
|
}
|
|
|
|
xaccSplitSetAmount(ret, amt);
|
2006-07-19 11:03:05 -05:00
|
|
|
|
|
|
|
/* Make sure val and amt have the same sign. Note that amt is
|
|
|
|
also allowed to be zero, because that is caused by a small
|
|
|
|
rate. */
|
2006-03-30 19:43:16 -06:00
|
|
|
if (gnc_numeric_positive_p(val))
|
2006-07-19 11:03:05 -05:00
|
|
|
g_assert(!gnc_numeric_negative_p(amt)); /* non-negative amt */
|
|
|
|
else
|
|
|
|
g_assert(!gnc_numeric_positive_p(amt)); /* non-positive amt */
|
2010-02-17 23:31:54 -06:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
xaccSplitSetSlots_nc(ret, get_random_kvp_frame());
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransCommitEdit(trn);
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2001-10-15 19:50:01 -05:00
|
|
|
void
|
|
|
|
make_random_changes_to_split (Split *split)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Transaction *trans;
|
|
|
|
Timespec *ts;
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (split);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
trans = xaccSplitGetParent (split);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransBeginEdit (trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
set_split_random_string (split, xaccSplitSetMemo);
|
|
|
|
set_split_random_string (split, xaccSplitSetAction);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccSplitSetReconcile (split, possible_chars[get_random_int_in_range(0, 3)]);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
ts = get_random_timespec();
|
|
|
|
xaccSplitSetDateReconciledTS (split, ts);
|
|
|
|
g_free(ts);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccSplitSetSlots_nc (split, get_random_kvp_frame());
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Don't change share values/prices here, since that would
|
|
|
|
* throw transactions out of balance. Do that in the corresponding
|
|
|
|
* change transaction function. */
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransCommitEdit (trans);
|
2001-10-15 19:50:01 -05:00
|
|
|
}
|
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
static void
|
|
|
|
set_tran_random_string(Transaction* trn,
|
|
|
|
void(*func)(Transaction *act, const gchar*str))
|
|
|
|
{
|
|
|
|
gchar *tmp_str = get_random_string();
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!trn || !(&trn->inst))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (tmp_str)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
2005-11-01 21:32:36 -06:00
|
|
|
xaccTransBeginEdit(trn);
|
2001-08-17 19:13:45 -05:00
|
|
|
(func)(trn, tmp_str);
|
|
|
|
g_free(tmp_str);
|
2005-11-01 21:32:36 -06:00
|
|
|
xaccTransCommitEdit(trn);
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
static void
|
|
|
|
set_tran_random_string_from_array(
|
|
|
|
Transaction* trn, void(*func)(Transaction *trn, const gchar*str),
|
|
|
|
const gchar *list[])
|
|
|
|
{
|
|
|
|
const gchar *tmp_str = get_random_string_in_array(list);
|
2010-02-17 23:31:54 -06:00
|
|
|
if (tmp_str)
|
2005-12-29 22:36:38 -06:00
|
|
|
(func)(trn, tmp_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
static void
|
|
|
|
trn_add_ran_timespec(Transaction *trn, void (*func)(Transaction*,
|
2010-02-17 23:31:54 -06:00
|
|
|
const Timespec*))
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
|
|
|
Timespec *to_set;
|
|
|
|
|
|
|
|
to_set = get_random_timespec();
|
|
|
|
func(trn, to_set);
|
|
|
|
g_free(to_set);
|
|
|
|
}
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
|
2001-10-13 03:09:30 -05:00
|
|
|
Transaction *
|
2003-06-26 21:51:10 -05:00
|
|
|
get_random_transaction_with_currency(QofBook *book,
|
2004-07-03 10:29:39 -05:00
|
|
|
gnc_commodity *currency,
|
|
|
|
GList *account_list)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
2005-12-29 22:36:38 -06:00
|
|
|
Transaction* trans;
|
2004-09-22 13:40:10 -05:00
|
|
|
KvpFrame *f;
|
2005-12-29 22:36:38 -06:00
|
|
|
gint num;
|
2006-05-07 16:39:30 -05:00
|
|
|
gchar *numstr;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (!account_list)
|
2004-07-03 10:29:39 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
account_list = gnc_account_get_descendants (gnc_book_get_root_account (book));
|
2004-07-03 10:29:39 -05:00
|
|
|
}
|
|
|
|
|
2004-07-08 22:07:34 -05:00
|
|
|
/* Gotta have at least two different accounts */
|
2010-02-17 23:31:54 -06:00
|
|
|
if (1 >= g_list_length (account_list))
|
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"get_random_transaction_with_currency: account_list too short");
|
|
|
|
return NULL;
|
2006-02-05 14:38:46 -06:00
|
|
|
}
|
2004-07-08 22:07:34 -05:00
|
|
|
|
2011-08-21 14:42:34 -05:00
|
|
|
numstr = g_new0(gchar, 10);
|
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
trans = xaccMallocTransaction(book);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransBeginEdit(trans);
|
2005-11-01 21:32:36 -06:00
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransSetCurrency (trans,
|
2001-10-13 03:09:30 -05:00
|
|
|
currency ? currency :
|
2001-11-24 06:10:42 -06:00
|
|
|
get_random_commodity (book));
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
num = get_random_int_in_range (1, max_trans_num);
|
2006-03-03 18:09:31 -06:00
|
|
|
g_snprintf(numstr, 10, "%d", num);
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransSetNum(trans, numstr);
|
|
|
|
set_tran_random_string_from_array(trans, xaccTransSetDescription,
|
|
|
|
sane_descriptions);
|
|
|
|
trn_add_ran_timespec(trans, xaccTransSetDatePostedTS);
|
|
|
|
trn_add_ran_timespec(trans, xaccTransSetDateEnteredTS);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2004-09-22 13:40:10 -05:00
|
|
|
f = get_random_kvp_frame();
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransSetSlots_nc(trans, f);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
add_random_splits(book, trans, account_list);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2001-11-07 02:59:30 -06:00
|
|
|
if (get_random_int_in_range (1, 10) == 1)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
char *reason = get_random_string ();
|
|
|
|
xaccTransVoid (trans, reason);
|
|
|
|
g_free (reason);
|
2001-11-07 02:59:30 -06:00
|
|
|
}
|
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
xaccTransCommitEdit(trans);
|
|
|
|
if (!trans)
|
2005-11-01 21:32:36 -06:00
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"get_random_transaction_with_currency failed");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-12-29 22:36:38 -06:00
|
|
|
return trans;
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2001-10-13 03:09:30 -05:00
|
|
|
Transaction*
|
2003-06-26 21:51:10 -05:00
|
|
|
get_random_transaction (QofBook *book)
|
2001-10-13 03:09:30 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Transaction *ret;
|
2005-11-01 21:32:36 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_val_if_fail(book, NULL);
|
|
|
|
ret = get_random_transaction_with_currency (book, NULL, NULL);
|
|
|
|
if (!ret)
|
2005-11-01 21:32:36 -06:00
|
|
|
{
|
|
|
|
failure_args("engine-stuff", __FILE__, __LINE__,
|
|
|
|
"get_random_transaction failed");
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-02-17 23:31:54 -06:00
|
|
|
return ret;
|
2001-10-13 03:09:30 -05:00
|
|
|
}
|
|
|
|
|
2001-10-16 04:13:07 -05:00
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_changes_to_transaction (QofBook *book, Transaction *trans)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (trans && book);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccTransGetVoidStatus (trans))
|
|
|
|
{
|
|
|
|
if (get_random_int_in_range (1, 2) == 1)
|
|
|
|
xaccTransUnvoid (trans);
|
|
|
|
return;
|
|
|
|
}
|
2001-11-07 02:59:30 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransBeginEdit (trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransSetCurrency (trans, get_random_commodity (book));
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
set_tran_random_string (trans, xaccTransSetNum);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
trn_add_ran_timespec (trans, xaccTransSetDatePostedTS);
|
|
|
|
trn_add_ran_timespec (trans, xaccTransSetDateEnteredTS);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
set_tran_random_string (trans, xaccTransSetDescription);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransSetSlots_nc (trans, get_random_kvp_frame());
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Do split manipulations in higher-level functions */
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransCommitEdit (trans);
|
2001-10-16 04:13:07 -05:00
|
|
|
}
|
|
|
|
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2001-08-17 19:13:45 -05:00
|
|
|
static GList *
|
|
|
|
get_random_guids(int max)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList *guids = NULL;
|
|
|
|
int num_guids;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (max < 1) return NULL;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
num_guids = get_random_int_in_range (1, max);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (num_guids-- > 0)
|
|
|
|
guids = g_list_prepend (guids, get_random_guid ());
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return guids;
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_random_guids(GList *guids)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList *node;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = guids; node; node = node->next)
|
|
|
|
g_free (node->data);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_list_free (guids);
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
static QofQueryOp
|
2001-08-17 19:13:45 -05:00
|
|
|
get_random_queryop(void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
int op_num = get_random_int_in_range(1, 11);
|
|
|
|
QofQueryOp op = QOF_QUERY_AND;
|
|
|
|
/* = get_random_int_in_range (1, QOF_QUERY_XOR); */
|
2006-02-19 13:29:51 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
/* Let's make it MUCH more likely to get AND and OR */
|
|
|
|
switch (op_num)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
op = QOF_QUERY_AND;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
case 8:
|
|
|
|
op = QOF_QUERY_OR;
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
op = QOF_QUERY_NAND;
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
op = QOF_QUERY_NOR;
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
op = QOF_QUERY_XOR;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
};
|
|
|
|
if (gnc_engine_debug_random) printf ("op = %d (int was %d), ", op, op_num);
|
|
|
|
return op;
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2001-11-05 18:49:46 -06:00
|
|
|
static GSList *
|
|
|
|
get_random_kvp_path (void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GSList *path;
|
|
|
|
gint len;
|
2001-11-05 18:49:46 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
path = NULL;
|
|
|
|
len = get_random_int_in_range (1, kvp_max_depth);
|
2001-11-05 18:49:46 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (len--)
|
|
|
|
path = g_slist_prepend (path, get_random_string ());
|
2001-11-05 18:49:46 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return g_slist_reverse (path);
|
2001-11-05 18:49:46 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_random_kvp_path (GSList *path)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GSList *node;
|
2001-11-05 18:49:46 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = path; node; node = node->next)
|
|
|
|
g_free (node->data);
|
2001-11-05 18:49:46 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_slist_free (path);
|
2001-11-05 18:49:46 -06:00
|
|
|
}
|
|
|
|
|
2003-06-26 02:30:48 -05:00
|
|
|
static QofIdType
|
2001-11-14 03:07:49 -06:00
|
|
|
get_random_id_type (void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (get_random_int_in_range (1, 3))
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
return GNC_ID_SPLIT;
|
|
|
|
case 2:
|
|
|
|
return GNC_ID_TRANS;
|
|
|
|
case 3:
|
|
|
|
return GNC_ID_ACCOUNT;
|
|
|
|
default:
|
|
|
|
return get_random_string ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
BY_STANDARD = 1,
|
|
|
|
BY_DATE,
|
|
|
|
BY_DATE_ENTERED,
|
|
|
|
BY_DATE_RECONCILED,
|
|
|
|
BY_NUM,
|
|
|
|
BY_AMOUNT,
|
|
|
|
BY_MEMO,
|
|
|
|
BY_DESC,
|
|
|
|
BY_NONE
|
2002-06-05 16:59:35 -05:00
|
|
|
} sort_type_t;
|
|
|
|
|
|
|
|
static void
|
2010-12-14 14:22:48 -06:00
|
|
|
set_query_sort (QofQuery *q, sort_type_t sort_code)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GSList *p1 = NULL, *p2 = NULL, *p3 = NULL, *standard;
|
2002-06-05 16:59:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
standard = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
|
2002-06-05 16:59:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (sort_code)
|
|
|
|
{
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_STANDARD:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_DATE:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, TRANS_DATE_POSTED);
|
|
|
|
p1 = g_slist_prepend (p1, SPLIT_TRANS);
|
|
|
|
p2 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_DATE_ENTERED:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, TRANS_DATE_ENTERED);
|
|
|
|
p1 = g_slist_prepend (p1, SPLIT_TRANS);
|
|
|
|
p2 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_DATE_RECONCILED:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, SPLIT_RECONCILE);
|
|
|
|
p2 = g_slist_prepend (p2, SPLIT_DATE_RECONCILED);
|
|
|
|
p3 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_NUM:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, TRANS_NUM);
|
|
|
|
p1 = g_slist_prepend (p1, SPLIT_TRANS);
|
|
|
|
p2 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_AMOUNT:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, SPLIT_VALUE);
|
|
|
|
p2 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_MEMO:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, SPLIT_MEMO);
|
|
|
|
p2 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_DESC:
|
2010-02-17 23:31:54 -06:00
|
|
|
p1 = g_slist_prepend (p1, TRANS_DESCRIPTION);
|
|
|
|
p1 = g_slist_prepend (p1, SPLIT_TRANS);
|
|
|
|
p2 = standard;
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
case BY_NONE:
|
2010-02-17 23:31:54 -06:00
|
|
|
g_slist_free (standard);
|
|
|
|
break;
|
2002-06-05 16:59:35 -05:00
|
|
|
default:
|
2010-02-17 23:31:54 -06:00
|
|
|
g_slist_free (standard);
|
|
|
|
g_return_if_fail (FALSE);
|
|
|
|
}
|
2002-06-05 16:59:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
qof_query_set_sort_order (q, p1, p2, p3);
|
2001-11-14 03:07:49 -06:00
|
|
|
}
|
|
|
|
|
2010-12-14 14:22:48 -06:00
|
|
|
QofQuery *
|
2001-08-17 19:13:45 -05:00
|
|
|
get_random_query(void)
|
|
|
|
{
|
2010-12-14 14:22:48 -06:00
|
|
|
QofQuery *q;
|
2010-02-17 23:31:54 -06:00
|
|
|
int num_terms;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
num_terms = get_random_int_in_range (1, 3);
|
|
|
|
if (gnc_engine_debug_random) printf("num_terms = %d", num_terms);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-10-13 11:16:04 -05:00
|
|
|
q = qof_query_create_for(GNC_ID_SPLIT);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (num_terms-- > 0)
|
2001-08-17 19:13:45 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
gint pr_type;
|
|
|
|
KvpValue *value;
|
|
|
|
Timespec *start;
|
|
|
|
Timespec *end;
|
|
|
|
GList *guids;
|
|
|
|
GSList *path;
|
|
|
|
char *string;
|
2010-03-27 16:01:21 -05:00
|
|
|
GncGUID *guid;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
pr_type = get_random_int_in_range (1, 20);
|
|
|
|
if (gnc_engine_debug_random) printf("\n pr_type = %d ", pr_type);
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (pr_type)
|
2001-11-05 18:49:46 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
case 1: /*PR_ACCOUNT */
|
|
|
|
guids = get_random_guids (10);
|
|
|
|
xaccQueryAddAccountGUIDMatch
|
|
|
|
(q,
|
|
|
|
guids,
|
|
|
|
get_random_int_in_range (1, QOF_GUID_MATCH_NONE),
|
|
|
|
get_random_queryop ());
|
|
|
|
free_random_guids (guids);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /*PR_ACTION */
|
|
|
|
string = get_random_string ();
|
|
|
|
xaccQueryAddActionMatch (q,
|
|
|
|
string,
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_queryop ());
|
|
|
|
g_free (string);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* PR_BALANCE */
|
|
|
|
xaccQueryAddBalanceMatch
|
|
|
|
(q,
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_queryop ());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4: /* PR_CLEARED */
|
|
|
|
xaccQueryAddClearedMatch
|
|
|
|
(q,
|
|
|
|
get_random_int_in_range (1,
|
|
|
|
CLEARED_NO |
|
|
|
|
CLEARED_CLEARED |
|
|
|
|
CLEARED_RECONCILED |
|
|
|
|
CLEARED_FROZEN |
|
|
|
|
CLEARED_VOIDED),
|
|
|
|
get_random_queryop ());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5: /* PR_DATE */
|
|
|
|
start = get_random_timespec ();
|
|
|
|
end = get_random_timespec ();
|
|
|
|
xaccQueryAddDateMatchTS (q,
|
|
|
|
get_random_boolean (),
|
|
|
|
*start,
|
|
|
|
get_random_boolean (),
|
|
|
|
*end,
|
|
|
|
get_random_queryop ());
|
|
|
|
g_free (start);
|
|
|
|
g_free (end);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6: /* PR_DESC */
|
|
|
|
string = get_random_string ();
|
|
|
|
xaccQueryAddDescriptionMatch (q,
|
|
|
|
string,
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_queryop ());
|
|
|
|
g_free (string);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 7: /* PR_GUID */
|
|
|
|
guid = get_random_guid ();
|
|
|
|
xaccQueryAddGUIDMatch (q,
|
|
|
|
guid,
|
|
|
|
get_random_id_type (),
|
|
|
|
get_random_queryop ());
|
|
|
|
g_free (guid);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 8: /* PR_KVP */
|
|
|
|
path = get_random_kvp_path ();
|
|
|
|
do
|
|
|
|
{
|
|
|
|
value = get_random_kvp_value_depth (-2, kvp_max_depth);
|
|
|
|
}
|
|
|
|
while (!value);
|
|
|
|
xaccQueryAddKVPMatch (q,
|
|
|
|
path,
|
|
|
|
value,
|
|
|
|
get_random_int_in_range (1, QOF_COMPARE_NEQ),
|
|
|
|
get_random_id_type (),
|
|
|
|
get_random_queryop ());
|
|
|
|
kvp_value_delete (value);
|
|
|
|
free_random_kvp_path (path);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 9: /* PR_MEMO */
|
|
|
|
string = get_random_string ();
|
|
|
|
xaccQueryAddMemoMatch (q,
|
|
|
|
string,
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_queryop ());
|
|
|
|
g_free (string);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 10: /* PR_NUM */
|
|
|
|
string = get_random_string ();
|
|
|
|
xaccQueryAddNumberMatch (q,
|
|
|
|
string,
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_queryop ());
|
|
|
|
g_free (string);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 11: /* PR_PRICE */
|
|
|
|
xaccQueryAddSharePriceMatch
|
|
|
|
(q,
|
|
|
|
get_random_gnc_numeric (),
|
|
|
|
get_random_int_in_range (1, QOF_COMPARE_NEQ),
|
|
|
|
get_random_queryop ());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 12: /* PR_SHRS */
|
|
|
|
xaccQueryAddSharesMatch
|
|
|
|
(q,
|
|
|
|
get_random_gnc_numeric (),
|
|
|
|
get_random_int_in_range (1, QOF_COMPARE_NEQ),
|
|
|
|
get_random_queryop ());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 13: /* PR_VALUE */
|
|
|
|
xaccQueryAddValueMatch
|
|
|
|
(q,
|
|
|
|
get_random_gnc_numeric (),
|
|
|
|
get_random_int_in_range (1, QOF_NUMERIC_MATCH_ANY),
|
|
|
|
get_random_int_in_range (1, QOF_COMPARE_NEQ),
|
|
|
|
get_random_queryop ());
|
|
|
|
break;
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
default:
|
|
|
|
if (gnc_engine_debug_random) printf("ignored..");
|
|
|
|
num_terms++;
|
|
|
|
break;
|
|
|
|
}
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (gnc_engine_debug_random) printf ("\n");
|
|
|
|
set_query_sort (q, get_random_int_in_range (1, BY_NONE));
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-10-13 11:16:04 -05:00
|
|
|
qof_query_set_sort_increasing (q,
|
2010-12-04 15:09:57 -06:00
|
|
|
get_random_boolean (),
|
|
|
|
get_random_boolean (),
|
|
|
|
get_random_boolean ());
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-10-13 11:16:04 -05:00
|
|
|
qof_query_set_max_results (q, get_random_int_in_range (-50000, 50000));
|
2001-08-17 19:13:45 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return q;
|
2001-08-17 19:13:45 -05:00
|
|
|
}
|
|
|
|
|
2003-06-26 21:51:10 -05:00
|
|
|
QofBook *
|
2001-11-24 06:10:42 -06:00
|
|
|
get_random_book (void)
|
2001-09-27 19:15:49 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
QofBook *book;
|
2001-09-27 19:15:49 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
book = qof_book_new ();
|
2001-09-27 19:15:49 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
get_random_account_tree (book);
|
|
|
|
get_random_pricedb (book);
|
2001-09-27 19:15:49 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return book;
|
2001-09-27 19:15:49 -05:00
|
|
|
}
|
2001-10-12 05:50:35 -05:00
|
|
|
|
2003-06-26 21:51:10 -05:00
|
|
|
QofSession *
|
2001-10-12 05:50:35 -05:00
|
|
|
get_random_session (void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
QofSession *session;
|
|
|
|
QofBook *book;
|
2001-10-12 05:50:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
session = qof_session_new ();
|
2001-10-12 05:50:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
book = qof_session_get_book (session);
|
2001-10-12 05:50:35 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
get_random_account_tree (book);
|
|
|
|
get_random_pricedb (book);
|
2001-10-18 04:33:01 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return session;
|
2001-10-12 05:50:35 -05:00
|
|
|
}
|
2001-10-13 03:09:30 -05:00
|
|
|
|
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
add_random_transactions_to_book (QofBook *book, gint num_transactions)
|
2001-10-13 03:09:30 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_commodity_table *table;
|
|
|
|
GList *accounts;
|
2001-10-13 03:09:30 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (num_transactions <= 0) return;
|
2001-10-13 03:09:30 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (book);
|
2001-10-13 03:09:30 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
accounts = gnc_account_get_descendants (gnc_book_get_root_account (book));
|
|
|
|
g_return_if_fail (accounts);
|
2001-10-13 03:09:30 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
table = gnc_commodity_table_get_table (book);
|
2001-10-13 03:09:30 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
while (num_transactions--)
|
|
|
|
{
|
|
|
|
gnc_commodity *com;
|
2001-10-13 03:09:30 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
com = get_random_commodity_from_table (table);
|
2012-05-26 18:47:34 -05:00
|
|
|
get_random_transaction_with_currency (book, com, accounts);
|
2010-02-17 23:31:54 -06:00
|
|
|
}
|
|
|
|
g_list_free (accounts);
|
2001-10-13 03:09:30 -05:00
|
|
|
}
|
2001-10-16 04:13:07 -05:00
|
|
|
|
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_changes_to_book (QofBook *book)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (book);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_changes_to_level (book, gnc_book_get_root_account (book));
|
|
|
|
make_random_changes_to_pricedb (book, gnc_pricedb_get_db (book));
|
2001-10-18 04:33:01 -05:00
|
|
|
|
|
|
|
#if 0
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_changes_to_commodity_table (gnc_commodity_table_get_table (book));
|
2001-10-18 04:33:01 -05:00
|
|
|
#endif
|
2001-10-16 04:13:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-26 21:51:10 -05:00
|
|
|
make_random_changes_to_session (QofSession *session)
|
2001-10-16 04:13:07 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
g_return_if_fail (session);
|
2001-10-16 04:13:07 -05:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
make_random_changes_to_book (qof_session_get_book (session));
|
2001-10-16 04:13:07 -05:00
|
|
|
}
|
2001-11-06 04:22:42 -06:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
QofIdType where;
|
|
|
|
GSList *path;
|
2010-12-14 14:22:48 -06:00
|
|
|
QofQuery *q;
|
2001-11-06 04:22:42 -06:00
|
|
|
} KVPQueryData;
|
|
|
|
|
|
|
|
static void
|
2004-07-08 22:07:34 -05:00
|
|
|
add_kvp_value_query (const char *key, KvpValue *value, gpointer data)
|
2001-11-06 04:22:42 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
KVPQueryData *kqd = data;
|
|
|
|
GSList *node;
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
kqd->path = g_slist_append (kqd->path, (gpointer) key);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (kvp_value_get_type (value) == KVP_TYPE_FRAME)
|
|
|
|
kvp_frame_for_each_slot (kvp_value_get_frame (value),
|
|
|
|
add_kvp_value_query, data);
|
|
|
|
else
|
|
|
|
xaccQueryAddKVPMatch (kqd->q, kqd->path, value,
|
|
|
|
QOF_COMPARE_EQUAL, kqd->where,
|
|
|
|
QOF_QUERY_AND);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
node = g_slist_last (kqd->path);
|
|
|
|
kqd->path = g_slist_remove_link (kqd->path, node);
|
|
|
|
g_slist_free_1 (node);
|
2001-11-06 04:22:42 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-12-14 14:22:48 -06:00
|
|
|
add_kvp_query (QofQuery *q, KvpFrame *frame, QofIdType where)
|
2001-11-06 04:22:42 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
KVPQueryData kqd;
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
kqd.where = where;
|
|
|
|
kqd.path = NULL;
|
|
|
|
kqd.q = q;
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
kvp_frame_for_each_slot (frame, add_kvp_value_query, &kqd);
|
2001-11-06 04:22:42 -06:00
|
|
|
}
|
|
|
|
|
2001-11-07 02:05:16 -06:00
|
|
|
static gboolean include_price = TRUE;
|
|
|
|
|
|
|
|
void
|
|
|
|
trans_query_include_price (gboolean include_price_in)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
include_price = include_price_in;
|
2001-11-07 02:05:16 -06:00
|
|
|
}
|
|
|
|
|
2001-11-09 05:50:29 -06:00
|
|
|
TestQueryTypes
|
|
|
|
get_random_query_type (void)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
switch (get_random_int_in_range (0, 4))
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return SIMPLE_QT;
|
|
|
|
case 1:
|
|
|
|
return SPLIT_KVP_QT;
|
|
|
|
case 2:
|
|
|
|
return TRANS_KVP_QT;
|
|
|
|
case 3:
|
|
|
|
return ACCOUNT_KVP_QT;
|
|
|
|
case 4:
|
|
|
|
return GUID_QT;
|
|
|
|
default:
|
|
|
|
return SIMPLE_QT;
|
|
|
|
}
|
2001-11-09 05:50:29 -06:00
|
|
|
}
|
|
|
|
|
2010-12-14 14:22:48 -06:00
|
|
|
QofQuery *
|
2001-11-09 05:50:29 -06:00
|
|
|
make_trans_query (Transaction *trans, TestQueryTypes query_types)
|
2001-11-06 04:22:42 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Account *a;
|
|
|
|
gnc_numeric n;
|
2010-12-14 14:22:48 -06:00
|
|
|
QofQuery *q;
|
2010-02-17 23:31:54 -06:00
|
|
|
Split *s;
|
2001-11-09 05:50:29 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (query_types == RANDOM_QT)
|
|
|
|
query_types = get_random_query_type ();
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-10-13 11:16:04 -05:00
|
|
|
q = qof_query_create_for(GNC_ID_SPLIT);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
s = xaccTransGetSplit (trans, 0);
|
|
|
|
a = xaccSplitGetAccount (s);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (query_types & SIMPLE_QT)
|
2006-05-07 16:39:30 -05:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccQueryAddSingleAccountMatch (q, xaccSplitGetAccount (s), QOF_QUERY_AND);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccTransGetDescription(trans) && *xaccTransGetDescription(trans) != '\0')
|
|
|
|
{
|
|
|
|
xaccQueryAddDescriptionMatch (q, xaccTransGetDescription (trans),
|
|
|
|
TRUE, FALSE, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccTransGetNum(trans) && *xaccTransGetNum(trans) != '\0')
|
|
|
|
{
|
|
|
|
xaccQueryAddNumberMatch (q, xaccTransGetNum (trans),
|
|
|
|
TRUE, FALSE, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccSplitGetAction(s) && *xaccSplitGetAction(s) != '\0')
|
|
|
|
{
|
|
|
|
xaccQueryAddActionMatch (q, xaccSplitGetAction (s),
|
|
|
|
TRUE, FALSE, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-07 02:05:16 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
n = xaccSplitGetValue (s);
|
|
|
|
xaccQueryAddValueMatch (q, n, QOF_NUMERIC_MATCH_ANY,
|
|
|
|
QOF_COMPARE_EQUAL, QOF_QUERY_AND);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
n = xaccSplitGetAmount (s);
|
|
|
|
xaccQueryAddSharesMatch (q, n, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (include_price)
|
|
|
|
{
|
|
|
|
n = xaccSplitGetSharePrice (s);
|
|
|
|
xaccQueryAddSharePriceMatch (q, n, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
{
|
|
|
|
Timespec ts;
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccTransGetDatePostedTS (trans, &ts);
|
|
|
|
xaccQueryAddDateMatchTS (q, TRUE, ts, TRUE, ts, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-09 05:50:29 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (xaccSplitGetMemo(s) && *xaccSplitGetMemo(s) != '\0')
|
|
|
|
{
|
|
|
|
xaccQueryAddMemoMatch (q, xaccSplitGetMemo (s), TRUE, FALSE, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-09 05:50:29 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
{
|
|
|
|
cleared_match_t how;
|
|
|
|
|
|
|
|
switch (xaccSplitGetReconcile (s))
|
|
|
|
{
|
|
|
|
case NREC:
|
|
|
|
how = CLEARED_NO;
|
|
|
|
break;
|
|
|
|
case CREC:
|
|
|
|
how = CLEARED_CLEARED;
|
|
|
|
break;
|
|
|
|
case YREC:
|
|
|
|
how = CLEARED_RECONCILED;
|
|
|
|
break;
|
|
|
|
case FREC:
|
|
|
|
how = CLEARED_FROZEN;
|
|
|
|
break;
|
|
|
|
case VREC:
|
|
|
|
how = CLEARED_VOIDED;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
failure ("bad reconcile flag");
|
2010-10-13 11:16:04 -05:00
|
|
|
qof_query_destroy (q);
|
2010-02-17 23:31:54 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
xaccQueryAddClearedMatch (q, how, QOF_QUERY_AND);
|
|
|
|
}
|
2001-11-06 04:22:42 -06:00
|
|
|
}
|
2001-11-29 05:09:33 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (query_types & ACCOUNT_QT)
|
2001-11-29 05:09:33 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
GList * list;
|
|
|
|
GList * node;
|
2001-11-29 05:09:33 -06:00
|
|
|
|
2010-12-13 15:00:23 -06:00
|
|
|
/* QOF_GUID_MATCH_ALL */
|
2010-02-17 23:31:54 -06:00
|
|
|
list = NULL;
|
|
|
|
for (node = xaccTransGetSplitList (trans); node; node = node->next)
|
|
|
|
{
|
|
|
|
Split * split = node->data;
|
|
|
|
list = g_list_prepend (list, xaccSplitGetAccount (split));
|
|
|
|
}
|
|
|
|
xaccQueryAddAccountMatch (q, list, QOF_GUID_MATCH_ALL, QOF_QUERY_AND);
|
|
|
|
g_list_free (list);
|
2001-11-29 05:09:33 -06:00
|
|
|
|
2010-12-13 15:00:23 -06:00
|
|
|
/* QOF_GUID_MATCH_NONE */
|
2010-02-17 23:31:54 -06:00
|
|
|
list = NULL;
|
|
|
|
list = g_list_prepend (list, get_random_guid ());
|
|
|
|
list = g_list_prepend (list, get_random_guid ());
|
|
|
|
list = g_list_prepend (list, get_random_guid ());
|
|
|
|
xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_NONE, QOF_QUERY_AND);
|
2001-11-29 05:09:33 -06:00
|
|
|
|
2010-12-13 15:00:23 -06:00
|
|
|
/* QOF_GUID_MATCH_ANY */
|
2010-02-17 23:31:54 -06:00
|
|
|
{
|
2010-03-27 16:01:21 -05:00
|
|
|
GncGUID * guid = get_random_guid ();
|
2010-02-17 23:31:54 -06:00
|
|
|
*guid = *xaccAccountGetGUID (a);
|
|
|
|
list = g_list_prepend (list, guid);
|
|
|
|
}
|
|
|
|
xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_ANY, QOF_QUERY_AND);
|
2001-11-29 05:09:33 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
for (node = list; node; node = node->next)
|
|
|
|
g_free (node->data);
|
|
|
|
g_list_free (list);
|
|
|
|
}
|
2001-11-14 03:07:49 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (query_types & GUID_QT)
|
|
|
|
{
|
|
|
|
xaccQueryAddGUIDMatch (q, xaccSplitGetGUID (s),
|
|
|
|
GNC_ID_SPLIT, QOF_QUERY_AND);
|
2001-11-14 03:07:49 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccQueryAddGUIDMatch (q, xaccTransGetGUID (trans),
|
|
|
|
GNC_ID_TRANS, QOF_QUERY_AND);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
xaccQueryAddGUIDMatch (q, xaccAccountGetGUID (a),
|
|
|
|
GNC_ID_ACCOUNT, QOF_QUERY_AND);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query_types & SPLIT_KVP_QT)
|
|
|
|
add_kvp_query (q, xaccSplitGetSlots (s), GNC_ID_SPLIT);
|
2001-11-09 05:50:29 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (query_types & TRANS_KVP_QT)
|
|
|
|
add_kvp_query (q, xaccTransGetSlots (trans), GNC_ID_TRANS);
|
2001-11-09 05:50:29 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
if (query_types & ACCOUNT_KVP_QT)
|
|
|
|
add_kvp_query (q, xaccAccountGetSlots (a), GNC_ID_ACCOUNT);
|
2001-11-06 04:22:42 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return q;
|
2001-11-06 04:22:42 -06:00
|
|
|
}
|
2007-01-19 17:45:45 -06:00
|
|
|
|
2007-02-18 18:14:53 -06:00
|
|
|
static Recurrence*
|
2010-08-22 06:10:12 -05:00
|
|
|
daily_freq(const GDate* start, int multiplier)
|
2007-01-19 17:45:45 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Recurrence *r = g_new0(Recurrence, 1);
|
|
|
|
recurrenceSet(r, multiplier, PERIOD_DAY, start, WEEKEND_ADJ_NONE);
|
|
|
|
return r;
|
2007-01-19 17:45:45 -06:00
|
|
|
}
|
|
|
|
|
2007-02-18 18:14:53 -06:00
|
|
|
static Recurrence*
|
2010-08-22 06:10:12 -05:00
|
|
|
once_freq(const GDate *when)
|
2007-01-19 17:45:45 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
Recurrence *r = g_new0(Recurrence, 1);
|
|
|
|
recurrenceSet(r, 1, PERIOD_ONCE, when, WEEKEND_ADJ_NONE);
|
|
|
|
return r;
|
2007-01-19 17:45:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static SchedXaction*
|
2010-08-22 06:10:12 -05:00
|
|
|
add_sx(gchar *name, const GDate *start, const GDate *end, const GDate *last_occur, Recurrence *r)
|
2007-01-19 17:45:45 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
QofBook *book = qof_session_get_book(gnc_get_current_session());
|
|
|
|
SchedXaction *sx = xaccSchedXactionMalloc(book);
|
|
|
|
xaccSchedXactionSetName(sx, name);
|
|
|
|
xaccSchedXactionSetStartDate(sx, start);
|
|
|
|
if (end != NULL)
|
|
|
|
xaccSchedXactionSetEndDate(sx, end);
|
|
|
|
if (last_occur != NULL)
|
|
|
|
xaccSchedXactionSetLastOccurDate(sx, last_occur);
|
|
|
|
{
|
|
|
|
GList *recurrences = NULL;
|
|
|
|
recurrences = g_list_append(recurrences, r);
|
|
|
|
gnc_sx_set_schedule(sx, recurrences);
|
|
|
|
}
|
2007-01-19 17:45:45 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
gnc_sxes_add_sx(gnc_book_get_schedxactions(book), sx);
|
2007-01-19 17:45:45 -06:00
|
|
|
|
2010-02-17 23:31:54 -06:00
|
|
|
return sx;
|
2007-01-19 17:45:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
SchedXaction*
|
2010-08-22 06:10:12 -05:00
|
|
|
add_daily_sx(gchar *name, const GDate *start, const GDate *end, const GDate *last_occur)
|
2007-01-19 17:45:45 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
return add_sx(name, start, end, last_occur, daily_freq(start, 1));
|
2007-01-19 17:45:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
SchedXaction*
|
2010-08-22 06:10:12 -05:00
|
|
|
add_once_sx(gchar *name, const GDate *when)
|
2007-01-19 17:45:45 -06:00
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
return add_sx(name, when, NULL, NULL, once_freq(when));
|
2007-01-19 17:45:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
remove_sx(SchedXaction *sx)
|
|
|
|
{
|
2010-02-17 23:31:54 -06:00
|
|
|
QofBook *book = qof_session_get_book(gnc_get_current_session());
|
|
|
|
SchedXactions *sxes = gnc_book_get_schedxactions(book);
|
|
|
|
gnc_sxes_del_sx(sxes, sx);
|
2007-01-19 17:45:45 -06:00
|
|
|
}
|