Revert "Move gio tests from gio/tests/ to tests/gio/"

This reverts commit 2262d76b33.

Move GIO tests back to where they belong.
This commit is contained in:
Matthias Clasen
2009-07-05 22:49:24 -04:00
parent 8de4be69a9
commit 5694ab7642
29 changed files with 4 additions and 2 deletions

24
gio/tests/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
buffered-input-stream
desktop-app-info
g-icon
simple-async-result
unix-streams
data-input-stream
data-output-stream
g-file
g-file-info
live-g-file
memory-input-stream
memory-output-stream
filter-streams
sleepy-stream
resolver
connectable
echo-server
httpd
readwrite
send-data
socket-client
socket-server
srvtarget
contexts

119
gio/tests/Makefile.am Normal file
View File

@@ -0,0 +1,119 @@
include $(top_srcdir)/Makefile.decl
INCLUDES = \
-g \
-I$(top_srcdir) \
-I$(top_srcdir)/glib \
-I$(top_srcdir)/gmodule \
-I$(top_srcdir)/gobject \
-I$(top_srcdir)/gio \
$(GLIB_DEBUG_FLAGS) \
-DSRCDIR=\""$(srcdir)"\"
noinst_PROGRAMS = $(TEST_PROGS) $(SAMPLE_PROGS)
progs_ldadd = \
$(top_builddir)/glib/libglib-2.0.la \
$(top_builddir)/gobject/libgobject-2.0.la \
$(top_builddir)/gio/libgio-2.0.la
TEST_PROGS += \
memory-input-stream \
memory-output-stream \
readwrite \
g-file \
g-file-info \
data-input-stream \
data-output-stream \
g-icon \
buffered-input-stream \
sleepy-stream \
filter-streams \
simple-async-result \
srvtarget \
contexts
SAMPLE_PROGS = resolver socket-server socket-client echo-server httpd send-data
if OS_UNIX
TEST_PROGS += live-g-file unix-streams desktop-app-info
endif
memory_input_stream_SOURCES = memory-input-stream.c
memory_input_stream_LDADD = $(progs_ldadd)
memory_output_stream_SOURCES = memory-output-stream.c
memory_output_stream_LDADD = $(progs_ldadd)
g_file_SOURCES = g-file.c
g_file_LDADD = $(progs_ldadd)
readwrite_SOURCES = readwrite.c
readwrite_LDADD = $(progs_ldadd)
g_file_info_SOURCES = g-file-info.c
g_file_info_LDADD = $(progs_ldadd)
data_input_stream_SOURCES = data-input-stream.c
data_input_stream_LDADD = $(progs_ldadd)
data_output_stream_SOURCES = data-output-stream.c
data_output_stream_LDADD = $(progs_ldadd)
g_icon_SOURCES = g-icon.c
g_icon_LDADD = $(progs_ldadd)
buffered_input_stream_SOURCES = buffered-input-stream.c
buffered_input_stream_LDADD = $(progs_ldadd)
live_g_file_SOURCES = live-g-file.c
live_g_file_LDADD = $(progs_ldadd)
desktop_app_info_SOURCES = desktop-app-info.c
desktop_app_info_LDADD = $(progs_ldadd)
unix_streams_SOURCES = unix-streams.c
unix_streams_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
simple_async_result_SOURCES = simple-async-result.c
simple_async_result_LDADD = $(progs_ldadd)
sleepy_stream_SOURCES = sleepy-stream.c
sleepy_stream_LDADD = $(progs_ldadd)
filter_streams_SOURCES = filter-streams.c
filter_streams_LDADD = $(progs_ldadd)
resolver_SOURCES = resolver.c
resolver_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
socket_server_SOURCES = socket-server.c
socket_server_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
socket_client_SOURCES = socket-client.c
socket_client_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
echo_server_SOURCES = echo-server.c
echo_server_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
httpd_SOURCES = httpd.c
httpd_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
send_data_SOURCES = send-data.c
send_data_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
srvtarget_SOURCES = srvtarget.c
srvtarget_LDADD = $(progs_ldadd)
contexts_SOURCES = contexts.c
contexts_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
DISTCLEAN_FILES = applications/mimeinfo.cache

View File

@@ -0,0 +1,60 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Matthias Clasen <mclasen@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_read_byte (void)
{
GInputStream *base;
GInputStream *in;
g_test_bug ("562393");
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
in = g_buffered_input_stream_new (base);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, NULL), ==, 'a');
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, NULL), ==, 'b');
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, NULL), ==, 'c');
g_assert_cmpint (g_input_stream_skip (in, 3, NULL, NULL), ==, 3);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, NULL), ==, 'g');
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/buffered-input-stream/read-byte", test_read_byte);
return g_test_run();
}

190
gio/tests/contexts.c Normal file
View File

@@ -0,0 +1,190 @@
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define TEST_FILE (SRCDIR "/Makefile.am")
char *test_file_buffer;
gsize test_file_size;
static char async_read_buffer[8192];
static void
read_data (GObject *source, GAsyncResult *result, gpointer loop)
{
GInputStream *in = G_INPUT_STREAM (source);
GError *error = NULL;
gssize nread;
nread = g_input_stream_read_finish (in, result, &error);
g_assert_no_error (error);
g_assert_cmpint (nread, >, 0);
g_assert_cmpint (nread, <=, MIN(sizeof (async_read_buffer), test_file_size));
g_assert (memcmp (async_read_buffer, test_file_buffer, nread) == 0);
g_main_loop_quit (loop);
}
static void
opened_for_read (GObject *source, GAsyncResult *result, gpointer loop)
{
GFile *file = G_FILE (source);
GFileInputStream *in;
GError *error = NULL;
in = g_file_read_finish (file, result, &error);
g_assert_no_error (error);
memset (async_read_buffer, 0, sizeof (async_read_buffer));
g_input_stream_read_async (G_INPUT_STREAM (in),
async_read_buffer, sizeof (async_read_buffer),
G_PRIORITY_DEFAULT, NULL,
read_data, loop);
}
/* Test 1: Async I/O started in a thread with a thread-default context
* will stick to that thread, and will complete even if the default
* main loop is blocked. (NB: the last part would not be true if we
* were testing GFileMonitor!)
*/
static gboolean idle_start_test1_thread (gpointer loop);
static gpointer test1_thread (gpointer user_data);
static GCond *test1_cond;
static GMutex *test1_mutex;
static void
test_thread_independence (void)
{
GMainLoop *loop;
test1_cond = g_cond_new ();
test1_mutex = g_mutex_new ();
loop = g_main_loop_new (NULL, FALSE);
g_idle_add (idle_start_test1_thread, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_mutex_free (test1_mutex);
g_cond_free (test1_cond);
}
static gboolean
idle_start_test1_thread (gpointer loop)
{
GTimeVal time;
GThread *thread;
gboolean io_completed;
g_mutex_lock (test1_mutex);
thread = g_thread_create (test1_thread, NULL, TRUE, NULL);
g_get_current_time (&time);
time.tv_sec += 2;
io_completed = g_cond_timed_wait (test1_cond, test1_mutex, &time);
g_assert (io_completed);
g_thread_join (thread);
g_mutex_unlock (test1_mutex);
g_main_loop_quit (loop);
return FALSE;
}
static gpointer
test1_thread (gpointer user_data)
{
GMainContext *context;
GMainLoop *loop;
GFile *file;
/* Wait for main thread to be waiting on test1_cond */
g_mutex_lock (test1_mutex);
g_mutex_unlock (test1_mutex);
context = g_main_context_new ();
g_assert (g_main_context_get_thread_default () == NULL);
g_main_context_push_thread_default (context);
g_assert (g_main_context_get_thread_default () == context);
file = g_file_new_for_path (TEST_FILE);
g_assert (g_file_supports_thread_contexts (file));
loop = g_main_loop_new (context, FALSE);
g_file_read_async (file, G_PRIORITY_DEFAULT, NULL,
opened_for_read, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_cond_signal (test1_cond);
return NULL;
}
/* Test 2: If we push a thread-default context in the main thread, we
* can run async ops in that context without running the default
* context.
*/
static gboolean test2_fail (gpointer user_data);
static void
test_context_independence (void)
{
GMainContext *context;
GMainLoop *loop;
GFile *file;
guint default_timeout;
GSource *thread_default_timeout;
context = g_main_context_new ();
g_assert (g_main_context_get_thread_default () == NULL);
g_main_context_push_thread_default (context);
g_assert (g_main_context_get_thread_default () == context);
file = g_file_new_for_path (TEST_FILE);
g_assert (g_file_supports_thread_contexts (file));
/* Add a timeout to the main loop, to fail immediately if it gets run */
default_timeout = g_timeout_add_full (G_PRIORITY_HIGH, 0,
test2_fail, NULL, NULL);
/* Add a timeout to the alternate loop, to fail if the I/O *doesn't* run */
thread_default_timeout = g_timeout_source_new_seconds (2);
g_source_set_callback (thread_default_timeout, test2_fail, NULL, NULL);
g_source_attach (thread_default_timeout, context);
loop = g_main_loop_new (context, FALSE);
g_file_read_async (file, G_PRIORITY_DEFAULT, NULL,
opened_for_read, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_source_remove (default_timeout);
g_source_destroy (thread_default_timeout);
g_source_unref (thread_default_timeout);
}
static gboolean
test2_fail (gpointer user_data)
{
g_assert_not_reached ();
return FALSE;
}
int
main (int argc, char **argv)
{
GError *error = NULL;
g_thread_init (NULL);
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_file_get_contents (TEST_FILE, &test_file_buffer,
&test_file_size, &error);
g_assert_no_error (error);
g_test_add_func ("/gio/contexts/thread-independence", test_thread_independence);
g_test_add_func ("/gio/contexts/context-independence", test_context_independence);
return g_test_run();
}

View File

@@ -0,0 +1,336 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 0xFFF
#define MAX_BYTES 0x10000
static void
test_seek_to_start (GInputStream *stream)
{
GError *error = NULL;
gboolean res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
g_assert_cmpint (res, ==, TRUE);
g_assert_no_error (error);
}
static void
test_read_lines (GDataStreamNewlineType newline_type)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *data;
int line;
const char* lines[MAX_LINES];
const char* endl[4] = {"\n", "\r", "\r\n", "\n"};
/* prepare data */
int i;
for (i = 0; i < MAX_LINES; i++)
lines[i] = "some_text";
base_stream = g_memory_input_stream_new ();
g_assert (base_stream != NULL);
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_assert(stream != NULL);
/* Byte order testing */
g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
/* Line ends testing */
g_data_input_stream_set_newline_type (G_DATA_INPUT_STREAM (stream), newline_type);
g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, newline_type);
/* Add sample data */
for (i = 0; i < MAX_LINES; i++)
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream),
g_strconcat (lines[i], endl[newline_type], NULL), -1, NULL);
/* Seek to the start */
test_seek_to_start (base_stream);
/* Test read line */
error = NULL;
data = (char*)1;
line = 0;
while (data)
{
gsize length = -1;
data = g_data_input_stream_read_line (G_DATA_INPUT_STREAM (stream), &length, NULL, &error);
if (data)
{
g_assert_cmpstr (data, ==, lines[line]);
g_assert_no_error (error);
line++;
}
}
g_assert_cmpint (line, ==, MAX_LINES);
g_object_unref (base_stream);
g_object_unref (stream);
}
static void
test_read_lines_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF);
}
static void
test_read_lines_CR (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR);
}
static void
test_read_lines_CR_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
}
static void
test_read_until (void)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *data;
int line;
int i;
#define REPEATS 10 /* number of rounds */
#define DATA_STRING " part1 # part2 $ part3 % part4 ^"
#define DATA_PART_LEN 7 /* number of characters between separators */
#define DATA_SEP "#$%^"
const int DATA_PARTS_NUM = strlen (DATA_SEP) * REPEATS;
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
for (i = 0; i < REPEATS; i++)
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, -1, NULL);
/* Test stop characters */
error = NULL;
data = (char*)1;
line = 0;
while (data)
{
gsize length = -1;
data = g_data_input_stream_read_until (G_DATA_INPUT_STREAM (stream), DATA_SEP, &length, NULL, &error);
if (data)
{
g_assert_cmpint (strlen (data), ==, DATA_PART_LEN);
g_assert_no_error (error);
line++;
}
}
g_assert_no_error (error);
g_assert_cmpint (line, ==, DATA_PARTS_NUM);
g_object_unref (base_stream);
g_object_unref (stream);
}
enum TestDataType {
TEST_DATA_BYTE = 0,
TEST_DATA_INT16,
TEST_DATA_UINT16,
TEST_DATA_INT32,
TEST_DATA_UINT32,
TEST_DATA_INT64,
TEST_DATA_UINT64
};
#define TEST_DATA_RETYPE_BUFF(a, t, v) \
(a == TEST_DATA_BYTE ? (t) *(guchar*)v : \
(a == TEST_DATA_INT16 ? (t) *(gint16*)v : \
(a == TEST_DATA_UINT16 ? (t) *(guint16*)v : \
(a == TEST_DATA_INT32 ? (t) *(gint32*)v : \
(a == TEST_DATA_UINT32 ? (t) *(guint32*)v : \
(a == TEST_DATA_INT64 ? (t) *(gint64*)v : \
(t) *(guint64*)v ))))))
static void
test_data_array (GInputStream *stream, GInputStream *base_stream,
gpointer buffer, int len,
enum TestDataType data_type, GDataStreamByteOrder byte_order)
{
GError *error = NULL;
int pos = 0;
int data_size = 1;
gint64 data;
GDataStreamByteOrder native;
gboolean swap;
/* Seek to start */
test_seek_to_start (base_stream);
/* Set correct data size */
switch (data_type)
{
case TEST_DATA_BYTE:
data_size = 1;
break;
case TEST_DATA_INT16:
case TEST_DATA_UINT16:
data_size = 2;
break;
case TEST_DATA_INT32:
case TEST_DATA_UINT32:
data_size = 4;
break;
case TEST_DATA_INT64:
case TEST_DATA_UINT64:
data_size = 8;
break;
default:
g_assert_not_reached ();
break;
}
/* Set flag to swap bytes if needed */
native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native);
data = 1;
while (data != 0)
{
switch (data_type)
{
case TEST_DATA_BYTE:
data = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error);
break;
case TEST_DATA_INT16:
data = g_data_input_stream_read_int16 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (gint16)GUINT16_SWAP_LE_BE((gint16)data);
break;
case TEST_DATA_UINT16:
data = g_data_input_stream_read_uint16 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (guint16)GUINT16_SWAP_LE_BE((guint16)data);
break;
case TEST_DATA_INT32:
data = g_data_input_stream_read_int32 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (gint32)GUINT32_SWAP_LE_BE((gint32)data);
break;
case TEST_DATA_UINT32:
data = g_data_input_stream_read_uint32 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (guint32)GUINT32_SWAP_LE_BE((guint32)data);
break;
case TEST_DATA_INT64:
data = g_data_input_stream_read_int64 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (gint64)GUINT64_SWAP_LE_BE((gint64)data);
break;
case TEST_DATA_UINT64:
data = g_data_input_stream_read_uint64 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (guint64)GUINT64_SWAP_LE_BE((guint64)data);
break;
default:
g_assert_not_reached ();
break;
}
if ((data) && (! error))
g_assert_cmpint (data, ==, TEST_DATA_RETYPE_BUFF(data_type, gint64, ((guchar*)buffer + pos)));
pos += data_size;
}
if (pos < len + 1)
g_assert_no_error (error);
g_assert_cmpint (pos - data_size, ==, len);
}
static void
test_read_int (void)
{
GInputStream *stream;
GInputStream *base_stream;
GRand *randomizer;
int i;
gpointer buffer;
randomizer = g_rand_new ();
buffer = g_malloc0 (MAX_BYTES);
/* Fill in some random data */
for (i = 0; i < MAX_BYTES; i++)
{
guchar x = 0;
while (! x)
x = (guchar)g_rand_int (randomizer);
*(guchar*)((guchar*)buffer + sizeof(guchar) * i) = x;
}
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), buffer, MAX_BYTES, NULL);
for (i = 0; i < 3; i++)
{
int j;
g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), i);
for (j = 0; j <= TEST_DATA_UINT64; j++)
test_data_array (stream, base_stream, buffer, MAX_BYTES, j, i);
}
g_object_unref (base_stream);
g_object_unref (stream);
g_rand_free (randomizer);
g_free (buffer);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/data-input-stream/read-lines-LF", test_read_lines_LF);
g_test_add_func ("/data-input-stream/read-lines-CR", test_read_lines_CR);
g_test_add_func ("/data-input-stream/read-lines-CR-LF", test_read_lines_CR_LF);
g_test_add_func ("/data-input-stream/read-until", test_read_until);
g_test_add_func ("/data-input-stream/read-int", test_read_int);
return g_test_run();
}

