Import Upstream version 2.72.4

This commit is contained in:
evinadmin 2023-07-04 11:23:22 +02:00
commit 4ef3ff9793
2003 changed files with 1332420 additions and 0 deletions

89
glib/tests/.gitignore vendored Normal file
View file

@ -0,0 +1,89 @@
1bit-emufutex
1bit-mutex
642026
642026-ec
array-test
asyncqueue
atomic
autoptr
base64
bitlock
bookmarkfile
bytes
cache
checksum
collate
cond
convert
dataset
date
dir
environment
error
fileutils
gdatetime
guuid
gvariant
gwakeup
gwakeup-fallback
hash
hmac
hook
hostutils
include
keyfile
list
logging
mainloop
malloc
mappedfile
markup
markup-collect
markup-escape
markup-parse
markup-subparser
mem-overflow
mutex
node
once
option-argv0
option-context
overflow
overflow-fallback
pattern
private
protocol
queue
rand
rec-mutex
regex
rwlock
scannerapi
search-utils
sequence
shell
slice
slist
sort
spawn-multithreaded
spawn-singlethread
strfuncs
string
testing
test-printf
test-spawn-echo
thread
timeout
timer
tmpsample.xml
tree
unicode
unix
unix-multithreaded
unix-nothreads
uri
utf8-misc
utf8-performance
utf8-pointer
utf8-validate
utils

165
glib/tests/1bit-mutex.c Normal file
View file

@ -0,0 +1,165 @@
/*
* Copyright © 2008 Ryan Lortie
* Copyright © 2010 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#include "config.h"
/* LOCKS should be more than the number of contention
* counters in gthread.c in order to ensure we exercise
* the case where they overlap.
*/
#define LOCKS 48
#define ITERATIONS 10000
#define THREADS 100
#include <glib.h>
#if TEST_EMULATED_FUTEX
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
/* this is defined for the 1bit-mutex-emufutex test.
*
* we want to test the emulated futex even if futex(2) is available.
*/
/* side-step some glib build stuff */
#define GLIB_COMPILATION
/* rebuild gbitlock.c without futex support,
defining our own version of the g_bit_*lock symbols
*/
#undef g_pointer_bit_lock
#undef g_pointer_bit_trylock
#undef g_pointer_bit_unlock
#define g_bit_lock _emufutex_g_bit_lock
#define g_bit_trylock _emufutex_g_bit_trylock
#define g_bit_unlock _emufutex_g_bit_unlock
#define g_pointer_bit_lock _emufutex_g_pointer_bit_lock
#define g_pointer_bit_trylock _emufutex_g_pointer_bit_trylock
#define g_pointer_bit_unlock _emufutex_g_pointer_bit_unlock
#define G_BIT_LOCK_FORCE_FUTEX_EMULATION
#include <glib/gbitlock.c>
#pragma GCC diagnostic pop
#endif
volatile GThread *owners[LOCKS];
volatile gint locks[LOCKS];
volatile gpointer ptrs[LOCKS];
volatile gint bits[LOCKS];
static void
acquire (int nr,
gboolean use_pointers)
{
GThread *self;
self = g_thread_self ();
g_assert_cmpint (((gsize) ptrs) % sizeof(gint), ==, 0);
if (!(use_pointers ?
g_pointer_bit_trylock (&ptrs[nr], bits[nr])
: g_bit_trylock (&locks[nr], bits[nr])))
{
if (g_test_verbose ())
g_printerr ("thread %p going to block on lock %d\n", self, nr);
if (use_pointers)
g_pointer_bit_lock (&ptrs[nr], bits[nr]);
else
g_bit_lock (&locks[nr], bits[nr]);
}
g_assert (owners[nr] == NULL); /* hopefully nobody else is here */
owners[nr] = self;
/* let some other threads try to ruin our day */
g_thread_yield ();
g_thread_yield ();
g_thread_yield ();
g_assert (owners[nr] == self); /* hopefully this is still us... */
owners[nr] = NULL; /* make way for the next guy */
if (use_pointers)
g_pointer_bit_unlock (&ptrs[nr], bits[nr]);
else
g_bit_unlock (&locks[nr], bits[nr]);
}
static gpointer
thread_func (gpointer data)
{
gboolean use_pointers = GPOINTER_TO_INT (data);
gint i;
GRand *rand;
rand = g_rand_new ();
for (i = 0; i < ITERATIONS; i++)
acquire (g_rand_int_range (rand, 0, LOCKS), use_pointers);
g_rand_free (rand);
return NULL;
}
static void
testcase (gconstpointer data)
{
gboolean use_pointers = GPOINTER_TO_INT (data);
GThread *threads[THREADS];
int i;
#ifdef TEST_EMULATED_FUTEX
#define SUFFIX "-emufutex"
/* ensure that we are using the emulated futex by checking
* (at compile-time) for the existence of 'g_futex_address_list'
*/
g_assert (g_futex_address_list == NULL);
#else
#define SUFFIX ""
#endif
for (i = 0; i < LOCKS; i++)
bits[i] = g_random_int () % 32;
for (i = 0; i < THREADS; i++)
threads[i] = g_thread_new ("foo", thread_func,
GINT_TO_POINTER (use_pointers));
for (i = 0; i < THREADS; i++)
g_thread_join (threads[i]);
for (i = 0; i < LOCKS; i++)
{
g_assert (owners[i] == NULL);
g_assert (locks[i] == 0);
}
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_data_func ("/glib/1bit-mutex" SUFFIX "/int", (gpointer) 0, testcase);
g_test_add_data_func ("/glib/1bit-mutex" SUFFIX "/pointer", (gpointer) 1, testcase);
return g_test_run ();
}

View file

@ -0,0 +1,45 @@
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXOxdolodx0WMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWMMMMMMMMMMMMMMMMMM0l' :NMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM0c. .:KMMMMMMMMMMMWd. ,MMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN, XMMMMMMMMMk. .MMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM' oMMMMMMMMc oMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMNklclkWMMMMMM0 lMMMMMMMc ;MMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMW: .XMMMMMk OMMMMMMx ;WMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMc 'MMMMMK .MMMMMMW. dMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM. KMMMMM' 0MMMMMM0 ,KMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM: OMMMMMK OMMMMMMM0 .OMMMMMMMMMMMMMMMM
MMMMMMMMMMMMW0kONMMMMMK KMMMMMMX, ,KMMMMMMMMW. ,kMMMMMMMMMMMMMMMMMM
MMMMMMMMMMWc lWMMMMO .MMMMMMMMMKxxXMMMMMMMMMMM0. .lXMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMM; 'WMMMMN: 0MMMMMMMMMMMMMMMMMMMMMMMMMNl'. ..:xXMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMM. oMMMMMMXdldNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMx .MMMMMMMMMMMMMMMMMMMMMMMWXK0OkkkkkkO0XNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMx NMMMMMMMMMMMMMMWKko:'. .;d0WMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMK, .MMMMMMMMMMW0o;. :KMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMXo;';KMMMMMMMKo' cMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMXl. xMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMk' :MMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMO. dMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMWc ,WMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMN. cWMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMW' '0MMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMd :KMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMM. 'dNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMM 'oXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMM. ,xNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMM; .:kNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMO .l0MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM, :KMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMN. oNMMMMMMMMMMMMMXkoc:,,,,:lOWMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMX. .XMMMMMMMMMMMM0:. .XMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMN. xMMMMMMMMMMMM0 OMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMWc 'NMMMMMMMMMMMO 'WMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMO. .kMMMMMMMMMMc .XMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMWl .l0WMMMW0; .KMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMNl ... ;NMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMWd. .OMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM0c. 'xWMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM0l. .cKMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNOo;. .;dKMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNKOxxdddkOXWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.

102
glib/tests/642026.c Normal file
View file

@ -0,0 +1,102 @@
/*
* Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
* Copyright © 2011 Nokia Corporation
*
* 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <glib.h>
static GStaticPrivate sp;
static GMutex *mutex;
static GCond *cond;
static guint i;
static gint freed = 0; /* (atomic) */
static void
notify (gpointer p)
{
if (!g_atomic_int_compare_and_exchange (&freed, 0, 1))
{
g_error ("someone already freed it after %u iterations", i);
}
}
static gpointer thread_func (gpointer nil)
{
/* wait for main thread to reach its g_cond_wait call */
g_mutex_lock (mutex);
g_static_private_set (&sp, &sp, notify);
g_cond_broadcast (cond);
g_mutex_unlock (mutex);
return nil;
}
static void
testcase (void)
{
/* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5
* iterations exhibited it 10/10 times in practice. YMMV.
*
* If running with `-m slow` we want to try hard to reproduce the bug 10/10
* times. However, as of 2022 this takes around 240s on a CI machine, which
* is a long time to tie up those resources to verify that a bug fixed 10
* years ago is still fixed.
*
* So if running without `-m slow`, try 100× less hard to reproduce the bug,
* and rely on the fact that this is run under CI often enough to have a good
* chance of reproducing the bug in 1% of CI runs. */
const guint n_iterations = g_test_slow () ? 100000 : 1000;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642026");
mutex = g_mutex_new ();
cond = g_cond_new ();
g_mutex_lock (mutex);
for (i = 0; i < n_iterations; i++)
{
GThread *t1;
g_static_private_init (&sp);
g_atomic_int_set (&freed, 0);
t1 = g_thread_create (thread_func, NULL, TRUE, NULL);
g_assert (t1 != NULL);
/* wait for t1 to set up its thread-private data */
g_cond_wait (cond, mutex);
/* exercise the bug, by racing with t1 to free the private data */
g_static_private_free (&sp);
g_thread_join (t1);
}
g_cond_free (cond);
g_mutex_unlock (mutex);
g_mutex_free (mutex);
}
int
main (int argc,
char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/glib/642026", testcase);
return g_test_run ();
}

2111
glib/tests/array-test.c Normal file

File diff suppressed because it is too large Load diff

526
glib/tests/asyncqueue.c Normal file
View file

@ -0,0 +1,526 @@
/* Unit tests for GAsyncQueue
* Copyright (C) 2011 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.
*/
/* We are testing some deprecated APIs here */
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <glib.h>
static gint
compare_func (gconstpointer d1, gconstpointer d2, gpointer data)
{
gint i1, i2;
i1 = GPOINTER_TO_INT (d1);
i2 = GPOINTER_TO_INT (d2);
return i1 - i2;
}
static
void test_async_queue_sort (void)
{
GAsyncQueue *q;
q = g_async_queue_new ();
g_async_queue_push (q, GINT_TO_POINTER (10));
g_async_queue_push (q, GINT_TO_POINTER (2));
g_async_queue_push (q, GINT_TO_POINTER (7));
g_async_queue_sort (q, compare_func, NULL);
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_sorted (NULL, GINT_TO_POINTER (1),
compare_func, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_sorted_unlocked (NULL, GINT_TO_POINTER (1),
compare_func, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_sort (NULL, compare_func, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_sort (q, NULL, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_sort_unlocked (NULL, compare_func, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_sort_unlocked (q, NULL, NULL);
g_test_assert_expected_messages ();
}
g_async_queue_push_sorted (q, GINT_TO_POINTER (1), compare_func, NULL);
g_async_queue_push_sorted (q, GINT_TO_POINTER (8), compare_func, NULL);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 8);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
g_assert_null (g_async_queue_try_pop (q));
g_async_queue_unref (q);
}
static gint destroy_count;
static void
destroy_notify (gpointer item)
{
destroy_count++;
}
static void
test_async_queue_destroy (void)
{
GAsyncQueue *q;
destroy_count = 0;
q = g_async_queue_new_full (destroy_notify);
g_assert_cmpint (destroy_count, ==, 0);
g_async_queue_push (q, GINT_TO_POINTER (1));
g_async_queue_push (q, GINT_TO_POINTER (1));
g_async_queue_push (q, GINT_TO_POINTER (1));
g_async_queue_push (q, GINT_TO_POINTER (1));
g_assert_cmpint (g_async_queue_length (q), ==, 4);
g_async_queue_unref (q);
g_assert_cmpint (destroy_count, ==, 4);
}
static GAsyncQueue *q;
static GThread *threads[10];
static gint counts[10];
static gint sums[10];
static gint total;
static gpointer
thread_func (gpointer data)
{
gint pos = GPOINTER_TO_INT (data);
gint value;
while (1)
{
value = GPOINTER_TO_INT (g_async_queue_pop (q));
if (value == -1)
break;
counts[pos]++;
sums[pos] += value;
g_usleep (1000);
}
return NULL;
}
static void
test_async_queue_threads (void)
{
gint i, j;
gint s, c;
gint value;
q = g_async_queue_new ();
for (i = 0; i < 10; i++)
threads[i] = g_thread_new ("test", thread_func, GINT_TO_POINTER (i));
for (i = 0; i < 100; i++)
{
g_async_queue_lock (q);
for (j = 0; j < 10; j++)
{
value = g_random_int_range (1, 100);
total += value;
g_async_queue_push_unlocked (q, GINT_TO_POINTER (value));
}
g_async_queue_unlock (q);
g_usleep (1000);
}
for (i = 0; i < 10; i++)
g_async_queue_push (q, GINT_TO_POINTER(-1));
for (i = 0; i < 10; i++)
g_thread_join (threads[i]);
g_assert_cmpint (g_async_queue_length (q), ==, 0);
s = c = 0;
for (i = 0; i < 10; i++)
{
g_assert_cmpint (sums[i], >, 0);
g_assert_cmpint (counts[i], >, 0);
s += sums[i];
c += counts[i];
}
g_assert_cmpint (s, ==, total);
g_assert_cmpint (c, ==, 1000);
g_async_queue_unref (q);
}
static void
test_async_queue_timed (void)
{
GAsyncQueue *q;
GTimeVal tv;
gint64 start, end, diff;
gpointer val;
g_get_current_time (&tv);
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_timed_pop (NULL, &tv);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_timed_pop_unlocked (NULL, &tv);
g_test_assert_expected_messages ();
}
q = g_async_queue_new ();
start = g_get_monotonic_time ();
g_assert_null (g_async_queue_timeout_pop (q, G_USEC_PER_SEC / 10));
end = g_get_monotonic_time ();
diff = end - start;
g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
/* diff should be only a little bit more than G_USEC_PER_SEC/10, but
* we have to leave some wiggle room for heavily-loaded machines...
*/
g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
g_async_queue_push (q, GINT_TO_POINTER (10));
val = g_async_queue_timed_pop (q, NULL);
g_assert_cmpint (GPOINTER_TO_INT (val), ==, 10);
g_assert_null (g_async_queue_try_pop (q));
start = end;
g_get_current_time (&tv);
g_time_val_add (&tv, G_USEC_PER_SEC / 10);
g_assert_null (g_async_queue_timed_pop (q, &tv));
end = g_get_monotonic_time ();
diff = end - start;
g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
g_async_queue_push (q, GINT_TO_POINTER (10));
val = g_async_queue_timed_pop_unlocked (q, NULL);
g_assert_cmpint (GPOINTER_TO_INT (val), ==, 10);
g_assert_null (g_async_queue_try_pop (q));
start = end;
g_get_current_time (&tv);
g_time_val_add (&tv, G_USEC_PER_SEC / 10);
g_async_queue_lock (q);
g_assert_null (g_async_queue_timed_pop_unlocked (q, &tv));
g_async_queue_unlock (q);
end = g_get_monotonic_time ();
diff = end - start;
g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
g_async_queue_unref (q);
}
static void
test_async_queue_remove (void)
{
GAsyncQueue *q;
q = g_async_queue_new ();
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_remove (NULL, GINT_TO_POINTER (1));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_remove (q, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_remove_unlocked (NULL, GINT_TO_POINTER (1));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_remove_unlocked (q, NULL);
g_test_assert_expected_messages ();
}
g_async_queue_push (q, GINT_TO_POINTER (10));
g_async_queue_push (q, GINT_TO_POINTER (2));
g_async_queue_push (q, GINT_TO_POINTER (7));
g_async_queue_push (q, GINT_TO_POINTER (1));
g_async_queue_remove (q, GINT_TO_POINTER (7));
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
g_assert_null (g_async_queue_try_pop (q));
g_async_queue_unref (q);
}
static void
test_async_queue_push_front (void)
{
GAsyncQueue *q;
q = g_async_queue_new ();
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_front (NULL, GINT_TO_POINTER (1));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_front (q, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_front_unlocked (NULL, GINT_TO_POINTER (1));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_front_unlocked (q, NULL);
g_test_assert_expected_messages ();
}
g_async_queue_push (q, GINT_TO_POINTER (10));
g_async_queue_push (q, GINT_TO_POINTER (2));
g_async_queue_push (q, GINT_TO_POINTER (7));
g_async_queue_push_front (q, GINT_TO_POINTER (1));
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7);
g_assert_null (g_async_queue_try_pop (q));
g_async_queue_unref (q);
}
static void
test_basics (void)
{
GAsyncQueue *q;
gpointer item;
destroy_count = 0;
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_length (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_length_unlocked (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_ref (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_ref_unlocked (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_unref (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_unref_and_unlock (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_lock (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_unlock (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_pop (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_pop_unlocked (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_try_pop (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_try_pop_unlocked (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_timeout_pop (NULL, 1);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_timeout_pop_unlocked (NULL, 1);
g_test_assert_expected_messages ();
}
q = g_async_queue_new_full (destroy_notify);
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push (NULL, GINT_TO_POINTER (1));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push (q, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_unlocked (NULL, GINT_TO_POINTER (1));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* failed*");
g_async_queue_push_unlocked (q, NULL);
g_test_assert_expected_messages ();
}
g_async_queue_lock (q);
g_async_queue_ref (q);
g_async_queue_unlock (q);
g_async_queue_lock (q);
g_async_queue_ref_unlocked (q);
g_async_queue_unref_and_unlock (q);
item = g_async_queue_try_pop (q);
g_assert_null (item);
g_async_queue_lock (q);
item = g_async_queue_try_pop_unlocked (q);
g_async_queue_unlock (q);
g_assert_null (item);
g_async_queue_push (q, GINT_TO_POINTER (1));
g_async_queue_push (q, GINT_TO_POINTER (2));
g_async_queue_push (q, GINT_TO_POINTER (3));
g_assert_cmpint (destroy_count, ==, 0);
g_async_queue_unref (q);
g_assert_cmpint (destroy_count, ==, 0);
item = g_async_queue_pop (q);
g_assert_cmpint (GPOINTER_TO_INT (item), ==, 1);
g_assert_cmpint (destroy_count, ==, 0);
g_async_queue_unref (q);
g_assert_cmpint (destroy_count, ==, 2);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/asyncqueue/basics", test_basics);
g_test_add_func ("/asyncqueue/sort", test_async_queue_sort);
g_test_add_func ("/asyncqueue/destroy", test_async_queue_destroy);
g_test_add_func ("/asyncqueue/threads", test_async_queue_threads);
g_test_add_func ("/asyncqueue/timed", test_async_queue_timed);
g_test_add_func ("/asyncqueue/remove", test_async_queue_remove);
g_test_add_func ("/asyncqueue/push_front", test_async_queue_push_front);
return g_test_run ();
}

314
glib/tests/atomic.c Normal file
View file

@ -0,0 +1,314 @@
/*
* Copyright 2011 Red Hat, Inc.
*
* 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#include <glib.h>
/* We want the g_atomic_pointer_get() macros to work when compiling third party
* projects with -Wbad-function-cast.
* See https://gitlab.gnome.org/GNOME/glib/issues/1041. */
#pragma GCC diagnostic error "-Wbad-function-cast"
static void
test_types (void)
{
const gint *csp;
const gint * const *cspp;
guint u, u2;
gint s, s2;
gpointer vp, vp2;
const char *vp_str;
const char *volatile vp_str_vol;
const char *str = "Hello";
int *ip, *ip2;
gsize gs, gs2;
gboolean res;
csp = &s;
cspp = &csp;
g_atomic_int_set (&u, 5);
u2 = (guint) g_atomic_int_get (&u);
g_assert_cmpint (u2, ==, 5);
res = g_atomic_int_compare_and_exchange (&u, 6, 7);
g_assert_false (res);
g_assert_cmpint (u, ==, 5);
g_atomic_int_add (&u, 1);
g_assert_cmpint (u, ==, 6);
g_atomic_int_inc (&u);
g_assert_cmpint (u, ==, 7);
res = g_atomic_int_dec_and_test (&u);
g_assert_false (res);
g_assert_cmpint (u, ==, 6);
u2 = g_atomic_int_and (&u, 5);
g_assert_cmpint (u2, ==, 6);
g_assert_cmpint (u, ==, 4);
u2 = g_atomic_int_or (&u, 8);
g_assert_cmpint (u2, ==, 4);
g_assert_cmpint (u, ==, 12);
u2 = g_atomic_int_xor (&u, 4);
g_assert_cmpint (u2, ==, 12);
g_assert_cmpint (u, ==, 8);
g_atomic_int_set (&s, 5);
s2 = g_atomic_int_get (&s);
g_assert_cmpint (s2, ==, 5);
res = g_atomic_int_compare_and_exchange (&s, 6, 7);
g_assert_false (res);
g_assert_cmpint (s, ==, 5);
g_atomic_int_add (&s, 1);
g_assert_cmpint (s, ==, 6);
g_atomic_int_inc (&s);
g_assert_cmpint (s, ==, 7);
res = g_atomic_int_dec_and_test (&s);
g_assert_false (res);
g_assert_cmpint (s, ==, 6);
s2 = (gint) g_atomic_int_and (&s, 5);
g_assert_cmpint (s2, ==, 6);
g_assert_cmpint (s, ==, 4);
s2 = (gint) g_atomic_int_or (&s, 8);
g_assert_cmpint (s2, ==, 4);
g_assert_cmpint (s, ==, 12);
s2 = (gint) g_atomic_int_xor (&s, 4);
g_assert_cmpint (s2, ==, 12);
g_assert_cmpint (s, ==, 8);
g_atomic_pointer_set (&vp, 0);
vp2 = g_atomic_pointer_get (&vp);
g_assert_true (vp2 == 0);
res = g_atomic_pointer_compare_and_exchange (&vp, &s, &s);
g_assert_false (res);
g_assert_true (vp == 0);
res = g_atomic_pointer_compare_and_exchange (&vp, NULL, NULL);
g_assert_true (res);
g_assert_true (vp == 0);
g_atomic_pointer_set (&vp_str, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, str);
g_assert_true (res);
/* Note that atomic variables should almost certainly not be marked as
* `volatile` see http://isvolatileusefulwiththreads.in/c/. This test exists
* to make sure that we dont warn when built against older third party code. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
g_atomic_pointer_set (&vp_str_vol, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str);
g_assert_true (res);
#pragma GCC diagnostic pop
g_atomic_pointer_set (&ip, 0);
ip2 = g_atomic_pointer_get (&ip);
g_assert_true (ip2 == 0);
res = g_atomic_pointer_compare_and_exchange (&ip, NULL, NULL);
g_assert_true (res);
g_assert_true (ip == 0);
g_atomic_pointer_set (&gs, 0);
vp2 = (gpointer) g_atomic_pointer_get (&gs);
gs2 = (gsize) vp2;
g_assert_cmpuint (gs2, ==, 0);
res = g_atomic_pointer_compare_and_exchange (&gs, NULL, (gsize) NULL);
g_assert_true (res);
g_assert_cmpuint (gs, ==, 0);
gs2 = (gsize) g_atomic_pointer_add (&gs, 5);
g_assert_cmpuint (gs2, ==, 0);
g_assert_cmpuint (gs, ==, 5);
gs2 = g_atomic_pointer_and (&gs, 6);
g_assert_cmpuint (gs2, ==, 5);
g_assert_cmpuint (gs, ==, 4);
gs2 = g_atomic_pointer_or (&gs, 8);
g_assert_cmpuint (gs2, ==, 4);
g_assert_cmpuint (gs, ==, 12);
gs2 = g_atomic_pointer_xor (&gs, 4);
g_assert_cmpuint (gs2, ==, 12);
g_assert_cmpuint (gs, ==, 8);
g_assert_cmpint (g_atomic_int_get (csp), ==, s);
g_assert_true (g_atomic_pointer_get ((const gint **) cspp) == csp);
/* repeat, without the macros */
#undef g_atomic_int_set
#undef g_atomic_int_get
#undef g_atomic_int_compare_and_exchange
#undef g_atomic_int_add
#undef g_atomic_int_inc
#undef g_atomic_int_and
#undef g_atomic_int_or
#undef g_atomic_int_xor
#undef g_atomic_int_dec_and_test
#undef g_atomic_pointer_set
#undef g_atomic_pointer_get
#undef g_atomic_pointer_compare_and_exchange
#undef g_atomic_pointer_add
#undef g_atomic_pointer_and
#undef g_atomic_pointer_or
#undef g_atomic_pointer_xor
g_atomic_int_set ((gint*)&u, 5);
u2 = (guint) g_atomic_int_get ((gint*)&u);
g_assert_cmpint (u2, ==, 5);
res = g_atomic_int_compare_and_exchange ((gint*)&u, 6, 7);
g_assert_false (res);
g_assert_cmpint (u, ==, 5);
g_atomic_int_add ((gint*)&u, 1);
g_assert_cmpint (u, ==, 6);
g_atomic_int_inc ((gint*)&u);
g_assert_cmpint (u, ==, 7);
res = g_atomic_int_dec_and_test ((gint*)&u);
g_assert_false (res);
g_assert_cmpint (u, ==, 6);
u2 = g_atomic_int_and (&u, 5);
g_assert_cmpint (u2, ==, 6);
g_assert_cmpint (u, ==, 4);
u2 = g_atomic_int_or (&u, 8);
g_assert_cmpint (u2, ==, 4);
g_assert_cmpint (u, ==, 12);
u2 = g_atomic_int_xor (&u, 4);
g_assert_cmpint (u2, ==, 12);
g_atomic_int_set (&s, 5);
s2 = g_atomic_int_get (&s);
g_assert_cmpint (s2, ==, 5);
res = g_atomic_int_compare_and_exchange (&s, 6, 7);
g_assert_false (res);
g_assert_cmpint (s, ==, 5);
g_atomic_int_add (&s, 1);
g_assert_cmpint (s, ==, 6);
g_atomic_int_inc (&s);
g_assert_cmpint (s, ==, 7);
res = g_atomic_int_dec_and_test (&s);
g_assert_false (res);
g_assert_cmpint (s, ==, 6);
s2 = (gint) g_atomic_int_and ((guint*)&s, 5);
g_assert_cmpint (s2, ==, 6);
g_assert_cmpint (s, ==, 4);
s2 = (gint) g_atomic_int_or ((guint*)&s, 8);
g_assert_cmpint (s2, ==, 4);
g_assert_cmpint (s, ==, 12);
s2 = (gint) g_atomic_int_xor ((guint*)&s, 4);
g_assert_cmpint (s2, ==, 12);
g_assert_cmpint (s, ==, 8);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
s2 = g_atomic_int_exchange_and_add ((gint*)&s, 1);
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_cmpint (s2, ==, 8);
g_assert_cmpint (s, ==, 9);
g_atomic_pointer_set (&vp, 0);
vp2 = g_atomic_pointer_get (&vp);
g_assert_true (vp2 == 0);
res = g_atomic_pointer_compare_and_exchange (&vp, &s, &s);
g_assert_false (res);
g_assert_true (vp == 0);
res = g_atomic_pointer_compare_and_exchange (&vp, NULL, NULL);
g_assert_true (res);
g_assert_true (vp == 0);
g_atomic_pointer_set (&vp_str, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, (char *) str);
g_assert_true (res);
/* Note that atomic variables should almost certainly not be marked as
* `volatile` see http://isvolatileusefulwiththreads.in/c/. This test exists
* to make sure that we dont warn when built against older third party code. */
g_atomic_pointer_set (&vp_str_vol, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, (char *) str);
g_assert_true (res);
g_atomic_pointer_set (&ip, 0);
ip2 = g_atomic_pointer_get (&ip);
g_assert_true (ip2 == 0);
res = g_atomic_pointer_compare_and_exchange (&ip, NULL, NULL);
g_assert_true (res);
g_assert_true (ip == 0);
g_atomic_pointer_set (&gs, 0);
vp = g_atomic_pointer_get (&gs);
gs2 = (gsize) vp;
g_assert_cmpuint (gs2, ==, 0);
res = g_atomic_pointer_compare_and_exchange (&gs, NULL, NULL);
g_assert_true (res);
g_assert_cmpuint (gs, ==, 0);
gs2 = (gsize) g_atomic_pointer_add (&gs, 5);
g_assert_cmpuint (gs2, ==, 0);
g_assert_cmpuint (gs, ==, 5);
gs2 = g_atomic_pointer_and (&gs, 6);
g_assert_cmpuint (gs2, ==, 5);
g_assert_cmpuint (gs, ==, 4);
gs2 = g_atomic_pointer_or (&gs, 8);
g_assert_cmpuint (gs2, ==, 4);
g_assert_cmpuint (gs, ==, 12);
gs2 = g_atomic_pointer_xor (&gs, 4);
g_assert_cmpuint (gs2, ==, 12);
g_assert_cmpuint (gs, ==, 8);
g_assert_cmpint (g_atomic_int_get (csp), ==, s);
g_assert_true (g_atomic_pointer_get (cspp) == csp);
}
#define THREADS 10
#define ROUNDS 10000
gint bucket[THREADS]; /* never contested by threads, not accessed atomically */
gint atomic; /* (atomic) */
static gpointer
thread_func (gpointer data)
{
gint idx = GPOINTER_TO_INT (data);
gint i;
gint d;
for (i = 0; i < ROUNDS; i++)
{
d = g_random_int_range (-10, 100);
bucket[idx] += d;
g_atomic_int_add (&atomic, d);
g_thread_yield ();
}
return NULL;
}
static void
test_threaded (void)
{
gint sum;
gint i;
GThread *threads[THREADS];
atomic = 0;
for (i = 0; i < THREADS; i++)
bucket[i] = 0;
for (i = 0; i < THREADS; i++)
threads[i] = g_thread_new ("atomic", thread_func, GINT_TO_POINTER (i));
for (i = 0; i < THREADS; i++)
g_thread_join (threads[i]);
sum = 0;
for (i = 0; i < THREADS; i++)
sum += bucket[i];
g_assert_cmpint (sum, ==, atomic);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/atomic/types", test_types);
g_test_add_func ("/atomic/threaded", test_threaded);
return g_test_run ();
}

767
glib/tests/autoptr.c Normal file
View file

@ -0,0 +1,767 @@
#include <glib.h>
#include <string.h>
typedef struct _HNVC HasNonVoidCleanup;
HasNonVoidCleanup * non_void_cleanup (HasNonVoidCleanup *);
/* Should not cause any warnings with -Wextra */
G_DEFINE_AUTOPTR_CLEANUP_FUNC(HasNonVoidCleanup, non_void_cleanup)
static void
test_autofree (void)
{
#ifdef __clang_analyzer__
g_test_skip ("autofree tests arent understood by the clang analyser");
#else
g_autofree gchar *p = NULL;
g_autofree gchar *p2 = NULL;
g_autofree gchar *alwaysnull = NULL;
p = g_malloc (10);
p2 = g_malloc (42);
if (TRUE)
{
g_autofree guint8 *buf = g_malloc (128);
g_autofree gchar *alwaysnull_again = NULL;
buf[0] = 1;
g_assert_null (alwaysnull_again);
}
if (TRUE)
{
g_autofree guint8 *buf2 = g_malloc (256);
buf2[255] = 42;
}
g_assert_null (alwaysnull);
#endif /* __clang_analyzer__ */
}
static void
test_g_async_queue (void)
{
g_autoptr(GAsyncQueue) val = g_async_queue_new ();
g_assert_nonnull (val);
}
static void
test_g_bookmark_file (void)
{
g_autoptr(GBookmarkFile) val = g_bookmark_file_new ();
g_assert_nonnull (val);
}
static void
test_g_bytes (void)
{
g_autoptr(GBytes) val = g_bytes_new ("foo", 3);
g_assert_nonnull (val);
}
static void
test_g_checksum (void)
{
g_autoptr(GChecksum) val = g_checksum_new (G_CHECKSUM_SHA256);
g_assert_nonnull (val);
}
static void
test_g_date (void)
{
g_autoptr(GDate) val = g_date_new ();
g_assert_nonnull (val);
}
static void
test_g_date_time (void)
{
g_autoptr(GDateTime) val = g_date_time_new_now_utc ();
g_assert_nonnull (val);
}
static void
test_g_dir (void)
{
g_autoptr(GDir) val = g_dir_open (".", 0, NULL);
g_assert_nonnull (val);
}
static void
test_g_error (void)
{
g_autoptr(GError) val = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED, "oops");
g_assert_nonnull (val);
}
static void
test_g_hash_table (void)
{
g_autoptr(GHashTable) val = g_hash_table_new (NULL, NULL);
g_assert_nonnull (val);
}
static void
test_g_hmac (void)
{
g_autoptr(GHmac) val = g_hmac_new (G_CHECKSUM_SHA256, (guint8*)"hello", 5);
g_assert_nonnull (val);
}
static void
test_g_io_channel (void)
{
#ifdef G_OS_WIN32
const gchar *devnull = "nul";
#else
const gchar *devnull = "/dev/null";
#endif
g_autoptr(GIOChannel) val = g_io_channel_new_file (devnull, "r", NULL);
g_assert_nonnull (val);
}
static void
test_g_key_file (void)
{
g_autoptr(GKeyFile) val = g_key_file_new ();
g_assert_nonnull (val);
}
static void
test_g_list (void)
{
g_autoptr(GList) val = NULL;
g_autoptr(GList) val2 = g_list_prepend (NULL, "foo");
g_assert_null (val);
g_assert_nonnull (val2);
}
static void
test_g_array (void)
{
g_autoptr(GArray) val = g_array_new (0, 0, sizeof (gpointer));
g_assert_nonnull (val);
}
static void
test_g_ptr_array (void)
{
g_autoptr(GPtrArray) val = g_ptr_array_new ();
g_assert_nonnull (val);
}
static void
test_g_byte_array (void)
{
g_autoptr(GByteArray) val = g_byte_array_new ();
g_assert_nonnull (val);
}
static void
test_g_main_context (void)
{
g_autoptr(GMainContext) val = g_main_context_new ();
g_assert_nonnull (val);
}
static void
test_g_main_context_pusher (void)
{
GMainContext *context, *old_thread_default;
context = g_main_context_new ();
old_thread_default = g_main_context_get_thread_default ();
g_assert_false (old_thread_default == context);
if (TRUE)
{
g_autoptr(GMainContextPusher) val = g_main_context_pusher_new (context);
g_assert_nonnull (val);
/* Check its now the thread-default main context */
g_assert_true (g_main_context_get_thread_default () == context);
}
/* Check its now the old thread-default main context */
g_assert_false (g_main_context_get_thread_default () == context);
g_assert_true (g_main_context_get_thread_default () == old_thread_default);
g_main_context_unref (context);
}
static void
test_g_main_loop (void)
{
g_autoptr(GMainLoop) val = g_main_loop_new (NULL, TRUE);
g_assert_nonnull (val);
}
static void
test_g_source (void)
{
g_autoptr(GSource) val = g_timeout_source_new_seconds (2);
g_assert_nonnull (val);
}
static void
test_g_mapped_file (void)
{
g_autoptr(GMappedFile) val = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "keyfiletest.ini", NULL), FALSE, NULL);
g_assert_nonnull (val);
}
static void
parser_start (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
}
static void
parser_end (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
}
static GMarkupParser parser = {
.start_element = parser_start,
.end_element = parser_end
};
static void
test_g_markup_parse_context (void)
{
g_autoptr(GMarkupParseContext) val = g_markup_parse_context_new (&parser, 0, NULL, NULL);
g_assert_nonnull (val);
}
static void
test_g_node (void)
{
g_autoptr(GNode) val = g_node_new ("hello");
g_assert_nonnull (val);
}
static void
test_g_option_context (void)
{
g_autoptr(GOptionContext) val = g_option_context_new ("hello");
g_assert_nonnull (val);
}
static void
test_g_option_group (void)
{
g_autoptr(GOptionGroup) val = g_option_group_new ("hello", "world", "helpme", NULL, NULL);
g_assert_nonnull (val);
}
static void
test_g_pattern_spec (void)
{
g_autoptr(GPatternSpec) val = g_pattern_spec_new ("plaid");
g_assert_nonnull (val);
}
static void
test_g_queue (void)
{
g_autoptr(GQueue) val = g_queue_new ();
g_auto(GQueue) stackval = G_QUEUE_INIT;
g_assert_nonnull (val);
g_assert_null (stackval.head);
}
static void
test_g_rand (void)
{
g_autoptr(GRand) val = g_rand_new ();
g_assert_nonnull (val);
}
static void
test_g_regex (void)
{
g_autoptr(GRegex) val = g_regex_new (".*", 0, 0, NULL);
g_assert_nonnull (val);
}
static void
test_g_match_info (void)
{
g_autoptr(GRegex) regex = g_regex_new (".*", 0, 0, NULL);
g_autoptr(GMatchInfo) match = NULL;
if (!g_regex_match (regex, "hello", 0, &match))
g_assert_not_reached ();
}
static void
test_g_scanner (void)
{
GScannerConfig config = { 0, };
g_autoptr(GScanner) val = g_scanner_new (&config);
g_assert_nonnull (val);
}
static void
test_g_sequence (void)
{
g_autoptr(GSequence) val = g_sequence_new (NULL);
g_assert_nonnull (val);
}
static void
test_g_slist (void)
{
g_autoptr(GSList) val = NULL;
g_autoptr(GSList) nonempty_val = g_slist_prepend (NULL, "hello");
g_assert_null (val);
g_assert_nonnull (nonempty_val);
}
static void
test_g_string (void)
{
g_autoptr(GString) val = g_string_new ("");
g_assert_nonnull (val);
}
static void
test_g_string_chunk (void)
{
g_autoptr(GStringChunk) val = g_string_chunk_new (42);
g_assert_nonnull (val);
}
static gpointer
mythread (gpointer data)
{
g_usleep (G_USEC_PER_SEC);
return NULL;
}
static void
test_g_thread (void)
{
g_autoptr(GThread) val = g_thread_new ("bob", mythread, NULL);
g_assert_nonnull (val);
}
static void
test_g_mutex (void)
{
g_auto(GMutex) val;
g_mutex_init (&val);
}
/* Thread function to check that a mutex given in @data is locked */
static gpointer
mutex_locked_thread (gpointer data)
{
GMutex *mutex = (GMutex *) data;
g_assert_false (g_mutex_trylock (mutex));
return NULL;
}
/* Thread function to check that a mutex given in @data is unlocked */
static gpointer
mutex_unlocked_thread (gpointer data)
{
GMutex *mutex = (GMutex *) data;
g_assert_true (g_mutex_trylock (mutex));
g_mutex_unlock (mutex);
return NULL;
}
static void
test_g_mutex_locker (void)
{
GMutex mutex;
GThread *thread;
g_mutex_init (&mutex);
if (TRUE)
{
g_autoptr(GMutexLocker) val = g_mutex_locker_new (&mutex);
g_assert_nonnull (val);
/* Verify that the mutex is actually locked */
thread = g_thread_new ("mutex locked", mutex_locked_thread, &mutex);
g_thread_join (thread);
}
/* Verify that the mutex is unlocked again */
thread = g_thread_new ("mutex unlocked", mutex_unlocked_thread, &mutex);
g_thread_join (thread);
}
/* Thread function to check that a recursive mutex given in @data is locked */
static gpointer
rec_mutex_locked_thread (gpointer data)
{
GRecMutex *rec_mutex = (GRecMutex *) data;
g_assert_false (g_rec_mutex_trylock (rec_mutex));
return NULL;
}
/* Thread function to check that a recursive mutex given in @data is unlocked */
static gpointer
rec_mutex_unlocked_thread (gpointer data)
{
GRecMutex *rec_mutex = (GRecMutex *) data;
g_assert_true (g_rec_mutex_trylock (rec_mutex));
return NULL;
}
static void
test_g_rec_mutex_locker (void)
{
GRecMutex rec_mutex;
GThread *thread;
g_rec_mutex_init (&rec_mutex);
if (TRUE)
{
g_autoptr(GRecMutexLocker) val = g_rec_mutex_locker_new (&rec_mutex);
g_assert_nonnull (val);
/* Verify that the mutex is actually locked */
thread = g_thread_new ("rec mutex locked", rec_mutex_locked_thread, &rec_mutex);
g_thread_join (thread);
}
/* Verify that the mutex is unlocked again */
thread = g_thread_new ("rec mutex unlocked", rec_mutex_unlocked_thread, &rec_mutex);
g_thread_join (thread);
g_rec_mutex_clear (&rec_mutex);
}
/* Thread function to check that an rw lock given in @data cannot be writer locked */
static gpointer
rw_lock_cannot_take_writer_lock_thread (gpointer data)
{
GRWLock *lock = (GRWLock *) data;
g_assert_false (g_rw_lock_writer_trylock (lock));
return NULL;
}
/* Thread function to check that an rw lock given in @data can be reader locked */
static gpointer
rw_lock_can_take_reader_lock_thread (gpointer data)
{
GRWLock *lock = (GRWLock *) data;
g_assert_true (g_rw_lock_reader_trylock (lock));
g_rw_lock_reader_unlock (lock);
return NULL;
}
static void
test_g_rw_lock_lockers (void)
{
GRWLock lock;
GThread *thread;
g_rw_lock_init (&lock);
if (TRUE)
{
g_autoptr(GRWLockWriterLocker) val = g_rw_lock_writer_locker_new (&lock);
g_assert_nonnull (val);
/* Verify that we cannot take another writer lock as a writer lock is currently held */
thread = g_thread_new ("rw lock cannot take writer lock", rw_lock_cannot_take_writer_lock_thread, &lock);
g_thread_join (thread);
/* Verify that we cannot take a reader lock as a writer lock is currently held */
g_assert_false (g_rw_lock_reader_trylock (&lock));
}
if (TRUE)
{
g_autoptr(GRWLockReaderLocker) val = g_rw_lock_reader_locker_new (&lock);
g_assert_nonnull (val);
/* Verify that we can take another reader lock from another thread */
thread = g_thread_new ("rw lock can take reader lock", rw_lock_can_take_reader_lock_thread, &lock);
g_thread_join (thread);
/* ... and also that recursive reader locking from the same thread works */
g_assert_true (g_rw_lock_reader_trylock (&lock));
g_rw_lock_reader_unlock (&lock);
/* Verify that we cannot take a writer lock as a reader lock is currently held */
thread = g_thread_new ("rw lock cannot take writer lock", rw_lock_cannot_take_writer_lock_thread, &lock);
g_thread_join (thread);
}
/* Verify that we can take a writer lock again: this can only work if all of
* the locks taken above have been correctly released. */
g_assert_true (g_rw_lock_writer_trylock (&lock));
g_rw_lock_writer_unlock (&lock);
g_rw_lock_clear (&lock);
}
static void
test_g_cond (void)
{
g_auto(GCond) val;
g_cond_init (&val);
}
static void
test_g_timer (void)
{
g_autoptr(GTimer) val = g_timer_new ();
g_assert_nonnull (val);
}
static void
test_g_time_zone (void)
{
g_autoptr(GTimeZone) val = g_time_zone_new_utc ();
g_assert_nonnull (val);
}
static void
test_g_tree (void)
{
g_autoptr(GTree) val = g_tree_new ((GCompareFunc)strcmp);
g_assert_nonnull (val);
}
static void
test_g_variant (void)
{
g_autoptr(GVariant) val = g_variant_new_string ("hello");
g_assert_nonnull (val);
}
static void
test_g_variant_builder (void)
{
g_autoptr(GVariantBuilder) val = g_variant_builder_new (G_VARIANT_TYPE ("as"));
g_auto(GVariantBuilder) stackval;
g_assert_nonnull (val);
g_variant_builder_init (&stackval, G_VARIANT_TYPE ("as"));
}
static void
test_g_variant_iter (void)
{
g_autoptr(GVariant) var = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, "", 0, sizeof(guint32));
g_autoptr(GVariantIter) val = g_variant_iter_new (var);
g_assert_nonnull (val);
}
static void
test_g_variant_dict (void)
{
g_autoptr(GVariant) data = g_variant_new_from_data (G_VARIANT_TYPE ("a{sv}"), "", 0, FALSE, NULL, NULL);
g_auto(GVariantDict) stackval;
g_autoptr(GVariantDict) val = g_variant_dict_new (data);
g_variant_dict_init (&stackval, data);
g_assert_nonnull (val);
}
static void
test_g_variant_type (void)
{
g_autoptr(GVariantType) val = g_variant_type_new ("s");
g_assert_nonnull (val);
}
static void
test_strv (void)
{
g_auto(GStrv) val = g_strsplit("a:b:c", ":", -1);
g_assert_nonnull (val);
}
static void
test_refstring (void)
{
g_autoptr(GRefString) str = g_ref_string_new ("hello, world");
g_assert_nonnull (str);
}
static void
mark_freed (gpointer ptr)
{
gboolean *freed = ptr;
*freed = TRUE;
}
static void
test_autolist (void)
{
char data[1] = {0};
gboolean freed1 = FALSE;
gboolean freed2 = FALSE;
gboolean freed3 = FALSE;
GBytes *b1 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed1);
GBytes *b2 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed2);
GBytes *b3 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed3);
{
g_autolist(GBytes) l = NULL;
l = g_list_prepend (l, b1);
l = g_list_prepend (l, b3);
/* Squash warnings about dead stores */
(void) l;
}
/* Only assert if autoptr works */
#ifdef __GNUC__
g_assert_true (freed1);
g_assert_true (freed3);
#endif
g_assert_false (freed2);
g_bytes_unref (b2);
g_assert_true (freed2);
}
static void
test_autoslist (void)
{
char data[1] = {0};
gboolean freed1 = FALSE;
gboolean freed2 = FALSE;
gboolean freed3 = FALSE;
GBytes *b1 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed1);
GBytes *b2 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed2);
GBytes *b3 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed3);
{
g_autoslist(GBytes) l = NULL;
l = g_slist_prepend (l, b1);
l = g_slist_prepend (l, b3);
}
/* Only assert if autoptr works */
#ifdef __GNUC__
g_assert_true (freed1);
g_assert_true (freed3);
#endif
g_assert_false (freed2);
g_bytes_unref (b2);
g_assert_true (freed2);
}
static void
test_autoqueue (void)
{
char data[1] = {0};
gboolean freed1 = FALSE;
gboolean freed2 = FALSE;
gboolean freed3 = FALSE;
GBytes *b1 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed1);
GBytes *b2 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed2);
GBytes *b3 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed3);
{
g_autoqueue(GBytes) q = g_queue_new ();
g_queue_push_head (q, b1);
g_queue_push_tail (q, b3);
}
/* Only assert if autoptr works */
#ifdef __GNUC__
g_assert_true (freed1);
g_assert_true (freed3);
#endif
g_assert_false (freed2);
g_bytes_unref (b2);
g_assert_true (freed2);
}
int
main (int argc, gchar *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/autoptr/autofree", test_autofree);
g_test_add_func ("/autoptr/g_async_queue", test_g_async_queue);
g_test_add_func ("/autoptr/g_bookmark_file", test_g_bookmark_file);
g_test_add_func ("/autoptr/g_bytes", test_g_bytes);
g_test_add_func ("/autoptr/g_checksum", test_g_checksum);
g_test_add_func ("/autoptr/g_date", test_g_date);
g_test_add_func ("/autoptr/g_date_time", test_g_date_time);
g_test_add_func ("/autoptr/g_dir", test_g_dir);
g_test_add_func ("/autoptr/g_error", test_g_error);
g_test_add_func ("/autoptr/g_hash_table", test_g_hash_table);
g_test_add_func ("/autoptr/g_hmac", test_g_hmac);
g_test_add_func ("/autoptr/g_io_channel", test_g_io_channel);
g_test_add_func ("/autoptr/g_key_file", test_g_key_file);
g_test_add_func ("/autoptr/g_list", test_g_list);
g_test_add_func ("/autoptr/g_array", test_g_array);
g_test_add_func ("/autoptr/g_ptr_array", test_g_ptr_array);
g_test_add_func ("/autoptr/g_byte_array", test_g_byte_array);
g_test_add_func ("/autoptr/g_main_context", test_g_main_context);
g_test_add_func ("/autoptr/g_main_context_pusher", test_g_main_context_pusher);
g_test_add_func ("/autoptr/g_main_loop", test_g_main_loop);
g_test_add_func ("/autoptr/g_source", test_g_source);
g_test_add_func ("/autoptr/g_mapped_file", test_g_mapped_file);
g_test_add_func ("/autoptr/g_markup_parse_context", test_g_markup_parse_context);
g_test_add_func ("/autoptr/g_node", test_g_node);
g_test_add_func ("/autoptr/g_option_context", test_g_option_context);
g_test_add_func ("/autoptr/g_option_group", test_g_option_group);
g_test_add_func ("/autoptr/g_pattern_spec", test_g_pattern_spec);
g_test_add_func ("/autoptr/g_queue", test_g_queue);
g_test_add_func ("/autoptr/g_rand", test_g_rand);
g_test_add_func ("/autoptr/g_regex", test_g_regex);
g_test_add_func ("/autoptr/g_match_info", test_g_match_info);
g_test_add_func ("/autoptr/g_scanner", test_g_scanner);
g_test_add_func ("/autoptr/g_sequence", test_g_sequence);
g_test_add_func ("/autoptr/g_slist", test_g_slist);
g_test_add_func ("/autoptr/g_string", test_g_string);
g_test_add_func ("/autoptr/g_string_chunk", test_g_string_chunk);
g_test_add_func ("/autoptr/g_thread", test_g_thread);
g_test_add_func ("/autoptr/g_mutex", test_g_mutex);
g_test_add_func ("/autoptr/g_mutex_locker", test_g_mutex_locker);
g_test_add_func ("/autoptr/g_rec_mutex_locker", test_g_rec_mutex_locker);
g_test_add_func ("/autoptr/g_rw_lock_lockers", test_g_rw_lock_lockers);
g_test_add_func ("/autoptr/g_cond", test_g_cond);
g_test_add_func ("/autoptr/g_timer", test_g_timer);
g_test_add_func ("/autoptr/g_time_zone", test_g_time_zone);
g_test_add_func ("/autoptr/g_tree", test_g_tree);
g_test_add_func ("/autoptr/g_variant", test_g_variant);
g_test_add_func ("/autoptr/g_variant_builder", test_g_variant_builder);
g_test_add_func ("/autoptr/g_variant_iter", test_g_variant_iter);
g_test_add_func ("/autoptr/g_variant_dict", test_g_variant_dict);
g_test_add_func ("/autoptr/g_variant_type", test_g_variant_type);
g_test_add_func ("/autoptr/strv", test_strv);
g_test_add_func ("/autoptr/refstring", test_refstring);
g_test_add_func ("/autoptr/autolist", test_autolist);
g_test_add_func ("/autoptr/autoslist", test_autoslist);
g_test_add_func ("/autoptr/autoqueue", test_autoqueue);
return g_test_run ();
}

