Page MenuHomePhorge

duplicate.c
No OneTemporary

Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None

duplicate.c

#include <unistd.h>
#include <stdlib.h>
#include "config.h"
#include "cunit/cunit.h"
#include "duplicate.h"
#include "xmalloc.h"
#include "retry.h"
#include "global.h"
#include "imap_err.h"
#include "cyrusdb.h"
#include "libcyr_cfg.h"
#include "libconfig.h"
#include "hash.h"
#define DBDIR "test-mb-dbdir"
struct result
{
struct result *next;
char *id;
char *to;
char *date;
time_t mark;
unsigned long uid;
};
#define GOTRESULT(expid, expto, expdate, expmark, expuid) \
{ \
struct result *actual = results; \
CU_ASSERT_PTR_NOT_NULL_FATAL(results); \
results = results->next; \
CU_ASSERT_STRING_EQUAL(expid, actual->id); \
CU_ASSERT_STRING_EQUAL(expto, actual->to); \
CU_ASSERT_STRING_EQUAL(expdate, actual->date); \
CU_ASSERT_EQUAL(expmark, actual->mark); \
CU_ASSERT_EQUAL(expuid, actual->uid); \
free(actual->id); \
free(actual->to); \
free(actual->date); \
free(actual); \
}
static void test_getset(void)
{
duplicate_key_t dkey = DUPLICATE_INITIALIZER;
time_t t;
time_t now;
static const char MSGID1[] = "<fake0999@fastmail.fm>";
static const char MSGID2[] = "<fake1001@fastmail.fm>";
static const char FOLDER[] = "user.smurf";
static const char DATE[] = "Wed, 27 Oct 2010 18:37:26 +1100";
static unsigned long UID = 42;
/* an invalid key returns 0 */
dkey.id = NULL;
dkey.to = NULL;
dkey.date = NULL;
t = duplicate_check(&dkey);
CU_ASSERT_EQUAL(t, 0);
/* a valid but missing key returns 0 */
dkey.id = MSGID1;
dkey.to = FOLDER;
dkey.date = DATE;
t = duplicate_check(&dkey);
CU_ASSERT_EQUAL(t, 0);
/* the other one too */
dkey.id = MSGID2;
dkey.to = FOLDER;
dkey.date = DATE;
t = duplicate_check(&dkey);
CU_ASSERT_EQUAL(t, 0);
/* mark appears to succeed */
dkey.id = MSGID1;
dkey.to = FOLDER;
dkey.date = DATE;
now = time(NULL);
duplicate_mark(&dkey, now, UID);
/* an invalid key still returns 0 */
dkey.id = NULL;
dkey.to = NULL;
dkey.date = NULL;
t = duplicate_check(&dkey);
CU_ASSERT_EQUAL(t, 0);
/* a valid and present key returns non-zero */
dkey.id = MSGID1;
dkey.to = FOLDER;
dkey.date = DATE;
t = duplicate_check(&dkey);
CU_ASSERT_NOT_EQUAL(t, 0);
CU_ASSERT_EQUAL(t, now);
/* a valid but missing key still returns 0 */
dkey.id = MSGID2;
dkey.to = FOLDER;
dkey.date = DATE;
t = duplicate_check(&dkey);
CU_ASSERT_EQUAL(t, 0);
}
static int finder(const duplicate_key_t *dkey, time_t mark,
unsigned long uid, void *rock)
{
struct result **head = (struct result **)rock;
struct result **tail;
struct result *res;
// if (verbose)
// fprintf(stderr, "found: id=\"%s\" to=\"%s\" date=\"%s\" "
// "mark=%lu uid=%lu\n",
// dkey->id, dkey->to, dkey->date,
// (unsigned long)mark, (unsigned long)uid);
/* remember arguments for later perusal */
res = xzmalloc(sizeof(*res));
res->id = xstrdup(dkey->id);
res->to = xstrdup(dkey->to);
res->date = xstrdup(dkey->date);
res->mark = mark;
res->uid = uid;
/* append to the list. yes, it's inefficient. */
for (tail = head ; *tail ; tail = &(*tail)->next)
;
*tail = res;
return 0;
}
static void test_find(void)
{
duplicate_key_t dkey = DUPLICATE_INITIALIZER;
struct result *results = NULL;
static const char MSGID1[] = "<fake0999@fastmail.fm>";
static const char MSGID2[] = "<fake1001@fastmail.fm>";
/* test data from hipsteripsum.me */
static const char FOLDER1[] = "user.vegan";
static const char FOLDER2[] = "user.irony";
static const char FOLDER3[] = "user.single.origin";
static const char FOLDER4[] = "user.loko";
static const char FOLDER5[] = "user.biodiesel";
static const char DATE1[] = "Wed, 27 Oct 2010 18:01:02 +1100";
static const char DATE2[] = "Wed, 27 Oct 2010 18:03:04 +1100";
static const char DATE3[] = "Wed, 27 Oct 2010 18:05:06 +1100";
static const char DATE4[] = "Wed, 27 Oct 2010 18:07:08 +1100";
static const char DATE5[] = "Wed, 27 Oct 2010 18:09:10 +1100";
static time_t MARK1 = 1319088235;
static time_t MARK2 = 1319088235;
static time_t MARK3 = 1319088236;
static time_t MARK4 = 1319088735;
static time_t MARK5 = 1319089235;
static unsigned long UID1 = 23;
static unsigned long UID2 = 37;
static unsigned long UID3 = 42;
static unsigned long UID4 = 1007;
static unsigned long UID5 = 314159;
int r;
/* find on an empty db returns nothing */
r = duplicate_find(MSGID1, finder, &results);
CU_ASSERT_EQUAL(r, 0);
CU_ASSERT_PTR_NULL(results);
r = duplicate_find(MSGID2, finder, &results);
CU_ASSERT_EQUAL(r, 0);
CU_ASSERT_PTR_NULL(results);
/* add one entry */
dkey.id = MSGID1;
dkey.to = FOLDER1;
dkey.date = DATE1;
duplicate_mark(&dkey, MARK1, UID1);
/* find returns the only entry */
r = duplicate_find(MSGID1, finder, &results);
CU_ASSERT_EQUAL(r, 0);
GOTRESULT(MSGID1, FOLDER1, DATE1, MARK1, UID1);
CU_ASSERT_PTR_NULL(results);
/* find of another msgid returns nothing */
r = duplicate_find(MSGID2, finder, &results);
CU_ASSERT_EQUAL(r, 0);
CU_ASSERT_PTR_NULL(results);
/* add some more entries */
dkey.id = MSGID1;
dkey.to = FOLDER2;
dkey.date = DATE2;
duplicate_mark(&dkey, MARK2, UID2);
dkey.id = MSGID1;
dkey.to = FOLDER3;
dkey.date = DATE3;
duplicate_mark(&dkey, MARK3, UID3);
/* find returns all the entries in lexical order */
r = duplicate_find(MSGID1, finder, &results);
CU_ASSERT_EQUAL(r, 0);
GOTRESULT(MSGID1, FOLDER2, DATE2, MARK2, UID2);
GOTRESULT(MSGID1, FOLDER3, DATE3, MARK3, UID3);
GOTRESULT(MSGID1, FOLDER1, DATE1, MARK1, UID1);
CU_ASSERT_PTR_NULL(results);
/* find of another msgid returns nothing */
r = duplicate_find(MSGID2, finder, &results);
CU_ASSERT_EQUAL(r, 0);
CU_ASSERT_PTR_NULL(results);
/* add some entries for another msgid */
dkey.id = MSGID2;
dkey.to = FOLDER4;
dkey.date = DATE4;
duplicate_mark(&dkey, MARK4, UID4);
dkey.id = MSGID2;
dkey.to = FOLDER5;
dkey.date = DATE5;
duplicate_mark(&dkey, MARK5, UID5);
/* find returns all the entries in lexical order */
r = duplicate_find(MSGID1, finder, &results);
CU_ASSERT_EQUAL(r, 0);
GOTRESULT(MSGID1, FOLDER2, DATE2, MARK2, UID2);
GOTRESULT(MSGID1, FOLDER3, DATE3, MARK3, UID3);
GOTRESULT(MSGID1, FOLDER1, DATE1, MARK1, UID1);
CU_ASSERT_PTR_NULL(results);
/* find of another msgid all it's entries in lexical order */
r = duplicate_find(MSGID2, finder, &results);
CU_ASSERT_EQUAL(r, 0);
GOTRESULT(MSGID2, FOLDER5, DATE5, MARK5, UID5);
GOTRESULT(MSGID2, FOLDER4, DATE4, MARK4, UID4);
CU_ASSERT_PTR_NULL(results);
/* find with msgid="" returns all the entries for all msgids */
r = duplicate_find("", finder, &results);
CU_ASSERT_EQUAL(r, 0);
GOTRESULT(MSGID1, FOLDER2, DATE2, MARK2, UID2);
GOTRESULT(MSGID1, FOLDER3, DATE3, MARK3, UID3);
GOTRESULT(MSGID1, FOLDER1, DATE1, MARK1, UID1);
GOTRESULT(MSGID2, FOLDER5, DATE5, MARK5, UID5);
GOTRESULT(MSGID2, FOLDER4, DATE4, MARK4, UID4);
CU_ASSERT_PTR_NULL(results);
/* likewise msgid=NULL */
r = duplicate_find(NULL, finder, &results);
CU_ASSERT_EQUAL(r, 0);
GOTRESULT(MSGID1, FOLDER2, DATE2, MARK2, UID2);
GOTRESULT(MSGID1, FOLDER3, DATE3, MARK3, UID3);
GOTRESULT(MSGID1, FOLDER1, DATE1, MARK1, UID1);
GOTRESULT(MSGID2, FOLDER5, DATE5, MARK5, UID5);
GOTRESULT(MSGID2, FOLDER4, DATE4, MARK4, UID4);
CU_ASSERT_PTR_NULL(results);
}
static void config_read_string(const char *s)
{
char *fname = xstrdup("/tmp/cyrus-cunit-configXXXXXX");
int fd = mkstemp(fname);
retry_write(fd, s, strlen(s));
config_reset();
config_read(fname);
unlink(fname);
free(fname);
close(fd);
}
static int set_up(void)
{
int r;
const char * const *d;
static const char * const dirs[] = {
DBDIR,
DBDIR"/db",
NULL
};
r = system("rm -rf " DBDIR);
if (r)
return r;
for (d = dirs ; *d ; d++) {
r = mkdir(*d, 0777);
if (r < 0) {
int e = errno;
perror(*d);
return e;
}
}
libcyrus_config_setstring(CYRUSOPT_CONFIG_DIR, DBDIR);
config_read_string(
"configdirectory: "DBDIR"/conf\n"
);
cyrusdb_init();
config_duplicate_db = "skiplist";
duplicate_init(0);
return 0;
}
static int tear_down(void)
{
int r;
duplicate_done();
cyrusdb_done();
config_duplicate_db = NULL;
config_reset();
r = system("rm -rf " DBDIR);
/* I'm ignoring you */
return 0;
}

File Metadata

Mime Type
text/x-c
Expires
Sat, Apr 4, 7:50 AM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18823082
Default Alt Text
duplicate.c (8 KB)

Event Timeline