View File

@@ -0,0 +1,289 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 0xFFF
#define MAX_LINES_BUFF 0xFFFFFF
#define MAX_BYTES_BINARY 0x100
static void
test_read_lines (GDataStreamNewlineType newline_type)
{
GOutputStream *stream;
GOutputStream *base_stream;
GError *error = NULL;
gpointer data;
char *lines;
int size;
int i;
#define TEST_STRING "some_text"
const char* endl[4] = {"\n", "\r", "\r\n", "\n"};
data = g_malloc0 (MAX_LINES_BUFF);
lines = g_malloc0 ((strlen (TEST_STRING) + strlen (endl[newline_type])) * MAX_LINES + 1);
/* initialize objects */
base_stream = g_memory_output_stream_new (data, MAX_LINES_BUFF, NULL, NULL);
stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream));
/* fill data */
for (i = 0; i < MAX_LINES; i++)
{
gboolean res;
char *s = g_strconcat (TEST_STRING, endl[newline_type], NULL);
res = g_data_output_stream_put_string (G_DATA_OUTPUT_STREAM (stream), s, NULL, &error);
g_stpcpy ((char*)(lines + i*strlen(s)), s);
g_assert_no_error (error);
g_assert (res == TRUE);
}
/* Byte order testing */
g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
/* compare data */
size = strlen (data);
g_assert_cmpint (size, <, MAX_LINES_BUFF);
g_assert_cmpstr ((char*)data, ==, lines);
g_object_unref (base_stream);
g_object_unref (stream);
g_free (data);
g_free (lines);
}
static void
test_read_lines_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF);
}
static void
test_read_lines_CR (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR);
}
static void
test_read_lines_CR_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
}
enum TestDataType {
TEST_DATA_BYTE = 0,
TEST_DATA_INT16,
TEST_DATA_UINT16,
TEST_DATA_INT32,
TEST_DATA_UINT32,
TEST_DATA_INT64,
TEST_DATA_UINT64
};
static void
test_data_array (guchar *buffer, gsize len,
enum TestDataType data_type, GDataStreamByteOrder byte_order)
{
GOutputStream *stream;
GOutputStream *base_stream;
guchar *stream_data;
GError *error = NULL;
guint pos;
GDataStreamByteOrder native;
gboolean swap;
gboolean res;
/* create objects */
stream_data = g_malloc0 (len);
base_stream = g_memory_output_stream_new (stream_data, len, NULL, NULL);
stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream));
g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), byte_order);
/* Set flag to swap bytes if needed */
native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native);
/* set len to length of buffer cast to actual type */
switch (data_type)
{
case TEST_DATA_BYTE:
break;
case TEST_DATA_INT16:
case TEST_DATA_UINT16:
g_assert_cmpint (len % 2, ==, 0);
case TEST_DATA_INT32:
case TEST_DATA_UINT32:
g_assert_cmpint (len % 4, ==, 0);
case TEST_DATA_INT64:
case TEST_DATA_UINT64:
g_assert_cmpint (len % 8, ==, 0);
len /= 8;
break;
default:
g_assert_not_reached ();
break;
}
/* Write data to the file */
for (pos = 0; pos < len; pos++)
{
switch (data_type)
{
case TEST_DATA_BYTE:
res = g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (stream), buffer[pos], NULL, &error);
break;
case TEST_DATA_INT16:
res = g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (stream), ((gint16 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_UINT16:
res = g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (stream), ((guint16 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_INT32:
res = g_data_output_stream_put_int32 (G_DATA_OUTPUT_STREAM (stream), ((gint32 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_UINT32:
res = g_data_output_stream_put_uint32 (G_DATA_OUTPUT_STREAM (stream), ((guint32 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_INT64:
res = g_data_output_stream_put_int64 (G_DATA_OUTPUT_STREAM (stream), ((gint64 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_UINT64:
res = g_data_output_stream_put_uint64 (G_DATA_OUTPUT_STREAM (stream), ((guint64 *) buffer)[pos], NULL, &error);
break;
default:
g_assert_not_reached ();
break;
}
g_assert_no_error (error);
g_assert_cmpint (res, ==, TRUE);
}
/* Compare data back */
for (pos = 0; pos < len; pos++)
{
switch (data_type)
{
case TEST_DATA_BYTE:
/* swapping unnecessary */
g_assert_cmpint (buffer[pos], ==, stream_data[pos]);
break;
case TEST_DATA_UINT16:
if (swap)
g_assert_cmpint (GUINT16_SWAP_LE_BE (((guint16 *) buffer)[pos]), ==, ((guint16 *) stream_data)[pos]);
else
g_assert_cmpint (((guint16 *) buffer)[pos], ==, ((guint16 *) stream_data)[pos]);
break;
case TEST_DATA_INT16:
if (swap)
g_assert_cmpint ((gint16) GUINT16_SWAP_LE_BE (((gint16 *) buffer)[pos]), ==, ((gint16 *) stream_data)[pos]);
else
g_assert_cmpint (((gint16 *) buffer)[pos], ==, ((gint16 *) stream_data)[pos]);
break;
case TEST_DATA_UINT32:
if (swap)
g_assert_cmpint (GUINT32_SWAP_LE_BE (((guint32 *) buffer)[pos]), ==, ((guint32 *) stream_data)[pos]);
else
g_assert_cmpint (((guint32 *) buffer)[pos], ==, ((guint32 *) stream_data)[pos]);
break;
case TEST_DATA_INT32:
if (swap)
g_assert_cmpint ((gint32) GUINT32_SWAP_LE_BE (((gint32 *) buffer)[pos]), ==, ((gint32 *) stream_data)[pos]);
else
g_assert_cmpint (((gint32 *) buffer)[pos], ==, ((gint32 *) stream_data)[pos]);
break;
case TEST_DATA_UINT64:
if (swap)
g_assert_cmpint (GUINT64_SWAP_LE_BE (((guint64 *) buffer)[pos]), ==, ((guint64 *) stream_data)[pos]);
else
g_assert_cmpint (((guint64 *) buffer)[pos], ==, ((guint64 *) stream_data)[pos]);
break;
case TEST_DATA_INT64:
if (swap)
g_assert_cmpint ((gint64) GUINT64_SWAP_LE_BE (((gint64 *) buffer)[pos]), ==, ((gint64 *) stream_data)[pos]);
else
g_assert_cmpint (((gint64 *) buffer)[pos], ==, ((gint64 *) stream_data)[pos]);
break;
default:
g_assert_not_reached ();
break;
}
}
g_object_unref (base_stream);
g_object_unref (stream);
g_free (stream_data);
}
static void
test_read_int (void)
{
GRand *randomizer;
gpointer buffer;
int i;
randomizer = g_rand_new ();
buffer = g_malloc0(MAX_BYTES_BINARY);
/* Fill in some random data */
for (i = 0; i < MAX_BYTES_BINARY; i++)
{
guchar x = 0;
while (! x) x = (guchar)g_rand_int (randomizer);
*(guchar*)((guchar*)buffer + sizeof (guchar) * i) = x;
}
for (i = 0; i < 3; i++)
{
int j;
for (j = 0; j <= TEST_DATA_UINT64; j++)
test_data_array (buffer, MAX_BYTES_BINARY, j, i);
}
g_rand_free (randomizer);
g_free (buffer);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/data-input-stream/read-lines-LF", test_read_lines_LF);
g_test_add_func ("/data-input-stream/read-lines-CR", test_read_lines_CR);
g_test_add_func ("/data-input-stream/read-lines-CR-LF", test_read_lines_CR_LF);
g_test_add_func ("/data-input-stream/read-int", test_read_int);
return g_test_run();
}

View File

@@ -0,0 +1,259 @@
/*
* Copyright (C) 2008 Red Hat, Inc
*
* 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 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.
*
* Author: Matthias Clasen
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
#include <stdlib.h>
#include <string.h>
static char *basedir;
static GAppInfo *
create_app_info (const char *name)
{
GError *error;
GAppInfo *info;
error = NULL;
info = g_app_info_create_from_commandline ("/usr/bin/true blah",
name,
G_APP_INFO_CREATE_NONE,
&error);
g_assert (error == NULL);
/* this is necessary to ensure that the info is saved */
g_app_info_set_as_default_for_type (info, "application/x-blah", &error);
g_assert (error == NULL);
g_app_info_remove_supports_type (info, "application/x-blah", &error);
g_assert (error == NULL);
g_app_info_reset_type_associations ("application/x-blah");
return info;
}
static void
test_delete (void)
{
GAppInfo *info;
const char *id;
char *filename;
gboolean res;
info = create_app_info ("Blah");
id = g_app_info_get_id (info);
g_assert (id != NULL);
filename = g_build_filename (basedir, "applications", id, NULL);
res = g_file_test (filename, G_FILE_TEST_EXISTS);
g_assert (res);
res = g_app_info_can_delete (info);
g_assert (res);
res = g_app_info_delete (info);
g_assert (res);
res = g_file_test (filename, G_FILE_TEST_EXISTS);
g_assert (!res);
g_object_unref (info);
if (g_file_test ("/usr/share/applications/gedit.desktop", G_FILE_TEST_EXISTS))
{
info = (GAppInfo*)g_desktop_app_info_new ("gedit.desktop");
g_assert (info);
res = g_app_info_can_delete (info);
g_assert (!res);
res = g_app_info_delete (info);
g_assert (!res);
}
}
static void
test_default (void)
{
GAppInfo *info, *info1, *info2, *info3;
GList *list;
GError *error = NULL;
info1 = create_app_info ("Blah1");
info2 = create_app_info ("Blah2");
info3 = create_app_info ("Blah3");
g_app_info_set_as_default_for_type (info1, "application/x-test", &error);
g_assert (error == NULL);
g_app_info_set_as_default_for_type (info2, "application/x-test", &error);
g_assert (error == NULL);
list = g_app_info_get_all_for_type ("application/x-test");
g_assert (g_list_length (list) == 2);
/* check that both are in the list, info2 before info1 */
info = (GAppInfo *)list->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info2)) == 0);
info = (GAppInfo *)list->next->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info1)) == 0);
g_list_foreach (list, (GFunc)g_object_unref, NULL);
g_list_free (list);
/* now try adding something at the end */
g_app_info_add_supports_type (info3, "application/x-test", &error);
g_assert (error == NULL);
list = g_app_info_get_all_for_type ("application/x-test");
g_assert (g_list_length (list) == 3);
/* check that all are in the list, info2, info1, info3 */
info = (GAppInfo *)list->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info2)) == 0);
info = (GAppInfo *)list->next->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info1)) == 0);
info = (GAppInfo *)list->next->next->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info3)) == 0);
g_list_foreach (list, (GFunc)g_object_unref, NULL);
g_list_free (list);
/* now remove info1 again */
g_app_info_remove_supports_type (info1, "application/x-test", &error);
g_assert (error == NULL);
list = g_app_info_get_all_for_type ("application/x-test");
g_assert (g_list_length (list) == 2);
/* check that both are in the list, info2 before info3 */
info = (GAppInfo *)list->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info2)) == 0);
info = (GAppInfo *)list->next->data;
g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info3)) == 0);
g_list_foreach (list, (GFunc)g_object_unref, NULL);
g_list_free (list);
/* now clean it all up */
g_app_info_reset_type_associations ("application/x-test");
list = g_app_info_get_all_for_type ("application/x-test");
g_assert (list == NULL);
g_app_info_delete (info1);
g_app_info_delete (info2);
g_app_info_delete (info3);
g_object_unref (info1);
g_object_unref (info2);
}
static void
cleanup_dir_recurse (GFile *parent, GFile *root)
{
gboolean res;
GError *error;
GFileEnumerator *enumerator;
GFileInfo *info;
GFile *descend;
char *relative_path;
g_assert (root != NULL);
error = NULL;
enumerator =
g_file_enumerate_children (parent, "*",
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
&error);
if (! enumerator)
return;
error = NULL;
info = g_file_enumerator_next_file (enumerator, NULL, &error);
while ((info) && (!error))
{
descend = g_file_get_child (parent, g_file_info_get_name (info));
g_assert (descend != NULL);
relative_path = g_file_get_relative_path (root, descend);
g_assert (relative_path != NULL);
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
cleanup_dir_recurse (descend, root);
error = NULL;
res = g_file_delete (descend, NULL, &error);
g_assert_cmpint (res, ==, TRUE);
g_object_unref (descend);
error = NULL;
info = g_file_enumerator_next_file (enumerator, NULL, &error);
}
g_assert (error == NULL);
error = NULL;
res = g_file_enumerator_close (enumerator, NULL, &error);
g_assert_cmpint (res, ==, TRUE);
g_assert (error == NULL);
}
static void
cleanup_subdirs (const char *base_dir)
{
GFile *base, *file;
base = g_file_new_for_path (base_dir);
file = g_file_get_child (base, "applications");
cleanup_dir_recurse (file, file);
g_object_unref (file);
file = g_file_get_child (base, "mime");
cleanup_dir_recurse (file, file);
g_object_unref (file);
}
int
main (int argc,
char *argv[])
{
gint result;
g_type_init ();
g_test_init (&argc, &argv, NULL);
basedir = g_get_current_dir ();
g_setenv ("XDG_DATA_HOME", basedir, TRUE);
cleanup_subdirs (basedir);
g_test_add_func ("/desktop-app-info/delete", test_delete);
g_test_add_func ("/desktop-app-info/default", test_default);
result = g_test_run ();
cleanup_subdirs (basedir);
return result;
}

