root/opal/mca/event/libevent2022/libevent/test/regress_main.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. timeval_msec_diff
  2. dnslogcb
  3. regress_make_tmpfile
  4. regress_fork
  5. ignore_log_cb
  6. basic_test_setup
  7. basic_test_cleanup
  8. legacy_test_setup
  9. run_legacy_test_fn
  10. legacy_test_cleanup
  11. main

   1 /*
   2  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
   3  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. The name of the author may not be used to endorse or promote products
  14  *    derived from this software without specific prior written permission.
  15  *
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26  */
  27 
  28 #ifdef WIN32
  29 #include <winsock2.h>
  30 #include <windows.h>
  31 #include <io.h>
  32 #include <fcntl.h>
  33 #endif
  34 
  35 #if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
  36 #if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \
  37     __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
  38 #define FORK_BREAKS_GCOV
  39 #include <vproc.h>
  40 #endif
  41 #endif
  42 
  43 #include "event2/event-config.h"
  44 
  45 #ifdef _EVENT___func__
  46 #define __func__ _EVENT___func__
  47 #endif
  48 
  49 #if 0
  50 #include <sys/types.h>
  51 #include <sys/stat.h>
  52 #ifdef _EVENT_HAVE_SYS_TIME_H
  53 #include <sys/time.h>
  54 #endif
  55 #include <sys/queue.h>
  56 #include <signal.h>
  57 #include <errno.h>
  58 #endif
  59 
  60 #include <sys/types.h>
  61 #ifdef _EVENT_HAVE_SYS_STAT_H
  62 #include <sys/stat.h>
  63 #endif
  64 
  65 #ifndef WIN32
  66 #include <sys/socket.h>
  67 #include <sys/wait.h>
  68 #include <signal.h>
  69 #include <unistd.h>
  70 #include <netdb.h>
  71 #endif
  72 
  73 #include <stdlib.h>
  74 #include <stdio.h>
  75 #include <string.h>
  76 #include <assert.h>
  77 
  78 #include "event2/util.h"
  79 #include "event2/event.h"
  80 #include "event2/event_compat.h"
  81 #include "event2/dns.h"
  82 #include "event2/dns_compat.h"
  83 #include "event2/thread.h"
  84 
  85 #include "event2/event-config.h"
  86 #include "regress.h"
  87 #include "tinytest.h"
  88 #include "tinytest_macros.h"
  89 #include "../iocp-internal.h"
  90 #include "../event-internal.h"
  91 
  92 long
  93 timeval_msec_diff(const struct timeval *start, const struct timeval *end)
  94 {
  95         long ms = end->tv_sec - start->tv_sec;
  96         ms *= 1000;
  97         ms += ((end->tv_usec - start->tv_usec)+500) / 1000;
  98         return ms;
  99 
 100 }
 101 
 102 /* ============================================================ */
 103 /* Code to wrap up old legacy test cases that used setup() and cleanup().
 104  *
 105  * Not all of the tests designated "legacy" are ones that used setup() and
 106  * cleanup(), of course.  A test is legacy it it uses setup()/cleanup(), OR
 107  * if it wants to find its event base/socketpair in global variables (ugh),
 108  * OR if it wants to communicate success/failure through test_ok.
 109  */
 110 
 111 /* This is set to true if we're inside a legacy test wrapper.  It lets the
 112    setup() and cleanup() functions in regress.c know they're not needed.
 113  */
 114 int in_legacy_test_wrapper = 0;
 115 
 116 static void dnslogcb(int w, const char *m)
 117 {
 118         TT_BLATHER(("%s", m));
 119 }
 120 
 121 /* creates a temporary file with the data in it */
 122 int
 123 regress_make_tmpfile(const void *data, size_t datalen)
 124 {
 125 #ifndef WIN32
 126         char tmpfilename[32];
 127         int fd;
 128         strcpy(tmpfilename, "/tmp/eventtmp.XXXXXX");
 129 #ifdef _EVENT_HAVE_UMASK
 130         umask(0077);
 131 #endif
 132         fd = mkstemp(tmpfilename);
 133         if (fd == -1)
 134                 return (-1);
 135         if (write(fd, data, datalen) != (int)datalen) {
 136                 close(fd);
 137                 return (-1);
 138         }
 139         lseek(fd, 0, SEEK_SET);
 140         /* remove it from the file system */
 141         unlink(tmpfilename);
 142         return (fd);
 143 #else
 144         /* XXXX actually delete the file later */
 145         char tmpfilepath[MAX_PATH];
 146         char tmpfilename[MAX_PATH];
 147         DWORD r, written;
 148         int tries = 16;
 149         HANDLE h;
 150         r = GetTempPathA(MAX_PATH, tmpfilepath);
 151         if (r > MAX_PATH || r == 0)
 152                 return (-1);
 153         for (; tries > 0; --tries) {
 154                 r = GetTempFileNameA(tmpfilepath, "LIBEVENT", 0, tmpfilename);
 155                 if (r == 0)
 156                         return (-1);
 157                 h = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE,
 158                     0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 159                 if (h != INVALID_HANDLE_VALUE)
 160                         break;
 161         }
 162         if (tries == 0)
 163                 return (-1);
 164         written = 0;
 165         WriteFile(h, data, (DWORD)datalen, &written, NULL);
 166         /* Closing the fd returned by this function will indeed close h. */
 167         return _open_osfhandle((intptr_t)h,_O_RDONLY);
 168 #endif
 169 }
 170 
 171 #ifndef _WIN32
 172 pid_t
 173 regress_fork(void)
 174 {
 175         pid_t pid = fork();
 176 #ifdef FORK_BREAKS_GCOV
 177         vproc_transaction_begin(0);
 178 #endif
 179         return pid;
 180 }
 181 #endif
 182 
 183 static void
 184 ignore_log_cb(int s, const char *msg)
 185 {
 186 }
 187 
 188 static void *
 189 basic_test_setup(const struct testcase_t *testcase)
 190 {
 191         struct event_base *base = NULL;
 192         evutil_socket_t spair[2] = { -1, -1 };
 193         struct basic_test_data *data = NULL;
 194 
 195 #ifndef WIN32
 196         if (testcase->flags & TT_ENABLE_IOCP_FLAG)
 197                 return (void*)TT_SKIP;
 198 #endif
 199 
 200         if (testcase->flags & TT_NEED_THREADS) {
 201                 if (!(testcase->flags & TT_FORK))
 202                         return NULL;
 203 #if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED)
 204                 if (evthread_use_pthreads())
 205                         exit(1);
 206 #elif defined(EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED)
 207                 if (evthread_use_windows_threads())
 208                         exit(1);
 209 #else
 210                 return (void*)TT_SKIP;
 211 #endif
 212         }
 213 
 214         if (testcase->flags & TT_NEED_SOCKETPAIR) {
 215                 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) {
 216                         fprintf(stderr, "%s: socketpair\n", __func__);
 217                         exit(1);
 218                 }
 219 
 220                 if (evutil_make_socket_nonblocking(spair[0]) == -1) {
 221                         fprintf(stderr, "fcntl(O_NONBLOCK)");
 222                         exit(1);
 223                 }
 224 
 225                 if (evutil_make_socket_nonblocking(spair[1]) == -1) {
 226                         fprintf(stderr, "fcntl(O_NONBLOCK)");
 227                         exit(1);
 228                 }
 229         }
 230         if (testcase->flags & TT_NEED_BASE) {
 231                 if (testcase->flags & TT_LEGACY)
 232                         base = event_init();
 233                 else
 234                         base = event_base_new();
 235                 if (!base)
 236                         exit(1);
 237         }
 238         if (testcase->flags & TT_ENABLE_IOCP_FLAG) {
 239                 if (event_base_start_iocp(base, 0)<0) {
 240                         event_base_free(base);
 241                         return (void*)TT_SKIP;
 242                 }
 243         }
 244 
 245         if (testcase->flags & TT_NEED_DNS) {
 246                 evdns_set_log_fn(dnslogcb);
 247                 if (evdns_init())
 248                         return NULL; /* fast failure */ /*XXX asserts. */
 249         }
 250 
 251         if (testcase->flags & TT_NO_LOGS)
 252                 event_set_log_callback(ignore_log_cb);
 253 
 254         data = calloc(1, sizeof(*data));
 255         if (!data)
 256                 exit(1);
 257         data->base = base;
 258         data->pair[0] = spair[0];
 259         data->pair[1] = spair[1];
 260         data->setup_data = testcase->setup_data;
 261         return data;
 262 }
 263 
 264 static int
 265 basic_test_cleanup(const struct testcase_t *testcase, void *ptr)
 266 {
 267         struct basic_test_data *data = ptr;
 268 
 269         if (testcase->flags & TT_NO_LOGS)
 270                 event_set_log_callback(NULL);
 271 
 272         if (testcase->flags & TT_NEED_SOCKETPAIR) {
 273                 if (data->pair[0] != -1)
 274                         evutil_closesocket(data->pair[0]);
 275                 if (data->pair[1] != -1)
 276                         evutil_closesocket(data->pair[1]);
 277         }
 278 
 279         if (testcase->flags & TT_NEED_DNS) {
 280                 evdns_shutdown(0);
 281         }
 282 
 283         if (testcase->flags & TT_NEED_BASE) {
 284                 if (data->base) {
 285                         event_base_assert_ok(data->base);
 286                         event_base_free(data->base);
 287                 }
 288         }
 289 
 290         free(data);
 291 
 292         return 1;
 293 }
 294 
 295 const struct testcase_setup_t basic_setup = {
 296         basic_test_setup, basic_test_cleanup
 297 };
 298 
 299 /* The "data" for a legacy test is just a pointer to the void fn(void)
 300    function implementing the test case.  We need to set up some globals,
 301    though, since that's where legacy tests expect to find a socketpair
 302    (sometimes) and a global event_base (sometimes).
 303  */
 304 static void *
 305 legacy_test_setup(const struct testcase_t *testcase)
 306 {
 307         struct basic_test_data *data = basic_test_setup(testcase);
 308         if (data == (void*)TT_SKIP || data == NULL)
 309                 return data;
 310         global_base = data->base;
 311         pair[0] = data->pair[0];
 312         pair[1] = data->pair[1];
 313         data->legacy_test_fn = testcase->setup_data;
 314         return data;
 315 }
 316 
 317 /* This function is the implementation of every legacy test case.  It
 318    sets test_ok to 0, invokes the test function, and tells tinytest that
 319    the test failed if the test didn't set test_ok to 1.
 320  */
 321 void
 322 run_legacy_test_fn(void *ptr)
 323 {
 324         struct basic_test_data *data = ptr;
 325         test_ok = called = 0;
 326 
 327         in_legacy_test_wrapper = 1;
 328         data->legacy_test_fn(); /* This part actually calls the test */
 329         in_legacy_test_wrapper = 0;
 330 
 331         if (!test_ok)
 332                 tt_abort_msg("Legacy unit test failed");
 333 
 334 end:
 335         test_ok = 0;
 336 }
 337 
 338 /* This function doesn't have to clean up ptr (which is just a pointer
 339    to the test function), but it may need to close the socketpair or
 340    free the event_base.
 341  */
 342 static int
 343 legacy_test_cleanup(const struct testcase_t *testcase, void *ptr)
 344 {
 345         int r = basic_test_cleanup(testcase, ptr);
 346         pair[0] = pair[1] = -1;
 347         global_base = NULL;
 348         return r;
 349 }
 350 
 351 const struct testcase_setup_t legacy_setup = {
 352         legacy_test_setup, legacy_test_cleanup
 353 };
 354 
 355 /* ============================================================ */
 356 
 357 #if (!defined(_EVENT_HAVE_PTHREADS) && !defined(WIN32)) || defined(_EVENT_DISABLE_THREAD_SUPPORT)
 358 struct testcase_t thread_testcases[] = {
 359         { "basic", NULL, TT_SKIP, NULL, NULL },
 360         END_OF_TESTCASES
 361 };
 362 #endif
 363 
 364 struct testgroup_t testgroups[] = {
 365         { "main/", main_testcases },
 366         { "heap/", minheap_testcases },
 367         { "et/", edgetriggered_testcases },
 368         { "evbuffer/", evbuffer_testcases },
 369         { "signal/", signal_testcases },
 370         { "util/", util_testcases },
 371         { "bufferevent/", bufferevent_testcases },
 372         { "http/", http_testcases },
 373         { "dns/", dns_testcases },
 374         { "evtag/", evtag_testcases },
 375         { "rpc/", rpc_testcases },
 376         { "thread/", thread_testcases },
 377         { "listener/", listener_testcases },
 378 #ifdef WIN32
 379         { "iocp/", iocp_testcases },
 380         { "iocp/bufferevent/", bufferevent_iocp_testcases },
 381         { "iocp/listener/", listener_iocp_testcases },
 382 #endif
 383 #ifdef _EVENT_HAVE_OPENSSL
 384         { "ssl/", ssl_testcases },
 385 #endif
 386         END_OF_GROUPS
 387 };
 388 
 389 int
 390 main(int argc, const char **argv)
 391 {
 392 #ifdef WIN32
 393         WORD wVersionRequested;
 394         WSADATA wsaData;
 395 
 396         wVersionRequested = MAKEWORD(2, 2);
 397 
 398         (void) WSAStartup(wVersionRequested, &wsaData);
 399 #endif
 400 
 401 #ifndef WIN32
 402         if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
 403                 return 1;
 404 #endif
 405 
 406 #ifdef WIN32
 407         tinytest_skip(testgroups, "http/connection_retry");
 408 #endif
 409 
 410 #ifndef _EVENT_DISABLE_THREAD_SUPPORT
 411         if (!getenv("EVENT_NO_DEBUG_LOCKS"))
 412                 evthread_enable_lock_debuging();
 413 #endif
 414 
 415         if (tinytest_main(argc,argv,testgroups))
 416                 return 1;
 417 
 418         return 0;
 419 }
 420 

/* [<][>][^][v][top][bottom][index][help] */