Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117755214
duplicate.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None
duplicate.c
View Options
#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
Details
Attached
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)
Attached To
Mode
R111 cyrus-imapd
Attached
Detach File
Event Timeline