73
gio/tests/echo-server.c Normal file
View File

@@ -0,0 +1,73 @@
#include <gio/gio.h>
#include <string.h>
#define MESSAGE "Welcome to the echo service!\n"
int port = 7777;
static GOptionEntry cmd_entries[] = {
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
"Local port to bind to", NULL},
{NULL}
};
static gboolean
handler (GThreadedSocketService *service,
GSocketConnection *connection,
GSocketListener *listener,
gpointer user_data)
{
GOutputStream *out;
GInputStream *in;
char buffer[1024];
gssize size;
out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
g_output_stream_write_all (out, MESSAGE, strlen (MESSAGE),
NULL, NULL, NULL);
while (0 < (size = g_input_stream_read (in, buffer,
sizeof buffer, NULL, NULL)))
g_output_stream_write (out, buffer, size, NULL, NULL);
return TRUE;
}
int
main (int argc, char *argv[])
{
GSocketService *service;
GOptionContext *context;
GError *error = NULL;
g_type_init ();
g_thread_init (NULL);
context = g_option_context_new (" - Test GSocket server stuff");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
service = g_threaded_socket_service_new (10);
if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service),
port,
NULL,
&error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
g_print ("Echo service listening on port %d\n", port);
g_signal_connect (service, "run", G_CALLBACK (handler), NULL);
g_main_loop_run (g_main_loop_new (NULL, FALSE));
g_assert_not_reached ();
}

239
gio/tests/filter-streams.c Normal file
View File

@@ -0,0 +1,239 @@
/*
* Copyright © 2009 Codethink Limited
*
* This program 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 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include <glib/glib.h>
#include <gio/gio.h>
static void
test_input_filter (void)
{
GInputStream *base, *f1, *f2;
g_test_bug ("568394");
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
f1 = g_buffered_input_stream_new (base);
f2 = g_buffered_input_stream_new (base);
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (f1), FALSE);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f1));
g_assert (!g_input_stream_is_closed (f2));
g_object_unref (f1);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f2));
g_object_unref (f2);
g_assert (g_input_stream_is_closed (base));
g_object_unref (base);
}
static void
test_output_filter (void)
{
GOutputStream *base, *f1, *f2;
base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
f1 = g_buffered_output_stream_new (base);
f2 = g_buffered_output_stream_new (base);
g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (f1), FALSE);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f1));
g_assert (!g_output_stream_is_closed (f2));
g_object_unref (f1);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f2));
g_object_unref (f2);
g_assert (g_output_stream_is_closed (base));
g_object_unref (base);
}
gpointer expected_obj;
gpointer expected_data;
gboolean callback_happened;
static void
in_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
g_assert (object == expected_obj);
g_assert (user_data == expected_data);
g_assert (callback_happened == FALSE);
g_input_stream_close_finish (expected_obj, result, &error);
g_assert (error == NULL);
callback_happened = TRUE;
}
static void
test_input_async (void)
{
GInputStream *base, *f1, *f2;
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
f1 = g_buffered_input_stream_new (base);
f2 = g_buffered_input_stream_new (base);
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (f1), FALSE);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f1));
g_assert (!g_input_stream_is_closed (f2));
expected_obj = f1;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_input_stream_close_async (f1, 0, NULL, in_cb, expected_data);
g_assert (callback_happened == FALSE);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
g_assert (callback_happened == TRUE);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f1);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f2));
expected_obj = f2;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_input_stream_close_async (f2, 0, NULL, in_cb, expected_data);
g_assert (callback_happened == FALSE);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
g_assert (callback_happened == TRUE);
g_assert (g_input_stream_is_closed (base));
g_assert (g_input_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f2);
g_assert (g_input_stream_is_closed (base));
g_object_unref (base);
}
static void
out_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
g_assert (object == expected_obj);
g_assert (user_data == expected_data);
g_assert (callback_happened == FALSE);
g_output_stream_close_finish (expected_obj, result, &error);
g_assert (error == NULL);
callback_happened = TRUE;
}
static void
test_output_async (void)
{
GOutputStream *base, *f1, *f2;
base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
f1 = g_buffered_output_stream_new (base);
f2 = g_buffered_output_stream_new (base);
g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (f1), FALSE);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f1));
g_assert (!g_output_stream_is_closed (f2));
expected_obj = f1;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_output_stream_close_async (f1, 0, NULL, out_cb, expected_data);
g_assert (callback_happened == FALSE);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
g_assert (callback_happened == TRUE);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f1);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f2));
expected_obj = f2;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_output_stream_close_async (f2, 0, NULL, out_cb, expected_data);
g_assert (callback_happened == FALSE);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, FALSE);
g_assert (callback_happened == TRUE);
g_assert (g_output_stream_is_closed (base));
g_assert (g_output_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f2);
g_assert (g_output_stream_is_closed (base));
g_object_unref (base);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_type_init ();
g_test_add_func ("/filter-stream/input", test_input_filter);
g_test_add_func ("/filter-stream/output", test_output_filter);
g_test_add_func ("/filter-stream/async-input", test_input_async);
g_test_add_func ("/filter-stream/async-output", test_output_async);
return g_test_run();
}

125
gio/tests/g-file-info.c Normal file
View File

@@ -0,0 +1,125 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define TEST_NAME "Prilis zlutoucky kun"
#define TEST_DISPLAY_NAME "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"
#define TEST_SIZE 0xFFFFFFF0
static void
test_assigned_values (GFileInfo *info)
{
const char *name, *display_name, *mistake;
guint64 size;
GFileType type;
/* Test for attributes presence */
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME) == TRUE);
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME) == TRUE);
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE) == TRUE);
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME) == FALSE);
/* Retrieve data back and compare */
name = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME);
display_name = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
mistake = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
type = g_file_info_get_file_type (info);
g_assert_cmpstr (name, ==, TEST_NAME);
g_assert_cmpstr (display_name, ==, TEST_DISPLAY_NAME);
g_assert (mistake == NULL);
g_assert_cmpint (size, ==, TEST_SIZE);
g_assert_cmpstr (name, ==, g_file_info_get_name (info));
g_assert_cmpstr (display_name, ==, g_file_info_get_display_name (info));
g_assert_cmpint (size, ==, g_file_info_get_size (info) );
g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY);
}
static void
test_g_file_info (void)
{
GFileInfo *info;
GFileInfo *info_dup;
GFileInfo *info_copy;
char **attr_list;
info = g_file_info_new ();
/* Test for empty instance */
attr_list = g_file_info_list_attributes (info, NULL);
g_assert (attr_list != NULL);
g_assert (*attr_list == NULL);
g_file_info_set_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME, TEST_NAME);
g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, TEST_DISPLAY_NAME);
g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE, TEST_SIZE);
g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
/* The attr list should not be empty now */
attr_list = g_file_info_list_attributes (info, NULL);
g_assert (attr_list != NULL);
g_assert (*attr_list != NULL);
test_assigned_values (info);
/* Test dups */
info_dup = g_file_info_dup (info);
g_assert (info_dup != NULL);
test_assigned_values (info_dup);
info_copy = g_file_info_new ();
g_file_info_copy_into (info_dup, info_copy);
g_assert (info_copy != NULL);
test_assigned_values (info_copy);
/* Test remove attribute */
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == FALSE);
g_file_info_set_attribute_int32 (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 10);
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == TRUE);
g_file_info_remove_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER);
g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == FALSE);
g_object_unref (info);
g_object_unref (info_dup);
g_object_unref (info_copy);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/g-file-info/test_g_file_info", test_g_file_info);
return g_test_run();
}

538
gio/tests/g-file.c Normal file
View File

