]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/cats_test.c
Backport from BEE
[bacula/bacula] / bacula / src / tools / cats_test.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2011-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *  Program to test CATS DB routines
18  *
19  *
20  */
21 #define _BDB_PRIV_INTERFACE_
22
23 #include "bacula.h"
24 #include "cats/cats.h"
25 #include "cats/bdb_priv.h"
26 #include "cats/sql_glue.h"
27 #include "cats/bvfs.h"
28 #include "findlib/find.h"
29
30 /* Local variables */
31 static B_DB *db;
32 static const char *file = "COPYRIGHT";
33 //static DBId_t fnid=0;
34 static const char *db_name = "bacula";
35 static const char *db_user = "bacula";
36 static const char *db_password = "";
37 static const char *db_host = NULL;
38 static const char *db_address = NULL;
39 static int db_port = 0;
40 static int64_t pid = 0;
41 static JCR *jcr=NULL;
42
43 #define PLINE "\n============================================================\n"
44 static void usage()
45 {
46    fprintf(stderr, _(
47 PROG_COPYRIGHT
48 "\nVersion: %s (%s)\n"
49 "       -d <nn>           set debug level to <nn>\n"
50 "       -dt               print timestamp in debug output\n"
51 "       -n <name>         specify the database name (default bacula)\n"
52 "       -u <user>         specify database user name (default bacula)\n"
53 "       -P <password      specify database password (default none)\n"
54 "       -h <host>         specify database host (default NULL)\n"
55 "       -w <working>      specify working directory\n"
56 "       -p <path>         specify path\n"
57 "       -f <file>         specify file\n"
58 "       -l <limit>        maximum tuple to fetch\n"
59 "       -q                print only errors\n"
60 "       -v                verbose\n"
61 "       -?                print this message\n\n"), 2011, VERSION, BDATE);
62    exit(1);
63 }
64
65 bool print_ok=true;
66 int _err=0;
67 int _wrn=0;
68 int _nb=0;
69
70 bool _warn(const char *file, int l, const char *op, int value, const char *label)
71 {
72    bool ret=false;
73    _nb++;
74    if (!value) {
75       _wrn++;
76       printf("WRN %.30s %s:%i on %s\n", label, file, l, op);
77    } else {
78       ret=true;
79       printf("OK  %.30s\n", label);
80    }
81    return ret;
82 }
83
84 #define warn(x, label) _warn(__FILE__, __LINE__, #x, (x), label)
85
86 bool _ok(const char *file, int l, const char *op, int value, const char *label)
87 {
88    bool ret=false;
89    _nb++;
90    if (!value) {
91       _err++;
92       printf("ERR %.30s %s:%i on %s\n", label, file, l, op);
93    } else {
94       ret=true;
95       if (print_ok) {
96          printf("OK  %.30s\n", label);
97       }
98    }
99    return ret;
100 }
101
102 #define ok(x, label) _ok(__FILE__, __LINE__, #x, (x), label)
103
104 bool _nok(const char *file, int l, const char *op, int value, const char *label)
105 {
106    bool ret=false;
107    _nb++;
108    if (value) {
109       _err++;
110       printf("ERR %.30s %s:%i on !%s\n", label, file, l, op);
111    } else {
112       ret = true;
113       if (print_ok) {
114          printf("OK  %.30s\n", label);
115       }
116    }
117    return ret;
118 }
119
120 #define nok(x, label) _nok(__FILE__, __LINE__, #x, (x), label)
121
122 int report()
123 {
124    printf("Result %i/%i OK\n", _nb - _err, _nb);
125    return _err>0;
126 }
127
128 static void cmp_pool(POOL_DBR &pr, POOL_DBR &pr2)
129 {
130    ok(pr.MaxVols == pr2.MaxVols,                "  Check Pool MaxVols");
131    ok(pr.UseOnce == pr2.UseOnce,                "  Check Pool UseOnce");
132    ok(pr.UseCatalog == pr2.UseCatalog,          "  Check Pool UseCatalog");
133    ok(pr.AcceptAnyVolume == pr2.AcceptAnyVolume,"  Check Pool AcceptAnyVolume");
134    ok(pr.AutoPrune == pr2.AutoPrune,            "  Check Pool AutoPrune");
135    ok(pr.Recycle == pr2.Recycle,                "  Check Pool Recycle");
136    ok(pr.VolRetention == pr2.VolRetention ,     "  Check Pool VolRetention");
137    ok(pr.VolUseDuration == pr2.VolUseDuration,  "  Check Pool VolUseDuration");
138    ok(pr.MaxVolJobs == pr2.MaxVolJobs,          "  Check Pool MaxVolJobs");
139    ok(pr.MaxVolFiles == pr2.MaxVolFiles,        "  Check Pool MaxVolFiles");
140    ok(pr.MaxVolBytes == pr2.MaxVolBytes,        "  Check Pool MaxVolBytes");
141    ok(!strcmp(pr.PoolType, pr2.PoolType),       "  Check Pool PoolType");
142    ok(pr.LabelType == pr2.LabelType,            "  Check Pool LabelType");
143    ok(!strcmp(pr.LabelFormat, pr2.LabelFormat), "  Check Pool LabelFormat");
144    ok(pr.RecyclePoolId == pr2.RecyclePoolId,    "  Check Pool RecyclePoolId");
145    ok(pr.ScratchPoolId == pr2.ScratchPoolId,    "  Check Pool ScratchPoolId");
146    ok(pr.ActionOnPurge == pr2.ActionOnPurge,    "  Check Pool ActionOnPurge");
147 }
148
149 static void cmp_client(CLIENT_DBR &cr, CLIENT_DBR &cr2)
150 {
151    ok(!strcmp(cr2.Name, cr.Name),           "  Check Client Name");
152    ok(!strcmp(cr2.Uname, cr.Uname),         "  Check Client Uname");
153    ok(cr.AutoPrune == cr2.AutoPrune,        "  Check Client Autoprune");
154    ok(cr.JobRetention == cr2.JobRetention,  "  Check Client JobRetention");
155    ok(cr.FileRetention == cr2.FileRetention,"  Check Client FileRetention");
156 }
157
158 static void cmp_job(JOB_DBR &jr, JOB_DBR &jr2)
159 {
160    ok(jr.VolSessionId == jr2.VolSessionId,     "  Check VolSessionId");
161    ok(jr.VolSessionTime == jr2.VolSessionTime, "  Check VolSessionTime");
162    ok(jr.PoolId == jr2.PoolId,                 "  Check PoolId");
163    ok(jr.StartTime == jr2.StartTime,           "  Check StartTime");
164    ok(jr.EndTime == jr2.EndTime,               "  Check EndTime");
165    ok(jr.JobFiles == jr2.JobFiles,             "  Check JobFiles");
166    ok(jr.JobBytes == jr2.JobBytes,             "  Check JobBytes");
167    ok(jr.JobTDate == jr2.JobTDate,             "  Check JobTDate");
168    ok(!strcmp(jr.Job, jr2.Job),                "  Check Job");
169    ok(jr.JobStatus == jr2.JobStatus,           "  Check JobStatus");
170    ok(jr.JobType == jr2.JobType,               "  Check Type");
171    ok(jr.JobLevel == jr2.JobLevel,             "  Check Level");
172    ok(jr.ClientId == jr2.ClientId,             "  Check ClientId");
173    ok(!strcmp(jr.Name, jr2.Name),              "  Check Name");
174    ok(jr.PriorJobId == jr2.PriorJobId,         "  Check PriorJobId");
175    ok(jr.RealEndTime == jr2.RealEndTime,       "  Check RealEndTime");
176    ok(jr.JobId == jr2.JobId,                   "  Check JobId");
177    ok(jr.FileSetId == jr2.FileSetId,           "  Check FileSetId");
178    ok(jr.SchedTime == jr2.SchedTime,           "  Check SchedTime");
179    ok(jr.RealEndTime == jr2.RealEndTime,       "  Check RealEndTime");
180    ok(jr.ReadBytes == jr2.ReadBytes,           "  Check ReadBytes");
181    ok(jr.HasBase == jr2.HasBase,               "  Check HasBase");
182    ok(jr.PurgedFiles == jr2.PurgedFiles,       "  Check PurgedFiles");
183 }
184
185
186 #define aPATH "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
187 #define aFILE "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
188
189 static int list_files(void *ctx, int nb_col, char **row)
190 {
191    uint32_t *k = (uint32_t*) ctx;
192    (*k)++;
193    ok(nb_col > 4, "Check result columns");
194    ok(!strcmp(row[0], aPATH aPATH aPATH aPATH "/"), "Check path");
195    ok(!strcmp(row[1], aFILE aFILE ".txt"), "Check filename");
196    ok(str_to_int64(row[2]) == 10, "Check FileIndex");
197    ok(str_to_int64(row[3]) == jcr->JobId, "Check JobId");
198    return 1;
199 }
200
201 static int count_col(void *ctx, int nb_col, char **row)
202 {
203    *((int32_t*) ctx) = nb_col;
204    return 1;
205 }
206
207 /* number of thread started */
208
209 int main (int argc, char *argv[])
210 {
211    int ch;
212    char *path=NULL, *client=NULL;
213    uint64_t limit=0;
214    bool clean=false;
215    bool full_test=false;
216    int dbtype;
217    uint32_t j;
218    char temp[20];
219    POOLMEM *buf = get_pool_memory(PM_FNAME);
220    POOLMEM *buf2 = get_pool_memory(PM_FNAME);
221    POOLMEM *buf3 = get_pool_memory(PM_FNAME);
222
223    setlocale(LC_ALL, "");
224    bindtextdomain("bacula", LOCALEDIR);
225    textdomain("bacula");
226    init_stack_dump();
227    pid = getpid();
228
229    Pmsg0(0, "Starting cats_test tool" PLINE);
230
231    my_name_is(argc, argv, "");
232    init_msg(NULL, NULL);
233
234    OSDependentInit();
235
236    while ((ch = getopt(argc, argv, "qh:c:l:d:n:P:Su:vFw:?p:f:T")) != -1) {
237       switch (ch) {
238       case 'q':
239          print_ok = false;
240          break;
241       case 'd':                    /* debug level */
242          if (*optarg == 't') {
243             dbg_timestamp = true;
244          } else {
245             debug_level = atoi(optarg);
246             if (debug_level <= 0) {
247                debug_level = 1;
248             }
249          }
250          break;
251       case 'l':
252          limit = str_to_int64(optarg);
253          break;
254
255       case 'c':
256          client = optarg;
257          break;
258
259       case 'h':
260          db_host = optarg;
261          break;
262
263       case 'n':
264          db_name = optarg;
265          break;
266
267       case 'w':
268          working_directory = optarg;
269          break;
270
271       case 'u':
272          db_user = optarg;
273          break;
274
275       case 'P':
276          db_password = optarg;
277          break;
278
279       case 'v':
280          verbose++;
281          break;
282
283       case 'p':
284          path = optarg;
285          break;
286
287       case 'F':
288          full_test = true;
289          break;
290
291       case 'f':
292          file = optarg;
293          break;
294
295       case 'T':
296          clean = true;
297          break;
298
299       case '?':
300       default:
301          usage();
302
303       }
304    }
305    argc -= optind;
306    argv += optind;
307
308    if (argc != 0) {
309       Pmsg0(0, _("Wrong number of arguments: \n"));
310       usage();
311    }
312
313    /* TODO:
314     *  - Open DB
315     *    - With errors
316     *    - With good info
317     *    - With multiple thread in //
318     *  - Test cats.h
319     *  - Test all sql_cmds.c
320     *  - Test all sql.c (db_)
321     *  - Test all sql_create.c
322     *  - Test db_handler
323     */
324
325    jcr = new_jcr(sizeof(JCR), NULL);
326    jcr->setJobType(JT_CONSOLE);
327    jcr->setJobLevel(L_NONE);
328    jcr->JobStatus = JS_Running;
329    bstrncpy(jcr->Job, "**dummy**", sizeof(jcr->Job));
330    jcr->JobId = pid;      /* this is JobId on tape */
331    jcr->start_time = jcr->sched_time = time(NULL);
332
333    /* Test DB connexion */
334    Pmsg1(0, PLINE "Test DB connection \"%s\"" PLINE, db_name);
335
336    if (full_test) {
337       db = db_init_database(jcr /* JCR */,
338                    NULL /* dbi driver */,
339                    db_name, db_user, db_password, db_address, db_port + 100,
340                    NULL /* db_socket */,
341                    0 /* mult_db_connections */, false);
342       ok(db != NULL, "Test bad connection");
343       if (!db) {
344          report();
345          exit (1);
346       }
347       nok(db_open_database(jcr, db), "Open bad Database");
348       db_close_database(jcr, db);
349    }
350
351    db = db_init_database(jcr /* JCR */,
352                 NULL /* dbi driver */,
353                 db_name, db_user, db_password, db_address, db_port,
354                 NULL /* db_socket */,
355                 false /* mult_db_connections */, false);
356
357    ok(db != NULL, "Test db connection");
358    if (!db) {
359       report();
360       exit (1);
361    }
362    if (!ok(db_open_database(jcr, db), "Open Database")) {
363       Pmsg1(000, _("Could not open database \"%s\".\n"), db_name);
364       Jmsg(jcr, M_FATAL, 0, _("Could not open, database \"%s\".\n"), db_name);
365       Jmsg(jcr, M_FATAL, 0, _("%s"), db_strerror(db));
366       Pmsg1(000, "%s", db_strerror(db));
367       db_close_database(jcr, db);
368       report();
369       exit (1);
370    }
371    dbtype = db_get_type_index(db);
372
373
374    /* Check if the SQL library is thread-safe */
375    //db_check_backend_thread_safe();
376    ok(check_tables_version(jcr, db), "Check table version");
377    ok(db_sql_query(db, "SELECT VersionId FROM Version",
378                    db_int_handler, &j), "SELECT VersionId");
379
380    ok(UPDATE_DB(jcr, db, (char*)"UPDATE Version SET VersionId = 1"),
381       "Update VersionId");
382    nok(check_tables_version(jcr, db), "Check table version");
383    Mmsg(buf, "UPDATE Version SET VersionId = %d", j);
384    ok(UPDATE_DB(jcr, db, buf), "Restore VersionId");
385
386    if (dbtype != SQL_TYPE_SQLITE3) {
387       ok(db_check_max_connections(jcr, db, 1), "Test min Max Connexion");
388       nok(db_check_max_connections(jcr, db, 10000), "Test max Max Connexion");
389    }
390
391    ok(db_open_batch_connexion(jcr, db), "Opening batch connection");
392    db_close_database(jcr, jcr->db_batch);
393    jcr->db_batch = NULL;
394
395    /* ---------------------------------------------------------------- */
396
397    uint32_t storageid=0;
398    ok(db_sql_query(db, "SELECT MIN(StorageId) FROM Storage",
399                    db_int_handler, &storageid), "Get StorageId");
400    ok(storageid > 0, "Check StorageId");
401    if (!storageid) {
402       Pmsg0(0, "Please, run REGRESS_DEBUG=1 tests/bacula-backup-test before this test");
403       exit (1);
404    }
405
406    /* ---------------------------------------------------------------- */
407    Pmsg0(0, PLINE "Doing Basic SQL tests" PLINE);
408    ok(db_sql_query(db, "SELECT 1,2,3,4,5", count_col, &j), "Count 5 rows");
409    ok(j == 5, "Check number of columns");
410    ok(db_sql_query(db, "SELECT 1,2,3,4,5,'a','b','c','d','e'",
411                    count_col, &j), "Count 10 rows");
412    ok(j == 10, "Check number of columns");
413
414    bsnprintf(temp, sizeof(temp), "t%lld", pid);
415    ok(db_sql_query(db, "SELECT 2", db_int_handler, &j), "Good SELECT query");
416    ok(db_sql_query(db, "SELECT 1 FROM Media WHERE VolumeName='missing'",
417                    db_int_handler, &j), "Good empty SELECT query");
418
419    db_int64_ctx i64;
420    i64.value = 0; i64.count = 0;
421    ok(db_sql_query(db, "SELECT 1",db_int64_handler, &i64),"db_int64_handler");
422    ok(i64.value == 1, "Check db_int64_handler return");
423
424    db_list_ctx lctx;
425    ok(db_sql_query(db, "SELECT FileId FROM File ORDER By FileId LIMIT 10",
426                    db_list_handler, &lctx), "db_list_ctx");
427    ok(lctx.count == 10, "Check db_list_ctx count ");
428    ok(!strcmp(lctx.list, "1,2,3,4,5,6,7,8,9,10"), "Check db_list_ctx list");
429
430    nok(db_sql_query(db, "blabla", db_int_handler, &j), "Bad query");
431
432    Mmsg(buf, "CREATE Table %s (a int)", temp);
433    ok(db_sql_query(db, buf, NULL, NULL), "CREATE query");
434
435    Mmsg(buf, "INSERT INTO %s (a) VALUES (1)", temp);
436    ok(INSERT_DB(jcr, db, buf), "INSERT query");
437    ok(INSERT_DB(jcr, db, buf), "INSERT query");
438    ok(sql_affected_rows(db) == 1, "Check sql_affected_rows");
439
440    Mmsg(buf, "INSERT INTO aaa%s (a) VALUES (1)", temp);
441    nok(INSERT_DB(jcr, db, buf), "Bad INSERT query");
442    ok(sql_affected_rows(db) == 0, "Check sql_affected_rows");
443
444    Mmsg(buf, "UPDATE %s SET a = 2", temp);
445    ok(UPDATE_DB(jcr, db, buf), "UPDATE query");
446    ok(sql_affected_rows(db) == 2, "Check sql_affected_rows");
447
448    Mmsg(buf, "UPDATE %s SET a = 2 WHERE a = 1", temp);
449    nok(UPDATE_DB(jcr, db, buf), "Empty UPDATE query");
450
451    Mmsg(buf, "UPDATE aaa%s SET a = 2", temp);
452    nok(UPDATE_DB(jcr, db, buf), "Bad UPDATE query");
453
454    Mmsg(buf, "DELETE FROM %s", temp);
455    ok(DELETE_DB(jcr, db, buf), "DELETE query");
456    nok(DELETE_DB(jcr, db, buf), "Empty DELETE query"); /* TODO bug ? */
457
458    Mmsg(buf, "DELETE FROM aaa%s", temp);
459    ok(DELETE_DB(jcr, db, buf), "Bad DELETE query"); /* TODO bug ? */
460
461    Mmsg(buf, "DROP TABLE %s", temp);
462    ok(QUERY_DB(jcr, db, buf), "DROP query");
463    nok(QUERY_DB(jcr, db, buf), "Empty DROP query");
464
465    /* ---------------------------------------------------------------- */
466
467    strcpy(buf, "This string should be 'escaped'");
468    db_escape_string(jcr, db, buf2, buf, strlen(buf));
469    ok((strlen(buf) + 2) == strlen(buf2),"Quoted string should be longer");
470    Mmsg(buf, "INSERT INTO Path (Path) VALUES ('%lld-%s')", pid, buf2);
471    ok(db_sql_query(db, buf, NULL, NULL), "Inserting quoted string");
472
473    /* ---------------------------------------------------------------- */
474    Pmsg0(0, PLINE "Doing Job tests" PLINE);
475
476    JOB_DBR jr, jr2;
477    memset(&jr, 0, sizeof(jr));
478    memset(&jr2, 0, sizeof(jr2));
479    jr.JobId = 1;
480    ok(db_get_job_record(jcr, db, &jr), "Get Job record for JobId=1");
481    ok(jr.JobFiles > 10, "Check number of files");
482
483    jr.JobId = (JobId_t)pid;
484    Mmsg(buf, "%s-%lld", jr.Job, pid);
485    strcpy(jr.Job, buf);
486    ok(db_create_job_record(jcr, db, &jr), "Create Job record");
487    ok(db_update_job_start_record(jcr, db, &jr), "Update Start Record");
488    ok(db_update_job_end_record(jcr, db, &jr), "Update End Record");
489    jr2.JobId = jr.JobId;
490    ok(db_get_job_record(jcr, db, &jr2), "Get Job record by JobId");
491    cmp_job(jr, jr2);
492
493    memset(&jr2, 0, sizeof(jr2));
494    strcpy(jr2.Job, jr.Job);
495    ok(db_get_job_record(jcr, db, &jr2), "Get Job record by Job name");
496    cmp_job(jr, jr2);
497
498    memset(&jr2, 0, sizeof(jr2));
499    jr2.JobId = 99999;
500    nok(db_get_job_record(jcr, db, &jr2), "Get non existing Job record (JobId)");
501
502    memset(&jr2, 0, sizeof(jr2));
503    strcpy(jr2.Job, "test");
504    nok(db_get_job_record(jcr, db, &jr2), "Get non existing Job record (Job)");
505
506    /* ---------------------------------------------------------------- */
507
508    ATTR_DBR ar;
509    memset(&ar, 0, sizeof(ar));
510    Mmsg(buf2, aPATH aPATH aPATH aPATH "/" aFILE aFILE ".txt");
511    ar.fname = buf2;
512    Mmsg(buf3, "gD ImIZ IGk B Po Po A A A JY BNNvf5 BNKzS7 BNNuwC A A C");
513    ar.attr = buf3;
514    ar.FileIndex = 10;
515    ar.Stream = STREAM_UNIX_ATTRIBUTES;
516    ar.FileType = FT_REG;
517    jcr->JobId = ar.JobId = jr.JobId;
518    jcr->JobStatus = JS_Running;
519    ok(db_create_attributes_record(jcr, db, &ar), "Inserting Filename");
520    ok(db_write_batch_file_records(jcr), "Commit batch session");
521    Mmsg(buf, "SELECT FileIndex FROM File WHERE JobId=%lld",(int64_t)jcr->JobId);
522    ok(db_sql_query(db, buf, db_int_handler, &j), "Get Inserted record");
523    ok(j == ar.FileIndex, "Check FileIndex");
524    Mmsg(buf, "SELECT COUNT(1) FROM File WHERE JobId=%lld",(int64_t)jcr->JobId);
525    ok(db_sql_query(db, buf, db_int_handler, &j), "List records");
526    ok(j == 1, "Check batch session records");
527    j = 0;
528    Mmsg(buf, "%lld", (uint64_t)jcr->JobId);
529    ok(db_get_file_list(jcr, jcr->db_batch, buf, false, false, list_files, &j),
530       "List files with db_get_file_list()");
531    ok(j == 1, "Check db_get_file_list results");
532    /* ---------------------------------------------------------------- */
533
534    Pmsg0(0, PLINE "Doing Client tests" PLINE);
535    CLIENT_DBR cr, cr2;
536    memset(&cr, 0, sizeof(cr));
537    memset(&cr2, 0, sizeof(cr2));
538
539    cr.AutoPrune = 1;
540    cr.FileRetention = 10;
541    cr.JobRetention = 15;
542    bsnprintf(cr.Name, sizeof(cr.Name), "client-%lld-fd", pid);
543    bsnprintf(cr.Uname, sizeof(cr.Uname), "uname-%lld", pid);
544
545    ok(db_create_client_record(jcr, db, &cr), "db_create_client_record()");
546    ok(cr.ClientId > 0, "Check ClientId");
547
548    cr2.ClientId = cr.ClientId; /* Save it */
549    cr.ClientId = 0;
550
551    Pmsg0(0, "Search client by ClientId\n");
552    ok(db_create_client_record(jcr, db, &cr),"Should get the client record");
553    ok(cr.ClientId == cr2.ClientId,           "Check if ClientId is the same");
554
555    ok(db_get_client_record(jcr, db, &cr2), "Search client by ClientId");
556    cmp_client(cr, cr2);
557
558    Pmsg0(0, "Search client by Name\n");
559    memset(&cr2, 0, sizeof(cr2));
560    strcpy(cr2.Name, cr.Name);
561    ok(db_get_client_record(jcr, db, &cr2),"Search client by Name");
562    cmp_client(cr, cr2);
563
564    Pmsg0(0, "Search non existing client by Name\n");
565    memset(&cr2, 0, sizeof(cr2));
566    bsnprintf(cr2.Name, sizeof(cr2.Name), "hollow-client-%lld-fd", pid);
567    nok(db_get_client_record(jcr, db, &cr2), "Search non existing client");
568    ok(cr2.ClientId == 0, "Check ClientId after failed search");
569
570    cr.AutoPrune = 0;
571    strcpy(cr.Uname, "NewUname");
572    ok(db_update_client_record(jcr, db, &cr), "Update Client record");
573    memset(&cr2, 0, sizeof(cr2));
574    cr2.ClientId = cr.ClientId;
575    ok(db_get_client_record(jcr, db, &cr2),"Search client by ClientId");
576    cmp_client(cr, cr2);
577
578    int nb, i;
579    uint32_t *ret_ids;
580    ok(db_get_client_ids(jcr, db, &nb, &ret_ids), "Get Client Ids");
581    ok(nb > 0, "Should find at least 1 Id");
582    for (i = 0; i < nb; i++) {
583       if (ret_ids[i] == cr2.ClientId) {
584          break;
585       }
586    }
587    ok(i < nb, "Check if ClientId was found");
588
589    /* ---------------------------------------------------------------- */
590    Pmsg0(0, PLINE "Doing Pool tests" PLINE);
591    POOL_DBR pr, pr2;
592    memset(&pr, 0, sizeof(pr));
593    memset(&pr2, 0, sizeof(pr2));
594
595    bsnprintf(pr.Name, sizeof(pr.Name), "pool-%lld", pid);
596    pr.MaxVols = 10;
597    pr.UseOnce = 0;
598    pr.UseCatalog = true;
599    pr.AcceptAnyVolume = true;
600    pr.AutoPrune = true;
601    pr.Recycle = true;
602    pr.VolRetention = 1000;
603    pr.VolUseDuration = 1000;
604    pr.MaxVolJobs = 100;
605    pr.MaxVolFiles = 1000;
606    pr.MaxVolBytes = 1000000;
607    strcpy(pr.PoolType, "Backup");
608    pr.LabelType = 0;
609    pr.LabelFormat[0] = 0;
610    pr.RecyclePoolId = 0;
611    pr.ScratchPoolId = 0;
612    pr.ActionOnPurge = 1;
613
614    ok(db_create_pool_record(jcr, db, &pr), "db_create_pool_record()");
615    ok(pr.PoolId > 0, "Check PoolId");
616
617    pr2.PoolId = pr.PoolId;
618    pr.PoolId = 0;
619
620    Pmsg0(0, "Search pool by PoolId\n");
621    nok(db_create_pool_record(jcr, db, &pr),"Can't create pool twice");
622    ok(db_get_pool_record(jcr, db, &pr2), "Search pool by PoolId");
623    cmp_pool(pr, pr2);
624
625    pr2.MaxVols++;
626    pr2.AutoPrune = false;
627    pr2.Recycle = false;
628    pr2.VolRetention++;
629    pr2.VolUseDuration++;
630    pr2.MaxVolJobs++;
631    pr2.MaxVolFiles++;
632    pr2.MaxVolBytes++;
633    strcpy(pr2.PoolType, "Restore");
634    strcpy(pr2.LabelFormat, "VolFormat");
635    pr2.RecyclePoolId = 0;
636    pr2.ScratchPoolId = 0;
637    pr2.ActionOnPurge = 2;
638
639    ok(db_update_pool_record(jcr, db, &pr2), "Update Pool record");
640    memset(&pr, 0, sizeof(pr));
641    pr.PoolId = pr2.PoolId;
642    ok(db_get_pool_record(jcr, db, &pr), "Search pool by PoolId");
643    cmp_pool(pr, pr2);
644
645    ok(db_delete_pool_record(jcr, db, &pr), "Delete Pool");
646    nok(db_delete_pool_record(jcr, db, &pr), "Delete non existing Pool");
647    nok(db_update_pool_record(jcr, db, &pr), "Update non existing Pool");
648    ok(db_create_pool_record(jcr, db, &pr), "Recreate Pool");
649
650    /* ---------------------------------------------------------------- */
651    Pmsg0(0, PLINE "Doing Media tests" PLINE);
652
653    MEDIA_DBR mr, mr2;
654    memset(&mr, 0, sizeof(mr));
655    memset(&mr2, 0, sizeof(mr2));
656
657    bsnprintf(mr.VolumeName, sizeof(mr.VolumeName), "media-%lld", pid);
658    bsnprintf(mr.MediaType, sizeof(mr.MediaType), "type-%lld", pid);
659
660    /* from set_pool_dbr_defaults_in_media_dbr(&mr, &pr);  */
661    mr.PoolId = pr.PoolId;
662    bstrncpy(mr.VolStatus, NT_("Append"), sizeof(mr.VolStatus));
663    mr.Recycle = pr.Recycle;
664    mr.VolRetention = pr.VolRetention;
665    mr.VolUseDuration = pr.VolUseDuration;
666    mr.ActionOnPurge = pr.ActionOnPurge;
667    mr.RecyclePoolId = pr.RecyclePoolId;
668    mr.MaxVolJobs = pr.MaxVolJobs;
669    mr.MaxVolFiles = pr.MaxVolFiles;
670    mr.MaxVolBytes = pr.MaxVolBytes;
671    mr.LabelType = pr.LabelType;
672    mr.Enabled = 1;
673
674    mr.VolCapacityBytes = 1000;
675    mr.Slot = 1;
676    mr.VolBytes = 1000;
677    mr.InChanger = 1;
678    mr.VolReadTime = 10000;
679    mr.VolWriteTime = 99999;
680    mr.StorageId = 0;
681    mr.DeviceId = 0;
682    mr.LocationId = 0;
683    mr.ScratchPoolId = 0;
684    mr.RecyclePoolId = 0;
685
686    ok(db_create_media_record(jcr, db, &mr), "Create Media");
687    nok(db_create_media_record(jcr, db, &mr), "Create Media twice");
688
689    /* ---------------------------------------------------------------- */
690    Pmsg0(0, PLINE "Doing ... tests" PLINE);
691
692    db_close_database(jcr, db);
693    report();
694    free_pool_memory(buf);
695    free_pool_memory(buf2);
696    free_pool_memory(buf3);
697    return 0;
698 }