From: <dg...@su...> - 2009-01-28 13:48:14
|
Author: bellmich Date: Wed Jan 28 14:46:49 2009 New Revision: 905 URL: http://libsyncml.opensync.org/changeset/905 Log: added a test for the high level DS API Added: trunk/tests/check_data_sync_api.c Modified: trunk/tests/CMakeLists.txt Modified: trunk/tests/CMakeLists.txt ============================================================================== --- trunk/tests/CMakeLists.txt Wed Jan 28 14:45:42 2009 (r904) +++ trunk/tests/CMakeLists.txt Wed Jan 28 14:46:49 2009 (r905) @@ -29,6 +29,7 @@ ADD_CHECK_TEST( san check_san.c ${TEST_TARGET_LIBRARIES} ) ADD_CHECK_TEST( devinf check_devinf.c ${TEST_TARGET_LIBRARIES} ) ADD_CHECK_TEST( sync check_sync.c ${TEST_TARGET_LIBRARIES} ) + ADD_CHECK_TEST( ds_api check_data_sync_api.c ${TEST_TARGET_LIBRARIES} ) # dependent tests Added: trunk/tests/check_data_sync_api.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/tests/check_data_sync_api.c Wed Jan 28 14:46:49 2009 (r905) @@ -0,0 +1,466 @@ +/* + * libsyncml - A syncml protocol implementation + * Copyright (C) 2009 Michael Bell <mic...@op...> + * + * 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 "support.h" + +#include <libsyncml/syncml.h> +#include <libsyncml/syncml_internals.h> +#include <libsyncml/data_sync_api/defines.h> +#include <libsyncml/data_sync_api/standard.h> +#include <libsyncml/data_sync_api/callbacks.h> +#include <glib.h> +// #include <glib/gstdio.h> + +//#include <stdio.h> +//#include <stdlib.h> +//#include <string.h> + +GMutex *runMutex = NULL; +int locks; + +GList *client_items; +SmlDataSyncObject *client; +SmlDataSyncObject *server; +const char *client_source; +const char *server_source; +char *transport; + + +/* ************************************ */ +/* *********** CALLBACKS ************** */ +/* ************************************ */ + +SmlBool sendAllChanges( + SmlDataSyncObject *dsObject, + SmlError **error) +{ + smlTrace(TRACE_ENTRY, "%s", __func__); + + if (dsObject == client) + { + GList *list = client_items; + size_t count = 0; + for (;list;list = list->next) + { + count++; + const char *test_data = list->data; + char *name = g_strdup_printf("%d", count); + if (!smlDataSyncAddChange(client, client_source, SML_CHANGE_ADD, + name , test_data, strlen(test_data), NULL, error)) + fail("%s", smlErrorPrint(error)); + smlSafeCFree(&name); + } + } + + smlTrace(TRACE_EXIT, "%s", __func__); + return smlDataSyncSendChanges(dsObject, error); +} + +static void recvEventCallback( + SmlDataSyncObject *dsObject, + SmlDataSyncEventType type, + void *userdata, + SmlError *error) +{ + smlTrace(TRACE_ENTRY, "%s(%p, %i, %p, %p)", __func__, dsObject, type, userdata, error); + SmlError *locerror = NULL; + + switch (type) { + case SML_DATA_SYNC_EVENT_ERROR: + fail("error from ds api: %s", smlErrorPrint(&error)); + break; + case SML_DATA_SYNC_EVENT_CONNECT: + /* g_message("Remote device was successfully connected."); */ + break; + case SML_DATA_SYNC_EVENT_DISCONNECT: + /* g_message("Remote device was successfully disconnected."); */ + break; + case SML_DATA_SYNC_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_EVENT_GOT_ALL_ALERTS: + /* g_message("All alerts of the remote device were received."); */ + if (dsObject == client) + { + if (!sendAllChanges(dsObject, &locerror)) + goto error; + } + break; + case SML_DATA_SYNC_EVENT_GOT_ALL_CHANGES: + /* g_message("All changes of the remote device were received."); */ + if (dsObject == server) + { + if (!sendAllChanges(dsObject, &locerror)) + goto error; + } + /* the map of the client is send automatically */ + break; + case SML_DATA_SYNC_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", smlErrorPrint(&locerror)); + smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&locerror)); + smlErrorDeref(&locerror); + exit(3); +} + +static SmlBool recvChangeCallback( + SmlDataSyncObject *dsObject, + const char *source, + SmlChangeType type, + const char *uid, + char *data, + unsigned int size, + void *userdata, + SmlError **error) +{ + smlTrace(TRACE_ENTRY, "%s(%s: %s)", __func__, VA_STRING(source), VA_STRING(uid)); + + /* clients should never receive a change in this test */ + + if (dsObject == client) + fail("A change was received from the server."); + + /* check the source */ + + if (strcmp(server_source, source)) + fail("The source %s is wrong.", server_source); + + /* handle the item */ + GList *list = client_items; + size_t count = 0; + for (; list; list = list->next) { + count++; + + /* test the uid */ + char *name = g_strdup_printf("%d", count); + if (strcmp(name, uid)) { + smlSafeCFree(&name); + continue; + } + smlSafeCFree(&name); + + /* item with correct uid */ + if (strcmp(list->data, data)) + fail("The data of the item %s was wrong(%s != %s).", uid, data, list->data); + } + smlSafeCFree(&data); + + smlTrace(TRACE_EXIT, "%s - TRUE", __func__); + return TRUE; +} + +//static SmlAlertType recvAlertTypeCallback( +// SmlDataSyncObject *dsObject, +// const char *source, +// SmlAlertType type, +// void *userdata, +// SmlError **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) { +// smlErrorSet(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__, smlErrorPrint(error)); +// return SML_ALERT_UNKNOWN; +//} + +void init_testbed(const char *transport_type, const char *port) +{ + /* general init */ + setup_testbed(NULL); + SmlError *error = NULL; + client_items = NULL; + +#ifdef ENABLE_OPENOBEX_TCP + transport = "OBEX"; +#endif +#ifdef ENABLE_HTTP + transport = "HTTP"; +#endif +#ifdef ENABLE_OPENOBEX_TCP + if (!strcasecmp(transport_type, "OBEX")) { + transport = "OBEX"; + } +#ifdef ENABLE_HTTP +#endif + if (!strcasecmp(transport_type, "HTTP")) { + transport = "HTTP"; + } +#endif + if (!strcmp(transport, "HTTP")) + { + client = smlDataSyncNew(SML_SESSION_TYPE_CLIENT, SML_TRANSPORT_HTTP_CLIENT, &error); + if (!client) + goto error; + server = smlDataSyncNew(SML_SESSION_TYPE_SERVER, SML_TRANSPORT_HTTP_SERVER, &error); + if (!server) + goto error; + } else { + client = smlDataSyncNew(SML_SESSION_TYPE_CLIENT, SML_TRANSPORT_OBEX_SERVER, &error); + if (!client) + goto error; + server = smlDataSyncNew(SML_SESSION_TYPE_SERVER, SML_TRANSPORT_OBEX_CLIENT, &error); + if (!server) + goto error; + } + + /* default configuration of callbacks */ + smlDataSyncRegisterEventCallback(client, recvEventCallback, NULL); + smlDataSyncRegisterEventCallback(server, recvEventCallback, NULL); + // smlDataSyncRegisterGetAlertTypeCallback(client, recvAlertTypeCallback, NULL); + // smlDataSyncRegisterGetAlertTypeCallback(server, recvAlertTypeCallback, NULL); + smlDataSyncRegisterChangeCallback(client, recvChangeCallback, NULL); + smlDataSyncRegisterChangeCallback(server, recvChangeCallback, NULL); + // smlDataSyncRegisterChangeStatusCallback(dsObject, recvChangeStatusCallback); + // smlDataSyncRegisterMappingCallback(dsObject, recvMappingCallback, NULL); + + /* configure transport */ + if (!strcmp(transport, "HTTP")) { + /* HTTP */ + char *url = g_strdup_printf("http://127.0.0.1:%s", port); + if (!smlDataSyncSetOption( + client, + SML_TRANSPORT_CONFIG_URL, + url, &error)) + goto error; + smlSafeCFree(&url); + } else { + /* OBEX */ + if (!smlDataSyncSetOption( + client, + SML_DATA_SYNC_CONFIG_CONNECTION_TYPE, + SML_DATA_SYNC_CONFIG_CONNECTION_NET, + &error)) + goto error; + if (!smlDataSyncSetOption( + server, + SML_DATA_SYNC_CONFIG_CONNECTION_TYPE, + SML_DATA_SYNC_CONFIG_CONNECTION_NET, + &error)) + goto error; + if (!smlDataSyncSetOption( + server, + SML_TRANSPORT_CONFIG_URL, + "127.0.0.1", &error)) + goto error; + if (!smlDataSyncSetOption( + client, + SML_TRANSPORT_CONFIG_PORT, + port, &error)) + goto error; + } + if (!smlDataSyncSetOption( + server, + SML_TRANSPORT_CONFIG_PORT, + port, &error)) + goto error; + + return; +error: + fail("%s", smlErrorPrint(&error)); +} + +void run_testbed() +{ + SmlError *error = NULL; + locks = 2; + + /* init the sync */ + if (!strcmp(transport, "HTTP")) + { + if (!smlDataSyncInit(server, &error)) + goto error; + if (!smlDataSyncInit(client, &error)) + goto error; + if (!smlDataSyncRun(server, &error)) + goto error; + if (!smlDataSyncRun(client, &error)) + goto error; + } else { + if (!smlDataSyncInit(client, &error)) + goto error; + if (!smlDataSyncInit(server, &error)) + goto error; + if (!smlDataSyncRun(client, &error)) + goto error; + if (!smlDataSyncRun(server, &error)) + goto error; + } + + runMutex = g_mutex_new(); + g_mutex_lock(runMutex); + g_mutex_lock(runMutex); + g_mutex_unlock(runMutex); + g_mutex_free(runMutex); + runMutex = NULL; + + /* close the object */ + smlDataSyncObjectUnref(&client); + smlDataSyncObjectUnref(&server); + g_list_free(client_items); + + return; +error: + fail("%s", smlErrorPrint(&error)); +} + +START_TEST (check_text_vcard_21) +{ + SmlError *error = NULL; + init_testbed("HTTP", "17001"); + + /* register datastore + * the source must be identical because this is http + */ + client_source = "contacts"; + server_source = "contacts"; + if (!smlDataSyncAddDatastore( + client, + "text/x-vcard", + NULL, + client_source, + &error)) + goto error; + if (!smlDataSyncAddDatastore( + server, + "text/x-vcard", + NULL, + server_source, + &error)) + goto error; + + /* configure test data */ + client_items = g_list_append(client_items, "blabla"); + + run_testbed(); + + return; +error: + fail("%s", smlErrorPrint(&error)); +} +END_TEST + +START_TEST (check_image_jpeg) +{ + SmlError *error = NULL; + init_testbed("OBEX", "17002"); + + /* register datastore + * the source must be identical because this is http + */ + client_source = "dcim"; + server_source = "photos"; + // server_source = "addressbook"; + if (!smlDataSyncAddDatastore( + client, + "image/jpeg", + NULL, + client_source, + &error)) + goto error; + if (!smlDataSyncAddDatastore( + server, + "image/jpeg", + NULL, + server_source, + &error)) + goto error; + + /* configure test data */ + client_items = g_list_append(client_items, "this is an image"); + + run_testbed(); + + return; +error: + fail("%s", smlErrorPrint(&error)); +} +END_TEST + +Suite *ds_suite(void) +{ + Suite *s = suite_create("OMA DS API"); + //Suite *s2 = suite_create("OMA DS API"); + + create_case(s, "check_text_vcard_21", check_text_vcard_21); + create_case(s, "check_image_jpeg", check_image_jpeg); + + return s; +} + +int main(void) +{ + configure_environment(); + + int nf; + + Suite *s = ds_suite(); + + SRunner *sr; + sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + nf = srunner_ntests_failed(sr); + srunner_free(sr); + return (nf == 0) ? 0 : 1; +} |