@@ -0,0 +1,538 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
struct TestPathsWithOper {
const char *path1;
gboolean equal;
gboolean use_uri;
const char *path2;
const char *path3;
};
/* TODO:
* - test on Windows
*
**/
static void
test_g_file_new_null (void)
{
const char *paths[] = {"/",
"/tmp///",
"/non-existent-file",
"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88",
NULL
};
const char *uris[] = {"file:///",
"file:///tmp///",
"non-existent-uri:///some-dir/",
"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88",
NULL
};
GFile *file = NULL;
int i = 0;
while (paths[i])
{
file = g_file_new_for_path (paths[i++]);
g_assert (file != NULL);
g_object_unref (file);
}
i = 0;
while (uris[i])
{
file = g_file_new_for_uri (uris[i++]);
g_assert (file != NULL);
g_object_unref(file);
}
}
static gboolean
compare_two_files (const gboolean use_uri, const char *path1, const char *path2)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
gboolean equal;
if (use_uri)
{
file1 = g_file_new_for_uri (path1);
file2 = g_file_new_for_uri (path2);
}
else
{
file1 = g_file_new_for_path (path1);
file2 = g_file_new_for_path (path2);
}
g_assert (file1 != NULL);
g_assert (file2 != NULL);
equal = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
return equal;
}
static void
test_g_file_new_for_path (void)
{
const struct TestPathsWithOper cmp_paths[] =
{
{"/", TRUE, 0, "/./"},
{"//", TRUE, 0, "//"},
{"//", TRUE, 0, "//./"},
{"/", TRUE, 0, "/.//"},
{"/", TRUE, 0, "/././"},
{"/tmp", TRUE, 0, "/tmp/d/../"},
{"/", TRUE, 0, "/somedir/../"},
{"/", FALSE, 0, "/somedir/.../"},
{"//tmp/dir1", TRUE, 0, "//tmp/dir1"},
{"/tmp/dir1", TRUE, 0, "///tmp/dir1"},
{"/tmp/dir1", TRUE, 0, "////tmp/dir1"},
{"/tmp/dir1", TRUE, 0, "/tmp/./dir1"},
{"/tmp/dir1", TRUE, 0, "/tmp//dir1"},
{"/tmp/dir1", TRUE, 0, "/tmp///dir1///"},
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, 0, "/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/"}
};
guint i;
for (i = 0; i < G_N_ELEMENTS (cmp_paths); i++)
{
gboolean equal = compare_two_files (FALSE, cmp_paths[i].path1, cmp_paths[i].path2);
g_assert_cmpint (equal, ==, cmp_paths[i].equal);
}
}
static void
test_g_file_new_for_uri (void)
{
const struct TestPathsWithOper cmp_uris[] = {
{"file:///", TRUE, 0, "file:///./"},
{"file:////", TRUE, 0, "file:////"},
{"file:////", TRUE, 0, "file:////./"},
{"file:///", TRUE, 0, "file:///.//"},
{"file:///", TRUE, 0, "file:///././"},
{"file:///tmp", TRUE, 0, "file:///tmp/d/../"},
{"file:///", TRUE, 0, "file:///somedir/../"},
{"file:///", FALSE, 0, "file:///somedir/.../"},
{"file:////tmp/dir1", TRUE, 0, "file:////tmp/dir1"},
{"file:///tmp/dir1", TRUE, 0, "file:///tmp/./dir1"},
{"file:///tmp/dir1", TRUE, 0, "file:///tmp//dir1"},
{"file:///tmp/dir1", TRUE, 0, "file:///tmp///dir1///"},
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, 0, "file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/"}
};
guint i;
for (i = 0; i < G_N_ELEMENTS (cmp_uris); i++)
{
gboolean equal = compare_two_files (TRUE, cmp_uris[i].path1, cmp_uris[i].path2);
g_assert_cmpint (equal, ==, cmp_uris[i].equal);
}
}
static gboolean
dup_equals (const gboolean use_uri, const char *path)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
gboolean equal;
if (use_uri)
file1 = g_file_new_for_uri (path);
else
file1 = g_file_new_for_path (path);
g_assert (file1 != NULL);
file2 = g_file_dup (file1);
g_assert (file2 != NULL);
equal = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
return equal;
}
static void
test_g_file_dup (void)
{
const struct TestPathsWithOper dup_paths[] =
{
{"/", 0, FALSE, ""},
{"file:///", 0, TRUE, ""},
{"totalnonsense", 0, FALSE, ""},
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, ""},
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", 0, TRUE, ""},
};
guint i;
for (i = 0; i < G_N_ELEMENTS (dup_paths); i++)
{
gboolean equal = dup_equals (dup_paths[i].use_uri, dup_paths[i].path1);
g_assert (equal == TRUE);
}
}
static gboolean
parse_check_utf8 (const gboolean use_uri, const char *path, const char *result_parse_name)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
char *parsed_name;
gboolean is_utf8_valid;
gboolean equal;
if (use_uri)
file1 = g_file_new_for_uri (path);
else
file1 = g_file_new_for_path (path);
g_assert (file1 != NULL);
parsed_name = g_file_get_parse_name (file1);
g_assert (parsed_name != NULL);
/* UTF-8 validation */
is_utf8_valid = g_utf8_validate (parsed_name, -1, NULL);
g_assert (is_utf8_valid == TRUE);
if (result_parse_name)
g_assert_cmpstr (parsed_name, ==, result_parse_name);
file2 = g_file_parse_name (parsed_name);
g_assert (file2 != NULL);
equal = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
g_free (parsed_name);
return equal;
}
static void
test_g_file_get_parse_name_utf8 (void)
{
const struct TestPathsWithOper strings[] =
{
{"/", 0, FALSE, "/"},
{"file:///", 0, TRUE, "/"},
{"totalnonsense", 0, FALSE, NULL},
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, NULL /* Depends on local file encoding */},
{"file:///invalid%08/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, TRUE, "file:///invalid%08/UTF-8%20p\xc5\x99\xc3\xadli\xc5\xa1%20\xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd%20k\xc5\xaf\xc5\x88"},
};
guint i;
for (i = 0; i < G_N_ELEMENTS (strings); i++)
{
gboolean equal = parse_check_utf8 (strings[i].use_uri, strings[i].path1, strings[i].path2);
g_assert (equal == TRUE);
}
}
static char *
resolve_arg (const gboolean is_uri_only, const char *arg)
{
GFile *file1 = NULL;
char *uri = NULL;
char *path = NULL;
char *s = NULL;
file1 = g_file_new_for_commandline_arg (arg);
g_assert (file1 != NULL);
/* Test if we get URI string */
uri = g_file_get_uri (file1);
g_assert_cmpstr (uri, !=, NULL);
g_print ("%s\n",uri);
/* Test if we get correct value of the local path */
path = g_file_get_path (file1);
if (is_uri_only)
g_assert_cmpstr (path, ==, NULL);
else
g_assert (g_path_is_absolute (path) == TRUE);
/* Get the URI scheme and compare it with expected one */
s = g_file_get_uri_scheme (file1);
g_object_unref (file1);
g_free (uri);
g_free (path);
return s;
}
static void
test_g_file_new_for_commandline_arg (void)
{
/* TestPathsWithOper.use_uri represents IsURIOnly here */
const struct TestPathsWithOper arg_data[] =
{
{"./", 0, FALSE, "file"},
{"../", 0, FALSE, "file"},
{"/tmp", 0, FALSE, "file"},
{"//UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "file"},
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, FALSE, "file"},
#if 0
{"http://www.gtk.org/", 0, TRUE, "http"},
{"ftp://user:pass@ftp.gimp.org/", 0, TRUE, "ftp"},
#endif
};
GFile *file;
char *resolved;
char *cwd;
guint i;
for (i = 0; i < G_N_ELEMENTS (arg_data); i++)
{
char *s = resolve_arg (arg_data[i].use_uri, arg_data[i].path1);
g_assert_cmpstr (s, ==, arg_data[i].path2);
g_free (s);
}
/* Manual test for getting correct cwd */
file = g_file_new_for_commandline_arg ("./");
resolved = g_file_get_path (file);
cwd = g_get_current_dir ();
g_assert_cmpstr (resolved, ==, cwd);
g_object_unref (file);
g_free (resolved);
g_free (cwd);
}
static char*
get_relative_path (const gboolean use_uri, const gboolean should_have_prefix, const char *dir1, const char *dir2)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
GFile *file3 = NULL;
gboolean has_prefix = FALSE;
char *relative_path = NULL;
if (use_uri)
{
file1 = g_file_new_for_uri (dir1);
file2 = g_file_new_for_uri (dir2);
}
else
{
file1 = g_file_new_for_path (dir1);
file2 = g_file_new_for_path (dir2);
}
g_assert (file1 != NULL);
g_assert (file2 != NULL);
has_prefix = g_file_has_prefix (file2, file1);
g_print ("%s %s\n", dir1, dir2);
g_assert (has_prefix == should_have_prefix);
relative_path = g_file_get_relative_path (file1, file2);
if (should_have_prefix)
{
g_assert (relative_path != NULL);
file3 = g_file_resolve_relative_path (file1, relative_path);
g_assert (g_file_equal (file2, file3) == TRUE);
}
if (file1)
g_object_unref (file1);
if (file2)
g_object_unref (file2);
if (file3)
g_object_unref (file3);
return relative_path;
}
static void
test_g_file_has_prefix (void)
{
/* TestPathsWithOper.equal represents here if the dir belongs to the directory structure */
const struct TestPathsWithOper dirs[] =
{
/* path1 equal uri path2 path3 */
{"/dir1", TRUE, FALSE, "/dir1/dir2/dir3/", "dir2/dir3"},
{"/dir1/", TRUE, FALSE, "/dir1/dir2/dir3/", "dir2/dir3"},
{"/dir1", TRUE, FALSE, "/dir1/dir2/dir3", "dir2/dir3"},
{"/dir1/", TRUE, FALSE, "/dir1/dir2/dir3", "dir2/dir3"},
{"/tmp/", FALSE, FALSE, "/something/", NULL},
{"/dir1/dir2", FALSE, FALSE, "/dir1/", NULL},
{"//dir1/new", TRUE, FALSE, "//dir1/new/dir2/dir3", "dir2/dir3"},
{"/dir/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, FALSE, "/dir/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/dir2", "dir2"},
{"file:///dir1", TRUE, TRUE, "file:///dir1/dir2/dir3/", "dir2/dir3"},
{"file:///dir1/", TRUE, TRUE, "file:///dir1/dir2/dir3/", "dir2/dir3"},
{"file:///dir1", TRUE, TRUE, "file:///dir1/dir2/dir3", "dir2/dir3"},
{"file:///dir1/", TRUE, TRUE, "file:///dir1/dir2/dir3", "dir2/dir3"},
{"file:///tmp/", FALSE, TRUE, "file:///something/", NULL},
{"file:///dir1/dir2", FALSE, TRUE, "file:///dir1/", NULL},
{"file:////dir1/new", TRUE, TRUE, "file:////dir1/new/dir2/dir3", "dir2/dir3"},
{"file:///dir/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, TRUE, "file:///dir/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/dir2", "dir2"},
#if 0
{"dav://www.gtk.org/plan/", TRUE, TRUE, "dav://www.gtk.org/plan/meetings/20071218.txt", "meetings/20071218.txt"},
{"dav://www.gtk.org/plan/meetings", TRUE, TRUE, "dav://www.gtk.org/plan/meetings/20071218.txt", "20071218.txt"},
#endif
};
guint i;
for (i = 0; i < G_N_ELEMENTS (dirs); i++)
{
char *s = get_relative_path (dirs[i].use_uri, dirs[i].equal, dirs[i].path1, dirs[i].path2);
if (dirs[i].equal)
g_assert_cmpstr (s, ==, dirs[i].path3);
g_free (s);
}
}
static void
roundtrip_parent_child (const gboolean use_uri, const gboolean under_root_descending,
const char *path, const char *dir_holder)
{
GFile *files[6] = {NULL};
guint i;
if (use_uri)
{
files[0] = g_file_new_for_uri (path);
files[1] = g_file_new_for_uri (path);
}
else
{
files[0] = g_file_new_for_path (path);
files[1] = g_file_new_for_path (path);
}
g_assert (files[0] != NULL);
g_assert (files[1] != NULL);
files[2] = g_file_get_child (files[1], dir_holder);
g_assert (files[2] != NULL);
files[3] = g_file_get_parent (files[2]);
g_assert (files[3] != NULL);
g_assert (g_file_equal (files[3], files[0]) == TRUE);
files[4] = g_file_get_parent (files[3]);
/* Don't go lower beyond the root */
if (under_root_descending)
g_assert (files[4] == NULL);
else
{
g_assert (files[4] != NULL);
files[5] = g_file_get_child (files[4], dir_holder);
g_assert (files[5] != NULL);
g_assert (g_file_equal (files[5], files[0]) == TRUE);
}
for (i = 0; i < G_N_ELEMENTS (files); i++)
{
if (files[i])
g_object_unref (files[i]);
}
}
static void
test_g_file_get_parent_child (void)
{
const struct TestPathsWithOper paths[] =
{
/* path root_desc uri dir_holder */
{"/dir1/dir", FALSE, FALSE, "dir"},
{"/dir", FALSE, FALSE, "dir"},
{"/", TRUE, FALSE, "dir"},
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", FALSE, FALSE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"},
{"file:///dir1/dir", FALSE, TRUE, "dir"},
{"file:///dir", FALSE, TRUE, "dir"},
{"file:///", TRUE, TRUE, "dir"},
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", FALSE, TRUE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"},
{"dav://www.gtk.org/plan/meetings", FALSE, TRUE, "meetings"},
};
guint i;
for (i = 0; i < G_N_ELEMENTS (paths); i++)
roundtrip_parent_child (paths[i].use_uri, paths[i].equal, paths[i].path1, paths[i].path2);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
/* Testing whether g_file_new_for_path() or g_file_new_for_uri() always returns non-NULL result */
g_test_add_func ("/g-file/test_g_file_new_null", test_g_file_new_null);
/* Testing whether the g_file_new_for_path() correctly canonicalizes strings and two files equals (g_file_equal()) */
g_test_add_func ("/g-file/test_g_file_new_for_path", test_g_file_new_for_path);
/* Testing whether the g_file_new_for_uri() correctly canonicalizes strings and two files equals (g_file_equal()) */
g_test_add_func ("/g-file/test_g_file_new_for_uri", test_g_file_new_for_uri);
/* Testing g_file_dup() equals original file via g_file_equal() */
g_test_add_func ("/g-file/test_g_file_dup", test_g_file_dup);
/* Testing g_file_get_parse_name() to return correct UTF-8 string */
g_test_add_func ("/g-file/test_g_file_get_parse_name_utf8", test_g_file_get_parse_name_utf8);
/* Testing g_file_new_for_commandline_arg() for correct relavive path resolution and correct path/URI guess */
g_test_add_func ("/g-file/test_g_file_new_for_commandline_arg", test_g_file_new_for_commandline_arg);
/* Testing g_file_has_prefix(), g_file_get_relative_path() and g_file_resolve_relative_path() to return and process correct relative paths */
g_test_add_func ("/g-file/test_g_file_has_prefix", test_g_file_has_prefix);
/* Testing g_file_get_parent() and g_file_get_child() */
g_test_add_func ("/g-file/test_g_file_get_parent_child", test_g_file_get_parent_child);
return g_test_run();
}

245
gio/tests/g-icon.c Normal file
View File

@@ -0,0 +1,245 @@
/* GLib testing framework examples and tests
*
* Copyright (C) 2008 Red Hat, Inc.
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*
* Authors: David Zeuthen <davidz@redhat.com>
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_g_icon_serialize (void)
{
GIcon *icon;
GIcon *icon2;
GIcon *icon3;
GIcon *icon4;
GIcon *icon5;
GEmblem *emblem1;
GEmblem *emblem2;
const char *uri;
GFile *location;
char *data;
GError *error;
error = NULL;
/* check that GFileIcon and GThemedIcon serialize to the encoding specified */
uri = "file:///some/native/path/to/an/icon.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "/some/native/path/to/an/icon.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
uri = "file:///some/native/path/to/an/icon with spaces.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "/some/native/path/to/an/icon with spaces.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
uri = "sftp:///some/non-native/path/to/an/icon.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///some/non-native/path/to/an/icon.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
#if 0
uri = "sftp:///some/non-native/path/to/an/icon with spaces.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///some/non-native/path/to/an/icon%20with%20spaces.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
#endif
icon = g_themed_icon_new ("network-server");
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "network-server");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
/* Check that we can serialize from well-known specified formats */
icon = g_icon_new_for_string ("network-server%", &error);
g_assert_no_error (error);
icon2 = g_themed_icon_new ("network-server%");
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
icon = g_icon_new_for_string ("/path/to/somewhere.png", &error);
g_assert_no_error (error);
location = g_file_new_for_commandline_arg ("/path/to/somewhere.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
icon = g_icon_new_for_string ("/path/to/somewhere with whitespace.png", &error);
g_assert_no_error (error);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "/path/to/somewhere with whitespace.png");
g_free (data);
location = g_file_new_for_commandline_arg ("/path/to/somewhere with whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
location = g_file_new_for_commandline_arg ("/path/to/somewhere%20with%20whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (!g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
g_object_unref (icon);
icon = g_icon_new_for_string ("sftp:///path/to/somewhere.png", &error);
g_assert_no_error (error);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///path/to/somewhere.png");
g_free (data);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
#if 0
icon = g_icon_new_for_string ("sftp:///path/to/somewhere with whitespace.png", &error);
g_assert_no_error (error);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///path/to/somewhere%20with%20whitespace.png");
g_free (data);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere with whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere%20with%20whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
g_object_unref (icon);
#endif
/* Check that GThemedIcon serialization works */
icon = g_themed_icon_new ("network-server");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new ("icon name with whitespace");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new_with_default_fallbacks ("network-server-xyz");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
/* Check that GEmblemedIcon serialization works */
icon = g_themed_icon_new ("face-smirk");
icon2 = g_themed_icon_new ("emblem-important");
g_themed_icon_append_name (G_THEMED_ICON (icon2), "emblem-shared");
location = g_file_new_for_uri ("file:///some/path/somewhere.png");
icon3 = g_file_icon_new (location);
g_object_unref (location);
emblem1 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_DEVICE);
emblem2 = g_emblem_new_with_origin (icon3, G_EMBLEM_ORIGIN_LIVEMETADATA);
icon4 = g_emblemed_icon_new (icon, emblem1);
g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2);
data = g_icon_to_string (icon4);
icon5 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon4, icon5));
g_object_unref (emblem1);
g_object_unref (emblem2);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (icon3);
g_object_unref (icon4);
g_object_unref (icon5);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/g-icon/serialize", test_g_icon_serialize);
return g_test_run();
}

183
gio/tests/httpd.c Normal file
View File

@@ -0,0 +1,183 @@
#include <gio/gio.h>
#include <string.h>
static int port = 8080;
static char *root = NULL;
static GOptionEntry cmd_entries[] = {
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
"Local port to bind to", NULL},
{NULL}
};
static void
send_error (GOutputStream *out,
int error_code,
const char *reason)
{
char *res;
res = g_strdup_printf ("HTTP/1.0 %d %s\r\n\r\n"
"<html><head><title>%d %s</title></head>"
"<body>%s</body></html>",
error_code, reason,
error_code, reason,
reason);
g_output_stream_write_all (out, res, strlen (res), NULL, NULL, NULL);
g_free (res);
}
static gboolean
handler (GThreadedSocketService *service,
GSocketConnection *connection,
GSocketListener *listener,
gpointer user_data)
{
GOutputStream *out;
GInputStream *in;
GFileInputStream *file_in;
GDataInputStream *data;
char *line, *escaped, *tmp, *query, *unescaped, *path, *version;
GFile *f;
GError *error;
GFileInfo *info;
GString *s;
in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
data = g_data_input_stream_new (in);
/* Be tolerant of input */
g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_ANY);
line = g_data_input_stream_read_line (data, NULL, NULL, NULL);
if (line == NULL)
{
send_error (out, 400, "Invalid request");
goto out;
}
if (!g_str_has_prefix (line, "GET "))
{
send_error (out, 501, "Only GET implemented");
goto out;
}
escaped = line + 4; /* Skip "GET " */
version = NULL;
tmp = strchr (escaped, ' ');
if (tmp != NULL)
{
*tmp = 0;
version = tmp + 1;
}
query = strchr (escaped, '?');
if (query != NULL)
*query++ = 0;
unescaped = g_uri_unescape_string (escaped, NULL);
path = g_build_filename (root, unescaped, NULL);
g_free (unescaped);
f = g_file_new_for_path (path);
g_free (path);
error = NULL;
file_in = g_file_read (f, NULL, &error);
if (file_in == NULL)
{
send_error (out, 404, error->message);
g_error_free (error);
goto out;
}
s = g_string_new ("HTTP/1.0 200 OK\r\n");
info = g_file_input_stream_query_info (file_in,
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
NULL, NULL);
if (info)
{
const char *content_type;
char *mime_type;
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
g_string_append_printf (s, "Content-Length: %"G_GINT64_FORMAT"\r\n",
g_file_info_get_size (info));
content_type = g_file_info_get_content_type (info);
if (content_type)
{
mime_type = g_content_type_get_mime_type (content_type);
if (mime_type)
{
g_string_append_printf (s, "Content-Type: %s\r\n",
mime_type);
g_free (mime_type);
}
}
}
g_string_append (s, "\r\n");
if (g_output_stream_write_all (out,
s->str, s->len,
NULL, NULL, NULL))
{
g_output_stream_splice (out,
G_INPUT_STREAM (file_in),
0, NULL, NULL);
}
g_string_free (s, TRUE);
g_input_stream_close (G_INPUT_STREAM (file_in), NULL, NULL);
g_object_unref (file_in);
out:
g_object_unref (data);
return TRUE;
}
int
main (int argc, char *argv[])
{
GSocketService *service;
GOptionContext *context;
GError *error = NULL;
g_type_init ();
g_thread_init (NULL);
context = g_option_context_new ("<http root dir> - Simple HTTP server");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (argc != 2)
{
g_printerr ("Root directory not specified\n");
return 1;
}
root = g_strdup (argv[1]);
service = g_threaded_socket_service_new (10);
if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service),
port,
NULL,
&error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
g_print ("Http server listening on port %d\n", port);
g_signal_connect (service, "run", G_CALLBACK (handler), NULL);
g_main_loop_run (g_main_loop_new (NULL, FALSE));
g_assert_not_reached ();
}

