Mercurial > dovecot > original-hg > dovecot-1.2
view src/tests/test-mail.c @ 6727:c49084d2148e HEAD
Added message-parser unit test.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 08 Nov 2007 03:08:03 +0200 |
parents | 4e4a5d6bb2cb |
children | d329f3c77c65 |
line wrap: on
line source
/* Copyright (c) 2007 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "istream-internal.h" #include "message-address.h" #include "message-date.h" #include "message-parser.h" #include "test-common.h" static const char test_msg[] = "Return-Path: <test@example.org>\n" "Subject: Hello world\n" "From: Test User <test@example.org>\n" "To: Another User <test2@example.org>\n" "Message-Id: <1.2.3.4@example>\n" "Mime-Version: 1.0\n" "Date: Sun, 23 May 2007 04:58:08 +0300\n" "Content-Type: multipart/signed; micalg=pgp-sha1;\n" " protocol=\"application/pgp-signature\";\n" " boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n" "\n" "--=-GNQXLhuj24Pl1aCkk4/d\n" "Content-Type: text/plain\n" "Content-Transfer-Encoding: quoted-printable\n" "\n" "There was a day=20\n" "a happy=20day\n" "\n" "--=-GNQXLhuj24Pl1aCkk4/d\n" "Content-Type: application/pgp-signature; name=signature.asc\n" "\n" "-----BEGIN PGP SIGNATURE-----\n" "Version: GnuPG v1.2.4 (GNU/Linux)\n" "\n" "invalid\n" "-----END PGP SIGNATURE-----\n" "\n" "--=-GNQXLhuj24Pl1aCkk4/d--\n" "\n" "\n"; #define TEST_MSG_LEN (sizeof(test_msg)-1) static bool cmp_addr(const struct message_address *a1, const struct message_address *a2) { return null_strcmp(a1->name, a2->name) == 0 && null_strcmp(a1->route, a2->route) == 0 && null_strcmp(a1->mailbox, a2->mailbox) == 0 && null_strcmp(a1->domain, a2->domain) == 0; } static void test_message_address(void) { static const char *input[] = { "user@domain", "<user@domain>", "foo bar <user@domain>", "\"foo bar\" <user@domain>", "<@route:user@domain>", "<@route@route2:user@domain>", "hello <@route ,@route2:user@domain>" }; static struct message_address group_prefix = { NULL, NULL, NULL, "group", NULL }; static struct message_address group_suffix = { NULL, NULL, NULL, NULL, NULL }; static struct message_address output[] = { { NULL, NULL, NULL, "user", "domain" }, { NULL, NULL, NULL, "user", "domain" }, { NULL, "foo bar", NULL, "user", "domain" }, { NULL, "foo bar", NULL, "user", "domain" }, { NULL, NULL, "@route", "user", "domain" }, { NULL, NULL, "@route,@route2", "user", "domain" }, { NULL, "hello", "@route,@route2", "user", "domain" } }; struct message_address *addr; string_t *group; unsigned int i; bool success; group = t_str_new(256); str_append(group, "group: "); for (i = 0; i < N_ELEMENTS(input); i++) { addr = message_address_parse(pool_datastack_create(), (const unsigned char *)input[i], strlen(input[i]), -1U, FALSE); success = addr != NULL && addr->next == NULL && cmp_addr(addr, &output[i]); test_out(t_strdup_printf("message_address_parse(%d)", i), success); if (i != 0) { if ((i % 2) == 0) str_append(group, ","); else str_append(group, " , \n "); } str_append(group, input[i]); } str_append_c(group, ';'); addr = message_address_parse(pool_datastack_create(), str_data(group), str_len(group), -1U, FALSE); success = addr != NULL && cmp_addr(addr, &group_prefix); addr = addr->next; for (i = 0; i < N_ELEMENTS(input) && addr != NULL; i++) { if (!cmp_addr(addr, &output[i])) { success = FALSE; break; } addr = addr->next; } if (addr == NULL || addr->next != NULL || !cmp_addr(addr, &group_suffix)) success = FALSE; test_out("message_address_parse(group)", success); } struct test_message_date_output { time_t time; int tz_offset; bool ret; }; static void test_message_date_parse(void) { static const char *input[] = { #ifdef TIME_T_SIGNED "Thu, 01 Jan 1970 01:59:59 +0200", "Fri, 13 Dec 1901 20:45:52 +0000", #endif #if TIME_T_MAX_BITS > 31 "Sun, 07 Feb 2106 06:28:15 +0000", #endif "Wed, 07 Nov 2007 01:07:20 +0200", "Wed, 07 Nov 2007 01:07:20", "Thu, 01 Jan 1970 02:00:00 +0200", "Tue, 19 Jan 2038 03:14:07 +0000", "Tue, 19 Jan 2038" }; static struct test_message_date_output output[] = { #ifdef TIME_T_SIGNED { -1, 2*60, TRUE }, { -2147483648, 0, TRUE }, #endif #if TIME_T_MAX_BITS > 31 { 4294967295, 0, TRUE }, #endif { 1194390440, 2*60, TRUE }, { 1194397640, 0, TRUE }, { 0, 2*60, TRUE }, { 2147483647, 0, TRUE }, { 0, 0, FALSE } }; unsigned int i; bool success; time_t t; int tz; bool ret; for (i = 0; i < N_ELEMENTS(input); i++) { ret = message_date_parse((const unsigned char *)input[i], strlen(input[i]), &t, &tz); success = (!ret && !output[i].ret) || (ret == output[i].ret && t == output[i].time && tz == output[i].tz_offset); test_out(t_strdup_printf("message_date_parse(%d)", i), success); } } static bool msg_parts_cmp(struct message_part *p1, struct message_part *p2) { while (p1 != NULL || p2 != NULL) { if ((p1 != NULL) != (p2 != NULL)) return FALSE; if ((p1->children != NULL) != (p2->children != NULL)) return FALSE; if (p1->children) { if (!msg_parts_cmp(p1->children, p2->children)) return FALSE; } if (p1->physical_pos != p2->physical_pos || p1->header_size.physical_size != p2->header_size.physical_size || p1->header_size.virtual_size != p2->header_size.virtual_size || p1->header_size.lines != p2->header_size.lines || p1->body_size.physical_size != p2->body_size.physical_size || p1->body_size.virtual_size != p2->body_size.virtual_size || p1->body_size.lines != p2->body_size.lines || p1->flags != p2->flags) return FALSE; p1 = p1->next; p2 = p2->next; } return TRUE; } static ssize_t test_read(struct istream_private *stream) { if (stream->pos < TEST_MSG_LEN) return 0; stream->istream.eof = TRUE; return -1; } static void test_message_parser(void) { struct message_parser_ctx *parser; struct istream *input; struct message_part *parts, *parts2; struct message_block block; unsigned int i; bool success = TRUE; pool_t pool; int ret; pool = pool_alloconly_create("message parser", 10240); input = i_stream_create_from_data(test_msg, TEST_MSG_LEN); parser = message_parser_init(pool, input, 0, 0); while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; i_assert(ret < 0); parts = message_parser_deinit(&parser); i_stream_unref(&input); input = i_stream_create_from_data(test_msg, TEST_MSG_LEN); input->blocking = FALSE; input->real_stream->read = test_read; parser = message_parser_init(pool, input, 0, 0); for (i = 1; i <= TEST_MSG_LEN; i++) { input->real_stream->pos = i; while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; if (ret < 0 && i < TEST_MSG_LEN) { success = FALSE; break; } } parts2 = message_parser_deinit(&parser); i_stream_unref(&input); if (!msg_parts_cmp(parts, parts2)) success = FALSE; pool_unref(&pool); test_out("message_parser()", success); } int main(void) { test_init(); test_message_address(); test_message_date_parse(); test_message_parser(); return test_deinit(); }