542
glib/tests/base64.c Normal file
View file

@ -0,0 +1,542 @@
#include <glib.h>
#include <string.h>
#include <stdlib.h>
#define DATA_SIZE 1024
#define BLOCK_SIZE 32
#define NUM_BLOCKS 32
static guchar data[DATA_SIZE];
static void
test_incremental (gboolean line_break,
gsize length)
{
char *p;
gsize len, decoded_len, max, input_len, block_size;
int state, save;
guint decoder_save;
char *text;
guchar *data2;
data2 = g_malloc (length);
text = g_malloc (length * 4);
len = 0;
state = 0;
save = 0;
input_len = 0;
while (input_len < length)
{
block_size = MIN (BLOCK_SIZE, length - input_len);
len += g_base64_encode_step (data + input_len, block_size,
line_break, text + len, &state, &save);
input_len += block_size;
}
len += g_base64_encode_close (line_break, text + len, &state, &save);
if (line_break)
max = length * 4 / 3 + length * 4 / (3 * 72) + 7;
else
max = length * 4 / 3 + 6;
/* Check encoded length */
g_assert_cmpint (len, <=, max);
decoded_len = 0;
state = 0;
decoder_save = 0;
p = text;
while (len > 0)
{
int chunk_len = MIN (BLOCK_SIZE, len);
decoded_len += g_base64_decode_step (p,
chunk_len,
data2 + decoded_len,
&state, &decoder_save);
p += chunk_len;
len -= chunk_len;
}
g_assert_cmpmem (data, length, data2, decoded_len);
g_free (text);
g_free (data2);
}
static void
test_incremental_break (gconstpointer d)
{
gint length = GPOINTER_TO_INT (d);
test_incremental (TRUE, length);
}
static void
test_incremental_nobreak (gconstpointer d)
{
gint length = GPOINTER_TO_INT (d);
test_incremental (FALSE, length);
}
static void
test_full (gconstpointer d)
{
gint length = GPOINTER_TO_INT (d);
char *text;
guchar *data2;
gsize len;
text = g_base64_encode (data, length);
data2 = g_base64_decode (text, &len);
g_free (text);
g_assert_cmpmem (data, length, data2, len);
g_free (data2);
}
struct MyRawData
{
gint length; /* of data */
guchar data[DATA_SIZE];
};
/* 100 pre-encoded string from data[] buffer. Data length from 1..100
*/
static const char *ok_100_encode_strs[] = {
"AA==",
"AAE=",
"AAEC",
"AAECAw==",
"AAECAwQ=",
"AAECAwQF",
"AAECAwQFBg==",
"AAECAwQFBgc=",
"AAECAwQFBgcI",
"AAECAwQFBgcICQ==",
"AAECAwQFBgcICQo=",
"AAECAwQFBgcICQoL",
"AAECAwQFBgcICQoLDA==",
"AAECAwQFBgcICQoLDA0=",
"AAECAwQFBgcICQoLDA0O",
"AAECAwQFBgcICQoLDA0ODw==",
"AAECAwQFBgcICQoLDA0ODxA=",
"AAECAwQFBgcICQoLDA0ODxAR",
"AAECAwQFBgcICQoLDA0ODxAREg==",
"AAECAwQFBgcICQoLDA0ODxAREhM=",
"AAECAwQFBgcICQoLDA0ODxAREhMU",
"AAECAwQFBgcICQoLDA0ODxAREhMUFQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRY=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYX",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBk=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBka",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGw==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxw=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHg==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8g",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gIQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISI=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCU=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUm",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJw==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJyg=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygp",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKg==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKis=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDE=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEy",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMw==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Ng==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0A=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BB",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQg==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkM=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNE",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUY=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSEk=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElK",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKSw==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0w=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xN",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTg==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk8=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9Q",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVI=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJT",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFU=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVW",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWVw==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1g=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWls=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltc",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXQ==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV4=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYA==",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGE=",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFi",
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiYw==",
NULL
};
static void
generate_databuffer_for_base64 (struct MyRawData *p)
{
int i;
for (i = 0; i < DATA_SIZE; i++)
p->data[i] = i;
}
static void
test_base64_encode (void)
{
int i;
gint length = 1;
char *text;
struct MyRawData myraw;
generate_databuffer_for_base64 (&myraw);
for (i = 0; ok_100_encode_strs[i]; i++)
{
length = i + 1;
text = g_base64_encode (myraw.data, length);
g_assert_cmpstr (text, ==, ok_100_encode_strs[i]);
/* printf ("\"%s\",\n",text); */
g_free (text);
}
}
/* Test that incremental and all-in-one encoding of strings of a length which
* is not a multiple of 3 bytes behave the same, as the state carried over
* between g_base64_encode_step() calls varies depending on how the input is
* split up. This is like the test_base64_decode_smallblock() test, but for
* encoding. */
static void
test_base64_encode_incremental_small_block (gconstpointer block_size_p)
{
gsize i;
struct MyRawData myraw;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=780066");
generate_databuffer_for_base64 (&myraw);
for (i = 0; ok_100_encode_strs[i] != NULL; i++)
{
const guint block_size = GPOINTER_TO_UINT (block_size_p);
gchar *encoded_complete = NULL;
gchar encoded_stepped[1024];
gint state = 0, save = 0;
gsize len_written, len_read, len_to_read, input_length;
input_length = i + 1;
/* Do it all at once. */
encoded_complete = g_base64_encode (myraw.data, input_length);
/* Split the data up so some number of bits remain after each step. */
for (len_written = 0, len_read = 0; len_read < input_length; len_read += len_to_read)
{
len_to_read = MIN (block_size, input_length - len_read);
len_written += g_base64_encode_step (myraw.data + len_read, len_to_read,
FALSE,
encoded_stepped + len_written,
&state, &save);
}
len_written += g_base64_encode_close (FALSE, encoded_stepped + len_written,
&state, &save);
g_assert_cmpuint (len_written, <, G_N_ELEMENTS (encoded_stepped));
/* Nul-terminate to make string comparison easier. */
encoded_stepped[len_written] = '\0';
/* Compare results. They should be the same. */
g_assert_cmpstr (encoded_complete, ==, ok_100_encode_strs[i]);
g_assert_cmpstr (encoded_stepped, ==, encoded_complete);
g_free (encoded_complete);
}
}
static void
decode_and_compare (const gchar *datap,
const struct MyRawData *p)
{
guchar *data2;
gsize len;
data2 = g_base64_decode (datap, &len);
g_assert_cmpmem (p->data, p->length, data2, len);
g_free (data2);
}
static void
decode_inplace_and_compare (const gchar *datap,
const struct MyRawData *p)
{
gchar *data;
guchar *data2;
gsize len;
data = g_strdup (datap);
data2 = g_base64_decode_inplace (data, &len);
g_assert_cmpmem (p->data, p->length, data2, len);
g_free (data2);
}
static void
test_base64_decode (void)
{
int i;
struct MyRawData myraw;
generate_databuffer_for_base64 (&myraw);
for (i = 0; ok_100_encode_strs[i]; i++)
{
myraw.length = i + 1;
decode_and_compare (ok_100_encode_strs[i], &myraw);
}
}
static void
test_base64_decode_inplace (void)
{
int i;
struct MyRawData myraw;
generate_databuffer_for_base64 (&myraw);
for (i = 0; ok_100_encode_strs[i]; i++)
{
myraw.length = i + 1;
decode_inplace_and_compare (ok_100_encode_strs[i], &myraw);
}
}
static void
test_base64_encode_decode (void)
{
int i;
char *text;
struct MyRawData myraw;
generate_databuffer_for_base64 (&myraw);
for (i = 0; i < DATA_SIZE; i++)
{
myraw.length = i + 1;
text = g_base64_encode (myraw.data, myraw.length);
decode_and_compare (text, &myraw);
g_free (text);
}
}
static void
test_base64_decode_smallblock (gconstpointer blocksize_p)
{
const guint blocksize = GPOINTER_TO_UINT (blocksize_p);
guint i;
for (i = 0; ok_100_encode_strs[i]; i++)
{
const char *str = ok_100_encode_strs[i];
const char *p;
gsize len = strlen (str);
gint state = 0;
guint save = 0;
guchar *decoded;
gsize decoded_size = 0;
guchar *decoded_atonce;
gsize decoded_atonce_size = 0;
decoded = g_malloc (len / 4 * 3 + 3);
p = str;
while (len > 0)
{
int chunk_len = MIN (blocksize, len);
gsize size = g_base64_decode_step (p, chunk_len,
decoded + decoded_size,
&state, &save);
decoded_size += size;
len -= chunk_len;
p += chunk_len;
}
decoded_atonce = g_base64_decode (str, &decoded_atonce_size);
g_assert_cmpmem (decoded, decoded_size, decoded_atonce, decoded_atonce_size);
g_free (decoded);
g_free (decoded_atonce);
}
}
/* Test that calling g_base64_encode (NULL, 0) returns correct output. This is
* as per the first test vector in RFC 4648 §10.
* https://tools.ietf.org/html/rfc4648#section-10 */
static void
test_base64_encode_empty (void)
{
gchar *encoded = NULL;
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1698");
encoded = g_base64_encode (NULL, 0);
g_assert_cmpstr (encoded, ==, "");
g_free (encoded);
encoded = g_base64_encode ((const guchar *) "", 0);
g_assert_cmpstr (encoded, ==, "");
g_free (encoded);
}
/* Test that calling g_base64_decode ("", *) returns correct output. This is
* as per the first test vector in RFC 4648 §10. Note that calling
* g_base64_decode (NULL, *) is not allowed.
* https://tools.ietf.org/html/rfc4648#section-10 */
static void
test_base64_decode_empty (void)
{
guchar *decoded = NULL;
gsize decoded_len;
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1698");
decoded = g_base64_decode ("", &decoded_len);
g_assert_cmpstr ((gchar *) decoded, ==, "");
g_assert_cmpuint (decoded_len, ==, 0);
g_free (decoded);
}
/* Check all the RFC 4648 test vectors for base 64 encoding from §10.
* https://tools.ietf.org/html/rfc4648#section-10 */
static void
test_base64_encode_decode_rfc4648 (void)
{
const struct
{
const gchar *decoded; /* technically this should be a byte array, but all the test vectors are ASCII strings */
const gchar *encoded;
}
vectors[] =
{
{ "", "" },
{ "f", "Zg==" },
{ "fo", "Zm8=" },
{ "foo", "Zm9v" },
{ "foob", "Zm9vYg==" },
{ "fooba", "Zm9vYmE=" },
{ "foobar", "Zm9vYmFy" },
};
gsize i;
for (i = 0; i < G_N_ELEMENTS (vectors); i++)
{
gchar *encoded = NULL;
guchar *decoded = NULL;
gsize expected_decoded_len = strlen (vectors[i].decoded);
gsize decoded_len;
g_test_message ("Vector %" G_GSIZE_FORMAT ": %s", i, vectors[i].decoded);
encoded = g_base64_encode ((const guchar *) vectors[i].decoded, expected_decoded_len);
g_assert_cmpstr (encoded, ==, vectors[i].encoded);
decoded = g_base64_decode (encoded, &decoded_len);
g_assert_cmpstr ((gchar *) decoded, ==, vectors[i].decoded);
g_assert_cmpuint (decoded_len, ==, expected_decoded_len);
g_free (encoded);
g_free (decoded);
}
}
int
main (int argc, char *argv[])
{
gint i;
g_test_init (&argc, &argv, NULL);
for (i = 0; i < DATA_SIZE; i++)
data[i] = (guchar)i;
g_test_add_data_func ("/base64/full/1", GINT_TO_POINTER (DATA_SIZE), test_full);
g_test_add_data_func ("/base64/full/2", GINT_TO_POINTER (1), test_full);
g_test_add_data_func ("/base64/full/3", GINT_TO_POINTER (2), test_full);
g_test_add_data_func ("/base64/full/4", GINT_TO_POINTER (3), test_full);
g_test_add_data_func ("/base64/encode/incremental/small-block/1", GINT_TO_POINTER (1), test_base64_encode_incremental_small_block);
g_test_add_data_func ("/base64/encode/incremental/small-block/2", GINT_TO_POINTER (2), test_base64_encode_incremental_small_block);
g_test_add_data_func ("/base64/encode/incremental/small-block/3", GINT_TO_POINTER (3), test_base64_encode_incremental_small_block);
g_test_add_data_func ("/base64/encode/incremental/small-block/4", GINT_TO_POINTER (4), test_base64_encode_incremental_small_block);
g_test_add_data_func ("/base64/incremental/nobreak/1", GINT_TO_POINTER (DATA_SIZE), test_incremental_nobreak);
g_test_add_data_func ("/base64/incremental/break/1", GINT_TO_POINTER (DATA_SIZE), test_incremental_break);
g_test_add_data_func ("/base64/incremental/nobreak/2", GINT_TO_POINTER (DATA_SIZE - 1), test_incremental_nobreak);
g_test_add_data_func ("/base64/incremental/break/2", GINT_TO_POINTER (DATA_SIZE - 1), test_incremental_break);
g_test_add_data_func ("/base64/incremental/nobreak/3", GINT_TO_POINTER (DATA_SIZE - 2), test_incremental_nobreak);
g_test_add_data_func ("/base64/incremental/break/3", GINT_TO_POINTER (DATA_SIZE - 2), test_incremental_break);
g_test_add_data_func ("/base64/incremental/nobreak/4-a", GINT_TO_POINTER (1), test_incremental_nobreak);
g_test_add_data_func ("/base64/incremental/nobreak/4-b", GINT_TO_POINTER (2), test_incremental_nobreak);
g_test_add_data_func ("/base64/incremental/nobreak/4-c", GINT_TO_POINTER (3), test_incremental_nobreak);
g_test_add_func ("/base64/encode", test_base64_encode);
g_test_add_func ("/base64/decode", test_base64_decode);
g_test_add_func ("/base64/decode-inplace", test_base64_decode_inplace);
g_test_add_func ("/base64/encode-decode", test_base64_encode_decode);
g_test_add_data_func ("/base64/incremental/smallblock/1", GINT_TO_POINTER(1),
test_base64_decode_smallblock);
g_test_add_data_func ("/base64/incremental/smallblock/2", GINT_TO_POINTER(2),
test_base64_decode_smallblock);
g_test_add_data_func ("/base64/incremental/smallblock/3", GINT_TO_POINTER(3),
test_base64_decode_smallblock);
g_test_add_data_func ("/base64/incremental/smallblock/4", GINT_TO_POINTER(4),
test_base64_decode_smallblock);
g_test_add_func ("/base64/encode/empty", test_base64_encode_empty);
g_test_add_func ("/base64/decode/empty", test_base64_decode_empty);
g_test_add_func ("/base64/encode-decode/rfc4648", test_base64_encode_decode_rfc4648);
return g_test_run ();
}

39
glib/tests/bitlock.c Normal file
View file

@ -0,0 +1,39 @@
#include <glib.h>
#define ITERATIONS 100000000
static void
test_bitlocks (void)
{
guint64 start = g_get_monotonic_time ();
gint lock = 0;
gint i;
for (i = 0; i < ITERATIONS; i++)
{
g_bit_lock (&lock, 0);
g_bit_unlock (&lock, 0);
}
{
gdouble elapsed;
gdouble rate;
elapsed = g_get_monotonic_time () - start;
elapsed /= 1000000;
rate = ITERATIONS / elapsed;
g_test_maximized_result (rate, "iterations per second");
}
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
if (g_test_perf ())
g_test_add_func ("/bitlock/performance/uncontended", test_bitlocks);
return g_test_run ();
}

728
glib/tests/bookmarkfile.c Normal file
View file