1211
gio/tests/live-g-file.c Normal file

File diff suppressed because it is too large Load Diff

27
gio/tests/live-g-file.txt Normal file
View File

@@ -0,0 +1,27 @@
Before you start testing it would be good to explain how it works.
The script works in three modes:
1. read-only (no special arguments) - suitable for read-only backends. Just
create the sample structure using the second mode, pack it (tar -p is
preffered to preserve unix modes) and put it on a reachable place.
2. create-structure - only creates reference structure for later testing
in read-only mode
3. write mode - full test suite, creates testing structure and performs all
read and write tests. Please note the delete/move tests are included
in this mode and target directory structure is unusable after the script
is finished.
To see the list of available parameters just run 'live-g-file --help'
Notes:
- it's advised to clean target directory first, otherwise some tests might fail
(i.e. the tests creating testing structure)
Tested:
- local filesystem (/tmp/...)
- file:// uri (file:///tmp/...)
- locatest:// gvfs backend (localtest:///tmp/...)
- FAT16 filesystem (no POSIX extensions)

View File

@@ -0,0 +1,78 @@
/* GLib testing framework examples and tests
* Copyright (C) 2007 Imendio AB
* Authors: Tim Janik
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_read_chunks (void)
{
const char *data1 = "abcdefghijklmnopqrstuvwxyz";
const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *result = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buffer[128];
gsize bytes_read, pos, len, chunk_size;
GError *error = NULL;
GInputStream *stream;
gboolean res;
stream = g_memory_input_stream_new ();
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
data1, -1, NULL);
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
data2, -1, NULL);
len = strlen (data1) + strlen (data2);
for (chunk_size = 1; chunk_size < len - 1; chunk_size++)
{
pos = 0;
while (pos < len)
{
bytes_read = g_input_stream_read (stream, buffer, chunk_size, NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (bytes_read, ==, MIN (chunk_size, len - pos));
g_assert (strncmp (buffer, result + pos, bytes_read) == 0);
pos += bytes_read;
}
g_assert_cmpint (pos, ==, len);
res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
g_assert_cmpint (res, ==, TRUE);
g_assert_no_error (error);
}
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/memory-input-stream/read-chunks", test_read_chunks);
return g_test_run();
}

View File

@@ -0,0 +1,100 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Author: Matthias Clasen
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_truncate (void)
{
GOutputStream *mo;
GDataOutputStream *o;
int i;
GError *error = NULL;
g_test_bug ("540423");
mo = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
o = g_data_output_stream_new (mo);
for (i = 0; i < 1000; i++)
{
g_data_output_stream_put_byte (o, 1, NULL, &error);
g_assert_no_error (error);
}
g_seekable_truncate (G_SEEKABLE (mo), 0, NULL, &error);
g_assert_no_error (error);
for (i = 0; i < 2000; i++)
{
g_data_output_stream_put_byte (o, 1, NULL, &error);
g_assert_no_error (error);
}
g_object_unref (o);
g_object_unref (mo);
}
static void
test_data_size (void)
{
GOutputStream *mo;
GDataOutputStream *o;
int pos;
g_test_bug ("540459");
mo = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
o = g_data_output_stream_new (mo);
g_data_output_stream_put_byte (o, 1, NULL, NULL);
pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
g_assert_cmpint (pos, ==, 1);
g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_CUR, NULL, NULL);
pos = g_seekable_tell (G_SEEKABLE (mo));
g_assert_cmpint (pos, ==, 1);
g_test_bug ("540461");
g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_SET, NULL, NULL);
pos = g_seekable_tell (G_SEEKABLE (mo));
g_assert_cmpint (pos, ==, 0);
pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
g_assert_cmpint (pos, ==, 1);
g_object_unref (o);
g_object_unref (mo);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/memory-output-stream/truncate", test_truncate);
g_test_add_func ("/memory-output-stream/get-data-size", test_data_size);
return g_test_run();
}

293
gio/tests/readwrite.c Normal file
View File

@@ -0,0 +1,293 @@
#include <glib/glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <unistd.h>
#include <string.h>
static const char *original_data = "This is some test data that we can put in a file...";
static const char *new_data = "new data..";
static void
verify_pos (GIOStream *iostream, goffset expected_pos)
{
goffset pos;
pos = g_seekable_tell (G_SEEKABLE (iostream));
g_assert_cmpint (pos, ==, expected_pos);
pos = g_seekable_tell (G_SEEKABLE (g_io_stream_get_input_stream (iostream)));
g_assert_cmpint (pos, ==, expected_pos);
pos = g_seekable_tell (G_SEEKABLE (g_io_stream_get_output_stream (iostream)));
g_assert_cmpint (pos, ==, expected_pos);
}
static void
verify_iostream (GFileIOStream *file_iostream)
{
gboolean res;
GIOStream *iostream;
GError *error;
GInputStream *in;
GOutputStream *out;
char buffer[1024];
gsize n_bytes;
char *modified_data;
iostream = G_IO_STREAM (file_iostream);
verify_pos (iostream, 0);
in = g_io_stream_get_input_stream (iostream);
out = g_io_stream_get_output_stream (iostream);
res = g_input_stream_read_all (in, buffer, 20, &n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint ((int)n_bytes, ==, 20);
g_assert (memcmp (buffer, original_data, 20) == 0);
verify_pos (iostream, 20);
res = g_seekable_seek (G_SEEKABLE (iostream),
-10, G_SEEK_END,
NULL, NULL);
g_assert (res);
verify_pos (iostream, strlen (original_data) - 10);
res = g_input_stream_read_all (in, buffer, 20, &n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint ((int)n_bytes, ==, 10);
g_assert (memcmp (buffer, original_data + strlen (original_data) - 10, 10) == 0);
verify_pos (iostream, strlen (original_data));
res = g_seekable_seek (G_SEEKABLE (iostream),
10, G_SEEK_SET,
NULL, NULL);
verify_pos (iostream, 10);
res = g_output_stream_write_all (out, new_data, strlen (new_data),
&n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint (n_bytes, ==, strlen (new_data));
verify_pos (iostream, 10 + strlen (new_data));
res = g_seekable_seek (G_SEEKABLE (iostream),
0, G_SEEK_SET,
NULL, NULL);
g_assert (res);
verify_pos (iostream, 0);
res = g_input_stream_read_all (in, buffer, strlen (original_data), &n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint ((int)n_bytes, ==, strlen (original_data));
buffer[n_bytes] = 0;
modified_data = g_strdup (original_data);
memcpy (modified_data + 10, new_data, strlen (new_data));
g_assert_cmpstr (buffer, ==, modified_data);
verify_pos (iostream, strlen (original_data));
res = g_seekable_seek (G_SEEKABLE (iostream),
0, G_SEEK_SET,
NULL, NULL);
g_assert (res);
verify_pos (iostream, 0);
res = g_output_stream_close (out, NULL, NULL);
g_assert (res);
res = g_input_stream_read_all (in, buffer, 15, &n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint ((int)n_bytes, ==, 15);
g_assert (memcmp (buffer, modified_data, 15) == 0);
error = NULL;
res = g_output_stream_write_all (out, new_data, strlen (new_data),
&n_bytes, NULL, &error);
g_assert (!res);
g_assert (error != NULL);
g_assert (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED));
error = NULL;
res = g_io_stream_close (iostream, NULL, &error);
g_assert (res && error == NULL);
g_free (modified_data);
}
static void
test_g_file_open_readwrite (void)
{
char *tmp_file;
int fd;
gboolean res;
GFileIOStream *file_iostream;
char *path;
GFile *file;
GError *error;
fd = g_file_open_tmp ("readwrite_XXXXXX",
&tmp_file, NULL);
g_assert (fd != -1);
close (fd);
res = g_file_set_contents (tmp_file,
original_data, -1, NULL);
g_assert (res);
path = g_build_filename (g_get_home_dir (), "g-a-nonexisting-file", NULL);
file = g_file_new_for_path (path);
g_free (path);
error = NULL;
file_iostream = g_file_open_readwrite (file, NULL, &error);
g_assert (file_iostream == NULL);
g_assert (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND));
g_error_free (error);
g_object_unref (file);
file = g_file_new_for_path (tmp_file);
error = NULL;
file_iostream = g_file_open_readwrite (file, NULL, &error);
g_assert (file_iostream != NULL);
verify_iostream (file_iostream);
g_object_unref (file_iostream);
g_unlink (tmp_file);
g_free (tmp_file);
}
static void
test_g_file_create_readwrite (void)
{
char *tmp_file;
int fd;
gboolean res;
GFileIOStream *file_iostream;
GOutputStream *out;
GFile *file;
GError *error;
gsize n_bytes;
fd = g_file_open_tmp ("readwrite_XXXXXX",
&tmp_file, NULL);
g_assert (fd != -1);
close (fd);
file = g_file_new_for_path (tmp_file);
error = NULL;
file_iostream = g_file_create_readwrite (file, 0, NULL, &error);
g_assert (file_iostream == NULL);
g_assert (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS));
g_unlink (tmp_file);
file_iostream = g_file_create_readwrite (file, 0, NULL, &error);
g_assert (file_iostream != NULL);
out = g_io_stream_get_output_stream (G_IO_STREAM (file_iostream));
res = g_output_stream_write_all (out, original_data, strlen (original_data),
&n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint (n_bytes, ==, strlen (original_data));
res = g_seekable_seek (G_SEEKABLE (file_iostream),
0, G_SEEK_SET,
NULL, NULL);
g_assert (res);
verify_iostream (file_iostream);
g_object_unref (file_iostream);
g_unlink (tmp_file);
g_free (tmp_file);
}
static void
test_g_file_replace_readwrite (void)
{
char *tmp_file, *backup, *data;
int fd;
gboolean res;
GFileIOStream *file_iostream;
GInputStream *in;
GOutputStream *out;
GFile *file;
GError *error;
char buffer[1024];
gsize n_bytes;
fd = g_file_open_tmp ("readwrite_XXXXXX",
&tmp_file, NULL);
g_assert (fd != -1);
close (fd);
res = g_file_set_contents (tmp_file,
new_data, -1, NULL);
g_assert (res);
file = g_file_new_for_path (tmp_file);
error = NULL;
file_iostream = g_file_replace_readwrite (file, NULL,
TRUE, 0, NULL, &error);
g_assert (file_iostream != NULL);
in = g_io_stream_get_input_stream (G_IO_STREAM (file_iostream));
/* Ensure its empty */
res = g_input_stream_read_all (in, buffer, sizeof buffer, &n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint ((int)n_bytes, ==, 0);
out = g_io_stream_get_output_stream (G_IO_STREAM (file_iostream));
res = g_output_stream_write_all (out, original_data, strlen (original_data),
&n_bytes, NULL, NULL);
g_assert (res);
g_assert_cmpint (n_bytes, ==, strlen (original_data));
res = g_seekable_seek (G_SEEKABLE (file_iostream),
0, G_SEEK_SET,
NULL, NULL);
g_assert (res);
verify_iostream (file_iostream);
g_object_unref (file_iostream);
backup = g_strconcat (tmp_file, "~", NULL);
res = g_file_get_contents (backup,
&data,
NULL, NULL);
g_assert (res);
g_assert_cmpstr (data, ==, new_data);
g_free (data);
g_unlink (backup);
g_free (backup);
g_unlink (tmp_file);
g_free (tmp_file);
}
int
main (int argc,
char *argv[])
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/readwrite/test_g_file_open_readwrite",
test_g_file_open_readwrite);
g_test_add_func ("/readwrite/test_g_file_create_readwrite",
test_g_file_create_readwrite);
g_test_add_func ("/readwrite/test_g_file_replace_readwrite",
test_g_file_replace_readwrite);
return g_test_run();
}

506
gio/tests/resolver.c Normal file
View File

