25277584059871825fb649d4e99369a8fbad5b24
[platform/upstream/curl.git] / tests / libtest / lib507.c
1 /*****************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * $Id$
9  */
10
11 #include "test.h"
12
13 #include "testutil.h"
14 #include "memdebug.h"
15
16 #define MAIN_LOOP_HANG_TIMEOUT     90 * 1000
17 #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
18
19 int test(char *URL)
20 {
21   CURL* curls;
22   CURLM* multi;
23   int still_running;
24   int i = -1;
25   int res = 0;
26   CURLMsg *msg;
27   CURLMcode ret;
28   struct timeval ml_start;
29   struct timeval mp_start;
30   char ml_timedout = FALSE;
31   char mp_timedout = FALSE;
32
33   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
34     fprintf(stderr, "curl_global_init() failed\n");
35     return TEST_ERR_MAJOR_BAD;
36   }
37
38   if ((multi = curl_multi_init()) == NULL) {
39     fprintf(stderr, "curl_multi_init() failed\n");
40     curl_global_cleanup();
41     return TEST_ERR_MAJOR_BAD;
42   }
43
44   if ((curls = curl_easy_init()) == NULL) {
45     fprintf(stderr, "curl_easy_init() failed\n");
46     curl_multi_cleanup(multi);
47     curl_global_cleanup();
48     return TEST_ERR_MAJOR_BAD;
49   }
50
51   test_setopt(curls, CURLOPT_URL, URL);
52
53   if ((ret = curl_multi_add_handle(multi, curls)) != CURLM_OK) {
54     fprintf(stderr, "curl_multi_add_handle() failed, "
55             "with code %d\n", ret);
56     curl_easy_cleanup(curls);
57     curl_multi_cleanup(multi);
58     curl_global_cleanup();
59     return TEST_ERR_MAJOR_BAD;
60   }
61
62   mp_timedout = FALSE;
63   mp_start = tutil_tvnow();
64
65   do {
66     ret = curl_multi_perform(multi, &still_running);
67     if (tutil_tvdiff(tutil_tvnow(), mp_start) > 
68         MULTI_PERFORM_HANG_TIMEOUT) {
69       mp_timedout = TRUE;
70       break;
71     }
72   } while (ret == CURLM_CALL_MULTI_PERFORM);
73
74   ml_timedout = FALSE;
75   ml_start = tutil_tvnow();
76
77   while ((!ml_timedout) && (!mp_timedout) && (still_running)) {
78     struct timeval timeout;
79     int rc;
80     fd_set fdread;
81     fd_set fdwrite;
82     fd_set fdexcep;
83     int maxfd;
84
85     FD_ZERO(&fdread);
86     FD_ZERO(&fdwrite);
87     FD_ZERO(&fdexcep);
88     timeout.tv_sec = 1;
89     timeout.tv_usec = 0;
90
91     if (tutil_tvdiff(tutil_tvnow(), ml_start) > 
92         MAIN_LOOP_HANG_TIMEOUT) {
93       ml_timedout = TRUE;
94       break;
95     }
96
97     curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
98     rc = select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
99     switch(rc) {
100       case -1:
101         break;
102       case 0:
103       default:
104         mp_timedout = FALSE;
105         mp_start = tutil_tvnow();
106         do {
107           ret = curl_multi_perform(multi, &still_running);
108           if (tutil_tvdiff(tutil_tvnow(), mp_start) > 
109               MULTI_PERFORM_HANG_TIMEOUT) {
110             mp_timedout = TRUE;
111             break;
112           }
113         } while (ret == CURLM_CALL_MULTI_PERFORM);
114         break;
115     }
116   }
117   if (ml_timedout || mp_timedout) {
118     if (ml_timedout) fprintf(stderr, "ml_timedout\n");
119     if (mp_timedout) fprintf(stderr, "mp_timedout\n");
120     fprintf(stderr, "ABORTING TEST, since it seems "
121             "that it would have run forever.\n");
122     i = TEST_ERR_RUNS_FOREVER;
123   }
124   else {
125     msg = curl_multi_info_read(multi, &still_running);
126     if(msg)
127       /* this should now contain a result code from the easy handle,
128          get it */
129       i = msg->data.result;
130   }
131
132 test_cleanup:
133
134   curl_multi_cleanup(multi);
135   curl_easy_cleanup(curls);
136   curl_global_cleanup();
137
138   if(res)
139     i = res;
140
141   return i; /* return the final return code */
142 }