@ -0,0 +1,728 @@
#undef G_DISABLE_ASSERT
#include <glib.h>
#include <glib/gstdio.h>
#include <time.h>
#include <locale.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define TEST_URI_0 "file:///abc/defgh/ijklmnopqrstuvwxyz"
#define TEST_URI_1 "file:///test/uri/1"
#define TEST_URI_2 "file:///test/uri/2"
#define TEST_MIME "text/plain"
#define TEST_APP_NAME "bookmarkfile-test"
#define TEST_APP_EXEC "bookmarkfile-test %f"
static void
test_load_from_data_dirs (void)
{
GBookmarkFile *bookmark;
gboolean res;
gchar *path = NULL;
GError *error = NULL;
bookmark = g_bookmark_file_new ();
res = g_bookmark_file_load_from_data_dirs (bookmark, "no-such-bookmark-file.xbel", &path, &error);
g_assert_false (res);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_assert_null (path);
g_error_free (error);
g_bookmark_file_free (bookmark);
}
static void
test_to_file (void)
{
GBookmarkFile *bookmark;
const gchar *filename;
gboolean res;
GError *error = NULL;
char *in, *out;
gchar *tmp_filename = NULL;
gint fd;
fd = g_file_open_tmp ("bookmarkfile-test-XXXXXX.xbel", &tmp_filename, NULL);
g_assert_cmpint (fd, >, -1);
g_close (fd, NULL);
bookmark = g_bookmark_file_new ();
g_test_message ("Roundtrip from newly created bookmark file %s", tmp_filename);
g_bookmark_file_set_title (bookmark, "file:///tmp/schedule.ps", "schedule.ps");
g_bookmark_file_set_mime_type (bookmark, "file:///tmp/schedule.ps", "application/postscript");
g_bookmark_file_add_application (bookmark, "file:///tmp/schedule.ps", "ghostscript", "ghostscript %F");
res = g_bookmark_file_to_file (bookmark, tmp_filename, &error);
g_assert_no_error (error);
g_assert_true (res);
res = g_bookmark_file_load_from_file (bookmark, tmp_filename, &error);
g_assert_no_error (error);
g_assert_true (res);
out = g_bookmark_file_get_title (bookmark, "file:///tmp/schedule.ps", &error);
g_assert_no_error (error);
g_assert_cmpstr (out, ==, "schedule.ps");
g_free (out);
out = g_bookmark_file_get_mime_type (bookmark, "file:///tmp/schedule.ps", &error);
g_assert_no_error (error);
g_assert_cmpstr (out, ==, "application/postscript");
g_free (out);
remove (tmp_filename);
g_test_message ("Roundtrip from a valid bookmark file");
filename = g_test_get_filename (G_TEST_DIST, "bookmarks", "valid-01.xbel", NULL);
res = g_bookmark_file_load_from_file (bookmark, filename, &error);
g_assert_no_error (error);
g_assert_true (res);
res = g_bookmark_file_to_file (bookmark, tmp_filename, &error);
g_assert_no_error (error);
g_assert_true (res);
res = g_file_get_contents (filename, &in, NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
res = g_file_get_contents (tmp_filename, &out, NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
remove (tmp_filename);
g_assert_cmpstr (in, ==, out);
g_free (in);
g_free (out);
g_bookmark_file_free (bookmark);
g_free (tmp_filename);
}
static void
test_move_item (void)
{
GBookmarkFile *bookmark;
const gchar *filename;
gboolean res;
GError *error = NULL;
bookmark = g_bookmark_file_new ();
filename = g_test_get_filename (G_TEST_DIST, "bookmarks", "valid-01.xbel", NULL);
res = g_bookmark_file_load_from_file (bookmark, filename, &error);
g_assert_true (res);
g_assert_no_error (error);
res = g_bookmark_file_move_item (bookmark,
"file:///home/zefram/Documents/milan-stuttgart.ps",
"file:///tmp/schedule.ps",
&error);
g_assert_true (res);
g_assert_no_error (error);
res = g_bookmark_file_move_item (bookmark,
"file:///tmp/schedule.ps",
"file:///tmp/schedule.ps",
&error);
g_assert_true (res);
g_assert_no_error (error);
res = g_bookmark_file_move_item (bookmark,
"file:///no-such-file.xbel",
"file:///tmp/schedule.ps",
&error);
g_assert_false (res);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
res = g_bookmark_file_move_item (bookmark,
"file:///tmp/schedule.ps",
NULL,
&error);
g_assert_true (res);
g_assert_no_error (error);
g_bookmark_file_free (bookmark);
}
static void
test_misc (void)
{
GBookmarkFile *bookmark;
const gchar *filename;
gboolean res;
GError *error = NULL;
gchar *s;
GDateTime *before, *after, *t;
gchar *cmd, *exec;
guint count;
bookmark = g_bookmark_file_new ();
filename = g_test_get_filename (G_TEST_DIST, "bookmarks", "valid-01.xbel", NULL);
res = g_bookmark_file_load_from_file (bookmark, filename, &error);
g_assert_true (res);
g_assert_no_error (error);
res = g_bookmark_file_get_icon (bookmark,
"file:///home/zefram/Documents/milan-stuttgart.ps",
NULL,
NULL,
&error);
g_assert_false (res);
g_assert_no_error (error);
res = g_bookmark_file_get_icon (bookmark,
"file:///tmp/schedule.ps",
NULL,
NULL,
&error);
g_assert_false (res);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
g_bookmark_file_set_description (bookmark,
"file:///tmp/schedule0.ps",
"imaginary schedule");
s = g_bookmark_file_get_description (bookmark,
"file:///tmp/schedule0.ps",
&error);
g_assert_no_error (error);
g_assert_cmpstr (s, ==, "imaginary schedule");
g_free (s);
s = g_bookmark_file_get_mime_type (bookmark,
"file:///tmp/schedule0.ps",
&error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_INVALID_VALUE);
g_assert_null (s);
g_clear_error (&error);
res = g_bookmark_file_get_is_private (bookmark,
"file:///tmp/schedule0.ps",
&error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_false (res);
g_bookmark_file_set_mime_type (bookmark,
"file:///tmp/schedule1.ps",
"image/png");
s = g_bookmark_file_get_mime_type (bookmark,
"file:///tmp/schedule1.ps",
&error);
g_assert_no_error (error);
g_assert_cmpstr (s, ==, "image/png");
g_free (s);
g_bookmark_file_set_is_private (bookmark,
"file:///tmp/schedule2.ps",
TRUE);
res = g_bookmark_file_get_is_private (bookmark,
"file:///tmp/schedule2.ps",
&error);
g_assert_no_error (error);
g_assert_true (res);
before = g_date_time_new_now_utc ();
g_bookmark_file_set_added_date_time (bookmark,
"file:///tmp/schedule3.ps",
before);
t = g_bookmark_file_get_added_date_time (bookmark,
"file:///tmp/schedule3.ps",
&error);
g_assert_no_error (error);
after = g_date_time_new_now_utc ();
g_assert_cmpint (g_date_time_compare (before, t), <=, 0);
g_assert_cmpint (g_date_time_compare (t, after), <=, 0);
g_date_time_unref (after);
g_date_time_unref (before);
before = g_date_time_new_now_utc ();
g_bookmark_file_set_modified_date_time (bookmark,
"file:///tmp/schedule4.ps",
before);
t = g_bookmark_file_get_modified_date_time (bookmark,
"file:///tmp/schedule4.ps",
&error);
g_assert_no_error (error);
after = g_date_time_new_now_utc ();
g_assert_cmpint (g_date_time_compare (before, t), <=, 0);
g_assert_cmpint (g_date_time_compare (t, after), <=, 0);
g_date_time_unref (after);
g_date_time_unref (before);
before = g_date_time_new_now_utc ();
g_bookmark_file_set_visited_date_time (bookmark,
"file:///tmp/schedule5.ps",
before);
t = g_bookmark_file_get_visited_date_time (bookmark,
"file:///tmp/schedule5.ps",
&error);
g_assert_no_error (error);
after = g_date_time_new_now_utc ();
g_assert_cmpint (g_date_time_compare (before, t), <=, 0);
g_assert_cmpint (g_date_time_compare (t, after), <=, 0);
g_date_time_unref (after);
g_date_time_unref (before);
g_bookmark_file_set_icon (bookmark,
"file:///tmp/schedule6.ps",
"application-x-postscript",
"image/png");
res = g_bookmark_file_get_icon (bookmark,
"file:///tmp/schedule6.ps",
&s,
NULL,
&error);
g_assert_no_error (error);
g_assert_true (res);
g_assert_cmpstr (s, ==, "application-x-postscript");
g_free (s);
g_bookmark_file_set_icon (bookmark,
"file:///tmp/schedule6.ps",
NULL, NULL);
res = g_bookmark_file_get_icon (bookmark,
"file:///tmp/schedule6.ps",
&s,
NULL,
&error);
g_assert_no_error (error);
g_assert_false (res);
res = g_bookmark_file_has_application (bookmark,
"file:///tmp/schedule7.ps",
"foo",
&error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_assert_false (res);
g_clear_error (&error);
before = g_date_time_new_now_utc ();
g_bookmark_file_add_application (bookmark,
"file:///tmp/schedule7.ps",
NULL, NULL);
res = g_bookmark_file_get_application_info (bookmark,
"file:///tmp/schedule7.ps",
g_get_application_name (),
&exec, &count, &t,
&error);
g_assert_no_error (error);
g_assert_true (res);
cmd = g_strconcat (g_get_prgname (), " file:///tmp/schedule7.ps", NULL);
g_assert_cmpstr (exec, ==, cmd);
g_free (cmd);
g_free (exec);
g_assert_cmpuint (count, ==, 1);
after = g_date_time_new_now_utc ();
g_assert_cmpint (g_date_time_compare (before, t), <=, 0);
g_assert_cmpint (g_date_time_compare (t, after), <=, 0);
g_date_time_unref (after);
g_date_time_unref (before);
g_bookmark_file_free (bookmark);
}
static void
test_deprecated (void)
{
GBookmarkFile *file = NULL;
GError *local_error = NULL;
time_t t, now;
gboolean retval;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
now = time (NULL);
file = g_bookmark_file_new ();
/* added */
g_bookmark_file_set_added (file, "file://test", -1);
t = g_bookmark_file_get_added (file, "file://test", &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (t, >=, now);
g_bookmark_file_set_added (file, "file://test", 1234);
t = g_bookmark_file_get_added (file, "file://test", &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (t, ==, 1234);
t = g_bookmark_file_get_added (file, "file://not-exist", &local_error);
g_assert_error (local_error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_assert_cmpint (t, ==, (time_t) -1);
g_clear_error (&local_error);
/* modified */
g_bookmark_file_set_modified (file, "file://test", -1);
t = g_bookmark_file_get_modified (file, "file://test", &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (t, >=, now);
g_bookmark_file_set_modified (file, "file://test", 1234);
t = g_bookmark_file_get_modified (file, "file://test", &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (t, ==, 1234);
t = g_bookmark_file_get_modified (file, "file://not-exist", &local_error);
g_assert_error (local_error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_assert_cmpint (t, ==, (time_t) -1);
g_clear_error (&local_error);
/* visited */
g_bookmark_file_set_visited (file, "file://test", -1);
t = g_bookmark_file_get_visited (file, "file://test", &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (t, >=, now);
g_bookmark_file_set_visited (file, "file://test", 1234);
t = g_bookmark_file_get_visited (file, "file://test", &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (t, ==, 1234);
t = g_bookmark_file_get_visited (file, "file://not-exist", &local_error);
g_assert_error (local_error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_assert_cmpint (t, ==, (time_t) -1);
g_clear_error (&local_error);
/* set app info */
retval = g_bookmark_file_set_app_info (file, "file://test", "app", "/path/to/app", 1, -1, &local_error);
g_assert_no_error (local_error);
g_assert_true (retval);
retval = g_bookmark_file_get_app_info (file, "file://test", "app", NULL, NULL, &t, &local_error);
g_assert_no_error (local_error);
g_assert_true (retval);
g_assert_cmpint (t, >=, now);
retval = g_bookmark_file_set_app_info (file, "file://test", "app", "/path/to/app", 1, 1234, &local_error);
g_assert_no_error (local_error);
g_assert_true (retval);
retval = g_bookmark_file_get_app_info (file, "file://test", "app", NULL, NULL, &t, &local_error);
g_assert_no_error (local_error);
g_assert_true (retval);
g_assert_cmpint (t, ==, 1234);
retval = g_bookmark_file_get_app_info (file, "file://test", "app", NULL, NULL, NULL, &local_error);
g_assert_no_error (local_error);
g_assert_true (retval);
retval = g_bookmark_file_get_app_info (file, "file://not-exist", "app", NULL, NULL, &t, &local_error);
g_assert_error (local_error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_assert_false (retval);
g_clear_error (&local_error);
g_bookmark_file_free (file);
G_GNUC_END_IGNORE_DEPRECATIONS
}
static gboolean
test_load (GBookmarkFile *bookmark,
const gchar *filename)
{
GError *error = NULL;
gboolean res;
res = g_bookmark_file_load_from_file (bookmark, filename, &error);
if (error && g_test_verbose ())
g_printerr ("Load error: %s\n", error->message);
g_clear_error (&error);
return res;
}
static void
test_query (GBookmarkFile *bookmark)
{
gint size;
gchar **uris;
gsize uris_len, i;
gchar *mime;
GError *error;
size = g_bookmark_file_get_size (bookmark);
uris = g_bookmark_file_get_uris (bookmark, &uris_len);
g_assert_cmpint (uris_len, ==, size);
for (i = 0; i < uris_len; i++)
{
g_assert_true (g_bookmark_file_has_item (bookmark, uris[i]));
error = NULL;
mime = g_bookmark_file_get_mime_type (bookmark, uris[i], &error);
g_assert_nonnull (mime);
g_assert_no_error (error);
g_free (mime);
}
g_strfreev (uris);
g_assert_false (g_bookmark_file_has_item (bookmark, "file:///no/such/uri"));
error = NULL;
mime = g_bookmark_file_get_mime_type (bookmark, "file:///no/such/uri", &error);
g_assert_null (mime);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_error_free (error);
g_free (mime);
}
static gboolean
test_modify (GBookmarkFile *bookmark)
{
gchar *text;
guint count;
GDateTime *stamp;
GDateTime *now = NULL;
GError *error = NULL;
gchar **groups;
gsize length;
gchar **apps;
gchar *icon;
gchar *mime;
if (g_test_verbose ())
g_printerr ("\t=> check global title/description...");
g_bookmark_file_set_title (bookmark, NULL, "a file");
g_bookmark_file_set_description (bookmark, NULL, "a bookmark file");
text = g_bookmark_file_get_title (bookmark, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (text, ==, "a file");
g_free (text);
text = g_bookmark_file_get_description (bookmark, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (text, ==, "a bookmark file");
g_free (text);
if (g_test_verbose ())
g_printerr ("ok\n");
if (g_test_verbose ())
g_printerr ("\t=> check bookmark title/description...");
g_bookmark_file_set_title (bookmark, TEST_URI_0, "a title");
g_bookmark_file_set_description (bookmark, TEST_URI_0, "a description");
g_bookmark_file_set_is_private (bookmark, TEST_URI_0, TRUE);
now = g_date_time_new_now_utc ();
g_bookmark_file_set_added_date_time (bookmark, TEST_URI_0, now);
g_bookmark_file_set_visited_date_time (bookmark, TEST_URI_0, now);
g_bookmark_file_set_icon (bookmark, TEST_URI_0, "testicon", "image/png");
/* Check the modification date by itself, as its updated whenever we modify
* other properties. */
g_bookmark_file_set_modified_date_time (bookmark, TEST_URI_0, now);
stamp = g_bookmark_file_get_modified_date_time (bookmark, TEST_URI_0, &error);
g_assert_no_error (error);
g_assert_cmpint (g_date_time_compare (stamp, now), ==, 0);
text = g_bookmark_file_get_title (bookmark, TEST_URI_0, &error);
g_assert_no_error (error);
g_assert_cmpstr (text, ==, "a title");
g_free (text);
text = g_bookmark_file_get_description (bookmark, TEST_URI_0, &error);
g_assert_no_error (error);
g_assert_cmpstr (text, ==, "a description");
g_free (text);
g_assert_true (g_bookmark_file_get_is_private (bookmark, TEST_URI_0, &error));
g_assert_no_error (error);
stamp = g_bookmark_file_get_added_date_time (bookmark, TEST_URI_0, &error);
g_assert_no_error (error);
g_assert_cmpint (g_date_time_compare (stamp, now), ==, 0);
stamp = g_bookmark_file_get_visited_date_time (bookmark, TEST_URI_0, &error);
g_assert_no_error (error);
g_assert_cmpint (g_date_time_compare (stamp, now), ==, 0);
g_assert_true (g_bookmark_file_get_icon (bookmark, TEST_URI_0, &icon, &mime, &error));
g_assert_no_error (error);
g_assert_cmpstr (icon, ==, "testicon");
g_assert_cmpstr (mime, ==, "image/png");
g_free (icon);
g_free (mime);
if (g_test_verbose ())
g_printerr ("ok\n");
if (g_test_verbose ())
g_printerr ("\t=> check non existing bookmark...");
g_bookmark_file_get_description (bookmark, TEST_URI_1, &error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
g_bookmark_file_get_is_private (bookmark, TEST_URI_1, &error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
g_bookmark_file_get_added_date_time (bookmark, TEST_URI_1, &error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
g_bookmark_file_get_modified_date_time (bookmark, TEST_URI_1, &error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
g_bookmark_file_get_visited_date_time (bookmark, TEST_URI_1, &error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
if (g_test_verbose ())
g_printerr ("ok\n");
if (g_test_verbose ())
g_printerr ("\t=> check application...");
g_bookmark_file_set_mime_type (bookmark, TEST_URI_0, TEST_MIME);
g_assert_false (g_bookmark_file_has_application (bookmark, TEST_URI_0, TEST_APP_NAME, NULL));
g_bookmark_file_add_application (bookmark, TEST_URI_0,
TEST_APP_NAME,
TEST_APP_EXEC);
g_assert_true (g_bookmark_file_has_application (bookmark, TEST_URI_0, TEST_APP_NAME, NULL));
g_bookmark_file_get_application_info (bookmark, TEST_URI_0, TEST_APP_NAME,
&text,
&count,
&stamp,
&error);
g_assert_no_error (error);
g_assert_cmpuint (count, ==, 1);
g_assert_cmpint (g_date_time_compare (stamp, g_bookmark_file_get_modified_date_time (bookmark, TEST_URI_0, NULL)), <=, 0);
g_free (text);
g_assert_true (g_bookmark_file_remove_application (bookmark, TEST_URI_0, TEST_APP_NAME, &error));
g_assert_no_error (error);
g_bookmark_file_add_application (bookmark, TEST_URI_0, TEST_APP_NAME, TEST_APP_EXEC);
apps = g_bookmark_file_get_applications (bookmark, TEST_URI_0, &length, &error);
g_assert_no_error (error);
g_assert_cmpint (length, ==, 1);
g_assert_cmpstr (apps[0], ==, TEST_APP_NAME);
g_strfreev (apps);
g_bookmark_file_get_application_info (bookmark, TEST_URI_0, "fail",
&text,
&count,
&stamp,
&error);
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED);
g_clear_error (&error);
if (g_test_verbose ())
g_printerr ("ok\n");
if (g_test_verbose ())
g_printerr ("\t=> check groups...");
g_assert_false (g_bookmark_file_has_group (bookmark, TEST_URI_1, "Test", NULL));
g_bookmark_file_add_group (bookmark, TEST_URI_1, "Test");
g_assert_true (g_bookmark_file_has_group (bookmark, TEST_URI_1, "Test", NULL));
g_assert_false (g_bookmark_file_has_group (bookmark, TEST_URI_1, "Fail", NULL));
g_assert_true (g_bookmark_file_remove_group (bookmark, TEST_URI_1, "Test", &error));
g_assert_no_error (error);
groups = g_bookmark_file_get_groups (bookmark, TEST_URI_1, NULL, &error);
g_assert_cmpint (g_strv_length (groups), ==, 0);
g_strfreev (groups);
groups = g_new0 (gchar *, 3);
groups[0] = "Group1";
groups[1] = "Group2";
groups[2] = NULL;
g_bookmark_file_set_groups (bookmark, TEST_URI_1, (const gchar **)groups, 2);
g_free (groups);
groups = g_bookmark_file_get_groups (bookmark, TEST_URI_1, &length, &error);
g_assert_cmpint (length, ==, 2);
g_strfreev (groups);
g_assert_no_error (error);
if (g_test_verbose ())
g_printerr ("ok\n");
if (g_test_verbose ())
g_printerr ("\t=> check remove...");
g_assert_true (g_bookmark_file_remove_item (bookmark, TEST_URI_1, &error));
g_assert_no_error (error);
g_assert_false (g_bookmark_file_remove_item (bookmark, TEST_URI_1, &error));
g_assert_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND);
g_clear_error (&error);
if (g_test_verbose ())
g_printerr ("ok\n");
g_date_time_unref (now);
return TRUE;
}
static void
test_file (gconstpointer d)
{
const gchar *filename = d;
GBookmarkFile *bookmark_file;
gboolean success;
gchar *data;
GError *error;
bookmark_file = g_bookmark_file_new ();
g_assert_nonnull (bookmark_file);
success = test_load (bookmark_file, filename);
if (success)
{
test_query (bookmark_file);
test_modify (bookmark_file);
error = NULL;
data = g_bookmark_file_to_data (bookmark_file, NULL, &error);
g_assert_no_error (error);
/* FIXME do some checks on data */
g_free (data);
}
g_bookmark_file_free (bookmark_file);
g_assert_true (success == (strstr (filename, "fail") == NULL));
}
int
main (int argc, char *argv[])
{
GDir *dir;
GError *error;
const gchar *name;
gchar *path;
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
if (argc > 1)
{
test_file (argv[1]);
return 0;
}
g_test_add_func ("/bookmarks/load-from-data-dirs", test_load_from_data_dirs);
g_test_add_func ("/bookmarks/to-file", test_to_file);
g_test_add_func ("/bookmarks/move-item", test_move_item);
g_test_add_func ("/bookmarks/misc", test_misc);
g_test_add_func ("/bookmarks/deprecated", test_deprecated);
error = NULL;
path = g_test_build_filename (G_TEST_DIST, "bookmarks", NULL);
dir = g_dir_open (path, 0, &error);
g_free (path);
g_assert_no_error (error);
while ((name = g_dir_read_name (dir)) != NULL)
{
if (!g_str_has_suffix (name, ".xbel"))
continue;
path = g_strdup_printf ("/bookmarks/parse/%s", name);
g_test_add_data_func_full (path, g_test_build_filename (G_TEST_DIST, "bookmarks", name, NULL),
test_file, g_free);
g_free (path);
}
g_dir_close (dir);
return g_test_run ();
}

23
glib/tests/bookmarks.xbel Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!DOCTYPE xbel PUBLIC
"+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks">
<bookmark href="file:///home/ebassi/bookmark-spec/bookmark-spec.xml">
<title>Desktop Bookmarks Spec</title>
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type>text/xml</mime:mime-type>
<bookmark:applications>
<bookmark:application name="GEdit" count="2" exec="gedit %u" timestamp="1115726763"/>
<bookmark:application name="GViM" count="7" exec="gvim %f" timestamp="1115726812"/>
</bookmark:applications>
<bookmark:groups>
<bookmark:group>Editors</bookmark:group>
</bookmark:groups>
</metadata>
</info>
</bookmark>
</xbel

View file

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<fail/>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark>
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" fail="attr">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file & containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</bookmark>
</xbel>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata>
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<bookmark:fail/>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<bookmark:applications>
<bookmark:application/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<title>&</title>
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
<bookmark:icon type="image/png"/>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
<fail/>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
<bookmark:groups>
<fail>Test</fail>
</bookmark:groups>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
<bookmark:groups>
<bookmark:group>Test</bookmark:group>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
<bookmark:groups>
<bookmark:group>Test</group>
</bookmark:groups>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</bookmark:applications>
</metadata>
<invalid/>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application c=""/><bookmark:application name=""exec=""/

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><mime:mime-type></mime:mime-type><bookmark:applications><bookmark:application name=""exec=""/

View file

@ -0,0 +1 @@
<?><!DOCTYPE<<><>>></

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application e=""/><bookmark:application name=""exec=""/

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application e=""/><bookmark:application name=""exec="">

View file

@ -0,0 +1 @@
</

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application n=""/><bookmark:application name=""exec="">

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:applications></bookmark:applications><bookmark:groups><bookmark:group><

View file

@ -0,0 +1 @@
<?><!DOCTYPE<><>></

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"f=""><title><bookmark:application e=""/><bookmark:application name=""exec=""/

View file

@ -0,0 +1 @@
<?><!DOCTYPE<><><>></

View file

@ -0,0 +1 @@
<?></

View file

@ -0,0 +1 @@
<?><!DOCTYPE<><<>><>></

View file

@ -0,0 +1 @@
<?><!DOCTYPE<><<>>></

View file

@ -0,0 +1 @@
<?><!DOCTYPE></

View file

@ -0,0 +1 @@
<?><!DOCTYPE<><><><>></

View file

@ -0,0 +1 @@
<?><!DOCTYPE<<>>></

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"m=""><title><mime:mime-type></mime:mime-type><mime:mime-type>

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><mime:mime-type></mime:mime-type><bookmark:applications><application name=""exec="">

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><mime:mime-type></mime:mime-type><bookmark:applications><bookmark:application name=""exec="">

View file

@ -0,0 +1 @@
<?><!DOCTYPE><xbel x=""/><o xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><bookmark:application e=""/><bookmark:application name=""exec=""/

View file

@ -0,0 +1 @@
<xbel version="1.0"><bookmark href=""><info><metadata owner="http://freedesktop.org"><mime-type/><mime-type/

View file

@ -0,0 +1 @@
<xbel version="1.0"><bookmark href=""><info><metadata owner="http://freedesktop.org"><applications><application name=""exec=""/><application name=""exec=""/

View file

@ -0,0 +1 @@
<xbel version="1.0"><bookmark href=""added="2T0+819855292164632335">

View file

@ -0,0 +1 @@
<xbel version="1.0"><bookmark href=""><info><metadata owner="http://freedesktop.org"><applications><application name=""exec=""timestamp="-77873021800189">

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
> <title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="2005-09-30T23:05:28Z" modified="2005-09-30T23:05:28Z" visited="2005-09-30T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:groups>
<bookmark:group>Office</bookmark:group>
<bookmark:group>Multimedia</bookmark:group>
</bookmark:groups>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" modified="2005-09-30T23:05:28Z" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<xbel version="1.0">
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<title>Milan-Stuttgart</title>
<desc>A schedule</desc>
<info>
<metadata owner="http://freedesktop.org">
<mime-type type="application/postscript"/>
<applications>
<application name="populate-recent" exec="populate-recent --info %u" timestamp="1128121528" count="1"/>
</applications>
</metadata>
</info>
</bookmark>
</xbel>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xbel
PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
<xbel version="1.0"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
>
<title>Singleton</title>
<desc>A file containing a single bookmark element</desc>
<bookmark href="file:///home/zefram/Documents/milan-stuttgart.ps" added="20050930T23:05:28Z" modified="20050930T23:05:28Z" visited="20050930T23:05:28Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="application/postscript"/>
<bookmark:applications>
<bookmark:application name="populate-recent" exec="populate-recent --info %u" modified="2005-09-30T23:05:28Z" count="1"/>
</bookmark:applications>
<bookmark:icon type="image/png" href="file:///usr/share/icons/gnome/48x48/gnome-mime-application-postscript.png"/>
</metadata>
</info>
</bookmark>
</xbel>

512
glib/tests/bytes.c Normal file
View file

@ -0,0 +1,512 @@
/*
* Copyright 2011 Collabora Ltd.
*
* 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#undef G_DISABLE_ASSERT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "glib.h"
/* Keep in sync with glib/gbytes.c */
struct _GBytes
{
gconstpointer data;
gsize size;
gint ref_count;
GDestroyNotify free_func;
gpointer user_data;
};
static const gchar *NYAN = "nyannyan";
static const gsize N_NYAN = 8;
static void
test_new (void)
{
const gchar *data;
GBytes *bytes;
gsize size;
data = "test";
bytes = g_bytes_new (data, 4);
g_assert_nonnull (bytes);
g_assert_true (g_bytes_get_data (bytes, &size) != data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
g_assert_cmpmem (data, 4, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
g_bytes_unref (bytes);
}
static void
test_new_take (void)
{
gchar *data;
GBytes *bytes;
gsize size;
data = g_strdup ("test");
bytes = g_bytes_new_take (data, 4);
g_assert_nonnull (bytes);
g_assert_true (g_bytes_get_data (bytes, &size) == data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
g_bytes_unref (bytes);
}
static void
test_new_static (void)
{
const gchar *data;
GBytes *bytes;
gsize size;
data = "test";
bytes = g_bytes_new_static (data, 4);
g_assert_nonnull (bytes);
g_assert_true (g_bytes_get_data (bytes, &size) == data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
g_bytes_unref (bytes);
}
static void
test_new_from_bytes (void)
{
const gchar *data = "smile and wave";
GBytes *bytes;
GBytes *sub;
bytes = g_bytes_new (data, 14);
sub = g_bytes_new_from_bytes (bytes, 10, 4);
g_assert_nonnull (sub);
g_assert_true (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
g_bytes_unref (bytes);
g_assert_cmpmem (g_bytes_get_data (sub, NULL), g_bytes_get_size (sub), "wave", 4);
g_bytes_unref (sub);
}
/* Verify that creating slices of GBytes reference the top-most bytes
* at the correct offset. Ensure that intermediate GBytes are not referenced.
*/
static void
test_new_from_bytes_slice (void)
{
GBytes *bytes = g_bytes_new_static ("Some stupid data", strlen ("Some stupid data") + 1);
GBytes *bytes1 = g_bytes_new_from_bytes (bytes, 4, 13);
GBytes *bytes2 = g_bytes_new_from_bytes (bytes1, 1, 12);
GBytes *bytes3 = g_bytes_new_from_bytes (bytes2, 0, 6);
g_assert_cmpint (bytes->ref_count, ==, 4);
g_assert_cmpint (bytes1->ref_count, ==, 1);
g_assert_cmpint (bytes2->ref_count, ==, 1);
g_assert_cmpint (bytes3->ref_count, ==, 1);
g_assert_null (bytes->user_data);
g_assert_true (bytes1->user_data == bytes);
g_assert_true (bytes2->user_data == bytes);
g_assert_true (bytes3->user_data == bytes);
g_assert_cmpint (17, ==, g_bytes_get_size (bytes));
g_assert_cmpint (13, ==, g_bytes_get_size (bytes1));
g_assert_cmpint (12, ==, g_bytes_get_size (bytes2));
g_assert_cmpint (6, ==, g_bytes_get_size (bytes3));
g_assert_cmpint (0, ==, strncmp ("Some stupid data", (gchar *)bytes->data, 17));
g_assert_cmpint (0, ==, strncmp (" stupid data", (gchar *)bytes1->data, 13));
g_assert_cmpint (0, ==, strncmp ("stupid data", (gchar *)bytes2->data, 12));
g_assert_cmpint (0, ==, strncmp ("stupid", (gchar *)bytes3->data, 6));
g_bytes_unref (bytes);
g_bytes_unref (bytes1);
g_bytes_unref (bytes2);
g_bytes_unref (bytes3);
}
/* Ensure that referencing an entire GBytes just returns the same bytes
* instance (with incremented reference count) instead of a new instance.
*/
static void
test_new_from_bytes_shared_ref (void)
{
GBytes *bytes = g_bytes_new_static ("Some data", strlen ("Some data") + 1);
GBytes *other = g_bytes_new_from_bytes (bytes, 0, g_bytes_get_size (bytes));
g_assert_true (bytes == other);
g_assert_cmpint (bytes->ref_count, ==, 2);
g_bytes_unref (bytes);
g_bytes_unref (other);
}
static void
on_destroy_increment (gpointer data)
{
gint *count = data;
g_assert_nonnull (count);
(*count)++;
}
static void
test_new_with_free_func (void)
{
GBytes *bytes;
gchar *data;
gint count = 0;
gsize size;
data = "test";
bytes = g_bytes_new_with_free_func (data, 4, on_destroy_increment, &count);
g_assert_nonnull (bytes);
g_assert_cmpint (count, ==, 0);
g_assert_true (g_bytes_get_data (bytes, &size) == data);
g_assert_cmpuint (size, ==, 4);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
g_bytes_unref (bytes);
g_assert_cmpuint (count, ==, 1);
}
static void
test_hash (void)
{
GBytes *bytes1;
GBytes *bytes2;
guint hash1;
guint hash2;
bytes1 = g_bytes_new ("blah", 4);
bytes2 = g_bytes_new ("blah", 4);
hash1 = g_bytes_hash (bytes1);
hash2 = g_bytes_hash (bytes2);
g_assert_cmpuint (hash1, ==, hash2);
g_bytes_unref (bytes1);
g_bytes_unref (bytes2);
}
static void
test_equal (void)
{
GBytes *bytes;
GBytes *bytes2;
bytes = g_bytes_new ("blah", 4);
bytes2 = g_bytes_new ("blah", 4);
g_assert_true (g_bytes_equal (bytes, bytes2));
g_assert_true (g_bytes_equal (bytes2, bytes));
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("bla", 3);
g_assert_false (g_bytes_equal (bytes, bytes2));
g_assert_false (g_bytes_equal (bytes2, bytes));
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("true", 4);
g_assert_false (g_bytes_equal (bytes, bytes2));
g_assert_false (g_bytes_equal (bytes2, bytes));
g_bytes_unref (bytes2);
g_bytes_unref (bytes);
}
static void
test_compare (void)
{
GBytes *bytes;
GBytes *bytes2;
bytes = g_bytes_new ("blah", 4);
bytes2 = g_bytes_new ("blah", 4);
g_assert_cmpint (g_bytes_compare (bytes, bytes2), ==, 0);
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("bla", 3);
g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0);
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("abcd", 4);
g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0);
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("blahblah", 8);
g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("zyx", 3);
g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
g_bytes_unref (bytes2);
bytes2 = g_bytes_new ("zyxw", 4);
g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
g_bytes_unref (bytes2);
g_bytes_unref (bytes);
}
static void
test_to_data_transferred (void)
{
gconstpointer memory;
gpointer data;
gsize size;
GBytes *bytes;
/* Memory transferred: one reference, and allocated with g_malloc */
bytes = g_bytes_new (NYAN, N_NYAN);
memory = g_bytes_get_data (bytes, NULL);
data = g_bytes_unref_to_data (bytes, &size);
g_assert_true (data == memory);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
}
static void
test_to_data_two_refs (void)
{
gconstpointer memory;
gpointer data;
gsize size;
GBytes *bytes;
/* Memory copied: two references */
bytes = g_bytes_new (NYAN, N_NYAN);
bytes = g_bytes_ref (bytes);
memory = g_bytes_get_data (bytes, NULL);
data = g_bytes_unref_to_data (bytes, &size);
g_assert_true (data != memory);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
g_assert_true (g_bytes_get_data (bytes, &size) == memory);
g_assert_cmpuint (size, ==, N_NYAN);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
g_bytes_unref (bytes);
}
static void
test_to_data_non_malloc (void)
{
gpointer data;
gsize size;
GBytes *bytes;
/* Memory copied: non malloc memory */
bytes = g_bytes_new_static (NYAN, N_NYAN);
g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
data = g_bytes_unref_to_data (bytes, &size);
g_assert_true (data != (gpointer)NYAN);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
}
static void
test_to_data_different_free_func (void)
{
gpointer data;
gsize size;
GBytes *bytes;
gchar *sentinel = g_strdup ("hello");
/* Memory copied: free func and user_data dont point to the bytes data */
bytes = g_bytes_new_with_free_func (NYAN, N_NYAN, g_free, sentinel);
g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
data = g_bytes_unref_to_data (bytes, &size);
g_assert_true (data != (gpointer)NYAN);
g_assert_cmpmem (data, size, NYAN, N_NYAN);
g_free (data);
/* @sentinel should not be leaked; testing that requires this test to be run
* under valgrind. We cant use a custom free func to check it isnt leaked,
* as the point of this test is to hit a condition in `try_steal_and_unref()`
* which is short-circuited if the free func isnt g_free().
* See discussion in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2152 */
}
static void
test_to_array_transferred (void)
{
gconstpointer memory;
GByteArray *array;
GBytes *bytes;
/* Memory transferred: one reference, and allocated with g_malloc */
bytes = g_bytes_new (NYAN, N_NYAN);
memory = g_bytes_get_data (bytes, NULL);
array = g_bytes_unref_to_array (bytes);
g_assert_nonnull (array);
g_assert_true (array->data == memory);
g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
g_byte_array_unref (array);
}
static void
test_to_array_transferred_oversize (void)
{
g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
"G_MAXUINT in length; test that longer ones are rejected");
if (sizeof (guint) >= sizeof (gsize))
{
g_test_skip ("Skipping test as guint is not smaller than gsize");
}
else if (g_test_undefined ())
{
GByteArray *array = NULL;
GBytes *bytes = NULL;
gpointer data = g_memdup2 (NYAN, N_NYAN);
gsize len = ((gsize) G_MAXUINT) + 1;
bytes = g_bytes_new_take (data, len);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
g_test_assert_expected_messages ();
g_assert_null (array);
g_free (data);
}
else
{
g_test_skip ("Skipping test as testing undefined behaviour is disabled");
}
}
static void
test_to_array_two_refs (void)
{
gconstpointer memory;
GByteArray *array;
GBytes *bytes;
gsize size;
/* Memory copied: two references */
bytes = g_bytes_new (NYAN, N_NYAN);
bytes = g_bytes_ref (bytes);
memory = g_bytes_get_data (bytes, NULL);
array = g_bytes_unref_to_array (bytes);
g_assert_nonnull (array);
g_assert_true (array->data != memory);
g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
g_byte_array_unref (array);
g_assert_true (g_bytes_get_data (bytes, &size) == memory);
g_assert_cmpuint (size, ==, N_NYAN);
g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
g_bytes_unref (bytes);
}
static void
test_to_array_non_malloc (void)
{
GByteArray *array;
GBytes *bytes;
/* Memory copied: non malloc memory */
bytes = g_bytes_new_static (NYAN, N_NYAN);
g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
array = g_bytes_unref_to_array (bytes);
g_assert_nonnull (array);
g_assert_true (array->data != (gpointer)NYAN);
g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
g_byte_array_unref (array);
}
static void
test_null (void)
{
GBytes *bytes;
gpointer data;
gsize size;
bytes = g_bytes_new (NULL, 0);
data = g_bytes_unref_to_data (bytes, &size);
g_assert_null (data);
g_assert_cmpuint (size, ==, 0);
}
static void
test_get_region (void)
{
GBytes *bytes;
bytes = g_bytes_new_static (NYAN, N_NYAN);
/* simple valid gets at the start */
g_assert_true (g_bytes_get_region (bytes, 1, 0, 1) == NYAN);
g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN) == NYAN);
/* an invalid get because the range is too wide */
g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN + 1) == NULL);
/* an valid get, but of a zero-byte range at the end */
g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 0) == NYAN + N_NYAN);
/* not a valid get because it overlap ones byte */
g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 1) == NULL);
/* let's try some multiplication overflow now */
g_assert_true (g_bytes_get_region (bytes, 32, 0, G_MAXSIZE / 32 + 1) == NULL);
g_assert_true (g_bytes_get_region (bytes, G_MAXSIZE / 32 + 1, 0, 32) == NULL);
/* and some addition overflow */
g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, -G_MAXSIZE) == NULL);
g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSSIZE, ((gsize) G_MAXSSIZE) + 1) == NULL);
g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, 1) == NULL);
g_bytes_unref (bytes);
}
static void
test_unref_null (void)
{
g_test_summary ("Test that calling g_bytes_unref() on NULL is a no-op");
g_bytes_unref (NULL);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/bytes/new", test_new);
g_test_add_func ("/bytes/new-take", test_new_take);
g_test_add_func ("/bytes/new-static", test_new_static);
g_test_add_func ("/bytes/new-with-free-func", test_new_with_free_func);
g_test_add_func ("/bytes/new-from-bytes", test_new_from_bytes);
g_test_add_func ("/bytes/new-from-bytes-slice", test_new_from_bytes_slice);
g_test_add_func ("/bytes/new-from-bytes-shared-ref", test_new_from_bytes_shared_ref);
g_test_add_func ("/bytes/hash", test_hash);
g_test_add_func ("/bytes/equal", test_equal);
g_test_add_func ("/bytes/compare", test_compare);
g_test_add_func ("/bytes/to-data/transferred", test_to_data_transferred);
g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs);
g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc);
g_test_add_func ("/bytes/to-data/different-free-func", test_to_data_different_free_func);
g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred);
g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
g_test_add_func ("/bytes/null", test_null);
g_test_add_func ("/bytes/get-region", test_get_region);
g_test_add_func ("/bytes/unref-null", test_unref_null);
return g_test_run ();
}

167
glib/tests/cache.c Normal file
View file

@ -0,0 +1,167 @@
/* Copyright (C) 2011 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/* We are testing some deprecated APIs here */
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <glib.h>
static gint value_create_count = 0;
static gint value_destroy_count = 0;
static gpointer
value_create (gpointer key)
{
gint *value;
value_create_count++;
value = g_new (gint, 1);
*value = *(gint*)key * 2;
return value;
}
static void
value_destroy (gpointer value)
{
value_destroy_count++;
g_free (value);
}
static gpointer
key_dup (gpointer key)
{
gint *newkey;
newkey = g_new (gint, 1);
*newkey = *(gint*)key;
return newkey;
}
static void
key_destroy (gpointer key)
{
g_free (key);
}
static guint
key_hash (gconstpointer key)
{
return *(guint*)key;
}
static guint
value_hash (gconstpointer value)
{
return *(guint*)value;
}
static gboolean
key_equal (gconstpointer key1, gconstpointer key2)
{
return *(gint*)key1 == *(gint*)key2;
}
static void
key_foreach (gpointer valuep, gpointer keyp, gpointer data)
{
gint *count = data;
gint *key = keyp;
(*count)++;
g_assert_cmpint (*key, ==, 2);
}
static void
value_foreach (gpointer keyp, gpointer nodep, gpointer data)
{
gint *count = data;
gint *key = keyp;
(*count)++;
g_assert_cmpint (*key, ==, 2);
}
static void
test_cache_basic (void)
{
GCache *c;
gint *key;
gint *value;
gint count;
value_create_count = 0;
value_destroy_count = 0;
c = g_cache_new (value_create, value_destroy,
key_dup, key_destroy,
key_hash, value_hash, key_equal);
key = g_new (gint, 1);
*key = 2;
value = g_cache_insert (c, key);
g_assert_cmpint (*value, ==, 4);
g_assert_cmpint (value_create_count, ==, 1);
g_assert_cmpint (value_destroy_count, ==, 0);
count = 0;
g_cache_key_foreach (c, key_foreach, &count);
g_assert_cmpint (count, ==, 1);
count = 0;
g_cache_value_foreach (c, value_foreach, &count);
g_assert_cmpint (count, ==, 1);
value = g_cache_insert (c, key);
g_assert_cmpint (*value, ==, 4);
g_assert_cmpint (value_create_count, ==, 1);
g_assert_cmpint (value_destroy_count, ==, 0);
g_cache_remove (c, value);
g_assert_cmpint (value_create_count, ==, 1);
g_assert_cmpint (value_destroy_count, ==, 0);
g_cache_remove (c, value);
g_assert_cmpint (value_create_count, ==, 1);
g_assert_cmpint (value_destroy_count, ==, 1);
value = g_cache_insert (c, key);
g_assert_cmpint (*value, ==, 4);
g_assert_cmpint (value_create_count, ==, 2);
g_assert_cmpint (value_destroy_count, ==, 1);
g_cache_remove (c, value);
g_cache_destroy (c);
g_free (key);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/cache/basic", test_cache_basic);
return g_test_run ();
}

1499
glib/tests/casefold.txt Normal file

File diff suppressed because it is too large Load diff

4023
glib/tests/casemap.txt Normal file

File diff suppressed because it is too large Load diff

83
glib/tests/charset.c Normal file
View file

@ -0,0 +1,83 @@
/*
* Copyright 2018 Red Hat, Inc.
*
* 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#include "glib.h"
#define TEST_LOCALE "fr_FR.UTF-8@latin:en_US.UTF-8"
const gchar *TEST_RESULT[] = {
"fr_FR.UTF-8@latin",
"fr_FR@latin",
"fr.UTF-8@latin",
"fr@latin",
"fr_FR.UTF-8",
"fr_FR",
"fr.UTF-8",
"fr",
"en_US.UTF-8",
"en_US",
"en.UTF-8",
"en",
"C",
NULL
};
const gchar *TEST_TABLE[] = {
"LANGUAGE",
"LC_ALL",
"LC_CTYPE",
"LANG",
NULL
};
static void
test_language_names_with_category (void)
{
const gchar * const *language_names = NULL;
gsize i, j;
for (i = 0; TEST_TABLE[i]; ++i)
{
g_test_message ("Test %" G_GSIZE_FORMAT, i);
g_assert_true (g_setenv (TEST_TABLE[i], TEST_LOCALE, TRUE));
language_names = g_get_language_names_with_category ("LC_CTYPE");
g_assert_cmpuint (g_strv_length ((gchar **)language_names), ==, g_strv_length ((gchar **)TEST_RESULT));
for (j = 0; language_names[j]; ++j)
{
g_assert_cmpstr (language_names[j], ==, TEST_RESULT[j]);
}
g_unsetenv (TEST_TABLE[i]);
}
}
static void
test_language_names_with_category_async (void)
{
g_thread_join (g_thread_new (
NULL, (GThreadFunc)g_get_language_names_with_category, "LC_CTYPE"));
/* g_get_language_names_with_category returns a pointer to a memory
which is owned by a thread it has been called from. The thread is dead now,
therefore returned pointer can't be used at this stage.
*/
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/charset/language_names_with_category", test_language_names_with_category);
g_test_add_func ("/charset/language_names_with_category_async", test_language_names_with_category_async);
return g_test_run ();
}

1213
glib/tests/checksum.c Normal file

File diff suppressed because it is too large Load diff

314
glib/tests/collate.c Normal file
View file

@ -0,0 +1,314 @@
#include "config.h"
#include <glib.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
static gboolean missing_locale = FALSE;
typedef struct {
const gchar **input;
const gchar **sorted;
const gchar **file_sorted;
} CollateTest;
typedef struct {
gchar *key;
const gchar *str;
} Line;
static void
clear_line (Line *line)
{
g_free (line->key);
}
static int
compare_collate (const void *a, const void *b)
{
const Line *line_a = a;
const Line *line_b = b;
return g_utf8_collate (line_a->str, line_b->str);
}
static int
compare_key (const void *a, const void *b)
{
const Line *line_a = a;
const Line *line_b = b;
return strcmp (line_a->key, line_b->key);
}
static void
do_collate (gboolean for_file, gboolean use_key, const CollateTest *test)
{
GArray *line_array;
Line line;
gint i;
if (missing_locale)
{
g_test_skip ("no en_US locale");
return;
}
line_array = g_array_new (FALSE, FALSE, sizeof(Line));
g_array_set_clear_func (line_array, (GDestroyNotify)clear_line);
for (i = 0; test->input[i]; i++)
{
line.str = test->input[i];
if (for_file)
line.key = g_utf8_collate_key_for_filename (line.str, -1);
else
line.key = g_utf8_collate_key (line.str, -1);
g_array_append_val (line_array, line);
}
qsort (line_array->data, line_array->len, sizeof (Line), use_key ? compare_key : compare_collate);
for (i = 0; test->input[i]; i++)
{
const gchar *str;
str = g_array_index (line_array, Line, i).str;
if (for_file)
g_assert_cmpstr (str, ==, test->file_sorted[i]);
else
g_assert_cmpstr (str, ==, test->sorted[i]);
}
g_array_free (line_array, TRUE);
}
static void
test_collate (gconstpointer d)
{
const CollateTest *test = d;
do_collate (FALSE, FALSE, test);
}
static void
test_collate_key (gconstpointer d)
{
const CollateTest *test = d;
do_collate (FALSE, TRUE, test);
}
static void
test_collate_file (gconstpointer d)
{
const CollateTest *test = d;
do_collate (TRUE, TRUE, test);
}
const gchar *input0[] = {
"z",
"c",
"eer34",
"223",
"er1",
"üĠണ",
"foo",
"bar",
"baz",
"GTK+",
NULL
};
const gchar *sorted0[] = {
"223",
"bar",
"baz",
"c",
"eer34",
"er1",
"foo",
"GTK+",
"üĠണ",
"z",
NULL
};
const gchar *file_sorted0[] = {
"223",
"bar",
"baz",
"c",
"eer34",
"er1",
"foo",
"GTK+",
"üĠണ",
"z",
NULL
};
const gchar *input1[] = {
"file.txt",
"file2.bla",
"file.c",
"file3.xx",
"bla001",
"bla02",
"bla03",
"bla4",
"bla10",
"bla100",
"event.c",
"eventgenerator.c",
"event.h",
NULL
};
const gchar *sorted1[] = {
"bla001",
"bla02",
"bla03",
"bla10",
"bla100",
"bla4",
"event.c",
"eventgenerator.c",
"event.h",
"file2.bla",
"file3.xx",
"file.c",
"file.txt",
NULL
};
const gchar *file_sorted1[] = {
"bla001",
"bla02",
"bla03",
"bla4",
"bla10",
"bla100",
"event.c",
"event.h",
"eventgenerator.c",
"file.c",
"file.txt",
"file2.bla",
"file3.xx",
NULL
};
const gchar *input2[] = {
"file26",
"file100",
"file1",
"file:foo",
"a.a",
"file027",
"file10",
"aa.a",
"file5",
"file0027",
"a-.a",
"file0000",
"file000x",
NULL
};
const gchar *sorted2[] = {
"a-.a",
"a.a",
"aa.a",
"file0000",
"file000x",
"file0027",
"file027",
"file1",
"file10",
"file100",
"file26",
"file5",
"file:foo",
NULL
};
const gchar *file_sorted2[] = {
/* Filename collation in OS X follows Finder style which gives
* a slightly different order from usual Linux locales. */
#ifdef HAVE_CARBON
"a-.a",
"a.a",
"aa.a",
"file:foo",
"file0000",
"file000x",
"file1",
"file5",
"file10",
"file26",
"file0027",
"file027",
"file100",
#else
"a.a",
"a-.a",
"aa.a",
"file0000",
"file000x",
"file1",
"file5",
"file10",
"file26",
"file027",
"file0027",
"file100",
"file:foo",
#endif
NULL
};
int
main (int argc, char *argv[])
{
gchar *path;
guint i;
const gchar *locale;
CollateTest test[3];
g_test_init (&argc, &argv, NULL);
g_setenv ("LC_ALL", "en_US", TRUE);
locale = setlocale (LC_ALL, "");
if (locale == NULL || strcmp (locale, "en_US") != 0)
{
g_test_message ("No suitable locale, skipping tests");
missing_locale = TRUE;
/* let the tests run to completion so they show up as SKIP'd in TAP
* output */
}
test[0].input = input0;
test[0].sorted = sorted0;
test[0].file_sorted = file_sorted0;
test[1].input = input1;
test[1].sorted = sorted1;
test[1].file_sorted = file_sorted1;
test[2].input = input2;
test[2].sorted = sorted2;
test[2].file_sorted = file_sorted2;
for (i = 0; i < G_N_ELEMENTS (test); i++)
{
path = g_strdup_printf ("/unicode/collate/%d", i);
g_test_add_data_func (path, &test[i], test_collate);
g_free (path);
path = g_strdup_printf ("/unicode/collate-key/%d", i);
g_test_add_data_func (path, &test[i], test_collate_key);
g_free (path);
path = g_strdup_printf ("/unicode/collate-filename/%d", i);
g_test_add_data_func (path, &test[i], test_collate_file);
g_free (path);
}
return g_test_run ();
}

102
glib/tests/completion.c Normal file
View file

@ -0,0 +1,102 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
/* We are testing some deprecated APIs here */
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <string.h>
#include "glib.h"
static void
test_completion (void)
{
static const char *const a1 = "a\302\243";
static const char *const a2 = "a\302\244";
static const char *const bb = "bb";
static const char *const bc = "bc";
GCompletion *cmp;
GList *items;
gchar *prefix;
cmp = g_completion_new (NULL);
g_completion_set_compare (cmp, strncmp);
items = NULL;
items = g_list_append (items, (gpointer) a1);
items = g_list_append (items, (gpointer) a2);
items = g_list_append (items, (gpointer) bb);
items = g_list_append (items, (gpointer) bc);
g_completion_add_items (cmp, items);
g_list_free (items);
items = g_completion_complete (cmp, "a", &prefix);
g_assert_cmpstr (prefix, ==, "a\302");
g_assert_cmpint (g_list_length (items), ==, 2);
g_free (prefix);
items = g_completion_complete_utf8 (cmp, "a", &prefix);
g_assert_cmpstr (prefix, ==, "a");
g_assert_cmpint (g_list_length (items), ==, 2);
g_free (prefix);
items = g_completion_complete (cmp, "b", &prefix);
g_assert_cmpstr (prefix, ==, "b");
g_assert_cmpint (g_list_length (items), ==, 2);
g_free (prefix);
items = g_completion_complete_utf8 (cmp, "b", &prefix);
g_assert_cmpstr (prefix, ==, "b");
g_assert_cmpint (g_list_length (items), ==, 2);
g_free (prefix);
items = g_completion_complete (cmp, "a", NULL);
g_assert_cmpint (g_list_length (items), ==, 2);
items = g_completion_complete_utf8 (cmp, "a", NULL);
g_assert_cmpint (g_list_length (items), ==, 2);
items = g_list_append (NULL, (gpointer) bb);
g_completion_remove_items (cmp, items);
g_list_free (items);
items = g_completion_complete_utf8 (cmp, "b", &prefix);
g_assert_cmpint (g_list_length (items), ==, 1);
g_free (prefix);
g_completion_free (cmp);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/completion/test-completion", test_completion);
return g_test_run ();
}

381
glib/tests/cond.c Normal file
View file

@ -0,0 +1,381 @@
/* Unit tests for GCond
* Copyright (C) 2011 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.
*/
/* We are testing some deprecated APIs here */
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <glib.h>
static GCond cond;
static GMutex mutex;
static gint next; /* locked by @mutex */
static void
push_value (gint value)
{
g_mutex_lock (&mutex);
while (next != 0)
g_cond_wait (&cond, &mutex);
next = value;
if (g_test_verbose ())
g_printerr ("Thread %p producing next value: %d\n", g_thread_self (), value);
if (value % 10 == 0)
g_cond_broadcast (&cond);
else
g_cond_signal (&cond);
g_mutex_unlock (&mutex);
}
static gint
pop_value (void)
{
gint value;
g_mutex_lock (&mutex);
while (next == 0)
{
if (g_test_verbose ())
g_printerr ("Thread %p waiting for cond\n", g_thread_self ());
g_cond_wait (&cond, &mutex);
}
value = next;
next = 0;
g_cond_broadcast (&cond);
if (g_test_verbose ())
g_printerr ("Thread %p consuming value %d\n", g_thread_self (), value);
g_mutex_unlock (&mutex);
return value;
}
static gpointer
produce_values (gpointer data)
{
gint total;
gint i;
total = 0;
for (i = 1; i < 100; i++)
{
total += i;
push_value (i);
}
push_value (-1);
push_value (-1);
if (g_test_verbose ())
g_printerr ("Thread %p produced %d altogether\n", g_thread_self (), total);
return GINT_TO_POINTER (total);
}
static gpointer
consume_values (gpointer data)
{
gint accum = 0;
gint value;
while (TRUE)
{
value = pop_value ();
if (value == -1)
break;
accum += value;
}
if (g_test_verbose ())
g_printerr ("Thread %p accumulated %d\n", g_thread_self (), accum);
return GINT_TO_POINTER (accum);
}
static GThread *producer, *consumer1, *consumer2;
static void
test_cond1 (void)
{
gint total, acc1, acc2;
producer = g_thread_create (produce_values, NULL, TRUE, NULL);
consumer1 = g_thread_create (consume_values, NULL, TRUE, NULL);
consumer2 = g_thread_create (consume_values, NULL, TRUE, NULL);
total = GPOINTER_TO_INT (g_thread_join (producer));
acc1 = GPOINTER_TO_INT (g_thread_join (consumer1));
acc2 = GPOINTER_TO_INT (g_thread_join (consumer2));
g_assert_cmpint (total, ==, acc1 + acc2);
}
typedef struct
{
GMutex mutex;
GCond cond;
gint limit;
gint count;
} Barrier;
static void
barrier_init (Barrier *barrier,
gint limit)
{
g_mutex_init (&barrier->mutex);
g_cond_init (&barrier->cond);
barrier->limit = limit;
barrier->count = limit;
}
static gint
barrier_wait (Barrier *barrier)
{
gint ret;
g_mutex_lock (&barrier->mutex);
barrier->count--;
if (barrier->count == 0)
{
ret = -1;
barrier->count = barrier->limit;
g_cond_broadcast (&barrier->cond);
}
else
{
ret = 0;
while (barrier->count != barrier->limit)
g_cond_wait (&barrier->cond, &barrier->mutex);
}
g_mutex_unlock (&barrier->mutex);
return ret;
}
static void
barrier_clear (Barrier *barrier)
{
g_mutex_clear (&barrier->mutex);
g_cond_clear (&barrier->cond);
}
static Barrier b;
static gint check;
static gpointer
cond2_func (gpointer data)
{
gint value = GPOINTER_TO_INT (data);
gint ret;
g_atomic_int_inc (&check);
if (g_test_verbose ())
g_printerr ("thread %d starting, check %d\n", value, g_atomic_int_get (&check));
g_usleep (10000 * value);
g_atomic_int_inc (&check);
if (g_test_verbose ())
g_printerr ("thread %d reaching barrier, check %d\n", value, g_atomic_int_get (&check));
ret = barrier_wait (&b);
g_assert_cmpint (g_atomic_int_get (&check), ==, 10);
if (g_test_verbose ())
g_printerr ("thread %d leaving barrier (%d), check %d\n", value, ret, g_atomic_int_get (&check));
return NULL;
}
/* this test demonstrates how to use a condition variable
* to implement a barrier
*/
static void
test_cond2 (void)
{
gint i;
GThread *threads[5];
g_atomic_int_set (&check, 0);
barrier_init (&b, 5);
for (i = 0; i < 5; i++)
threads[i] = g_thread_create (cond2_func, GINT_TO_POINTER (i), TRUE, NULL);
for (i = 0; i < 5; i++)
g_thread_join (threads[i]);
g_assert_cmpint (g_atomic_int_get (&check), ==, 10);
barrier_clear (&b);
}
static void
test_wait_until (void)
{
gint64 until;
GMutex lock;
GCond cond;
/* This test will make sure we don't wait too much or too little.
*
* We check the 'too long' with a timeout of 60 seconds.
*
* We check the 'too short' by verifying a guarantee of the API: we
* should not wake up until the specified time has passed.
*/
g_mutex_init (&lock);
g_cond_init (&cond);
until = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
/* Could still have spurious wakeups, so we must loop... */
g_mutex_lock (&lock);
while (g_cond_wait_until (&cond, &lock, until))
;
g_mutex_unlock (&lock);
/* Make sure it's after the until time */
g_assert_cmpint (until, <=, g_get_monotonic_time ());
/* Make sure it returns FALSE on timeout */
until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 50;
g_mutex_lock (&lock);
g_assert (g_cond_wait_until (&cond, &lock, until) == FALSE);
g_mutex_unlock (&lock);
g_mutex_clear (&lock);
g_cond_clear (&cond);
}
#ifdef __linux__
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
static pthread_t main_thread;
static void *
mutex_holder (void *data)
{
GMutex *lock = data;
g_mutex_lock (lock);
/* Let the lock become contended */
g_usleep (G_TIME_SPAN_SECOND);
/* Interrupt the wait on the other thread */
pthread_kill (main_thread, SIGHUP);
/* If we don't sleep here, then the g_mutex_unlock() below will clear
* the mutex, causing the interrupted futex call in the other thread
* to return success (which is not what we want).
*
* The other thread needs to have time to wake up and see that the
* lock is still contended.
*/
g_usleep (G_TIME_SPAN_SECOND / 10);
g_mutex_unlock (lock);
return NULL;
}
static void
signal_handler (int sig)
{
}
static void
test_wait_until_errno (void)
{
gboolean result;
GMutex lock;
GCond cond;
struct sigaction act = { };
/* important: no SA_RESTART (we want EINTR) */
act.sa_handler = signal_handler;
g_test_summary ("Check proper handling of errno in g_cond_wait_until with a contended mutex");
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/957");
g_mutex_init (&lock);
g_cond_init (&cond);
main_thread = pthread_self ();
sigaction (SIGHUP, &act, NULL);
g_mutex_lock (&lock);
/* We create an annoying worker thread that will do two things:
*
* 1) hold the lock that we want to reacquire after returning from
* the condition variable wait
*
* 2) send us a signal to cause our wait on the contended lock to
* return EINTR, clobbering the errno return from the condition
* variable
*/
g_thread_unref (g_thread_new ("mutex-holder", mutex_holder, &lock));
result = g_cond_wait_until (&cond, &lock,
g_get_monotonic_time () + G_TIME_SPAN_SECOND / 50);
/* Even after all that disruption, we should still successfully return
* 'timed out'.
*/
g_assert_false (result);
g_mutex_unlock (&lock);
g_cond_clear (&cond);
g_mutex_clear (&lock);
}
#else
static void
test_wait_until_errno (void)
{
g_test_skip ("We only test this on Linux");
}
#endif
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/thread/cond1", test_cond1);
g_test_add_func ("/thread/cond2", test_cond2);
g_test_add_func ("/thread/cond/wait-until", test_wait_until);
g_test_add_func ("/thread/cond/wait-until/contended-and-interrupted", test_wait_until_errno);
return g_test_run ();
}

969
glib/tests/convert.c Normal file
View file

@ -0,0 +1,969 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
#undef G_DISABLE_ASSERT
#undef G_LOG_DOMAIN
#include <locale.h>
#include <string.h>
#include <glib.h>
/* Bug 311337 */
static void
test_iconv_state (void)
{
const gchar *in = "\xf4\xe5\xf8\xe5\xed";
const gchar *expected = "\xd7\xa4\xd7\x95\xd7\xa8\xd7\x95\xd7\x9d";
gchar *out;
gsize bytes_read = 0;
gsize bytes_written = 0;
GError *error = NULL;
out = g_convert (in, -1, "UTF-8", "CP1255",
&bytes_read, &bytes_written, &error);
if (error && error->code == G_CONVERT_ERROR_NO_CONVERSION)
return; /* silently skip if CP1255 is not supported, see bug 467707 */
g_assert_no_error (error);
g_assert_cmpint (bytes_read, ==, 5);
g_assert_cmpint (bytes_written, ==, 10);
g_assert_cmpstr (out, ==, expected);
g_free (out);
}
/* Some tests involving "vulgar fraction one half" (U+00BD). This is
* represented in UTF-8 as \xC2\xBD, in ISO-8859-1 as \xBD, and is not
* represented in ISO-8859-15. */
static void
test_one_half (void)
{
const gchar *in_utf8 = "\xc2\xbd";
gchar *out;
gsize bytes_read = 0;
gsize bytes_written = 0;
GError *error = NULL;
out = g_convert (in_utf8, -1,
"ISO-8859-1", "UTF-8",
&bytes_read, &bytes_written,
&error);
g_assert_no_error (error);
g_assert_cmpint (bytes_read, ==, 2);
g_assert_cmpint (bytes_written, ==, 1);
g_assert_cmpstr (out, ==, "\xbd");
g_free (out);
out = g_convert (in_utf8, -1,
"ISO-8859-15", "UTF-8",
&bytes_read, &bytes_written,
&error);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpint (bytes_read, ==, 0);
g_assert_cmpint (bytes_written, ==, 0);
g_assert_cmpstr (out, ==, NULL);
g_clear_error (&error);
g_free (out);
out = g_convert_with_fallback (in_utf8, -1,
"ISO8859-15", "UTF-8",
"a",
&bytes_read, &bytes_written,
&error);
g_assert_no_error (error);
g_assert_cmpint (bytes_read, ==, 2);
g_assert_cmpint (bytes_written, ==, 1);
g_assert_cmpstr (out, ==, "a");
g_free (out);
}
static void
test_byte_order (void)
{
gchar in_be[4] = { 0xfe, 0xff, 0x03, 0x93}; /* capital gamma */
gchar in_le[4] = { 0xff, 0xfe, 0x93, 0x03};
const gchar *expected = "\xce\x93";
gchar *out;
gsize bytes_read = 0;
gsize bytes_written = 0;
GError *error = NULL;
out = g_convert (in_be, sizeof (in_be),
"UTF-8", "UTF-16",
&bytes_read, &bytes_written,
&error);
g_assert_no_error (error);
g_assert_cmpint (bytes_read, ==, 4);
g_assert_cmpint (bytes_written, ==, 2);
g_assert_cmpstr (out, ==, expected);
g_free (out);
out = g_convert (in_le, sizeof (in_le),
"UTF-8", "UTF-16",
&bytes_read, &bytes_written,
&error);
g_assert_no_error (error);
g_assert_cmpint (bytes_read, ==, 4);
g_assert_cmpint (bytes_written, ==, 2);
g_assert_cmpstr (out, ==, expected);
g_free (out);
}
static void
check_utf8_to_ucs4 (const char *utf8,
gsize utf8_len,
const gunichar *ucs4,
glong ucs4_len,
glong error_pos)
{
gunichar *result, *result2, *result3;
glong items_read, items_read2;
glong items_written, items_written2;
GError *error, *error2, *error3;
gint i;
if (!error_pos)
{
/* check the fast conversion */
result = g_utf8_to_ucs4_fast (utf8, utf8_len, &items_written);
g_assert_cmpint (items_written, ==, ucs4_len);
g_assert (result);
for (i = 0; i <= items_written; i++)
g_assert (result[i] == ucs4[i]);
g_free (result);
}
error = NULL;
result = g_utf8_to_ucs4 (utf8, utf8_len, &items_read, &items_written, &error);
if (utf8_len == strlen (utf8))
{
/* check that len == -1 yields identical results */
error2 = NULL;
result2 = g_utf8_to_ucs4 (utf8, -1, &items_read2, &items_written2, &error2);
g_assert (error || items_read2 == items_read);
g_assert (error || items_written2 == items_written);
g_assert_cmpint (!!result, ==, !!result2);
g_assert_cmpint (!!error, ==, !!error2);
if (result)
for (i = 0; i <= items_written; i++)
g_assert (result[i] == result2[i]);
g_free (result2);
if (error2)
g_error_free (error2);
}
error3 = NULL;
result3 = g_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL, &error3);
if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, error_pos);
g_assert_cmpint (items_written, ==, ucs4_len);
g_assert (result);
for (i = 0; i <= items_written; i++)
g_assert (result[i] == ucs4[i]);
g_error_free (error3);
}
else if (error_pos)
{
g_assert (error != NULL);
g_assert (result == NULL);
g_assert_cmpint (items_read, ==, error_pos);
g_error_free (error);
g_assert (error3 != NULL);
g_assert (result3 == NULL);
g_error_free (error3);
}
else
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, utf8_len);
g_assert_cmpint (items_written, ==, ucs4_len);
g_assert (result);
for (i = 0; i <= items_written; i++)
g_assert (result[i] == ucs4[i]);
g_assert_no_error (error3);
g_assert (result3);
for (i = 0; i <= ucs4_len; i++)
g_assert (result3[i] == ucs4[i]);
}
g_free (result);
g_free (result3);
}
static void
check_ucs4_to_utf8 (const gunichar *ucs4,
glong ucs4_len,
const char *utf8,
glong utf8_len,
glong error_pos)
{
gchar *result, *result2, *result3;
glong items_read, items_read2;
glong items_written, items_written2;
GError *error, *error2, *error3;
error = NULL;
result = g_ucs4_to_utf8 (ucs4, ucs4_len, &items_read, &items_written, &error);
if (ucs4[ucs4_len] == 0)
{
/* check that len == -1 yields identical results */
error2 = NULL;
result2 = g_ucs4_to_utf8 (ucs4, -1, &items_read2, &items_written2, &error2);
g_assert (error || items_read2 == items_read);
g_assert (error || items_written2 == items_written);
g_assert_cmpint (!!result, ==, !!result2);
g_assert_cmpint (!!error, ==, !!error2);
if (result)
g_assert_cmpstr (result, ==, result2);
g_free (result2);
if (error2)
g_error_free (error2);
}
error3 = NULL;
result3 = g_ucs4_to_utf8 (ucs4, ucs4_len, NULL, NULL, &error3);
if (error_pos)
{
g_assert (error != NULL);
g_assert (result == NULL);
g_assert_cmpint (items_read, ==, error_pos);
g_error_free (error);
g_assert (error3 != NULL);
g_assert (result3 == NULL);
g_error_free (error3);
}
else
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, ucs4_len);
g_assert_cmpint (items_written, ==, utf8_len);
g_assert (result);
g_assert_cmpstr (result, ==, utf8);
g_assert_no_error (error3);
g_assert (result3);
g_assert_cmpstr (result3, ==, utf8);
}
g_free (result);
g_free (result3);
}
static void
check_utf8_to_utf16 (const char *utf8,
gsize utf8_len,
const gunichar2 *utf16,
glong utf16_len,
glong error_pos)
{
gunichar2 *result, *result2, *result3;
glong items_read, items_read2;
glong items_written, items_written2;
GError *error, *error2, *error3;
gint i;
error = NULL;
result = g_utf8_to_utf16 (utf8, utf8_len, &items_read, &items_written, &error);
if (utf8_len == strlen (utf8))
{
/* check that len == -1 yields identical results */
error2 = NULL;
result2 = g_utf8_to_utf16 (utf8, -1, &items_read2, &items_written2, &error2);
g_assert (error || items_read2 == items_read);
g_assert (error || items_written2 == items_written);
g_assert_cmpint (!!result, ==, !!result2);
g_assert_cmpint (!!error, ==, !!error2);
if (result)
for (i = 0; i <= items_written; i++)
g_assert (result[i] == result2[i]);
g_free (result2);
if (error2)
g_error_free (error2);
}
error3 = NULL;
result3 = g_utf8_to_utf16 (utf8, utf8_len, NULL, NULL, &error3);
if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, error_pos);
g_assert_cmpint (items_written, ==, utf16_len);
g_assert (result);
for (i = 0; i <= items_written; i++)
g_assert (result[i] == utf16[i]);
g_error_free (error3);
}
else if (error_pos)
{
g_assert (error != NULL);
g_assert (result == NULL);
g_assert_cmpint (items_read, ==, error_pos);
g_error_free (error);
g_assert (error3 != NULL);
g_assert (result3 == NULL);
g_error_free (error3);
}
else
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, utf8_len);
g_assert_cmpint (items_written, ==, utf16_len);
g_assert (result);
for (i = 0; i <= items_written; i++)
g_assert (result[i] == utf16[i]);
g_assert_no_error (error3);
g_assert (result3);
for (i = 0; i <= utf16_len; i++)
g_assert (result3[i] == utf16[i]);
}
g_free (result);
g_free (result3);
}
static void
check_utf16_to_utf8 (const gunichar2 *utf16,
glong utf16_len,
const char *utf8,
glong utf8_len,
glong error_pos)
{
gchar *result, *result2, *result3;
glong items_read, items_read2;
glong items_written, items_written2;
GError *error, *error2, *error3;
error = NULL;
result = g_utf16_to_utf8 (utf16, utf16_len, &items_read, &items_written, &error);
if (utf16[utf16_len] == 0)
{
/* check that len == -1 yields identical results */
error2 = NULL;
result2 = g_utf16_to_utf8 (utf16, -1, &items_read2, &items_written2, &error2);
g_assert (error || items_read2 == items_read);
g_assert (error || items_written2 == items_written);
g_assert_cmpint (!!result, ==, !!result2);
g_assert_cmpint (!!error, ==, !!error2);
if (result)
g_assert_cmpstr (result, ==, result2);
g_free (result2);
if (error2)
g_error_free (error2);
}
error3 = NULL;
result3 = g_utf16_to_utf8 (utf16, utf16_len, NULL, NULL, &error3);
if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, error_pos);
g_assert_cmpint (items_read + 1, ==, utf16_len);
g_assert_cmpint (items_written, ==, utf8_len);
g_assert (result);
g_assert_cmpstr (result, ==, utf8);
g_error_free (error3);
}
else if (error_pos)
{
g_assert (error != NULL);
g_assert (result == NULL);
g_assert_cmpint (items_read, ==, error_pos);
g_error_free (error);
g_assert (error3 != NULL);
g_assert (result3 == NULL);
g_error_free (error3);
}
else
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, utf16_len);
g_assert_cmpint (items_written, ==, utf8_len);
g_assert (result);
g_assert_cmpstr (result, ==, utf8);
g_assert_no_error (error3);
g_assert (result3);
g_assert_cmpstr (result3, ==, utf8);
}
g_free (result);
g_free (result3);
}
static void
check_ucs4_to_utf16 (const gunichar *ucs4,
glong ucs4_len,
const gunichar2 *utf16,
glong utf16_len,
glong error_pos)
{
gunichar2 *result, *result2, *result3;
glong items_read, items_read2;
glong items_written, items_written2;
GError *error, *error2, *error3;
gint i;
error = NULL;
result = g_ucs4_to_utf16 (ucs4, ucs4_len, &items_read, &items_written, &error);
if (ucs4[ucs4_len] == 0)
{
/* check that len == -1 yields identical results */
error2 = NULL;
result2 = g_ucs4_to_utf16 (ucs4, -1, &items_read2, &items_written2, &error2);
g_assert (error || items_read2 == items_read);
g_assert (error || items_written2 == items_written);
g_assert_cmpint (!!result, ==, !!result2);
g_assert_cmpint (!!error, ==, !!error2);
if (result)
for (i = 0; i <= utf16_len; i++)
g_assert (result[i] == result2[i]);
g_free (result2);
if (error2)
g_error_free (error2);
}
error3 = NULL;
result3 = g_ucs4_to_utf16 (ucs4, -1, NULL, NULL, &error3);
if (error_pos)
{
g_assert (error != NULL);
g_assert (result == NULL);
g_assert_cmpint (items_read, ==, error_pos);
g_error_free (error);
g_assert (error3 != NULL);
g_assert (result3 == NULL);
g_error_free (error3);
}
else
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, ucs4_len);
g_assert_cmpint (items_written, ==, utf16_len);
g_assert (result);
for (i = 0; i <= utf16_len; i++)
g_assert (result[i] == utf16[i]);
g_assert_no_error (error3);
g_assert (result3);
for (i = 0; i <= utf16_len; i++)
g_assert (result3[i] == utf16[i]);
}
g_free (result);
g_free (result3);
}
static void
check_utf16_to_ucs4 (const gunichar2 *utf16,
glong utf16_len,
const gunichar *ucs4,
glong ucs4_len,
glong error_pos)
{
gunichar *result, *result2, *result3;
glong items_read, items_read2;
glong items_written, items_written2;
GError *error, *error2, *error3;
gint i;
error = NULL;
result = g_utf16_to_ucs4 (utf16, utf16_len, &items_read, &items_written, &error);
if (utf16[utf16_len] == 0)
{
/* check that len == -1 yields identical results */
error2 = NULL;
result2 = g_utf16_to_ucs4 (utf16, -1, &items_read2, &items_written2, &error2);
g_assert (error || items_read2 == items_read);
g_assert (error || items_written2 == items_written);
g_assert_cmpint (!!result, ==, !!result2);
g_assert_cmpint (!!error, ==, !!error2);
if (result)
for (i = 0; i <= items_written; i++)
g_assert (result[i] == result2[i]);
g_free (result2);
if (error2)
g_error_free (error2);
}
error3 = NULL;
result3 = g_utf16_to_ucs4 (utf16, utf16_len, NULL, NULL, &error3);
if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, error_pos);
g_assert_cmpint (items_read + 1, ==, utf16_len);
g_assert_cmpint (items_written, ==, ucs4_len);
g_assert (result);
for (i = 0; i <= items_written; i++)
g_assert (result[i] == ucs4[i]);
g_error_free (error3);
}
else if (error_pos)
{
g_assert (error != NULL);
g_assert (result == NULL);
g_assert_cmpint (items_read, ==, error_pos);
g_error_free (error);
g_assert (error3 != NULL);
g_assert (result3 == NULL);
g_error_free (error3);
}
else
{
g_assert_no_error (error);
g_assert_cmpint (items_read, ==, utf16_len);
g_assert_cmpint (items_written, ==, ucs4_len);
g_assert (result);
for (i = 0; i <= ucs4_len; i++)
g_assert (result[i] == ucs4[i]);
g_assert_no_error (error3);
g_assert (result3);
for (i = 0; i <= ucs4_len; i++)
g_assert (result3[i] == ucs4[i]);
}
g_free (result);
g_free (result3);
}
static void
test_unicode_conversions (void)
{
const char *utf8;
gunichar ucs4[100];
gunichar2 utf16[100];
utf8 = "abc";
ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x63; ucs4[3] = 0;
utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0x63; utf16[3] = 0;
check_utf8_to_ucs4 (utf8, 3, ucs4, 3, 0);
check_ucs4_to_utf8 (ucs4, 3, utf8, 3, 0);
check_utf8_to_utf16 (utf8, 3, utf16, 3, 0);
check_utf16_to_utf8 (utf16, 3, utf8, 3, 0);
check_ucs4_to_utf16 (ucs4, 3, utf16, 3, 0);
check_utf16_to_ucs4 (utf16, 3, ucs4, 3, 0);
utf8 = "\316\261\316\262\316\263";
ucs4[0] = 0x03b1; ucs4[1] = 0x03b2; ucs4[2] = 0x03b3; ucs4[3] = 0;
utf16[0] = 0x03b1; utf16[1] = 0x03b2; utf16[2] = 0x03b3; utf16[3] = 0;
check_utf8_to_ucs4 (utf8, 6, ucs4, 3, 0);
check_ucs4_to_utf8 (ucs4, 3, utf8, 6, 0);
check_utf8_to_utf16 (utf8, 6, utf16, 3, 0);
check_utf16_to_utf8 (utf16, 3, utf8, 6, 0);
check_ucs4_to_utf16 (ucs4, 3, utf16, 3, 0);
check_utf16_to_ucs4 (utf16, 3, ucs4, 3, 0);
/* partial utf8 character */
utf8 = "abc\316";
ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x63; ucs4[3] = 0;
utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0x63; utf16[3] = 0;
check_utf8_to_ucs4 (utf8, 4, ucs4, 3, 3);
check_utf8_to_utf16 (utf8, 4, utf16, 3, 3);
/* invalid utf8 */
utf8 = "abc\316\316";
ucs4[0] = 0;
utf16[0] = 0;
check_utf8_to_ucs4 (utf8, 5, ucs4, 0, 3);
check_utf8_to_utf16 (utf8, 5, utf16, 0, 3);
/* partial utf16 character */
utf8 = "ab";
ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0;
utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0xd801; utf16[3] = 0;
check_utf16_to_utf8 (utf16, 3, utf8, 2, 2);
check_utf16_to_ucs4 (utf16, 3, ucs4, 2, 2);
/* invalid utf16 */
utf8 = NULL;
ucs4[0] = 0;
utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0xdc01; utf16[3] = 0;
check_utf16_to_utf8 (utf16, 3, utf8, 0, 2);
check_utf16_to_ucs4 (utf16, 3, ucs4, 0, 2);
/* invalid ucs4 */
utf8 = NULL;
ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x80000000; ucs4[3] = 0;
utf16[0] = 0;
check_ucs4_to_utf8 (ucs4, 3, utf8, 0, 2);
check_ucs4_to_utf16 (ucs4, 3, utf16, 0, 2);
}
static void
test_filename_utf8 (void)
{
const gchar *filename = "/my/path/to/foo";
gchar *utf8;
gchar *back;
GError *error;
error = NULL;
utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, &error);
g_assert_no_error (error);
back = g_filename_from_utf8 (utf8, -1, NULL, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (back, ==, filename);
g_free (utf8);
g_free (back);
}
static void
test_filename_display (void)
{
const gchar *filename = "/my/path/to/foo";
char *display;
display = g_filename_display_basename (filename);
g_assert_cmpstr (display, ==, "foo");
g_free (display);
}
/* g_convert() should accept and produce text buffers with embedded
* nul bytes/characters.
*/
static void
test_convert_embedded_nul (void)
{
gchar *res;
gsize bytes_read, bytes_written;
GError *error = NULL;
res = g_convert ("ab\0\xf6", 4, "UTF-8", "ISO-8859-1",
&bytes_read, &bytes_written, &error);
g_assert_no_error (error);
g_assert_cmpuint (bytes_read, ==, 4);
g_assert_cmpmem (res, bytes_written, "ab\0\xc3\xb6", 5);
g_free (res);
}
static void
test_locale_to_utf8_embedded_nul (void)
{
g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/utf8", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/iconv", 0, 0);
g_test_trap_assert_passed ();
}
/* Test that embedded nul characters in UTF-8 input to g_locale_to_utf8()
* result in an error.
*/
static void
test_locale_to_utf8_embedded_nul_utf8 (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
setlocale (LC_ALL, "");
g_setenv ("CHARSET", "UTF-8", TRUE);
g_assert_true (g_get_charset (NULL));
res = g_locale_to_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
/* Test that embedded nul characters in output of g_locale_to_utf8(),
* when converted from non-UTF8 input, result in an error.
*/
static void
test_locale_to_utf8_embedded_nul_iconv (void)
{
gchar *res;
GError *error = NULL;
setlocale (LC_ALL, "C");
g_setenv ("CHARSET", "US-ASCII", TRUE);
g_assert_false (g_get_charset (NULL));
res = g_locale_to_utf8 ("ab\0c", 4, NULL, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_EMBEDDED_NUL);
g_error_free (error);
}
static void
test_locale_from_utf8_embedded_nul (void)
{
g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/utf8", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/iconv", 0, 0);
g_test_trap_assert_passed ();
}
/* Test that embedded nul characters in input to g_locale_from_utf8(),
* when converting (copying) to UTF-8 output, result in an error.
*/
static void
test_locale_from_utf8_embedded_nul_utf8 (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
setlocale (LC_ALL, "");
g_setenv ("CHARSET", "UTF-8", TRUE);
g_assert_true (g_get_charset (NULL));
res = g_locale_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
/* Test that embedded nul characters in input to g_locale_from_utf8(),
* when converting to non-UTF-8 output, result in an error.
*/
static void
test_locale_from_utf8_embedded_nul_iconv (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
setlocale (LC_ALL, "C");
g_setenv ("CHARSET", "US-ASCII", TRUE);
g_assert_false (g_get_charset (NULL));
res = g_locale_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
static void
test_filename_to_utf8_embedded_nul (void)
{
g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/utf8", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/iconv", 0, 0);
g_test_trap_assert_passed ();
}
/* Test that embedded nul characters in UTF-8 input to g_filename_to_utf8()
* result in an error.
*/
static void
test_filename_to_utf8_embedded_nul_utf8 (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
#ifndef G_OS_WIN32
/* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */
g_setenv ("G_FILENAME_ENCODING", "UTF-8", TRUE);
g_assert_true (g_get_filename_charsets (NULL));
#endif
res = g_filename_to_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
/* Test that embedded nul characters in non-UTF-8 input of g_filename_to_utf8()
* result in an error.
*/
static void
test_filename_to_utf8_embedded_nul_iconv (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
#ifndef G_OS_WIN32
/* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */
g_setenv ("G_FILENAME_ENCODING", "US-ASCII", TRUE);
g_assert_false (g_get_filename_charsets (NULL));
#endif
res = g_filename_to_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
static void
test_filename_from_utf8_embedded_nul (void)
{
g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/utf8", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/iconv", 0, 0);
g_test_trap_assert_passed ();
}
/* Test that embedded nul characters in input to g_filename_from_utf8(),
* when converting (copying) to UTF-8 output, result in an error.
*/
static void
test_filename_from_utf8_embedded_nul_utf8 (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
#ifndef G_OS_WIN32
/* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */
g_setenv ("G_FILENAME_ENCODING", "UTF-8", TRUE);
g_assert_true (g_get_filename_charsets (NULL));
#endif
res = g_filename_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
/* Test that embedded nul characters in input to g_filename_from_utf8(),
* when converting to non-UTF-8 output, result in an error.
*/
static void
test_filename_from_utf8_embedded_nul_iconv (void)
{
gchar *res;
gsize bytes_read;
GError *error = NULL;
#ifndef G_OS_WIN32
/* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */
g_setenv ("G_FILENAME_ENCODING", "US-ASCII", TRUE);
g_assert_false (g_get_filename_charsets (NULL));
#endif
res = g_filename_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error);
g_assert_null (res);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
g_assert_cmpuint (bytes_read, ==, 2);
g_error_free (error);
}
static void
test_no_conv (void)
{
const gchar *in = "";
gchar *out G_GNUC_UNUSED;
gsize bytes_read = 0;
gsize bytes_written = 0;
GError *error = NULL;
out = g_convert (in, -1, "XXX", "UVZ",
&bytes_read, &bytes_written, &error);
/* error code is unreliable, since we mishandle errno there */
g_assert (error && error->domain == G_CONVERT_ERROR);
g_error_free (error);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/conversion/no-conv", test_no_conv);
g_test_add_func ("/conversion/iconv-state", test_iconv_state);
g_test_add_func ("/conversion/illegal-sequence", test_one_half);
g_test_add_func ("/conversion/byte-order", test_byte_order);
g_test_add_func ("/conversion/unicode", test_unicode_conversions);
g_test_add_func ("/conversion/filename-utf8", test_filename_utf8);
g_test_add_func ("/conversion/filename-display", test_filename_display);
g_test_add_func ("/conversion/convert-embedded-nul", test_convert_embedded_nul);
g_test_add_func ("/conversion/locale-to-utf8/embedded-nul", test_locale_to_utf8_embedded_nul);
g_test_add_func ("/conversion/locale-to-utf8/embedded-nul/subprocess/utf8", test_locale_to_utf8_embedded_nul_utf8);
g_test_add_func ("/conversion/locale-to-utf8/embedded-nul/subprocess/iconv", test_locale_to_utf8_embedded_nul_iconv);
g_test_add_func ("/conversion/locale-from-utf8/embedded-nul", test_locale_from_utf8_embedded_nul);
g_test_add_func ("/conversion/locale-from-utf8/embedded-nul/subprocess/utf8", test_locale_from_utf8_embedded_nul_utf8);
g_test_add_func ("/conversion/locale-from-utf8/embedded-nul/subprocess/iconv", test_locale_from_utf8_embedded_nul_iconv);
g_test_add_func ("/conversion/filename-to-utf8/embedded-nul", test_filename_to_utf8_embedded_nul);
g_test_add_func ("/conversion/filename-to-utf8/embedded-nul/subprocess/utf8", test_filename_to_utf8_embedded_nul_utf8);
g_test_add_func ("/conversion/filename-to-utf8/embedded-nul/subprocess/iconv", test_filename_to_utf8_embedded_nul_iconv);
g_test_add_func ("/conversion/filename-from-utf8/embedded-nul", test_filename_from_utf8_embedded_nul);
g_test_add_func ("/conversion/filename-from-utf8/embedded-nul/subprocess/utf8", test_filename_from_utf8_embedded_nul_utf8);
g_test_add_func ("/conversion/filename-from-utf8/embedded-nul/subprocess/iconv", test_filename_from_utf8_embedded_nul_iconv);
return g_test_run ();
}

104
glib/tests/cxx.cpp Normal file
View file

@ -0,0 +1,104 @@
/*
* Copyright 2020 Xavier Claessens
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
typedef struct
{
int dummy;
} MyObject;
static void
test_typeof (void)
{
#if __cplusplus >= 201103L
// Test that with C++11 we don't get those kind of errors:
// error: invalid conversion from gpointer {aka void*} to MyObject* [-fpermissive]
MyObject *obj = g_rc_box_new0 (MyObject);
MyObject *obj2 = g_rc_box_acquire (obj);
g_assert_true (obj2 == obj);
MyObject *obj3 = g_atomic_pointer_get (&obj2);
g_assert_true (obj3 == obj);
MyObject *obj4 = nullptr;
g_atomic_pointer_set (&obj4, obj3);
g_assert_true (obj4 == obj);
MyObject *obj5 = nullptr;
g_atomic_pointer_compare_and_exchange (&obj5, nullptr, obj4);
g_assert_true (obj5 == obj);
MyObject *obj6 = g_steal_pointer (&obj5);
g_assert_true (obj6 == obj);
g_clear_pointer (&obj6, g_rc_box_release);
g_rc_box_release (obj);
#else
g_test_skip ("This test requires a C++11 compiler");
#endif
}
static void
test_atomic_pointer_compare_and_exchange (void)
{
#if __cplusplus >= 201103L
const gchar *str1 = "str1";
const gchar *str2 = "str2";
const gchar *atomic_string = str1;
g_test_message ("Test that g_atomic_pointer_compare_and_exchange() with a "
"non-void* pointer doesnt have any compiler warnings in C++ mode");
g_assert_true (g_atomic_pointer_compare_and_exchange (&atomic_string, str1, str2));
g_assert_true (atomic_string == str2);
#else
g_test_skip ("This test requires a C++11 compiler");
#endif
}
static void
test_atomic_int_compare_and_exchange (void)
{
#if __cplusplus >= 201103L
gint atomic_int = 5;
g_test_message ("Test that g_atomic_int_compare_and_exchange() doesnt have "
"any compiler warnings in C++ mode");
g_assert_true (g_atomic_int_compare_and_exchange (&atomic_int, 5, 50));
g_assert_cmpint (atomic_int, ==, 50);
#else
g_test_skip ("This test requires a C++11 compiler");
#endif
}
int
main (int argc, char *argv[])
{
#if __cplusplus >= 201103L
g_test_init (&argc, &argv, nullptr);
#else
g_test_init (&argc, &argv, NULL);
#endif
g_test_add_func ("/C++/typeof", test_typeof);
g_test_add_func ("/C++/atomic-pointer-compare-and-exchange", test_atomic_pointer_compare_and_exchange);
g_test_add_func ("/C++/atomic-int-compare-and-exchange", test_atomic_int_compare_and_exchange);
return g_test_run ();
}

270
glib/tests/dataset.c Normal file
View file

@ -0,0 +1,270 @@
#include <glib.h>
#include <stdlib.h>
static void
test_quark_basic (void)
{
GQuark quark;
const gchar *orig = "blargh";
gchar *copy;
const gchar *str;
quark = g_quark_try_string ("no-such-quark");
g_assert (quark == 0);
copy = g_strdup (orig);
quark = g_quark_from_static_string (orig);
g_assert (quark != 0);
g_assert (g_quark_from_string (orig) == quark);
g_assert (g_quark_from_string (copy) == quark);
g_assert (g_quark_try_string (orig) == quark);
str = g_quark_to_string (quark);
g_assert_cmpstr (str, ==, orig);
g_free (copy);
}
static void
test_quark_string (void)
{
const gchar *orig = "string1";
gchar *copy;
const gchar *str1;
const gchar *str2;
copy = g_strdup (orig);
str1 = g_intern_static_string (orig);
str2 = g_intern_string (copy);
g_assert (str1 == str2);
g_assert (str1 == orig);
g_free (copy);
}
static void
test_dataset_basic (void)
{
gpointer location = (gpointer)test_dataset_basic;
gpointer other = (gpointer)test_quark_basic;
gpointer data = "test1";
gpointer ret;
g_dataset_set_data (location, "test1", data);
ret = g_dataset_get_data (location, "test1");
g_assert (ret == data);
ret = g_dataset_get_data (location, "test2");
g_assert (ret == NULL);
ret = g_dataset_get_data (other, "test1");
g_assert (ret == NULL);
g_dataset_set_data (location, "test1", "new-value");
ret = g_dataset_get_data (location, "test1");
g_assert (ret != data);
g_dataset_remove_data (location, "test1");
ret = g_dataset_get_data (location, "test1");
g_assert (ret == NULL);
ret = g_dataset_get_data (location, NULL);
g_assert (ret == NULL);
}
static gint destroy_count;
static void
notify (gpointer data)
{
destroy_count++;
}
static void
test_dataset_full (void)
{
gpointer location = (gpointer)test_dataset_full;
g_dataset_set_data_full (location, "test1", "test1", notify);
destroy_count = 0;
g_dataset_set_data (location, "test1", NULL);
g_assert (destroy_count == 1);
g_dataset_set_data_full (location, "test1", "test1", notify);
destroy_count = 0;
g_dataset_remove_data (location, "test1");
g_assert (destroy_count == 1);
g_dataset_set_data_full (location, "test1", "test1", notify);
destroy_count = 0;
g_dataset_remove_no_notify (location, "test1");
g_assert (destroy_count == 0);
}
static void
foreach (GQuark id,
gpointer data,
gpointer user_data)
{
gint *counter = user_data;
*counter += 1;
}
static void
test_dataset_foreach (void)
{
gpointer location = (gpointer)test_dataset_foreach;
gint my_count;
my_count = 0;
g_dataset_set_data_full (location, "test1", "test1", notify);
g_dataset_set_data_full (location, "test2", "test2", notify);
g_dataset_set_data_full (location, "test3", "test3", notify);
g_dataset_foreach (location, foreach, &my_count);
g_assert (my_count == 3);
g_dataset_destroy (location);
}
static void
test_dataset_destroy (void)
{
gpointer location = (gpointer)test_dataset_destroy;
destroy_count = 0;
g_dataset_set_data_full (location, "test1", "test1", notify);
g_dataset_set_data_full (location, "test2", "test2", notify);
g_dataset_set_data_full (location, "test3", "test3", notify);
g_dataset_destroy (location);
g_assert (destroy_count == 3);
}
static void
test_dataset_id (void)
{
gpointer location = (gpointer)test_dataset_id;
gpointer other = (gpointer)test_quark_basic;
gpointer data = "test1";
gpointer ret;
GQuark quark;
quark = g_quark_from_string ("test1");
g_dataset_id_set_data (location, quark, data);
ret = g_dataset_id_get_data (location, quark);
g_assert (ret == data);
ret = g_dataset_id_get_data (location, g_quark_from_string ("test2"));
g_assert (ret == NULL);
ret = g_dataset_id_get_data (other, quark);
g_assert (ret == NULL);
g_dataset_id_set_data (location, quark, "new-value");
ret = g_dataset_id_get_data (location, quark);
g_assert (ret != data);
g_dataset_id_remove_data (location, quark);
ret = g_dataset_id_get_data (location, quark);
g_assert (ret == NULL);
ret = g_dataset_id_get_data (location, 0);
g_assert (ret == NULL);
}
static GData *global_list;
static void
free_one (gpointer data)
{
/* recurse */
g_datalist_clear (&global_list);
}
static void
test_datalist_clear (void)
{
/* Need to use a subprocess because it will deadlock if it fails */
if (g_test_subprocess ())
{
g_datalist_init (&global_list);
g_datalist_set_data_full (&global_list, "one", GINT_TO_POINTER (1), free_one);
g_datalist_set_data_full (&global_list, "two", GINT_TO_POINTER (2), NULL);
g_datalist_clear (&global_list);
g_assert (global_list == NULL);
return;
}
g_test_trap_subprocess (NULL, 500000, 0);
g_test_trap_assert_passed ();
}
static void
test_datalist_basic (void)
{
GData *list = NULL;
gpointer data;
gpointer ret;
g_datalist_init (&list);
data = "one";
g_datalist_set_data (&list, "one", data);
ret = g_datalist_get_data (&list, "one");
g_assert (ret == data);
ret = g_datalist_get_data (&list, "two");
g_assert (ret == NULL);
ret = g_datalist_get_data (&list, NULL);
g_assert (ret == NULL);
g_datalist_clear (&list);
}
static void
test_datalist_id (void)
{
GData *list = NULL;
gpointer data;
gpointer ret;
g_datalist_init (&list);
data = "one";
g_datalist_id_set_data (&list, g_quark_from_string ("one"), data);
ret = g_datalist_id_get_data (&list, g_quark_from_string ("one"));
g_assert (ret == data);
ret = g_datalist_id_get_data (&list, g_quark_from_string ("two"));
g_assert (ret == NULL);
ret = g_datalist_id_get_data (&list, 0);
g_assert (ret == NULL);
g_datalist_clear (&list);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/quark/basic", test_quark_basic);
g_test_add_func ("/quark/string", test_quark_string);
g_test_add_func ("/dataset/basic", test_dataset_basic);
g_test_add_func ("/dataset/id", test_dataset_id);
g_test_add_func ("/dataset/full", test_dataset_full);
g_test_add_func ("/dataset/foreach", test_dataset_foreach);
g_test_add_func ("/dataset/destroy", test_dataset_destroy);
g_test_add_func ("/datalist/basic", test_datalist_basic);
g_test_add_func ("/datalist/id", test_datalist_id);
g_test_add_func ("/datalist/recursive-clear", test_datalist_clear);
return g_test_run ();
}

1811
glib/tests/date.c Normal file

File diff suppressed because it is too large Load diff

53
glib/tests/dir.c Normal file
View file

@ -0,0 +1,53 @@
#include <glib.h>
static void
test_dir_read (void)
{
GDir *dir;
GError *error;
gchar *first;
const gchar *name;
error = NULL;
dir = g_dir_open (".", 0, &error);
g_assert_no_error (error);
first = NULL;
while ((name = g_dir_read_name (dir)) != NULL)
{
if (first == NULL)
first = g_strdup (name);
g_assert_cmpstr (name, !=, ".");
g_assert_cmpstr (name, !=, "..");
}
g_dir_rewind (dir);
g_assert_cmpstr (g_dir_read_name (dir), ==, first);
g_free (first);
g_dir_close (dir);
}
static void
test_dir_nonexisting (void)
{
GDir *dir;
GError *error;
error = NULL;
dir = g_dir_open ("/pfrkstrf", 0, &error);
g_assert (dir == NULL);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_error_free (error);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/dir/read", test_dir_read);
g_test_add_func ("/dir/nonexisting", test_dir_nonexisting);
return g_test_run ();
}

2
glib/tests/echo-script Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
echo "echo"

View file

@ -0,0 +1,2 @@
@echo off
echo echo

0
glib/tests/empty Normal file
View file

305
glib/tests/environment.c Normal file
View file

@ -0,0 +1,305 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 2010 Ryan Lortie
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
static void
test_listenv (void)
{
GHashTable *table;
gchar **list;
gint i;
table = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
list = g_get_environ ();
for (i = 0; list[i]; i++)
{
gchar **parts;
parts = g_strsplit (list[i], "=", 2);
g_assert_null (g_hash_table_lookup (table, parts[0]));
if (g_strcmp0 (parts[0], ""))
g_hash_table_insert (table, parts[0], parts[1]);
g_free (parts);
}
g_strfreev (list);
g_assert_cmpint (g_hash_table_size (table), >, 0);
list = g_listenv ();
for (i = 0; list[i]; i++)
{
const gchar *expected;
const gchar *value;
expected = g_hash_table_lookup (table, list[i]);
value = g_getenv (list[i]);
g_assert_cmpstr (value, ==, expected);
g_hash_table_remove (table, list[i]);
}
g_assert_cmpint (g_hash_table_size (table), ==, 0);
g_hash_table_unref (table);
g_strfreev (list);
}
static void
test_getenv (void)
{
const gchar *data;
const gchar *variable = "TEST_G_SETENV";
const gchar *value1 = "works";
const gchar *value2 = "again";
/* Check that TEST_G_SETENV is not already set */
g_assert_null (g_getenv (variable));
/* Check if g_setenv() failed */
g_assert_cmpint (g_setenv (variable, value1, TRUE), !=, 0);
data = g_getenv (variable);
g_assert_nonnull (data);
g_assert_cmpstr (data, ==, value1);
g_assert_cmpint (g_setenv (variable, value2, FALSE), !=, 0);
data = g_getenv (variable);
g_assert_nonnull (data);
g_assert_cmpstr (data, !=, value2);
g_assert_cmpstr (data, ==, value1);
g_assert_cmpint (g_setenv (variable, value2, TRUE), !=, 0);
data = g_getenv (variable);
g_assert_nonnull (data);
g_assert_cmpstr (data, !=, value1);
g_assert_cmpstr (data, ==, value2);
g_unsetenv (variable);
g_assert_null (g_getenv (variable));
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
g_assert_false (g_setenv (NULL, "baz", TRUE));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
g_assert_false (g_setenv ("foo", NULL, TRUE));
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* == NULL*");
g_assert_false (g_setenv ("foo=bar", "baz", TRUE));
g_test_assert_expected_messages ();
}
g_assert_true (g_setenv ("foo", "bar=baz", TRUE));
/* Different OSs return different values; some return NULL because the key
* is invalid, but some are happy to return what we set above. */
data = g_getenv ("foo=bar");
if (data != NULL)
g_assert_cmpstr (data, ==, "baz");
data = g_getenv ("foo");
g_assert_cmpstr (data, ==, "bar=baz");
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
g_unsetenv (NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* == NULL*");
g_unsetenv ("foo=bar");
g_test_assert_expected_messages ();
}
g_unsetenv ("foo");
g_assert_null (g_getenv ("foo"));
}
static void
test_setenv (void)
{
const gchar *var, *value;
var = "NOSUCHENVVAR";
value = "value1";
g_assert_null (g_getenv (var));
g_setenv (var, value, FALSE);
g_assert_cmpstr (g_getenv (var), ==, value);
g_assert_true (g_setenv (var, "value2", FALSE));
g_assert_cmpstr (g_getenv (var), ==, value);
g_assert_true (g_setenv (var, "value2", TRUE));
g_assert_cmpstr (g_getenv (var), ==, "value2");
g_unsetenv (var);
g_assert_null (g_getenv (var));
}
static void
test_environ_array (void)
{
gchar **env;
const gchar *value;
env = g_new (gchar *, 1);
env[0] = NULL;
if (g_test_undefined ())
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
g_environ_getenv (env, NULL);
g_test_assert_expected_messages ();
}
value = g_environ_getenv (env, "foo");
g_assert_null (value);
if (g_test_undefined ())
{
gchar **undefined_env;
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
undefined_env = g_environ_setenv (env, NULL, "bar", TRUE);
g_test_assert_expected_messages ();
g_strfreev (undefined_env);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* == NULL*");
undefined_env = g_environ_setenv (env, "foo=fuz", "bar", TRUE);
g_test_assert_expected_messages ();
g_strfreev (undefined_env);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
undefined_env = g_environ_setenv (env, "foo", NULL, TRUE);
g_test_assert_expected_messages ();
g_strfreev (undefined_env);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion* != NULL*");
undefined_env = g_environ_unsetenv (env, NULL);
g_test_assert_expected_messages ();
g_strfreev (undefined_env);
}
env = g_environ_setenv (env, "foo", "bar", TRUE);
value = g_environ_getenv (env, "foo");
g_assert_cmpstr (value, ==, "bar");
env = g_environ_setenv (env, "foo2", "bar2", FALSE);
value = g_environ_getenv (env, "foo");
g_assert_cmpstr (value, ==, "bar");
value = g_environ_getenv (env, "foo2");
g_assert_cmpstr (value, ==, "bar2");
env = g_environ_setenv (env, "foo", "x", FALSE);
value = g_environ_getenv (env, "foo");
g_assert_cmpstr (value, ==, "bar");
env = g_environ_setenv (env, "foo", "x", TRUE);
value = g_environ_getenv (env, "foo");
g_assert_cmpstr (value, ==, "x");
env = g_environ_unsetenv (env, "foo2");
value = g_environ_getenv (env, "foo2");
g_assert_null (value);
g_strfreev (env);
}
static void
test_environ_null (void)
{
gchar **env;
const gchar *value;
env = NULL;
value = g_environ_getenv (env, "foo");
g_assert_null (value);
env = g_environ_setenv (NULL, "foo", "bar", TRUE);
g_assert_nonnull (env);
g_strfreev (env);
env = g_environ_unsetenv (NULL, "foo");
g_assert_null (env);
}
static void
test_environ_case (void)
{
gchar **env;
const gchar *value;
env = NULL;
env = g_environ_setenv (env, "foo", "bar", TRUE);
value = g_environ_getenv (env, "foo");
g_assert_cmpstr (value, ==, "bar");
value = g_environ_getenv (env, "Foo");
#ifdef G_OS_WIN32
g_assert_cmpstr (value, ==, "bar");
#else
g_assert_null (value);
#endif
env = g_environ_setenv (env, "FOO", "x", TRUE);
value = g_environ_getenv (env, "foo");
#ifdef G_OS_WIN32
g_assert_cmpstr (value, ==, "x");
#else
g_assert_cmpstr (value, ==, "bar");
#endif
env = g_environ_unsetenv (env, "Foo");
value = g_environ_getenv (env, "foo");
#ifdef G_OS_WIN32
g_assert_null (value);
#else
g_assert_cmpstr (value, ==, "bar");
#endif
g_strfreev (env);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/environ/listenv", test_listenv);
g_test_add_func ("/environ/getenv", test_getenv);
g_test_add_func ("/environ/setenv", test_setenv);
g_test_add_func ("/environ/array", test_environ_array);
g_test_add_func ("/environ/null", test_environ_null);
g_test_add_func ("/environ/case", test_environ_case);
return g_test_run ();
}

