bus: Assign a serial number for messages from the driver
[platform/upstream/dbus.git] / test / shell-test.c
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include <dbus/dbus-internals.h>
6 #include <dbus/dbus-list.h>
7 #include <dbus/dbus-memory.h>
8 #include <dbus/dbus-shell.h>
9 #include <dbus/dbus-string.h>
10 #include <dbus/dbus-sysdeps.h>
11
12 static int test_num = 0;
13 static int num_failed = 0;
14
15 static dbus_bool_t
16 test_command_line_internal (dbus_bool_t should_work,
17     const char *arg1,
18     va_list var_args)
19 {
20   int i, original_argc, shell_argc;
21   char **shell_argv;
22   char **original_argv;
23   char *command_line, *tmp;
24   DBusString str;
25   DBusList *list = NULL, *node;
26   DBusError error;
27
28   if (!_dbus_list_append (&list, (char *)arg1))
29     return FALSE;
30
31   do
32     {
33       tmp = va_arg (var_args, char *);
34       if (!tmp)
35         break;
36       if (!_dbus_list_append (&list, tmp))
37         {
38           _dbus_list_clear (&list);
39           return FALSE;
40         }
41     } while (tmp);
42
43   original_argc = _dbus_list_get_length (&list);
44   original_argv = dbus_new (char *, original_argc);
45   if (!_dbus_string_init (&str))
46     {
47       _dbus_list_clear (&list);
48       dbus_free (original_argv);
49       return FALSE;
50     }
51
52   for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node;
53        i++, node = _dbus_list_get_next_link (&list, node))
54     {
55       original_argv[i] = node->data;
56       if ((i > 0 && !_dbus_string_append_byte (&str, ' ')) ||
57           !_dbus_string_append (&str, original_argv[i]))
58         {
59           _dbus_list_clear (&list);
60           dbus_free (original_argv);
61           _dbus_string_free (&str);
62           return FALSE;
63         }
64     }
65   
66   _dbus_list_clear (&list);
67   command_line = _dbus_string_get_data (&str);
68   printf ("# Testing command line '%s'\n", command_line);
69
70   dbus_error_init (&error);
71   if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error))
72     {
73       printf ("# Error%s parsing command line: %s\n",
74           should_work ? "" : " (as expected)",
75           error.message ? error.message : "");
76       dbus_free (original_argv);
77       _dbus_string_free (&str);
78       return !should_work;
79     }
80   else
81     {
82       if (shell_argc != original_argc)
83         {
84           printf ("# Number of arguments returned (%d) don't match original (%d)\n",
85                   shell_argc, original_argc);
86           dbus_free (original_argv);
87           dbus_free_string_array (shell_argv);
88           return FALSE;
89         } 
90       printf ("# Number of arguments: %d\n", shell_argc);
91       for (i = 0; i < shell_argc; i++)
92         {
93           char *unquoted;
94           
95           unquoted = _dbus_shell_unquote (original_argv[i]);
96           if (strcmp (unquoted ? unquoted : "",
97                       shell_argv[i] ? shell_argv[i] : ""))
98             {
99               printf ("Position %d, returned argument (%s) does not match original (%s)\n",
100                       i, shell_argv[i], unquoted);
101               dbus_free (unquoted);
102               dbus_free (original_argv);
103               dbus_free_string_array (shell_argv);
104               return FALSE;
105             }
106           dbus_free (unquoted);
107           if (shell_argv[i])
108             printf ("Argument %d = %s\n", i, shell_argv[i]);
109         }
110       
111       dbus_free_string_array (shell_argv);
112     }
113
114   _dbus_string_free (&str);
115   dbus_free (original_argv);
116
117   if (!should_work)
118     {
119       printf ("# Expected an error\n");
120       return FALSE;
121     }
122
123   return TRUE;
124 }
125
126 static void
127 test_command_line (const char *arg1, ...)
128 {
129   va_list var_args;
130
131   va_start (var_args, arg1);
132
133   if (test_command_line_internal (TRUE, arg1, var_args))
134     {
135       printf ("ok %d\n", ++test_num);
136     }
137   else
138     {
139       printf ("not ok %d\n", ++test_num);
140       num_failed++;
141     }
142
143   va_end (var_args);
144 }
145
146 static void
147 test_command_line_fails (const char *arg1, ...)
148 {
149   va_list var_args;
150
151   va_start (var_args, arg1);
152
153   if (test_command_line_internal (FALSE, arg1, var_args))
154     {
155       printf ("ok %d\n", ++test_num);
156     }
157   else
158     {
159       printf ("not ok %d\n", ++test_num);
160       num_failed++;
161     }
162
163   va_end (var_args);
164 }
165
166 /* This test outputs TAP syntax: http://testanything.org/ */
167 int
168 main (int argc, char **argv)
169 {
170   test_command_line ("command", "-s", "--force-shutdown", "\"a string\"", "123", NULL);
171   test_command_line ("command", "-s", NULL);
172   test_command_line ("/opt/gnome/bin/service-start", NULL);
173   test_command_line ("grep", "-l", "-r", "-i", "'whatever'", "files*.c", NULL);
174   test_command_line ("/home/boston/johnp/devel-local/dbus/test/test-segfault", NULL);
175   test_command_line ("ls", "-l", "-a", "--colors", NULL);
176   test_command_line ("rsync-to-server", NULL);
177   test_command_line ("test-segfault", "--no-segfault", NULL);
178   test_command_line ("evolution", "mailto:pepe@cuco.com", NULL);
179   test_command_line ("run", "\"a \n multiline\"", NULL);
180   test_command_line_fails ("ls", "\"a wrong string'", NULL);
181
182   /* Tell the TAP driver that we have done all the tests we plan to do.
183    * This is how it can distinguish between an unexpected exit and
184    * successful completion. */
185   printf ("1..%d\n", test_num);
186
187   return (num_failed != 0);
188 }