/* * libsyncml - A syncml protocol implementation * Copyright (C) 2005 Armin Bauer * Copyright (C) 2008-2009 Michael Bell * * 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; either * version 2.1 of the License, or (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "tests/support.h" #include #include #include #include #include #include #include #include #include typedef struct SmlSessionThread { GMainContext *context; GSourceFuncs *functions; GSourceFuncs *data_functions; GSource *data_source; GSource *session_source; SmlThread *thread; SmlSession *session; SmlTransportData **data; } SmlSessionThread; gint current_msg_id = 1; gint current_cmd_id = 1; gint data_received = 0; int start_commands_received = 0; int end_commands_received = 0; int finals_received = 0; int end_received = 0; int errors_received = 0; int numflushes = 0; int num_changes = 0; SmlTransportData *to_session = NULL; SmlTransportData *to_session2 = NULL; gint numreplies = 0; GMutex *mutex = NULL; char *item_data = NULL; unsigned int item_size = 0; unsigned int defaultMaxMsgSize = 10240; unsigned int defaultMaxObjSize = 1024000; void init_testbed() { current_msg_id = 1; current_cmd_id = 1; data_received = 0; start_commands_received = 0; end_commands_received = 0; finals_received = 0; end_received = 0; errors_received = 0; numflushes = 0; num_changes = 0; to_session = NULL; to_session2 = NULL; numreplies = 0; mutex = NULL; item_data = NULL; item_size = 0; // if (!g_thread_supported ()) g_thread_init (NULL); // g_type_init(); setup_testbed(NULL); } void cleanup_testbed() { if (to_session) { smlTransportDataDeref(to_session); to_session = NULL; } if (to_session2) { smlTransportDataDeref(to_session2); to_session2 = NULL; } } gboolean _session_prepare(GSource *source, gint *timeout_) { smlTrace(TRACE_INTERNAL, "%s(%p, %p)", __func__, source, timeout_); *timeout_ = 1; return FALSE; } gboolean _session_check(GSource *source) { SmlSession *session = *((SmlSession **)(source + 1)); return smlSessionCheck(session); } gboolean _session_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { smlTrace(TRACE_INTERNAL, "%s(%p, %p, %p)", __func__, source, callback, user_data); SmlSession *session = user_data; while (smlSessionCheck(session)) smlSessionDispatch(session); return TRUE; } gboolean _data_prepare(GSource *source, gint *timeout_) { smlTrace(TRACE_INTERNAL, "%s(%p, %p)", __func__, source, timeout_); *timeout_ = 1; return FALSE; } gboolean _data_check(GSource *source) { SmlSessionThread *thread = *((SmlSessionThread **)(source + 1)); smlAssert(thread != NULL); smlAssert(thread->data != NULL); if (*(thread->data)) return TRUE; return FALSE; } gboolean _data_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { smlTrace(TRACE_INTERNAL, "%s(%p. %p, %p)", __func__, source, callback, user_data); SmlSessionThread *check = user_data; GError *error = NULL; smlAssert(check != NULL); smlAssert(check->data != NULL); if (*(check->data)) { if (mutex) g_mutex_lock(mutex); SmlTransportData *data = *(check->data); *(check->data) = NULL; smlTrace(TRACE_ENTRY, "%s(data: %p, real %p, size %i)", __func__, data, data->data, data->size); SmlParser *parser = smlParserNew(data->type, 0, &error); smlAssert(parser != NULL); smlAssert(smlParserStart(parser, data->data, data->size, &error)); SmlHeader *header = NULL; SmlCred *cred = NULL; smlAssert(smlParserGetHeader(parser, &header, &cred, &error)); smlAssert(header != NULL); //smlAssert(header->messageID == current_msg_id); smlAssert(smlSessionReceiveHeader(check->session, header, &error)); smlHeaderFree(header); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, check->session->lastReceivedMessageID, check->session->source, check->session->target, SML_COMMAND_TYPE_HEADER, &error); smlAssert(smlSessionSendReply(check->session, reply, &error)); smlAssert(error == NULL); check->session->established = TRUE; smlStatusUnref(reply); g_atomic_int_inc(¤t_msg_id); smlAssert(smlSessionReceiveBody(check->session, parser, &error)); smlParserFree(parser); smlTransportDataDeref(data); *(check->data) = NULL; /* cleanup transport data reference */ if (mutex) g_mutex_unlock(mutex); smlTrace(TRACE_EXIT, "%s", __func__); } return TRUE; } SmlSessionThread *smlSessionRunAsync(SmlSession *session, SmlTransportData **input) { smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, session, input); GError *error = NULL; SmlSessionThread *thread = g_malloc0(sizeof(SmlSessionThread)); thread->context = g_main_context_new(); g_main_context_ref(thread->context); thread->functions = g_malloc0(sizeof(GSourceFuncs)); thread->functions->prepare = _session_prepare; thread->functions->check = _session_check; thread->functions->dispatch = _session_dispatch; thread->functions->finalize = NULL; thread->session_source = g_source_new(thread->functions, sizeof(GSource) + sizeof(SmlSession *)); SmlSession **sessionptr = (SmlSession **)(thread->session_source + 1); *sessionptr = session; g_source_set_callback(thread->session_source, NULL, session, NULL); g_source_attach(thread->session_source, thread->context); thread->data_functions = g_malloc0(sizeof(GSourceFuncs)); thread->data_functions->prepare = _data_prepare; thread->data_functions->check = _data_check; thread->data_functions->dispatch = _data_dispatch; thread->data_functions->finalize = NULL; thread->data = input; thread->session = session; thread->data_source = g_source_new(thread->data_functions, sizeof(GSource) + sizeof(SmlSession *)); SmlSessionThread **threadptr = (SmlSessionThread **)(thread->data_source + 1); *threadptr = thread; g_source_set_callback(thread->data_source, NULL, thread, NULL); g_source_attach(thread->data_source, thread->context); thread->thread = smlThreadNew(thread->context, &error); sml_fail_unless(thread->thread != NULL, NULL); smlThreadStart(thread->thread); smlTrace(TRACE_EXIT, "%s", __func__); return thread; } /** @brief Stops a asynchronously running transport * * @param tsp The transport * */ void smlSessionStop(SmlSessionThread *thread) { smlTrace(TRACE_ENTRY, "%s(%p)", __func__, thread); smlAssert(thread); smlThreadStop(thread->thread); smlThreadFree(thread->thread); g_source_destroy(thread->data_source); g_source_unref(thread->data_source); g_source_destroy(thread->session_source); g_source_unref(thread->session_source); g_free(thread->functions); g_free(thread->data_functions); g_main_context_unref(thread->context); g_main_context_unref(thread->context); g_free(thread); smlTrace(TRACE_EXIT, "%s", __func__); } /* If the notification is a normal SyncML message then a manager is * required. The easiest way are two function which create and destroy * a default manager - only for testing. */ SmlTransport *_tsp = NULL; SmlManager* _start_manager() { GError *error = NULL; _tsp = smlTransportNew(SML_TRANSPORT_HTTP_SERVER, &error); sml_fail_unless(_tsp != NULL, "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(error == NULL, "%s", GET_ERROR_MESSAGE(error)); SmlManager *manager = smlManagerNew(_tsp, &error); sml_fail_unless(manager != NULL, "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(error == NULL, "%s", GET_ERROR_MESSAGE(error)); smlManagerSetLocalMaxMsgSize(manager, defaultMaxMsgSize); smlManagerSetLocalMaxObjSize(manager, defaultMaxObjSize); return manager; } void _stop_manager(SmlManager *manager) { smlManagerFree(manager); smlTransportFree(_tsp); } START_TEST (session_new) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_location_set_uri(loc, "/test"); sml_fail_unless(loc != NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); sml_fail_unless(session != NULL, NULL); sml_fail_unless(error == NULL, NULL); smlSessionUnref(session); g_object_unref(loc); cleanup_testbed(); } END_TEST START_TEST (session_send) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, NULL, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); smlSessionUnref(session); g_object_unref(loc); cleanup_testbed(); } END_TEST static void _event_callback(SmlSession *session, SmlSessionEventType type, SmlCommand *command, SmlCommand *parent, SmlStatus *reply, const GError *error, void *userdata) { smlTrace(TRACE_ENTRY, "%s: %d (%p)", __func__, type, parent); smlAssert(GPOINTER_TO_INT(userdata) <= 5); GError *locerror = NULL; switch (type) { case SML_SESSION_EVENT_HEADER_REPLY: // FIXME: Why should the msgRef be the current_msg_id minus 2? // FIXME: This is wrong even if you count all messages // FIXME: because it depends on the SyncML role (server or client). // smlAssert(reply->msgRef == g_atomic_int_get(¤t_msg_id) - 2); smlAssert(reply->cmdRef == 0); g_atomic_int_inc(¤t_cmd_id); break; case SML_SESSION_EVENT_CHILD_COMMAND: case SML_SESSION_EVENT_COMMAND_START: g_atomic_int_inc(&start_commands_received); g_atomic_int_inc(&num_changes); g_atomic_int_inc(¤t_cmd_id); if (GPOINTER_TO_INT(userdata) == 3 && command->type == SML_COMMAND_TYPE_ADD) { smlAssert(smlCommandGetNumChanges(command)); SmlDataSyncChangeItem *item = smlCommandGetNthChange(command, 0); smlAssert(item); //smlAssert(smlItemCheck(item)); const char *data = sml_data_sync_change_item_get_data(item); smlAssert(strlen(data) == 8); smlAssert(!strncmp(data, "datadata", 8)); } if (GPOINTER_TO_INT(userdata) == 4 && command->type == SML_COMMAND_TYPE_ADD) { smlAssert(smlCommandGetNumChanges(command)); SmlDataSyncChangeItem *item = smlCommandGetNthChange(command, 0); smlAssert(item); //smlAssert(smlItemCheck(item)); const char *data = sml_data_sync_change_item_get_data(item); smlAssert(strlen(data) == 20); smlAssert(!strncmp(data, "datadatadatadatatest", 20)); } if (GPOINTER_TO_INT(userdata) == 5 && command->type == SML_COMMAND_TYPE_ADD) { smlAssert(smlCommandGetNumChanges(command)); SmlDataSyncChangeItem *item = smlCommandGetNthChange(command, 0); smlAssert(item); //smlAssert(smlItemCheck(item)); const char *data = sml_data_sync_change_item_get_data(item); if (strlen(data) != 4) { smlAssert(strlen(data) == item_size); smlAssert(!strncmp(data, item_data, item_size)); } else { smlAssert(strlen(data) == 4); smlAssert(!strncmp(data, "data", 4)); } } SmlStatus *status = smlCommandNewReply(command, SML_NO_ERROR, &locerror); smlAssert(status != NULL); smlAssert(locerror == NULL); smlAssert(smlSessionSendReply(session, status, &locerror)); smlAssert(locerror == NULL); smlStatusUnref(status); break; case SML_SESSION_EVENT_COMMAND_END: g_atomic_int_inc(&end_commands_received); break; case SML_SESSION_EVENT_FINAL: g_atomic_int_inc(&finals_received); current_cmd_id = 1; break; case SML_SESSION_EVENT_END: g_atomic_int_inc(&end_received); break; case SML_SESSION_EVENT_FLUSH: current_cmd_id = 1; g_atomic_int_inc(&numflushes); break; case SML_SESSION_EVENT_ERROR: smlAssert(error != NULL); if (GPOINTER_TO_INT(userdata) == 2) g_atomic_int_inc(&errors_received); else { sml_fail_unless(FALSE, "%s", GET_ERROR_MESSAGE(error)); abort(); } break; case SML_MANAGER_SESSION_ESTABLISHED: case SML_SESSION_EVENT_RESPONSE_URI: // not used here break; } smlTrace(TRACE_EXIT, "%s", __func__); } void _status_reply(SmlSession *session, SmlStatus *status, void *userdata) { smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata); smlAssert(session != NULL); smlAssert(status != NULL); //smlAssert(status->msgRef == current_msg_id - 1); if (GPOINTER_TO_INT(userdata) == 2) { smlAssert(smlStatusGetCode(status) >= 500); } else if (GPOINTER_TO_INT(userdata) == 1) { smlAssert(smlStatusGetClass(status) == SML_ERRORCLASS_SUCCESS); } else abort(); g_atomic_int_inc(¤t_cmd_id); g_atomic_int_inc(&numreplies); smlTrace(TRACE_EXIT, "%s", __func__); } void _status_reply_conc(SmlSession *session, SmlStatus *status, void *userdata) { smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata); smlAssert(session != NULL); smlAssert(status != NULL); smlAssert(smlStatusGetClass(status) == SML_ERRORCLASS_SUCCESS); g_atomic_int_inc(¤t_cmd_id); g_atomic_int_inc(&numreplies); smlTrace(TRACE_EXIT, "%s", __func__); } static void _data_send_callback(SmlSession *session, SmlTransportData *data, void *userdata) { smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, data, userdata); smlTrace(TRACE_INTERNAL, "%s: setting data(data: %p, real %p, size %i)", __func__, data, data->data, data->size); SmlTransportData **dataptr = userdata; if (*dataptr != NULL) smlTransportDataDeref(*dataptr); smlTransportDataRef(data); *dataptr = data; g_atomic_int_inc(&data_received); smlTrace(TRACE_EXIT, "%s", __func__); } START_TEST (session_flush) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, NULL, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session, FALSE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (data_received != 1) { usleep(100); } smlSessionStop(thread1); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_flush_final) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, NULL, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (data_received != 1) { usleep(100); } smlSessionStop(thread1); smlSessionUnref(session); cleanup_testbed(); } END_TEST /* Check that event callbacks are working */ START_TEST (session_recv) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.211/test/test1/test/testlastnext200"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST /* Check that a session can parse the output of another session */ START_TEST (session_transmit) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, NULL, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (data_received != 1) { usleep(100); } smlSessionStop(thread1); smlSessionUnref(session); session = NULL; SmlParser *parser = smlParserNew(to_session2->type, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, to_session2->data, to_session2->size, &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); g_object_unref(loc); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); sml_fail_unless(smlSessionReceiveHeader(session2, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session2->source, session2->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session2, reply, &error), NULL); smlStatusUnref(reply); session2->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session2, parser, &error), NULL); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); smlParserFree(parser); smlSessionUnref(session2); cleanup_testbed(); } END_TEST /* Check if statuses are working */ /* session --- Alert --> session2 * session2 --- Status ---> Session */ START_TEST (session_reply) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(data_received == 1, NULL); sml_fail_unless(numreplies == 0, NULL); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); /* do not test on final because this is a race condition */ while (end_received < 2) { usleep(100); } sml_fail_unless(data_received == 2, NULL); sml_fail_unless(numreplies == 1, NULL); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST /* Check if sessions can talk to each other * session2 must reply with a empty message since * it is a server * * session --- Alert --> session2 * session2 --- Status, Alert ---> session * session --- Status ---> session2 * session2 --- ---> session */ START_TEST (session_talk) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(data_received == 1, NULL); sml_fail_unless(numreplies == 0, NULL); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionSendCommand(session2, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 2) { usleep(100); } sml_fail_unless(data_received == 2, NULL); sml_fail_unless(numreplies == 1, NULL); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 4 || end_received != 2) { usleep(100); } sml_fail_unless(data_received == 4, NULL); sml_fail_unless(numreplies == 2, NULL); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 4, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST /* Check if sessions can talk to each other * session2 must reply with a empty message since * it is a server * * session --- num * Alert --> session2 * session2 --- num * Status, num * Alert ---> session * session --- num * Status ---> session2 * session2 --- ---> session */ START_TEST (session_talk_alot) { init_testbed(); int num_commands = 1000; GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); /* The test is not designed for splitted packages or objects. */ smlSessionSetLocalMaxMsgSize(session2, defaultMaxObjSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); int i = 0; for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(data_received == 1, NULL); sml_fail_unless(numreplies == 0, NULL); sml_fail_unless(start_commands_received == num_commands, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session2, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 2) { usleep(100); } sml_fail_unless(data_received == 2, NULL); sml_fail_unless(numreplies == num_commands, NULL); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, "%s", GET_ERROR_MESSAGE(error)); /*while (finals_received != 3) { usleep(100); } sml_fail_unless(data_received == 3, NULL); sml_fail_unless(numreplies == 2 * num_commands, NULL); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 3, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL);*/ while (finals_received != 4 || end_received != 2) { usleep(100); } sml_fail_unless(data_received == 4, NULL); sml_fail_unless(numreplies == 2 * num_commands, NULL); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 4, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST /* Check if sessions can talk to each other * session2 must reply with a empty message since * it is a server * * session --- num * Alert --> session2 * session2 --- num * Status, num * Alert ---> session * session --- num * Status ---> session2 * session2 --- ---> session */ START_TEST (session_talk_alot_limit) { init_testbed(); int num_commands = 1000; int limit = 20000; mutex = g_mutex_new(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetLocalMaxMsgSize(session2, limit); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetRemoteMaxMsgSize(session2, limit); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); int i = 0; for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(start_commands_received == num_commands, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session2, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 2) { usleep(100); } sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); /*while (finals_received != 3) { usleep(100); } sml_fail_unless(numreplies == 2 * num_commands, NULL); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 3, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL);*/ while (finals_received != 4 || end_received != 2) { usleep(100); } sml_fail_unless(numreplies == 2 * num_commands, NULL); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 4, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); g_mutex_free(mutex); cleanup_testbed(); } END_TEST /* Check if the session obeys remote message * limits. * * For this we setup a session with the remote limit set. The * expected behaviour is to see * - first the commands are added * - when the limit is reached, the data callback should be called * - more commands can be added * - as soon the session receives the reply from the remote side (a status in our case) * the session should call the data callback again * * Flushing while waiting for the remote reply should be ignored * * session -- x Alert (not final) --> session2 * session2 -- x Status (not final) --> session * session -- y Alert (final) --> session2 * session2 -- y Alert (final) --> session * */ START_TEST (session_limit_remote) { init_testbed(); int num_commands = 100; int limit = 5000; mutex = g_mutex_new(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); int i = 0; for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received < 1) { usleep(100); } sml_fail_unless(start_commands_received == num_commands, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); int flush_before = numflushes; for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session2, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received < 2) { usleep(100); } // fprintf(stderr, "numflushes: %i, flush_before: %i\n", numflushes, flush_before); sml_fail_unless(numflushes - flush_before > 5, "numflushes: %i, flush_before: %i", numflushes, flush_before); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 4 || end_received != 2) { usleep(100); } sml_fail_unless(numreplies == 2 * num_commands, NULL); sml_fail_unless(start_commands_received == 2 * num_commands, NULL); sml_fail_unless(finals_received == 4, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); g_mutex_free(mutex); cleanup_testbed(); } END_TEST START_TEST (session_split_child) { init_testbed(); int num_commands = 100; int limit = 5000; mutex = g_mutex_new(); setup_testbed(NULL); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetLocalMaxMsgSize(session2, limit); smlSessionSetRemoteMaxMsgSize(session2, limit); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlCommand *cmd1 = smlCommandNewSync(loc, loc, 0, &error); sml_fail_unless(cmd1 != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); SmlCommand *cmd2 = NULL; TEST_DATA_SYNC_CHANGE_ITEM_NEW(SML_CHANGE_ADD, "uid", "data", 5, SML_ELEMENT_TEXT_VCARD); cmd2 = smlCommandNewChange(TEST_DATA_SYNC_CHANGE_ITEM, &error); TEST_DATA_SYNC_CHANGE_ITEM_FREE(); sml_fail_unless(smlSessionStartCommand(session, cmd1, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); int i = 0; for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session, cmd2, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } sml_fail_unless(smlSessionEndCommand(session, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(start_commands_received == num_commands + 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionStartCommand(session2, cmd1, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); for (i = 0; i < num_commands; i++) { sml_fail_unless(smlSessionSendCommand(session2, cmd2, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); } sml_fail_unless(smlSessionEndCommand(session2, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd1); smlCommandUnref(cmd2); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 2) { usleep(100); } sml_fail_unless(start_commands_received == 2 * (num_commands + 1), NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); /*while (finals_received != 3) { usleep(100); } sml_fail_unless(numreplies == 2 * (num_commands + 1), NULL); sml_fail_unless(start_commands_received == 2 * (num_commands + 1), NULL); sml_fail_unless(finals_received == 3, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL);*/ while (finals_received != 4 || end_received != 2) { usleep(100); } sml_fail_unless(numreplies == 2 * (num_commands + 1), NULL); sml_fail_unless(start_commands_received == 2 * (num_commands + 1), NULL); sml_fail_unless(finals_received == 4, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); g_mutex_free(mutex); cleanup_testbed(); } END_TEST START_TEST (session_recv_large_obj) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard8uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(3)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; const char *input2 = "SyncML/1.11.121/vcards/vcards114Alert2002/vcards/vcards3text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 2, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), "%s", error?error->message:"No GError set."); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 3, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_recv_large_obj2) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard20uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(4)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; const char *input2 = "SyncML/1.11.121/vcards/vcards114Alert2002/vcards/vcards3text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 2, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; input2 = "SyncML/1.11.131/vcards/vcards128Alert2002/vcards/vcards3text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 3, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 3, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; input2 = "SyncML/1.11.141/vcards/vcards1312Alert2002/vcards/vcards3text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 4, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); smlSessionDispatch(session); smlSessionDispatch(session); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); smlSessionDispatch(session); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 5, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; /* libsyncml does not reset the CmdID during a session. * So the CmdID must be the total number of all send commands. */ input2 = "SyncML/1.11.151/vcards/vcards1416Alert200/vcards/vcards2/vcards/vcards3text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 5, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 7, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_recv_wrong_order) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard8uid3text/x-vcarduid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(2)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, "%d != 1", start_commands_received); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_large_obj_10) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.01.011/vcards/vcards1/vcards/vcards12text/x-vcard8uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_10, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(2)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); current_cmd_id = 1; input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard8uid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(2)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error == NULL, NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_large_obj_open) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard8uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_10, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(2)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); /* Even if MoreData and Final is impossible in the same message * then this is no reason why the received final should not be * signaled. If the syntax of the message is wrong then only * the syntax handler (ReceiveBody) should fail. Any other * stuff is undefinite. */ sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); g_object_unref(loc); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_large_obj_no_size) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcarduid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(2)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); g_object_unref(loc); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_large_obj_several_size) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard8uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(3)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; const char *input2 = "SyncML/1.11.121/vcards/vcards1/vcards/vcards2text/x-vcard8uid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_recv_large_wrong_size) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard9uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(3)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; const char *input2 = "SyncML/1.11.121/vcards/vcards1/vcards/vcards2text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_recv_large_wrong_size2) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); const char *input = "SyncML/1.11.111/vcards/vcards1/vcards/vcards12text/x-vcard7uid"; SmlParser *parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input, strlen(input), &error), NULL); SmlHeader *header = NULL; SmlCred *cred = NULL; sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); smlSessionSetLocalMaxMsgSize(session, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session, defaultMaxObjSize); g_object_unref(loc); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(3)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); SmlStatus *reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(smlSessionReceiveBody(session, parser, &error), NULL); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(to_session2 != NULL, NULL); smlTransportDataDeref(to_session2); to_session2 = NULL; const char *input2 = "SyncML/1.11.121/vcards/vcards1/vcards/vcards2text/x-vcarduid"; parser = smlParserNew(SML_MIMETYPE_XML, 0, &error); sml_fail_unless(parser != NULL, NULL); sml_fail_unless(smlParserStart(parser, input2, strlen(input2), &error), NULL); sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL); sml_fail_unless(header != NULL, NULL); sml_fail_unless(cred == NULL, NULL); sml_fail_unless(smlSessionReceiveHeader(session, header, &error), NULL); reply = smlStatusNew(SML_NO_ERROR, 0, 1, session->source, session->target, SML_COMMAND_TYPE_HEADER, &error); sml_fail_unless(smlSessionSendReply(session, reply, &error), NULL); smlStatusUnref(reply); session->established = TRUE; sml_fail_unless(!smlSessionReceiveBody(session, parser, &error), NULL); sml_fail_unless(error != NULL, NULL); SML_ERROR_FREE(error); smlParserFree(parser); smlHeaderFree(header); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 0, NULL); sml_fail_unless(end_received == 0, NULL); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_send_large_obj) { init_testbed(); int limit = 1000; int objlength = 600; GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); // smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetRemoteMaxObjSize(session, defaultMaxObjSize); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); SmlCommand *cmd1 = smlCommandNewSync(loc, loc, 0, &error); sml_fail_unless(cmd1 != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionStartCommand(session, cmd1, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); item_data = smlRandStr(objlength, TRUE); item_size = objlength; SmlCommand *cmd2 = NULL; TEST_DATA_SYNC_CHANGE_ITEM_NEW(SML_CHANGE_ADD, "uid", item_data, item_size, SML_ELEMENT_TEXT_VCARD); cmd2 = smlCommandNewChange(TEST_DATA_SYNC_CHANGE_ITEM, &error); TEST_DATA_SYNC_CHANGE_ITEM_FREE(); sml_fail_unless(smlSessionSendCommand(session, cmd2, cmd1, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionEndCommand(session, cmd1, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd1); smlCommandUnref(cmd2); sml_fail_unless(smlSessionEndCommand(session, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received < 1) { usleep(100); } /* The data is additionally set to test the size of the * resulting message. So the variable name data_received * is not fully correct. */ sml_fail_unless(data_received >= 3, NULL); sml_fail_unless(numreplies == 1, NULL); /* 3x sync (in each of the three messages) and 1x add (large obj) */ sml_fail_unless(start_commands_received == 4, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); g_free(item_data); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_send_large_obj2) { init_testbed(); int limit = 1000; int objlength = 4000; GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); SmlCommand *cmd1 = smlCommandNewSync(loc, loc, 0, &error); sml_fail_unless(cmd1 != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionStartCommand(session, cmd1, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); item_data = smlRandStr(objlength, TRUE); item_size = objlength; SmlCommand *cmd2 = NULL; TEST_DATA_SYNC_CHANGE_ITEM_NEW(SML_CHANGE_ADD, "uid", item_data, item_size, SML_ELEMENT_TEXT_VCARD); cmd2 = smlCommandNewChange(TEST_DATA_SYNC_CHANGE_ITEM, &error); TEST_DATA_SYNC_CHANGE_ITEM_FREE(); sml_fail_unless(smlSessionSendCommand(session, cmd2, cmd1, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionEndCommand(session, cmd1, &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd1); smlCommandUnref(cmd2); sml_fail_unless(smlSessionEndCommand(session, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); g_free(item_data); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_send_multi_large_obj) { init_testbed(); int limit = 1000; int objlength = 1500; int num_obj = 10; GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); SmlCommand *cmd1 = smlCommandNewSync(loc, loc, 0, &error); sml_fail_unless(cmd1 != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionStartCommand(session, cmd1, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); item_data = smlRandStr(objlength, TRUE); item_size = objlength; SmlCommand *cmd2 = NULL; int i = 0; for (i = 0; i < num_obj; i++) { TEST_DATA_SYNC_CHANGE_ITEM_NEW(SML_CHANGE_ADD, "uid", item_data, item_size, SML_ELEMENT_TEXT_VCARD); cmd2 = smlCommandNewChange(TEST_DATA_SYNC_CHANGE_ITEM, &error); TEST_DATA_SYNC_CHANGE_ITEM_FREE(); sml_fail_unless(smlSessionSendCommand(session, cmd2, cmd1, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd2); } smlCommandUnref(cmd1); sml_fail_unless(smlSessionEndCommand(session, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received < 1) { usleep(100); } sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); g_free(item_data); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_send_multi_large_obj_alter) { init_testbed(); int limit = 1000; int objlength = 1500; int num_obj = 5; GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(5)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); smlSessionSetLocalMaxMsgSize(session, limit); smlSessionSetRemoteMaxMsgSize(session, limit); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); SmlCommand *cmd1 = smlCommandNewSync(loc, loc, 0, &error); sml_fail_unless(cmd1 != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionStartCommand(session, cmd1, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); item_data = smlRandStr(objlength, TRUE); item_size = objlength; SmlCommand *cmd2 = NULL; int i = 0; for (i = 0; i < num_obj; i++) { TEST_DATA_SYNC_CHANGE_ITEM_NEW(SML_CHANGE_ADD, "uid", item_data, item_size, SML_ELEMENT_TEXT_VCARD); cmd2 = smlCommandNewChange(TEST_DATA_SYNC_CHANGE_ITEM, &error); TEST_DATA_SYNC_CHANGE_ITEM_FREE(); sml_fail_unless(smlSessionSendCommand(session, cmd2, cmd1, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd2); TEST_DATA_SYNC_CHANGE_ITEM_NEW(SML_CHANGE_ADD, "uid", "data", 4, SML_ELEMENT_TEXT_VCARD); cmd2 = smlCommandNewChange(TEST_DATA_SYNC_CHANGE_ITEM, &error); TEST_DATA_SYNC_CHANGE_ITEM_FREE(); sml_fail_unless(smlSessionSendCommand(session, cmd2, cmd1, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd2); } smlCommandUnref(cmd1); sml_fail_unless(smlSessionEndCommand(session, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received < 1) { usleep(100); } sml_fail_unless(num_changes = num_obj * 2, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); g_free(item_data); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); cleanup_testbed(); } END_TEST START_TEST (session_san) { init_testbed(); GError *error = NULL; SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "/test"); SmlSession *session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread1 = smlSessionRunAsync(session, &to_session); SmlSession *session2 = smlSessionNew(SML_SESSION_TYPE_SERVER, SML_MIMETYPE_XML, SML_VERSION_12, SML_PROTOCOL_SYNCML, loc, loc, 1, 0, &error); SmlSessionThread *thread2 = smlSessionRunAsync(session2, &to_session2); smlSessionSetLocalMaxMsgSize(session2, defaultMaxMsgSize); smlSessionSetLocalMaxObjSize(session2, defaultMaxObjSize); smlSessionSetEventCallback(session2, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session2, _data_send_callback, &to_session); smlSessionSetEventCallback(session, _event_callback, GINT_TO_POINTER(1)); smlSessionSetDataCallback(session, _data_send_callback, &to_session2); SmlNotification *san = smlNotificationNew(SML_SAN_VERSION_11, SML_SAN_UIMODE_USER, SML_SAN_INITIATOR_SERVER, 65535, "test", "/", SML_MIMETYPE_XML, &error); sml_fail_unless(san != NULL, "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(error == NULL, "%s", GET_ERROR_MESSAGE(error)); SmlManager *manager = _start_manager(); smlNotificationSetManager(san, manager); sml_fail_unless(smlNotificationNewAlert(san, SML_ALERT_TWO_WAY_BY_SERVER, SML_ELEMENT_TEXT_VCARD, "tttt", &error), NULL); sml_fail_unless(error == NULL, NULL); char *buffer = NULL; gsize size = 0; sml_fail_unless(smlNotificationAssemble(san, &buffer, &size, &error), NULL); sml_fail_unless(error == NULL, NULL); smlNotificationFree(san); to_session = smlTransportDataNew(buffer, size, SML_MIMETYPE_XML, TRUE, &error); sml_fail_unless(to_session != NULL, NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 1) { usleep(100); } sml_fail_unless(data_received == 0, NULL); sml_fail_unless(numreplies == 0, NULL); sml_fail_unless(start_commands_received == 1, NULL); sml_fail_unless(finals_received == 1, NULL); sml_fail_unless(end_received == 0, NULL); SmlCommand *cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY, loc, loc, "last", "next", NULL, &error); sml_fail_unless(cmd != NULL, NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlSessionSendCommand(session, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 2) { usleep(100); } sml_fail_unless(data_received == 1, NULL); sml_fail_unless(numreplies == 0, NULL); sml_fail_unless(start_commands_received == 2, NULL); sml_fail_unless(finals_received == 2, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionSendCommand(session2, cmd, NULL, _status_reply, GINT_TO_POINTER(1), &error), NULL); sml_fail_unless(error == NULL, NULL); smlCommandUnref(cmd); sml_fail_unless(smlSessionFlush(session2, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 3) { usleep(100); } sml_fail_unless(data_received == 2, NULL); sml_fail_unless(numreplies == 1, NULL); sml_fail_unless(start_commands_received == 3, NULL); sml_fail_unless(finals_received == 3, NULL); sml_fail_unless(end_received == 0, NULL); sml_fail_unless(smlSessionFlush(session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (finals_received != 5 || end_received != 2) { usleep(100); } sml_fail_unless(data_received == 4, NULL); sml_fail_unless(numreplies == 2, NULL); sml_fail_unless(start_commands_received == 3, NULL); sml_fail_unless(finals_received == 5, NULL); sml_fail_unless(end_received == 2, NULL); smlSessionStop(thread1); smlSessionStop(thread2); smlSessionUnref(session2); smlSessionUnref(session); _stop_manager(manager); cleanup_testbed(); } END_TEST @SML_TESTCASE_CODE@