409
glib/tests/error.c Normal file
View file

@ -0,0 +1,409 @@
#include <glib.h>
#include "glib-private.h"
static void
test_overwrite (void)
{
GError *error, *dest, *src;
if (!g_test_undefined ())
return;
error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*set over the top*");
g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
g_test_assert_expected_messages ();
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
g_error_free (error);
error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*set over the top*");
g_set_error (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
g_test_assert_expected_messages ();
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
g_error_free (error);
dest = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*set over the top*");
g_propagate_error (&dest, src);
g_test_assert_expected_messages ();
g_assert_error (dest, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
g_error_free (dest);
}
static void
test_prefix (void)
{
GError *error;
GError *dest, *src;
error = NULL;
g_prefix_error (&error, "foo %d %s: ", 1, "two");
g_assert (error == NULL);
error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
g_prefix_error (&error, "foo %d %s: ", 1, "two");
g_assert_cmpstr (error->message, ==, "foo 1 two: bla");
g_error_free (error);
dest = NULL;
src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
g_propagate_prefixed_error (&dest, src, "foo %d %s: ", 1, "two");
g_assert_cmpstr (dest->message, ==, "foo 1 two: bla");
g_error_free (dest);
src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
g_propagate_prefixed_error (NULL, src, "foo %d %s: ", 1, "two");
}
static void
test_prefix_literal (void)
{
GError *error = NULL;
g_prefix_error_literal (NULL, "foo: ");
g_prefix_error_literal (&error, "foo: ");
g_assert_null (error);
error = NULL;
g_prefix_error_literal (&error, "foo: ");
g_assert_null (error);
error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
g_assert_nonnull (error);
g_prefix_error_literal (&error, "foo: ");
g_assert_cmpstr (error->message, ==, "foo: bla");
g_error_free (error);
}
static void
test_literal (void)
{
GError *error;
error = NULL;
g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x");
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
g_assert_cmpstr (error->message, ==, "%s %d %x");
g_error_free (error);
}
static void
test_copy (void)
{
GError *error;
GError *copy;
error = NULL;
g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x");
copy = g_error_copy (error);
g_assert_error (copy, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
g_assert_cmpstr (copy->message, ==, "%s %d %x");
g_error_free (error);
g_error_free (copy);
}
static void
test_new_valist_invalid_va (gpointer dummy,
...)
{
#ifdef __linux__
/* Only worth testing this on Linux; if other platforms regress on this legacy
* behaviour, we dont care. In particular, calling g_error_new_valist() with
* a %NULL format will crash on FreeBSD as its implementation of vasprintf()
* is less forgiving than Linuxs. Thats fine: its a programmer error in
* either case. */
const struct
{
GQuark domain;
const gchar *format;
}
tests[] =
{
{ G_MARKUP_ERROR, NULL },
{ 0, "Message" },
};
gsize i;
g_test_summary ("Test that g_error_new_valist() rejects invalid input");
if (!g_test_undefined ())
{
g_test_skip ("Not testing response to programmer error");
return;
}
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
GError *error = NULL, *error_copy = NULL;
va_list ap;
g_test_message ("Test %" G_GSIZE_FORMAT, i);
va_start (ap, dummy);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
g_test_expect_message (G_LOG_DOMAIN,
G_LOG_LEVEL_WARNING,
"*g_error_new_valist: runtime check failed*");
error = g_error_new_valist (tests[i].domain, G_MARKUP_ERROR_EMPTY, tests[i].format, ap);
g_test_assert_expected_messages ();
g_assert_nonnull (error);
#pragma GCC diagnostic pop
g_test_expect_message (G_LOG_DOMAIN,
G_LOG_LEVEL_WARNING,
"*g_error_copy: runtime check failed*");
error_copy = g_error_copy (error);
g_test_assert_expected_messages ();
g_assert_nonnull (error_copy);
g_clear_error (&error);
g_clear_error (&error_copy);
va_end (ap);
}
#else /* if !__linux__ */
g_test_skip ("g_error_new_valist() programmer error handling is only relevant on Linux");
#endif /* !__linux__ */
}
static void
test_new_valist_invalid (void)
{
/* We need a wrapper function so we can build a va_list */
test_new_valist_invalid_va (NULL);
}
static void
test_matches (void)
{
GError *error = NULL;
g_test_summary ("Test g_error_matches()");
error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!");
g_assert_true (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY));
g_assert_false (g_error_matches (NULL, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY));
g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE)); /* same numeric value as G_MARKUP_ERROR_EMPTY */
g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED)); /* different numeric value from G_MARKUP_ERROR_EMPTY */
g_assert_false (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_BAD_UTF8));
g_error_free (error);
}
static void
test_clear (void)
{
GError *error = NULL;
g_test_summary ("Test g_error_clear()");
g_clear_error (&error);
g_assert_null (error);
g_clear_error (NULL);
error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!");
g_clear_error (&error);
g_assert_null (error);
}
typedef struct
{
int init_called;
int copy_called;
int free_called;
} TestErrorCheck;
static TestErrorCheck *init_check;
GQuark test_error_quark (void);
#define TEST_ERROR (test_error_quark ())
typedef struct
{
int foo;
TestErrorCheck *check;
} TestErrorPrivate;
static void
test_error_private_init (TestErrorPrivate *priv)
{
priv->foo = 13;
/* If that triggers, it's test bug.
*/
g_assert_nonnull (init_check);
/* Using global init_check, because error->check is still nil at
* this point.
*/
init_check->init_called++;
}
static void
test_error_private_copy (const TestErrorPrivate *src_priv,
TestErrorPrivate *dest_priv)
{
dest_priv->foo = src_priv->foo;
dest_priv->check = src_priv->check;
dest_priv->check->copy_called++;
}
static void
test_error_private_clear (TestErrorPrivate *priv)
{
priv->check->free_called++;
}
G_DEFINE_EXTENDED_ERROR (TestError, test_error)
static TestErrorPrivate *
fill_test_error (GError *error, TestErrorCheck *check)
{
TestErrorPrivate *test_error = test_error_get_private (error);
test_error->check = check;
return test_error;
}
static void
test_extended (void)
{
TestErrorCheck check = { 0, 0, 0 };
GError *error;
TestErrorPrivate *test_priv;
GError *copy_error;
TestErrorPrivate *copy_test_priv;
init_check = &check;
error = g_error_new_literal (TEST_ERROR, 0, "foo");
test_priv = fill_test_error (error, &check);
g_assert_cmpint (check.init_called, ==, 1);
g_assert_cmpint (check.copy_called, ==, 0);
g_assert_cmpint (check.free_called, ==, 0);
g_assert_cmpuint (error->domain, ==, TEST_ERROR);
g_assert_cmpint (test_priv->foo, ==, 13);
copy_error = g_error_copy (error);
g_assert_cmpint (check.init_called, ==, 2);
g_assert_cmpint (check.copy_called, ==, 1);
g_assert_cmpint (check.free_called, ==, 0);
g_assert_cmpuint (error->domain, ==, copy_error->domain);
g_assert_cmpint (error->code, ==, copy_error->code);
g_assert_cmpstr (error->message, ==, copy_error->message);
copy_test_priv = test_error_get_private (copy_error);
g_assert_cmpint (test_priv->foo, ==, copy_test_priv->foo);
g_error_free (error);
g_error_free (copy_error);
g_assert_cmpint (check.init_called, ==, 2);
g_assert_cmpint (check.copy_called, ==, 1);
g_assert_cmpint (check.free_called, ==, 2);
}
static void
test_extended_duplicate (void)
{
g_test_summary ("Test that registering a duplicate extended error domain doesnt work");
if (!g_test_subprocess ())
{
/* Spawn a subprocess and expect it to fail. */
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*CRITICAL*Attempted to register an extended error domain for TestError more than once*");
}
else
{
GQuark q;
guint i;
for (i = 0; i < 2; i++)
{
q = g_error_domain_register_static ("TestError",
sizeof (TestErrorPrivate),
g_error_with_test_error_private_init,
g_error_with_test_error_private_copy,
g_error_with_test_error_private_clear);
g_assert_cmpstr (g_quark_to_string (q), ==, "TestError");
}
}
}
typedef struct
{
int dummy;
} TestErrorNonStaticPrivate;
static void test_error_non_static_private_init (GError *error) {}
static void test_error_non_static_private_copy (const GError *src_error, GError *dest_error) {}
static void test_error_non_static_private_clear (GError *error) {}
static void
test_extended_non_static (void)
{
gchar *domain_name = g_strdup ("TestErrorNonStatic");
GQuark q;
GError *error = NULL;
g_test_summary ("Test registering an extended error domain with a non-static name");
q = g_error_domain_register (domain_name,
sizeof (TestErrorNonStaticPrivate),
test_error_non_static_private_init,
test_error_non_static_private_copy,
test_error_non_static_private_clear);
g_free (domain_name);
error = g_error_new (q, 0, "Test error: %s", "hello");
g_assert_true (g_error_matches (error, q, 0));
g_assert_cmpstr (g_quark_to_string (q), ==, "TestErrorNonStatic");
g_error_free (error);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/error/overwrite", test_overwrite);
g_test_add_func ("/error/prefix", test_prefix);
g_test_add_func ("/error/prefix-literal", test_prefix_literal);
g_test_add_func ("/error/literal", test_literal);
g_test_add_func ("/error/copy", test_copy);
g_test_add_func ("/error/matches", test_matches);
g_test_add_func ("/error/clear", test_clear);
g_test_add_func ("/error/new-valist/invalid", test_new_valist_invalid);
g_test_add_func ("/error/extended", test_extended);
g_test_add_func ("/error/extended/duplicate", test_extended_duplicate);
g_test_add_func ("/error/extended/non-static", test_extended_non_static);
return g_test_run ();
}

