1
/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
9
#include "master-service.h"
10
#include "test-common.h"
11
#include "dsync-proxy-server.h"
12
#include "test-dsync-worker.h"
13
#include "test-dsync-common.h"
15
#define ALL_MAIL_FLAGS "\\Answered \\Flagged \\Deleted \\Seen \\Draft \\Recent"
17
struct master_service *master_service;
19
static struct dsync_proxy_server *server;
20
static struct test_dsync_worker *test_worker;
21
static struct dsync_proxy_server_command *cur_cmd;
22
static const char *cur_cmd_args[20];
24
void master_service_stop(struct master_service *service ATTR_UNUSED) {}
26
static void out_clear(void)
28
o_stream_seek(server->output, 0);
32
static int run_more(void)
36
ret = cur_cmd->func(server, cur_cmd_args);
44
static int ATTR_SENTINEL
45
run_cmd(const char *cmd_name, ...)
51
i_assert(cur_cmd == NULL);
53
va_start(va, cmd_name);
54
while ((str = va_arg(va, const char *)) != NULL) {
55
i_assert(i < N_ELEMENTS(cur_cmd_args)+1);
56
cur_cmd_args[i++] = str;
58
cur_cmd_args[i] = NULL;
61
cur_cmd = dsync_proxy_server_command_find(cmd_name);
62
i_assert(cur_cmd != NULL);
66
static void test_dsync_proxy_box_list(void)
68
struct dsync_mailbox box;
70
test_begin("proxy server box list");
72
test_assert(run_cmd("BOX-LIST", NULL) == 0);
74
/* \noselect mailbox */
75
memset(&box, 0, sizeof(box));
76
box.name = "\t\001\r\nname\t\001\n\r";
78
box.last_change = 992;
79
box.flags = DSYNC_MAILBOX_FLAG_NOSELECT;
80
test_worker->box_iter.next_box = &box;
81
test_assert(run_more() == 0);
82
test_assert(strcmp(str_c(out), t_strconcat(str_tabescape(box.name),
83
"\t/\t992\t1\n", NULL)) == 0);
86
/* selectable mailbox */
87
memset(&box, 0, sizeof(box));
90
memcpy(box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE);
91
box.uid_validity = 4275878552;
92
box.uid_next = 4023233417;
93
box.message_count = 4525;
94
box.highest_modseq = 18080787909545915012ULL;
95
box.first_recent_uid = 353;
96
test_worker->box_iter.next_box = &box;
98
test_assert(run_more() == 0);
100
test_assert(strcmp(str_c(out), "foo/bar\t/\t0\t0\t"
101
TEST_MAILBOX_GUID1"\t"
105
"18080787909545915012\t"
110
test_worker->box_iter.last = TRUE;
111
test_assert(run_more() == 1);
112
test_assert(strcmp(str_c(out), "+\n") == 0);
118
static void test_dsync_proxy_subs_list(void)
121
struct dsync_worker_subscription subs;
122
struct dsync_worker_unsubscription unsubs;
124
test_begin("proxy server subs list");
126
test_assert(run_cmd("SUBS-LIST", NULL) == 0);
129
name = "\t\001\r\nname\t\001\n\r";
131
subs.storage_name = "\tstorage_name\n";
132
subs.last_change = 1234567890;
133
subs.ns_prefix = "\t\001\r\nprefix\t\001\n\r";
134
test_worker->subs_iter.next_subscription = &subs;
135
test_assert(run_more() == 0);
136
test_assert(strcmp(str_c(out), t_strconcat(
137
str_tabescape(name), "\t",
138
str_tabescape(subs.storage_name), "\t",
139
str_tabescape(subs.ns_prefix),
140
"\t1234567890\n", NULL)) == 0);
143
test_worker->subs_iter.last_subs = TRUE;
144
test_assert(run_more() == 0);
145
test_assert(strcmp(str_c(out), "+\n") == 0);
149
memcpy(unsubs.name_sha1.guid, test_mailbox_guid1,
150
sizeof(unsubs.name_sha1.guid));
151
unsubs.ns_prefix = "\t\001\r\nprefix2\t\001\n\r";
152
unsubs.last_change = 987654321;
153
test_worker->subs_iter.next_unsubscription = &unsubs;
154
test_assert(run_more() == 0);
155
test_assert(strcmp(str_c(out), t_strconcat(TEST_MAILBOX_GUID1, "\t",
156
str_tabescape(unsubs.ns_prefix), "\t987654321\n", NULL)) == 0);
159
test_worker->subs_iter.last_unsubs = TRUE;
160
test_assert(run_more() == 1);
161
test_assert(strcmp(str_c(out), "+\n") == 0);
167
static void test_dsync_proxy_msg_list(void)
169
static const char *test_keywords[] = {
172
struct dsync_message msg;
173
struct test_dsync_worker_msg test_msg;
175
test_begin("proxy server msg list");
177
test_assert(run_cmd("MSG-LIST", TEST_MAILBOX_GUID1, TEST_MAILBOX_GUID2, NULL) == 0);
179
memset(&msg, 0, sizeof(msg));
180
msg.guid = "\t\001\r\nguid\t\001\n\r";
182
msg.modseq = 98765432101234;
183
msg.save_date = 1234567890;
187
test_msg.mailbox_idx = 98;
188
array_append(&test_worker->msg_iter.msgs, &test_msg, 1);
189
test_assert(run_more() == 0);
190
test_assert(strcmp(str_c(out), t_strconcat(
191
"98\t", str_tabescape(msg.guid),
192
"\t123\t98765432101234\t\t1234567890\n", NULL)) == 0);
195
/* all flags, some keywords */
199
msg.flags = MAIL_FLAGS_MASK;
200
msg.keywords = test_keywords;
202
test_msg.mailbox_idx = 76;
203
array_append(&test_worker->msg_iter.msgs, &test_msg, 1);
204
test_assert(run_more() == 0);
205
test_assert(strcmp(str_c(out), "76\tguid\t123\t1\t"
206
ALL_MAIL_FLAGS" kw1 kw2\t2\n") == 0);
210
test_worker->msg_iter.last = TRUE;
211
test_assert(run_more() == 1);
212
test_assert(strcmp(str_c(out), "+\n") == 0);
218
static void test_dsync_proxy_box_create(void)
220
struct test_dsync_box_event event;
222
test_begin("proxy server box create");
224
test_assert(run_cmd("BOX-CREATE", "noselect", "/",
225
"553", "1", NULL) == 1);
226
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
227
test_assert(event.type == LAST_BOX_TYPE_CREATE);
228
test_assert(strcmp(event.box.name, "noselect") == 0);
229
test_assert(event.box.name_sep == '/');
230
test_assert(event.box.last_change == 553);
231
test_assert(event.box.flags == DSYNC_MAILBOX_FLAG_NOSELECT);
232
test_assert(event.box.uid_validity == 0);
234
test_assert(run_cmd("BOX-CREATE", "selectable", "?",
235
"61", "2", TEST_MAILBOX_GUID2, "1234567890", "9876",
236
"4610", "28427847284728", "853", NULL) == 1);
237
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
238
test_assert(event.type == LAST_BOX_TYPE_CREATE);
239
test_assert(strcmp(event.box.name, "selectable") == 0);
240
test_assert(event.box.name_sep == '?');
241
test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
242
test_assert(event.box.flags == 2);
243
test_assert(event.box.uid_validity == 1234567890);
244
test_assert(event.box.uid_next == 9876);
245
test_assert(event.box.message_count == 4610);
246
test_assert(event.box.highest_modseq == 28427847284728);
247
test_assert(event.box.first_recent_uid == 853);
248
test_assert(event.box.last_change == 61);
253
static void test_dsync_proxy_box_delete(void)
255
struct test_dsync_box_event event;
257
test_begin("proxy server box delete");
259
test_assert(run_cmd("BOX-DELETE", TEST_MAILBOX_GUID1, "4351", NULL) == 1);
260
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
261
test_assert(event.type == LAST_BOX_TYPE_DELETE);
262
test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
263
test_assert(event.box.last_change == 4351);
265
test_assert(run_cmd("BOX-DELETE", TEST_MAILBOX_GUID2, "653", NULL) == 1);
266
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
267
test_assert(event.type == LAST_BOX_TYPE_DELETE);
268
test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
269
test_assert(event.box.last_change == 653);
274
static void test_dsync_proxy_box_rename(void)
276
struct test_dsync_box_event event;
278
test_begin("proxy server box rename");
280
test_assert(run_cmd("BOX-RENAME", TEST_MAILBOX_GUID1, "name\t1", "/", NULL) == 1);
281
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
282
test_assert(event.type == LAST_BOX_TYPE_RENAME);
283
test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
284
test_assert(strcmp(event.box.name, "name\t1") == 0);
285
test_assert(event.box.name_sep == '/');
287
test_assert(run_cmd("BOX-RENAME", TEST_MAILBOX_GUID2, "", "?", NULL) == 1);
288
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
289
test_assert(event.type == LAST_BOX_TYPE_RENAME);
290
test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
291
test_assert(strcmp(event.box.name, "") == 0);
292
test_assert(event.box.name_sep == '?');
297
static void test_dsync_proxy_box_update(void)
299
struct test_dsync_box_event event;
301
test_begin("proxy server box update");
303
test_assert(run_cmd("BOX-UPDATE", "updated", "/",
304
"53", "2", TEST_MAILBOX_GUID1, "34343", "22",
305
"58293", "2238427847284728", "2482", NULL) == 1);
306
test_assert(test_dsync_worker_next_box_event(test_worker, &event));
307
test_assert(event.type == LAST_BOX_TYPE_UPDATE);
308
test_assert(strcmp(event.box.name, "updated") == 0);
309
test_assert(event.box.name_sep == '/');
310
test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
311
test_assert(event.box.flags == DSYNC_MAILBOX_FLAG_DELETED_MAILBOX);
312
test_assert(event.box.uid_validity == 34343);
313
test_assert(event.box.uid_next == 22);
314
test_assert(event.box.message_count == 58293);
315
test_assert(event.box.highest_modseq == 2238427847284728);
316
test_assert(event.box.first_recent_uid == 2482);
317
test_assert(event.box.last_change == 53);
322
static void test_dsync_proxy_box_select(void)
324
test_begin("proxy server box select");
326
test_assert(run_cmd("BOX-SELECT", TEST_MAILBOX_GUID1, NULL) == 1);
327
test_assert(memcmp(test_worker->selected_mailbox.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
329
test_assert(run_cmd("BOX-SELECT", TEST_MAILBOX_GUID2, NULL) == 1);
330
test_assert(memcmp(test_worker->selected_mailbox.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
335
static void test_dsync_proxy_msg_update(void)
337
struct test_dsync_msg_event event;
339
test_begin("proxy server msg update");
341
test_assert(run_cmd("MSG-UPDATE", "123", "4782782842924",
342
"kw1 "ALL_MAIL_FLAGS" kw2", NULL) == 1);
343
test_assert(test_dsync_worker_next_msg_event(test_worker, &event));
344
test_assert(event.type == LAST_MSG_TYPE_UPDATE);
345
test_assert(event.msg.uid == 123);
346
test_assert(event.msg.modseq == 4782782842924);
347
test_assert(event.msg.flags == MAIL_FLAGS_MASK);
348
test_assert(strcmp(event.msg.keywords[0], "kw1") == 0);
349
test_assert(strcmp(event.msg.keywords[1], "kw2") == 0);
350
test_assert(event.msg.keywords[2] == NULL);
355
static void test_dsync_proxy_msg_uid_change(void)
357
struct test_dsync_msg_event event;
359
test_begin("proxy server msg uid change");
361
test_assert(run_cmd("MSG-UID-CHANGE", "454", "995", NULL) == 1);
362
test_assert(test_dsync_worker_next_msg_event(test_worker, &event));
363
test_assert(event.type == LAST_MSG_TYPE_UPDATE_UID);
364
test_assert(event.msg.uid == 454);
365
test_assert(event.msg.modseq == 995);
370
static void test_dsync_proxy_msg_expunge(void)
372
struct test_dsync_msg_event event;
374
test_begin("proxy server msg expunge");
376
test_assert(run_cmd("MSG-EXPUNGE", "8585", NULL) == 1);
377
test_assert(test_dsync_worker_next_msg_event(test_worker, &event));
378
test_assert(event.type == LAST_MSG_TYPE_EXPUNGE);
379
test_assert(event.msg.uid == 8585);
384
static void test_dsync_proxy_msg_copy(void)
386
struct test_dsync_msg_event msg_event;
388
test_begin("proxy server msg copy");
390
test_assert(run_cmd("MSG-COPY", TEST_MAILBOX_GUID1, "5454",
391
"copyguid", "5678", "74782482882924", "\\Seen foo \\Draft",
392
"8294284", NULL) == 1);
393
test_assert(test_dsync_worker_next_msg_event(test_worker, &msg_event));
394
test_assert(msg_event.type == LAST_MSG_TYPE_COPY);
395
test_assert(memcmp(msg_event.copy_src_mailbox.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
396
test_assert(msg_event.copy_src_uid == 5454);
397
test_assert(strcmp(msg_event.msg.guid, "copyguid") == 0);
398
test_assert(msg_event.msg.uid == 5678);
399
test_assert(msg_event.msg.modseq == 74782482882924);
400
test_assert(msg_event.msg.flags == (MAIL_SEEN | MAIL_DRAFT));
401
test_assert(strcmp(msg_event.msg.keywords[0], "foo") == 0);
402
test_assert(msg_event.msg.keywords[1] == NULL);
403
test_assert(msg_event.msg.save_date == 8294284);
408
static void test_dsync_proxy_msg_save(void)
410
static const char *input = "..dotty\n..behavior\nfrom you\n.\nstop";
411
struct test_dsync_msg_event event;
412
const unsigned char *data;
415
test_begin("proxy server msg save");
417
server->input = i_stream_create_from_data(input, strlen(input));
419
test_assert(run_cmd("MSG-SAVE", "28492428", "pop3uidl",
420
"saveguid", "874", "33982482882924", "\\Flagged bar \\Answered",
421
"8294284", NULL) == 1);
422
test_assert(test_dsync_worker_next_msg_event(test_worker, &event));
423
test_assert(event.type == LAST_MSG_TYPE_SAVE);
424
test_assert(event.save_data.received_date == 28492428);
425
test_assert(strcmp(event.save_data.pop3_uidl, "pop3uidl") == 0);
426
test_assert(strcmp(event.save_body, ".dotty\n.behavior\nfrom you") == 0);
428
test_assert(strcmp(event.msg.guid, "saveguid") == 0);
429
test_assert(event.msg.uid == 874);
430
test_assert(event.msg.modseq == 33982482882924);
431
test_assert(event.msg.flags == (MAIL_FLAGGED | MAIL_ANSWERED));
432
test_assert(strcmp(event.msg.keywords[0], "bar") == 0);
433
test_assert(event.msg.keywords[1] == NULL);
434
test_assert(event.msg.save_date == 8294284);
436
data = i_stream_get_data(server->input, &size);
437
test_assert(size == 4 && memcmp(data, "stop", 4) == 0);
438
i_stream_destroy(&server->input);
443
static struct dsync_proxy_server *
444
dsync_proxy_server_init_test(buffer_t *outbuf)
446
struct dsync_proxy_server *server;
448
server = i_new(struct dsync_proxy_server, 1);
449
server->worker = dsync_worker_init_test();
453
server->cmd_pool = pool_alloconly_create("worker server cmd", 1024);
454
server->output = o_stream_create_buffer(outbuf);
460
static void (*test_functions[])(void) = {
461
test_dsync_proxy_box_list,
462
test_dsync_proxy_subs_list,
463
test_dsync_proxy_msg_list,
464
test_dsync_proxy_box_create,
465
test_dsync_proxy_box_delete,
466
test_dsync_proxy_box_rename,
467
test_dsync_proxy_box_update,
468
test_dsync_proxy_box_select,
469
test_dsync_proxy_msg_update,
470
test_dsync_proxy_msg_uid_change,
471
test_dsync_proxy_msg_expunge,
472
test_dsync_proxy_msg_copy,
473
test_dsync_proxy_msg_save,
479
out = buffer_create_dynamic(default_pool, 1024);
480
server = dsync_proxy_server_init_test(out);
481
test_worker = (struct test_dsync_worker *)server->worker;
483
test_run_funcs(test_functions);
484
return test_deinit();