Initial commit of visual studio 9 git build superproject.
[git-build-vc9.git] / curl / tests / libtest / lib526.c
blob1f4350e1190dba51e8d1b853ae9f0c996939b522
1 /*****************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * $Id: lib526.c,v 1.14 2008-05-22 21:49:53 danf Exp $
9 */
12 * This code sets up multiple easy handles that transfer a single file from
13 * the same URL, in a serial manner after each other. Due to the connection
14 * sharing within the multi handle all transfers are performed on the same
15 * persistent connection.
17 * This source code is used for lib526, lib527 and lib532 with only #ifdefs
18 * controlling the small differences.
20 * - lib526 closes all easy handles after
21 * they all have transfered the file over the single connection
22 * - lib527 closes each easy handle after each single transfer.
23 * - lib532 uses only a single easy handle that is removed, reset and then
24 * re-added for each transfer
26 * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but
27 * with HTTP.
30 #include "test.h"
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
36 #include "testutil.h"
38 #define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
39 #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
41 #define NUM_HANDLES 4
43 int test(char *URL)
45 int res = 0;
46 CURL *curl[NUM_HANDLES];
47 int running;
48 char done=FALSE;
49 CURLM *m;
50 int current=0;
51 int i, j;
52 struct timeval ml_start;
53 struct timeval mp_start;
54 char ml_timedout = FALSE;
55 char mp_timedout = FALSE;
57 if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
58 fprintf(stderr, "curl_global_init() failed\n");
59 return TEST_ERR_MAJOR_BAD;
62 /* get NUM_HANDLES easy handles */
63 for(i=0; i < NUM_HANDLES; i++) {
64 curl[i] = curl_easy_init();
65 if(!curl[i]) {
66 fprintf(stderr, "curl_easy_init() failed "
67 "on handle #%d\n", i);
68 for (j=i-1; j >= 0; j--) {
69 curl_easy_cleanup(curl[j]);
71 curl_global_cleanup();
72 return TEST_ERR_MAJOR_BAD + i;
74 curl_easy_setopt(curl[i], CURLOPT_URL, URL);
76 /* go verbose */
77 curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
80 if ((m = curl_multi_init()) == NULL) {
81 fprintf(stderr, "curl_multi_init() failed\n");
82 for(i=0; i < NUM_HANDLES; i++) {
83 curl_easy_cleanup(curl[i]);
85 curl_global_cleanup();
86 return TEST_ERR_MAJOR_BAD;
89 if ((res = (int)curl_multi_add_handle(m, curl[current])) != CURLM_OK) {
90 fprintf(stderr, "curl_multi_add_handle() failed, "
91 "with code %d\n", res);
92 curl_multi_cleanup(m);
93 for(i=0; i < NUM_HANDLES; i++) {
94 curl_easy_cleanup(curl[i]);
96 curl_global_cleanup();
97 return TEST_ERR_MAJOR_BAD;
100 ml_timedout = FALSE;
101 ml_start = tutil_tvnow();
103 fprintf(stderr, "Start at URL 0\n");
105 while (!done) {
106 fd_set rd, wr, exc;
107 int max_fd;
108 struct timeval interval;
110 interval.tv_sec = 1;
111 interval.tv_usec = 0;
113 if (tutil_tvdiff(tutil_tvnow(), ml_start) >
114 MAIN_LOOP_HANG_TIMEOUT) {
115 ml_timedout = TRUE;
116 break;
118 mp_timedout = FALSE;
119 mp_start = tutil_tvnow();
121 while (res == CURLM_CALL_MULTI_PERFORM) {
122 res = (int)curl_multi_perform(m, &running);
123 if (tutil_tvdiff(tutil_tvnow(), mp_start) >
124 MULTI_PERFORM_HANG_TIMEOUT) {
125 mp_timedout = TRUE;
126 break;
128 if (running <= 0) {
129 #ifdef LIB527
130 /* NOTE: this code does not remove the handle from the multi handle
131 here, which would be the nice, sane and documented way of working.
132 This however tests that the API survives this abuse gracefully. */
133 curl_easy_cleanup(curl[current]);
134 #endif
135 if(++current < NUM_HANDLES) {
136 fprintf(stderr, "Advancing to URL %d\n", current);
137 #ifdef LIB532
138 /* first remove the only handle we use */
139 curl_multi_remove_handle(m, curl[0]);
141 /* make us re-use the same handle all the time, and try resetting
142 the handle first too */
143 curl_easy_reset(curl[0]);
144 curl_easy_setopt(curl[0], CURLOPT_URL, URL);
145 curl_easy_setopt(curl[0], CURLOPT_VERBOSE, 1L);
147 /* re-add it */
148 res = (int)curl_multi_add_handle(m, curl[0]);
149 #else
150 res = (int)curl_multi_add_handle(m, curl[current]);
151 #endif
152 if(res) {
153 fprintf(stderr, "add handle failed: %d.\n", res);
154 res = 243;
155 break;
158 else
159 done = TRUE; /* bail out */
160 break;
163 if (mp_timedout || done)
164 break;
166 if (res != CURLM_OK) {
167 fprintf(stderr, "not okay???\n");
168 break;
171 FD_ZERO(&rd);
172 FD_ZERO(&wr);
173 FD_ZERO(&exc);
174 max_fd = 0;
176 if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
177 fprintf(stderr, "unexpected failured of fdset.\n");
178 res = 189;
179 break;
182 if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
183 fprintf(stderr, "bad select??\n");
184 res = 195;
185 break;
188 res = CURLM_CALL_MULTI_PERFORM;
191 if (ml_timedout || mp_timedout) {
192 if (ml_timedout) fprintf(stderr, "ml_timedout\n");
193 if (mp_timedout) fprintf(stderr, "mp_timedout\n");
194 fprintf(stderr, "ABORTING TEST, since it seems "
195 "that it would have run forever.\n");
196 res = TEST_ERR_RUNS_FOREVER;
199 #ifndef LIB527
200 /* get NUM_HANDLES easy handles */
201 for(i=0; i < NUM_HANDLES; i++) {
202 #ifdef LIB526
203 curl_multi_remove_handle(m, curl[i]);
204 #endif
205 curl_easy_cleanup(curl[i]);
207 #endif
208 curl_multi_cleanup(m);
210 curl_global_cleanup();
211 return res;