2468
glib/tests/fileutils.c Normal file

File diff suppressed because it is too large Load diff

3193
glib/tests/gdatetime.c Normal file

File diff suppressed because it is too large Load diff

83
glib/tests/gen-casefold-txt.py Executable file
View file

@ -0,0 +1,83 @@
#!/usr/bin/env python3
# Copyright (C) 1998, 1999 Tom Tromey
# Copyright (C) 2001 Red Hat Software
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
"""
gen-casefold-txt.py - Generate test cases for casefolding from Unicode data.
See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html
Usage:
I consider the output of this program to be unrestricted.
Use it as you will.
"""
import sys
import argparse
def main(argv):
parser = argparse.ArgumentParser(
description="Generate test cases for casefolding from Unicode data"
)
parser.add_argument("UNICODE-VERSION")
parser.add_argument("CaseFolding.txt")
args = parser.parse_args(argv[1:])
version = getattr(args, "UNICODE-VERSION")
filename = getattr(args, "CaseFolding.txt")
print(
"""\
# Test cases generated from Unicode {} data
# by gen-casefold-txt.py. Do not edit.
#
# Some special hand crafted tests
#
AaBbCc@@\taabbcc@@
#
# Now the automatic tests
#""".format(
version
)
)
# Names of fields in the CaseFolding table
CODE, STATUS, MAPPING = range(3)
with open(filename, encoding="utf-8") as fileobj:
for line in fileobj:
# strip comments and skip empty lines
line = line.split("#", 1)[0].strip()
if not line:
continue
fields = [f.strip() for f in line.split(";", 3)[:3]]
if len(fields) != 3:
raise SystemExit(
"Entry for %s has wrong number of fields (%d)"
% (fields[CODE], len(fields))
)
status = fields[STATUS]
# skip simple and Turkic mappings
if status in "ST":
continue
code = chr(int(fields[CODE], 16))
values = "".join([chr(int(v, 16)) for v in fields[MAPPING].split()])
print("{}\t{}".format(code, values))
if __name__ == "__main__":
sys.exit(main(sys.argv))

240
glib/tests/gen-casemap-txt.py Executable file
View file

