Home | History | Annotate | Download | only in libtest
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 /*
     23  * This code sets up multiple easy handles that transfer a single file from
     24  * the same URL, in a serial manner after each other. Due to the connection
     25  * sharing within the multi handle all transfers are performed on the same
     26  * persistent connection.
     27  *
     28  * This source code is used for lib526, lib527 and lib532 with only #ifdefs
     29  * controlling the small differences.
     30  *
     31  * - lib526 closes all easy handles after
     32  *   they all have transferred the file over the single connection
     33  * - lib527 closes each easy handle after each single transfer.
     34  * - lib532 uses only a single easy handle that is removed, reset and then
     35  *   re-added for each transfer
     36  *
     37  * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but
     38  * with HTTP.
     39  */
     40 
     41 #include "test.h"
     42 
     43 #include <fcntl.h>
     44 
     45 #include "testutil.h"
     46 #include "warnless.h"
     47 #include "memdebug.h"
     48 
     49 #define TEST_HANG_TIMEOUT 60 * 1000
     50 
     51 #define NUM_HANDLES 4
     52 
     53 int test(char *URL)
     54 {
     55   int res = 0;
     56   CURL *curl[NUM_HANDLES];
     57   int running;
     58   CURLM *m = NULL;
     59   int current = 0;
     60   int i;
     61 
     62   for(i = 0; i < NUM_HANDLES; i++)
     63     curl[i] = NULL;
     64 
     65   start_test_timing();
     66 
     67   global_init(CURL_GLOBAL_ALL);
     68 
     69   /* get NUM_HANDLES easy handles */
     70   for(i = 0; i < NUM_HANDLES; i++) {
     71     easy_init(curl[i]);
     72     /* specify target */
     73     easy_setopt(curl[i], CURLOPT_URL, URL);
     74     /* go verbose */
     75     easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
     76   }
     77 
     78   multi_init(m);
     79 
     80   multi_add_handle(m, curl[current]);
     81 
     82   fprintf(stderr, "Start at URL 0\n");
     83 
     84   for(;;) {
     85     struct timeval interval;
     86     fd_set rd, wr, exc;
     87     int maxfd = -99;
     88 
     89     interval.tv_sec = 1;
     90     interval.tv_usec = 0;
     91 
     92     multi_perform(m, &running);
     93 
     94     abort_on_test_timeout();
     95 
     96     if(!running) {
     97 #ifdef LIB527
     98       /* NOTE: this code does not remove the handle from the multi handle
     99          here, which would be the nice, sane and documented way of working.
    100          This however tests that the API survives this abuse gracefully. */
    101       curl_easy_cleanup(curl[current]);
    102       curl[current] = NULL;
    103 #endif
    104       if(++current < NUM_HANDLES) {
    105         fprintf(stderr, "Advancing to URL %d\n", current);
    106 #ifdef LIB532
    107         /* first remove the only handle we use */
    108         curl_multi_remove_handle(m, curl[0]);
    109 
    110         /* make us re-use the same handle all the time, and try resetting
    111            the handle first too */
    112         curl_easy_reset(curl[0]);
    113         easy_setopt(curl[0], CURLOPT_URL, URL);
    114         /* go verbose */
    115         easy_setopt(curl[0], CURLOPT_VERBOSE, 1L);
    116 
    117         /* re-add it */
    118         multi_add_handle(m, curl[0]);
    119 #else
    120         multi_add_handle(m, curl[current]);
    121 #endif
    122       }
    123       else {
    124         break; /* done */
    125       }
    126     }
    127 
    128     FD_ZERO(&rd);
    129     FD_ZERO(&wr);
    130     FD_ZERO(&exc);
    131 
    132     multi_fdset(m, &rd, &wr, &exc, &maxfd);
    133 
    134     /* At this point, maxfd is guaranteed to be greater or equal than -1. */
    135 
    136     select_test(maxfd + 1, &rd, &wr, &exc, &interval);
    137 
    138     abort_on_test_timeout();
    139   }
    140 
    141 test_cleanup:
    142 
    143 #if defined(LIB526)
    144 
    145   /* test 526 and 528 */
    146   /* proper cleanup sequence - type PB */
    147 
    148   for(i = 0; i < NUM_HANDLES; i++) {
    149     curl_multi_remove_handle(m, curl[i]);
    150     curl_easy_cleanup(curl[i]);
    151   }
    152   curl_multi_cleanup(m);
    153   curl_global_cleanup();
    154 
    155 #elif defined(LIB527)
    156 
    157   /* test 527 */
    158 
    159   /* Upon non-failure test flow the easy's have already been cleanup'ed. In
    160      case there is a failure we arrive here with easy's that have not been
    161      cleanup'ed yet, in this case we have to cleanup them or otherwise these
    162      will be leaked, let's use undocumented cleanup sequence - type UB */
    163 
    164   if(res)
    165     for(i = 0; i < NUM_HANDLES; i++)
    166       curl_easy_cleanup(curl[i]);
    167 
    168   curl_multi_cleanup(m);
    169   curl_global_cleanup();
    170 
    171 #elif defined(LIB532)
    172 
    173   /* test 532 */
    174   /* undocumented cleanup sequence - type UB */
    175 
    176   for(i = 0; i < NUM_HANDLES; i++)
    177     curl_easy_cleanup(curl[i]);
    178   curl_multi_cleanup(m);
    179   curl_global_cleanup();
    180 
    181 #endif
    182 
    183   return res;
    184 }
    185