@@ -0,0 +1,506 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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 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 "config.h"
#include <glib.h>
#include "glibintl.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gio/gio.h>
static GResolver *resolver;
static GCancellable *cancellable;
static GMainLoop *loop;
static int nlookups = 0;
static void G_GNUC_NORETURN
usage (void)
{
fprintf (stderr, "Usage: resolver [-t] [-s] [hostname | IP | service/protocol/domain ] ...\n");
fprintf (stderr, " resolver [-t] [-s] -c [hostname | IP | service/protocol/domain ]\n");
fprintf (stderr, " Use -t to enable threading.\n");
fprintf (stderr, " Use -s to do synchronous lookups.\n");
fprintf (stderr, " Both together will result in simultaneous lookups in multiple threads\n");
fprintf (stderr, " Use -c (and only a single resolvable argument) to test GSocketConnectable.\n");
exit (1);
}
G_LOCK_DEFINE_STATIC (response);
static void
done_lookup (void)
{
nlookups--;
if (nlookups == 0)
{
/* In the sync case we need to make sure we don't call
* g_main_loop_quit before the loop is actually running...
*/
g_idle_add ((GSourceFunc)g_main_loop_quit, loop);
}
}
static void
print_resolved_name (const char *phys,
char *name,
GError *error)
{
G_LOCK (response);
printf ("Address: %s\n", phys);
if (error)
{
printf ("Error: %s\n", error->message);
g_error_free (error);
}
else
{
printf ("Name: %s\n", name);
g_free (name);
}
printf ("\n");
done_lookup ();
G_UNLOCK (response);
}
static void
print_resolved_addresses (const char *name,
GList *addresses,
GError *error)
{
char *phys;
GList *a;
G_LOCK (response);
printf ("Name: %s\n", name);
if (error)
{
printf ("Error: %s\n", error->message);
g_error_free (error);
}
else
{
for (a = addresses; a; a = a->next)
{
phys = g_inet_address_to_string (a->data);
printf ("Address: %s\n", phys);
g_free (phys);
g_object_unref (a->data);
}
g_list_free (addresses);
}
printf ("\n");
done_lookup ();
G_UNLOCK (response);
}
static void
print_resolved_service (const char *service,
GList *targets,
GError *error)
{
GList *t;
G_LOCK (response);
printf ("Service: %s\n", service);
if (error)
{
printf ("Error: %s\n", error->message);
g_error_free (error);
}
else
{
for (t = targets; t; t = t->next)
{
printf ("%s:%u (pri %u, weight %u)\n",
g_srv_target_get_hostname (t->data),
g_srv_target_get_port (t->data),
g_srv_target_get_priority (t->data),
g_srv_target_get_weight (t->data));
g_srv_target_free (t->data);
}
g_list_free (targets);
}
printf ("\n");
done_lookup ();
G_UNLOCK (response);
}
static void
lookup_one_sync (const char *arg)
{
GError *error = NULL;
if (strchr (arg, '/'))
{
GList *targets;
/* service/protocol/domain */
char **parts = g_strsplit (arg, "/", 3);
if (!parts || !parts[2])
usage ();
targets = g_resolver_lookup_service (resolver,
parts[0], parts[1], parts[2],
cancellable, &error);
print_resolved_service (arg, targets, error);
}
else if (g_hostname_is_ip_address (arg))
{
GInetAddress *addr = g_inet_address_new_from_string (arg);
char *name;
name = g_resolver_lookup_by_address (resolver, addr, cancellable, &error);
print_resolved_name (arg, name, error);
g_object_unref (addr);
}
else
{
GList *addresses;
addresses = g_resolver_lookup_by_name (resolver, arg, cancellable, &error);
print_resolved_addresses (arg, addresses, error);
}
}
static gpointer
lookup_thread (gpointer arg)
{
lookup_one_sync (arg);
return NULL;
}
static void
start_threaded_lookups (char **argv, int argc)
{
int i;
for (i = 0; i < argc; i++)
g_thread_create (lookup_thread, argv[i], FALSE, NULL);
}
static void
start_sync_lookups (char **argv, int argc)
{
int i;
for (i = 0; i < argc; i++)
lookup_one_sync (argv[i]);
}
static void
lookup_by_addr_callback (GObject *source, GAsyncResult *result,
gpointer user_data)
{
const char *phys = user_data;
GError *error = NULL;
char *name;
name = g_resolver_lookup_by_address_finish (resolver, result, &error);
print_resolved_name (phys, name, error);
}
static void
lookup_by_name_callback (GObject *source, GAsyncResult *result,
gpointer user_data)
{
const char *name = user_data;
GError *error = NULL;
GList *addresses;
addresses = g_resolver_lookup_by_name_finish (resolver, result, &error);
print_resolved_addresses (name, addresses, error);
}
static void
lookup_service_callback (GObject *source, GAsyncResult *result,
gpointer user_data)
{
const char *service = user_data;
GError *error = NULL;
GList *targets;
targets = g_resolver_lookup_service_finish (resolver, result, &error);
print_resolved_service (service, targets, error);
}
static void
start_async_lookups (char **argv, int argc)
{
int i;
for (i = 0; i < argc; i++)
{
if (strchr (argv[i], '/'))
{
/* service/protocol/domain */
char **parts = g_strsplit (argv[i], "/", 3);
if (!parts || !parts[2])
usage ();
g_resolver_lookup_service_async (resolver,
parts[0], parts[1], parts[2],
cancellable,
lookup_service_callback, argv[i]);
}
else if (g_hostname_is_ip_address (argv[i]))
{
GInetAddress *addr = g_inet_address_new_from_string (argv[i]);
g_resolver_lookup_by_address_async (resolver, addr, cancellable,
lookup_by_addr_callback, argv[i]);
g_object_unref (addr);
}
else
{
g_resolver_lookup_by_name_async (resolver, argv[i], cancellable,
lookup_by_name_callback,
argv[i]);
}
}
}
static void
print_connectable_sockaddr (GSocketAddress *sockaddr,
GError *error)
{
char *phys;
if (error)
{
printf ("Error: %s\n", error->message);
g_error_free (error);
}
else if (!G_IS_INET_SOCKET_ADDRESS (sockaddr))
{
printf ("Error: Unexpected sockaddr type '%s'\n", g_type_name_from_instance ((GTypeInstance *)sockaddr));
g_object_unref (sockaddr);
}
else
{
GInetSocketAddress *isa = G_INET_SOCKET_ADDRESS (sockaddr);
phys = g_inet_address_to_string (g_inet_socket_address_get_address (isa));
printf ("Address: %s%s%s:%d\n",
strchr (phys, ':') ? "[" : "", phys, strchr (phys, ':') ? "]" : "",
g_inet_socket_address_get_port (isa));
g_free (phys);
g_object_unref (sockaddr);
}
}
static void
do_sync_connectable (GSocketAddressEnumerator *enumerator)
{
GSocketAddress *sockaddr;
GError *error = NULL;
while ((sockaddr = g_socket_address_enumerator_next (enumerator, cancellable, &error)))
print_connectable_sockaddr (sockaddr, error);
g_object_unref (enumerator);
done_lookup ();
}
static void do_async_connectable (GSocketAddressEnumerator *enumerator);
static void
got_next_async (GObject *source, GAsyncResult *result, gpointer user_data)
{
GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (source);
GSocketAddress *sockaddr;
GError *error = NULL;
sockaddr = g_socket_address_enumerator_next_finish (enumerator, result, &error);
if (sockaddr || error)
print_connectable_sockaddr (sockaddr, error);
if (sockaddr)
do_async_connectable (enumerator);
else
{
g_object_unref (enumerator);
done_lookup ();
}
}
static void
do_async_connectable (GSocketAddressEnumerator *enumerator)
{
g_socket_address_enumerator_next_async (enumerator, cancellable,
got_next_async, NULL);
}
static void
do_connectable (const char *arg, gboolean synchronous)
{
char **parts;
GSocketConnectable *connectable;
GSocketAddressEnumerator *enumerator;
if (strchr (arg, '/'))
{
/* service/protocol/domain */
parts = g_strsplit (arg, "/", 3);
if (!parts || !parts[2])
usage ();
connectable = g_network_service_new (parts[0], parts[1], parts[2]);
}
else
{
guint16 port;
parts = g_strsplit (arg, ":", 2);
if (parts && parts[1])
{
arg = parts[0];
port = strtoul (parts[1], NULL, 10);
}
else
port = 0;
if (g_hostname_is_ip_address (arg))
{
GInetAddress *addr = g_inet_address_new_from_string (arg);
GSocketAddress *sockaddr = g_inet_socket_address_new (addr, port);
g_object_unref (addr);
connectable = G_SOCKET_CONNECTABLE (sockaddr);
}
else
connectable = g_network_address_new (arg, port);
}
enumerator = g_socket_connectable_enumerate (connectable);
g_object_unref (connectable);
if (synchronous)
do_sync_connectable (enumerator);
else
do_async_connectable (enumerator);
}
#ifdef G_OS_UNIX
static int cancel_fds[2];
static void
interrupted (int sig)
{
signal (SIGINT, SIG_DFL);
write (cancel_fds[1], "x", 1);
}
static gboolean
async_cancel (GIOChannel *source, GIOCondition cond, gpointer cancel)
{
g_cancellable_cancel (cancel);
return FALSE;
}
#endif
int
main (int argc, char **argv)
{
gboolean threaded = FALSE, synchronous = FALSE;
gboolean use_connectable = FALSE;
#ifdef G_OS_UNIX
GIOChannel *chan;
guint watch;
#endif
/* We can't use GOptionContext because we use the arguments to
* decide whether or not to call g_thread_init().
*/
while (argc >= 2 && argv[1][0] == '-')
{
if (!strcmp (argv[1], "-t"))
{
g_thread_init (NULL);
threaded = TRUE;
}
else if (!strcmp (argv[1], "-s"))
synchronous = TRUE;
else if (!strcmp (argv[1], "-c"))
use_connectable = TRUE;
else
usage ();
argv++;
argc--;
}
g_type_init ();
if (argc < 2 || (argc > 2 && use_connectable))
usage ();
resolver = g_resolver_get_default ();
cancellable = g_cancellable_new ();
#ifdef G_OS_UNIX
/* Set up cancellation; we want to cancel if the user ^C's the
* program, but we can't cancel directly from an interrupt.
*/
signal (SIGINT, interrupted);
if (pipe (cancel_fds) == -1)
{
perror ("pipe");
exit (1);
}
chan = g_io_channel_unix_new (cancel_fds[0]);
watch = g_io_add_watch (chan, G_IO_IN, async_cancel, cancellable);
g_io_channel_unref (chan);
#endif
nlookups = argc - 1;
loop = g_main_loop_new (NULL, TRUE);
if (use_connectable)
do_connectable (argv[1], synchronous);
else
{
if (threaded && synchronous)
start_threaded_lookups (argv + 1, argc - 1);
else if (synchronous)
start_sync_lookups (argv + 1, argc - 1);
else
start_async_lookups (argv + 1, argc - 1);
}
g_main_loop_run (loop);
g_main_loop_unref (loop);
#ifdef G_OS_UNIX
g_source_remove (watch);
#endif
g_object_unref (cancellable);
return 0;
}

163
gio/tests/send-data.c Normal file
View File

@@ -0,0 +1,163 @@
#include <gio/gio.h>
#include <string.h>
#include <stdio.h>
GMainLoop *loop;
int cancel_timeout = 0;
gboolean async = FALSE;
gboolean graceful = FALSE;
static GOptionEntry cmd_entries[] = {
{"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout,
"Cancel any op after the specified amount of seconds", NULL},
{"async", 'a', 0, G_OPTION_ARG_NONE, &async,
"Use async ops", NULL},
{"graceful-disconnect", 'g', 0, G_OPTION_ARG_NONE, &graceful,
"Use graceful disconnect", NULL},
{NULL}
};
static gpointer
cancel_thread (gpointer data)
{
GCancellable *cancellable = data;
g_usleep (1000*1000*cancel_timeout);
g_print ("Cancelling\n");
g_cancellable_cancel (cancellable);
return NULL;
}
static char *
socket_address_to_string (GSocketAddress *address)
{
GInetAddress *inet_address;
char *str, *res;
int port;
inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
str = g_inet_address_to_string (inet_address);
port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
res = g_strdup_printf ("%s:%d", str, port);
g_free (str);
return res;
}
static void
async_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GAsyncResult **resp = user_data;
*resp = g_object_ref (res);
g_main_loop_quit (loop);
}
int
main (int argc, char *argv[])
{
GOptionContext *context;
GSocketClient *client;
GSocketConnection *connection;
GSocketAddress *address;
GCancellable *cancellable;
GOutputStream *out;
GError *error = NULL;
char buffer[1000];
g_type_init ();
g_thread_init (NULL);
context = g_option_context_new (" <hostname>[:port] - send data to tcp host");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (argc != 2)
{
g_printerr ("%s: %s\n", argv[0], "Need to specify hostname");
return 1;
}
if (async)
loop = g_main_loop_new (NULL, FALSE);
if (cancel_timeout)
{
cancellable = g_cancellable_new ();
g_thread_create (cancel_thread, cancellable, FALSE, NULL);
}
else
{
cancellable = NULL;
}
client = g_socket_client_new ();
connection = g_socket_client_connect_to_host (client,
argv[1],
7777,
cancellable, &error);
if (connection == NULL)
{
g_printerr ("%s can't connect: %s\n", argv[0], error->message);
return 1;
}
address = g_socket_connection_get_remote_address (connection, &error);
if (!address)
{
g_printerr ("Error getting remote address: %s\n",
error->message);
return 1;
}
g_print ("Connected to address: %s\n",
socket_address_to_string (address));
g_object_unref (address);
if (graceful)
g_tcp_connection_set_graceful_disconnect (G_TCP_CONNECTION (connection), TRUE);
out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
while (fgets(buffer, sizeof (buffer), stdin) != NULL)
{
if (!g_output_stream_write_all (out, buffer, strlen (buffer),
NULL, cancellable, &error))
{
g_warning ("send error: %s\n", error->message);
g_error_free (error);
error = NULL;
}
}
g_print ("closing stream\n");
if (async)
{
GAsyncResult *res;
g_io_stream_close_async (G_IO_STREAM (connection),
0, cancellable, async_cb, &res);
g_main_loop_run (loop);
if (!g_io_stream_close_finish (G_IO_STREAM (connection),
res, &error))
{
g_object_unref (res);
g_warning ("close error: %s\n", error->message);
return 1;
}
g_object_unref (res);
}
else
{
if (!g_io_stream_close (G_IO_STREAM (connection), cancellable, &error))
{
g_warning ("close error: %s\n", error->message);
return 1;
}
}
return 0;
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright © 2009 Ryan Lortie
*
* This program 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 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static GObject *got_source;
static GAsyncResult *got_result;
static gpointer got_user_data;
static void
ensure_destroyed (gpointer obj)
{
g_object_add_weak_pointer (obj, &obj);
g_object_unref (obj);
g_assert (obj == NULL);
}
static void
reset (void)
{
got_source = NULL;
if (got_result)
ensure_destroyed (got_result);
got_result = NULL;
got_user_data = NULL;
}
static void
check (gpointer a, gpointer b, gpointer c)
{
g_assert (a == got_source);
g_assert (b == got_result);
g_assert (c == got_user_data);
}
static void
callback_func (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
got_source = source;
got_result = g_object_ref (result);
got_user_data = user_data;
}
static gboolean
test_simple_async_idle (gpointer user_data)
{
GSimpleAsyncResult *result;
GObject *a, *b, *c;
gboolean *ran = user_data;
a = g_object_new (G_TYPE_OBJECT, NULL);
b = g_object_new (G_TYPE_OBJECT, NULL);
c = g_object_new (G_TYPE_OBJECT, NULL);
result = g_simple_async_result_new (a, callback_func, b, test_simple_async_idle);
check (NULL, NULL, NULL);
g_simple_async_result_complete (result);
check (a, result, b);
g_object_unref (result);
g_assert (g_simple_async_result_is_valid (got_result, a, test_simple_async_idle));
g_assert (!g_simple_async_result_is_valid (got_result, b, test_simple_async_idle));
g_assert (!g_simple_async_result_is_valid (got_result, c, test_simple_async_idle));
g_assert (!g_simple_async_result_is_valid (got_result, b, callback_func));
g_assert (!g_simple_async_result_is_valid ((gpointer) a, NULL, NULL));
reset ();
reset ();
reset ();
ensure_destroyed (a);
ensure_destroyed (b);
ensure_destroyed (c);
*ran = TRUE;
return FALSE;
}
static void
test_simple_async (void)
{
GSimpleAsyncResult *result;
GObject *a, *b;
gboolean ran_test_in_idle = FALSE;
g_idle_add (test_simple_async_idle, &ran_test_in_idle);
g_main_context_iteration (NULL, FALSE);
g_assert (ran_test_in_idle);
a = g_object_new (G_TYPE_OBJECT, NULL);
b = g_object_new (G_TYPE_OBJECT, NULL);
result = g_simple_async_result_new (a, callback_func, b, test_simple_async);
check (NULL, NULL, NULL);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
check (NULL, NULL, NULL);
g_main_context_iteration (NULL, FALSE);
check (a, result, b);
reset ();
ensure_destroyed (a);
ensure_destroyed (b);
}
int
main (int argc, char **argv)
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/gio/simple-async-result/test", test_simple_async);
return g_test_run();
}