@ -0,0 +1,240 @@
#!/usr/bin/env python3
# Copyright (C) 1998, 1999 Tom Tromey
# Copyright (C) 2001 Red Hat Software
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
"""
gen-casemap-txt.py - Generate test cases for case mapping from Unicode data.
See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html
Usage:
I consider the output of this program to be unrestricted.
Use it as you will.
"""
import sys
import argparse
# Disable line length warnings as wrapping the test templates would be hard
# flake8: noqa: E501
def main(argv):
parser = argparse.ArgumentParser(
description="Generate test cases for case mapping from Unicode data"
)
parser.add_argument("UNICODE-VERSION")
parser.add_argument("UnicodeData.txt")
parser.add_argument("SpecialCasing.txt")
args = parser.parse_args(argv[1:])
version = getattr(args, "UNICODE-VERSION")
filename_udata = getattr(args, "UnicodeData.txt")
filename_casing = getattr(args, "SpecialCasing.txt")
# Names of fields in Unicode data table.
(
CODE,
NAME,
CATEGORY,
COMBINING_CLASSES,
BIDI_CATEGORY,
DECOMPOSITION,
DECIMAL_VALUE,
DIGIT_VALUE,
NUMERIC_VALUE,
MIRRORED,
OLD_NAME,
COMMENT,
UPPER,
LOWER,
TITLE,
) = range(15)
# Names of fields in the SpecialCasing table
CASE_CODE, CASE_LOWER, CASE_TITLE, CASE_UPPER, CASE_CONDITION = range(5)
upper = {}
title = {}
lower = {}
def make_hex(codes):
"""Converts a string of white space separated code points encoded as
hex values to a Unicode string. Any extra white space is ignored.
"""
return "".join([chr(int(c, 16)) for c in codes.split()])
def process_one(code, fields):
type_ = fields[CATEGORY]
if type_ == "Ll":
upper[code] = make_hex(fields[UPPER])
lower[code] = chr(code)
title[code] = make_hex(fields[TITLE])
elif type_ == "Lu":
lower[code] = make_hex(fields[LOWER])
upper[code] = chr(code)
title[code] = make_hex(fields[TITLE])
elif type_ == "Lt":
upper[code] = make_hex(fields[UPPER])
lower[code] = make_hex(fields[LOWER])
title[code] = make_hex(fields[LOWER])
with open(filename_udata, encoding="utf-8") as fileobj:
last_code = -1
for line in fileobj:
line = line.strip()
fields = [f.strip() for f in line.split(";")]
if len(fields) != 15:
raise SystemExit(
"Entry for %s has wrong number of fields (%d)"
% (fields[CODE], len(fields))
)
code = int(fields[CODE], 16)
if code > last_code + 1:
# Found a gap
if fields[NAME].endswith("Last>"):
# Fill the gap with the last character read,
# since this was a range specified in the char database
gfields = fields
else:
# The gap represents undefined characters. Only the type
# matters.
gfields = [
"",
"",
"Cn",
"0",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
]
last_code += 1
while last_code < code:
gfields[CODE] = "%04x" % last_code
process_one(last_code, gfields)
last_code += 1
process_one(code, fields)
last_code = code
with open(filename_casing, encoding="utf-8") as fileobj:
last_code = -1
for line in fileobj:
# strip comments and skip empty lines
line = line.split("#", 1)[0].strip()
if not line:
continue
# all lines end with ";" so just remove it
line = line.rstrip(";").rstrip()
fields = [f.strip() for f in line.split(";")]
if len(fields) not in (4, 5):
raise SystemExit(
"Entry for %s has wrong number of fields (%d)"
% (fields[CASE_CODE], len(fields))
)
if len(fields) == 5:
# Ignore conditional special cases - we'll handle them manually
continue
code = int(fields[CASE_CODE], 16)
upper[code] = make_hex(fields[CASE_UPPER])
lower[code] = make_hex(fields[CASE_LOWER])
title[code] = make_hex(fields[CASE_TITLE])
print_tests(version, upper, title, lower)
def print_tests(version, upper, title, lower):
print(
"""\
# Test cases generated from Unicode {} data
# by gen-casemap-txt.py. Do not edit.
#
# Some special hand crafted tests
#
tr_TR\ti\ti\t\u0130\t\u0130\t# i => LATIN CAPITAL LETTER I WITH DOT ABOVE
tr_TR\tI\t\u0131\tI\tI\t# I => LATIN SMALL LETTER DOTLESS I
tr_TR\tI\u0307\ti\tI\u0307\tI\u0307\t# I => LATIN SMALL LETTER DOTLESS I
tr_TR.UTF-8\ti\ti\t\u0130\t\u0130\t# i => LATIN CAPITAL LETTER I WITH DOT ABOVE
tr_TR.UTF-8\tI\t\u0131\tI\tI\t# I => LATIN SMALL LETTER DOTLESS I
tr_TR.UTF-8\tI\u0307\ti\tI\u0307\tI\u0307\t# I => LATIN SMALL LETTER DOTLESS I
# Test reordering of YPOGEGRAMMENI across other accents
\t\u03b1\u0345\u0314\t\u03b1\u0345\u0314\t\u0391\u0345\u0314\t\u0391\u0314\u0399\t
\t\u03b1\u0314\u0345\t\u03b1\u0314\u0345\t\u0391\u0314\u0345\t\u0391\u0314\u0399\t
# Handling of final and nonfinal sigma
\tΜΆΙΟΣ μάιος Μάιος ΜΆΙΟΣ \t
\tΜΆΙΟΣ μάιος Μάιος ΜΆΙΟΣ\t
\ΙΓΜΑ σιγμα Σιγμα ΣΙΓΜΑ\t
# Lithuanian rule of i followed by letter with dot. Not at all sure
# about the titlecase part here
lt_LT\ti\u0117\ti\u0117\tIe\tIE\t
lt_LT\tie\u0307\tie\u0307\tIe\tIE\t
lt_LT\t\u00cc\ti\u0307\u0300\t\u00cc\t\u00cc\t # LATIN CAPITAL LETTER I WITH GRAVE
lt_LT\t\u00CD\ti\u0307\u0301\t\u00CD\t\u00CD\t # LATIN CAPITAL LETTER I WITH ACUTE
lt_LT\t\u0128\ti\u0307\u0303\t\u0128\t\u0128\t # LATIN CAPITAL LETTER I WITH TILDE
lt_LT\tI\u0301\ti\u0307\u0301\tI\u0301\tI\u0301\t # LATIN CAPITAL LETTER I (with acute accent)
lt_LT\tI\u0300\ti\u0307\u0300\tI\u0300\tI\u0300\t # LATIN CAPITAL LETTER I (with grave accent)
lt_LT\tI\u0303\ti\u0307\u0303\tI\u0303\tI\u0303\t # LATIN CAPITAL LETTER I (with tilde above)
lt_LT\tI\u0328\u0301\ti\u0307\u0328\u0301\tI\u0328\u0301\tI\u0328\u0301\t # LATIN CAPITAL LETTER I (with ogonek and acute accent)
lt_LT\tJ\u0301\tj\u0307\u0301\tJ\u0301\tJ\u0301\t # LATIN CAPITAL LETTER J (with acute accent)
lt_LT\t\u012e\u0301\t\u012f\u0307\u0301\t\u012e\u0301\t\u012e\u0301\t # LATIN CAPITAL LETTER I WITH OGONEK (with acute accent)
lt_LT.UTF-8\ti\u0117\ti\u0117\tIe\tIE\t
lt_LT.UTF-8\tie\u0307\tie\u0307\tIe\tIE\t
lt_LT.UTF-8\t\u00cc\ti\u0307\u0300\t\u00cc\t\u00cc\t # LATIN CAPITAL LETTER I WITH GRAVE
lt_LT.UTF-8\t\u00CD\ti\u0307\u0301\t\u00CD\t\u00CD\t # LATIN CAPITAL LETTER I WITH ACUTE
lt_LT.UTF-8\t\u0128\ti\u0307\u0303\t\u0128\t\u0128\t # LATIN CAPITAL LETTER I WITH TILDE
lt_LT.UTF-8\tI\u0301\ti\u0307\u0301\tI\u0301\tI\u0301\t # LATIN CAPITAL LETTER I (with acute accent)
lt_LT.UTF-8\tI\u0300\ti\u0307\u0300\tI\u0300\tI\u0300\t # LATIN CAPITAL LETTER I (with grave accent)
lt_LT.UTF-8\tI\u0303\ti\u0307\u0303\tI\u0303\tI\u0303\t # LATIN CAPITAL LETTER I (with tilde above)
lt_LT.UTF-8\tI\u0328\u0301\ti\u0307\u0328\u0301\tI\u0328\u0301\tI\u0328\u0301\t # LATIN CAPITAL LETTER I (with ogonek and acute accent)
lt_LT.UTF-8\tJ\u0301\tj\u0307\u0301\tJ\u0301\tJ\u0301\t # LATIN CAPITAL LETTER J (with acute accent)
lt_LT.UTF-8\t\u012e\u0301\t\u012f\u0307\u0301\t\u012e\u0301\t\u012e\u0301\t # LATIN CAPITAL LETTER I WITH OGONEK (with acute accent)
# Special case not at initial position
\ta\ufb04\ta\ufb04\tAffl\tAFFL\t# FB04
#
# Now the automatic tests
#""".format(
version
)
)
for i in range(0x10FFFF):
if i == 0x3A3:
# Greek sigma needs special tests
continue
up = upper.get(i, "")
lo = lower.get(i, "")
ti = title.get(i, "")
if any([up, lo, ti]):
print("\t%s\t%s\t%s\t%s\t# %4X" % (chr(i), lo, ti, up, i))
if __name__ == "__main__":
sys.exit(main(sys.argv))

View file

@ -0,0 +1,45 @@
/* GLIB - Library of useful routines for C programming
*
* Copyright (C) 2020 Red Hat, Inc.
*
* Author: Jakub Jelen <jjelen@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <dlfcn.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
static struct passwd my_pw;
/* This is used in gutils.c used to make sure utility functions
* handling user information do not crash on bad data (for example
* caused by getpwuid returning some NULL elements.
*/
struct passwd *
getpwuid (uid_t uid)
{
static struct passwd *(*real_getpwuid) (uid_t);
struct passwd *pw;
if (real_getpwuid == NULL)
real_getpwuid = dlsym (RTLD_NEXT, "getpwuid");
pw = real_getpwuid (uid);
my_pw = *pw;
my_pw.pw_name = NULL;
return &my_pw;
}

624
glib/tests/gpoll.c Normal file
View file

@ -0,0 +1,624 @@
/* Unit test for W32 version of g_poll()
*
* Copyright © 2017 Руслан Ижбулатов <lrn1986@gmail.com>
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This 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, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
#include <winsock2.h>
#define NUM_POLLEES 999
#define NUM_POLLFDS 1000
#define ASYNC_CONNECT_OK(r) (r == 0 || (r < 0 && GetLastError () == WSAEWOULDBLOCK))
#define REPEAT 1
static void
init_networking (void)
{
WSADATA wsadata;
if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
g_error ("Windows Sockets could not be initialized");
}
static void
prepare_fds (SOCKET sockets[],
GPollFD fds[],
int num_pollees)
{
gint i;
for (i = 0; i < num_pollees; i++)
{
fds[i].fd = (gintptr) WSACreateEvent ();
g_assert (WSAEventSelect (sockets[i], (HANDLE) fds[i].fd, FD_READ | FD_CLOSE) == 0);
}
}
static void
reset_fds (GPollFD fds[],
int num_pollees)
{
gint i;
for (i = 0; i < num_pollees; i++)
{
WSAResetEvent ((HANDLE) fds[i].fd);
fds[i].events = G_IO_IN | G_IO_OUT | G_IO_ERR;
fds[i].revents = 0;
}
}
static void
reset_fds_msg (GPollFD fds[],
int num_pollfds)
{
fds[num_pollfds - 1].fd = G_WIN32_MSG_HANDLE;
fds[num_pollfds - 1].events = G_IO_IN;
fds[num_pollfds - 1].revents = 0;
}
static void
check_fds (SOCKET sockets[],
GPollFD fds[],
int num_pollees)
{
gint i;
for (i = 0; i < num_pollees; i++)
{
if (fds[i].revents != 0)
{
WSANETWORKEVENTS events;
g_assert (WSAEnumNetworkEvents (sockets[i], 0, &events) == 0);
fds[i].revents = 0;
if (events.lNetworkEvents & (FD_READ | FD_ACCEPT))
fds[i].revents |= G_IO_IN;
if (events.lNetworkEvents & FD_WRITE)
fds[i].revents |= G_IO_OUT;
else
{
/* We have called WSAEnumNetworkEvents() above but it didn't
* set FD_WRITE.
*/
if (events.lNetworkEvents & FD_CONNECT)
{
if (events.iErrorCode[FD_CONNECT_BIT] == 0)
fds[i].revents |= G_IO_OUT;
else
fds[i].revents |= (G_IO_HUP | G_IO_ERR);
}
if (fds[i].revents == 0 && (events.lNetworkEvents & (FD_CLOSE)))
fds[i].revents |= G_IO_HUP;
}
}
}
}
static void
prepare_sockets (SOCKET sockets[],
SOCKET opp_sockets[],
GPollFD fds[],
int num_pollees)
{
gint i;
SOCKET server;
struct sockaddr_in sa;
unsigned long ul = 1;
int sa_size;
int r;
server = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
g_assert (server != INVALID_SOCKET);
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_port = 0;
sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
sa_size = sizeof (sa);
g_assert (bind (server, (const struct sockaddr *) &sa, sa_size) == 0);
g_assert (getsockname (server, (struct sockaddr *) &sa, &sa_size) == 0);
g_assert (listen (server, 1) == 0);
for (i = 0; i < num_pollees; i++)
{
opp_sockets[i] = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
g_assert (opp_sockets[i] != INVALID_SOCKET);
g_assert (ioctlsocket (opp_sockets[i], FIONBIO, &ul) == 0);
r = connect (opp_sockets[i], (const struct sockaddr *) &sa, sizeof (sa));
g_assert (ASYNC_CONNECT_OK (r));
sockets[i] = accept (server, NULL, NULL);
g_assert (sockets[i] != INVALID_SOCKET);
g_assert (ioctlsocket (sockets[i], FIONBIO, &ul) == 0);
}
closesocket (server);
}
static void
cleanup_sockets (SOCKET sockets[],
SOCKET opp_sockets[],
int num_pollees)
{
gint i;
for (i = 0; i < num_pollees; i++)
{
closesocket (sockets[i]);
closesocket (opp_sockets[i]);
}
}
static void
bucketize (gint64 val,
gint buckets[],
gint64 bucket_limits[],
gint count)
{
gint i;
if (val > bucket_limits[count - 1])
{
buckets[count - 1] += 1;
return;
}
for (i = count - 1; i > 0; i--)
if (val < bucket_limits[i] && val >= bucket_limits[i - 1])
{
buckets[i] += 1;
return;
}
buckets[0] += 1;
}
static void
print_buckets (gint buckets[],
gint64 bucket_limits[],
gint count)
{
gint i;
for (i = 0; i < count; i++)
if (i < count - 1)
g_print ("%-4lld-%4lld|", i == 0 ? 0 : bucket_limits[i - 1], bucket_limits[i] - 1);
else
g_print (" >= %-4lld|", bucket_limits[i - 1]);
g_print ("\n");
for (i = 0; i < count; i++)
{
gint len;
gint padding;
gint j;
if (buckets[i] < 10)
len = 1;
else if (buckets[i] < 100)
len = 2;
else if (buckets[i] < 1000)
len = 3;
else
len = 4;
padding = 9 - len;
for (j = 0; j < padding / 2; j++)
g_print (" ");
if (buckets[i] != 0)
g_print ("%*d", len, buckets[i]);
else
g_print (" ");
for (j = padding / 2; j < padding; j++)
g_print (" ");
g_print (" ");
}
g_print ("\n\n");
}
static void
test_gpoll (void)
{
SOCKET sockets[NUM_POLLEES];
GPollFD fds[NUM_POLLFDS];
SOCKET opp_sockets[NUM_POLLEES];
gint i;
gint activatable;
gint64 times[REPEAT][2];
#define BUCKET_COUNT 25
gint64 bucket_limits[BUCKET_COUNT] = {3, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 120, 150, 180, 220, 280, 350, 450, 600, 800, 1000};
gint buckets[BUCKET_COUNT];
gint64 times_avg = 0, times_min = G_MAXINT64, times_max = 0;
prepare_sockets (sockets, opp_sockets, fds, NUM_POLLEES);
prepare_fds (sockets, fds, NUM_POLLEES);
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
for (i = 0; i < REPEAT; i++)
{
gint r;
gint64 diff;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 0);
times[i][1] = g_get_monotonic_time ();
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
}
times_avg /= NUM_POLLEES;
g_print ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
activatable = 0;
for (i = 0; i < REPEAT; i++)
{
gint r, s, v, t;
gint64 diff;
MSG msg;
gboolean found_app;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
s = send (opp_sockets[activatable], (const char *) &t, 1, 0);
g_assert (PostMessage (NULL, WM_APP, 1, 2));
/* This is to ensure that all sockets catch up, otherwise some might not poll active */
g_usleep (G_USEC_PER_SEC / 1000);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 1000);
times[i][1] = g_get_monotonic_time ();
check_fds (sockets, fds, NUM_POLLEES);
v = recv (sockets[activatable], (char *) &t, 1, 0);
found_app = FALSE;
while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
found_app = TRUE;
g_assert (s == 1);
g_assert (r == 2);
g_assert (v == 1);
g_assert (found_app);
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
r = g_poll (fds, NUM_POLLFDS, 0);
check_fds (sockets, fds, NUM_POLLEES);
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
activatable = (activatable + 1) % NUM_POLLEES;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
}
times_avg /= NUM_POLLEES;
g_print ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
activatable = 0;
for (i = 0; i < REPEAT; i++)
{
gint r, s, v, t;
gint64 diff;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
s = send (opp_sockets[activatable], (const char *) &t, 1, 0);
g_usleep (G_USEC_PER_SEC / 1000);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 1000);
times[i][1] = g_get_monotonic_time ();
check_fds (sockets, fds, NUM_POLLEES);
v = recv (sockets[activatable], (char *) &t, 1, 0);
g_assert (s == 1);
g_assert (r == 1);
g_assert (v == 1);
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
r = g_poll (fds, NUM_POLLFDS, 0);
check_fds (sockets, fds, NUM_POLLEES);
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
activatable = (activatable + 1) % NUM_POLLEES;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
}
times_avg /= NUM_POLLEES;
g_print ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
for (i = 0; i < REPEAT; i++)
{
gint r, s, v, t;
gint64 diff;
gint j;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
s = v = 0;
for (j = 0; j < NUM_POLLEES / 2; j++)
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
g_usleep (G_USEC_PER_SEC / 1000);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 1000);
times[i][1] = g_get_monotonic_time ();
check_fds (sockets, fds, NUM_POLLEES);
for (j = 0; j < NUM_POLLEES / 2; j++)
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
g_assert (s == NUM_POLLEES / 2);
g_assert (r == NUM_POLLEES / 2);
g_assert (v == NUM_POLLEES / 2);
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
r = g_poll (fds, NUM_POLLFDS, 0);
check_fds (sockets, fds, NUM_POLLEES);
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
}
times_avg /= NUM_POLLEES;
g_print ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
for (i = 0; i < REPEAT; i++)
{
gint r, s, v, t;
gint64 diff;
gint j;
MSG msg;
gboolean found_app;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
s = v = 0;
for (j = 0; j < NUM_POLLEES / 2; j++)
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
g_assert (PostMessage (NULL, WM_APP, 1, 2));
/* This is to ensure that all sockets catch up, otherwise some might not poll active */
g_usleep (G_USEC_PER_SEC / 1000);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 1000);
times[i][1] = g_get_monotonic_time ();
check_fds (sockets, fds, NUM_POLLEES);
for (j = 0; j < NUM_POLLEES / 2; j++)
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
found_app = FALSE;
while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
found_app = TRUE;
g_assert (s == NUM_POLLEES / 2);
g_assert (r == NUM_POLLEES / 2 + 1);
g_assert (v == NUM_POLLEES / 2);
g_assert (found_app);
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
r = g_poll (fds, NUM_POLLFDS, 0);
check_fds (sockets, fds, NUM_POLLEES);
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
}
times_avg /= NUM_POLLEES;
g_print ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
for (i = 0; i < REPEAT; i++)
{
gint r, s, v, t;
gint64 diff;
gint j;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
s = v = 0;
for (j = 0; j < NUM_POLLEES; j++)
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
g_usleep (G_USEC_PER_SEC / 1000);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 1000);
times[i][1] = g_get_monotonic_time ();
check_fds (sockets, fds, NUM_POLLEES);
for (j = 0; j < NUM_POLLEES; j++)
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
g_assert (s == NUM_POLLEES);
g_assert (r == NUM_POLLEES);
g_assert (v == NUM_POLLEES);
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
r = g_poll (fds, NUM_POLLFDS, 0);
check_fds (sockets, fds, NUM_POLLEES);
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
}
times_avg /= NUM_POLLEES;
g_print ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
activatable = 0;
times_avg = 0;
times_min = G_MAXINT64;
times_max = 0;
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
for (i = 0; i < REPEAT; i++)
{
gint r, s, v, t;
gint64 diff;
gint j;
MSG msg;
gboolean found_app;
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
s = v = 0;
for (j = 0; j < activatable; j++)
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
g_assert (PostMessage (NULL, WM_APP, 1, 2));
g_usleep (G_USEC_PER_SEC / 1000);
times[i][0] = g_get_monotonic_time ();
r = g_poll (fds, NUM_POLLFDS, 1000);
times[i][1] = g_get_monotonic_time ();
check_fds (sockets, fds, NUM_POLLEES);
for (j = 0; j < activatable; j++)
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
found_app = FALSE;
while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
found_app = TRUE;
g_assert (s == activatable);
g_assert (r == activatable + 1);
g_assert (v == activatable);
g_assert (found_app);
reset_fds (fds, NUM_POLLEES);
reset_fds_msg (fds, NUM_POLLFDS);
r = g_poll (fds, NUM_POLLFDS, 0);
check_fds (sockets, fds, NUM_POLLEES);
g_assert (r == 0);
diff = times[i][1] - times[i][0];
if (times_min > diff)
times_min = diff;
if (times_max < diff)
times_max = diff;
times_avg += diff;
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
activatable = (activatable + 1) % NUM_POLLEES;
}
times_avg /= NUM_POLLEES;
g_print ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
cleanup_sockets (sockets, opp_sockets, NUM_POLLEES);
}
int
main (int argc,
char *argv[])
{
int result;
GMainContext *ctx;
g_test_init (&argc, &argv, NULL);
init_networking ();
ctx = g_main_context_new ();
g_test_add_func ("/gpoll/gpoll", test_gpoll);
result = g_test_run ();
g_main_context_unref (ctx);
return result;
}

View file

@ -0,0 +1,42 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* Author: Jakub Jelen <jjelen@redhat.com>
*
* 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#include <glib.h>
/* The function g_get_user_database_entry() is called from the
* g_get_real_name(), g_get_user_name() and g_build_home_dir()
* functions. These two calls are here just to invoke the code
* paths. The real-test is the ld_preload used to inject the
* NULL in place of pw->pw_name.
*/
static void
test_get_user_database_entry (void)
{
const gchar *r = NULL;
r = g_get_user_name ();
g_assert_nonnull (r);
r = g_get_real_name ();
g_assert_nonnull (r);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/gutils/get_user_database_entry", test_get_user_database_entry);
return g_test_run ();
}

70
glib/tests/guuid.c Normal file
View file

@ -0,0 +1,70 @@
/* guuid.c
*
* Copyright (C) 2013-2015, 2017 Red Hat, Inc.
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#undef G_DISABLE_ASSERT
#include <glib.h>
#include <string.h>
static void
test_guuid_string (void)
{
g_assert_false (g_uuid_string_is_valid ("00010203-0405-0607-0809"));
g_assert_false (g_uuid_string_is_valid ("zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"));
g_assert_false (g_uuid_string_is_valid ("000102030405060708090a0b0c0d0e0f"));
g_assert_false (g_uuid_string_is_valid ("{urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6}"));
g_assert_false (g_uuid_string_is_valid ("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"));
g_assert_true (g_uuid_string_is_valid ("00010203-0405-0607-0809-0a0b0c0d0e0f"));
g_assert_true (g_uuid_string_is_valid ("7d444840-9dc0-11d1-b245-5ffdce74fad2"));
g_assert_true (g_uuid_string_is_valid ("e902893a-9d22-3c7e-a7b8-d6e313b71d9f"));
g_assert_true (g_uuid_string_is_valid ("6ba7b810-9dad-11d1-80b4-00c04fd430c8"));
}
static void
test_guuid_random (void)
{
gchar *str1, *str2;
str1 = g_uuid_string_random ();
g_assert_cmpuint (strlen (str1), ==, 36);
g_assert_true (g_uuid_string_is_valid (str1));
str2 = g_uuid_string_random ();
g_assert_cmpuint (strlen (str2), ==, 36);
g_assert_true (g_uuid_string_is_valid (str2));
g_assert_cmpstr (str1, !=, str2);
g_free (str1);
g_free (str2);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
/* GUuid Tests */
g_test_add_func ("/uuid/string", test_guuid_string);
g_test_add_func ("/uuid/random", test_guuid_random);
return g_test_run ();
}

5206
glib/tests/gvariant.c Normal file

File diff suppressed because it is too large Load diff

276
glib/tests/gwakeuptest.c Normal file
View file

@ -0,0 +1,276 @@
#include <glib.h>
#include <glib/gwakeup.h>
#ifdef G_OS_UNIX
#include <unistd.h>
#endif
#ifdef _WIN32
static void alarm (int sec) { }
#endif
static gboolean
check_signaled (GWakeup *wakeup)
{
GPollFD fd;
g_wakeup_get_pollfd (wakeup, &fd);
return g_poll (&fd, 1, 0);
}
static void
wait_for_signaled (GWakeup *wakeup)
{
GPollFD fd;
g_wakeup_get_pollfd (wakeup, &fd);
g_poll (&fd, 1, -1);
}
static void
test_semantics (void)
{
GWakeup *wakeup;
gint i;
/* prevent the test from deadlocking */
alarm (60);
wakeup = g_wakeup_new ();
g_assert (!check_signaled (wakeup));
g_wakeup_signal (wakeup);
g_assert (check_signaled (wakeup));
g_wakeup_acknowledge (wakeup);
g_assert (!check_signaled (wakeup));
g_wakeup_free (wakeup);
/* free unused */
wakeup = g_wakeup_new ();
g_wakeup_free (wakeup);
/* free while signaled */
wakeup = g_wakeup_new ();
g_wakeup_signal (wakeup);
g_wakeup_free (wakeup);
/* ensure excessive signalling doesn't deadlock */
wakeup = g_wakeup_new ();
for (i = 0; i < 1000000; i++)
g_wakeup_signal (wakeup);
g_assert (check_signaled (wakeup));
/* ensure a single acknowledgement is sufficient */
g_wakeup_acknowledge (wakeup);
g_assert (!check_signaled (wakeup));
g_wakeup_free (wakeup);
/* cancel the alarm */
alarm (0);
}
struct token
{
gpointer owner;
gint ttl;
};
struct context
{
GSList *pending_tokens;
GMutex lock;
GWakeup *wakeup;
gboolean quit;
};
#define NUM_THREADS 50
#define NUM_TOKENS 5
#define TOKEN_TTL 100000
static struct context contexts[NUM_THREADS];
static GThread *threads[NUM_THREADS];
static GWakeup *last_token_wakeup;
static gint tokens_alive; /* (atomic) */
static void
context_init (struct context *ctx)
{
ctx->pending_tokens = NULL;
g_mutex_init (&ctx->lock);
ctx->wakeup = g_wakeup_new ();
ctx->quit = FALSE;
}
static void
context_clear (struct context *ctx)
{
g_assert (ctx->pending_tokens == NULL);
g_assert (ctx->quit);
g_mutex_clear (&ctx->lock);
g_wakeup_free (ctx->wakeup);
}
static void
context_quit (struct context *ctx)
{
g_atomic_int_set (&ctx->quit, TRUE);
g_wakeup_signal (ctx->wakeup);
}
static struct token *
context_try_pop_token (struct context *ctx)
{
struct token *token = NULL;
g_mutex_lock (&ctx->lock);
if (ctx->pending_tokens != NULL)
{
token = ctx->pending_tokens->data;
ctx->pending_tokens = g_slist_delete_link (ctx->pending_tokens,
ctx->pending_tokens);
}
g_mutex_unlock (&ctx->lock);
return token;
}
static void
context_push_token (struct context *ctx,
struct token *token)
{
g_assert (token->owner == ctx);
g_mutex_lock (&ctx->lock);
ctx->pending_tokens = g_slist_prepend (ctx->pending_tokens, token);
g_mutex_unlock (&ctx->lock);
g_wakeup_signal (ctx->wakeup);
}
static void
dispatch_token (struct token *token)
{
if (token->ttl > 0)
{
struct context *ctx;
gint next_ctx;
next_ctx = g_test_rand_int_range (0, NUM_THREADS);
ctx = &contexts[next_ctx];
token->owner = ctx;
token->ttl--;
context_push_token (ctx, token);
}
else
{
g_slice_free (struct token, token);
if (g_atomic_int_dec_and_test (&tokens_alive))
g_wakeup_signal (last_token_wakeup);
}
}
static struct token *
token_new (int ttl)
{
struct token *token;
token = g_slice_new (struct token);
token->ttl = ttl;
g_atomic_int_inc (&tokens_alive);
return token;
}
static gpointer
thread_func (gpointer data)
{
struct context *ctx = data;
struct token *token;
while (!g_atomic_int_get (&ctx->quit))
{
wait_for_signaled (ctx->wakeup);
g_wakeup_acknowledge (ctx->wakeup);
while ((token = context_try_pop_token (ctx)) != NULL)
{
g_assert (token->owner == ctx);
dispatch_token (token);
}
}
return NULL;
}
static void
test_threaded (void)
{
gint i;
/* make sure we don't block forever */
alarm (60);
/* simple mainloop test based on GWakeup.
*
* create a bunch of contexts and a thread to 'run' each one. create
* some tokens and randomly pass them between the threads, until the
* TTL on each token is zero.
*
* when no tokens are left, signal that we are done. the mainthread
* will then signal each worker thread to exit and join them to make
* sure that works.
*/
last_token_wakeup = g_wakeup_new ();
/* create contexts, assign to threads */
for (i = 0; i < NUM_THREADS; i++)
{
context_init (&contexts[i]);
threads[i] = g_thread_new ("test", thread_func, &contexts[i]);
}
/* dispatch tokens */
for (i = 0; i < NUM_TOKENS; i++)
dispatch_token (token_new (TOKEN_TTL));
/* wait until all tokens are gone */
wait_for_signaled (last_token_wakeup);
/* ask threads to quit, join them, cleanup */
for (i = 0; i < NUM_THREADS; i++)
{
context_quit (&contexts[i]);
g_thread_join (threads[i]);
context_clear (&contexts[i]);
}
g_wakeup_free (last_token_wakeup);
/* cancel alarm */
alarm (0);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
#ifdef TEST_EVENTFD_FALLBACK
#define TESTNAME_SUFFIX "-fallback"
#else
#define TESTNAME_SUFFIX
#endif
g_test_add_func ("/gwakeup/semantics" TESTNAME_SUFFIX, test_semantics);
g_test_add_func ("/gwakeup/threaded" TESTNAME_SUFFIX, test_threaded);
return g_test_run ();
}

1742
glib/tests/hash.c Normal file

File diff suppressed because it is too large Load diff

550
glib/tests/hmac.c Normal file
View file

