#include #include #include #include #include #include #include #define DEBUG #include /* $Id: tester.c 32 2006-02-20 11:48:43Z fli $ */ /* * This is a small test program to ease the development * of new backend modules. It doesn't catch all bugs * but the most obvious ones. * * Run with ./birdbtest path/to/module [optional module arguments] */ /* Define this will cause the tester to abort on failure */ /* #define EXIT_ON_FAILURE */ #define WPROMPT_DONE printf("done\n"); #define WPROMPT_FAIL printf("failed\n"); #define BSP "{ffffffff-ffff-ffff-ffff-ffffffffffff}" void tprompt(char *fmt, ...) { va_list va; va_start(va, fmt); printf("* TEST "); vprintf(fmt, va); printf("\n"); va_end(va); } void tres(int assert, char *errstr, ...) { va_list va; va_start(va, errstr); printf("* TEST "); if (!assert) { printf("FAILED : "); vprintf(errstr, va); #ifdef EXIT_ON_FAILURE exit(EXIT_FAILURE); #endif } else { printf("OK"); } putchar('\n'); va_end(va); } void wprompt(char *fmt, ...) { va_list va; va_start(va, fmt); printf("* "); vprintf(fmt, va); printf("..."); fflush(stdout); va_end(va); } void test_listmods(birdb *bdb) { struct birdb_mod **tmp; int elms, i; tmp = birdb_getmodlist(bdb, &elms); for (i = 0; i < elms; i++) { printf("vaddr=%x, name=\"%s\", desc=\"%s\"\n", tmp[i], birdb_backend_getname(tmp[i]), birdb_backend_getdesc(tmp[i])); } birdb_freemodlist(tmp); } int test_listrecs(struct birdb_mod *bm, void *beh) { struct birdb_rec *recptr; int i = 0; for (recptr = birdb_backend_seqgetfirst(bm, beh); recptr != NULL; recptr = birdb_backend_seqgetnext(bm, beh, recptr)) { printf("key=%s, time=%d\n", recptr->br_key, recptr->br_ctime); i++; } birdb_backend_seqfree(bm, beh, recptr); return (i); } int test_delall(struct birdb_mod *bm, void *beh) { struct birdb_rec *recptr; int i = 0, error; for (recptr = birdb_backend_seqgetfirst(bm, beh); recptr != NULL; recptr = birdb_backend_seqgetnext(bm, beh, recptr)) { printf("removing key=%s, time=%d\n", recptr->br_key, recptr->br_ctime); error = birdb_backend_del(bm, beh, recptr); if (error != 0) { warnx("birdb_backend_del failed"); break; } i++; } birdb_backend_seqfree(bm, beh, recptr); return (i); } int test_ins(struct birdb_mod *bm, void *beh, char *key, char *data, size_t dlen) { struct birdb_rec rec; BioAPI_BIR bir; int error; memset(&bir.Header, 0xD0, sizeof(BioAPI_BIR_HEADER)); bir.Header.Length = sizeof(BioAPI_BIR_HEADER) + dlen; bir.BiometricData = data; bir.Signature = NULL; rec.br_key = key; rec.br_bir = &bir; printf("inserting record with key \"%s\"\n", key); error = birdb_backend_ins(bm, beh, &rec); return (error); } int test_get(struct birdb_mod *bm, void *beh, char *key) { struct birdb_rec rec, *recptr, **recarr; int i; rec.br_key = key; recarr = birdb_backend_get(bm, beh, &rec); if (recarr == NULL) { return (0); } for (i = 0; recarr[i] != NULL; i++) { recptr = recarr[i]; printf("key=%s, time=%d\n", recptr->br_key, recptr->br_ctime); } return (i); } int test_del(struct birdb_mod *bm, void *beh, char *key) { struct birdb_rec rec, *recptr, **recarr; int i, error; rec.br_key = key; recarr = birdb_backend_get(bm, beh, &rec); if (recarr == NULL) { errx(1, "birdb_backend_get failed"); return (-1); } for (i = 0; recarr[i] != NULL; i++) { recptr = recarr[i]; printf("removing key=%s, time=%d\n", recptr->br_key, recptr->br_ctime); error = birdb_backend_del(bm, beh, recptr); if (error != 0) { printf("failed to remove key=%s, time=%d\n", recptr->br_key, recptr->br_ctime); break; } } birdb_backend_freegetres(bm, beh, recarr); return (i); } int main(int argc, char *argv[]) { birdb *bdb; struct birdb_mod *bm; void *beh; int i, error; if (argc < 2) { fprintf(stderr, "Usage %s module [module args]\n", argv[0]); exit(EXIT_FAILURE); } wprompt("Initializing birdb"); bdb = birdb_init(); if (bdb == NULL) errx(1, "birdb_init failed"); WPROMPT_DONE; wprompt("Loading module %s", argv[1]); bm = birdb_addmod(bdb, argv[1]); if (bm == NULL) errx(1, "birdb_addmod failed for module %s", argv[1]); WPROMPT_DONE; tprompt("Listing loaded modules"); test_listmods(bdb); tres(1 == 1, "never fail"); tprompt("Calling backend open"); printf("bsp=%s, argc=%d\n", BSP, argc - 2); for (i = 2; i < argc; i++) { printf("argv[%d] = %s\n", i - 2, argv[i]); } beh = birdb_backend_open(bm, BSP, (argc - 2), &argv[2]); tres(beh != NULL, "birdb_backend_open failed"); if (beh == NULL) errx(1, "unable to continue"); tprompt("Listing current records..."); error = test_listrecs(bm, beh); tres(error == 0, "expected zero results"); #define DATA "ABCDEF" tprompt("Inserting record"); printf("Using payload=%s\n", DATA); error = test_ins(bm, beh, "foo", DATA, strlen(DATA)); tres(error == 0, "insertion failed"); sleep(1); tprompt("Inserting record"); printf("Using payload=%s\n", DATA); error = test_ins(bm, beh, "foo", DATA, strlen(DATA)); tres(error == 0, "insertion failed"); tprompt("Inserting record"); printf("Using payload=%s\n", DATA); error = test_ins(bm, beh, "foobar", DATA, strlen(DATA)); tres(error == 0, "insertion failed"); tprompt("Listing current records (sequential)..."); error = test_listrecs(bm, beh); tres(error == 3, "expected 3 results"); tprompt("Listing current records with key foo..."); error = test_get(bm, beh, "foo"); tres(error == 2, "expected 2 results"); tprompt("Removing records with key foo..."); error = test_del(bm, beh, "foo"); tres(error == 2, "expected 2 results"); tprompt("Listing current records with key foo..."); error = test_get(bm, beh, "foo"); tres(error == 0, "expected 0 results"); tprompt("Listing current records (sequential)..."); error = test_listrecs(bm, beh); tres(error == 1, "expected 1 results"); tprompt("Removing all records"); error = test_delall(bm, beh); tres(error == 1, "expected 1 results"); tprompt("Listing current records (sequential)..."); error = test_listrecs(bm, beh); tres(error == 0, "expected 0 results"); wprompt("Closing backend"); birdb_backend_close(bm, beh); WPROMPT_DONE; wprompt("Closing birdb"); birdb_close(bdb); WPROMPT_DONE; }