296
gio/tests/sleepy-stream.c Normal file
View File

@@ -0,0 +1,296 @@
/*
* Copyright © 2009 Codethink Limited
*
* This program 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 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include <gio/gio.h>
#include <string.h>
#define MAX_PIECE_SIZE 100
#define MAX_PIECES 60
static gchar *
cook_piece (void)
{
char buffer[MAX_PIECE_SIZE * 2];
gint symbols, i = 0;
symbols = g_test_rand_int_range (1, MAX_PIECE_SIZE + 1);
while (symbols--)
{
gint c = g_test_rand_int_range (0, 30);
switch (c)
{
case 26:
buffer[i++] = '\n';
case 27:
buffer[i++] = '\r';
break;
case 28:
buffer[i++] = '\r';
case 29:
buffer[i++] = '\n';
break;
default:
buffer[i++] = c + 'a';
break;
}
g_assert_cmpint (i, <=, sizeof buffer);
}
return g_strndup (buffer, i);
}
static gchar **
cook_pieces (void)
{
gchar **array;
gint pieces;
pieces = g_test_rand_int_range (0, MAX_PIECES + 1);
array = g_new (char *, pieces + 1);
array[pieces] = NULL;
while (pieces--)
array[pieces] = cook_piece ();
return array;
}
typedef struct
{
GInputStream parent_instance;
gboolean built_to_fail;
gchar **pieces;
gint index;
const gchar *current;
} SleepyStream;
typedef GInputStreamClass SleepyStreamClass;
GType sleepy_stream_get_type (void);
G_DEFINE_TYPE (SleepyStream, sleepy_stream, G_TYPE_INPUT_STREAM)
static gssize
sleepy_stream_read (GInputStream *stream,
void *buffer,
gsize length,
GCancellable *cancellable,
GError **error)
{
SleepyStream *sleepy = (SleepyStream *) stream;
if (sleepy->pieces[sleepy->index] == NULL)
{
if (sleepy->built_to_fail)
{
g_set_error (error, 0, 0, "fail");
return -1;
}
else
return 0;
}
else
{
if (!sleepy->current)
sleepy->current = sleepy->pieces[sleepy->index++];
length = MIN (strlen (sleepy->current), length);
memcpy (buffer, sleepy->current, length);
sleepy->current += length;
if (*sleepy->current == '\0')
sleepy->current = NULL;
return length;
}
}
static void
sleepy_stream_init (SleepyStream *sleepy)
{
sleepy->pieces = cook_pieces ();
sleepy->built_to_fail = FALSE;
sleepy->index = 0;
}
static void
sleepy_stream_finalize (GObject *object)
{
SleepyStream *sleepy = (SleepyStream *) object;
g_strfreev (sleepy->pieces);
G_OBJECT_CLASS (sleepy_stream_parent_class)
->finalize (object);
}
static void
sleepy_stream_class_init (SleepyStreamClass *class)
{
G_OBJECT_CLASS (class)->finalize = sleepy_stream_finalize;
class->read_fn = sleepy_stream_read;
/* no read_async implementation.
* main thread will sleep while read runs in a worker.
*/
}
static SleepyStream *
sleepy_stream_new (void)
{
return g_object_new (sleepy_stream_get_type (), NULL);
}
static gboolean
read_line (GDataInputStream *stream,
GString *string,
const gchar *eol,
GError **error)
{
gsize length;
int eol_len;
char *str;
eol_len = 1 + (eol[1] != '\0');
str = g_data_input_stream_read_line (stream, &length, NULL, error);
if (str == NULL)
return FALSE;
g_assert (strstr (str, eol) == NULL);
g_assert (strlen (str) == length);
g_string_append (string, str);
g_string_append (string, eol);
g_free (str);
return TRUE;
}
static void
build_comparison (GString *str,
SleepyStream *stream)
{
/* build this for comparison */
gint i;
for (i = 0; stream->pieces[i]; i++)
g_string_append (str, stream->pieces[i]);
if (str->len && str->str[str->len - 1] != '\n')
g_string_append_c (str, '\n');
}
static void
test (void)
{
SleepyStream *stream = sleepy_stream_new ();
GDataInputStream *data;
GError *error = NULL;
GString *one;
GString *two;
one = g_string_new (NULL);
two = g_string_new (NULL);
data = g_data_input_stream_new (G_INPUT_STREAM (stream));
g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_LF);
build_comparison (one, stream);
while (read_line (data, two, "\n", &error));
g_assert_cmpstr (one->str, ==, two->str);
g_string_free (one, TRUE);
g_string_free (two, TRUE);
g_object_unref (stream);
g_object_unref (data);
}
static GDataInputStream *data;
static GString *one, *two;
static GMainLoop *loop;
static const gchar *eol;
static void
asynch_ready (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
gsize length;
gchar *str;
g_assert (data == G_DATA_INPUT_STREAM (object));
str = g_data_input_stream_read_line_finish (data, result, &length, &error);
if (str == NULL)
{
g_main_loop_quit (loop);
if (error)
g_error_free (error);
}
else
{
g_assert (length == strlen (str));
g_string_append (two, str);
g_string_append (two, eol);
g_free (str);
/* MOAR!! */
g_data_input_stream_read_line_async (data, 0, NULL, asynch_ready, NULL);
}
}
static void
asynch (void)
{
SleepyStream *sleepy = sleepy_stream_new ();
data = g_data_input_stream_new (G_INPUT_STREAM (sleepy));
one = g_string_new (NULL);
two = g_string_new (NULL);
eol = "\n";
build_comparison (one, sleepy);
g_data_input_stream_read_line_async (data, 0, NULL, asynch_ready, NULL);
g_main_loop_run (loop = g_main_loop_new (NULL, FALSE));
g_assert_cmpstr (one->str, ==, two->str);
g_string_free (one, TRUE);
g_string_free (two, TRUE);
g_object_unref (sleepy);
g_object_unref (data);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_type_init ();
g_test_add_func ("/filter-stream/input", test);
g_test_add_func ("/filter-stream/async", asynch);
return g_test_run();
}

298
gio/tests/socket-client.c Normal file
View File

@@ -0,0 +1,298 @@
#include <gio/gio.h>
#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
GMainLoop *loop;
gboolean verbose = FALSE;
gboolean non_blocking = FALSE;
gboolean use_udp = FALSE;
gboolean use_source = FALSE;
int cancel_timeout = 0;
static GOptionEntry cmd_entries[] = {
{"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout,
"Cancel any op after the specified amount of seconds", NULL},
{"udp", 'u', 0, G_OPTION_ARG_NONE, &use_udp,
"Use udp instead of tcp", NULL},
{"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
"Be verbose", NULL},
{"non-blocking", 'n', 0, G_OPTION_ARG_NONE, &non_blocking,
"Enable non-blocking i/o", NULL},
{"use-source", 's', 0, G_OPTION_ARG_NONE, &use_source,
"Use GSource to wait for non-blocking i/o", NULL},
{NULL}
};
static char *
socket_address_to_string (GSocketAddress *address)
{
GInetAddress *inet_address;
char *str, *res;
int port;
inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
str = g_inet_address_to_string (inet_address);
port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
res = g_strdup_printf ("%s:%d", str, port);
g_free (str);
return res;
}
static gboolean
source_ready (gpointer data,
GIOCondition condition)
{
g_main_loop_quit (loop);
return FALSE;
}
static void
ensure_condition (GSocket *socket,
const char *where,
GCancellable *cancellable,
GIOCondition condition)
{
GError *error = NULL;
GSource *source;
if (!non_blocking)
return;
if (use_source)
{
source = g_socket_create_source (socket,
condition,
cancellable);
g_source_set_callback (source,
(GSourceFunc) source_ready,
NULL, NULL);
g_source_attach (source, NULL);
g_source_unref (source);
g_main_loop_run (loop);
}
else
{
if (!g_socket_condition_wait (socket, condition, cancellable, &error))
{
g_printerr ("condition wait error for %s: %s\n",
where,
error->message);
exit (1);
}
}
}
static gpointer
cancel_thread (gpointer data)
{
GCancellable *cancellable = data;
g_usleep (1000*1000*cancel_timeout);
g_print ("Cancelling\n");
g_cancellable_cancel (cancellable);
return NULL;
}
int
main (int argc,
char *argv[])
{
GSocket *socket;
GSocketAddress *src_address;
GSocketAddress *address;
GSocketType socket_type;
GError *error = NULL;
GOptionContext *context;
GCancellable *cancellable;
GSocketAddressEnumerator *enumerator;
GSocketConnectable *connectable;
g_thread_init (NULL);
g_type_init ();
context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (argc != 2)
{
g_printerr ("%s: %s\n", argv[0], "Need to specify hostname");
return 1;
}
if (cancel_timeout)
{
cancellable = g_cancellable_new ();
g_thread_create (cancel_thread, cancellable, FALSE, NULL);
}
else
{
cancellable = NULL;
}
loop = g_main_loop_new (NULL, FALSE);
if (use_udp)
socket_type = G_SOCKET_TYPE_DATAGRAM;
else
socket_type = G_SOCKET_TYPE_STREAM;
socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, 0, &error);
if (socket == NULL)
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
connectable = g_network_address_parse (argv[1], 7777, &error);
if (connectable == NULL)
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
enumerator = g_socket_connectable_enumerate (connectable);
while (TRUE)
{
address = g_socket_address_enumerator_next (enumerator, cancellable, &error);
if (address == NULL)
{
if (error == NULL)
g_printerr ("%s: No more addresses to try\n", argv[0]);
else
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (g_socket_connect (socket, address, cancellable, &error))
break;
g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message);
g_error_free (error);
error = NULL;
g_object_unref (address);
}
g_object_unref (enumerator);
g_print ("Connected to %s\n",
socket_address_to_string (address));
/* TODO: Test non-blocking connect */
if (non_blocking)
g_socket_set_blocking (socket, FALSE);
src_address = g_socket_get_local_address (socket, &error);
if (!src_address)
{
g_printerr ("Error getting local address: %s\n",
error->message);
return 1;
}
g_print ("local address: %s\n",
socket_address_to_string (src_address));
g_object_unref (src_address);
while (TRUE)
{
gchar buffer[4096] = { };
gssize size;
gsize to_send;
if (fgets (buffer, sizeof buffer, stdin) == NULL)
break;
to_send = strlen (buffer);
while (to_send > 0)
{
ensure_condition (socket, "send", cancellable, G_IO_OUT);
if (use_udp)
size = g_socket_send_to (socket, address,
buffer, to_send,
cancellable, &error);
else
size = g_socket_send (socket, buffer, to_send,
cancellable, &error);
if (size < 0)
{
if (g_error_matches (error,
G_IO_ERROR,
G_IO_ERROR_WOULD_BLOCK))
{
g_print ("socket send would block, handling\n");
g_error_free (error);
error = NULL;
continue;
}
else
{
g_printerr ("Error sending to socket: %s\n",
error->message);
return 1;
}
}
g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size);
if (size == 0)
{
g_printerr ("Unexpected short write\n");
return 1;
}
to_send -= size;
}
ensure_condition (socket, "receive", cancellable, G_IO_IN);
if (use_udp)
size = g_socket_receive_from (socket, &src_address,
buffer, sizeof buffer,
cancellable, &error);
else
size = g_socket_receive (socket, buffer, sizeof buffer,
cancellable, &error);
if (size < 0)
{
g_printerr ("Error receiving from socket: %s\n",
error->message);
return 1;
}
if (size == 0)
break;
g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size);
if (use_udp)
g_print (" from %s", socket_address_to_string (src_address));
g_print ("\n");
if (verbose)
g_print ("-------------------------\n"
"%.*s"
"-------------------------\n",
(int)size, buffer);
}
g_print ("closing socket\n");
if (!g_socket_close (socket, &error))
{
g_printerr ("Error closing master socket: %s\n",
error->message);
return 1;
}
g_object_unref (G_OBJECT (socket));
return 0;
}

308
gio/tests/socket-server.c Normal file
View File