@ -0,0 +1,550 @@
#include <glib.h>
#include <string.h>
#include <stdlib.h>
/* HMAC-MD5 test vectors as per RFC 2202 */
/* Test 1 */
guint8 key_md5_test1[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
guint8 result_md5_test1[] = {
0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4,
0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d };
/* Test 2 */
guint8 result_md5_test2[] = {
0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8,
0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 };
/* Test 3 */
guint8 key_md5_test3[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
guint8 data_md5_test3[] = {
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd };
guint8 result_md5_test3[] = {
0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, 0xdb, 0xb8,
0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 };
/* Test 4 */
guint8 key_md5_test4[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19 };
guint8 data_md5_test4[] = {
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd };
guint8 result_md5_test4[] = {
0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, 0x3a, 0x75,
0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 };
/* Test 5 */
guint8 key_md5_test5[] = {
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c};
guint8 result_md5_test5[] = {
0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, 0xf9, 0xba,
0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c };
/* Test 6 */
guint8 key_md5_test6[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
guint8 result_md5_test6[] = {
0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, 0x0b, 0x62,
0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd };
/* Test 6 */
guint8 key_md5_test7[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
guint8 result_md5_test7[] = {
0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1,
0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e };
/* HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 test vectors
* as per RFCs 2202 and 4868.
*
* See: https://tools.ietf.org/html/rfc4868#section-2.7.1 */
/* Test 1 */
guint8 key_sha_test1[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
guint8 result_sha1_test1[] = {
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b,
0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, 0x46, 0xbe, 0x00 };
guint8 result_sha256_test1[] = {
0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8,
0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00,
0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32,
0xcf, 0xf7 };
guint8 result_sha384_test1[] = {
0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, 0x6b, 0x08,
0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, 0x15, 0xf9, 0xda, 0xdb,
0xe4, 0x10, 0x1e, 0xc6, 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb,
0xc5, 0x9c, 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 };
guint8 result_sha512_test1[] = {
0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, 0x4f, 0xf0,
0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, 0x23, 0x79, 0xf4, 0xe2,
0xce, 0x4e, 0xc2, 0x78, 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1,
0x7c, 0xde, 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, 0xbe, 0x9d,
0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, 0x2e, 0x69, 0x6c, 0x20,
0x3a, 0x12, 0x68, 0x54 };
/* Test 2 */
guint8 result_sha1_test2[] = {
0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74,
0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 };
guint8 result_sha256_test2[] = {
0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04,
0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08,
0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec,
0x38, 0x43 };
guint8 result_sha384_test2[] = {
0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, 0x61, 0x7f,
0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, 0x9c, 0x7e, 0xf4, 0x64,
0xf5, 0xa0, 0x1b, 0x47, 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22,
0x44, 0x5e, 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 };
guint8 result_sha512_test2[] = {
0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95,
0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, 0x87, 0xbd, 0x64, 0x22,
0x2e, 0x83, 0x1f, 0xd6, 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25,
0x05, 0x54, 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, 0xca, 0xea,
0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, 0x63, 0x6e, 0x07, 0x0a,
0x38, 0xbc, 0xe7, 0x37 };
/* Test 3 */
guint8 key_sha_test3[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
guint8 data_sha_test3[] = {
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd };
guint8 result_sha1_test3[] = {
0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3,
0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 };
guint8 result_sha256_test3[] = {
0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d,
0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b,
0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5,
0x65, 0xfe };
guint8 result_sha384_test3[] = {
0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, 0x0a, 0xa2,
0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f, 0x0a, 0xa6, 0x35, 0xd9,
0x47, 0xac, 0x9f, 0xeb, 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66,
0x14, 0x4b, 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 };
guint8 result_sha512_test3[] = {
0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, 0xef, 0xb0,
0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9, 0xb1, 0xb5, 0xdb, 0xdd,
0x8e, 0xe8, 0x1a, 0x36, 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27,
0x9d, 0x39, 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07, 0xb9, 0x46,
0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59,
0xe1, 0x32, 0x92, 0xfb };
/* Test 4 */
guint8 key_sha_test4[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19 };
guint8 data_sha_test4[] = {
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd };
guint8 result_sha1_test4[] = {
0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84,
0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda };
guint8 result_sha256_test4[] = {
0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc,
0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3,
0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29,
0x66, 0x5b };
guint8 result_sha384_test4[] = {
0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85, 0x19, 0x33,
0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7, 0x7a, 0x99, 0x81, 0x48,
0x08, 0x50, 0x00, 0x9c, 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57,
0x3b, 0x4e, 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb };
guint8 result_sha512_test4[] = {
0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69, 0x90, 0xe5,
0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7, 0xe5, 0x76, 0xd9, 0x7f,
0xf9, 0x4b, 0x87, 0x2d, 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e,
0xe3, 0xdb, 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63, 0xa5, 0xf1,
0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d, 0xe2, 0xad, 0xeb, 0xeb,
0x10, 0xa2, 0x98, 0xdd };
/* Test 5 (note: different for SHA-256/SHA-512) */
guint8 key_sha1_test5[] = {
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c };
guint8 result_sha1_test5[] = {
0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 };
/* Test 6 & 7 (note: different for SHA-1 and SHA-256/SHA-512) */
guint8 key_sha1_test6_7[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
guint8 result_sha1_test6[] = {
0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70,
0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 };
guint8 result_sha1_test7[] = {
0xe8, 0xe9, 0x9d, 0xf, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b,
0xba, 0xa7, 0x96, 0x5c, 0x78, 0x8, 0xbb, 0xff, 0x1a, 0x91 };
/* Test 5 & 6 for SHA-256 and SHA-512. */
guint8 key_sha256_test5_6[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa };
guint8 result_sha256_test5[] = {
0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a,
0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21,
0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3,
0x7f, 0x54 };
guint8 result_sha384_test5[] = {
0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, 0x88, 0xd2,
0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4, 0x4f, 0x9e, 0xf1, 0x01,
0x2a, 0x2b, 0x58, 0x8f, 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a,
0xc4, 0xc6, 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 };
guint8 result_sha512_test5[] = {
0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, 0xb7, 0x14,
0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4, 0x9b, 0x46, 0xd1, 0xf4,
0x1b, 0x4a, 0xee, 0xc1, 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8,
0xf3, 0x52, 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, 0x95, 0xe6,
0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98,
0x5d, 0x78, 0x65, 0x98 };
guint8 result_sha256_test6[] = {
0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63,
0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64,
0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a,
0x35, 0xe2 };
guint8 result_sha384_test6[] = {
0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, 0x35, 0x1e,
0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c, 0x60, 0x24, 0x20, 0xfe,
0xb0, 0xb8, 0xfb, 0x9a, 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e,
0x99, 0xc5, 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e };
guint8 result_sha512_test6[] = {
0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, 0xa4, 0xdf,
0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd, 0xde, 0xbd, 0x71, 0xf8,
0x86, 0x72, 0x89, 0x86, 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd,
0xc9, 0x44, 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, 0x13, 0x46,
0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60, 0x65, 0xc9, 0x74, 0x40,
0xfa, 0x8c, 0x6a, 0x58 };
typedef struct {
GChecksumType digest_type;
gconstpointer key;
gsize key_len;
gconstpointer data;
gsize data_len;
gconstpointer result;
} HmacCase;
HmacCase hmac_md5_tests[] = {
{ G_CHECKSUM_MD5, key_md5_test1, 16, "Hi There", 8, result_md5_test1 },
{ G_CHECKSUM_MD5, "Jefe", 4, "what do ya want for nothing?", 28,
result_md5_test2 },
{ G_CHECKSUM_MD5, key_md5_test3, 16, data_md5_test3, 50,
result_md5_test3 },
{ G_CHECKSUM_MD5, key_md5_test4, 25, data_md5_test4, 50,
result_md5_test4 },
{ G_CHECKSUM_MD5, key_md5_test5, 16, "Test With Truncation", 20,
result_md5_test5 },
{ G_CHECKSUM_MD5, key_md5_test6, 80,
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
result_md5_test6 },
{ G_CHECKSUM_MD5, key_md5_test7, 80,
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
73, result_md5_test7 },
{ -1, NULL, 0, NULL, 0, NULL },
};
HmacCase hmac_sha1_tests[] = {
{ G_CHECKSUM_SHA1, key_sha_test1, 20, "Hi There", 8, result_sha1_test1 },
{ G_CHECKSUM_SHA1, "Jefe", 4, "what do ya want for nothing?", 28,
result_sha1_test2 },
{ G_CHECKSUM_SHA1, key_sha_test3, 20, data_sha_test3, 50,
result_sha1_test3 },
{ G_CHECKSUM_SHA1, key_sha_test4, 25, data_sha_test4, 50,
result_sha1_test4 },
{ G_CHECKSUM_SHA1, key_sha1_test5, 20, "Test With Truncation", 20,
result_sha1_test5 },
{ G_CHECKSUM_SHA1, key_sha1_test6_7, 80,
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
result_sha1_test6 },
{ G_CHECKSUM_SHA1, key_sha1_test6_7, 80,
"Test Using Larger Than Block-Size Key and Larger" \
" Than One Block-Size Data", 73, result_sha1_test7, },
{ -1, NULL, 0, NULL, 0, NULL },
};
HmacCase hmac_sha256_tests[] = {
{ G_CHECKSUM_SHA256, key_sha_test1, 20, "Hi There", 8, result_sha256_test1 },
{ G_CHECKSUM_SHA256, "Jefe", 4, "what do ya want for nothing?", 28,
result_sha256_test2 },
{ G_CHECKSUM_SHA256, key_sha_test3, 20, data_sha_test3, 50,
result_sha256_test3 },
{ G_CHECKSUM_SHA256, key_sha_test4, 25, data_sha_test4, 50,
result_sha256_test4 },
{ G_CHECKSUM_SHA256, key_sha256_test5_6, 131,
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
result_sha256_test5 },
{ G_CHECKSUM_SHA256, key_sha256_test5_6, 131,
"This is a test using a larger than block-size key and a larger than "
"block-size data. The key needs to be hashed before being used by the "
"HMAC algorithm.", 152, result_sha256_test6, },
{ -1, NULL, 0, NULL, 0, NULL },
};
HmacCase hmac_sha384_tests[] = {
{ G_CHECKSUM_SHA384, key_sha_test1, 20, "Hi There", 8, result_sha384_test1 },
{ G_CHECKSUM_SHA384, "Jefe", 4, "what do ya want for nothing?", 28,
result_sha384_test2 },
{ G_CHECKSUM_SHA384, key_sha_test3, 20, data_sha_test3, 50,
result_sha384_test3 },
{ G_CHECKSUM_SHA384, key_sha_test4, 25, data_sha_test4, 50,
result_sha384_test4 },
{ G_CHECKSUM_SHA384, key_sha256_test5_6, 131,
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
result_sha384_test5 },
{ G_CHECKSUM_SHA384, key_sha256_test5_6, 131,
"This is a test using a larger than block-size key and a larger than "
"block-size data. The key needs to be hashed before being used by the "
"HMAC algorithm.", 152, result_sha384_test6, },
{ -1, NULL, 0, NULL, 0, NULL },
};
HmacCase hmac_sha512_tests[] = {
{ G_CHECKSUM_SHA512, key_sha_test1, 20, "Hi There", 8, result_sha512_test1 },
{ G_CHECKSUM_SHA512, "Jefe", 4, "what do ya want for nothing?", 28,
result_sha512_test2 },
{ G_CHECKSUM_SHA512, key_sha_test3, 20, data_sha_test3, 50,
result_sha512_test3 },
{ G_CHECKSUM_SHA512, key_sha_test4, 25, data_sha_test4, 50,
result_sha512_test4 },
{ G_CHECKSUM_SHA512, key_sha256_test5_6, 131,
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
result_sha512_test5 },
{ G_CHECKSUM_SHA512, key_sha256_test5_6, 131,
"This is a test using a larger than block-size key and a larger than "
"block-size data. The key needs to be hashed before being used by the "
"HMAC algorithm.", 152, result_sha512_test6, },
{ -1, NULL, 0, NULL, 0, NULL },
};
static void
test_hmac (HmacCase *t)
{
GHmac *hmac;
gsize digest_len, hmac_len;
gpointer digest;
hmac_len = digest_len = g_checksum_type_get_length (t->digest_type);
digest = g_malloc (hmac_len);
hmac = g_hmac_new (t->digest_type, t->key, t->key_len);
g_hmac_update (hmac, t->data, t->data_len);
g_hmac_get_digest (hmac, digest, &digest_len);
g_assert_cmpmem (digest, hmac_len, t->result, digest_len);
g_free (digest);
g_hmac_unref (hmac);
}
static void
test_hmac_ref_unref (void)
{
GHmac *hmac, *check;
hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3);
check = g_hmac_ref (hmac);
g_assert (check == hmac);
g_hmac_unref (check);
g_hmac_unref (hmac);
}
static void
test_hmac_copy (void)
{
GHmac *hmac, *check;
hmac = g_hmac_new (G_CHECKSUM_SHA256, (guchar*)"aaa", 3);
check = g_hmac_copy (hmac);
g_assert (check != hmac);
g_assert_cmpstr (g_hmac_get_string (hmac), ==, g_hmac_get_string (check));
g_hmac_unref (check);
g_hmac_unref (hmac);
}
static void
test_hmac_for_data (void)
{
gchar *string;
GHmac *hmac;
string = g_compute_hmac_for_data (G_CHECKSUM_SHA1,
(guchar*)"aaa", 3,
(guchar*)"bcdef", 5);
hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3);
g_hmac_update (hmac, (guchar*)"bcdef", 5);
g_assert_cmpstr (string, ==, g_hmac_get_string (hmac));
g_hmac_unref (hmac);
g_free (string);
}
static void
test_hmac_for_string (void)
{
gchar *string;
GHmac *hmac;
string = g_compute_hmac_for_string (G_CHECKSUM_SHA1,
(guchar*)"aaa", 3,
"bcdef", -1);
hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3);
g_hmac_update (hmac, (guchar*)"bcdef", 5);
g_assert_cmpstr (string, ==, g_hmac_get_string (hmac));
g_hmac_unref (hmac);
g_free (string);
}
static void
test_hmac_for_bytes (void)
{
gchar *string;
GHmac *hmac;
GBytes *key, *data;
key = g_bytes_new ("aaa", 3);
data = g_bytes_new ("bcdef", 5);
string = g_compute_hmac_for_bytes (G_CHECKSUM_SHA1, key, data);
hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3);
g_hmac_update (hmac, (guchar*)"bcdef", 5);
g_assert_cmpstr (string, ==, g_hmac_get_string (hmac));
g_hmac_unref (hmac);
g_free (string);
g_bytes_unref (key);
g_bytes_unref (data);
}
int
main (int argc,
char **argv)
{
int i;
g_test_init (&argc, &argv, NULL);
for (i = 0 ; hmac_sha1_tests[i].key_len > 0 ; i++)
{
gchar *name = g_strdup_printf ("/hmac/sha1-%d", i + 1);
g_test_add_data_func (name, hmac_sha1_tests + i,
(void (*)(const void *)) test_hmac);
g_free (name);
}
for (i = 0 ; hmac_sha256_tests[i].key_len > 0 ; i++)
{
gchar *name = g_strdup_printf ("/hmac/sha256-%d", i + 1);
g_test_add_data_func (name, hmac_sha256_tests + i,
(void (*)(const void *)) test_hmac);
g_free (name);
}
for (i = 0 ; hmac_sha384_tests[i].key_len > 0 ; i++)
{
gchar *name = g_strdup_printf ("/hmac/sha384-%d", i + 1);
g_test_add_data_func (name, hmac_sha384_tests + i,
(void (*)(const void *)) test_hmac);
g_free (name);
}
for (i = 0 ; hmac_sha512_tests[i].key_len > 0 ; i++)
{
gchar *name = g_strdup_printf ("/hmac/sha512-%d", i + 1);
g_test_add_data_func (name, hmac_sha512_tests + i,
(void (*)(const void *)) test_hmac);
g_free (name);
}
for (i = 0 ; hmac_md5_tests[i].key_len > 0 ; i++)
{
gchar *name = g_strdup_printf ("/hmac/md5-%d", i + 1);
g_test_add_data_func (name, hmac_md5_tests + i,
(void (*)(const void *)) test_hmac);
g_free (name);
}
g_test_add_func ("/hmac/ref-unref", test_hmac_ref_unref);
g_test_add_func ("/hmac/copy", test_hmac_copy);
g_test_add_func ("/hmac/for-data", test_hmac_for_data);
g_test_add_func ("/hmac/for-string", test_hmac_for_string);
g_test_add_func ("/hmac/for-bytes", test_hmac_for_bytes);
return g_test_run ();
}

94
glib/tests/hook.c Normal file
View file

@ -0,0 +1,94 @@
/* Unit tests for hook lists
* Copyright (C) 2011 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.
*
* Author: Matthias Clasen
*/
#include "glib.h"
static void
hook_func (gpointer data)
{
}
static void
destroy (gpointer data)
{
}
static void
test_hook1 (void)
{
GHookList *hl;
GHook *hook;
gulong id;
GHook *h;
hl = g_new (GHookList, 1);
g_hook_list_init (hl, sizeof (GHook));
hook = g_hook_alloc (hl);
hook->data = GINT_TO_POINTER(1);
hook->func = hook_func;
hook->flags = G_HOOK_FLAG_ACTIVE;
hook->destroy = destroy;
g_hook_append (hl, hook);
id = hook->hook_id;
h = g_hook_get (hl, id);
g_assert (h == hook);
h = hook = g_hook_alloc (hl);
hook->data = GINT_TO_POINTER(2);
hook->func = hook_func;
hook->flags = G_HOOK_FLAG_ACTIVE;
hook->destroy = destroy;
g_hook_prepend (hl, hook);
g_hook_destroy (hl, id);
hook = g_hook_alloc (hl);
hook->data = GINT_TO_POINTER(3);
hook->func = hook_func;
hook->flags = G_HOOK_FLAG_ACTIVE;
hook->destroy = destroy;
g_hook_insert_sorted (hl, hook, g_hook_compare_ids);
hook = g_hook_alloc (hl);
hook->data = GINT_TO_POINTER(4);
hook->func = hook_func;
hook->flags = G_HOOK_FLAG_ACTIVE;
hook->destroy = destroy;
g_hook_insert_before (hl, h, hook);
g_hook_list_invoke (hl, TRUE);
g_hook_list_clear (hl);
g_free (hl);
}
int main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/hook/test1", test_hook1);
return g_test_run ();
}

367
glib/tests/hostutils.c Normal file
View file

@ -0,0 +1,367 @@
/*
* 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <glib/glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const struct {
const gchar *ascii_name, *unicode_name;
} idn_test_domains[] = {
/* "example.test" in various languages */
{ "xn--mgbh0fb.xn--kgbechtv", "\xd9\x85\xd8\xab\xd8\xa7\xd9\x84.\xd8\xa5\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1" },
{ "xn--fsqu00a.xn--0zwm56d", "\xe4\xbe\x8b\xe5\xad\x90.\xe6\xb5\x8b\xe8\xaf\x95" },
{ "xn--fsqu00a.xn--g6w251d", "\xe4\xbe\x8b\xe5\xad\x90.\xe6\xb8\xac\xe8\xa9\xa6" },
{ "xn--hxajbheg2az3al.xn--jxalpdlp", "\xcf\x80\xce\xb1\xcf\x81\xce\xac\xce\xb4\xce\xb5\xce\xb9\xce\xb3\xce\xbc\xce\xb1.\xce\xb4\xce\xbf\xce\xba\xce\xb9\xce\xbc\xce\xae" },
{ "xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g", "\xe0\xa4\x89\xe0\xa4\xa6\xe0\xa4\xbe\xe0\xa4\xb9\xe0\xa4\xb0\xe0\xa4\xa3.\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe" },
{ "xn--r8jz45g.xn--zckzah", "\xe4\xbe\x8b\xe3\x81\x88.\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" },
{ "xn--9n2bp8q.xn--9t4b11yi5a", "\xec\x8b\xa4\xeb\xa1\x80.\xed\x85\x8c\xec\x8a\xa4\xed\x8a\xb8" },
{ "xn--mgbh0fb.xn--hgbk6aj7f53bba", "\xd9\x85\xd8\xab\xd8\xa7\xd9\x84.\xd8\xa2\xd8\xb2\xd9\x85\xd8\xa7\xdb\x8c\xd8\xb4\xdb\x8c" },
{ "xn--e1afmkfd.xn--80akhbyknj4f", "\xd0\xbf\xd1\x80\xd0\xb8\xd0\xbc\xd0\xb5\xd1\x80.\xd0\xb8\xd1\x81\xd0\xbf\xd1\x8b\xd1\x82\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5" },
{ "xn--zkc6cc5bi7f6e.xn--hlcj6aya9esc7a", "\xe0\xae\x89\xe0\xae\xa4\xe0\xae\xbe\xe0\xae\xb0\xe0\xae\xa3\xe0\xae\xae\xe0\xaf\x8d.\xe0\xae\xaa\xe0\xae\xb0\xe0\xae\xbf\xe0\xae\x9f\xe0\xaf\x8d\xe0\xae\x9a\xe0\xaf\x88" },
{ "xn--fdbk5d8ap9b8a8d.xn--deba0ad", "\xd7\x91\xd7\xb2\xd6\xb7\xd7\xa9\xd7\xa4\xd6\xbc\xd7\x99\xd7\x9c.\xd7\x98\xd7\xa2\xd7\xa1\xd7\x98" },
/* further examples without their own IDN-ized TLD */
{ "xn--1xd0bwwra.idn.icann.org", "\xe1\x8a\xa0\xe1\x88\x9b\xe1\x88\xad\xe1\x8a\x9b.idn.icann.org" },
{ "xn--54b7fta0cc.idn.icann.org", "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe.idn.icann.org" },
{ "xn--5dbqzzl.idn.icann.org", "\xd7\xa2\xd7\x91\xd7\xa8\xd7\x99\xd7\xaa.idn.icann.org" },
{ "xn--j2e7beiw1lb2hqg.idn.icann.org", "\xe1\x9e\x97\xe1\x9e\xb6\xe1\x9e\x9f\xe1\x9e\xb6\xe1\x9e\x81\xe1\x9f\x92\xe1\x9e\x98\xe1\x9f\x82\xe1\x9e\x9a.idn.icann.org" },
{ "xn--o3cw4h.idn.icann.org", "\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2.idn.icann.org" },
{ "xn--mgbqf7g.idn.icann.org", "\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x88.idn.icann.org" }
};
static const gint num_idn_test_domains = G_N_ELEMENTS (idn_test_domains);
static const struct {
const gchar *orig_name, *ascii_name;
gboolean orig_is_unicode, ascii_is_encoded;
} non_round_trip_names[] = {
/* uppercase characters */
{ "EXAMPLE.COM", "example.com", FALSE, FALSE },
{ "\xc3\x89XAMPLE.COM", "xn--xample-9ua.com", TRUE, TRUE },
/* unicode that decodes to ascii */
{ "\xe2\x93\x94\xe2\x93\xa7\xe2\x93\x90\xe2\x93\x9c\xe2\x93\x9f\xe2\x93\x9b\xe2\x93\x94.com", "example.com", TRUE, FALSE },
/* non-standard dot characters */
{ "example\xe3\x80\x82" "com", "example.com", TRUE, FALSE },
{ "\xc3\xa9xample\xe3\x80\x82" "com", "xn--xample-9ua.com", TRUE, TRUE },
{ "Å.idn.icann.org", "xn--5ca.idn.icann.org", TRUE, TRUE },
{ "ℵℶℷ\xcd\x8f.idn.icann.org", "xn--4dbcd.idn.icann.org", TRUE, TRUE }
};
static const gint num_non_round_trip_names = G_N_ELEMENTS (non_round_trip_names);
static const gchar *bad_names[] = {
"disallowed\xef\xbf\xbd" "character",
"non-utf\x88",
"xn--mixed-\xc3\xbcp",
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong"
"verylongverylongverylongverylongverylongverylongverylongverylongverylong",
};
static const gint num_bad_names = G_N_ELEMENTS (bad_names);
static void
test_to_ascii (void)
{
gint i;
gchar *ascii;
for (i = 0; i < num_idn_test_domains; i++)
{
g_assert_true (g_hostname_is_non_ascii (idn_test_domains[i].unicode_name));
ascii = g_hostname_to_ascii (idn_test_domains[i].unicode_name);
g_assert_cmpstr (idn_test_domains[i].ascii_name, ==, ascii);
g_free (ascii);
ascii = g_hostname_to_ascii (idn_test_domains[i].ascii_name);
g_assert_cmpstr (idn_test_domains[i].ascii_name, ==, ascii);
g_free (ascii);
}
for (i = 0; i < num_non_round_trip_names; i++)
{
if (non_round_trip_names[i].orig_is_unicode)
g_assert_true (g_hostname_is_non_ascii (non_round_trip_names[i].orig_name));
else
g_assert_true (!g_hostname_is_non_ascii (non_round_trip_names[i].orig_name));
if (non_round_trip_names[i].ascii_is_encoded)
g_assert_true (g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name));
else
g_assert_true (!g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name));
ascii = g_hostname_to_ascii (non_round_trip_names[i].orig_name);
g_assert_cmpstr (non_round_trip_names[i].ascii_name, ==, ascii);
g_free (ascii);
ascii = g_hostname_to_ascii (non_round_trip_names[i].ascii_name);
g_assert_cmpstr (non_round_trip_names[i].ascii_name, ==, ascii);
g_free (ascii);
}
for (i = 0; i < num_bad_names; i++)
{
ascii = g_hostname_to_ascii (bad_names[i]);
g_assert_cmpstr (ascii, ==, NULL);
}
}
static void
test_to_unicode (void)
{
gint i;
gchar *unicode;
for (i = 0; i < num_idn_test_domains; i++)
{
g_assert_true (g_hostname_is_ascii_encoded (idn_test_domains[i].ascii_name));
unicode = g_hostname_to_unicode (idn_test_domains[i].ascii_name);
g_assert_cmpstr (idn_test_domains[i].unicode_name, ==, unicode);
g_free (unicode);
unicode = g_hostname_to_unicode (idn_test_domains[i].unicode_name);
g_assert_cmpstr (idn_test_domains[i].unicode_name, ==, unicode);
g_free (unicode);
}
for (i = 0; i < num_bad_names; i++)
{
unicode = g_hostname_to_unicode (bad_names[i]);
g_assert_cmpstr (unicode, ==, NULL);
}
}
static const struct {
const gchar *addr;
gboolean is_addr;
} ip_addr_tests[] = {
/* IPv6 tests */
{ "0123:4567:89AB:cdef:3210:7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef:3210:7654:ba98::", TRUE },
{ "0123:4567:89AB:cdef:3210:7654::", TRUE },
{ "0123:4567:89AB:cdef:3210::", TRUE },
{ "0123:4567:89AB:cdef::", TRUE },
{ "0123:4567:89AB::", TRUE },
{ "0123:4567::", TRUE },
{ "0123::", TRUE },
{ "::4567:89AB:cdef:3210:7654:ba98:FeDc", TRUE },
{ "::89AB:cdef:3210:7654:ba98:FeDc", TRUE },
{ "::cdef:3210:7654:ba98:FeDc", TRUE },
{ "::3210:7654:ba98:FeDc", TRUE },
{ "::7654:ba98:FeDc", TRUE },
{ "::ba98:FeDc", TRUE },
{ "::FeDc", TRUE },
{ "0123::89AB:cdef:3210:7654:ba98:FeDc", TRUE },
{ "0123:4567::cdef:3210:7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB::3210:7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef::7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef:3210::ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef:3210:7654::FeDc", TRUE },
{ "0123::cdef:3210:7654:ba98:FeDc", TRUE },
{ "0123:4567::3210:7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB::7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef::ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef:3210::FeDc", TRUE },
{ "0123::3210:7654:ba98:FeDc", TRUE },
{ "0123:4567::7654:ba98:FeDc", TRUE },
{ "0123:4567:89AB::ba98:FeDc", TRUE },
{ "0123:4567:89AB:cdef::FeDc", TRUE },
{ "0123::7654:ba98:FeDc", TRUE },
{ "0123:4567::ba98:FeDc", TRUE },
{ "0123:4567:89AB::FeDc", TRUE },
{ "0123::ba98:FeDc", TRUE },
{ "0123:4567::FeDc", TRUE },
{ "0123::FeDc", TRUE },
{ "::", TRUE },
{ "0:12:345:6789:a:bc:def::", TRUE },
{ "0123:4567:89AB:cdef:3210:7654:123.45.67.89", TRUE },
{ "0123:4567:89AB:cdef:3210::123.45.67.89", TRUE },
{ "0123:4567:89AB:cdef::123.45.67.89", TRUE },
{ "0123:4567:89AB::123.45.67.89", TRUE },
{ "0123:4567::123.45.67.89", TRUE },
{ "0123::123.45.67.89", TRUE },
{ "::123.45.67.89", TRUE },
/* accept zone-id from rfc6874 */
{ "0123:4567:89AB:cdef:3210:7654:ba98:FeDc%zoneid0", TRUE },
{ "fe80::dead:beef%zonÉid0%weird", TRUE },
{ "fe80::dead:beef%", FALSE },
/* Contain non-hex chars */
{ "012x:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:45x7:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:8xAB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:xdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:321;:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:76*4:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:b-98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:ba98:+eDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:ba98:FeDc and some trailing junk", FALSE },
{ " 123:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "012 :4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123: 567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:ba98:FeD ", FALSE },
/* Contains too-long/out-of-range segments */
{ "00123:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:04567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:189AB:cdef:3210:7654:ba98:FeDc", FALSE },
/* Too short */
{ "0123:4567:89AB:cdef:3210:7654:ba98", FALSE },
{ "0123:4567:89AB:cdef:3210:7654", FALSE },
{ "0123:4567:89AB:cdef:3210", FALSE },
{ "0123", FALSE },
{ "", FALSE },
/* Too long */
{ "0123:4567:89AB:cdef:3210:7654:ba98:FeDc:9999", FALSE },
{ "0123::4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567::89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB::cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef::3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210::7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654::ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:ba98::FeDc", FALSE },
/* Invalid use of ":"s */
{ "0123::89AB::3210:7654:ba98:FeDc", FALSE },
{ "::4567:89AB:cdef:3210:7654::FeDc", FALSE },
{ "0123::89AB:cdef:3210:7654:ba98::", FALSE },
{ ":4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:ba98:", FALSE },
{ "0123:::cdef:3210:7654:ba98:FeDc", FALSE },
{ "0123:4567:89AB:cdef:3210:7654:ba98:FeDc:", FALSE },
{ ":0123:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE },
{ ":::", FALSE },
/* IPv4 address at wrong place */
{ "0123:4567:89AB:cdef:3210:123.45.67.89", FALSE },
{ "0123:4567:89AB:cdef:3210:7654::123.45.67.89", FALSE },
{ "0123:4567:89AB:cdef:123.45.67.89", FALSE },
{ "0123:4567:89AB:cdef:3210:123.45.67.89:FeDc", FALSE },
/* IPv4 tests */
{ "123.45.67.89", TRUE },
{ "1.2.3.4", TRUE },
{ "1.2.3.0", TRUE },
{ "023.045.067.089", FALSE },
{ "1234.5.67.89", FALSE },
{ "123.45.67.00", FALSE },
{ " 1.2.3.4", FALSE },
{ "1 .2.3.4", FALSE },
{ "1. 2.3.4", FALSE },
{ "1.2.3.4 ", FALSE },
{ "1.2.3", FALSE },
{ "1.2.3.4.5", FALSE },
{ "1.b.3.4", FALSE },
{ "1.2.3:4", FALSE },
{ "1.2.3.4, etc", FALSE },
{ "1,2,3,4", FALSE },
{ "1.2.3.com", FALSE },
{ "1.2.3.4.", FALSE },
{ "1.2.3.", FALSE },
{ ".1.2.3.4", FALSE },
{ ".2.3.4", FALSE },
{ "1..2.3.4", FALSE },
{ "1..3.4", FALSE }
};
static const gint num_ip_addr_tests = G_N_ELEMENTS (ip_addr_tests);
static void
test_is_ip_addr (void)
{
gint i;
for (i = 0; i < num_ip_addr_tests; i++)
{
if (g_hostname_is_ip_address (ip_addr_tests[i].addr) != ip_addr_tests[i].is_addr)
{
char *msg = g_strdup_printf ("g_hostname_is_ip_address (\"%s\") == %s",
ip_addr_tests[i].addr,
ip_addr_tests[i].is_addr ? "TRUE" : "FALSE");
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
}
}
}
/* FIXME: test names with both unicode and ACE-encoded labels */
/* FIXME: test invalid unicode names */
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
if (argc == 2 && argv[1][0] != '-')
{
const gchar *hostname = argv[1];
gchar *converted;
if (g_hostname_is_non_ascii (hostname))
{
converted = g_hostname_to_ascii (hostname);
printf ("to_ascii: %s\n", converted);
g_free (converted);
}
else if (g_hostname_is_ascii_encoded (hostname))
{
converted = g_hostname_to_unicode (hostname);
printf ("to_unicode: %s\n", converted);
g_free (converted);
}
else
printf ("hostname is neither unicode nor ACE encoded\n");
return 0;
}
g_test_add_func ("/hostutils/to_ascii", test_to_ascii);
g_test_add_func ("/hostutils/to_unicode", test_to_unicode);
g_test_add_func ("/hostutils/is_ip_addr", test_is_ip_addr);
return g_test_run ();
}

26
glib/tests/include.c Normal file
View file

@ -0,0 +1,26 @@
/* Test case for bug 659866 */
#define _POSIX_C_SOURCE 199309L
#undef _GNU_SOURCE
#undef _XOPEN_SOURCE
#include <pthread.h>
#include <glib.h>
static void
test_rwlock (void)
{
GRWLock lock;
g_rw_lock_init (&lock);
g_rw_lock_clear (&lock);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/include/rwlock", test_rwlock);
return g_test_run ();
}

222
glib/tests/io-channel.c Normal file
View file

@ -0,0 +1,222 @@
/* GLib testing framework examples and tests
*
* Copyright © 2001 Hidetoshi Tajima
* Copyright © 2001 Ron Steinke
* Copyright © 2001 Owen Taylor
* Copyright © 2002 Manish Singh
* Copyright © 2011 Sjoerd Simons
* Copyright © 2012 Simon McVittie
* Copyright © 2013 Stef Walter
* Copyright © 2005, 2006, 2008, 2012, 2013 Matthias Clasen
* Copyright © 2020 Endless Mobile, 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Philip Withnall <withnall@endlessm.com>
*/
#include <glib.h>
#include <glib/gstdio.h>
static void
test_small_writes (void)
{
GIOChannel *io;
GIOStatus status = G_IO_STATUS_ERROR;
guint bytes_remaining;
gchar tmp;
GError *local_error = NULL;
io = g_io_channel_new_file ("iochannel-test-outfile", "w", &local_error);
g_assert_no_error (local_error);
g_io_channel_set_encoding (io, NULL, NULL);
g_io_channel_set_buffer_size (io, 1022);
bytes_remaining = 2 * g_io_channel_get_buffer_size (io);
tmp = 0;
while (bytes_remaining)
{
status = g_io_channel_write_chars (io, &tmp, 1, NULL, NULL);
if (status == G_IO_STATUS_ERROR)
break;
if (status == G_IO_STATUS_NORMAL)
bytes_remaining--;
}
g_assert_cmpint (status, ==, G_IO_STATUS_NORMAL);
g_io_channel_unref (io);
}
static void
test_read_write (void)
{
GIOChannel *gio_r, *gio_w ;
GError *local_error = NULL;
GString *buffer;
char *filename;
gint rlength = 0;
glong wlength = 0;
gsize length_out;
const gchar *encoding = "EUC-JP";
GIOStatus status;
const gsize buffer_size_bytes = 1024;
filename = g_test_build_filename (G_TEST_DIST, "iochannel-test-infile", NULL);
setbuf (stdout, NULL); /* For debugging */
gio_r = g_io_channel_new_file (filename, "r", &local_error);
g_assert_no_error (local_error);
gio_w = g_io_channel_new_file ("iochannel-test-outfile", "w", &local_error);
g_assert_no_error (local_error);
g_io_channel_set_encoding (gio_r, encoding, &local_error);
g_assert_no_error (local_error);
g_io_channel_set_buffer_size (gio_r, buffer_size_bytes);
status = g_io_channel_set_flags (gio_r, G_IO_FLAG_NONBLOCK, &local_error);
if (status == G_IO_STATUS_ERROR)
{
/* Errors should not happen */
g_assert_no_error (local_error);
g_clear_error (&local_error);
}
buffer = g_string_sized_new (buffer_size_bytes);
while (TRUE)
{
do
status = g_io_channel_read_line_string (gio_r, buffer, NULL, &local_error);
while (status == G_IO_STATUS_AGAIN);
if (status != G_IO_STATUS_NORMAL)
break;
rlength += buffer->len;
do
status = g_io_channel_write_chars (gio_w, buffer->str, buffer->len,
&length_out, &local_error);
while (status == G_IO_STATUS_AGAIN);
if (status != G_IO_STATUS_NORMAL)
break;
wlength += length_out;
/* Ensure the whole line was written */
g_assert_cmpuint (length_out, ==, buffer->len);
g_test_message ("%s", buffer->str);
g_string_truncate (buffer, 0);
}
switch (status)
{
case G_IO_STATUS_EOF:
break;
case G_IO_STATUS_ERROR:
/* Errors should not happen */
g_assert_no_error (local_error);
g_clear_error (&local_error);
break;
default:
g_assert_not_reached ();
break;
}
do
status = g_io_channel_flush (gio_w, &local_error);
while (status == G_IO_STATUS_AGAIN);
if (status == G_IO_STATUS_ERROR)
{
/* Errors should not happen */
g_assert_no_error (local_error);
g_clear_error (&local_error);
}
g_test_message ("read %d bytes, wrote %ld bytes", rlength, wlength);
g_io_channel_unref (gio_r);
g_io_channel_unref (gio_w);
test_small_writes ();
g_free (filename);
g_string_free (buffer, TRUE);
}
static void
test_read_line_embedded_nuls (void)
{
const guint8 test_data[] = { 'H', 'i', '!', '\0', 'y', 'o', 'u', '\n', ':', ')', '\n' };
gint fd;
gchar *filename = NULL;
GIOChannel *channel = NULL;
GError *local_error = NULL;
gchar *line = NULL;
gsize line_length, terminator_pos;
GIOStatus status;
g_test_summary ("Test that reading a line containing embedded nuls works "
"when using non-standard line terminators.");
/* Write out a temporary file. */
fd = g_file_open_tmp ("glib-test-io-channel-XXXXXX", &filename, &local_error);
g_assert_no_error (local_error);
g_close (fd, NULL);
fd = -1;
g_file_set_contents (filename, (const gchar *) test_data, sizeof (test_data), &local_error);
g_assert_no_error (local_error);
/* Create the channel. */
channel = g_io_channel_new_file (filename, "r", &local_error);
g_assert_no_error (local_error);
/* Only break on newline characters, not nuls.
* Use length -1 here to exercise glib#2323; the case where length > 0
* is covered in glib/tests/protocol.c. */
g_io_channel_set_line_term (channel, "\n", -1);
g_io_channel_set_encoding (channel, NULL, &local_error);
g_assert_no_error (local_error);
status = g_io_channel_read_line (channel, &line, &line_length,
&terminator_pos, &local_error);
g_assert_no_error (local_error);
g_assert_cmpint (status, ==, G_IO_STATUS_NORMAL);
g_assert_cmpuint (line_length, ==, 8);
g_assert_cmpuint (terminator_pos, ==, 7);
g_assert_cmpmem (line, line_length, test_data, 8);
g_free (line);
g_io_channel_unref (channel);
g_free (filename);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/io-channel/read-write", test_read_write);
g_test_add_func ("/io-channel/read-line/embedded-nuls", test_read_line_embedded_nuls);
return g_test_run ();
}

View file

@ -0,0 +1,5 @@
Line one
Line two
Line three
/* Hello */
\x1234\x567890\x6666

1876
glib/tests/keyfile.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
[test]
key1=16
key2=32
key3=fourty-eight

659
glib/tests/list.c Normal file
View file

@ -0,0 +1,659 @@
#include <glib.h>
#include <stdlib.h>
#define SIZE 50
#define NUMBER_MIN 0000
#define NUMBER_MAX 9999
static guint32 array[SIZE];
static gint
sort (gconstpointer p1, gconstpointer p2)
{
gint32 a, b;
a = GPOINTER_TO_INT (p1);
b = GPOINTER_TO_INT (p2);
return (a > b ? +1 : a == b ? 0 : -1);
}
/*
* glist sort tests
*/
static void
test_list_sort (void)
{
GList *list = NULL;
gint i;
for (i = 0; i < SIZE; i++)
list = g_list_append (list, GINT_TO_POINTER (array[i]));
list = g_list_sort (list, sort);
for (i = 0; i < SIZE - 1; i++)
{
gpointer p1, p2;
p1 = g_list_nth_data (list, i);
p2 = g_list_nth_data (list, i+1);
g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
}
g_list_free (list);
}
static void
test_list_sort_with_data (void)
{
GList *list = NULL;
gint i;
for (i = 0; i < SIZE; i++)
list = g_list_append (list, GINT_TO_POINTER (array[i]));
list = g_list_sort_with_data (list, (GCompareDataFunc)sort, NULL);
for (i = 0; i < SIZE - 1; i++)
{
gpointer p1, p2;
p1 = g_list_nth_data (list, i);
p2 = g_list_nth_data (list, i+1);
g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
}
g_list_free (list);
}
/* Test that the sort is stable. */
static void
test_list_sort_stable (void)
{
GList *list = NULL; /* (element-type utf8) */
GList *copy = NULL; /* (element-type utf8) */
gsize i;
/* Build a test list, already ordered. */
for (i = 0; i < SIZE; i++)
list = g_list_append (list, g_strdup_printf ("%" G_GSIZE_FORMAT, i / 5));
/* Take a copy and sort it. */
copy = g_list_copy (list);
copy = g_list_sort (copy, (GCompareFunc) g_strcmp0);
/* Compare the two lists, checking pointers are equal to ensure the elements
* have been kept stable. */
for (i = 0; i < SIZE; i++)
{
gpointer p1, p2;
p1 = g_list_nth_data (list, i);
p2 = g_list_nth_data (list, i);
g_assert (p1 == p2);
}
g_list_free (copy);
g_list_free_full (list, g_free);
}
static void
test_list_insert_sorted (void)
{
GList *list = NULL;
gint i;
for (i = 0; i < SIZE; i++)
list = g_list_insert_sorted (list, GINT_TO_POINTER (array[i]), sort);
for (i = 0; i < SIZE - 1; i++)
{
gpointer p1, p2;
p1 = g_list_nth_data (list, i);
p2 = g_list_nth_data (list, i+1);
g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
}
g_list_free (list);
}
static void
test_list_insert_sorted_with_data (void)
{
GList *list = NULL;
gint i;
for (i = 0; i < SIZE; i++)
list = g_list_insert_sorted_with_data (list,
GINT_TO_POINTER (array[i]),
(GCompareDataFunc)sort,
NULL);
for (i = 0; i < SIZE - 1; i++)
{
gpointer p1, p2;
p1 = g_list_nth_data (list, i);
p2 = g_list_nth_data (list, i+1);
g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
}
g_list_free (list);
}
static void
test_list_reverse (void)
{
GList *list = NULL;
GList *st;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
for (i = 0; i < 10; i++)
list = g_list_append (list, &nums[i]);
list = g_list_reverse (list);
for (i = 0; i < 10; i++)
{
st = g_list_nth (list, i);
g_assert (*((gint*) st->data) == (9 - i));
}
g_list_free (list);
}
static void
test_list_nth (void)
{
GList *list = NULL;
GList *st;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
for (i = 0; i < 10; i++)
list = g_list_append (list, &nums[i]);
for (i = 0; i < 10; i++)
{
st = g_list_nth (list, i);
g_assert (*((gint*) st->data) == i);
}
g_list_free (list);
}
static void
test_list_concat (void)
{
GList *list1 = NULL;
GList *list2 = NULL;
GList *st;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
for (i = 0; i < 5; i++)
{
list1 = g_list_append (list1, &nums[i]);
list2 = g_list_append (list2, &nums[i+5]);
}
g_assert_cmpint (g_list_length (list1), ==, 5);
g_assert_cmpint (g_list_length (list2), ==, 5);
list1 = g_list_concat (list1, list2);
g_assert_cmpint (g_list_length (list1), ==, 10);
for (i = 0; i < 10; i++)
{
st = g_list_nth (list1, i);
g_assert (*((gint*) st->data) == i);
}
list2 = g_list_concat (NULL, list1);
g_assert_cmpint (g_list_length (list2), ==, 10);
list2 = g_list_concat (list1, NULL);
g_assert_cmpint (g_list_length (list2), ==, 10);
list2 = g_list_concat (NULL, NULL);
g_assert (list2 == NULL);
g_list_free (list1);
}
static void
test_list_remove (void)
{
GList *list = NULL;
GList *st;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
for (i = 0; i < 10; i++)
{
list = g_list_append (list, &nums[i]);
list = g_list_append (list, &nums[i]);
}
g_assert_cmpint (g_list_length (list), ==, 20);
for (i = 0; i < 10; i++)
{
list = g_list_remove (list, &nums[i]);
}
g_assert_cmpint (g_list_length (list), ==, 10);
for (i = 0; i < 10; i++)
{
st = g_list_nth (list, i);
g_assert (*((gint*) st->data) == i);
}
g_list_free (list);
}
static void
test_list_remove_all (void)
{
GList *list = NULL;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
for (i = 0; i < 10; i++)
{
list = g_list_append (list, &nums[i]);
list = g_list_append (list, &nums[i]);
}
g_assert_cmpint (g_list_length (list), ==, 20);
for (i = 0; i < 5; i++)
{
list = g_list_remove_all (list, &nums[2 * i + 1]);
list = g_list_remove_all (list, &nums[8 - 2 * i]);
}
g_assert_cmpint (g_list_length (list), ==, 0);
g_assert (list == NULL);
}
static void
test_list_first_last (void)
{
GList *list = NULL;
GList *st;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
for (i = 0; i < 10; i++)
list = g_list_append (list, &nums[i]);
st = g_list_last (list);
g_assert (*((gint*) st->data) == 9);
st = g_list_nth_prev (st, 3);
g_assert (*((gint*) st->data) == 6);
st = g_list_first (st);
g_assert (*((gint*) st->data) == 0);
g_list_free (list);
}
static void
test_list_insert (void)
{
GList *list = NULL;
GList *st;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint i;
list = g_list_insert_before (NULL, NULL, &nums[1]);
list = g_list_insert (list, &nums[3], 1);
list = g_list_insert (list, &nums[4], -1);
list = g_list_insert (list, &nums[0], 0);
list = g_list_insert (list, &nums[5], 100);
list = g_list_insert_before (list, NULL, &nums[6]);
list = g_list_insert_before (list, list->next->next, &nums[2]);
list = g_list_insert (list, &nums[9], 7);
list = g_list_insert (list, &nums[8], 7);
list = g_list_insert (list, &nums[7], 7);
for (i = 0; i < 10; i++)
{
st = g_list_nth (list, i);
g_assert (*((gint*) st->data) == i);
}
g_list_free (list);
}
typedef struct
{
gboolean freed;
int x;
} ListItem;
static void
free_func (gpointer data)
{
ListItem *item = data;
item->freed = TRUE;
}
static ListItem *
new_item (int x)
{
ListItem *item;
item = g_slice_new (ListItem);
item->freed = FALSE;
item->x = x;
return item;
}
static void
test_free_full (void)
{
ListItem *one, *two, *three;
GSList *slist = NULL;
GList *list = NULL;
slist = g_slist_prepend (slist, one = new_item (1));
slist = g_slist_prepend (slist, two = new_item (2));
slist = g_slist_prepend (slist, three = new_item (3));
g_assert (!one->freed);
g_assert (!two->freed);
g_assert (!three->freed);
g_slist_free_full (slist, free_func);
g_assert (one->freed);
g_assert (two->freed);
g_assert (three->freed);
g_slice_free (ListItem, one);
g_slice_free (ListItem, two);
g_slice_free (ListItem, three);
list = g_list_prepend (list, one = new_item (1));
list = g_list_prepend (list, two = new_item (2));
list = g_list_prepend (list, three = new_item (3));
g_assert (!one->freed);
g_assert (!two->freed);
g_assert (!three->freed);
g_list_free_full (list, free_func);
g_assert (one->freed);
g_assert (two->freed);
g_assert (three->freed);
g_slice_free (ListItem, one);
g_slice_free (ListItem, two);
g_slice_free (ListItem, three);
}
static void
test_list_copy (void)
{
GList *l, *l2;
GList *u, *v;
l = NULL;
l = g_list_append (l, GINT_TO_POINTER (1));
l = g_list_append (l, GINT_TO_POINTER (2));
l = g_list_append (l, GINT_TO_POINTER (3));
l2 = g_list_copy (l);
for (u = l, v = l2; u && v; u = u->next, v = v->next)
{
g_assert (u->data == v->data);
}
g_list_free (l);
g_list_free (l2);
}
static gpointer
multiply_value (gconstpointer value, gpointer data)
{
return GINT_TO_POINTER (GPOINTER_TO_INT (value) * GPOINTER_TO_INT (data));
}
static void
test_list_copy_deep (void)
{
GList *l, *l2;
GList *u, *v;
l = NULL;
l = g_list_append (l, GINT_TO_POINTER (1));
l = g_list_append (l, GINT_TO_POINTER (2));
l = g_list_append (l, GINT_TO_POINTER (3));
l2 = g_list_copy_deep (l, multiply_value, GINT_TO_POINTER (2));
for (u = l, v = l2; u && v; u = u->next, v = v->next)
{
g_assert_cmpint (GPOINTER_TO_INT (u->data) * 2, ==, GPOINTER_TO_INT (v->data));
}
g_list_free (l);
g_list_free (l2);
}
static void
test_delete_link (void)
{
GList *l, *l2;
l = NULL;
l = g_list_append (l, GINT_TO_POINTER (1));
l = g_list_append (l, GINT_TO_POINTER (2));
l = g_list_append (l, GINT_TO_POINTER (3));
l2 = l->next;
l = g_list_delete_link (l, l2);
g_assert (l->data == GINT_TO_POINTER (1));
g_assert (l->next->data == GINT_TO_POINTER (3));
g_list_free (l);
}
static void
test_prepend (void)
{
gpointer a = "a";
gpointer b = "b";
gpointer c = "c";
GList *l, *l2;
l = NULL;
l = g_list_prepend (l, c);
l = g_list_prepend (l, a);
g_assert (l->data == a);
g_assert (l->next->data == c);
g_assert (l->next->next == NULL);
l2 = l->next;
l2 = g_list_prepend (l2, b);
g_assert (l2->prev == l);
g_assert (l->data == a);
g_assert (l->next->data == b);
g_assert (l->next->next->data == c);
g_assert (l->next->next->next == NULL);
g_list_free (l);
}
static void
test_position (void)
{
GList *l, *ll;
char *a = "a";
char *b = "b";
char *c = "c";
char *d = "d";
l = NULL;
l = g_list_append (l, a);
l = g_list_append (l, b);
l = g_list_append (l, c);
ll = g_list_find (l, a);
g_assert_cmpint (g_list_position (l, ll), ==, 0);
g_assert_cmpint (g_list_index (l, a), ==, 0);
ll = g_list_find (l, b);
g_assert_cmpint (g_list_position (l, ll), ==, 1);
g_assert_cmpint (g_list_index (l, b), ==, 1);
ll = g_list_find (l, c);
g_assert_cmpint (g_list_position (l, ll), ==, 2);
g_assert_cmpint (g_list_index (l, c), ==, 2);
ll = g_list_append (NULL, d);
g_assert_cmpint (g_list_position (l, ll), ==, -1);
g_assert_cmpint (g_list_index (l, d), ==, -1);
g_list_free (l);
g_list_free (ll);
}
static void
test_double_free (void)
{
GList *list, *link;
// Casts to size_t first ensure compilers won't warn about pointer casts that change size
// MSVC's C4312 warning with /Wp64
GList intruder = { NULL, (gpointer)(size_t)0xDEADBEEF, (gpointer)(size_t)0xDEADBEEF };
if (g_test_subprocess ())
{
list = NULL;
list = g_list_append (list, "a");
link = list = g_list_append (list, "b");
list = g_list_append (list, "c");
list = g_list_remove_link (list, link);
link->prev = list;
link->next = &intruder;
list = g_list_remove_link (list, link);
g_list_free (list);
return;
}
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*corrupted double-linked list detected*");
}
static void
test_list_insert_before_link (void)
{
GList a = {0};
GList b = {0};
GList c = {0};
GList d = {0};
GList e = {0};
GList *list;
list = g_list_insert_before_link (NULL, NULL, &a);
g_assert_nonnull (list);
g_assert_true (list == &a);
g_assert_null (a.prev);
g_assert_null (a.next);
g_assert_cmpint (g_list_length (list), ==, 1);
list = g_list_insert_before_link (list, &a, &b);
g_assert_nonnull (list);
g_assert_true (list == &b);
g_assert_null (b.prev);
g_assert_true (b.next == &a);
g_assert_true (a.prev == &b);
g_assert_null (a.next);
g_assert_cmpint (g_list_length (list), ==, 2);
list = g_list_insert_before_link (list, &a, &c);
g_assert_nonnull (list);
g_assert_true (list == &b);
g_assert_null (b.prev);
g_assert_true (b.next == &c);
g_assert_true (c.next == &a);
g_assert_true (c.prev == &b);
g_assert_true (a.prev == &c);
g_assert_null (a.next);
g_assert_cmpint (g_list_length (list), ==, 3);
list = g_list_insert_before_link (list, &b, &d);
g_assert_nonnull (list);
g_assert_true (list == &d);
g_assert_null (d.prev);
g_assert_true (b.prev == &d);
g_assert_true (c.prev == &b);
g_assert_true (a.prev == &c);
g_assert_true (d.next == &b);
g_assert_true (b.next == &c);
g_assert_true (c.next == &a);
g_assert_null (a.next);
g_assert_cmpint (g_list_length (list), ==, 4);
list = g_list_insert_before_link (list, NULL, &e);
g_assert_nonnull (list);
g_assert_true (list == &d);
g_assert_null (d.prev);
g_assert_true (b.prev == &d);
g_assert_true (c.prev == &b);
g_assert_true (a.prev == &c);
g_assert_true (d.next == &b);
g_assert_true (b.next == &c);
g_assert_true (c.next == &a);
g_assert_true (a.next == &e);
g_assert_true (e.prev == &a);
g_assert_null (e.next);
g_assert_cmpint (g_list_length (list), ==, 5);
}
int
main (int argc, char *argv[])
{
gint i;
g_test_init (&argc, &argv, NULL);
/* Create an array of random numbers. */
for (i = 0; i < SIZE; i++)
array[i] = g_test_rand_int_range (NUMBER_MIN, NUMBER_MAX);
g_test_add_func ("/list/sort", test_list_sort);
g_test_add_func ("/list/sort-with-data", test_list_sort_with_data);
g_test_add_func ("/list/sort/stable", test_list_sort_stable);
g_test_add_func ("/list/insert-before-link", test_list_insert_before_link);
g_test_add_func ("/list/insert-sorted", test_list_insert_sorted);
g_test_add_func ("/list/insert-sorted-with-data", test_list_insert_sorted_with_data);
g_test_add_func ("/list/reverse", test_list_reverse);
g_test_add_func ("/list/nth", test_list_nth);
g_test_add_func ("/list/concat", test_list_concat);
g_test_add_func ("/list/remove", test_list_remove);
g_test_add_func ("/list/remove-all", test_list_remove_all);
g_test_add_func ("/list/first-last", test_list_first_last);
g_test_add_func ("/list/insert", test_list_insert);
g_test_add_func ("/list/free-full", test_free_full);
g_test_add_func ("/list/copy", test_list_copy);
g_test_add_func ("/list/copy-deep", test_list_copy_deep);
g_test_add_func ("/list/delete-link", test_delete_link);
g_test_add_func ("/list/prepend", test_prepend);
g_test_add_func ("/list/position", test_position);
g_test_add_func ("/list/double-free", test_double_free);
return g_test_run ();
}

668
glib/tests/logging.c Normal file
View file

@ -0,0 +1,668 @@
#include <stdlib.h>
#include <string.h>
#define G_LOG_USE_STRUCTURED 1
#include <glib.h>
/* Test g_warn macros */
static void
test_warnings (void)
{
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*test_warnings*should not be reached*");
g_warn_if_reached ();
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*test_warnings*runtime check failed*");
g_warn_if_fail (FALSE);
g_test_assert_expected_messages ();
}
static guint log_count = 0;
static void
log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
g_assert_cmpstr (log_domain, ==, "bu");
g_assert_cmpint (log_level, ==, G_LOG_LEVEL_INFO);
log_count++;
}
/* test that custom log handlers only get called for
* their domain and level
*/
static void
test_set_handler (void)
{
guint id;
id = g_log_set_handler ("bu", G_LOG_LEVEL_INFO, log_handler, NULL);
g_log ("bu", G_LOG_LEVEL_DEBUG, "message");
g_log ("ba", G_LOG_LEVEL_DEBUG, "message");
g_log ("bu", G_LOG_LEVEL_INFO, "message");
g_log ("ba", G_LOG_LEVEL_INFO, "message");
g_assert_cmpint (log_count, ==, 1);
g_log_remove_handler ("bu", id);
}
static void
test_default_handler_error (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_error ("message1");
exit (0);
}
static void
test_default_handler_critical (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_critical ("message2");
exit (0);
}
static void
test_default_handler_warning (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_warning ("message3");
exit (0);
}
static void
test_default_handler_message (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_message ("message4");
exit (0);
}
static void
test_default_handler_info (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5");
exit (0);
}
static void
test_default_handler_bar_info (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
g_log ("bar", G_LOG_LEVEL_INFO, "message5");
exit (0);
}
static void
test_default_handler_baz_debug (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
g_log ("baz", G_LOG_LEVEL_DEBUG, "message6");
exit (0);
}
static void
test_default_handler_debug (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
g_log ("foo", G_LOG_LEVEL_DEBUG, "6");
g_log ("bar", G_LOG_LEVEL_DEBUG, "6");
g_log ("baz", G_LOG_LEVEL_DEBUG, "6");
exit (0);
}
static void
test_default_handler_debug_stderr (void)
{
g_log_writer_default_set_use_stderr (TRUE);
g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
g_log ("foo", G_LOG_LEVEL_DEBUG, "6");
g_log ("bar", G_LOG_LEVEL_DEBUG, "6");
g_log ("baz", G_LOG_LEVEL_DEBUG, "6");
exit (0);
}
static void
test_default_handler_would_drop (void)
{
g_unsetenv ("G_MESSAGES_DEBUG");
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
g_setenv ("G_MESSAGES_DEBUG", "bar baz", TRUE);
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
g_setenv ("G_MESSAGES_DEBUG", "foo bar", TRUE);
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo"));
g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
g_assert_false (g_log_writer_default_would_drop (1<<G_LOG_LEVEL_USER_SHIFT, "foo"));
exit (0);
}
static void
test_default_handler_0x400 (void)
{
g_log_set_default_handler (g_log_default_handler, NULL);
g_log (G_LOG_DOMAIN, 1<<10, "message7");
exit (0);
}
static void
test_default_handler (void)
{
g_test_trap_subprocess ("/logging/default-handler/subprocess/error", 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*ERROR*message1*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/critical", 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*CRITICAL*message2*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/warning", 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*WARNING*message3*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/message", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stderr ("*Message*message4*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/info", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout_unmatched ("*INFO*message5*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/bar-info", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout ("*INFO*message5*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/baz-debug", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout ("*DEBUG*message6*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/debug", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout ("*DEBUG*6*6*6*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/debug-stderr", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout_unmatched ("DEBUG");
g_test_trap_assert_stderr ("*DEBUG*6*6*6*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/0x400", 0, 0);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout ("*LOG-0x400*message7*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop", 0, 0);
g_test_trap_assert_passed ();
}
static void
test_fatal_log_mask (void)
{
if (g_test_subprocess ())
{
g_log_set_fatal_mask ("bu", G_LOG_LEVEL_INFO);
g_log ("bu", G_LOG_LEVEL_INFO, "fatal");
return;
}
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
/* G_LOG_LEVEL_INFO isn't printed by default */
g_test_trap_assert_stdout_unmatched ("*fatal*");
}
static gint my_print_count = 0;
static void
my_print_handler (const gchar *text)
{
my_print_count++;
}
static void
test_print_handler (void)
{
GPrintFunc old_print_handler;
old_print_handler = g_set_print_handler (my_print_handler);
g_assert (old_print_handler == NULL);
my_print_count = 0;
g_print ("bu ba");
g_assert_cmpint (my_print_count, ==, 1);
g_set_print_handler (NULL);
}
static void
test_printerr_handler (void)
{
GPrintFunc old_printerr_handler;
old_printerr_handler = g_set_printerr_handler (my_print_handler);
g_assert (old_printerr_handler == NULL);
my_print_count = 0;
g_printerr ("bu ba");
g_assert_cmpint (my_print_count, ==, 1);
g_set_printerr_handler (NULL);
}
static char *fail_str = "foo";
static char *log_str = "bar";
static gboolean
good_failure_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *msg,
gpointer user_data)
{
g_test_message ("The Good Fail Message Handler\n");
g_assert ((char *)user_data != log_str);
g_assert ((char *)user_data == fail_str);
return FALSE;
}
static gboolean
bad_failure_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *msg,
gpointer user_data)
{
g_test_message ("The Bad Fail Message Handler\n");
g_assert ((char *)user_data == log_str);
g_assert ((char *)user_data != fail_str);
return FALSE;
}
static void
test_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *msg,
gpointer user_data)
{
g_test_message ("The Log Message Handler\n");
g_assert ((char *)user_data != fail_str);
g_assert ((char *)user_data == log_str);
}
static void
bug653052 (void)
{
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=653052");
g_test_log_set_fatal_handler (good_failure_handler, fail_str);
g_log_set_default_handler (test_handler, log_str);
g_return_if_fail (0);
g_test_log_set_fatal_handler (bad_failure_handler, fail_str);
g_log_set_default_handler (test_handler, log_str);
g_return_if_fail (0);
}
static void
test_gibberish (void)
{
if (g_test_subprocess ())
{
g_warning ("bla bla \236\237\190");
return;
}
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*bla bla \\x9e\\x9f\\u000190*");
}
static GLogWriterOutput
null_log_writer (GLogLevelFlags log_level,
const GLogField *fields,
gsize n_fields,
gpointer user_data)
{
log_count++;
return G_LOG_WRITER_HANDLED;
}
typedef struct {
const GLogField *fields;
gsize n_fields;
} ExpectedMessage;
static gboolean
compare_field (const GLogField *f1, const GLogField *f2)
{
if (strcmp (f1->key, f2->key) != 0)
return FALSE;
if (f1->length != f2->length)
return FALSE;
if (f1->length == -1)
return strcmp (f1->value, f2->value) == 0;
else
return memcmp (f1->value, f2->value, f1->length) == 0;
}
static gboolean
compare_fields (const GLogField *f1, gsize n1, const GLogField *f2, gsize n2)
{
gsize i, j;
for (i = 0; i < n1; i++)
{
for (j = 0; j < n2; j++)
{
if (compare_field (&f1[i], &f2[j]))
break;
}
if (j == n2)
return FALSE;
}
return TRUE;
}
static GSList *expected_messages = NULL;
static const guchar binary_field[] = {1, 2, 3, 4, 5};
static GLogWriterOutput
expect_log_writer (GLogLevelFlags log_level,
const GLogField *fields,
gsize n_fields,
gpointer user_data)
{
ExpectedMessage *expected = expected_messages->data;
if (compare_fields (fields, n_fields, expected->fields, expected->n_fields))
{
expected_messages = g_slist_delete_link (expected_messages, expected_messages);
}
else if ((log_level & G_LOG_LEVEL_DEBUG) != G_LOG_LEVEL_DEBUG)
{
char *str;
str = g_log_writer_format_fields (log_level, fields, n_fields, FALSE);
g_test_fail_printf ("Unexpected message: %s", str);
g_free (str);
}
return G_LOG_WRITER_HANDLED;
}
static void
test_structured_logging_no_state (void)
{
gpointer some_pointer = GUINT_TO_POINTER (0x100);
guint some_integer = 123;
log_count = 0;
g_log_set_writer_func (null_log_writer, NULL, NULL);
g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE,
"MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e",
"MY_APPLICATION_CUSTOM_FIELD", "some debug string",
"MESSAGE", "This is a debug message about pointer %p and integer %u.",
some_pointer, some_integer);
g_assert_cmpint (log_count, ==, 1);
}
static void
test_structured_logging_some_state (void)
{
gpointer state_object = NULL; /* this must not be dereferenced */
const GLogField fields[] = {
{ "MESSAGE", "This is a debug message.", -1 },
{ "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
{ "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 },
{ "MY_APPLICATION_STATE", state_object, 0 },
};
log_count = 0;
g_log_set_writer_func (null_log_writer, NULL, NULL);
g_log_structured_array (G_LOG_LEVEL_DEBUG, fields, G_N_ELEMENTS (fields));
g_assert_cmpint (log_count, ==, 1);
}
static void
test_structured_logging_robustness (void)
{
log_count = 0;
g_log_set_writer_func (null_log_writer, NULL, NULL);
/* NULL log_domain shouldn't crash */
g_log (NULL, G_LOG_LEVEL_MESSAGE, "Test");
g_log_structured (NULL, G_LOG_LEVEL_MESSAGE, "MESSAGE", "Test");
g_assert_cmpint (log_count, ==, 1);
}
static void
test_structured_logging_roundtrip1 (void)
{
gpointer some_pointer = GUINT_TO_POINTER (0x100);
gint some_integer = 123;
gchar message[200];
GLogField fields[] = {
{ "GLIB_DOMAIN", "some-domain", -1 },
{ "PRIORITY", "5", -1 },
{ "MESSAGE", "String assigned using g_snprintf() below", -1 },
{ "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
{ "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 }
};
ExpectedMessage expected = { fields, 5 };
/* %p format is implementation defined and depends on the platform */
g_snprintf (message, sizeof (message),
"This is a debug message about pointer %p and integer %u.",
some_pointer, some_integer);
fields[2].value = message;
expected_messages = g_slist_append (NULL, &expected);
g_log_set_writer_func (expect_log_writer, NULL, NULL);
g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE,
"MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893",
"MY_APPLICATION_CUSTOM_FIELD", "some debug string",
"MESSAGE", "This is a debug message about pointer %p and integer %u.",
some_pointer, some_integer);
if (expected_messages != NULL)
{
char *str;
ExpectedMessage *msg = expected_messages->data;
str = g_log_writer_format_fields (0, msg->fields, msg->n_fields, FALSE);
g_test_fail_printf ("Unexpected message: %s", str);
g_free (str);
}
}
static void
test_structured_logging_roundtrip2 (void)
{
const gchar *some_string = "abc";
const GLogField fields[] = {
{ "GLIB_DOMAIN", "some-domain", -1 },
{ "PRIORITY", "5", -1 },
{ "MESSAGE", "This is a debug message about string 'abc'.", -1 },
{ "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
{ "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 }
};
ExpectedMessage expected = { fields, 5 };
expected_messages = g_slist_append (NULL, &expected);
g_log_set_writer_func (expect_log_writer, NULL, NULL);
g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE,
"MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893",
"MY_APPLICATION_CUSTOM_FIELD", "some debug string",
"MESSAGE", "This is a debug message about string '%s'.",
some_string);
g_assert (expected_messages == NULL);
}
static void
test_structured_logging_roundtrip3 (void)
{
const GLogField fields[] = {
{ "GLIB_DOMAIN", "some-domain", -1 },
{ "PRIORITY", "4", -1 },
{ "MESSAGE", "Test test test.", -1 }
};
ExpectedMessage expected = { fields, 3 };
expected_messages = g_slist_append (NULL, &expected);
g_log_set_writer_func (expect_log_writer, NULL, NULL);
g_log_structured ("some-domain", G_LOG_LEVEL_WARNING,
"MESSAGE", "Test test test.");
g_assert (expected_messages == NULL);
}
static GVariant *
create_variant_fields (void)
{
GVariant *binary;
GVariantBuilder builder;
binary = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, binary_field, G_N_ELEMENTS (binary_field), sizeof (binary_field[0]));
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&builder, "{sv}", "MESSAGE_ID", g_variant_new_string ("06d4df59e6c24647bfe69d2c27ef0b4e"));
g_variant_builder_add (&builder, "{sv}", "MESSAGE", g_variant_new_string ("This is a debug message"));
g_variant_builder_add (&builder, "{sv}", "MY_APPLICATION_CUSTOM_FIELD", g_variant_new_string ("some debug string"));
g_variant_builder_add (&builder, "{sv}", "MY_APPLICATION_CUSTOM_FIELD_BINARY", binary);
return g_variant_builder_end (&builder);
}
static void
test_structured_logging_variant1 (void)
{
GVariant *v = create_variant_fields ();
log_count = 0;
g_log_set_writer_func (null_log_writer, NULL, NULL);
g_log_variant ("some-domain", G_LOG_LEVEL_MESSAGE, v);
g_variant_unref (v);
g_assert_cmpint (log_count, ==, 1);
}
static void
test_structured_logging_variant2 (void)
{
const GLogField fields[] = {
{ "GLIB_DOMAIN", "some-domain", -1 },
{ "PRIORITY", "5", -1 },
{ "MESSAGE", "This is a debug message", -1 },
{ "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e", -1 },
{ "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 },
{ "MY_APPLICATION_CUSTOM_FIELD_BINARY", binary_field, sizeof (binary_field) }
};
ExpectedMessage expected = { fields, 6 };
GVariant *v = create_variant_fields ();
expected_messages = g_slist_append (NULL, &expected);
g_log_set_writer_func (expect_log_writer, NULL, NULL);
g_log_variant ("some-domain", G_LOG_LEVEL_MESSAGE, v);
g_variant_unref (v);
g_assert (expected_messages == NULL);
}
int
main (int argc, char *argv[])
{
g_unsetenv ("G_MESSAGES_DEBUG");
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/logging/default-handler", test_default_handler);
g_test_add_func ("/logging/default-handler/subprocess/error", test_default_handler_error);
g_test_add_func ("/logging/default-handler/subprocess/critical", test_default_handler_critical);
g_test_add_func ("/logging/default-handler/subprocess/warning", test_default_handler_warning);
g_test_add_func ("/logging/default-handler/subprocess/message", test_default_handler_message);
g_test_add_func ("/logging/default-handler/subprocess/info", test_default_handler_info);
g_test_add_func ("/logging/default-handler/subprocess/bar-info", test_default_handler_bar_info);
g_test_add_func ("/logging/default-handler/subprocess/baz-debug", test_default_handler_baz_debug);
g_test_add_func ("/logging/default-handler/subprocess/debug", test_default_handler_debug);
g_test_add_func ("/logging/default-handler/subprocess/debug-stderr", test_default_handler_debug_stderr);
g_test_add_func ("/logging/default-handler/subprocess/0x400", test_default_handler_0x400);
g_test_add_func ("/logging/default-handler/subprocess/would-drop", test_default_handler_would_drop);
g_test_add_func ("/logging/warnings", test_warnings);
g_test_add_func ("/logging/fatal-log-mask", test_fatal_log_mask);
g_test_add_func ("/logging/set-handler", test_set_handler);
g_test_add_func ("/logging/print-handler", test_print_handler);
g_test_add_func ("/logging/printerr-handler", test_printerr_handler);
g_test_add_func ("/logging/653052", bug653052);
g_test_add_func ("/logging/gibberish", test_gibberish);
g_test_add_func ("/structured-logging/no-state", test_structured_logging_no_state);
g_test_add_func ("/structured-logging/some-state", test_structured_logging_some_state);
g_test_add_func ("/structured-logging/robustness", test_structured_logging_robustness);
g_test_add_func ("/structured-logging/roundtrip1", test_structured_logging_roundtrip1);
g_test_add_func ("/structured-logging/roundtrip2", test_structured_logging_roundtrip2);
g_test_add_func ("/structured-logging/roundtrip3", test_structured_logging_roundtrip3);
g_test_add_func ("/structured-logging/variant1", test_structured_logging_variant1);
g_test_add_func ("/structured-logging/variant2", test_structured_logging_variant2);
return g_test_run ();
}

71
glib/tests/macros.c Normal file
View file

@ -0,0 +1,71 @@
/* GLib testing framework examples and tests
*
* Copyright © 2018 Endless Mobile, 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.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Philip Withnall <withnall@endlessm.com>
*/
#include <glib.h>
/* Test that G_STATIC_ASSERT_EXPR can be used as an expression */
static void
test_assert_static (void)
{
G_STATIC_ASSERT (4 == 4);
if (G_STATIC_ASSERT_EXPR (1 == 1), sizeof (gchar) == 2)
g_assert_not_reached ();
}
/* Test G_ALIGNOF() gives the same results as the G_STRUCT_OFFSET fallback. This
* should be the minimal alignment for the given type.
*
* This is necessary because the implementation of G_ALIGNOF() varies depending
* on the compiler in use. We want all implementations to be consistent.
*
* In the case that the compiler uses the G_STRUCT_OFFSET fallback, this test
* is a no-op. */
static void
test_alignof_fallback (void)
{
#define check_alignof(type) \
g_assert_cmpint (G_ALIGNOF (type), ==, G_STRUCT_OFFSET (struct { char a; type b; }, b))
check_alignof (char);
check_alignof (int);
check_alignof (float);
check_alignof (double);
check_alignof (struct { char a; int b; });
}
static void
test_struct_sizeof_member (void)
{
G_STATIC_ASSERT (G_SIZEOF_MEMBER (struct { char a; int b; }, a) == sizeof (char));
g_assert_cmpint (G_SIZEOF_MEMBER (struct { char a; int b; }, b), ==, sizeof (int));
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/alignof/fallback", test_alignof_fallback);
g_test_add_func ("/assert/static", test_assert_static);
g_test_add_func ("/struct/sizeof_member", test_struct_sizeof_member);
return g_test_run ();
}

2394
glib/tests/mainloop.c Normal file

File diff suppressed because it is too large Load diff

205
glib/tests/mappedfile.c Normal file
View file

@ -0,0 +1,205 @@
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <glib.h>
#include <string.h>
#include <glib/gstdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef G_OS_UNIX
#include <unistd.h>
#endif
#ifdef G_OS_WIN32
#include <io.h>
#endif
static void
test_basic (void)
{
GMappedFile *file;
GError *error;
error = NULL;
file = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "empty", NULL), FALSE, &error);
g_assert_no_error (error);
g_mapped_file_ref (file);
g_mapped_file_unref (file);
g_mapped_file_unref (file);
}
static void
test_empty (void)
{
GMappedFile *file;
GError *error;
error = NULL;
file = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "empty", NULL), FALSE, &error);
g_assert_no_error (error);
g_assert_null (g_mapped_file_get_contents (file));
g_mapped_file_free (file);
}
#ifdef G_OS_UNIX
static void
test_device (void)
{
GError *error = NULL;
GMappedFile *file;
file = g_mapped_file_new ("/dev/null", FALSE, &error);
g_assert_true (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_INVAL) ||
g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NODEV) ||
g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM));
g_assert_null (file);
g_error_free (error);
}
#endif
static void
test_nonexisting (void)
{
GMappedFile *file;
GError *error;
error = NULL;
file = g_mapped_file_new ("no-such-file", FALSE, &error);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_clear_error (&error);
g_assert_null (file);
}
static void
test_writable (void)
{
GMappedFile *file;
GError *error = NULL;
gchar *contents;
gsize len;
const gchar *old = "MMMMMMMMMMMMMMMMMMMMMMMMM";
const gchar *new = "abcdefghijklmnopqrstuvxyz";
gchar *tmp_copy_path;
tmp_copy_path = g_build_filename (g_get_tmp_dir (), "glib-test-4096-random-bytes", NULL);
g_file_get_contents (g_test_get_filename (G_TEST_DIST, "4096-random-bytes", NULL), &contents, &len, &error);
g_assert_no_error (error);
g_file_set_contents (tmp_copy_path, contents, len, &error);
g_assert_no_error (error);
g_free (contents);
file = g_mapped_file_new (tmp_copy_path, TRUE, &error);
g_assert_no_error (error);
contents = g_mapped_file_get_contents (file);
g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0);
memcpy (contents, new, strlen (new));
g_assert_cmpuint (strncmp (contents, new, strlen (new)), ==, 0);
g_mapped_file_free (file);
error = NULL;
file = g_mapped_file_new (tmp_copy_path, FALSE, &error);
g_assert_no_error (error);
contents = g_mapped_file_get_contents (file);
g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0);
g_mapped_file_free (file);
g_free (tmp_copy_path);
}
static void
test_writable_fd (void)
{
GMappedFile *file;
GError *error = NULL;
gchar *contents;
const gchar *old = "MMMMMMMMMMMMMMMMMMMMMMMMM";
const gchar *new = "abcdefghijklmnopqrstuvxyz";
gsize len;
int fd;
gchar *tmp_copy_path;
tmp_copy_path = g_build_filename (g_get_tmp_dir (), "glib-test-4096-random-bytes", NULL);
g_file_get_contents (g_test_get_filename (G_TEST_DIST, "4096-random-bytes", NULL), &contents, &len, &error);
g_assert_no_error (error);
g_file_set_contents (tmp_copy_path, contents, len, &error);
g_assert_no_error (error);
g_free (contents);
fd = g_open (tmp_copy_path, O_RDWR, 0);
g_assert_cmpint (fd, !=, -1);
file = g_mapped_file_new_from_fd (fd, TRUE, &error);
g_assert_no_error (error);
contents = g_mapped_file_get_contents (file);
g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0);
memcpy (contents, new, strlen (new));
g_assert_cmpuint (strncmp (contents, new, strlen (new)), ==, 0);
g_mapped_file_free (file);
close (fd);
error = NULL;
fd = g_open (tmp_copy_path, O_RDWR, 0);
g_assert_cmpint (fd, !=, -1);
file = g_mapped_file_new_from_fd (fd, TRUE, &error);
g_assert_no_error (error);
contents = g_mapped_file_get_contents (file);
g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0);
g_mapped_file_free (file);
g_free (tmp_copy_path);
}
static void
test_gbytes (void)
{
GMappedFile *file;
GBytes *bytes;
GError *error;
error = NULL;
file = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "empty", NULL), FALSE, &error);
g_assert_no_error (error);
bytes = g_mapped_file_get_bytes (file);
g_mapped_file_unref (file);
g_assert_cmpint (g_bytes_get_size (bytes), ==, 0);
g_bytes_unref (bytes);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/mappedfile/basic", test_basic);
g_test_add_func ("/mappedfile/empty", test_empty);
#ifdef G_OS_UNIX
g_test_add_func ("/mappedfile/device", test_device);
#endif
g_test_add_func ("/mappedfile/nonexisting", test_nonexisting);
g_test_add_func ("/mappedfile/writable", test_writable);
g_test_add_func ("/mappedfile/writable_fd", test_writable_fd);
g_test_add_func ("/mappedfile/gbytes", test_gbytes);
return g_test_run ();
}

Some files were not shown because too many files have changed in this diff Show more