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