|
Packit |
4b6dd7 |
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
|
Packit |
4b6dd7 |
/*
|
|
Packit |
4b6dd7 |
* GData Client
|
|
Packit |
4b6dd7 |
* Copyright (C) Philip Withnall 2009 <philip@tecnocode.co.uk>
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* GData Client is free software; you can redistribute it and/or
|
|
Packit |
4b6dd7 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
4b6dd7 |
* License as published by the Free Software Foundation; either
|
|
Packit |
4b6dd7 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* GData Client is distributed in the hope that it will be useful,
|
|
Packit |
4b6dd7 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
4b6dd7 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
4b6dd7 |
* Lesser General Public License for more details.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
4b6dd7 |
* License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
#include <glib.h>
|
|
Packit |
4b6dd7 |
#include <gdata/gdata.h>
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
#include <uhttpmock/uhm.h>
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
#ifndef GDATA_TEST_COMMON_H
|
|
Packit |
4b6dd7 |
#define GDATA_TEST_COMMON_H
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
G_BEGIN_DECLS
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
#define CLIENT_ID "ytapi-GNOME-libgdata-444fubtt-0"
|
|
Packit |
4b6dd7 |
#define DOCUMENTS_USERNAME "libgdata.documents@gmail.com"
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/* These two must match */
|
|
Packit |
4b6dd7 |
#define USERNAME_NO_DOMAIN "libgdata.test"
|
|
Packit |
4b6dd7 |
#define USERNAME USERNAME_NO_DOMAIN "@gmail.com"
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/* This must not match the above two */
|
|
Packit |
4b6dd7 |
#define INCORRECT_USERNAME "libgdata.test.invalid@gmail.com"
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/* These two must not match (obviously) */
|
|
Packit |
4b6dd7 |
#define PASSWORD "gdata-gdata"
|
|
Packit |
4b6dd7 |
#define INCORRECT_PASSWORD "bad-password"
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/* The amount of fuzziness (in seconds) used in comparisons between times which should (theoretically) be equal.
|
|
Packit |
4b6dd7 |
* Due to the weak consistency used in Google's servers, it's hard to guarantee that timestamps which should be equal,
|
|
Packit |
4b6dd7 |
* actually are. */
|
|
Packit |
4b6dd7 |
#define TIME_FUZZINESS 5
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
void gdata_test_init (int argc, char **argv);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
UhmServer *gdata_test_get_mock_server (void) G_GNUC_WARN_UNUSED_RESULT;
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gboolean gdata_test_interactive (void);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
guint gdata_test_batch_operation_query (GDataBatchOperation *operation, const gchar *id, GType entry_type,
|
|
Packit |
4b6dd7 |
GDataEntry *entry, GDataEntry **returned_entry, GError **error);
|
|
Packit |
4b6dd7 |
guint gdata_test_batch_operation_insertion (GDataBatchOperation *operation, GDataEntry *entry, GDataEntry **inserted_entry, GError **error);
|
|
Packit |
4b6dd7 |
guint gdata_test_batch_operation_update (GDataBatchOperation *operation, GDataEntry *entry, GDataEntry **updated_entry, GError **error);
|
|
Packit |
4b6dd7 |
guint gdata_test_batch_operation_deletion (GDataBatchOperation *operation, GDataEntry *entry, GError **error);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gboolean gdata_test_batch_operation_run (GDataBatchOperation *operation, GCancellable *cancellable, GError **error);
|
|
Packit |
4b6dd7 |
gboolean gdata_test_batch_operation_run_finish (GDataBatchOperation *operation, GAsyncResult *async_result, GError **error);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gboolean gdata_test_compare_xml_strings (const gchar *parsable_xml, const gchar *expected_xml, gboolean print_error);
|
|
Packit |
4b6dd7 |
gboolean gdata_test_compare_xml (GDataParsable *parsable, const gchar *expected_xml, gboolean print_error);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gboolean gdata_test_compare_json_strings (const gchar *parsable_json, const gchar *expected_json, gboolean print_error);
|
|
Packit |
4b6dd7 |
gboolean gdata_test_compare_json (GDataParsable *parsable, const gchar *expected_json, gboolean print_error);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gboolean gdata_test_compare_kind (GDataEntry *entry, const gchar *expected_term, const gchar *expected_label);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/* Convenience macros. */
|
|
Packit |
4b6dd7 |
#define gdata_test_assert_xml(Parsable, XML) \
|
|
Packit |
4b6dd7 |
G_STMT_START { \
|
|
Packit |
4b6dd7 |
gboolean _test_success = gdata_test_compare_xml (GDATA_PARSABLE (Parsable), XML, TRUE); \
|
|
Packit |
4b6dd7 |
g_assert (_test_success == TRUE); \
|
|
Packit |
4b6dd7 |
} G_STMT_END
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
#define gdata_test_assert_json(Parsable, JSON) \
|
|
Packit |
4b6dd7 |
G_STMT_START { \
|
|
Packit |
4b6dd7 |
gboolean _test_success = gdata_test_compare_json (GDATA_PARSABLE (Parsable), JSON, TRUE); \
|
|
Packit |
4b6dd7 |
g_assert (_test_success == TRUE); \
|
|
Packit |
4b6dd7 |
} G_STMT_END
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/* Common code for tests of async query functions that have progress callbacks */
|
|
Packit |
4b6dd7 |
typedef struct {
|
|
Packit |
4b6dd7 |
guint progress_destroy_notify_count;
|
|
Packit |
4b6dd7 |
guint async_ready_notify_count;
|
|
Packit |
4b6dd7 |
GMainLoop *main_loop;
|
|
Packit |
4b6dd7 |
} GDataAsyncProgressClosure;
|
|
Packit |
4b6dd7 |
void gdata_test_async_progress_callback (GDataEntry *entry, guint entry_key, guint entry_count, GDataAsyncProgressClosure *data);
|
|
Packit |
4b6dd7 |
void gdata_test_async_progress_closure_free (GDataAsyncProgressClosure *data);
|
|
Packit |
4b6dd7 |
void gdata_test_async_progress_finish_callback (GObject *service, GAsyncResult *res, GDataAsyncProgressClosure *data);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
typedef struct {
|
|
Packit |
4b6dd7 |
/*< private >*/
|
|
Packit |
4b6dd7 |
GMainLoop *main_loop;
|
|
Packit |
4b6dd7 |
GCancellable *cancellable;
|
|
Packit |
4b6dd7 |
guint cancellation_timeout; /* timeout period in ms */
|
|
Packit |
4b6dd7 |
guint cancellation_timeout_id; /* ID of the callback source */
|
|
Packit |
4b6dd7 |
gboolean cancellation_successful;
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gconstpointer test_data;
|
|
Packit |
4b6dd7 |
} GDataAsyncTestData;
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/**
|
|
Packit |
4b6dd7 |
* GDATA_ASYNC_CLOSURE_FUNCTIONS:
|
|
Packit |
4b6dd7 |
* @CLOSURE_NAME: the name of the closure
|
|
Packit |
4b6dd7 |
* @TestStructType: the type of the synchronous closure structure
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Defines set up and tear down functions for a version of @TestStructType which is wrapped by #GDataAsyncTestData (i.e. allocated and pointed to by
|
|
Packit |
4b6dd7 |
* the #GDataAsyncTestData.test_data pointer). These functions will be named <function>set_up_<replaceable>CLOSURE_NAME</replaceable>_async</function>
|
|
Packit |
4b6dd7 |
* and <function>tear_down_<replaceable>CLOSURE_NAME</replaceable>_async</function>.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Since: 0.10.0
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
#define GDATA_ASYNC_CLOSURE_FUNCTIONS(CLOSURE_NAME, TestStructType) \
|
|
Packit |
4b6dd7 |
static void \
|
|
Packit |
4b6dd7 |
set_up_##CLOSURE_NAME##_async (GDataAsyncTestData *async_data, gconstpointer service) \
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
TestStructType *test_data = g_slice_new (TestStructType); \
|
|
Packit |
4b6dd7 |
set_up_##CLOSURE_NAME (test_data, service); \
|
|
Packit |
4b6dd7 |
gdata_set_up_async_test_data (async_data, test_data); \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
static void \
|
|
Packit |
4b6dd7 |
tear_down_##CLOSURE_NAME##_async (GDataAsyncTestData *async_data, gconstpointer service) \
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
tear_down_##CLOSURE_NAME ((TestStructType*) async_data->test_data, service); \
|
|
Packit |
4b6dd7 |
g_slice_free (TestStructType, (TestStructType*) async_data->test_data); \
|
|
Packit |
4b6dd7 |
gdata_tear_down_async_test_data (async_data, async_data->test_data); \
|
|
Packit |
4b6dd7 |
}
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/**
|
|
Packit |
4b6dd7 |
* GDATA_ASYNC_STARTING_TIMEOUT:
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* The initial timeout for cancellation tests, which will be the first timeout used after testing cancelling the operation before it's started.
|
|
Packit |
4b6dd7 |
* The value is in milliseconds.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Since: 0.10.0
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
#define GDATA_ASYNC_STARTING_TIMEOUT 20 /* ms */
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/**
|
|
Packit |
4b6dd7 |
* GDATA_ASYNC_TIMEOUT_MULTIPLIER:
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* The factor by which the asynchronous cancellation timeout will be multiplied between iterations of the cancellation test.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Since: 0.10.0
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
#define GDATA_ASYNC_TIMEOUT_MULTIPLIER 3
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/**
|
|
Packit |
4b6dd7 |
* GDATA_ASYNC_MAXIMUM_TIMEOUT:
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* The maximum timeout value for cancellation tests before they fail. i.e. If an operation takes longer than this period of time, the asynchronous
|
|
Packit |
4b6dd7 |
* operation test will fail.
|
|
Packit |
4b6dd7 |
* The value is in milliseconds.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Since: 0.10.0
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
#define GDATA_ASYNC_MAXIMUM_TIMEOUT 43740 /* ms */
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/**
|
|
Packit |
4b6dd7 |
* GDATA_ASYNC_TEST_FUNCTIONS:
|
|
Packit |
4b6dd7 |
* @TEST_NAME: the name of the test, excluding the “test_” prefix and the “_async” suffix
|
|
Packit |
4b6dd7 |
* @TestStructType: type of the closure structure to use, or <type>void</type>
|
|
Packit |
4b6dd7 |
* @TEST_BEGIN_CODE: code to execute to begin the test and start the asynchronous call
|
|
Packit |
4b6dd7 |
* @TEST_END_CODE: code to execute once the asynchronous call has completed, which will check the return values and any changed state
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Defines test and callback functions to test normal asynchronous operation and the cancellation behaviour of the given asynchronous function call.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* The asynchronous function call should be started in @TEST_BEGIN_CODE, using <varname>cancellable</varname> as its #GCancellable parameter,
|
|
Packit |
4b6dd7 |
* <varname>async_ready_callback</varname> as its #GAsyncReadyCallback parameter and <varname>async_data</varname> as its <varname>user_data</varname>
|
|
Packit |
4b6dd7 |
* parameter. There is no need for the code to create its own main loop: that's taken care of by the wrapper code.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* The code in @TEST_END_CODE will be inserted into the callback function for both the normal asynchronous test and the cancellation test, so should
|
|
Packit |
4b6dd7 |
* finish the asynchronous function call, using <varname>obj</varname> as the object on which the asynchronous function call was made,
|
|
Packit |
4b6dd7 |
* <varname>async_result</varname> as its #GAsyncResult parameter and <varname>error</varname> as its #GError parameter. The code should then check
|
|
Packit |
4b6dd7 |
* <varname>error: if it's %NULL, the code should assert success conditions; if it's non-%NULL, the code should assert failure conditions.
|
|
Packit |
4b6dd7 |
* The wrapper code will ensure that the error is a %G_IO_ERROR_CANCELLED at the appropriate times.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* The following functions will be defined, and should be added to the test suite using the #GAsyncTestData closure structure:
|
|
Packit |
4b6dd7 |
* <function>test_<replaceable>TEST_NAME</replaceable>_async</function> and
|
|
Packit |
4b6dd7 |
* <function>test_<replaceable>TEST_NAME</replaceable>_async_cancellation</function>.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* These functions assume the existence of a <varname>mock_server</varname> variable which points to the current #UhmServer instance. They
|
|
Packit |
4b6dd7 |
* will automatically use traces <varname><replaceable>TEST_NAME</replaceable>-async</varname> and
|
|
Packit |
4b6dd7 |
* <varname><replaceable>TEST_NAME</replaceable>-async-cancellation</varname>.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Since: 0.10.0
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
#define GDATA_ASYNC_TEST_FUNCTIONS(TEST_NAME, TestStructType, TEST_BEGIN_CODE, TEST_END_CODE) \
|
|
Packit |
4b6dd7 |
static void \
|
|
Packit |
4b6dd7 |
test_##TEST_NAME##_async_cb (GObject *obj, GAsyncResult *async_result, GDataAsyncTestData *async_data) \
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
TestStructType *data = (TestStructType*) async_data->test_data; \
|
|
Packit |
4b6dd7 |
GError *error = NULL; \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
(void) data; /* hide potential unused variable warning */ \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
TEST_END_CODE; \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) == TRUE) { \
|
|
Packit |
4b6dd7 |
g_assert (g_cancellable_is_cancelled (async_data->cancellable) == TRUE); \
|
|
Packit |
4b6dd7 |
async_data->cancellation_successful = TRUE; \
|
|
Packit |
4b6dd7 |
} else if (error == NULL) { \
|
|
Packit |
4b6dd7 |
g_assert (g_cancellable_is_cancelled (async_data->cancellable) == FALSE || async_data->cancellation_timeout > 0); \
|
|
Packit |
4b6dd7 |
async_data->cancellation_successful = FALSE; \
|
|
Packit |
4b6dd7 |
} else { \
|
|
Packit |
4b6dd7 |
/* Unexpected error: explode. */ \
|
|
Packit |
4b6dd7 |
g_assert_no_error (error); \
|
|
Packit |
4b6dd7 |
async_data->cancellation_successful = FALSE; \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
g_clear_error (&error); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
g_main_loop_quit (async_data->main_loop); \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
static void \
|
|
Packit |
4b6dd7 |
test_##TEST_NAME##_async (GDataAsyncTestData *async_data, gconstpointer service) \
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
GAsyncReadyCallback async_ready_callback = (GAsyncReadyCallback) test_##TEST_NAME##_async_cb; \
|
|
Packit |
4b6dd7 |
TestStructType *data = (TestStructType*) async_data->test_data; \
|
|
Packit |
4b6dd7 |
GCancellable *cancellable = NULL; /* don't expose the cancellable, so the test proceeds as normal */ \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
(void) data; /* hide potential unused variable warning */ \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Just run the test without doing any cancellation, and assert that it succeeds. */ \
|
|
Packit |
4b6dd7 |
async_data->cancellation_timeout = 0; \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
g_test_message ("Running normal operation test…"); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
gdata_test_mock_server_start_trace (mock_server, G_STRINGIFY (TEST_NAME) "-async"); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
TEST_BEGIN_CODE; \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
g_main_loop_run (async_data->main_loop); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
uhm_server_end_trace (mock_server); \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
static void \
|
|
Packit |
4b6dd7 |
test_##TEST_NAME##_async_cancellation (GDataAsyncTestData *async_data, gconstpointer service) \
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
async_data->cancellation_timeout = 0; \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Starting with a short timeout, repeatedly run the async. operation, cancelling it after the timeout and increasing the timeout until
|
|
Packit |
4b6dd7 |
* the operation succeeds for the first time. We then finish the test. This guarantees that if, for example, the test creates an entry on
|
|
Packit |
4b6dd7 |
* the server, it only ever creates one; because the test only ever succeeds once. (Of course, this assumes that the server does not change
|
|
Packit |
4b6dd7 |
* state if we cancel the operation, which is a fairly optimistic assumption. Sigh.) */ \
|
|
Packit |
4b6dd7 |
do { \
|
|
Packit |
4b6dd7 |
GCancellable *cancellable = async_data->cancellable; \
|
|
Packit |
4b6dd7 |
GAsyncReadyCallback async_ready_callback = (GAsyncReadyCallback) test_##TEST_NAME##_async_cb; \
|
|
Packit |
4b6dd7 |
TestStructType *data = (TestStructType*) async_data->test_data; \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
gdata_test_mock_server_start_trace (mock_server, G_STRINGIFY (TEST_NAME) "-async-cancellation"); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
(void) data; /* hide potential unused variable warning */ \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Ensure the timeout remains sane. */ \
|
|
Packit |
4b6dd7 |
g_assert_cmpuint (async_data->cancellation_timeout, <=, GDATA_ASYNC_MAXIMUM_TIMEOUT); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Schedule the cancellation after the timeout. */ \
|
|
Packit |
4b6dd7 |
if (async_data->cancellation_timeout == 0) { \
|
|
Packit |
4b6dd7 |
/* For the first test, cancel the cancellable before the test code is run */ \
|
|
Packit |
4b6dd7 |
gdata_async_test_cancellation_cb (async_data); \
|
|
Packit |
4b6dd7 |
} else { \
|
|
Packit |
4b6dd7 |
async_data->cancellation_timeout_id = g_timeout_add (async_data->cancellation_timeout, \
|
|
Packit |
4b6dd7 |
(GSourceFunc) gdata_async_test_cancellation_cb, async_data); \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Mark the cancellation as unsuccessful and hope we get proven wrong. */ \
|
|
Packit |
4b6dd7 |
async_data->cancellation_successful = FALSE; \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
g_test_message ("Running cancellation test with timeout of %u ms…", async_data->cancellation_timeout); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
{ \
|
|
Packit |
4b6dd7 |
TEST_BEGIN_CODE; \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
g_main_loop_run (async_data->main_loop); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Reset the cancellable for the next iteration and increase the timeout geometrically. */ \
|
|
Packit |
4b6dd7 |
g_cancellable_reset (cancellable); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
if (async_data->cancellation_timeout == 0) { \
|
|
Packit |
4b6dd7 |
async_data->cancellation_timeout = GDATA_ASYNC_STARTING_TIMEOUT; /* ms */ \
|
|
Packit |
4b6dd7 |
} else { \
|
|
Packit |
4b6dd7 |
async_data->cancellation_timeout *= GDATA_ASYNC_TIMEOUT_MULTIPLIER; \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
uhm_server_end_trace (mock_server); \
|
|
Packit |
4b6dd7 |
} while (async_data->cancellation_successful == TRUE); \
|
|
Packit |
4b6dd7 |
\
|
|
Packit |
4b6dd7 |
/* Clean up the last timeout callback */ \
|
|
Packit |
4b6dd7 |
if (async_data->cancellation_timeout_id != 0) { \
|
|
Packit |
4b6dd7 |
g_source_remove (async_data->cancellation_timeout_id); \
|
|
Packit |
4b6dd7 |
} \
|
|
Packit |
4b6dd7 |
}
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gboolean gdata_async_test_cancellation_cb (GDataAsyncTestData *async_data);
|
|
Packit |
4b6dd7 |
void gdata_set_up_async_test_data (GDataAsyncTestData *async_data, gconstpointer test_data);
|
|
Packit |
4b6dd7 |
void gdata_tear_down_async_test_data (GDataAsyncTestData *async_data, gconstpointer test_data);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
/**
|
|
Packit |
4b6dd7 |
* GDataTestRequestErrorData:
|
|
Packit |
4b6dd7 |
* @status_code: HTTP response status code
|
|
Packit |
4b6dd7 |
* @reason_phrase: HTTP response status phrase
|
|
Packit |
4b6dd7 |
* @message_body: HTTP response message body
|
|
Packit |
4b6dd7 |
* @error_domain_func: constant function returning the #GQuark for the expected error domain
|
|
Packit |
4b6dd7 |
* @error_code: expected error code
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* A mapping between a HTTP response emitted by a #UhmServer and the error expected to be thrown by the HTTP client.
|
|
Packit |
4b6dd7 |
* This is designed for testing error handling in the client code, typically by running a single request through an array
|
|
Packit |
4b6dd7 |
* of these such mappings and testing the client code throws the correct error in each case.
|
|
Packit |
4b6dd7 |
*
|
|
Packit |
4b6dd7 |
* Since: 0.13.4
|
|
Packit |
4b6dd7 |
*/
|
|
Packit |
4b6dd7 |
typedef struct {
|
|
Packit |
4b6dd7 |
/* HTTP response. */
|
|
Packit |
4b6dd7 |
guint status_code;
|
|
Packit |
4b6dd7 |
const gchar *reason_phrase;
|
|
Packit |
4b6dd7 |
const gchar *message_body;
|
|
Packit |
4b6dd7 |
/* Expected GData error. */
|
|
Packit |
4b6dd7 |
GQuark (*error_domain_func) (void); /* typically gdata_service_error_quark */
|
|
Packit |
4b6dd7 |
gint error_code;
|
|
Packit |
4b6dd7 |
} GDataTestRequestErrorData;
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
void gdata_test_set_https_port (UhmServer *server);
|
|
Packit |
4b6dd7 |
void gdata_test_mock_server_start_trace (UhmServer *server, const gchar *trace_filename);
|
|
Packit |
4b6dd7 |
gboolean gdata_test_mock_server_handle_message_error (UhmServer *server, SoupMessage *message, SoupClientContext *client, gpointer user_data);
|
|
Packit |
4b6dd7 |
gboolean gdata_test_mock_server_handle_message_timeout (UhmServer *server, SoupMessage *message, SoupClientContext *client, gpointer user_data);
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
gchar *gdata_test_query_user_for_verifier (const gchar *authentication_uri) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
G_END_DECLS
|
|
Packit |
4b6dd7 |
|
|
Packit |
4b6dd7 |
#endif /* !GDATA_TEST_COMMON_H */
|