Home | History | Annotate | Line # | Download | only in test
      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 # define read _read
     29 #else
     30 # include <unistd.h>
     31 #endif
     32 
     33 #include "uv.h"
     34 #include "runner.h"
     35 #include "task.h"
     36 
     37 /* Actual tests and helpers are defined in test-list.h */
     38 #include "test-list.h"
     39 
     40 #ifdef __MVS__
     41 #include "zos-base.h"
     42 /* Initialize environment and zoslib */
     43 __attribute__((constructor)) void init() {
     44   zoslib_config_t config;
     45   init_zoslib_config(&config);
     46   init_zoslib(config);
     47 }
     48 #endif
     49 
     50 int ipc_helper(int listen_after_write);
     51 int ipc_helper_heavy_traffic_deadlock_bug(void);
     52 int ipc_helper_tcp_connection(void);
     53 int ipc_send_recv_helper(void);
     54 int ipc_helper_bind_twice(void);
     55 int ipc_helper_send_zero(void);
     56 int stdio_over_pipes_helper(void);
     57 void spawn_stdin_stdout(void);
     58 void process_title_big_argv(void);
     59 int spawn_tcp_server_helper(void);
     60 
     61 static int maybe_run_test(int argc, char **argv);
     62 
     63 #ifdef _WIN32
     64 typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
     65 #endif
     66 
     67 
     68 int main(int argc, char **argv) {
     69 #ifndef _WIN32
     70   if (0 == geteuid() && NULL == getenv("UV_RUN_AS_ROOT")) {
     71     fprintf(stderr, "The libuv test suite cannot be run as root.\n");
     72     return EXIT_FAILURE;
     73   }
     74 #endif
     75 
     76   platform_init(argc, argv);
     77   argv = uv_setup_args(argc, argv);
     78 
     79   switch (argc) {
     80   case 1: return run_tests(0);
     81   case 2: return maybe_run_test(argc, argv);
     82   case 3: return run_test_part(argv[1], argv[2]);
     83   case 4: return maybe_run_test(argc, argv);
     84   default:
     85     fprintf(stderr, "Too many arguments.\n");
     86     fflush(stderr);
     87     return EXIT_FAILURE;
     88   }
     89 }
     90 
     91 
     92 static int maybe_run_test(int argc, char **argv) {
     93   if (strcmp(argv[1], "--list") == 0) {
     94     print_tests(stdout);
     95     return 0;
     96   }
     97 
     98   if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
     99     return ipc_helper(0);
    100   }
    101 
    102   if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
    103     return ipc_helper(1);
    104   }
    105 
    106   if (strcmp(argv[1], "ipc_helper_heavy_traffic_deadlock_bug") == 0) {
    107     return ipc_helper_heavy_traffic_deadlock_bug();
    108   }
    109 
    110   if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
    111     return ipc_send_recv_helper();
    112   }
    113 
    114   if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) {
    115     return ipc_helper_tcp_connection();
    116   }
    117 
    118   if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) {
    119     return ipc_helper_bind_twice();
    120   }
    121 
    122   if (strcmp(argv[1], "ipc_helper_send_zero") == 0) {
    123     return ipc_helper_send_zero();
    124   }
    125 
    126   if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
    127     return stdio_over_pipes_helper();
    128   }
    129 
    130   if (strcmp(argv[1], "spawn_helper1") == 0) {
    131     notify_parent_process();
    132     return 1;
    133   }
    134 
    135   if (strcmp(argv[1], "spawn_helper2") == 0) {
    136     notify_parent_process();
    137     printf("hello world\n");
    138     return 1;
    139   }
    140 
    141   if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) {
    142     notify_parent_process();
    143     return spawn_tcp_server_helper();
    144   }
    145 
    146   if (strcmp(argv[1], "spawn_helper3") == 0) {
    147     char buffer[256];
    148     notify_parent_process();
    149     ASSERT_PTR_EQ(buffer, fgets(buffer, sizeof(buffer) - 1, stdin));
    150     buffer[sizeof(buffer) - 1] = '\0';
    151     fputs(buffer, stdout);
    152     return 1;
    153   }
    154 
    155   if (strcmp(argv[1], "spawn_helper4") == 0) {
    156     notify_parent_process();
    157     /* Never surrender, never return! */
    158     for (;;) uv_sleep(10000);
    159   }
    160 
    161   if (strcmp(argv[1], "spawn_helper5") == 0) {
    162     const char out[] = "fourth stdio!\n";
    163     notify_parent_process();
    164     {
    165 #ifdef _WIN32
    166       DWORD bytes;
    167       WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
    168 #else
    169       ssize_t r;
    170 
    171       do
    172         r = write(3, out, sizeof(out) - 1);
    173       while (r == -1 && errno == EINTR);
    174 
    175       fsync(3);
    176 #endif
    177     }
    178     return 1;
    179   }
    180 
    181   if (strcmp(argv[1], "spawn_helper6") == 0) {
    182     int r;
    183 
    184     notify_parent_process();
    185 
    186     r = fprintf(stdout, "hello world\n");
    187     ASSERT_GT(r, 0);
    188 
    189     r = fprintf(stderr, "hello errworld\n");
    190     ASSERT_GT(r, 0);
    191 
    192     return 1;
    193   }
    194 
    195   if (strcmp(argv[1], "spawn_helper7") == 0) {
    196     int r;
    197     char *test;
    198 
    199     notify_parent_process();
    200 
    201     /* Test if the test value from the parent is still set */
    202     test = getenv("ENV_TEST");
    203     ASSERT_NOT_NULL(test);
    204 
    205     r = fprintf(stdout, "%s", test);
    206     ASSERT_GT(r, 0);
    207 
    208     return 1;
    209   }
    210 
    211   if (strcmp(argv[1], "spawn_helper8") == 0) {
    212     uv_os_fd_t closed_fd;
    213     uv_os_fd_t open_fd;
    214 #ifdef _WIN32
    215     DWORD flags;
    216     HMODULE kernelbase_module;
    217     sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
    218 #endif
    219     notify_parent_process();
    220     ASSERT_EQ(sizeof(closed_fd), read(0, &closed_fd, sizeof(closed_fd)));
    221     ASSERT_EQ(sizeof(open_fd), read(0, &open_fd, sizeof(open_fd)));
    222 #ifdef _WIN32
    223     ASSERT_GT((intptr_t) closed_fd, 0);
    224     ASSERT_GT((intptr_t) open_fd, 0);
    225     ASSERT_NE(0, GetHandleInformation(open_fd, &flags));
    226     kernelbase_module = GetModuleHandleA("kernelbase.dll");
    227     pCompareObjectHandles = (sCompareObjectHandles)
    228         GetProcAddress(kernelbase_module, "CompareObjectHandles");
    229     ASSERT_NE(pCompareObjectHandles == NULL || \
    230               !pCompareObjectHandles(open_fd, closed_fd), 0);
    231 #else
    232     ASSERT_GT(open_fd, 2);
    233     ASSERT_GT(closed_fd, 2);
    234 # if defined(__PASE__)  /* On IBMi PASE, write() returns 1 */
    235     ASSERT_EQ(1, write(closed_fd, "x", 1));
    236 # else
    237     ASSERT_EQ(-1, write(closed_fd, "x", 1));
    238 # endif  /* !__PASE__ */
    239 #endif
    240     return 1;
    241   }
    242 
    243   if (strcmp(argv[1], "spawn_helper9") == 0) {
    244     notify_parent_process();
    245     spawn_stdin_stdout();
    246     return 1;
    247   }
    248 
    249 #ifndef _WIN32
    250   if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) {
    251     uv_uid_t uid = atoi(argv[2]);
    252     uv_gid_t gid = atoi(argv[3]);
    253 
    254     ASSERT_EQ(uid, getuid());
    255     ASSERT_EQ(gid, getgid());
    256     notify_parent_process();
    257 
    258     return 1;
    259   }
    260 #endif  /* !_WIN32 */
    261 
    262   if (strcmp(argv[1], "process_title_big_argv_helper") == 0) {
    263     notify_parent_process();
    264     process_title_big_argv();
    265     return 0;
    266   }
    267 
    268   return run_test(argv[1], 0, 1);
    269 }
    270