/*
openisis - an open implementation of the CDS/ISIS database
Version 0.8.x (patchlevel see file Version)
Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
see README for more information
EOH */
/*
$Id: lstbtest.c,v 1.23 2003/06/30 09:52:03 kripke Exp $
tests for lstb methods.
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* unlink */
#include "openisis.h"
#include "loi.h"
#include "ldb.h" /* ldb_getdb */
#include "luti.h" /* luti_unwrap */
static int _RspCld[1] = { 0 };
static int _DelCld[1] = { 0 };
static OpenIsisStubCbData cbdta;
static Stub st0, st1, st2, st3;
static Schema *sc0, *sc1, *sc2, *sc3;
static Db *db;
static Rec *rqs, *rsp;
static char *args[64];
static int alen;
/* ************************************************************
utils
*/
static void _lstb_assert (int cond, const char *where, char *fmt, ...) {
if (! cond) {
va_list ap;
va_start (ap, fmt);
fprintf (stderr, "ERR %s: ", where ? where : "");
vfprintf (stderr, fmt, ap);
fprintf (stderr, "\n");
va_end (ap);
exit (1);
}
}
static int _rsp_cb (void *cld, Stub stb, Rec *rsprec, Db *x) {
(void)stb; (void)rsprec; (void)x;
if (cld) {
++(*((int*)cld));
}
return 0;
}
static void _del_cb (void *cld, Stub stb, void *cbd) {
(void)stb;
++(*((int*)cld));
if (cbd) {
_lstb_assert (cbd == (void*)_RspCld, "DELCB",
"%d: %p != %p", *((int*)cld), cbd, _RspCld);
--(*((int*)cbd));
}
}
static void _cmp_rec (const char *msg, Rec *r1, Rec *r2) {
char buf1[32], buf2[32];
Field *f1, *f2;
int j;
_lstb_assert (0 != r1, msg, "chkr: r1 == 0");
_lstb_assert (0 != r2, msg, "chkr: r2 == 0");
_lstb_assert (r1->len == r2->len, msg, "chkr: reclen = %d/%d",
r1->len, r2->len);
buf1[31] = buf2[31] = 0;
for (f1 = r1->field, f2 = r2->field, j = 0;
r1->len > j;
++f1, ++f2, ++j) {
_lstb_assert (f1->tag == f2->tag, msg, "chkr: tag[%d] = %d/%d",
j, f1->tag, f2->tag);
_lstb_assert (f1->len == f2->len, msg, "chkr: len[%d] = %d/%d",
j, f1->len, f2->len);
strncpy (buf1, f1->val, 31 < f1->len ? 31 : f1->len);
strncpy (buf2, f2->val, 31 < f1->len ? 31 : f1->len);
_lstb_assert (0 == memcmp (f1->val, f2->val, f1->len), msg,
"field[%d] = %s/%s", j, buf1, buf2);
}
}
static void _chk_rec (const char *msg, Rec *rec, int dbid, int rowid) {
Rec *r2 = dRead (dbid, rowid);
_cmp_rec (msg, rec, r2);
mFree (r2);
}
static Rec* _buildrqs (int argc, char **argv) {
return rSet (0, RARGV | RFDT | argc, openIsisFdtRqs, argv);
}
static int _set_tms (const char *msg, char *dbn, int delta) {
static char tbuf[32];
int j;
_lstb_assert (0 != sc0, msg, "(tms) sc0 == 0");
_lstb_assert (0 < sc0->ndbs, msg, "(tms) sc0->ndbs = %d", sc0->ndbs);
for (j = 0, db = 0; sc0->ndbs > j; ++j) {
if (0 == strcmp (sc0->dbs[j]->name, dbn)) {
db = sc0->dbs[j];
break;
}
}
_lstb_assert (0 != db, msg, "(tms) no such db: %s", dbn);
_lstb_assert (0 != db->tms, msg, "(tms) tms == 0");
sprintf (tbuf, "%d", (db->tms + delta));
args[alen++] = "tms";
args[alen++] = tbuf;
return db->tms;
}
/* ************************************************************
tests
*/
static void _open_srv (const char *msg, int argc, const char **argv) {
const char *scargs[] = {
"host", "tonno", "port", "4242"
};
int scnum = sizeof (scargs) / sizeof (scargs[0]);
st0 = openIsisNInit (argc, argv, &cbdta);
_lstb_assert (0 != st0, msg, "st0 == 0");
sc0 = openIsisNSchema (st0);
_lstb_assert (0 != sc0, msg, "sc0 == 0");
_lstb_assert (0 == sc0->scid, msg, "sc0.scid = %x", sc0->scid);
st1 = openIsisNOpen ("nonno", scnum, scargs, &cbdta);
_lstb_assert (0 != st1, msg, "st1 == 0");
_lstb_assert (st0 != st1, msg, "st1 == st0");
sc1 = openIsisNSchema (st1);
_lstb_assert (0 != sc1, msg, "sc1 == 0");
_lstb_assert (0x0100 == sc1->scid, msg, "sc1.scid = %x", sc1->scid);
st2 = openIsisNInit (0, 0, 0);
_lstb_assert (st2 == st0, msg, "st2 %p != %p", st2, st0);
sc2 = openIsisNSchema (st2);
_lstb_assert (sc2 == sc0, msg, "sc2 %p != %p", sc2, sc0);
st3 = openIsisNOpen ("nonno", 0, 0, 0);
_lstb_assert (st3 == st1, msg, "st3 %p != %p", st3, st1);
sc3 = openIsisNSchema (st1);
_lstb_assert (sc3 == sc1, msg, "sc3 %p != %p", sc3, sc1);
}
static void _open_db (const char *msg, char *dbn) {
int rt;
alen = 0;
args[alen++] = "type";
args[alen++] = "open";
args[alen++] = "db";
args[alen++] = dbn;
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, &_rsp_cb, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, 0);
_lstb_assert (0 != rsp, msg, "rsp == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (0 == rt, msg, "err = %d", rt);
db = ldb_getdb (0);
_lstb_assert (0 != db, msg, "db == 0");
_lstb_assert (0 == strcmp (db->name, "cds"), msg, "db0: %s", db->name);
}
static void _close_db (const char *msg, char *dbn, int dbid) {
int rt;
alen = 0;
args[alen++] = "type";
args[alen++] = "close";
args[alen++] = "db";
args[alen++] = dbn;
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, &_rsp_cb, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, 0);
_lstb_assert (0 != rsp, msg, "rsp == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (0 == rt, msg, "err = %d", rt);
if (0 <= dbid) {
db = ldb_getdb (dbid);
_lstb_assert (0 == db, msg, "db != 0");
}
}
static void _lsdb (const char *msg) {
char dbn[OPENISIS_DB_NAMELEN];
char *n1;
int rt, pos;
alen = 0;
args[alen++] = "type";
args[alen++] = "ls";
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, 0, 0, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, 0);
_lstb_assert (0 != rsp, msg, "rsp == 0");
pos = 0;
n1 = rString (rsp, OPENISIS_COM_DBN, &pos, dbn, OPENISIS_DB_NAMELEN);
_lstb_assert (0 != n1, msg, "db(0) == 0");
_lstb_assert (0 == strcmp (n1, "cds"), msg, "db(0) = %s", n1);
n1 = rString (rsp, OPENISIS_COM_DBN, &pos, dbn, OPENISIS_DB_NAMELEN);
_lstb_assert (0 != n1, msg, "db(1) == 0");
_lstb_assert (0 == strcmp (n1, "lstbtest"), msg, "db(1) = %s", n1);
n1 = rString (rsp, OPENISIS_COM_DBN, &pos, dbn, OPENISIS_DB_NAMELEN);
_lstb_assert (0 == n1, msg, "db(2) = %s", n1);
}
static void _maxrow (const char *msg, char *dbn, int exp) {
int rt;
alen = 0;
args[alen++] = "type";
args[alen++] = "maxrow";
args[alen++] = "db";
args[alen++] = dbn;
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, &_rsp_cb, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, 0);
_lstb_assert (0 != rsp, msg, "rsp == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (0 == rt, msg, "err = %d", rt);
rt = rInt (rsp, OPENISIS_RSP_NUMT, -1, 0);
_lstb_assert (-1 == rt, msg, "numt = %d", rt);
rt = rInt (rsp, OPENISIS_COM_ROW, -1, 0);
if (0 <= exp) {
_lstb_assert (exp == rt, msg, "rowid = %d(%d)", rt, exp);
}
else {
_lstb_assert (0 <= rt, msg, "rowid = %d", rt);
}
}
static void _maxrowerr (const char *msg, char *dbn) {
int rt, tms;
alen = 0;
args[alen++] = "type";
args[alen++] = "maxrow";
args[alen++] = "db";
args[alen++] = dbn;
tms = _set_tms (msg, dbn, -2);
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, &_rsp_cb, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d x%x", rt, rt);
rsp = openIsisNRecv (st0, 0);
_lstb_assert (0 != rsp, msg, "rsp == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (ERR_INVAL == rt, msg, "err = %d", rt);
rt = rInt (rsp, OPENISIS_COM_TMS, -1, 0);
_lstb_assert (tms == rt, msg, "tms = %d(%d)", rt, tms);
}
static void _lstb_read (const char *msg, int rid, int rlen) { /* no _rsp_cb */
Rec *rec;
Db *rdb;
char rbuf[32];
int rt;
alen = 0;
args[alen++] = "type";
args[alen++] = "read";
args[alen++] = "db";
args[alen++] = "cds";
_set_tms (msg, "cds", 0);
sprintf (rbuf, "%d", rid);
args[alen++] = "rowid";
args[alen++] = rbuf;
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, 0, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, &rdb);
_lstb_assert (0 != rsp, msg, "rsp == 0");
_lstb_assert (0 != rdb, msg, "rdb == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (0 == rt, msg, "err = %d", rt);
rt = rInt (rsp, OPENISIS_RSP_NUMT, -1, 0);
_lstb_assert (1 == rt, msg, "numt = %d", rt);
rt = rInt (rsp, OPENISIS_COM_ROW, -1, 0);
_lstb_assert (rid == rt, msg, "rowid = %d(%d)", rt, rid);
rec = luti_unwrap (rsp, 0, OPENISIS_COM_REC, rdb->dbid);
_lstb_assert (0 != rec, msg, "rec == 0");
if (0 < rlen) {
_lstb_assert (rlen == rec->len, msg, "rec->len = %d(%d)", rec->len, rlen);
}
else {
_lstb_assert (0 < rec->len, msg, "rec->len = %d", rec->len);
}
_lstb_assert (rdb->dbid == rec->dbid, msg,
"rec->dbid = %d(%d)", rec->dbid, rdb->dbid);
_chk_rec (msg, rec, 0, rid);
mFree (rec);
}
static int _query ( /* no _rsp_cb */
const char *msg, int flg, int mode, int skip, int size, int exp
) {
Rec **recs;
Db *rdb;
char fbuf[32], mbuf[32], kbuf[32], sbuf[32];
int *rowids;
int rt, rr, j;
alen = 0;
args[alen++] = "type";
args[alen++] = "query";
args[alen++] = "db";
args[alen++] = "cds";
sprintf (mbuf, "%d", mode);
args[alen++] = "mode";
args[alen++] = mbuf;
if (flg) {
sprintf (fbuf, "%d", flg);
args[alen++] = "flags";
args[alen++] = fbuf;
}
if (skip) {
sprintf (kbuf, "%d", skip);
args[alen++] = "skip";
args[alen++] = kbuf;
}
if (size) {
sprintf (sbuf, "%d", size);
args[alen++] = "size";
args[alen++] = sbuf;
}
args[alen++] = "key";
args[alen++] = "Africa$";
rqs = _buildrqs (alen, args);
_lstb_assert (0 != rqs, msg, "rqs == 0");
rt = openIsisNSend (st0, rqs, 0, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, &rdb);
_lstb_assert (0 != rsp, msg, "rsp == 0");
_lstb_assert (0 != rdb, msg, "rdb == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (0 == rt, msg, "err = %d", rt);
rr = openIsisNGetResult (st0, &rowids, &recs, 0, &rt);
if (0 <= exp) {
_lstb_assert (exp == rr, msg, "numr = %d(%d)", rr, exp);
}
else {
_lstb_assert (0 <= rr, msg, "numr = %d", rr);
}
_lstb_assert (rt >= rr, msg, "numt = %d/%d", rt, rr);
if (recs) {
for (j = 0; rr > j; ++j) {
_chk_rec (msg, recs[j], 0, rowids[j]);
mFree (recs[j]);
}
mFree (recs);
}
rt = rr ? rowids[rr - 1] : -1;
mFree (rowids);
return rt;
}
static int _update (const char *msg,
int rid, int rtag, char *rval, int itag, char *ival, int exp
) {
Rec *rec;
char rbuf[32];
int rt;
alen = 0;
args[alen++] = "type";
args[alen++] = 0 <= rid ? "update" : "insert";
args[alen++] = "db";
args[alen++] = "lstbtest";
_set_tms (msg, "lstbtest", 0);
if (0 <= rid) {
sprintf (rbuf, "%d", rid);
args[alen++] = "rowid";
args[alen++] = rbuf;
}
rqs = _buildrqs (alen, args);
rec = rSet (0, 0, rtag, rval,
88, "summary of the conference in gondor", 0);
rqs = luti_wrap (rqs, rec, OPENISIS_COM_REC);
mFree (rec);
if (itag) {
rec = rSet (0, 0, itag, ival, 0);
rqs = luti_wrap (rqs, rec, OPENISIS_COM_REC);
mFree (rec);
}
rt = openIsisNSend (st0, rqs, &_rsp_cb, _RspCld, 0);
_lstb_assert (0 == rt, msg, "rt = %d", rt);
rsp = openIsisNRecv (st0, 0);
_lstb_assert (0 != rsp, msg, "rsp == 0");
rt = rInt (rsp, OPENISIS_RSP_ERR, -1, 0);
_lstb_assert (0 == rt, msg, "err = %d", rt);
rt = rInt (rsp, OPENISIS_COM_ROW, -1, 0);
if (0 < exp) {
_lstb_assert (exp == rt, msg, "rowid = %d(%d)", rt, exp);
}
else {
_lstb_assert (0 < rt, msg, "rowid = %d", rt);
}
return rt;
}
static void _rmtstdb () {
char *exts[] = { "oxi", "txt", "ptr" };
char path[1024];
char *p;
int err, j;
if (! sc0) {
fprintf (stderr, "rmtstdb: st0 == 0\n");
return;
}
if (! sc0->cfg) {
fprintf (stderr, "rmtstdb: st0->cfg == 0\n");
return;
}
if (! rString (sc0->cfg, OPENISIS_SPATH, 0, path, 990)) {
fprintf (stderr, "rmtstdb: path not given\n");
return;
}
p = path + strlen (path);
*p++ = '/';
if (rString (sc0->cfg, OPENISIS_DPATH, 0, p, 10)) {
p += strlen (p);
*p++ = '/';
}
err = 0;
strcpy (p, "lstbtest.");
p += 9;
for (j = sizeof (exts) / sizeof (exts[0]); 0 <= --j; ) {
strcpy (p, exts[j]);
errno = 0;
if (unlink (path)) {
fprintf (stderr, "rmtstdb: cannot unlink %s: errno = %d\n",
p - 9, errno);
err = !0;
}
}
if (! err) {
log_msg (LOG_INFO, "db lstbtest removed.");
}
}
static void _tstUnwrap () {
Rec *r1, *r2, *r31, *r32, *r4;
r31 = rSet (0, 0, 11, "r3111", 12, "r3112", 13, "r3113", 0);
r32 = rSet (0, 0, 11, "r3211", 12, "r3212", 13, "r3213", 0);
r2 = rSet (0, 0, 21, "r221", 22, "r222", 0);
r2 = luti_wrap (r2, r31, 89);
r2 = rSet (r2, 0, 23, "r223", 0);
r2 = luti_wrap (r2, r32, 89);
r1 = 0;
r1 = luti_wrap (r1, r2, 79);
r1 = rSet (r1, 0, 111, "r1111", 112, "r1112", 0);
r4 = luti_getembed (r1, ".79.89[1]", 0);
_cmp_rec ("unwrap", r4, r32);
mFree (r1);
mFree (r2);
mFree (r31);
mFree (r32);
mFree (r4);
}
int main (int argc, char **argv) {
char *argd[64];
int lastid, lvl, j;
lvl = LOG_ERROR;
switch (argc) {
case 2:
j = atoi (argv[1]);
goto dfltargs;
case 0:
case 1:
j = 1;
dfltargs:
argc = 0;
argd[argc++] = "syspath";
argd[argc++] = "/opt/openisis/db";
argd[argc++] = "dbpath";
argd[argc++] = "cds";
argv = argd;
break;
default:
if ((j = atoi (argv[1]))) {
--argc;
++argv;
if (0 < (lastid = atoi (argv[2]))) {
lvl = lastid;
--argc;
++argv;
}
}
else {
j = 1;
}
--argc;
++argv;
}
cLog (lvl, 0);
do {
_RspCld[0] = _DelCld[0] = 0;
st0 = st1 = st2 = st3 = 0;
sc0 = sc1 = sc2 = sc3 = 0;
db = 0;
rqs = rsp = 0;
openIsisNInit (0, 0, 0);
openIsisNDeinit ();
memset (&cbdta, 0, sizeof (OpenIsisStubCbData));
cbdta.delcb = &_del_cb;
cbdta.delcld = _DelCld;
_open_srv ("A", argc, (const char**)argv);
openIsisNDeinit ();
_lstb_assert (0 == stub0, "B", "stub0 != 0");
_lstb_assert (2 == _DelCld[0], "B", "_DelCld = %d", _DelCld[0]);
sc1 = openIsisNSchema (st1);
_lstb_assert (sc1 == 0, "B", "sc1 != 0");
_open_srv ("C", argc, (const char**)argv);
openIsisNClose (st3);
_lstb_assert (3 == _DelCld[0], "D", "_DelCld = %d", _DelCld[0]);
sc1 = openIsisNSchema (st1);
_lstb_assert (sc1 == 0, "D", "sc1 != 0");
_open_db ("E", "cds");
_close_db ("F", "cds", 0);
_open_db ("G", "cds");
_close_db ("H", "cds", 0);
_open_db ("I", "cds");
_lstb_assert (0 == _RspCld[0], "I", "_RspCld = %d", _RspCld[0]);
_lstb_assert (8 == _DelCld[0], "I", "_DelCld = %d", _DelCld[0]);
_maxrow ("J", "cds", 151);
_lstb_read ("K", 94, 7);
_lstb_assert (0 == _RspCld[0], "K", "_RspCld = %d", _RspCld[0]);
_lstb_assert (9 == _DelCld[0], "K", "_DelCld = %d", _DelCld[0]);
_query ("L", 0, OPENISIS_QRY_KEYAT, 0, 0, 5);
lastid = _query ("M", 0, OPENISIS_QRY_KEYAT, 0, 4, 4);
_query ("N", 0, OPENISIS_QRY_KEYAT, 1 + lastid, 4, 1);
_query ("P", OPENISIS_RQSF_QRR, OPENISIS_QRY_KEYAT, 0, 0, 5);
lastid = _query ("Q", OPENISIS_RQSF_QRR, OPENISIS_QRY_KEYAT, 0, 4, 4);
_query ("R", OPENISIS_RQSF_QRR, OPENISIS_QRY_KEYAT, 1 + lastid, 4, 1);
_lstb_assert (0 == _RspCld[0], "R", "_RspCld = %d", _RspCld[0]);
_lstb_assert (9 == _DelCld[0], "R", "_DelCld = %d", _DelCld[0]);
_open_db ("S", "lstbtest");
lastid = _update ("T", -1, 22, "Gandalf", 22, "Frodo", 1);
_update ("U", -1, 23, "Larry", 0, 0, 2);
_update ("V", lastid, 22, "Harry", 0, 0, 1);
_maxrow ("W", "lstbtest", 2);
_lsdb ("X");
_close_db ("Y", "lstbtest", 1);
_lstb_assert (0 == _RspCld[0], "Y", "_RspCld = %d", _RspCld[0]);
_lstb_assert (15 == _DelCld[0], "Y", "_DelCld = %d", _DelCld[0]);
_rmtstdb ();
_maxrowerr ("Z", "cds");
_lstb_read ("a", 94, 7);
_maxrow ("b", "cds", 151);
_lstb_read ("c", 94, 7);
_tstUnwrap ();
openIsisNDeinit ();
_lstb_assert (0 == _RspCld[0], "z", "_RspCld = %d", _RspCld[0]);
_lstb_assert (18 == _DelCld[0], "z", "_DelCld = %d", _DelCld[0]);
if (0 == (j % 100)) {
printf ("%d ...\n", j);
}
} while (--j);
printf ("ok.\n");
return 0;
}