/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* unit-test-dh.c: Test egg-spawn.c
Copyright (C) 2009 Stefan Walter
The Gnome Keyring Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Keyring 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
.
Author: Stef Walter
*/
#include "config.h"
#include "egg/egg-spawn.h"
#include "egg/egg-testing.h"
#include
#include
#include
#include
#include
#include
typedef struct _EchoData {
gint index;
gchar *output;
gchar *error;
gboolean finalized;
gboolean completed;
gboolean is_async;
pid_t parent_pid;
} EchoData;
static gboolean
want_input (gint fd, gpointer user_data)
{
EchoData *data = user_data;
gchar *buffer;
g_assert (data);
if (data->index == 85)
return FALSE;
g_assert (data->index >= 80);
g_assert (data->index < 85);
buffer = g_strdup_printf ("%d\n", data->index);
if (egg_spawn_write_input (fd, (guchar*)buffer, strlen (buffer)) < 0)
g_assert_not_reached ();
g_free (buffer);
++data->index;
return TRUE;
}
static gboolean
have_output (gint fd, gpointer user_data)
{
EchoData *data = user_data;
gchar buffer[1024];
gssize length;
gchar *output;
g_assert (data);
length = egg_spawn_read_output (fd, (guchar*)buffer, 1023);
g_assert (length >= 0);
buffer[length] = 0;
output = g_strconcat (data->output ? data->output : "", buffer, NULL);
g_free (data->output);
data->output = output;
return (length > 0);
}
static gboolean
have_error (gint fd, gpointer user_data)
{
EchoData *data = user_data;
gchar buffer[1024];
gssize length;
gchar *error;
g_assert (data);
length = egg_spawn_read_output (fd, (guchar*)buffer, 1023);
g_assert (length >= 0);
buffer[length] = 0;
error = g_strconcat (data->error ? data->error : "", buffer, NULL);
g_free (data->error);
data->error = error;
return (length > 0);
}
static void
completed_func (gpointer user_data)
{
EchoData *data = user_data;
g_assert (data);
g_assert (!data->finalized);
g_assert (!data->completed);
data->completed = TRUE;
if (data->is_async)
egg_test_wait_stop ();
}
static void
finalize_func (gpointer user_data)
{
EchoData *data = user_data;
g_assert (!data->finalized);
data->finalized = 1;
}
static void
child_setup (gpointer user_data)
{
EchoData *data = user_data;
g_assert (data->parent_pid != getpid ());
}
static EggSpawnCallbacks echo_callbacks = {
want_input,
have_output,
have_error,
completed_func,
finalize_func,
child_setup,
};
static char* echo_argv[] = {
"/bin/sh",
"./echo-script.sh",
NULL
};
static char* error_argv[] = {
"/nonexistent",
NULL
};
static EggSpawnCallbacks null_callbacks = {
NULL,
NULL,
NULL,
completed_func,
finalize_func,
child_setup,
};
static void
test_sync (void)
{
GError *error = NULL;
gboolean ret;
gint exit_status;
EchoData data;
GPid pid = 0;
memset (&data, 0, sizeof (data));
data.parent_pid = getpid();
data.index = 80;
ret = egg_spawn_sync_with_callbacks (SRCDIR "/egg/fixtures",
echo_argv, NULL, 0, &pid,
&echo_callbacks, &data,
&exit_status, &error);
g_assert (ret == TRUE);
g_assert (pid != 0);
g_assert (WIFEXITED (exit_status));
g_assert_cmpint (WEXITSTATUS(exit_status), ==, 3);
g_assert (error == NULL);
g_assert (data.finalized);
g_assert (data.completed);
g_assert_cmpstr (data.output, ==, "80 81 82 83 84\n");
g_assert_cmpstr (data.error, ==, "1\n2\n3\n4\n5\n");
}
static void
test_sync_error (void)
{
GError *error = NULL;
gboolean ret;
ret = egg_spawn_sync_with_callbacks (SRCDIR "/egg/fixtures",
error_argv, NULL, 0, NULL,
NULL, NULL,
NULL, &error);
g_assert (ret == FALSE);
g_assert (error != NULL);
g_clear_error (&error);
}
static void
test_async (void)
{
GError *error = NULL;
EchoData data;
guint ret;
GPid pid;
memset (&data, 0, sizeof (data));
data.parent_pid = getpid();
data.index = 80;
data.is_async = TRUE;
ret = egg_spawn_async_with_callbacks (SRCDIR "/egg/fixtures",
echo_argv, NULL, 0, &pid,
&echo_callbacks, &data,
NULL, &error);
g_assert (ret != 0);
g_assert (error == NULL);
g_assert (!data.finalized);
egg_test_wait_until (2000);
g_assert (data.finalized);
g_assert (data.completed);
g_assert_cmpstr (data.output, ==, "80 81 82 83 84\n");
g_assert_cmpstr (data.error, ==, "1\n2\n3\n4\n5\n");
}
static void
test_async_none (void)
{
GError *error = NULL;
EchoData data;
guint ret;
memset (&data, 0, sizeof (data));
data.parent_pid = getpid();
data.is_async = TRUE;
ret = egg_spawn_async_with_callbacks (SRCDIR "/egg/fixtures",
echo_argv, NULL, 0, NULL,
&null_callbacks, &data,
NULL, &error);
g_assert (ret != 0);
g_assert (error == NULL);
g_assert (!data.finalized);
egg_test_wait_until (2000);
g_assert (data.finalized);
g_assert (data.completed);
g_assert (!data.output);
}
static void
test_async_error (void)
{
GError *error = NULL;
guint ret;
ret = egg_spawn_async_with_callbacks (SRCDIR "/egg/fixtures",
error_argv, NULL, 0, NULL,
NULL, NULL,
NULL, &error);
g_assert (ret == 0);
g_assert (error != NULL);
g_clear_error (&error);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/spawn/sync", test_sync);
g_test_add_func ("/spawn/sync_error", test_sync_error);
g_test_add_func ("/spawn/async", test_async);
g_test_add_func ("/spawn/async_none", test_async_none);
g_test_add_func ("/spawn/async_error", test_async_error);
return egg_tests_run_in_thread_with_loop ();
}