xref: /netbsd-src/external/mit/libuv/dist/test/run-tests.c (revision 5f2f42719cd62ff11fd913b40b7ce19f07c4fd25)
10e552da7Schristos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
20e552da7Schristos  *
30e552da7Schristos  * Permission is hereby granted, free of charge, to any person obtaining a copy
40e552da7Schristos  * of this software and associated documentation files (the "Software"), to
50e552da7Schristos  * deal in the Software without restriction, including without limitation the
60e552da7Schristos  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
70e552da7Schristos  * sell copies of the Software, and to permit persons to whom the Software is
80e552da7Schristos  * furnished to do so, subject to the following conditions:
90e552da7Schristos  *
100e552da7Schristos  * The above copyright notice and this permission notice shall be included in
110e552da7Schristos  * all copies or substantial portions of the Software.
120e552da7Schristos  *
130e552da7Schristos  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
140e552da7Schristos  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
150e552da7Schristos  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
160e552da7Schristos  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
170e552da7Schristos  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
180e552da7Schristos  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
190e552da7Schristos  * IN THE SOFTWARE.
200e552da7Schristos  */
210e552da7Schristos 
220e552da7Schristos #include <errno.h>
230e552da7Schristos #include <stdio.h>
240e552da7Schristos #include <string.h>
250e552da7Schristos 
260e552da7Schristos #ifdef _WIN32
270e552da7Schristos # include <io.h>
280e552da7Schristos #else
290e552da7Schristos # include <unistd.h>
300e552da7Schristos #endif
310e552da7Schristos 
320e552da7Schristos #include "uv.h"
330e552da7Schristos #include "runner.h"
340e552da7Schristos #include "task.h"
350e552da7Schristos 
360e552da7Schristos /* Actual tests and helpers are defined in test-list.h */
370e552da7Schristos #include "test-list.h"
380e552da7Schristos 
39*5f2f4271Schristos #ifdef __MVS__
40*5f2f4271Schristos #include "zos-base.h"
41*5f2f4271Schristos /* Initialize environment and zoslib */
init()42*5f2f4271Schristos __attribute__((constructor)) void init() {
43*5f2f4271Schristos   zoslib_config_t config;
44*5f2f4271Schristos   init_zoslib_config(&config);
45*5f2f4271Schristos   init_zoslib(config);
46*5f2f4271Schristos }
47*5f2f4271Schristos #endif
48*5f2f4271Schristos 
490e552da7Schristos int ipc_helper(int listen_after_write);
500e552da7Schristos int ipc_helper_heavy_traffic_deadlock_bug(void);
510e552da7Schristos int ipc_helper_tcp_connection(void);
520e552da7Schristos int ipc_send_recv_helper(void);
530e552da7Schristos int ipc_helper_bind_twice(void);
540e552da7Schristos int ipc_helper_send_zero(void);
550e552da7Schristos int stdio_over_pipes_helper(void);
560e552da7Schristos void spawn_stdin_stdout(void);
570e552da7Schristos void process_title_big_argv(void);
580e552da7Schristos int spawn_tcp_server_helper(void);
590e552da7Schristos 
600e552da7Schristos static int maybe_run_test(int argc, char **argv);
610e552da7Schristos 
62*5f2f4271Schristos #ifdef _WIN32
63*5f2f4271Schristos typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
64*5f2f4271Schristos #endif
65*5f2f4271Schristos 
660e552da7Schristos 
main(int argc,char ** argv)670e552da7Schristos int main(int argc, char **argv) {
680e552da7Schristos #ifndef _WIN32
690e552da7Schristos   if (0 == geteuid() && NULL == getenv("UV_RUN_AS_ROOT")) {
700e552da7Schristos     fprintf(stderr, "The libuv test suite cannot be run as root.\n");
710e552da7Schristos     return EXIT_FAILURE;
720e552da7Schristos   }
730e552da7Schristos #endif
740e552da7Schristos 
750e552da7Schristos   platform_init(argc, argv);
760e552da7Schristos   argv = uv_setup_args(argc, argv);
770e552da7Schristos 
780e552da7Schristos   switch (argc) {
790e552da7Schristos   case 1: return run_tests(0);
800e552da7Schristos   case 2: return maybe_run_test(argc, argv);
810e552da7Schristos   case 3: return run_test_part(argv[1], argv[2]);
820e552da7Schristos   case 4: return maybe_run_test(argc, argv);
830e552da7Schristos   default:
840e552da7Schristos     fprintf(stderr, "Too many arguments.\n");
850e552da7Schristos     fflush(stderr);
860e552da7Schristos     return EXIT_FAILURE;
870e552da7Schristos   }
880e552da7Schristos 
890e552da7Schristos #ifndef __SUNPRO_C
900e552da7Schristos   return EXIT_SUCCESS;
910e552da7Schristos #endif
920e552da7Schristos }
930e552da7Schristos 
940e552da7Schristos 
maybe_run_test(int argc,char ** argv)950e552da7Schristos static int maybe_run_test(int argc, char **argv) {
960e552da7Schristos   if (strcmp(argv[1], "--list") == 0) {
970e552da7Schristos     print_tests(stdout);
980e552da7Schristos     return 0;
990e552da7Schristos   }
1000e552da7Schristos 
1010e552da7Schristos   if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
1020e552da7Schristos     return ipc_helper(0);
1030e552da7Schristos   }
1040e552da7Schristos 
1050e552da7Schristos   if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
1060e552da7Schristos     return ipc_helper(1);
1070e552da7Schristos   }
1080e552da7Schristos 
1090e552da7Schristos   if (strcmp(argv[1], "ipc_helper_heavy_traffic_deadlock_bug") == 0) {
1100e552da7Schristos     return ipc_helper_heavy_traffic_deadlock_bug();
1110e552da7Schristos   }
1120e552da7Schristos 
1130e552da7Schristos   if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
1140e552da7Schristos     return ipc_send_recv_helper();
1150e552da7Schristos   }
1160e552da7Schristos 
1170e552da7Schristos   if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) {
1180e552da7Schristos     return ipc_helper_tcp_connection();
1190e552da7Schristos   }
1200e552da7Schristos 
1210e552da7Schristos   if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) {
1220e552da7Schristos     return ipc_helper_bind_twice();
1230e552da7Schristos   }
1240e552da7Schristos 
1250e552da7Schristos   if (strcmp(argv[1], "ipc_helper_send_zero") == 0) {
1260e552da7Schristos     return ipc_helper_send_zero();
1270e552da7Schristos   }
1280e552da7Schristos 
1290e552da7Schristos   if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
1300e552da7Schristos     return stdio_over_pipes_helper();
1310e552da7Schristos   }
1320e552da7Schristos 
1330e552da7Schristos   if (strcmp(argv[1], "spawn_helper1") == 0) {
1340e552da7Schristos     notify_parent_process();
1350e552da7Schristos     return 1;
1360e552da7Schristos   }
1370e552da7Schristos 
1380e552da7Schristos   if (strcmp(argv[1], "spawn_helper2") == 0) {
1390e552da7Schristos     notify_parent_process();
1400e552da7Schristos     printf("hello world\n");
1410e552da7Schristos     return 1;
1420e552da7Schristos   }
1430e552da7Schristos 
1440e552da7Schristos   if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) {
1450e552da7Schristos     notify_parent_process();
1460e552da7Schristos     return spawn_tcp_server_helper();
1470e552da7Schristos   }
1480e552da7Schristos 
1490e552da7Schristos   if (strcmp(argv[1], "spawn_helper3") == 0) {
1500e552da7Schristos     char buffer[256];
1510e552da7Schristos     notify_parent_process();
1520e552da7Schristos     ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
1530e552da7Schristos     buffer[sizeof(buffer) - 1] = '\0';
1540e552da7Schristos     fputs(buffer, stdout);
1550e552da7Schristos     return 1;
1560e552da7Schristos   }
1570e552da7Schristos 
1580e552da7Schristos   if (strcmp(argv[1], "spawn_helper4") == 0) {
1590e552da7Schristos     notify_parent_process();
1600e552da7Schristos     /* Never surrender, never return! */
161*5f2f4271Schristos     for (;;) uv_sleep(10000);
1620e552da7Schristos   }
1630e552da7Schristos 
1640e552da7Schristos   if (strcmp(argv[1], "spawn_helper5") == 0) {
1650e552da7Schristos     const char out[] = "fourth stdio!\n";
1660e552da7Schristos     notify_parent_process();
1670e552da7Schristos     {
1680e552da7Schristos #ifdef _WIN32
1690e552da7Schristos       DWORD bytes;
1700e552da7Schristos       WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
1710e552da7Schristos #else
1720e552da7Schristos       ssize_t r;
1730e552da7Schristos 
1740e552da7Schristos       do
1750e552da7Schristos         r = write(3, out, sizeof(out) - 1);
1760e552da7Schristos       while (r == -1 && errno == EINTR);
1770e552da7Schristos 
1780e552da7Schristos       fsync(3);
1790e552da7Schristos #endif
1800e552da7Schristos     }
1810e552da7Schristos     return 1;
1820e552da7Schristos   }
1830e552da7Schristos 
1840e552da7Schristos   if (strcmp(argv[1], "spawn_helper6") == 0) {
1850e552da7Schristos     int r;
1860e552da7Schristos 
1870e552da7Schristos     notify_parent_process();
1880e552da7Schristos 
1890e552da7Schristos     r = fprintf(stdout, "hello world\n");
1900e552da7Schristos     ASSERT(r > 0);
1910e552da7Schristos 
1920e552da7Schristos     r = fprintf(stderr, "hello errworld\n");
1930e552da7Schristos     ASSERT(r > 0);
1940e552da7Schristos 
1950e552da7Schristos     return 1;
1960e552da7Schristos   }
1970e552da7Schristos 
1980e552da7Schristos   if (strcmp(argv[1], "spawn_helper7") == 0) {
1990e552da7Schristos     int r;
2000e552da7Schristos     char *test;
2010e552da7Schristos 
2020e552da7Schristos     notify_parent_process();
2030e552da7Schristos 
2040e552da7Schristos     /* Test if the test value from the parent is still set */
2050e552da7Schristos     test = getenv("ENV_TEST");
206*5f2f4271Schristos     ASSERT_NOT_NULL(test);
2070e552da7Schristos 
2080e552da7Schristos     r = fprintf(stdout, "%s", test);
2090e552da7Schristos     ASSERT(r > 0);
2100e552da7Schristos 
2110e552da7Schristos     return 1;
2120e552da7Schristos   }
2130e552da7Schristos 
2140e552da7Schristos   if (strcmp(argv[1], "spawn_helper8") == 0) {
215*5f2f4271Schristos     uv_os_fd_t closed_fd;
216*5f2f4271Schristos     uv_os_fd_t open_fd;
217*5f2f4271Schristos #ifdef _WIN32
218*5f2f4271Schristos     DWORD flags;
219*5f2f4271Schristos     HMODULE kernelbase_module;
220*5f2f4271Schristos     sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
221*5f2f4271Schristos #endif
2220e552da7Schristos     notify_parent_process();
223*5f2f4271Schristos     ASSERT(sizeof(closed_fd) == read(0, &closed_fd, sizeof(closed_fd)));
224*5f2f4271Schristos     ASSERT(sizeof(open_fd) == read(0, &open_fd, sizeof(open_fd)));
225*5f2f4271Schristos #ifdef _WIN32
226*5f2f4271Schristos     ASSERT((intptr_t) closed_fd > 0);
227*5f2f4271Schristos     ASSERT((intptr_t) open_fd > 0);
228*5f2f4271Schristos     ASSERT(0 != GetHandleInformation(open_fd, &flags));
229*5f2f4271Schristos     kernelbase_module = GetModuleHandleA("kernelbase.dll");
230*5f2f4271Schristos     pCompareObjectHandles = (sCompareObjectHandles)
231*5f2f4271Schristos         GetProcAddress(kernelbase_module, "CompareObjectHandles");
232*5f2f4271Schristos     ASSERT(pCompareObjectHandles == NULL || !pCompareObjectHandles(open_fd, closed_fd));
2330e552da7Schristos #else
234*5f2f4271Schristos     ASSERT(open_fd > 2);
235*5f2f4271Schristos     ASSERT(closed_fd > 2);
236*5f2f4271Schristos # if defined(__PASE__)  /* On IBMi PASE, write() returns 1 */
237*5f2f4271Schristos     ASSERT(1 == write(closed_fd, "x", 1));
238*5f2f4271Schristos # else
239*5f2f4271Schristos     ASSERT(-1 == write(closed_fd, "x", 1));
2400e552da7Schristos # endif  /* !__PASE__ */
241*5f2f4271Schristos #endif
2420e552da7Schristos     return 1;
2430e552da7Schristos   }
2440e552da7Schristos 
2450e552da7Schristos   if (strcmp(argv[1], "spawn_helper9") == 0) {
2460e552da7Schristos     notify_parent_process();
2470e552da7Schristos     spawn_stdin_stdout();
2480e552da7Schristos     return 1;
2490e552da7Schristos   }
2500e552da7Schristos 
2510e552da7Schristos #ifndef _WIN32
2520e552da7Schristos   if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) {
2530e552da7Schristos     uv_uid_t uid = atoi(argv[2]);
2540e552da7Schristos     uv_gid_t gid = atoi(argv[3]);
2550e552da7Schristos 
2560e552da7Schristos     ASSERT(uid == getuid());
2570e552da7Schristos     ASSERT(gid == getgid());
2580e552da7Schristos     notify_parent_process();
2590e552da7Schristos 
2600e552da7Schristos     return 1;
2610e552da7Schristos   }
2620e552da7Schristos #endif  /* !_WIN32 */
2630e552da7Schristos 
2640e552da7Schristos   if (strcmp(argv[1], "process_title_big_argv_helper") == 0) {
2650e552da7Schristos     notify_parent_process();
2660e552da7Schristos     process_title_big_argv();
2670e552da7Schristos     return 0;
2680e552da7Schristos   }
2690e552da7Schristos 
2700e552da7Schristos   return run_test(argv[1], 0, 1);
2710e552da7Schristos }
272