/* * libsyncml - A syncml protocol implementation * Copyright (C) 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 #include "tests/support.h" #include #include #include #include GMutex *runMutex = NULL; int locks; GList *clients; typedef struct SmlDataSyncTestClient { GList *items; SmlDataSync *client; SmlDataSyncDataStore *data_store; gboolean is_binary; } SmlDataSyncTestClient; SmlDataSync *server; SmlDataSyncDataStore *server_data_store; const char *transport; /* ************************************ */ /* *********** CALLBACKS ************** */ /* ************************************ */ SmlDataSyncTestClient* getTestClientFromDataSyncSession(SmlDataSyncSession *session) { /* This is a hack because of the behaviour of the OBEX server. */ smlTrace(TRACE_INTERNAL, "%s: session(server->remote) ::= %p", __func__, sml_data_sync_session_get_remote(session)); smlTrace(TRACE_INTERNAL, "%s: session(server->remote) ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_session_get_remote(session))); smlTrace(TRACE_INTERNAL, "%s: session(server->local) ::= %p", __func__, sml_data_sync_session_get_local(session)); smlTrace(TRACE_INTERNAL, "%s: session(server->local) ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_session_get_local(session))); GList *list = clients; SmlDataSyncTestClient *client = NULL; for (;list; list = list->next) { client = list->data; smlTrace(TRACE_INTERNAL, "%s: client(local) ::= %p", __func__, sml_data_sync_get_local(client->client)); smlTrace(TRACE_INTERNAL, "%s: client(local) ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_get_local(client->client))); smlTrace(TRACE_INTERNAL, "%s: client(remote) ::= %p", __func__, sml_data_sync_get_remote(client->client)); smlTrace(TRACE_INTERNAL, "%s: client(remote) ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_get_remote(client->client))); if (sml_location_is_equal(sml_data_sync_get_local(client->client), sml_data_sync_session_get_remote(session))) { /* correct client */ smlTrace(TRACE_INTERNAL, "%s - correct client", __func__); break; } else { /* wrong client */ client = NULL; } } sml_fail_unless(client != NULL, "Cannot find correct client."); return client; } gboolean sendAllChanges (SmlDataSyncSession *session, SmlDataSyncTestClient *client, GError **error) { smlTrace(TRACE_ENTRY, "%s (%p, %p, %p)", __func__, session, client, error); gboolean is_server = client ? FALSE : TRUE; SmlDataSyncDataStoreSession *dss = NULL; if (!is_server) dss = sml_data_sync_session_get_data_store_session(session, client->data_store, error); else dss = sml_data_sync_session_get_data_store_session(session, server_data_store, error); sml_fail_unless(dss != NULL, "%s", GET_ERROR_MESSAGE((*error))); if (is_server) { /* determine the remote client */ client = getTestClientFromDataSyncSession(session); } GList *list = client->items; size_t count = 0; for (;list;list = list->next) { count++; char *name = NULL; if (is_server) name = g_strdup_printf("%d from server", count); else name = g_strdup_printf("%d", count); SmlLocation *loc = sml_location_new(); sml_location_set_uri(loc, name); smlSafeCFree(&name); SmlDataSyncChangeItem *item = sml_data_sync_change_item_new(); sml_data_sync_change_item_set_action(item, SML_CHANGE_ADD); if (client->is_binary) { sml_fail_unless(sml_data_sync_change_item_set_binary_data(item, list->data, strlen(list->data), error), "%s", GET_ERROR_MESSAGE((*error))); } else { sml_fail_unless(sml_data_sync_change_item_set_data(item, list->data, 0, error), "%s", GET_ERROR_MESSAGE((*error))); } sml_fail_unless(sml_data_sync_change_item_set_location(item, loc, error), "%s", GET_ERROR_MESSAGE((*error))); g_object_unref(loc); loc = NULL; sml_fail_unless(sml_data_sync_data_store_session_add_change(dss, item, NULL, error), "%s", GET_ERROR_MESSAGE((*error))); } gboolean result = sml_data_sync_session_send_changes(session, error); smlTrace(TRACE_EXIT, "%s - %d", __func__); return result; } static void recvEventCallback (SmlDataSyncSession *session, SmlDataSync *dsObject, SmlDataSyncEventType type, void *userdata, const GError *error) { smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p)", __func__, session, dsObject, type, userdata, error); GError *locerror = NULL; SmlDataSyncTestClient *client = NULL; if (userdata) client = userdata; switch (type) { case SML_DATA_SYNC_SESSION_EVENT_ERROR: if (client) { sml_fail_unless(FALSE, "OMA DS client failed: %s", error->message); } else { sml_fail_unless(FALSE, "OMA DS server failed: %s", error->message); } break; case SML_DATA_SYNC_SESSION_EVENT_CONNECT: /* g_message("Remote device was successfully connected."); */ break; case SML_DATA_SYNC_SESSION_EVENT_DISCONNECT: /* g_message("Remote device was successfully disconnected."); */ break; case SML_DATA_SYNC_SESSION_EVENT_FINISHED: /* g_message("SyncML session finished successfully."); */ if (g_atomic_int_dec_and_test(&locks)) g_mutex_unlock(runMutex); break; case SML_DATA_SYNC_SESSION_EVENT_GOT_ALL_ALERTS: /* g_message("All alerts of the remote device were received."); */ if (client) { if (!sendAllChanges(session, client, &locerror)) goto error; } break; case SML_DATA_SYNC_SESSION_EVENT_GOT_ALL_CHANGES: /* g_message("All changes of the remote device were received."); */ if (!client) { if (!sendAllChanges(session, NULL, &locerror)) goto error; } /* the map of the client is send automatically */ break; case SML_DATA_SYNC_SESSION_EVENT_GOT_ALL_MAPPINGS: if (dsObject == server) { /* g_message("All mappings of the remote device were received."); */ } else { g_error("Received a map but I'm a client!"); } break; default: g_error("Unknown event(%d).\n", type); break; } smlTrace(TRACE_EXIT, "%s", __func__); return; error: fprintf(stderr, "An error occured while handling events: %s\n", locerror->message); smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, locerror->message); g_error_free(locerror); exit(3); } static gboolean serverRecvChangeCallback (SmlDataSyncDataStoreSession *session, SmlDataSyncChangeItem *item, void *userdata, GError **error) { smlTrace(TRACE_ENTRY, "%s: (%p, %p, %p, %p)", __func__, session, item, userdata, error); /* determine the relevant data sync objects */ SmlDataSyncDataStore *datastore = sml_data_sync_data_store_session_get_data_store(session); SmlDataSyncSession *dss = sml_data_sync_data_store_session_get_data_sync_session(session); SmlDataSync *dsObject = sml_data_sync_session_get_data_sync(dss); /* check the source */ if (dsObject != server || datastore != server_data_store) { sml_fail_unless(FALSE, "This is the server callback."); } /* determine client */ SmlDataSyncTestClient *client = getTestClientFromDataSyncSession(dss); /* handle the item */ GList *list = client->items; size_t count = 0; for (; list; list = list->next) { count++; /* test the uid */ const gchar *uid = sml_location_get_full_uri(sml_data_sync_change_item_get_location(item)); char *name = g_strdup_printf("%d", count); if (strcmp(name, uid)) { smlSafeCFree(&name); continue; } smlSafeCFree(&name); /* item with correct uid */ const gchar *data = sml_data_sync_change_item_get_data(item); if (client->is_binary) { /* this is a base64 encoded item */ if (!strcmp(list->data, data)) { sml_fail_unless(FALSE, "The binary item was not base64 encoded.", uid, data, list->data); } gchar *binary = NULL; gsize size = 0; sml_fail_unless(sml_data_sync_change_item_get_binary_data(item, &binary, &size, error), "%s", GET_ERROR_MESSAGE((*error))); sml_fail_unless(strlen(list->data) == size, "The length of the decoded item is wrong."); sml_fail_unless(strcmp(list->data, binary) == 0, "The data of the decoded item is wrong."); smlSafeCFree(&binary); } else { /* this is a plain text item */ if (strcmp(list->data, data)) { sml_fail_unless(FALSE, "The data of the item %s was wrong(%s != %s).", uid, data, list->data); } } } smlTrace(TRACE_EXIT, "%s - TRUE", __func__); return TRUE; } static gboolean clientRecvChangeCallback (SmlDataSyncDataStoreSession *session, SmlDataSyncChangeItem *item, void *userdata, GError **error) { smlTrace(TRACE_ENTRY, "%s: (%p, %p, %p, %p)", __func__, session, item, userdata, error); /* determine the relevant data sync objects */ SmlDataSyncDataStore *datastore = sml_data_sync_data_store_session_get_data_store(session); SmlDataSyncSession *dss = sml_data_sync_data_store_session_get_data_sync_session(session); SmlDataSync *dsObject = sml_data_sync_session_get_data_sync(dss); /* check the source */ if (dsObject == server || datastore == server_data_store) { sml_fail_unless(FALSE, "This is the client callback."); } /* document remote and local locations */ smlTrace(TRACE_INTERNAL, "%s: server->remote ::= %p", __func__, sml_data_sync_get_remote(server)); if (sml_data_sync_get_remote(server)) smlTrace(TRACE_INTERNAL, "%s: server->remote ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_get_remote(server))); smlTrace(TRACE_INTERNAL, "%s: server->local ::= %p", __func__, sml_data_sync_get_local(server)); smlTrace(TRACE_INTERNAL, "%s: server->local ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_get_local(server))); smlTrace(TRACE_INTERNAL, "%s: client session(local) ::= %p", __func__, sml_data_sync_session_get_local(dss)); smlTrace(TRACE_INTERNAL, "%s: client session(local) ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_session_get_local(dss))); smlTrace(TRACE_INTERNAL, "%s: client session(remote) ::= %p", __func__, sml_data_sync_session_get_remote(dss)); smlTrace(TRACE_INTERNAL, "%s: client session(remote) ::= %s", __func__, sml_location_get_full_uri(sml_data_sync_session_get_remote(dss))); /* create a mapping per add item */ SmlLocation* remote = sml_data_sync_change_item_get_location(item); SmlLocation* local = sml_location_clone(remote); gchar *local_uri = g_strdup_printf("%s => mapped ID", sml_location_get_uri(remote)); sml_location_set_uri(local, local_uri); smlSafeCFree(&local_uri); SmlMapItem *map = sml_map_item_new(); sml_fail_unless(sml_map_item_set_remote(map, remote, error), "%s", GET_ERROR_MESSAGE((*error))); sml_fail_unless(sml_map_item_set_local(map, local, error), "%s", GET_ERROR_MESSAGE((*error))); sml_fail_unless(sml_map_item_is_compliant(map, error), "%s", GET_ERROR_MESSAGE((*error))); g_object_unref(local); local = NULL; /* add the mapping to the session */ sml_fail_unless(sml_data_sync_data_store_session_add_mapping(session, map, NULL, error), "%s", GET_ERROR_MESSAGE((*error))); smlTrace(TRACE_EXIT, "%s - TRUE", __func__); return TRUE; } static gboolean serverRecvMappingCallback (SmlDataSyncDataStoreSession *session, SmlMapItem *item, void *userdata, GError **error) { smlTrace(TRACE_ENTRY, "%s: (%p, %p, %p, %p)", __func__, session, item, userdata, error); /* determine the relevant data sync objects */ SmlDataSyncDataStore *datastore = sml_data_sync_data_store_session_get_data_store(session); SmlDataSyncSession *dss = sml_data_sync_data_store_session_get_data_sync_session(session); SmlDataSync *dsObject = sml_data_sync_session_get_data_sync(dss); /* check the source */ if (dsObject != server || datastore != server_data_store) { sml_fail_unless(FALSE, "This is the server callback."); } /* determine client */ SmlDataSyncTestClient *client = getTestClientFromDataSyncSession(dss); /* handle the item */ GList *list = client->items; size_t count = 0; for (; list; list = list->next) { count++; /* test the uid */ const gchar *uid = sml_map_item_get_remote_uri(item); char *name = g_strdup_printf("%d from server", count); if (strcmp(name, uid)) { smlSafeCFree(&name); continue; } smlSafeCFree(&name); /* item with correct uid */ const gchar *mapped = sml_map_item_get_local_uri(item); name = g_strdup_printf("%d from server => mapped ID", count); if (strcmp(name, mapped)) { sml_fail_unless(FALSE, "The mapped ID of the item %s was wrong(%s != %s).", uid, name, mapped); } smlSafeCFree(&name); } smlTrace(TRACE_EXIT, "%s - TRUE", __func__); return TRUE; } //static SmlAlertType recvAlertTypeCallback( // SmlDataSyncObject *dsObject, // const char *source, // SmlAlertType type, // void *userdata, // GError **error) //{ // smlTrace(TRACE_ENTRY, "%s - %s: %d", __func__, VA_STRING(source), type); // /* find the appropriate datasoure */ // SmlDsToolLocationType *datastore = NULL; // GList *o = datastores; // while (o) { // datastore = o->data; // if (!strcmp(datastore->source, source)) { // /* abort the scan */ // o = NULL; // } else { // datastore = NULL; // } // if (o) o = o->next; // } // if (!datastore) { // SML_SET_ERROR(error, SML_ERROR_GENERIC, // "Cannot found datastore %s.", // source); // goto error; // } // smlTrace(TRACE_INTERNAL, "%s: datastores scanned", __func__); // // /* synchronize the alert type */ // if (type == SML_ALERT_SLOW_SYNC) // datastore->slow = TRUE; // if (datastore->slow) // type = SML_ALERT_SLOW_SYNC; // // smlTrace(TRACE_EXIT, "%s - slow == %d", __func__, datastore->slow); // return type; //error: // smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, (*error)->message); // return SML_ALERT_UNKNOWN; //} void init_testbed(unsigned int peers, const char *transport_type, const char *port) { /* general init */ setup_testbed(NULL); GError *error = NULL; clients = NULL; server = NULL; server_data_store = NULL; /* initialize clients */ unsigned int i = 0; for (;i < peers; i++) { SmlDataSyncTestClient *client = smlTryMalloc0(sizeof(SmlDataSyncTestClient), &error); if (!client) goto error; clients = g_list_append(clients, client); } #ifdef ENABLE_OPENOBEX_TCP transport = "OBEX"; #endif #ifdef ENABLE_HTTP transport = "HTTP"; #endif #ifdef ENABLE_OPENOBEX_TCP if (!strcasecmp(transport_type, "OBEX")) { transport = "OBEX"; } #endif #ifdef ENABLE_HTTP if (!strcasecmp(transport_type, "HTTP")) { transport = "HTTP"; } #endif if (!strcmp(transport, "HTTP")) { GList *list = clients; for (; list; list = list->next) { SmlDataSyncTestClient *client = list->data; client->client = sml_data_sync_new(); if (!sml_data_sync_set_session_type(client->client, SML_SESSION_TYPE_CLIENT, &error)) goto error; if (!sml_data_sync_set_transport_type(client->client, SML_TRANSPORT_HTTP_CLIENT, &error)) goto error; } server = sml_data_sync_new(); if (!sml_data_sync_set_session_type(server, SML_SESSION_TYPE_SERVER, &error)) goto error; if (!sml_data_sync_set_transport_type(server, SML_TRANSPORT_HTTP_SERVER, &error)) goto error; } else { /* OBEX */ GList *list = clients; for (; list; list = list->next) { SmlDataSyncTestClient *client = list->data; client->client = sml_data_sync_new(); if (!sml_data_sync_set_session_type(client->client, SML_SESSION_TYPE_CLIENT, &error)) goto error; if (!sml_data_sync_set_transport_type(client->client, SML_TRANSPORT_OBEX_SERVER, &error)) goto error; } server = sml_data_sync_new(); if (!sml_data_sync_set_session_type(server, SML_SESSION_TYPE_SERVER, &error)) goto error; if (!sml_data_sync_set_transport_type(server, SML_TRANSPORT_OBEX_CLIENT, &error)) goto error; } /* client configuration */ GList *list = clients; unsigned int count = 0; for (; list; list = list->next) { count++; SmlDataSyncTestClient *client = list->data; /* set identifier for test verification */ gchar *name = g_strdup_printf("client %d", count); if (!sml_data_sync_set_option (client->client, SML_DATA_SYNC_CONFIG_IDENTIFIER, name, &error)) goto error; if (!sml_data_sync_set_option (client->client, SML_DATA_SYNC_CONFIG_TARGET, "account", &error)) goto error; smlSafeCFree(&name); /* default configuration of callbacks */ sml_data_sync_register_event_callback(client->client, recvEventCallback, client); /* configure transport */ if (!strcmp(transport, "HTTP")) { /* HTTP */ char *url = g_strdup_printf("http://127.0.0.1:%s", port); if (!sml_data_sync_set_option( client->client, SML_TRANSPORT_CONFIG_URL, url, &error)) goto error; smlSafeCFree(&url); } else { /* OBEX */ if (!sml_data_sync_set_option( client->client, SML_DATA_SYNC_CONFIG_CONNECTION_TYPE, SML_DATA_SYNC_CONFIG_CONNECTION_NET, &error)) goto error; if (!sml_data_sync_set_option( client->client, SML_TRANSPORT_CONFIG_PORT, port, &error)) goto error; } } /* server configuration */ /* default configuration of callbacks */ sml_data_sync_register_event_callback(server, recvEventCallback, NULL); /* configure transport */ if (strcmp(transport, "HTTP")) { /* OBEX */ if (!sml_data_sync_set_option( server, SML_DATA_SYNC_CONFIG_CONNECTION_TYPE, SML_DATA_SYNC_CONFIG_CONNECTION_NET, &error)) goto error; if (!sml_data_sync_set_option( server, SML_TRANSPORT_CONFIG_URL, "127.0.0.1", &error)) goto error; } if (!sml_data_sync_set_option( server, SML_TRANSPORT_CONFIG_PORT, port, &error)) goto error; return; error: sml_fail_unless(FALSE, "%s", error->message); } void test_ds_api_cleanup_server () { g_object_unref(server); server = NULL; g_object_unref(server_data_store); server_data_store = NULL; } void test_ds_api_cleanup_client () { while (clients) { SmlDataSyncTestClient *client = clients->data; clients = g_list_remove(clients, client); g_object_unref(client->client); g_object_unref(client->data_store); while(client->items) { gchar* item = client->items->data; client->items = g_list_remove(client->items, item); smlSafeCFree(&item); } smlSafeFree((gpointer *)&client); } } void run_testbed() { GError *error = NULL; locks = 2*g_list_length(clients); runMutex = g_mutex_new(); g_mutex_lock(runMutex); /* init the sync */ if (!strcmp(transport, "HTTP")) { if (!sml_data_sync_initialize(server, &error)) goto error; GList *list = clients; for (; list; list = list->next) { SmlDataSyncTestClient *client = list->data; if (!sml_data_sync_initialize(client->client, &error)) goto error; } if (!sml_data_sync_run(server, &error)) goto error; list = clients; for (; list; list = list->next) { SmlDataSyncTestClient *client = list->data; if (!sml_data_sync_run(client->client, &error)) goto error; /* It is necessary to perform the first request alone * because otherwise the test can fail on Solaris * because Solaris uses an outdated libsoup 2.2. */ if (list == clients) { /* first client => wait for Soup Session init */ usleep(5000); } } } else { /* OBEX */ GList *list = clients; for (; list; list = list->next) { SmlDataSyncTestClient *client = list->data; if (!sml_data_sync_initialize(client->client, &error)) goto error; } if (!sml_data_sync_initialize(server, &error)) goto error; list = clients; for (; list; list = list->next) { SmlDataSyncTestClient *client = list->data; if (!sml_data_sync_run(client->client, &error)) goto error; } /* The OBEX server needs some time to start. */ if (g_getenv("SYNCML_TRACE")) usleep(2000); else usleep(5000); if (!sml_data_sync_run(server, &error)) goto error; } g_mutex_lock(runMutex); g_mutex_unlock(runMutex); g_mutex_free(runMutex); runMutex = NULL; /* close the object */ smlTrace(TRACE_INTERNAL, "%s: shutting down all SmlDataSync objects", __func__); if (sml_data_sync_get_transport_type(server) == SML_TRANSPORT_OBEX_CLIENT) { test_ds_api_cleanup_server(); test_ds_api_cleanup_client(); } else { test_ds_api_cleanup_client(); test_ds_api_cleanup_server(); } return; error: if (runMutex) { g_mutex_trylock(runMutex); g_mutex_unlock(runMutex); g_mutex_free(runMutex); runMutex = NULL; } sml_fail_unless(FALSE, "%s", error->message); } START_TEST (ds_api_single_client_single_text_vcard_21) { GError *error = NULL; init_testbed(1, "HTTP", "17001"); /* register datastore * the source must be identical because this is http */ SmlDataSyncTestClient *client = clients->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (client->data_store, "contacts"); sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, client); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (server_data_store, "contacts"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; /* configure test data */ client->items = g_list_append(client->items, g_strdup("blabla")); run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } END_TEST START_TEST (ds_api_single_client_single_image_jpeg) { GError *error = NULL; init_testbed(1, "OBEX", "17002"); /* register datastore * the source must be identical if this is http */ SmlDataSyncTestClient *client = clients->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "image/jpeg"); sml_data_sync_data_store_set_local_uri (client->data_store, "dcim"); client->is_binary = TRUE; sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, NULL); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "image/jpeg"); if (!strcmp(transport, "OBEX")) sml_data_sync_data_store_set_local_uri (server_data_store, "photos"); else sml_data_sync_data_store_set_local_uri (server_data_store, "dcim"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; /* configure test data */ client->items = g_list_append(client->items, g_strdup("this is an image")); run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } END_TEST START_TEST (ds_api_single_client_single_unknown_ct) { GError *error = NULL; init_testbed(1, "HTTP", "17003"); /* register datastore * the source must be identical because this is http */ SmlDataSyncTestClient *client = clients->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "unknown/content-type"); sml_data_sync_data_store_set_local_uri (client->data_store, "data"); sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, NULL); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "unknown/content-type"); sml_data_sync_data_store_set_local_uri (server_data_store, "data"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; /* configure test data */ client->items = g_list_append(client->items, g_strdup("this is some data")); run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } END_TEST START_TEST (ds_api_single_client_multi_text_vcard_21) { GError *error = NULL; init_testbed(1, "HTTP", "17004"); /* register datastore * the source must be identical because this is http */ SmlDataSyncTestClient *client = clients->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (client->data_store, "contacts"); sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, NULL); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (server_data_store, "contacts"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; /* configure test data */ int max_items = 1000; int i; for(i = 0; i < max_items; i++) { client->items = g_list_append(client->items, g_strdup_printf("client 1 data %d", (i+1))); } run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } END_TEST START_TEST (ds_api_multi_client_single_text_vcard_21) { GError *error = NULL; init_testbed(5, "HTTP", "17005"); /* register datastore * the source must be identical because this is http */ SmlDataSyncTestClient *client = NULL; GList *list = clients; unsigned int count = 0; for (;list; list = list->next) { count ++; client = list->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (client->data_store, "contacts"); sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, client); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; /* configure test data */ client->items = g_list_append(client->items, g_strdup_printf("client %d data 1", count)); } server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (server_data_store, "contacts"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } END_TEST START_TEST (ds_api_multi_client_multi_text_vcard_21) { GError *error = NULL; init_testbed(10, "HTTP", "17006"); /* register datastore * the source must be identical because this is http */ SmlDataSyncTestClient *client = NULL; GList *list = clients; unsigned int count = 0; for (;list; list = list->next) { count ++; client = list->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (client->data_store, "contacts"); sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, client); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; /* configure test data */ int max_items = 100; int i; for(i = 0; i < max_items; i++) { client->items = g_list_append(client->items, g_strdup_printf("client %d data %d", count, (i+1))); } } server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (server_data_store, "contacts"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } END_TEST void test_ds_api_max_msg_changes (const char *port, const char *max, gsize max_items) { GError *error = NULL; init_testbed(1, "HTTP", port); if (!sml_data_sync_set_option(server, SML_DATA_SYNC_CONFIG_MAX_MSG_CHANGES, max, &error)) goto error; /* register datastore * the source must be identical because this is http */ SmlDataSyncTestClient *client = clients->data; client->data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (client->data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (client->data_store, "contacts"); sml_data_sync_data_store_register_change_callback(client->data_store, clientRecvChangeCallback, NULL); if (!sml_data_sync_add_data_store(client->client, client->data_store, &error)) goto error; server_data_store = sml_data_sync_data_store_new(); sml_data_sync_data_store_set_content_type (server_data_store, "text/x-vcard"); sml_data_sync_data_store_set_local_uri (server_data_store, "contacts"); sml_data_sync_data_store_register_change_callback(server_data_store, serverRecvChangeCallback, NULL); sml_data_sync_data_store_register_mapping_callback(server_data_store, serverRecvMappingCallback, NULL); if (!sml_data_sync_add_data_store(server, server_data_store, &error)) goto error; /* configure test data */ int i; for(i = 0; i < max_items; i++) { client->items = g_list_append(client->items, g_strdup_printf("client 1 data %d", (i+1))); } run_testbed(); return; error: sml_fail_unless(FALSE, "%s", error->message); } START_TEST (ds_api_max_msg_changes_empty) { test_ds_api_max_msg_changes("17007", "0", 1000); } END_TEST START_TEST (ds_api_max_msg_changes_single) { test_ds_api_max_msg_changes("17008", "1", 100); } END_TEST START_TEST (ds_api_max_msg_changes_multi) { test_ds_api_max_msg_changes("17009", "5", 500); } END_TEST START_TEST (ds_api_max_msg_changes_multi_plus_one) { test_ds_api_max_msg_changes("17010", "5", 501); } END_TEST @SML_TESTCASE_CODE@