@@ -0,0 +1,308 @@
#include <gio/gio.h>
#include <glib.h>
#include <stdlib.h>
GMainLoop *loop;
int port = 7777;
gboolean verbose = FALSE;
gboolean dont_reuse_address = FALSE;
gboolean non_blocking = FALSE;
gboolean use_udp = FALSE;
gboolean use_source = FALSE;
int cancel_timeout = 0;
static GOptionEntry cmd_entries[] = {
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
"Local port to bind to", NULL},
{"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout,
"Cancel any op after the specified amount of seconds", NULL},
{"udp", 'u', 0, G_OPTION_ARG_NONE, &use_udp,
"Use udp instead of tcp", NULL},
{"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
"Be verbose", NULL},
{"no-reuse", 0, 0, G_OPTION_ARG_NONE, &dont_reuse_address,
"Don't SOADDRREUSE", NULL},
{"non-blocking", 'n', 0, G_OPTION_ARG_NONE, &non_blocking,
"Enable non-blocking i/o", NULL},
{"use-source", 's', 0, G_OPTION_ARG_NONE, &use_source,
"Use GSource to wait for non-blocking i/o", NULL},
{NULL}
};
static char *
socket_address_to_string (GSocketAddress *address)
{
GInetAddress *inet_address;
char *str, *res;
int the_port;
inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
str = g_inet_address_to_string (inet_address);
the_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
res = g_strdup_printf ("%s:%d", str, the_port);
g_free (str);
return res;
}
static gboolean
source_ready (gpointer data,
GIOCondition condition)
{
g_main_loop_quit (loop);
return FALSE;
}
static void
ensure_condition (GSocket *socket,
const char *where,
GCancellable *cancellable,
GIOCondition condition)
{
GError *error = NULL;
GSource *source;
if (!non_blocking)
return;
if (use_source)
{
source = g_socket_create_source (socket,
condition,
cancellable);
g_source_set_callback (source,
(GSourceFunc) source_ready,
NULL, NULL);
g_source_attach (source, NULL);
g_source_unref (source);
g_main_loop_run (loop);
}
else
{
if (!g_socket_condition_wait (socket, condition, cancellable, &error))
{
g_printerr ("condition wait error for %s: %s\n",
where,
error->message);
exit (1);
}
}
}
static gpointer
cancel_thread (gpointer data)
{
GCancellable *cancellable = data;
g_usleep (1000*1000*cancel_timeout);
g_print ("Cancelling\n");
g_cancellable_cancel (cancellable);
return NULL;
}
int
main (int argc,
char *argv[])
{
GSocket *socket, *new_socket, *recv_socket;
GSocketAddress *src_address;
GSocketAddress *address;
GSocketType socket_type;
GError *error = NULL;
GOptionContext *context;
GCancellable *cancellable;
g_thread_init (NULL);
g_type_init ();
context = g_option_context_new (" - Test GSocket server stuff");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (cancel_timeout)
{
cancellable = g_cancellable_new ();
g_thread_create (cancel_thread, cancellable, FALSE, NULL);
}
else
{
cancellable = NULL;
}
loop = g_main_loop_new (NULL, FALSE);
if (use_udp)
socket_type = G_SOCKET_TYPE_DATAGRAM;
else
socket_type = G_SOCKET_TYPE_STREAM;
socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, 0, &error);
if (socket == NULL)
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (non_blocking)
g_socket_set_blocking (socket, FALSE);
src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port);
if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error))
{
g_printerr ("Can't bind socket: %s\n", error->message);
return 1;
}
if (!use_udp)
{
if (!g_socket_listen (socket, &error))
{
g_printerr ("Can't listen on socket: %s\n", error->message);
return 1;
}
g_print ("listening on port %d...\n", port);
ensure_condition (socket, "accept", cancellable, G_IO_IN);
new_socket = g_socket_accept (socket, cancellable, &error);
if (!new_socket)
{
g_printerr ("Error accepting socket: %s\n",
error->message);
return 1;
}
if (non_blocking)
g_socket_set_blocking (new_socket, FALSE);
address = g_socket_get_remote_address (new_socket, &error);
if (!address)
{
g_printerr ("Error getting remote address: %s\n",
error->message);
return 1;
}
g_print ("got a new connection from %s\n",
socket_address_to_string (address));
g_object_unref (address);
recv_socket = new_socket;
}
else
{
recv_socket = socket;
new_socket = NULL;
}
while (TRUE)
{
gchar buffer[4096] = { };
gssize size;
gsize to_send;
ensure_condition (recv_socket, "receive", cancellable, G_IO_IN);
if (use_udp)
size = g_socket_receive_from (recv_socket, &address,
buffer, sizeof buffer,
cancellable, &error);
else
size = g_socket_receive (recv_socket, buffer, sizeof buffer,
cancellable, &error);
if (size < 0)
{
g_printerr ("Error receiving from socket: %s\n",
error->message);
return 1;
}
if (size == 0)
break;
g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size);
if (use_udp)
g_print (" from %s", socket_address_to_string (address));
g_print ("\n");
if (verbose)
g_print ("-------------------------\n"
"%.*s\n"
"-------------------------\n",
(int)size, buffer);
to_send = size;
while (to_send > 0)
{
ensure_condition (recv_socket, "send", cancellable, G_IO_OUT);
if (use_udp)
size = g_socket_send_to (recv_socket, address,
buffer, to_send, cancellable, &error);
else
size = g_socket_send (recv_socket, buffer, to_send,
cancellable, &error);
if (size < 0)
{
if (g_error_matches (error,
G_IO_ERROR,
G_IO_ERROR_WOULD_BLOCK))
{
g_print ("socket send would block, handling\n");
g_error_free (error);
error = NULL;
continue;
}
else
{
g_printerr ("Error sending to socket: %s\n",
error->message);
return 1;
}
}
g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size);
if (size == 0)
{
g_printerr ("Unexpected short write\n");
return 1;
}
to_send -= size;
}
}
g_print ("connection closed\n");
if (new_socket)
{
if (!g_socket_close (new_socket, &error))
{
g_printerr ("Error closing connection socket: %s\n",
error->message);
return 1;
}
g_object_unref (G_OBJECT (new_socket));
}
if (!g_socket_close (socket, &error))
{
g_printerr ("Error closing master socket: %s\n",
error->message);
return 1;
}
g_object_unref (G_OBJECT (socket));
return 0;
}

158
gio/tests/srvtarget.c Normal file
View File

@@ -0,0 +1,158 @@
/* GLib testing framework examples and tests
* Copyright (C) 2009 Red Hat, Inc.
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_TRIALS 250000
struct {
const char *order;
int expected, seen;
} ordering[] = {
/* There are 32 legitimate orderings; the result always has to start
* with either "fe" (usually) or "ef" (rarely). For the remaining
* letters, "cbda" is the most likely, with various other orders
* possible, down to "adbc" being the most improbable. However,
* almost all "fe" orderings are more likely than almost any "ef"
* orderings. The complete probability ordering, from most-likely
* to least-likely is something roughly like:
*/
{ "fecbda", 0.2468 * NUM_TRIALS, 0},
{ "febcda", 0.1885 * NUM_TRIALS, 0},
{ "fecdba", 0.1346 * NUM_TRIALS, 0},
{ "fedcba", 0.0830 * NUM_TRIALS, 0},
{ "febdca", 0.0706 * NUM_TRIALS, 0},
{ "fedbca", 0.0571 * NUM_TRIALS, 0},
{ "fecbad", 0.0496 * NUM_TRIALS, 0},
{ "febcad", 0.0374 * NUM_TRIALS, 0},
{ "fecabd", 0.0185 * NUM_TRIALS, 0},
{ "fecdab", 0.0136 * NUM_TRIALS, 0},
{ "fecadb", 0.0110 * NUM_TRIALS, 0},
{ "febacd", 0.0108 * NUM_TRIALS, 0},
{ "feacbd", 0.0096 * NUM_TRIALS, 0},
{ "fedcab", 0.0083 * NUM_TRIALS, 0},
{ "feabcd", 0.0073 * NUM_TRIALS, 0},
{ "feacdb", 0.0058 * NUM_TRIALS, 0},
{ "efcbda", 0.0049 * NUM_TRIALS, 0},
{ "febdac", 0.0048 * NUM_TRIALS, 0},
{ "febadc", 0.0043 * NUM_TRIALS, 0},
{ "fedbac", 0.0038 * NUM_TRIALS, 0},
{ "efbcda", 0.0038 * NUM_TRIALS, 0},
{ "feadcb", 0.0036 * NUM_TRIALS, 0},
{ "fedacb", 0.0035 * NUM_TRIALS, 0},
{ "feabdc", 0.0029 * NUM_TRIALS, 0},
{ "feadbc", 0.0026 * NUM_TRIALS, 0},
{ "fedabc", 0.0026 * NUM_TRIALS, 0},
{ "efcdba", 0.0026 * NUM_TRIALS, 0},
{ "efdcba", 0.0017 * NUM_TRIALS, 0},
{ "efbdca", 0.0014 * NUM_TRIALS, 0},
{ "efdbca", 0.0011 * NUM_TRIALS, 0},
{ "efcbad", 0.0010 * NUM_TRIALS, 0},
{ "efbcad", 0.0008 * NUM_TRIALS, 0},
{ "efcabd", 0.0004 * NUM_TRIALS, 0},
{ "efcdab", 0.0003 * NUM_TRIALS, 0},
{ "efcadb", 0.0002 * NUM_TRIALS, 0},
{ "efbacd", 0.0002 * NUM_TRIALS, 0},
{ "efacbd", 0.0002 * NUM_TRIALS, 0},
{ "efdcab", 0.0002 * NUM_TRIALS, 0},
{ "efabcd", 0.0002 * NUM_TRIALS, 0},
{ "efacdb", 0.0001 * NUM_TRIALS, 0},
{ "efbdac", 0.0001 * NUM_TRIALS, 0},
{ "efadcb", 0.0001 * NUM_TRIALS, 0},
{ "efdbac", 0.0001 * NUM_TRIALS, 0},
{ "efbadc", 0.0001 * NUM_TRIALS, 0},
{ "efdacb", 0.0001 * NUM_TRIALS, 0},
{ "efabdc", 0.0001 * NUM_TRIALS, 0},
{ "efadbc", 0.00005 * NUM_TRIALS, 0},
{ "efdabc", 0.00005 * NUM_TRIALS, 0}
};
#define NUM_ORDERINGS G_N_ELEMENTS (ordering)
static void
test_srv_target_ordering (void)
{
GList *targets, *sorted, *t;
char result[7], *p;
int i;
guint o;
targets = NULL;
/* name, port, priority, weight */
targets = g_list_append (targets, g_srv_target_new ("a", 0, 2, 0));
targets = g_list_append (targets, g_srv_target_new ("b", 0, 2, 10));
targets = g_list_append (targets, g_srv_target_new ("c", 0, 2, 15));
targets = g_list_append (targets, g_srv_target_new ("d", 0, 2, 5));
targets = g_list_append (targets, g_srv_target_new ("e", 0, 1, 0));
targets = g_list_append (targets, g_srv_target_new ("f", 0, 1, 50));
for (i = 0; i < NUM_TRIALS; i++)
{
g_random_set_seed (i);
sorted = g_srv_target_list_sort (g_list_copy (targets));
for (t = sorted, p = result; t; t = t->next)
*(p++) = *g_srv_target_get_hostname (t->data);
*p = '\0';
g_list_free (sorted);
for (o = 0; o < NUM_ORDERINGS; o++)
{
if (!strcmp (result, ordering[o].order))
{
ordering[o].seen++;
break;
}
}
/* Assert that @result matched one of the valid orderings */
if (o == NUM_ORDERINGS)
{
char *msg = g_strdup_printf ("result '%s' is invalid", result);
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
}
}
/* Assert that each ordering appeared roughly the expected
* number of times.
*/
for (o = 0; o < NUM_ORDERINGS; o++)
{
g_assert_cmpint (ordering[o].seen, >, ordering[o].expected / 2);
g_assert_cmpint (ordering[o].seen, <, ordering[o].expected * 2);
}
g_resolver_free_targets (targets);
}
int
main (int argc, char **argv)
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/srvtarget/srv-target-ordering", test_srv_target_ordering);
return g_test_run();
}

256
gio/tests/unix-streams.c Normal file
View File

@@ -0,0 +1,256 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work 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.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define DATA "abcdefghijklmnopqrstuvwxyz"
int writer_pipe[2], reader_pipe[2];
GCancellable *writer_cancel, *reader_cancel, *main_cancel;
GMainLoop *loop;
static gpointer
writer_thread (gpointer user_data)
{
GOutputStream *out;
gssize nwrote, offset;
GError *err = NULL;
out = g_unix_output_stream_new (writer_pipe[1], TRUE);
do
{
g_usleep (10);
offset = 0;
while (offset < (gssize) sizeof (DATA))
{
nwrote = g_output_stream_write (out, DATA + offset,
sizeof (DATA) - offset,
writer_cancel, &err);
if (nwrote <= 0 || err != NULL)
break;
offset += nwrote;
}
g_assert (nwrote > 0 || err != NULL);
}
while (err == NULL);
if (g_cancellable_is_cancelled (writer_cancel))
{
g_cancellable_cancel (main_cancel);
g_object_unref (out);
return NULL;
}
g_warning ("writer: %s", err->message);
g_assert_not_reached ();
}
static gpointer
reader_thread (gpointer user_data)
{
GInputStream *in;
gssize nread, total;
GError *err = NULL;
char buf[sizeof (DATA)];
in = g_unix_input_stream_new (reader_pipe[0], TRUE);
do
{
total = 0;
while (total < (gssize) sizeof (DATA))
{
nread = g_input_stream_read (in, buf + total, sizeof (buf) - total,
reader_cancel, &err);
if (nread <= 0 || err != NULL)
break;
total += nread;
}
if (err)
break;
if (nread == 0)
{
g_assert (err == NULL);
/* pipe closed */
g_object_unref (in);
return NULL;
}
g_assert_cmpstr (buf, ==, DATA);
g_assert (!g_cancellable_is_cancelled (reader_cancel));
}
while (err == NULL);
g_warning ("reader: %s", err->message);
g_assert_not_reached ();
}
char main_buf[sizeof (DATA)];
gssize main_len, main_offset;
static void readable (GObject *source, GAsyncResult *res, gpointer user_data);
static void writable (GObject *source, GAsyncResult *res, gpointer user_data);
static void
do_main_cancel (GOutputStream *out)
{
g_output_stream_close (out, NULL, NULL);
g_main_loop_quit (loop);
}
static void
readable (GObject *source, GAsyncResult *res, gpointer user_data)
{
GInputStream *in = G_INPUT_STREAM (source);
GOutputStream *out = user_data;
GError *err = NULL;
main_len = g_input_stream_read_finish (in, res, &err);
if (g_cancellable_is_cancelled (main_cancel))
{
do_main_cancel (out);
return;
}
g_assert (err == NULL);
main_offset = 0;
g_output_stream_write_async (out, main_buf, main_len,
G_PRIORITY_DEFAULT, main_cancel,
writable, in);
}
static void
writable (GObject *source, GAsyncResult *res, gpointer user_data)
{
GOutputStream *out = G_OUTPUT_STREAM (source);
GInputStream *in = user_data;
GError *err = NULL;
gssize nwrote;
nwrote = g_output_stream_write_finish (out, res, &err);
if (g_cancellable_is_cancelled (main_cancel))
{
do_main_cancel (out);
return;
}
g_assert (err == NULL);
g_assert_cmpint (nwrote, <=, main_len - main_offset);
main_offset += nwrote;
if (main_offset == main_len)
{
g_input_stream_read_async (in, main_buf, sizeof (main_buf),
G_PRIORITY_DEFAULT, main_cancel,
readable, out);
}
else
{
g_output_stream_write_async (out, main_buf + main_offset,
main_len - main_offset,
G_PRIORITY_DEFAULT, main_cancel,
writable, in);
}
}
static gboolean
timeout (gpointer cancellable)
{
g_cancellable_cancel (cancellable);
return FALSE;
}
static void
test_pipe_io (void)
{
GThread *writer, *reader;
GInputStream *in;
GOutputStream *out;
/* Split off two (additional) threads, a reader and a writer. From
* the writer thread, write data synchronously in small chunks,
* which gets read asynchronously by the main thread and then
* written asynchronously to the reader thread, which reads it
* synchronously. Eventually a timeout in the main thread will cause
* it to cancel the writer thread, which will in turn cancel the
* read op in the main thread, which will then close the pipe to
* the reader thread, causing the read op to fail.
*/
g_assert (pipe (writer_pipe) == 0 && pipe (reader_pipe) == 0);
writer_cancel = g_cancellable_new ();
reader_cancel = g_cancellable_new ();
main_cancel = g_cancellable_new ();
writer = g_thread_create (writer_thread, NULL, TRUE, NULL);
reader = g_thread_create (reader_thread, NULL, TRUE, NULL);
in = g_unix_input_stream_new (writer_pipe[0], TRUE);
out = g_unix_output_stream_new (reader_pipe[1], TRUE);
g_input_stream_read_async (in, main_buf, sizeof (main_buf),
G_PRIORITY_DEFAULT, main_cancel,
readable, out);
g_timeout_add (500, timeout, writer_cancel);
loop = g_main_loop_new (NULL, TRUE);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_thread_join (reader);
g_thread_join (writer);
g_object_unref (main_cancel);
g_object_unref (reader_cancel);
g_object_unref (writer_cancel);
g_object_unref (in);
g_object_unref (out);
}
int
main (int argc,
char *argv[])
{
g_thread_init (NULL);
g_type_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/unix-streams/pipe-io-test", test_pipe_io);
return g_test_run();
}