1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
4  *
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include <signal.h>
24 #include "atk_test_util.h"
25 
26 pid_t child_pid;
27 
assert_clean_exit(int sig)28 static void assert_clean_exit (int sig)
29 {
30   kill (child_pid, SIGTERM);
31 }
32 
clean_exit_on_fail()33 void clean_exit_on_fail ()
34 {
35   signal (SIGABRT, assert_clean_exit);
36 }
37 
38 void
run_app(const char * file_name)39 run_app (const char *file_name)
40 {
41   child_pid = fork ();
42   if (child_pid == 0) {
43     execlp (TESTS_BUILD_DIR "/app-test",
44             TESTS_BUILD_DIR "/app-test",
45             "--test-data-file",
46             file_name,
47             NULL);
48     _exit (EXIT_SUCCESS);
49   }
50   if (child_pid) fprintf(stderr, "child_pid %d\n", child_pid);
51 }
52 
try_get_root_obj(AtspiAccessible * obj)53 static AtspiAccessible *try_get_root_obj (AtspiAccessible *obj)
54 {
55   int i;
56 
57   gint child_count = atspi_accessible_get_child_count (obj, NULL);
58   if (child_count < 1) {
59     return NULL;
60   }
61 
62   for (i=0; i<child_count; i++) {
63     AtspiAccessible *child = atspi_accessible_get_child_at_index (obj,i, NULL);
64     if (child && !strcmp (atspi_accessible_get_name (child, NULL), "root_object"))
65       return child;
66   }
67 
68   return NULL;
69 }
70 
get_root_obj(const char * file_name)71 AtspiAccessible * get_root_obj (const char *file_name)
72 {
73   int tries = 0;
74   AtspiAccessible *child;
75   struct timespec timeout = { .tv_sec = 0, .tv_nsec = 10 * 1000000 };
76   AtspiAccessible *obj = NULL;
77 
78   fprintf(stderr, "run_app: %s\n", file_name);
79   run_app (file_name);
80 
81   obj = atspi_get_desktop (0);
82 
83   /* Wait for application to start, up to 100 times 10ms.  */
84   while (++tries <= 100)
85   {
86     child = try_get_root_obj (obj);
87     if (child)
88       return child;
89 
90     nanosleep(&timeout, NULL);
91   }
92 
93   if (atspi_accessible_get_child_count (obj, NULL) < 1) {
94     g_test_message ("Fail, test application not found\n");
95   } else {
96     g_test_message ("test object not found\n");
97   }
98   g_test_fail ();
99   kill (child_pid, SIGTERM);
100   return NULL;
101 }
102 
terminate_app(void)103 void terminate_app (void)
104 {
105   int tries = 0;
106 
107   AtspiAccessible *child;
108   struct timespec timeout = { .tv_sec = 0, .tv_nsec = 10 * 1000000 };
109   AtspiAccessible *obj = NULL;
110 
111   kill (child_pid, SIGTERM);
112 
113   obj = atspi_get_desktop (0);
114 
115   /* Wait for application to stop, up to 100 times 10ms.  */
116   while (++tries <= 100)
117   {
118     child = try_get_root_obj (obj);
119     if (child == NULL)
120       return;
121 
122     nanosleep(&timeout, NULL);
123   }
124 
125   g_test_message ("Fail, test application still running\n");
126   g_test_fail ();
127 }
128