summaryrefslogtreecommitdiff
path: root/tests/at-spi2-atk/atk_test_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/at-spi2-atk/atk_test_util.c')
-rw-r--r--tests/at-spi2-atk/atk_test_util.c187
1 files changed, 130 insertions, 57 deletions
diff --git a/tests/at-spi2-atk/atk_test_util.c b/tests/at-spi2-atk/atk_test_util.c
index 57f7098f..2af00135 100644
--- a/tests/at-spi2-atk/atk_test_util.c
+++ b/tests/at-spi2-atk/atk_test_util.c
@@ -23,8 +23,11 @@
#include "atk_test_util.h"
#include <signal.h>
+static AtspiEventListener *fixture_listener = NULL;
+static TestAppFixture *current_fixture = NULL;
+
static pid_t
-run_app (const char *file_name)
+run_app (const char *file_name, const char *name_to_claim)
{
pid_t child_pid = fork ();
if (child_pid == 0)
@@ -34,12 +37,10 @@ run_app (const char *file_name)
"--test-data-file",
file_name,
"--atspi-dbus-name",
- "org.a11y.Atspi2Atk.TestApplication",
+ name_to_claim,
NULL);
_exit (EXIT_SUCCESS);
}
- if (child_pid)
- fprintf (stderr, "child_pid %d\n", child_pid);
return child_pid;
}
@@ -47,113 +48,185 @@ run_app (const char *file_name)
static AtspiAccessible *
try_get_root_obj (AtspiAccessible *obj)
{
+ GError *error = NULL;
gchar *name;
int i;
- gint child_count = atspi_accessible_get_child_count (obj, NULL);
- if (child_count < 1)
+ gint child_count = atspi_accessible_get_child_count (obj, &error);
+ if (child_count < 0)
{
+ if (error)
+ {
+ g_print (" get_child_count: %s\n", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_print (" get_child_count=%d with no error\n", child_count);
+ }
+ return NULL;
+ }
+ else if (child_count < 1)
+ {
+ g_print (" child_count == %d, bailing out\n", child_count);
return NULL;
}
for (i = 0; i < child_count; i++)
{
- AtspiAccessible *child = atspi_accessible_get_child_at_index (obj, i, NULL);
+ AtspiAccessible *child = atspi_accessible_get_child_at_index (obj, i, &error);
if (!child)
- continue;
- if ((name = atspi_accessible_get_name (child, NULL)) != NULL)
+ {
+ if (error)
+ {
+ g_print (" getting child_at_index: %s\n", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_print (" getting child_at_index returned NULL child with no error\n");
+ }
+ continue;
+ }
+ if ((name = atspi_accessible_get_name (child, &error)) != NULL)
{
if (!strcmp (name, "root_object"))
{
g_free (name);
return child;
}
+ g_print (" name=%s\n", name);
g_free (name);
}
+ else
+ {
+ if (error)
+ {
+ g_print ("try_get_root_obj getting child name: %s\n", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_print (" get_name returned NULL name with no error\n");
+ }
+ }
g_object_unref (child);
}
return NULL;
}
+/* Callback from AtspiEventListener. We monitor children-changed on the root, so we can know
+ * when the helper test-application has launched and registered.
+ */
static void
-get_root_obj (const char *file_name, AtspiAccessible **out_root_obj, pid_t *out_child_pid)
+listener_event_cb (AtspiEvent *event, void *user_data)
{
- int tries = 0;
- AtspiAccessible *child;
- struct timespec timeout = { .tv_sec = 0, .tv_nsec = 10 * 1000000 };
- AtspiAccessible *obj = NULL;
- pid_t child_pid;
+ TestAppFixture *fixture = current_fixture;
- fprintf (stderr, "run_app: %s\n", file_name);
- child_pid = run_app (file_name);
- *out_child_pid = child_pid;
+ if (atspi_accessible_get_role (event->source, NULL) == ATSPI_ROLE_DESKTOP_FRAME && strstr (event->type, "add"))
+ {
+ AtspiAccessible *obj = atspi_get_desktop (0);
- obj = atspi_get_desktop (0);
+ fixture->root_obj = try_get_root_obj (obj);
- /* Wait for application to start, up to 100 times 10ms. */
- while (++tries <= 100)
- {
- child = try_get_root_obj (obj);
- if (child)
+ if (fixture->root_obj)
{
- *out_root_obj = child;
- return;
+ fixture->state = FIXTURE_STATE_CHILD_ACQUIRED;
+ atspi_event_quit ();
}
-
- nanosleep (&timeout, NULL);
}
+}
+
+/* Sets up the atspi event listener for the test-application helpers.
+ *
+ * We get notified when the test-application registers its root object by listening
+ * to the children-changed signal.
+ */
+void
+fixture_listener_init (void)
+{
+ GError *error = NULL;
- if (atspi_accessible_get_child_count (obj, NULL) < 1)
+ fixture_listener = atspi_event_listener_new (listener_event_cb, NULL, NULL);
+ if (!atspi_event_listener_register (fixture_listener, "object:children-changed", &error))
{
- g_test_message ("Fail, test application not found\n");
+ g_error ("Could not register event listener for children-changed: %s\n", error->message);
}
- else
+}
+
+void
+fixture_listener_destroy (void)
+{
+ GError *error = NULL;
+
+ if (!atspi_event_listener_deregister (fixture_listener, "object:children-changed", &error))
{
- g_test_message ("test object not found\n");
+ g_error ("Could not deregister event listener: %s", error->message);
}
- g_test_fail ();
- kill (child_pid, SIGTERM);
- *out_root_obj = NULL;
+
+ g_object_unref (fixture_listener);
+ fixture_listener = NULL;
+}
+
+static gboolean
+wait_for_test_app_timeout_cb (gpointer user_data)
+{
+ TestAppFixture *fixture = user_data;
+
+ fixture->test_app_timed_out = TRUE;
+ atspi_event_quit ();
+
+ return FALSE;
}
+/* Each of the helper programs with the test fixtures claims a different DBus name,
+ * to make them non-ambiguous when they get restarted all the time. This is the serial
+ * number that gets appended to each name.
+ */
+static guint fixture_serial = 0;
+
void
fixture_setup (TestAppFixture *fixture, gconstpointer user_data)
{
const char *file_name = user_data;
- pid_t child_pid;
- AtspiAccessible *root_obj;
- get_root_obj (file_name, &root_obj, &child_pid);
- g_assert (root_obj != NULL);
+ fixture->state = FIXTURE_STATE_WAITING_FOR_CHILD;
+ fixture->name_to_claim = g_strdup_printf ("org.a11y.Atspi2Atk.TestApplication_%u", fixture_serial);
+ fixture_serial += 1;
+
+ fixture->child_pid = run_app (file_name, fixture->name_to_claim);
+
+ fixture->test_app_timed_out = FALSE;
+ fixture->wait_for_test_app_timeout = g_timeout_add (500, wait_for_test_app_timeout_cb, fixture); /* 500 msec */
+
+ current_fixture = fixture;
+ atspi_event_main ();
- fixture->child_pid = child_pid;
- fixture->root_obj = root_obj;
+ g_source_remove (fixture->wait_for_test_app_timeout);
+ fixture->wait_for_test_app_timeout = 0;
+
+ if (fixture->test_app_timed_out)
+ {
+ g_print ("test app timed out before registering its root object");
+ g_test_fail ();
+ }
}
void
fixture_teardown (TestAppFixture *fixture, gconstpointer user_data)
{
- int tries = 0;
-
- AtspiAccessible *child;
- struct timespec timeout = { .tv_sec = 0, .tv_nsec = 10 * 1000000 };
- AtspiAccessible *obj = NULL;
+ current_fixture = NULL;
kill (fixture->child_pid, SIGTERM);
+ fixture->child_pid = -1;
- obj = atspi_get_desktop (0);
-
- /* Wait for application to stop, up to 100 times 10ms. */
- while (++tries <= 100)
+ if (fixture->root_obj)
{
- child = try_get_root_obj (obj);
- if (child == NULL)
- return;
-
- nanosleep (&timeout, NULL);
+ g_object_unref (fixture->root_obj);
+ fixture->root_obj = NULL;
}
- g_test_message ("Fail, test application still running\n");
- g_test_fail ();
+ g_free (fixture->name_to_claim);
+ fixture->name_to_claim = NULL;
}