39 #include <kvp-frame.hpp> 43 #define __STDC_FORMAT_MACROS 45 #include <sys/types.h> 62 #include "gnc-session.h" 64 #include "TransactionP.hpp" 65 #include "Recurrence.h" 70 #include "test-stuff.h" 71 #include "test-engine-strings.h" 72 #include <qofinstance-p.h> 74 static GHashTable *exclude_kvp_types = NULL;
75 static gint kvp_max_depth = 5;
76 static gint kvp_frame_max_elements = 10;
78 static gint max_tree_depth = 1;
79 static gint max_level_accounts = 3;
80 static gint max_total_accounts = 10;
81 static gint max_trans_num = 1000;
82 static gint total_num_accounts = 0;
84 static gint max_scu = 100;
85 static gint min_scu = 100;
86 static const int64_t num_limit = INT64_MAX;
87 static const int64_t max_denom_mult = 1000000000LL;
96 static gint borked = 80;
98 gboolean gnc_engine_debug_random = FALSE;
104 set_max_account_tree_depth (gint max_tree_depth_in)
106 max_tree_depth = MAX (max_tree_depth_in, 1);
110 set_max_accounts_per_level (gint max_level_accounts_in)
112 max_level_accounts = MAX (max_level_accounts_in, 1);
116 set_max_kvp_depth (gint max_kvp_depth)
118 kvp_max_depth = MAX (max_kvp_depth, 1);
122 set_max_kvp_frame_elements (gint max_kvp_frame_elements)
124 kvp_frame_max_elements = MAX (max_kvp_frame_elements, 1);
128 kvp_type_excluded (KvpValue::Type kvp_type)
132 if (!exclude_kvp_types)
135 if (g_hash_table_lookup (exclude_kvp_types, &key))
143 static inline gboolean
146 if (1 == get_random_int_in_range (0, borked))
157 get_random_list_element (GList *list)
159 g_return_val_if_fail (list, NULL);
161 return g_list_nth_data (list,
162 get_random_int_in_range (0,
163 g_list_length (list) - 1));
166 static KvpValue* get_random_kvp_value_depth (
int type, gint depth);
169 get_random_glist_depth (gint depth)
172 int count = get_random_int_in_range(1, 5);
175 if (depth >= kvp_max_depth)
178 for (i = 0; i < count; i++)
180 KvpValue *value =
nullptr;
184 value = get_random_kvp_value_depth (-2, depth + 1);
188 ret = g_list_prepend(ret, value);
198 get_random_time (
void)
207 get_random_guid(
void)
215 static KvpFrame* get_random_kvp_frame_depth (gint depth);
218 get_random_kvp_value_depth (
int type, gint depth)
220 KvpValue::Type datype;
225 datype =
static_cast<KvpValue::Type
>(get_random_int_in_range(KvpValue::Type::INT64, KvpValue::Type::FRAME));
230 datype =
static_cast<KvpValue::Type
>(get_random_int_in_range(KvpValue::Type::INT64, KvpValue::Type::FRAME - 1));
233 datype =
static_cast<KvpValue::Type
>(type);
235 if (datype == KvpValue::Type::FRAME && depth >= kvp_max_depth)
238 if (datype == KvpValue::Type::GLIST && depth >= kvp_max_depth)
241 if (kvp_type_excluded (datype))
246 case KvpValue::Type::INT64:
247 ret =
new KvpValue(get_random_gint64());
250 case KvpValue::Type::DOUBLE:
254 case KvpValue::Type::NUMERIC:
258 case KvpValue::Type::STRING:
261 tmp_str = get_random_string();
265 ret =
new KvpValue(tmp_str);
269 case KvpValue::Type::GUID:
271 return new KvpValue(get_random_guid());
275 case KvpValue::Type::TIME64:
277 time64 t = get_random_time();
278 ret =
new KvpValue(t);
282 case KvpValue::Type::GLIST:
283 ret =
new KvpValue(get_random_glist_depth (depth + 1));
286 case KvpValue::Type::FRAME:
288 return new KvpValue(get_random_kvp_frame_depth(depth + 1));
300 get_random_kvp_frame_depth (gint depth)
305 if (depth >= kvp_max_depth)
308 auto ret =
new KvpFrame;
310 vals_to_add = get_random_int_in_range(1, kvp_frame_max_elements);
313 for (; vals_to_add > 0; vals_to_add--)
321 key = get_random_string_without(
"/");
329 val = get_random_kvp_value_depth (-1, depth + 1);
340 ret->set_path({key}, val);
349 get_random_kvp_frame (
void)
351 return get_random_kvp_frame_depth (0);
355 get_random_kvp_value(
int type)
357 return get_random_kvp_value_depth (type, 0);
363 #define RAND_IN_RANGE(X) (((X)*((gint64) (rand()+1)))/RAND_MAX) 366 get_random_gnc_numeric(int64_t deno)
372 if (RAND_MAX / 8 > rand())
375 deno = RAND_IN_RANGE(6000ULL);
379 gint64 norm = RAND_IN_RANGE (11ULL);
391 if (0 == deno) deno = 1;
399 limit = num_limit / (max_denom_mult / deno == 0 ? max_denom_mult : max_denom_mult / deno);
400 numer = get_random_gint64 ();
403 int64_t num = numer % limit;
409 if (0 == numer) numer = 1;
410 g_log(
"test.engine.suff", G_LOG_LEVEL_INFO,
"New GncNumeric %" PRIu64
" / %" PRIu64
" !\n", numer, deno);
411 return gnc_numeric_create(numer, deno);
418 get_random_rate (
void)
422 gint64 numer = get_random_gint64 () % (2ULL << 24);
423 gint64 denom = 100LL;
424 return gnc_numeric_create (numer, denom);
430 const char *types[] =
441 get_random_commodity_namespace(
void)
443 return get_random_string_in_array(types);
446 static gnc_commodity *
447 get_random_commodity_from_table (gnc_commodity_table *
table)
450 gnc_commodity *com = NULL;
452 g_return_val_if_fail (
table, NULL);
461 name_space =
static_cast<char*
>(get_random_list_element (namespaces));
467 com =
static_cast<gnc_commodity*
>(get_random_list_element (commodities));
469 g_list_free (commodities);
475 g_list_free (namespaces);
481 get_random_commodity (QofBook *book)
489 gnc_commodity_table *
table;
496 get_random_int_in_range (1, 5) < 5)
497 return get_random_commodity_from_table (
table);
500 mn = get_random_string_length_in_range(1, 3);
501 space = get_random_commodity_namespace();
505 ret = gnc_commodity_table_lookup (
table, space, mn);
514 name = get_random_string();
515 cusip = get_random_string();
517 ran_int = get_random_int_in_range(min_scu, max_scu);
532 make_random_changes_to_commodity (gnc_commodity *com)
536 g_return_if_fail (com);
538 str = get_random_string ();
542 str = get_random_string ();
546 str = get_random_string ();
550 str = get_random_string ();
558 make_random_changes_to_commodity_table (gnc_commodity_table *
table)
563 g_return_if_fail (
table);
567 for (node = namespaces; node; node = node->next)
569 auto ns =
static_cast<const char *
>(node->data);
578 for (com_node = commodities; com_node; com_node = com_node->next)
580 auto com =
static_cast<gnc_commodity *
>(com_node->data);
583 make_random_changes_to_commodity (com);
587 g_list_free (commodities);
590 g_list_free (namespaces);
596 make_random_changes_to_price (QofBook *book, GNCPrice *p)
603 g_return_if_fail (book && p);
605 gnc_price_begin_edit (p);
607 c = get_random_commodity (book);
608 gnc_price_set_commodity (p, c);
610 c = get_random_commodity (book);
611 gnc_price_set_currency (p, c);
613 time = get_random_time ();
614 gnc_price_set_time64 (p, time);
616 ps = (
PriceSource)get_random_int_in_range((
int)PRICE_SOURCE_EDIT_DLG,
617 (int)PRICE_SOURCE_INVALID);
618 gnc_price_set_source (p, ps);
620 string = get_random_string ();
621 gnc_price_set_typestr (p,
string);
626 gnc_price_commit_edit (p);
630 get_random_price(QofBook *book)
637 failure_args(
"engine-stuff", __FILE__, __LINE__,
638 "get_random_price failed");
642 make_random_changes_to_price (book, p);
645 failure_args(
"engine-stuff", __FILE__, __LINE__,
646 "make_random_changes_to_price failed");
654 make_random_pricedb (QofBook *book, GNCPriceDB *db)
658 num_prices = get_random_int_in_range (1, 41);
661 failure_args(
"engine-stuff", __FILE__, __LINE__,
662 "get_random_int_in_range failed");
666 while (num_prices-- > 0)
670 p = get_random_price (book);
673 failure_args(
"engine-stuff", __FILE__, __LINE__,
674 "get_random_price failed");
688 get_random_pricedb(QofBook *book)
695 failure_args(
"engine-stuff", __FILE__, __LINE__,
696 "gnc_pricedb_get_db failed");
699 if (!make_random_pricedb (book, db))
708 price_accumulator (GNCPrice *p, gpointer data)
710 auto list =
static_cast<GList**
>(data);
712 *list = g_list_prepend (*list, p);
718 make_random_changes_to_pricedb (QofBook *book, GNCPriceDB *pdb)
723 g_return_if_fail (pdb);
727 for (node = list; node; node = node->next)
729 auto p =
static_cast<GNCPrice *
>(node->data);
731 switch (get_random_int_in_range (0, 5))
739 make_random_changes_to_price (book, p);
751 int i = get_random_int_in_range (1, 5);
755 GNCPrice *p = get_random_price (book);
768 set_account_random_string(
Account* act,
769 void(*func)(
Account *act,
const gchar*str))
771 gchar *tmp_str = get_random_string();
774 (func)(act, tmp_str);
780 set_account_random_string_from_array(
784 const gchar *tmp_str = get_random_string_in_array(list);
786 (func)(act, tmp_str);
791 account_add_subaccounts (QofBook *book,
Account *account,
int depth)
798 num_accounts = get_random_int_in_range (1, 10);
799 while (num_accounts-- > 0)
801 Account *sub = get_random_account (book);
805 total_num_accounts ++;
806 if (total_num_accounts > max_total_accounts)
return;
808 account_add_subaccounts (book, sub, depth - 1);
813 make_random_account_tree (QofBook *book,
Account *root)
817 g_return_if_fail (book);
818 g_return_if_fail (root);
820 total_num_accounts = 0;
821 depth = get_random_int_in_range (1, max_tree_depth);
823 account_add_subaccounts (book, root, depth);
826 if (total_num_accounts <= 1)
827 account_add_subaccounts (book, root, 1);
831 get_random_account_tree (QofBook *book)
835 g_return_val_if_fail (book, NULL);
837 root = gnc_book_get_root_account (book);
841 gnc_book_set_root_account (book, root);
844 make_random_account_tree (book, root);
858 add_random_splits(QofBook *book, Transaction *trn, GList *account_list)
865 if (1 >= g_list_length (account_list))
return;
867 auto acc =
static_cast<Account*
>(get_random_list_element (account_list));
869 s1 = get_random_split(book, acc, trn);
871 auto bcc =
static_cast<Account*
>(get_random_list_element (account_list));
872 if ((bcc == acc) && (!do_bork()))
880 bcc =
static_cast<Account*
>(get_random_list_element (account_list));
886 s2 = get_random_split(book, bcc, trn);
892 val = get_random_gnc_numeric(s2_scu);
893 g_log (
"test.engine.suff", G_LOG_LEVEL_DEBUG,
"Borking second %" PRIu64
894 " / %" PRIu64
", scu %d\n", val.num, val.denom, s2_scu);
898 if (val.denom != s2_scu)
900 if (val.denom > s2_scu)
901 val.num /= val.denom / s2_scu;
914 make_random_changes_to_transaction_and_splits (QofBook *book,
922 g_return_if_fail (book);
923 g_return_if_fail (trans);
924 g_return_if_fail (accounts);
928 make_random_changes_to_transaction (book, trans);
930 switch (get_random_int_in_range (0, 3))
944 add_random_splits (book, trans, accounts);
953 for (node = splits; node; node = node->next)
955 auto split =
static_cast<Split *
>(node->data);
956 auto account =
static_cast<Account*
>(get_random_list_element (accounts));
979 for (node = splits; node; node = node->next)
981 auto split =
static_cast<Split *
>(node->data);
983 if (get_random_boolean ())
984 make_random_changes_to_split (split);
987 if (get_random_boolean ())
994 add_trans_helper (Transaction *trans, gpointer data)
997 auto list =
static_cast<GList **
>(data);
1003 *list = g_list_prepend (*list, ti);
1008 make_random_changes_to_level (QofBook *book,
Account *parent)
1017 g_return_if_fail (parent && book);
1022 new_account = get_random_account (book);
1024 if (get_random_boolean () || !accounts)
1028 account =
static_cast<Account*
>(get_random_list_element (accounts));
1033 g_list_free (accounts);
1037 add_random_transactions_to_book (book, get_random_int_in_range (1, 6));
1040 for (node = accounts; node; node = node->next)
1042 auto account =
static_cast<Account *
>(node->data);
1044 if (get_random_boolean ())
1045 make_random_changes_to_account (book, account);
1052 for (node = transes; node; node = node->next)
1054 auto ti =
static_cast<TransInfo *
>(node->data);
1060 make_random_changes_to_transaction_and_splits (book, trans, accounts);
1063 for (node = transes; node; node = node->next)
1065 auto ti =
static_cast<TransInfo *
>(node->data);
1069 g_list_free (transes);
1073 account =
static_cast<Account*
>(get_random_list_element (accounts));
1077 for (node = splits; node; node = node->next)
1079 auto split =
static_cast<Split *
>(node->data);
1083 new_account =
static_cast<Account*
>(get_random_list_element (accounts));
1085 while (new_account == account);
1093 g_list_free (splits);
1094 g_list_free (accounts);
1099 if (accounts && (g_list_length (accounts) > 1))
1101 int i = get_random_int_in_range (1, 4);
1107 auto a1 =
static_cast<Account*
>(get_random_list_element (accounts));
1109 if (get_random_boolean ())
1110 a2 = static_cast<Account*>(get_random_list_element (accounts));
1132 g_list_free (accounts);
1136 get_random_account(QofBook *book)
1146 sane_account_names);
1156 qof_instance_set_slots(QOF_INSTANCE(ret), get_random_kvp_frame());
1158 root = gnc_book_get_root_account (book);
1162 gnc_book_set_root_account (book, root);
1171 make_random_changes_to_account (QofBook *book,
Account *account)
1175 g_return_if_fail (account);
1189 qof_instance_set_slots(QOF_INSTANCE(account), get_random_kvp_frame());
1195 set_split_random_string(Split *spl,
1196 void(*func)(Split *act,
const gchar*str))
1198 gchar *tmp_str = get_random_string();
1201 (func)(spl, tmp_str);
1210 get_random_split(QofBook *book,
Account *acct, Transaction *trn)
1213 gnc_numeric amt = {0, 1}, val = {0, 1}, rate = {0, 0};
1224 str = get_random_string_in_array(sane_descriptions);
1226 str = get_random_string_in_array(sane_actions);
1231 time = get_random_time();
1237 xaccSplitSetParent(ret, trn);
1238 xaccSplitSetAccount(ret, acct);
1242 val = get_random_gnc_numeric (scu);
1244 fprintf(stderr,
"get_random_split: Created split with zero value: %p\n", ret);
1251 if (val.denom > scu && val.num > num_limit / (max_denom_mult / scu))
1253 int64_t new_num = val.num / (val.denom / scu);
1254 g_log(
"test.engine.suff", G_LOG_LEVEL_DEBUG,
1255 "Adjusting val.denom from %" PRIu64
" to %" PRIu64
"\n",
1263 g_log (
"test.engine.suff", G_LOG_LEVEL_DEBUG,
1264 "Random split value: %" PRIu64
" / %" PRIu64
", scu %d\n",
1265 val.num, val.denom, scu);
1282 rate = get_random_rate ();
1287 g_log (
"test.engine.suff", G_LOG_LEVEL_DEBUG,
"Random split amount: %" 1288 PRIu64
" / %" PRIu64
", rate %" PRIu64
" / %" PRIu64
"\n",
1289 amt.num, amt.denom, rate.num, rate.denom);
1303 qof_instance_set_slots(QOF_INSTANCE (ret), get_random_kvp_frame());
1310 make_random_changes_to_split (Split *split)
1315 g_return_if_fail (split);
1326 time = get_random_time();
1329 qof_instance_set_slots (QOF_INSTANCE (split), get_random_kvp_frame());
1339 set_tran_random_string(Transaction* trn,
1340 void(*func)(Transaction *act,
const gchar*str))
1342 gchar *tmp_str = get_random_string();
1350 (func)(trn, tmp_str);
1357 set_tran_random_string_from_array(
1358 Transaction* trn,
void(*func)(Transaction *trn,
const gchar*str),
1359 const gchar *list[])
1361 const gchar *tmp_str = get_random_string_in_array(list);
1363 (func)(trn, tmp_str);
1367 trn_add_ran_time (Transaction *trn,
void (*func)(Transaction*,
time64))
1369 func(trn, get_random_time());
1374 get_random_transaction_with_currency(QofBook *book,
1375 gnc_commodity *currency,
1376 GList *account_list)
1387 if (1 >= g_list_length (account_list))
1389 failure_args(
"engine-stuff", __FILE__, __LINE__,
1390 "get_random_transaction_with_currency: account_list too short");
1399 currency ? currency :
1400 get_random_commodity (book));
1402 gint num = get_random_int_in_range (1, max_trans_num);
1403 auto numstr = std::to_string(num);
1411 f = get_random_kvp_frame();
1412 qof_instance_set_slots (QOF_INSTANCE (trans), f);
1414 add_random_splits(book, trans, account_list);
1416 if (get_random_int_in_range (1, 10) == 1)
1418 char *reason = get_random_string ();
1426 failure_args(
"engine-stuff", __FILE__, __LINE__,
1427 "get_random_transaction_with_currency failed");
1435 get_random_transaction (QofBook *book)
1439 g_return_val_if_fail(book, NULL);
1440 ret = get_random_transaction_with_currency (book, NULL, NULL);
1443 failure_args(
"engine-stuff", __FILE__, __LINE__,
1444 "get_random_transaction failed");
1451 make_random_changes_to_transaction (QofBook *book, Transaction *trans)
1453 g_return_if_fail (trans && book);
1457 if (get_random_int_in_range (1, 2) == 1)
1473 qof_instance_set_slots (QOF_INSTANCE (trans), get_random_kvp_frame());
1482 get_random_guids(
int max)
1484 GList *guids = NULL;
1487 if (max < 1)
return NULL;
1489 num_guids = get_random_int_in_range (1, max);
1491 while (num_guids-- > 0)
1492 guids = g_list_prepend (guids, get_random_guid ());
1498 free_guids(GList *guids)
1500 g_list_free_full (guids, (GDestroyNotify)guid_free);
1504 get_random_queryop(
void)
1506 int op_num = get_random_int_in_range(1, 11);
1526 op = QOF_QUERY_NAND;
1535 g_assert_not_reached();
1538 if (gnc_engine_debug_random) printf (
"op = %d (int was %d), ", op, op_num);
1543 get_random_id_type (
void)
1545 switch (get_random_int_in_range (1, 3))
1548 return GNC_ID_SPLIT;
1550 return GNC_ID_TRANS;
1552 return GNC_ID_ACCOUNT;
1554 return get_random_string ();
1572 set_query_sort (
QofQuery *q, sort_type_t sort_code)
1574 GSList *p1 = NULL, *p2 = NULL, *p3 = NULL, *standard;
1584 p1 = g_slist_prepend (p1, const_cast<char*>(TRANS_DATE_POSTED));
1585 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_TRANS));
1588 case BY_DATE_ENTERED:
1589 p1 = g_slist_prepend (p1, const_cast<char*>(TRANS_DATE_ENTERED));
1590 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_TRANS));
1593 case BY_DATE_RECONCILED:
1594 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_RECONCILE));
1595 p2 = g_slist_prepend (p2, const_cast<char*>(SPLIT_DATE_RECONCILED));
1599 p1 = g_slist_prepend (p1, const_cast<char*>(TRANS_NUM));
1600 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_TRANS));
1604 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_VALUE));
1608 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_MEMO));
1612 p1 = g_slist_prepend (p1, const_cast<char*>(TRANS_DESCRIPTION));
1613 p1 = g_slist_prepend (p1, const_cast<char*>(SPLIT_TRANS));
1617 g_slist_free (standard);
1620 g_slist_free (standard);
1621 g_return_if_fail (FALSE);
1628 template <
typename T>
inline T
1629 compare_param(
int max)
1631 auto ret = get_random_int_in_range (max == 1 ? 0 : 1, max);
1632 return static_cast<T
>(ret);
1636 get_random_query(
void)
1641 num_terms = get_random_int_in_range (1, 3);
1642 if (gnc_engine_debug_random) printf(
"num_terms = %d", num_terms);
1644 q = qof_query_create_for(GNC_ID_SPLIT);
1646 while (num_terms-- > 0)
1655 pr_type = get_random_int_in_range (1, 20);
1656 if (gnc_engine_debug_random) printf(
"\n pr_type = %d ", pr_type);
1661 guids = get_random_guids (10);
1662 xaccQueryAddAccountGUIDMatch
1665 compare_param<QofGuidMatch>(QOF_GUID_MATCH_NONE),
1666 get_random_queryop ());
1671 string = get_random_string_without (
"\\");
1672 xaccQueryAddActionMatch (q,
1674 get_random_boolean (),
1675 get_random_boolean (),
1676 compare_param<QofQueryCompare>(QOF_COMPARE_CONTAINS),
1677 get_random_queryop ());
1682 xaccQueryAddBalanceMatch
1684 compare_param<QofQueryCompare> (1),
1685 get_random_queryop ());
1689 xaccQueryAddClearedMatch
1691 static_cast<cleared_match_t>(get_random_int_in_range (1,
1694 CLEARED_RECONCILED |
1697 get_random_queryop ());
1701 start = get_random_time ();
1702 end = get_random_time ();
1703 xaccQueryAddDateMatchTT (q,
1704 get_random_boolean (),
1706 get_random_boolean (),
1708 get_random_queryop ());
1712 string = get_random_string_without (
"\\");
1713 xaccQueryAddDescriptionMatch (q,
1715 get_random_boolean (),
1716 get_random_boolean (),
1717 compare_param<QofQueryCompare>(QOF_COMPARE_CONTAINS),
1718 get_random_queryop ());
1723 guid = get_random_guid ();
1724 xaccQueryAddGUIDMatch (q,
1726 get_random_id_type (),
1727 get_random_queryop ());
1735 string = get_random_string_without (
"\\");
1736 xaccQueryAddMemoMatch (q,
1738 get_random_boolean (),
1739 get_random_boolean (),
1740 compare_param<QofQueryCompare>(QOF_COMPARE_CONTAINS),
1741 get_random_queryop ());
1746 string = get_random_string_without (
"\\");
1747 xaccQueryAddNumberMatch (q,
1749 get_random_boolean (),
1750 get_random_boolean (),
1751 compare_param<QofQueryCompare>(QOF_COMPARE_CONTAINS),
1752 get_random_queryop ());
1757 xaccQueryAddSharePriceMatch
1760 compare_param<QofQueryCompare> (QOF_COMPARE_NEQ),
1761 get_random_queryop ());
1765 xaccQueryAddSharesMatch
1768 compare_param<QofQueryCompare> (QOF_COMPARE_NEQ),
1769 get_random_queryop ());
1773 xaccQueryAddValueMatch
1776 compare_param<QofNumericMatch> (QOF_NUMERIC_MATCH_ANY),
1777 compare_param<QofQueryCompare> (QOF_COMPARE_NEQ),
1778 get_random_queryop ());
1782 if (gnc_engine_debug_random) printf(
"ignored..");
1788 if (gnc_engine_debug_random) printf (
"\n");
1789 set_query_sort (q, compare_param<sort_type_t>(BY_NONE));
1792 get_random_boolean (),
1793 get_random_boolean (),
1794 get_random_boolean ());
1802 get_random_book (
void)
1808 get_random_account_tree (book);
1809 get_random_pricedb (book);
1815 get_random_session (
void)
1818 auto session = qof_session_new (book);
1820 get_random_account_tree (book);
1821 get_random_pricedb (book);
1827 add_random_transactions_to_book (QofBook *book, gint num_transactions)
1829 gnc_commodity_table *
table;
1832 if (num_transactions <= 0)
return;
1834 g_return_if_fail (book);
1837 g_return_if_fail (accounts);
1841 while (num_transactions--)
1845 com = get_random_commodity_from_table (
table);
1846 get_random_transaction_with_currency (book, com, accounts);
1848 g_list_free (accounts);
1852 make_random_changes_to_book (QofBook *book)
1854 g_return_if_fail (book);
1856 make_random_changes_to_level (book, gnc_book_get_root_account (book));
1865 make_random_changes_to_session (QofSession *session)
1867 g_return_if_fail (session);
1879 static gboolean include_price = TRUE;
1882 trans_query_include_price (gboolean include_price_in)
1884 include_price = include_price_in;
1888 get_random_query_type (
void)
1890 switch (get_random_int_in_range (0, 1))
1902 make_trans_query (Transaction *trans, TestQueryTypes query_types)
1909 if (query_types == RANDOM_QT)
1910 query_types = get_random_query_type ();
1912 q = qof_query_create_for(GNC_ID_SPLIT);
1917 if (query_types & SIMPLE_QT)
1924 TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
1930 TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
1936 TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
1940 xaccQueryAddValueMatch (q, n, QOF_NUMERIC_MATCH_ANY,
1941 QOF_COMPARE_EQUAL, QOF_QUERY_AND);
1944 xaccQueryAddSharesMatch (q, n, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
1949 xaccQueryAddSharePriceMatch (q, n, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
1954 xaccQueryAddDateMatchTT (q, TRUE, time, TRUE, time, QOF_QUERY_AND);
1959 xaccQueryAddMemoMatch (q,
xaccSplitGetMemo (s), TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
1963 cleared_match_t how;
1971 how = CLEARED_CLEARED;
1974 how = CLEARED_RECONCILED;
1977 how = CLEARED_FROZEN;
1980 how = CLEARED_VOIDED;
1983 failure (
"bad reconcile flag");
1988 xaccQueryAddClearedMatch (q, how, QOF_QUERY_AND);
1992 if (query_types & ACCOUNT_QT)
2001 auto split =
static_cast<Split *
>(node->data);
2009 list = g_list_prepend (list, get_random_guid ());
2010 list = g_list_prepend (list, get_random_guid ());
2011 list = g_list_prepend (list, get_random_guid ());
2012 xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_NONE, QOF_QUERY_AND);
2016 GncGUID * guid = get_random_guid ();
2018 list = g_list_prepend (list, guid);
2025 if (query_types & GUID_QT)
2028 GNC_ID_SPLIT, QOF_QUERY_AND);
2031 GNC_ID_TRANS, QOF_QUERY_AND);
2034 GNC_ID_ACCOUNT, QOF_QUERY_AND);
2041 daily_freq(
const GDate* start,
int multiplier)
2044 recurrenceSet(r, multiplier, PERIOD_DAY, start, WEEKEND_ADJ_NONE);
2049 once_freq(
const GDate *when)
2052 recurrenceSet(r, 1, PERIOD_ONCE, when, WEEKEND_ADJ_NONE);
2056 static SchedXaction*
2057 add_sx(
const gchar *name,
const GDate *start,
const GDate *end,
2063 xaccSchedXactionSetStartDate(sx, start);
2066 if (last_occur != NULL)
2067 xaccSchedXactionSetLastOccurDate(sx, last_occur);
2069 GList *recurrences = NULL;
2070 recurrences = g_list_append(recurrences, r);
2074 gnc_sxes_add_sx(gnc_book_get_schedxactions(book), sx);
2080 add_daily_sx(
const gchar *name,
const GDate *start,
2081 const GDate *end,
const GDate *last_occur)
2083 return add_sx(name, start, end, last_occur, daily_freq(start, 1));
2087 add_once_sx(
const gchar *name,
const GDate *when)
2089 return add_sx(name, when, NULL, NULL, once_freq(when));
2093 remove_sx(SchedXaction *sx)
2096 SchedXactions *sxes = gnc_book_get_schedxactions(book);
2097 gnc_sxes_del_sx(sxes, sx);
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account's type.
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
Add a new commodity to the commodity table.
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1...
int xaccAccountTreeForEachTransaction(Account *acc, TransactionCallback proc, void *data)
Traverse all of the transactions in the given account group.
This is the private header for the account structure.
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void xaccSplitSetAction(Split *split, const char *actn)
The Action is an arbitrary user-assigned string.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship, and will then add the account as a child of the new parent.
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
SplitList * xaccAccountGetSplitList(const Account *acc)
The xaccAccountGetSplitList() routine returns a pointer to a GList of the splits in the account...
void qof_query_set_sort_order(QofQuery *q, QofQueryParamList *params1, QofQueryParamList *params2, QofQueryParamList *params3)
When a query is run, the results are sorted before being returned.
gboolean xaccSplitDestroy(Split *split)
Destructor.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void gnc_price_unref(GNCPrice *p)
gnc_price_unref - indicate you're finished with a price (i.e.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
GncGUID * guid_new(void)
Allocate and construct a new GUID.
void gnc_commodity_set_fraction(gnc_commodity *cm, int fraction)
Set the fraction for the specified commodity.
char xaccSplitGetReconcile(const Split *split)
Returns the value of the reconcile flag.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void xaccAccountSetCode(Account *acc, const char *str)
Set the account's accounting code.
QofBook * qof_book_new(void)
Allocate, initialise and return a new QofBook.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
void xaccTransSetNum(Transaction *trans, const char *xnum)
Sets the transaction Number (or ID) field; rather than use this function directly, see 'gnc_set_num_action' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically.
stop here; the following types just aren't ready for prime time
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
void qof_query_set_sort_increasing(QofQuery *q, gboolean prim_inc, gboolean sec_inc, gboolean tert_inc)
When a query is run, the results are sorted before being returned.
$brief This file declares testing functions for the engine.
const char * xaccTransGetNum(const Transaction *trans)
Gets the transaction Number (or ID) field; rather than use this function directly, see 'gnc_get_num_action' and 'gnc_get_action_num' in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically.
These expect a single object and expect the QofAccessFunc returns GncGUID*.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
#define VREC
split is void
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
void qof_query_set_max_results(QofQuery *q, int n)
Set the maximum number of results that should be returned.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
void xaccAccountDestroy(Account *acc)
The xaccAccountDestroy() routine can be used to get rid of an account.
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
The xaccTransLookup() subroutine will return the transaction associated with the given id...
const gchar * QofIdType
QofIdType declaration.
#define xaccAccountGetGUID(X)
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Account handling public routines.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
void xaccTransVoid(Transaction *trans, const char *reason)
xaccTransVoid voids a transaction.
#define YREC
The Split has been reconciled.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
Set the 'exchange code' for the specified commodity.
#define FREC
frozen into accounting period
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
Create a new commodity.
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
Anchor Scheduled Transaction info in a book.
The bank account type denotes a savings or checking account held at a bank.
gboolean gnc_commodity_namespace_is_iso(const char *name_space)
Checks to see if the specified commodity namespace is the namespace for ISO 4217 currencies.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
#define xaccSplitGetGUID(X)
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
gnc_numeric xaccSplitGetSharePrice(const Split *split)
Returns the price of the split, that is, the value divided by the amount.
void xaccTransUnvoid(Transaction *trans)
xaccTransUnvoid restores a voided transaction to its original state.
All type declarations for the whole Gnucash engine.
These expect a GList* of objects and calls the QofAccessFunc routine on each item in the list to obta...
#define CREC
The Split has been cleared.
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
gboolean gnc_pricedb_remove_price(GNCPriceDB *db, GNCPrice *p)
Remove a price from the pricedb and unref the price.
Split * xaccMallocSplit(QofBook *book)
Constructor.
#define xaccTransGetGUID(X)
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
Return a list of all commodities in the commodity table that are in the given namespace.
void xaccSplitSetDateReconciledSecs(Split *split, time64 secs)
Set the date on which this split was reconciled by specifying the time as time64. ...
void xaccSchedXactionSetName(SchedXaction *sx, const gchar *newName)
A copy of the name is made.
QofQueryOp
Query Term Operators, for combining Query Terms.
void xaccTransSetDatePostedSecs(Transaction *trans, time64 secs)
The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction, specified by a time64 (see ctime(3)).
gboolean xaccTransGetVoidStatus(const Transaction *trans)
Retrieve information on whether or not a transaction has been voided.
void gnc_commodity_set_fullname(gnc_commodity *cm, const char *fullname)
Set the full name for the specified commodity.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor)
Returns true if the account is 'ancestor' or has 'ancestor' as an ancestor.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
void gnc_commodity_set_mnemonic(gnc_commodity *cm, const char *mnemonic)
Set the mnemonic for the specified commodity.
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
PriceSource
Price source enum.
#define QUERY_DEFAULT_SORT
Default sort object type.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
Account * xaccMallocAccount(QofBook *book)
Constructor.
void gnc_commodity_table_remove(gnc_commodity_table *table, gnc_commodity *comm)
Remove a commodity from the commodity table.
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
Set the namespace for the specified commodity.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
Check for error signal in value.
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
const char * xaccSplitGetAction(const Split *split)
Returns the action string.
SchedXaction * xaccSchedXactionMalloc(QofBook *book)
Creates and initializes a scheduled transaction.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
guint gnc_commodity_table_get_size(const gnc_commodity_table *tbl)
Returns the number of commodities in the commodity table.
gboolean gnc_pricedb_foreach_price(GNCPriceDB *db, GncPriceForeachFunc f, gpointer user_data, gboolean stable_order)
Call a GncPriceForeachFunction once for each price in db, until the function returns FALSE...
void xaccAccountSetDescription(Account *acc, const char *str)
Set the account's description.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
Scheduled Transactions public handling routines.
void xaccSchedXactionSetEndDate(SchedXaction *sx, const GDate *newEnd)
Set to an invalid GDate to turn off 'end-date' definition.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
API for Transactions and Splits (journal entries)
The type used to store guids in C.
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
void xaccAccountSetName(Account *acc, const char *str)
Set the account's name.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
void xaccTransRollbackEdit(Transaction *trans)
The xaccTransRollbackEdit() routine rejects all edits made, and sets the transaction back to where it...
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account's commodity.
#define NREC
not reconciled or cleared
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.