/*
* This library is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*/
/* threaded folder testing */
#include
#include "camel-test.h"
#include "camel-test-provider.h"
#include "folders.h"
#include "messages.h"
#include "session.h"
#define MAX_MESSAGES (100)
#define MAX_THREADS (10)
static const gchar *local_drivers[] = { "local" };
static const gchar *local_providers[] = {
"mbox",
"mh",
"maildir"
};
static void
test_add_message (CamelFolder *folder,
gint j)
{
CamelMimeMessage *msg;
gchar *content;
gchar *subject;
GError *error = NULL;
push ("creating message %d\n", j);
msg = test_message_create_simple ();
content = g_strdup_printf ("Test message %08x contents\n\n", j);
test_message_set_content_simple (
(CamelMimePart *) msg, 0, "text/plain",
content, strlen (content));
test_free (content);
subject = g_strdup_printf ("Test message %08x subject", j);
camel_mime_message_set_subject (msg, subject);
pull ();
push ("appending simple message %d", j);
camel_folder_append_message_sync (
folder, msg, NULL, NULL, NULL, &error);
check_msg (error == NULL, "%s", error->message);
g_clear_error (&error);
pull ();
check_unref (msg, 1);
}
struct _threadinfo {
gint id;
CamelFolder *folder;
};
static gpointer
worker (gpointer d)
{
struct _threadinfo *info = d;
gint i, j, id = info->id;
gchar *sub, *content;
GPtrArray *res;
CamelMimeMessage *msg;
GError *error = NULL;
/* we add a message, search for it, twiddle some flags, delete it */
/* and flat out */
for (i = 0; i < MAX_MESSAGES; i++) {
test_add_message (info->folder, id + i);
sub = g_strdup_printf ("(match-all (header-contains \"subject\" \"message %08x subject\"))", id + i);
push ("searching for message %d\n\tusing: %s", id + i, sub);
res = camel_folder_search_by_expression (info->folder, sub, NULL, &error);
check_msg (error == NULL, "%s", error->message);
check_msg (res && res->len == 1, "res->len = %d", res ? res->len : -1);
g_clear_error (&error);
pull ();
push ("getting message '%s'", res->pdata[0]);
msg = camel_folder_get_message_sync (
info->folder, (gchar *) res->pdata[0], NULL, &error);
check_msg (error == NULL, "%s", error->message);
g_clear_error (&error);
pull ();
content = g_strdup_printf ("Test message %08x contents\n\n", id + i);
push ("comparing content '%s': '%s'", res->pdata[0], content);
test_message_compare_content (camel_medium_get_content ((CamelMedium *) msg), content, strlen (content));
test_free (content);
pull ();
push ("deleting message, cleanup");
j = g_random_int_range (0, 100);
if (j <= 70) {
camel_folder_delete_message (info->folder, res->pdata[0]);
}
camel_folder_search_free (info->folder, res);
res = NULL;
test_free (sub);
check_unref (msg, 1);
pull ();
/* about 1-in 100 calls will expunge */
j = g_random_int_range (0, 200);
if (j <= 2) {
push ("expunging folder");
camel_folder_expunge_sync (info->folder, NULL, &error);
check_msg (error == NULL, "%s", error->message);
pull ();
}
}
return info;
}
gint main (gint argc, gchar **argv)
{
CamelSession *session;
gint i, j, index;
gchar *path;
CamelStore *store;
CamelService *service;
GThread *threads[MAX_THREADS];
struct _threadinfo *info;
CamelFolder *folder;
GPtrArray *uids;
GError *error = NULL;
camel_test_init (argc, argv);
camel_test_provider_init (1, local_drivers);
/* clear out any camel-test data */
system ("/bin/rm -rf /tmp/camel-test");
session = camel_test_session_new ("/tmp/camel-test");
for (j = 0; j < G_N_ELEMENTS (local_providers); j++) {
for (index = 0; index < 2; index++) {
gchar *uid;
path = g_strdup_printf ("method %s %s", local_providers[j], index?"indexed":"nonindexed");
camel_test_start (path);
test_free (path);
push ("trying %s index %d", local_providers[j], index);
uid = g_strdup_printf ("test-uid-%d", j);
path = g_strdup_printf ("%s:///tmp/camel-test/%s", local_providers[j], local_providers[j]);
service = camel_session_add_service (
session, uid, path,
CAMEL_PROVIDER_STORE, &error);
g_free (uid);
check_msg (error == NULL, "%s", error->message);
check (CAMEL_IS_STORE (service));
store = CAMEL_STORE (service);
test_free (path);
if (index == 0)
folder = camel_store_get_folder_sync (
store, "testbox",
CAMEL_STORE_FOLDER_CREATE,
NULL, &error);
else
folder = camel_store_get_folder_sync (
store, "testbox",
CAMEL_STORE_FOLDER_CREATE |
CAMEL_STORE_FOLDER_BODY_INDEX,
NULL, &error);
check_msg (error == NULL, "%s", error->message);
g_clear_error (&error);
for (i = 0; i < MAX_THREADS; i++) {
GError *error = NULL;
info = g_malloc (sizeof (*info));
info->id = i * MAX_MESSAGES;
info->folder = folder;
threads[i] = g_thread_try_new (NULL, worker, info, &error);
check_msg (error == NULL, "g_thread_try_new() failed: %s", error->message);
}
for (i = 0; i < MAX_THREADS; i++) {
if (threads[i]) {
info = g_thread_join (threads[i]);
g_free (info);
}
}
pull ();
push ("deleting remaining messages");
uids = camel_folder_get_uids (folder);
for (i = 0; i < uids->len; i++) {
camel_folder_delete_message (folder, uids->pdata[i]);
}
camel_folder_free_uids (folder, uids);
camel_folder_expunge_sync (folder, NULL, &error);
check_msg (error == NULL, "%s", error->message);
check_unref (folder, 1);
camel_store_delete_folder_sync (
store, "testbox", NULL, &error);
check_msg (error == NULL, "%s", error->message);
g_clear_error (&error);
check_unref (store, 1);
pull ();
camel_test_end ();
}
}
g_object_unref (session);
return 0;
}