/* * libsyncml - A syncml protocol implementation * Copyright (C) 2005 Armin Bauer * Copyright (C) 2008 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 "libsyncml/parser/sml_xml_parse.h" #include #include #include #define NUM_SESSIONS 30 typedef struct managerTracker { SmlManager *manager; SmlSession *session; } managerTracker; unsigned int transport_errors = 0; unsigned int num_sessions = 0; unsigned int num_finals = 0; unsigned int num_end = 0; unsigned int session_errors = 0; int num_disconnects = 0; unsigned int defaultMaxMsgSize = 10240; unsigned int defaultMaxObjSize = 1024000; static void _manager_event(SmlManager *manager, SmlManagerEventType type, SmlSession *session, const GError *error, void *userdata) { smlTrace(TRACE_ENTRY, "%s(%p, %i, %p, %p, %p)", __func__, manager, type, session, error, userdata); managerTracker *tracker = userdata; smlAssert(manager); smlAssert(userdata); switch (type) { case SML_MANAGER_SESSION_FLUSH: break; case SML_MANAGER_CONNECT_DONE: case SML_MANAGER_SESSION_ESTABLISHED: break; case SML_MANAGER_DISCONNECT_DONE: num_disconnects++; break; case SML_MANAGER_TRANSPORT_ERROR: transport_errors++; break; case SML_MANAGER_SESSION_NEW: smlAssert(session); tracker->session = session; num_sessions++; smlSessionRef(session); break; case SML_MANAGER_SESSION_FINAL: num_finals++; break; case SML_MANAGER_SESSION_END: num_end++; break; case SML_MANAGER_SESSION_ERROR: case SML_MANAGER_SESSION_WARNING: session_errors++; break; } smlTrace(TRACE_EXIT, "%s", __func__); } START_TEST (devinf_crash) { transport_errors = 0; num_sessions = 0; num_finals = 0; num_end = 0; num_disconnects = 0; session_errors = 0; setup_testbed(NULL); GError *error = NULL; GError *gerror = NULL; SmlTransport *server = smlTransportNew(SML_TRANSPORT_HTTP_SERVER, &error); SmlTransport *client = smlTransportNew(SML_TRANSPORT_HTTP_CLIENT, &error); sml_fail_unless(smlTransportSetConfigOption(client, "URL", "http://127.0.0.1:12030", &error), NULL); sml_fail_unless(smlTransportSetConfigOption(server, "PORT", "12030", &error), NULL); managerTracker *clienttracker = g_malloc0(sizeof(managerTracker)); SmlManager *clientmanager = clienttracker->manager = smlManagerNew(client, &error); smlManagerSetEventCallback(clienttracker->manager, _manager_event, clienttracker); managerTracker *servertracker = g_malloc0(sizeof(managerTracker)); SmlManager *servermanager = servertracker->manager = smlManagerNew(server, &error); smlManagerSetEventCallback(servertracker->manager, _manager_event, servertracker); smlManagerSetLocalMaxMsgSize(servermanager, defaultMaxMsgSize); smlManagerSetLocalMaxObjSize(servermanager, defaultMaxObjSize); sml_fail_unless(smlTransportInitialize(client, &error), "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(smlTransportInitialize(server, &error), "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(smlManagerStart(clientmanager, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlManagerStart(servermanager, &error), NULL); sml_fail_unless(error == NULL, NULL); SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "test"); /* The authenticator */ SmlAuthenticator *auth2 = smlAuthNew(&error); smlAuthSetEnable(auth2, FALSE); smlAuthRegister(auth2, servermanager, &error); /* The devinf obj for the server */ SmlDevInf *devinf = sml_dev_inf_new(); sml_fail_unless(devinf != NULL, NULL); sml_dev_inf_set_dev_typ(devinf, SML_DEVINF_DEVTYP_WORKSTATION); sml_fail_unless(sml_dev_inf_set_dev_id(devinf, "LibSyncML", &gerror), "%s", gerror?gerror->message:"No GError set."); sml_dev_inf_set_support_large_objs(devinf, TRUE); SmlDevInfAgent *agent = smlDevInfAgentNew(devinf, &error); smlDevInfAgentRegister(agent, servermanager, &error); /* And we also add the devinfo to the devinf agent */ SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new(sml_location_get_uri(loc), &gerror); _SET_DATASTORE_RX_PREF(SML_ELEMENT_TEXT_VCARD, "2.1"); _SET_DATASTORE_TX_PREF(SML_ELEMENT_TEXT_VCARD, "2.1"); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SERVER_ALERTED_SYNC, TRUE); sml_fail_unless(sml_dev_inf_add_data_store(devinf, datastore, &gerror), "%s", gerror?gerror->message:"No GError set."); g_object_unref(loc); const char *datastr = "1.1SyncML/1.1101PC SuiteIMEI:xxxxxxxxxxxxxxx10000110SyncHdr/PC Suite200211AlertContacts2003201./Contacts./C\\System\\Data\\Contacts.cdb20060317T083025Z4application/vnd.syncml-devinf+xml./devinf111.1NOKIA66802.04.15IMEI:xxxxxxxxxxxxxxxphone./C\\System\\Data\\Contacts.cdb8text/x-vcard2.1text/vcard3.0text/x-vcard2.11234567text/x-vcardBEGINVCARDENDVCARDVERSION2.1REVNADRHOMEWORKTELHOMEWORKCELLPAGERFAXVIDEOFNEMAILINTERNETHOMEWORKURLHOMEWORKNOTETITLEORGPHOTOBDAYSOUNDX-IRMC-Ntext/vcardBEGINVCARDENDVCARDVERSION3.0REVNADRHOMEWORKTELHOMEWORKCELLPAGERFAXVIDEOFNEMAILINTERNETHOMEWORKURLHOMEWORKNOTETITLEORGPHOTOBDAYSOUNDX-IRMC-N5application/vnd.syncml-devinf+xml./devinf11"; SmlTransportData *data = smlTransportDataNew((char *)datastr, strlen(datastr), SML_MIMETYPE_XML, FALSE, &error); sml_fail_unless(data != NULL, NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlTransportSend(client, NULL, data, &error), NULL); sml_fail_unless(error == NULL, NULL); smlTransportDataDeref(data); while (num_finals != 1) { smlManagerDispatch(servermanager); usleep(100); } SmlDevInf *devinf2 = smlDevInfAgentGetSessionDevInf(agent, servertracker->session); sml_fail_unless(devinf2 != NULL, NULL); sml_fail_unless(transport_errors == 0, NULL); sml_fail_unless(num_sessions == 1, NULL); sml_fail_unless(num_finals == 1, NULL); sml_fail_unless(num_end == 0, NULL); sml_fail_unless(session_errors == 1, NULL); /* stop the server */ smlManagerStop(servermanager); while(num_disconnects < 1) { smlManagerDispatch(servermanager); } smlManagerFree(servermanager); smlAuthFree(auth2); /* stop the client */ smlManagerStop(clientmanager); smlManagerFree(clientmanager); /* The clienttracker session was referenced by the manager callback. */ smlSessionUnref(servertracker->session); smlSafeFree((gpointer *)&clienttracker); smlSafeFree((gpointer *)&servertracker); sml_fail_unless(smlTransportFinalize(server, &error), "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(smlTransportFinalize(client, &error), "%s", GET_ERROR_MESSAGE(error)); smlTransportFree(server); smlTransportFree(client); smlDevInfAgentFree(agent); } END_TEST /* client -- devinf get --> server * server -- result --> client * client -- status --> server * server -- status --> client */ START_TEST (devinf_result) { transport_errors = 0; num_sessions = 0; num_finals = 0; num_end = 0; num_disconnects = 0; session_errors = 0; setup_testbed(NULL); GError *error = NULL; GError *gerror = NULL; SmlTransport *server = smlTransportNew(SML_TRANSPORT_HTTP_SERVER, &error); SmlTransport *client = smlTransportNew(SML_TRANSPORT_HTTP_CLIENT, &error); sml_fail_unless(smlTransportSetConfigOption(client, "URL", "http://127.0.0.1:12031", &error), NULL); sml_fail_unless(smlTransportSetConfigOption(server, "PORT", "12031", &error), NULL); managerTracker *clienttracker = g_malloc0(sizeof(managerTracker)); SmlManager *clientmanager = clienttracker->manager = smlManagerNew(client, &error); smlManagerSetEventCallback(clienttracker->manager, _manager_event, clienttracker); managerTracker *servertracker = g_malloc0(sizeof(managerTracker)); SmlManager *servermanager = servertracker->manager = smlManagerNew(server, &error); smlManagerSetEventCallback(servertracker->manager, _manager_event, servertracker); smlManagerSetLocalMaxMsgSize(servermanager, defaultMaxMsgSize); smlManagerSetLocalMaxObjSize(servermanager, defaultMaxObjSize); sml_fail_unless(smlTransportInitialize(client, &error), "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(smlTransportInitialize(server, &error), "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(smlManagerStart(clientmanager, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlManagerStart(servermanager, &error), NULL); sml_fail_unless(error == NULL, NULL); SmlLocation *loc = sml_location_new(); sml_fail_unless(loc != NULL, NULL); sml_location_set_uri(loc, "test"); SmlLocation *loc1 = sml_location_new(); sml_fail_unless(loc1 != NULL, NULL); sml_location_set_uri(loc1, "test"); /* The devinf obj */ SmlDevInf *devinf = sml_dev_inf_new(); sml_fail_unless(devinf != NULL, NULL); sml_dev_inf_set_dev_typ(devinf, SML_DEVINF_DEVTYP_WORKSTATION); sml_fail_unless(sml_dev_inf_set_dev_id(devinf, "LibSyncML", &gerror), "%s", gerror?gerror->message:"No GError set."); SmlDevInfAgent *clientagent = smlDevInfAgentNew(devinf, &error); smlDevInfAgentRegister(clientagent, clientmanager, &error); /* And we also add the devinfo to the devinf agent */ SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new(sml_location_get_uri(loc1), &gerror); _SET_DATASTORE_RX_PREF(SML_ELEMENT_TEXT_VCARD, "2.1"); _SET_DATASTORE_TX_PREF(SML_ELEMENT_TEXT_VCARD, "2.1"); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SERVER_ALERTED_SYNC, TRUE); sml_fail_unless(sml_dev_inf_add_data_store(devinf, datastore, &gerror), "%s", gerror?gerror->message:"No GError set."); devinf = sml_dev_inf_new(); sml_fail_unless(devinf != NULL, NULL); sml_dev_inf_set_dev_typ(devinf, SML_DEVINF_DEVTYP_SERVER); sml_fail_unless(sml_dev_inf_set_dev_id(devinf, "LibSyncML", &gerror), "%s", gerror?gerror->message:"No GError set."); sml_dev_inf_set_support_large_objs(devinf, TRUE); SmlDevInfAgent *serveragent = smlDevInfAgentNew(devinf, &error); smlDevInfAgentRegister(serveragent, servermanager, &error); datastore = sml_dev_inf_data_store_new(sml_location_get_uri(loc1), &gerror); _SET_DATASTORE_RX_PREF(SML_ELEMENT_TEXT_VCARD, "2.1"); _SET_DATASTORE_TX_PREF(SML_ELEMENT_TEXT_VCARD, "2.1"); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SERVER_ALERTED_SYNC, TRUE); sml_fail_unless(sml_dev_inf_add_data_store(devinf, datastore, &gerror), "%s", gerror?gerror->message:"No GError set."); g_object_unref(loc1); /* The authenticator */ SmlAuthenticator *auth = smlAuthNew(&error); smlAuthSetEnable(auth, FALSE); smlAuthRegister(auth, clientmanager, &error); /* The authenticator */ SmlAuthenticator *auth2 = smlAuthNew(&error); smlAuthSetEnable(auth2, FALSE); smlAuthRegister(auth2, servermanager, &error); clienttracker->session = smlSessionNew(SML_SESSION_TYPE_CLIENT, SML_MIMETYPE_XML, SML_VERSION_11, SML_PROTOCOL_SYNCML, loc, loc, 0, 0, &error); sml_fail_unless(smlManagerSessionAdd(clientmanager, clienttracker->session, NULL, &error), NULL); sml_fail_unless(error == NULL, NULL); g_object_unref(loc); sml_fail_unless(smlDevInfAgentRequestDevInf(clientagent, clienttracker->session, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlDevInfAgentSendDevInf(clientagent, clienttracker->session, &error), NULL); sml_fail_unless(error == NULL, NULL); sml_fail_unless(smlSessionFlush(clienttracker->session, TRUE, &error), NULL); sml_fail_unless(error == NULL, NULL); while (num_sessions != 2 || !smlDevInfAgentGetSessionDevInf(serveragent, servertracker->session)) { smlManagerDispatch(servermanager); smlManagerDispatch(clientmanager); usleep(100); } SmlDevInf *recvClientDevInf = smlDevInfAgentGetSessionDevInf(serveragent, servertracker->session); sml_fail_unless(recvClientDevInf != NULL, NULL); sml_fail_unless(sml_dev_inf_num_data_stores(recvClientDevInf) == 1, NULL); sml_fail_unless(servertracker->session != NULL, NULL); sml_fail_unless(smlSessionFlush(servertracker->session, TRUE, &error), NULL); while (!smlDevInfAgentGetSessionDevInf(clientagent, clienttracker->session)) { smlManagerDispatch(servermanager); smlManagerDispatch(clientmanager); usleep(100); } SmlDevInf *recvServerDevInf = smlDevInfAgentGetSessionDevInf(clientagent, clienttracker->session); sml_fail_unless(recvServerDevInf != NULL, NULL); sml_fail_unless(sml_dev_inf_num_data_stores(recvServerDevInf) == 1, NULL); sml_fail_unless(servertracker->session != NULL, NULL); sml_fail_unless(smlSessionEnd(clienttracker->session, &error), NULL); sml_fail_unless(error == NULL, NULL); while (num_end != 2 || num_finals != 4) { smlManagerDispatch(servermanager); smlManagerDispatch(clientmanager); usleep(100); } /* The tracker sessions were referenced by the manager callback. * The clienttracker session is referenced twice because it * was created by the testcase itself. */ smlSessionUnref(servertracker->session); smlSessionUnref(clienttracker->session); smlSessionUnref(clienttracker->session); sml_fail_unless(num_sessions == 2, NULL); sml_fail_unless(num_finals == 4, NULL); sml_fail_unless(num_end == 2, NULL); sml_fail_unless(session_errors == 0, NULL); smlAuthFree(auth); smlAuthFree(auth2); smlSafeFree((gpointer *)&clienttracker); smlSafeFree((gpointer *)&servertracker); smlManagerStop(clientmanager); smlManagerStop(servermanager); while(num_disconnects < 2) { smlManagerDispatch(clientmanager); smlManagerDispatch(servermanager); } smlManagerFree(clientmanager); smlManagerFree(servermanager); sml_fail_unless(smlTransportFinalize(server, &error), "%s", GET_ERROR_MESSAGE(error)); sml_fail_unless(smlTransportFinalize(client, &error), "%s", GET_ERROR_MESSAGE(error)); smlTransportFree(server); smlTransportFree(client); smlDevInfAgentFree(clientagent); smlDevInfAgentFree(serveragent); } END_TEST @SML_TESTCASE_CODE@