1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #ifdef _WIN32
27 # include <io.h>
28 #else
29 # include <unistd.h>
30 #endif
31
32 #include "uv.h"
33 #include "runner.h"
34 #include "task.h"
35
36 /* Actual tests and helpers are defined in test-list.h */
37 #include "test-list.h"
38
39 int ipc_helper(int listen_after_write);
40 int ipc_helper_heavy_traffic_deadlock_bug(void);
41 int ipc_helper_tcp_connection(void);
42 int ipc_helper_closed_handle(void);
43 int ipc_send_recv_helper(void);
44 int ipc_helper_bind_twice(void);
45 int ipc_helper_send_zero(void);
46 int stdio_over_pipes_helper(void);
47 void spawn_stdin_stdout(void);
48 void process_title_big_argv(void);
49 int spawn_tcp_server_helper(void);
50
51 static int maybe_run_test(int argc, char **argv);
52
53
main(int argc,char ** argv)54 int main(int argc, char **argv) {
55 #ifndef _WIN32
56 if (0 == geteuid() && NULL == getenv("UV_RUN_AS_ROOT")) {
57 fprintf(stderr, "The libuv test suite cannot be run as root.\n");
58 return EXIT_FAILURE;
59 }
60 #endif
61
62 if (platform_init(argc, argv))
63 return EXIT_FAILURE;
64
65 argv = uv_setup_args(argc, argv);
66
67 switch (argc) {
68 case 1: return run_tests(0);
69 case 2: return maybe_run_test(argc, argv);
70 case 3: return run_test_part(argv[1], argv[2]);
71 case 4: return maybe_run_test(argc, argv);
72 default:
73 fprintf(stderr, "Too many arguments.\n");
74 fflush(stderr);
75 return EXIT_FAILURE;
76 }
77
78 #ifndef __SUNPRO_C
79 return EXIT_SUCCESS;
80 #endif
81 }
82
83
maybe_run_test(int argc,char ** argv)84 static int maybe_run_test(int argc, char **argv) {
85 if (strcmp(argv[1], "--list") == 0) {
86 print_tests(stdout);
87 return 0;
88 }
89
90 if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
91 return ipc_helper(0);
92 }
93
94 if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
95 return ipc_helper(1);
96 }
97
98 if (strcmp(argv[1], "ipc_helper_heavy_traffic_deadlock_bug") == 0) {
99 return ipc_helper_heavy_traffic_deadlock_bug();
100 }
101
102 if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
103 return ipc_send_recv_helper();
104 }
105
106 if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) {
107 return ipc_helper_tcp_connection();
108 }
109
110 if (strcmp(argv[1], "ipc_helper_closed_handle") == 0) {
111 return ipc_helper_closed_handle();
112 }
113
114 if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) {
115 return ipc_helper_bind_twice();
116 }
117
118 if (strcmp(argv[1], "ipc_helper_send_zero") == 0) {
119 return ipc_helper_send_zero();
120 }
121
122 if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
123 return stdio_over_pipes_helper();
124 }
125
126 if (strcmp(argv[1], "spawn_helper1") == 0) {
127 notify_parent_process();
128 return 1;
129 }
130
131 if (strcmp(argv[1], "spawn_helper2") == 0) {
132 notify_parent_process();
133 printf("hello world\n");
134 return 1;
135 }
136
137 if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) {
138 notify_parent_process();
139 return spawn_tcp_server_helper();
140 }
141
142 if (strcmp(argv[1], "spawn_helper3") == 0) {
143 char buffer[256];
144 notify_parent_process();
145 ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
146 buffer[sizeof(buffer) - 1] = '\0';
147 fputs(buffer, stdout);
148 return 1;
149 }
150
151 if (strcmp(argv[1], "spawn_helper4") == 0) {
152 notify_parent_process();
153 /* Never surrender, never return! */
154 while (1) uv_sleep(10000);
155 }
156
157 if (strcmp(argv[1], "spawn_helper5") == 0) {
158 const char out[] = "fourth stdio!\n";
159 notify_parent_process();
160 {
161 #ifdef _WIN32
162 DWORD bytes;
163 WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
164 #else
165 ssize_t r;
166
167 do
168 r = write(3, out, sizeof(out) - 1);
169 while (r == -1 && errno == EINTR);
170
171 fsync(3);
172 #endif
173 }
174 return 1;
175 }
176
177 if (strcmp(argv[1], "spawn_helper6") == 0) {
178 int r;
179
180 notify_parent_process();
181
182 r = fprintf(stdout, "hello world\n");
183 ASSERT(r > 0);
184
185 r = fprintf(stderr, "hello errworld\n");
186 ASSERT(r > 0);
187
188 return 1;
189 }
190
191 if (strcmp(argv[1], "spawn_helper7") == 0) {
192 int r;
193 char *test;
194
195 notify_parent_process();
196
197 /* Test if the test value from the parent is still set */
198 test = getenv("ENV_TEST");
199 ASSERT(test != NULL);
200
201 r = fprintf(stdout, "%s", test);
202 ASSERT(r > 0);
203
204 return 1;
205 }
206
207 #ifndef _WIN32
208 if (strcmp(argv[1], "spawn_helper8") == 0) {
209 int fd;
210
211 notify_parent_process();
212 ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd)));
213 ASSERT(fd > 2);
214 # if defined(__PASE__) /* On IBMi PASE, write() returns 1 */
215 ASSERT(1 == write(fd, "x", 1));
216 # else
217 ASSERT(-1 == write(fd, "x", 1));
218 # endif /* !__PASE__ */
219
220 return 1;
221 }
222 #endif /* !_WIN32 */
223
224 if (strcmp(argv[1], "spawn_helper9") == 0) {
225 notify_parent_process();
226 spawn_stdin_stdout();
227 return 1;
228 }
229
230 #ifndef _WIN32
231 if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) {
232 uv_uid_t uid = atoi(argv[2]);
233 uv_gid_t gid = atoi(argv[3]);
234
235 ASSERT(uid == getuid());
236 ASSERT(gid == getgid());
237 notify_parent_process();
238
239 return 1;
240 }
241 #endif /* !_WIN32 */
242
243 if (strcmp(argv[1], "process_title_big_argv_helper") == 0) {
244 notify_parent_process();
245 process_title_big_argv();
246 return 0;
247 }
248
249 return run_test(argv[1], 0, 1);
250 }
251