QOF: test-engine-stuff.c Source File

QOF 0.7.5

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

test-engine-stuff.c
Go to the documentation of this file.
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
15 */
16
25 #include <sys/types.h>
26 #include <dirent.h>
27 #include <fcntl.h>
28 #include <glib.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include "config.h"
35 #include "qof.h"
36 #include "test-engine-stuff.h"
37 #include "test-stuff.h"
38
39 static gboolean glist_strings_only = FALSE;
40
41 static GHashTable *exclude_kvp_types = NULL;
42 static gint kvp_max_depth = 5;
43 static gint kvp_frame_max_elements = 10;
44
45 gboolean gnc_engine_debug_random = FALSE;
46
47 /* ========================================================== */
48 /* Set control parameters governing the run. */
49
50 void
51 set_max_kvp_depth (gint max_kvp_depth)
52 {
53 kvp_max_depth = MAX (max_kvp_depth, 1);
54 }
55
56 void
57 set_max_kvp_frame_elements (gint max_kvp_frame_elements)
58 {
59 kvp_frame_max_elements = MAX (max_kvp_frame_elements, 1);
60 }
61
62 void
63 kvp_exclude_type (KvpValueType kvp_type)
64 {
65 gint *key;
66
67 if (!exclude_kvp_types)
68 exclude_kvp_types = g_hash_table_new (g_int_hash, g_int_equal);
69
70 key = g_new (gint, 1);
71 *key = kvp_type;
72
73 g_hash_table_insert (exclude_kvp_types, key, exclude_kvp_types);
74 }
75
76 static gboolean
77 kvp_type_excluded (KvpValueType kvp_type)
78 {
79 gint key = kvp_type;
80
81 if (!exclude_kvp_types)
82 return FALSE;
83
84 if (g_hash_table_lookup (exclude_kvp_types, &key))
85 return TRUE;
86
87 return FALSE;
88 }
89
90 void
91 random_glist_strings_only (gboolean strings_only)
92 {
93 glist_strings_only = strings_only;
94 }
95
96
97 #ifndef QOF_DISABLE_DEPRECATED
98 static gboolean zero_nsec = FALSE;
99
100 void
101 random_timespec_zero_nsec (gboolean zero_nsec_in)
102 {
103 zero_nsec = zero_nsec_in;
104 }
105
106 static gboolean usec_resolution = FALSE;
107
108 void
109 random_timespec_usec_resolution (gboolean usec_resolution_in)
110 {
111 usec_resolution = usec_resolution_in;
112 }
113 #endif
114 /* ========================================================== */
115
116 static gint borked = 80;
117
118 static inline gboolean
119 do_bork (void)
120 {
121 if (1 == get_random_int_in_range (0, borked))
122 {
123 return TRUE;
124 }
125 return FALSE;
126 }
127
128 /* ========================================================== */
129 /* GList stuff */
130 /*
131 static gpointer
132 get_random_list_element (GList *list)
133 {
134 g_return_val_if_fail (list, NULL);
135
136 return g_list_nth_data (list,
137 get_random_int_in_range (0,
138 g_list_length (list) - 1));
139 }
140 */
141 static KvpValue *get_random_kvp_value_depth (int type, gint depth);
142
143 static GList *
144 get_random_glist_depth (gint depth)
145 {
146 GList *ret = NULL;
147 int count = get_random_int_in_range (1, 5);
148 int i;
149
150 if (depth >= kvp_max_depth)
151 return NULL;
152
153 for (i = 0; i < count; i++)
154 {
155 KvpValueType kvpt;
156 KvpValue *value;
157
158 kvpt = glist_strings_only ? KVP_TYPE_STRING : -2;
159
160 do
161 {
162 value = get_random_kvp_value_depth (kvpt, depth + 1);
163 }
164 while (!value);
165
166 ret = g_list_prepend (ret, value);
167 }
168
169 return ret;
170 }
171
172 GList *
173 get_random_glist (void)
174 {
175 return get_random_glist_depth (0);
176 }
177
178 /* ========================================================== */
179 /* Time/Date, GUID, binary data stuff */
180 #ifndef QOF_DISABLE_DEPRECATED
181 Timespec *
182 get_random_timespec (void)
183 {
184 Timespec *ret;
185
186 ret = g_new0 (Timespec, 1);
187
188 while (ret->tv_sec <= 0)
189 ret->tv_sec = rand ();
190
191 if (zero_nsec)
192 ret->tv_nsec = 0;
193 else
194 {
195 ret->tv_nsec = rand ();
196
197 if (usec_resolution)
198 {
199 ret->tv_nsec = MIN (ret->tv_nsec, 999999999);
200 ret->tv_nsec /= 1000;
201 ret->tv_nsec *= 1000;
202 }
203 }
204
205 return ret;
206 }
207 #endif
208
209 GUID *
210 get_random_guid (void)
211 {
212 GUID *ret;
213
214 ret = g_new (GUID, 1);
215 guid_new (ret);
216
217 return ret;
218 }
219
220 bin_data *
221 get_random_binary_data (void)
222 {
223 int len;
224 bin_data *ret;
225
226 len = get_random_int_in_range (20, 100);
227 ret = g_new (bin_data, 1);
228 ret->data = g_new (guchar, len);
229 ret->len = len;
230
231 for (len--; len >= 0; len--)
232 {
233 ret->data[len] = (guchar) get_random_int_in_range (0, 255);
234 }
235
236 return ret;
237 }
238
239 /* ========================================================== */
240 /* KVP stuff */
241
242 static KvpFrame *get_random_kvp_frame_depth (gint depth);
243
244 static KvpValue *
245 get_random_kvp_value_depth (int type, gint depth)
246 {
247 int datype = type;
248 KvpValue *ret;
249
250 if (datype == -1)
251 {
252 datype = get_random_int_in_range (KVP_TYPE_GINT64, KVP_TYPE_FRAME);
253 }
254
255 if (datype == -2)
256 {
257 datype =
258 get_random_int_in_range (KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1);
259 }
260
261 if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth)
262 return NULL;
263
264 if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth)
265 return NULL;
266
267 if (kvp_type_excluded (datype))
268 return NULL;
269
270 switch (datype)
271 {
272 case KVP_TYPE_GINT64:
273 ret = kvp_value_new_gint64 (get_random_gint64 ());
274 break;
275
276 case KVP_TYPE_DOUBLE:
277 ret = NULL;
278 break;
279
280 case KVP_TYPE_NUMERIC:
281 ret = kvp_value_new_numeric (get_random_qof_numeric ());
282 break;
283
284 case KVP_TYPE_STRING:
285 {
286 gchar *tmp_str;
287 tmp_str = get_random_string ();
288 if (!tmp_str)
289 return NULL;
290
291 ret = kvp_value_new_string (tmp_str);
292 g_free (tmp_str);
293 }
294 break;
295
296 case KVP_TYPE_GUID:
297 {
298 GUID *tmp_guid;
299 tmp_guid = get_random_guid ();
300 ret = kvp_value_new_guid (tmp_guid);
301 g_free (tmp_guid);
302 }
303 break;
304 #ifndef QOF_DISABLE_DEPRECATED
305 case KVP_TYPE_TIMESPEC:
306 {
307 Timespec *ts = get_random_timespec ();
308 ret = kvp_value_new_timespec (*ts);
309 g_free (ts);
310 }
311 break;
312 #endif
313 case KVP_TYPE_BINARY:
314 {
315 bin_data *tmp_data;
316 tmp_data = get_random_binary_data ();
317 ret = kvp_value_new_binary (tmp_data->data, tmp_data->len);
318 g_free (tmp_data->data);
319 g_free (tmp_data);
320 }
321 break;
322
323 case KVP_TYPE_GLIST:
324 ret = kvp_value_new_glist_nc (get_random_glist_depth (depth + 1));
325 break;
326
327 case KVP_TYPE_FRAME:
328 {
329 KvpFrame *tmp_frame;
330 tmp_frame = get_random_kvp_frame_depth (depth + 1);
331 ret = kvp_value_new_frame (tmp_frame);
332 kvp_frame_delete (tmp_frame);
333 }
334 break;
335
336 default:
337 ret = NULL;
338 break;
339 }
340 return ret;
341 }
342
343 static KvpFrame *
344 get_random_kvp_frame_depth (gint depth)
345 {
346 KvpFrame *ret;
347 int vals_to_add;
348 gboolean val_added;
349
350 if (depth >= kvp_max_depth)
351 return NULL;
352
353 ret = kvp_frame_new ();
354
355 vals_to_add = get_random_int_in_range (1, kvp_frame_max_elements);
356 val_added = FALSE;
357
358 for (; vals_to_add > 0; vals_to_add--)
359 {
360 gchar *key;
361 KvpValue *val;
362
363 key = NULL;
364 while (key == NULL)
365 {
366 key = get_random_string_without ("/");
367 if (*key == '\0')
368 {
369 g_free (key);
370 key = NULL;
371 }
372 }
373
374 val = get_random_kvp_value_depth (-1, depth + 1);
375 if (!val)
376 {
377 g_free (key);
378 if (!val_added)
379 vals_to_add++;
380 continue;
381 }
382
383 val_added = TRUE;
384
385 kvp_frame_set_slot_nc (ret, key, val);
386
387 g_free (key);
388 }
389
390 return ret;
391 }
392
393 KvpFrame *
394 get_random_kvp_frame (void)
395 {
396 return get_random_kvp_frame_depth (0);
397 }
398
399 KvpValue *
400 get_random_kvp_value (int type)
401 {
402 return get_random_kvp_value_depth (type, 0);
403 }
404
405 /* ================================================================= */
406 /* Numeric stuff */
407
408 #define RAND_IN_RANGE(X) (((X)*((gint64) (rand()+1)))/RAND_MAX)
409
410 QofNumeric
411 get_random_qof_numeric (void)
412 {
413 gint64 numer;
414 gint64 deno;
415
416 if (RAND_MAX / 8 > rand ())
417 {
418 /* Random number between 1 and 6000 */
419 deno = RAND_IN_RANGE (6000ULL);
420 }
421 else
422 {
423 gint64 norm = RAND_IN_RANGE (10ULL);
424
425 /* multiple of 10, between 1 and 10 000 million */
426 deno = 1;
427 while (norm)
428 {
429 deno *= 10;
430 norm--;
431 }
432 }
433
434 /* Arbitrary random numbers can cause pointless overflow
435 * during calculations. Limit dynamic range in hopes
436 * of avoiding overflow. */
437 numer = get_random_gint64 () / 100000;
438 if (0 == numer)
439 numer = 1;
440 return qof_numeric_create (numer, deno);
441 }
442
443 /*
444 static GList *
445 get_random_guids(int max)
446 {
447 GList *guids = NULL;
448 int num_guids;
449
450 if (max < 1) return NULL;
451
452 num_guids = get_random_int_in_range (1, max);
453
454 while (num_guids-- > 0)
455 g_list_prepend (guids, get_random_guid ());
456
457 return guids;
458 }
459 *//*
460 static void
461 free_random_guids(GList *guids)
462 {
463 GList *node;
464
465 for (node = guids; node; node = node->next)
466 g_free (node->data);
467
468 g_list_free (guids);
469 }
470 *//*
471 static QofQueryOp
472 get_random_queryop(void)
473 {
474 QofQueryOp op = get_random_int_in_range (1, QOF_QUERY_XOR);
475 if (gnc_engine_debug_random) printf ("op = %d, ", op);
476 return op;
477 }
478 *//*
479 static GSList *
480 get_random_kvp_path (void)
481 {
482 GSList *path;
483 gint len;
484
485 path = NULL;
486 len = get_random_int_in_range (1, kvp_max_depth);
487
488 while (len--)
489 path = g_slist_prepend (path, get_random_string ());
490
491 return g_slist_reverse (path);
492 }
493 *//*
494 static void
495 free_random_kvp_path (GSList *path)
496 {
497 GSList *node;
498
499 for (node = path; node; node = node->next)
500 g_free (node->data);
501
502 g_slist_free (path);
503 }
504 */
505 typedef enum
506 {
507 BY_STANDARD = 1,
508 BY_DATE,
509 BY_DATE_ENTERED,
510 BY_DATE_RECONCILED,
511 BY_NUM,
512 BY_AMOUNT,
513 BY_MEMO,
514 BY_DESC,
515 BY_NONE
516 } sort_type_t;
517
518 typedef struct
519 {
520 QofIdType where;
521 GSList *path;
522 QofQuery *q;
523 } KVPQueryData;
524
525 TestQueryTypes
526 get_random_query_type (void)
527 {
528 switch (get_random_int_in_range (0, 4))
529 {
530 case 0:
531 return SIMPLE_QT;
532 case 4:
533 return GUID_QT;
534 default:
535 return SIMPLE_QT;
536 }
537 }
KVP_TYPE_TIMESPEC
Definition: kvpframe.h:121
QofIdType
const gchar * QofIdType
Definition: qofid.h:81
KvpValueType
KvpValueType
possible types in the union KvpValue
Definition: kvpframe.h:87
KVP_TYPE_GUID
Unique identifier.
Definition: kvpframe.h:118
KvpFrame
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
timespec64
Definition: qoftime.h:97
KVP_TYPE_GLIST
Definition: kvpframe.h:132
KVP_TYPE_FRAME
Definition: kvpframe.h:134
test-engine-stuff.h
This file declares testing functions for the engine.
QofQuery
struct _QofQuery QofQuery
Definition: qofquery.h:85
KVP_TYPE_NUMERIC
128bit denominator/numerator maths.
Definition: kvpframe.h:106
kvp_frame_delete
void kvp_frame_delete(KvpFrame *frame)
Definition: kvpframe.c:118
KvpValue
struct _KvpValue KvpValue
Definition: kvpframe.h:78
kvp_value_new_timespec
KvpValue * kvp_value_new_timespec(Timespec timespec)
Definition: deprecated.c:1482
KVP_TYPE_GINT64
64bit integer
Definition: kvpframe.h:94
_QofNumeric
Definition: qofnumeric.h:52
qof_numeric_create
static QofNumeric qof_numeric_create(gint64 num, gint64 denom)
Definition: qofnumeric.h:243
kvp_frame_set_slot_nc
void kvp_frame_set_slot_nc(KvpFrame *frame, const gchar *slot, KvpValue *value)
Definition: kvpframe.c:700
_GUID
Definition: guid.h:53
guid_new
void guid_new(GUID *guid)
Definition: guid.c:487
kvp_value_new_glist_nc
KvpValue * kvp_value_new_glist_nc(GList *value)
Definition: kvpframe.c:1322
KVP_TYPE_BINARY
Definition: kvpframe.h:130
KVP_TYPE_STRING
standard C string
Definition: kvpframe.h:112
kvp_frame_new
KvpFrame * kvp_frame_new(void)
Definition: kvpframe.c:100
KVP_TYPE_DOUBLE
standard C double type
Definition: kvpframe.h:100
bin_data
Definition: test-engine-stuff.h:43