summaryrefslogtreecommitdiff
path: root/tests/libtest/lib1900.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/libtest/lib1900.c')
-rw-r--r--tests/libtest/lib1900.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/tests/libtest/lib1900.c b/tests/libtest/lib1900.c
new file mode 100644
index 000000000..b2a943440
--- /dev/null
+++ b/tests/libtest/lib1900.c
@@ -0,0 +1,256 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+#define MAX_URLS 200
+#define MAX_BLACKLIST 20
+
+int urltime[MAX_URLS];
+char *urlstring[MAX_URLS];
+CURL *handles[MAX_URLS];
+char *site_blacklist[MAX_BLACKLIST];
+char *server_blacklist[MAX_BLACKLIST];
+int num_handles;
+int blacklist_num_servers;
+int blacklist_num_sites;
+
+int parse_url_file(const char *filename);
+void free_urls(void);
+int create_handles(void);
+void setup_handle(char *base_url, CURLM *m, int handlenum);
+void remove_handles(void);
+
+static size_t
+write_callback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ size_t realsize = size * nmemb;
+ (void)contents;
+ (void)userp;
+
+ return realsize;
+}
+
+int parse_url_file(const char *filename)
+{
+ FILE *f;
+ int time;
+ char buf[200];
+
+ num_handles = 0;
+ blacklist_num_sites = 0;
+ blacklist_num_servers = 0;
+
+ f = fopen(filename, "rb");
+ if(!f)
+ return 0;
+
+ while(!feof(f)) {
+ if(fscanf(f, "%d %s\n", &time, buf)) {
+ urltime[num_handles] = time;
+ urlstring[num_handles] = strdup(buf);
+ num_handles++;
+ continue;
+ }
+
+ if(fscanf(f, "blacklist_site %s\n", buf)) {
+ site_blacklist[blacklist_num_sites] = strdup(buf);
+ blacklist_num_sites++;
+ continue;
+ }
+
+ break;
+ }
+ fclose(f);
+
+ site_blacklist[blacklist_num_sites] = NULL;
+ server_blacklist[blacklist_num_servers] = NULL;
+ return num_handles;
+}
+
+void free_urls(void)
+{
+ int i;
+ for(i = 0;i < num_handles;i++) {
+ free(urlstring[i]);
+ }
+ for(i = 0;i < blacklist_num_servers;i++) {
+ free(server_blacklist[i]);
+ }
+ for(i = 0;i < blacklist_num_sites;i++) {
+ free(site_blacklist[i]);
+ }
+}
+
+int create_handles(void)
+{
+ int i;
+
+ for(i = 0;i < num_handles;i++) {
+ handles[i] = curl_easy_init();
+ }
+ return 0;
+}
+
+void setup_handle(char *base_url, CURLM *m, int handlenum)
+{
+ char urlbuf[256];
+
+ sprintf(urlbuf, "%s%s", base_url, urlstring[handlenum]);
+ curl_easy_setopt(handles[handlenum], CURLOPT_URL, urlbuf);
+ curl_easy_setopt(handles[handlenum], CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(handles[handlenum], CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt(handles[handlenum], CURLOPT_WRITEFUNCTION, write_callback);
+ curl_easy_setopt(handles[handlenum], CURLOPT_WRITEDATA, NULL);
+ curl_multi_add_handle(m, handles[handlenum]);
+}
+
+void remove_handles(void)
+{
+ int i;
+
+ for(i = 0;i < num_handles;i++) {
+ if(handles[i])
+ curl_easy_cleanup(handles[i]);
+ }
+}
+
+int test(char *URL)
+{
+ int res = 0;
+ CURLM *m = NULL;
+ CURLMsg *msg; /* for picking up messages with the transfer status */
+ int msgs_left; /* how many messages are left */
+ int running;
+ int handlenum = 0;
+ struct timeval last_handle_add;
+
+ if(parse_url_file("log/urls.txt") <= 0)
+ goto test_cleanup;
+
+ start_test_timing();
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ m = curl_multi_init();
+
+ create_handles();
+
+ multi_setopt(m, CURLMOPT_PIPELINING, 1L);
+ multi_setopt(m, CURLMOPT_MAX_HOST_CONNECTIONS, 2L);
+ multi_setopt(m, CURLMOPT_MAX_PIPELINE_LENGTH, 3L);
+ multi_setopt(m, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, 15000L);
+ multi_setopt(m, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, 10000L);
+
+ multi_setopt(m, CURLMOPT_PIPELINING_SITE_BL, site_blacklist);
+ multi_setopt(m, CURLMOPT_PIPELINING_SERVER_BL, server_blacklist);
+
+ gettimeofday(&last_handle_add, NULL);
+
+ for(;;) {
+ struct timeval interval;
+ struct timeval now;
+ long int msnow, mslast;
+ fd_set rd, wr, exc;
+ int maxfd = -99;
+ long timeout;
+
+ interval.tv_sec = 1;
+ interval.tv_usec = 0;
+
+ if(handlenum < num_handles) {
+ gettimeofday(&now, NULL);
+ msnow = now.tv_sec * 1000 + now.tv_usec / 1000;
+ mslast = last_handle_add.tv_sec * 1000 + last_handle_add.tv_usec / 1000;
+ if(msnow - mslast >= urltime[handlenum] && handlenum < num_handles) {
+ fprintf(stdout, "Adding handle %d\n", handlenum);
+ setup_handle(URL, m, handlenum);
+ last_handle_add = now;
+ handlenum++;
+ }
+ }
+
+ curl_multi_perform(m, &running);
+
+ abort_on_test_timeout();
+
+ /* See how the transfers went */
+ while ((msg = curl_multi_info_read(m, &msgs_left))) {
+ if (msg->msg == CURLMSG_DONE) {
+ int i, found = 0;
+
+ /* Find out which handle this message is about */
+ for (i = 0; i < num_handles; i++) {
+ found = (msg->easy_handle == handles[i]);
+ if(found)
+ break;
+ }
+
+ printf("Handle %d Completed with status %d\n", i, msg->data.result);
+ curl_multi_remove_handle(m, handles[i]);
+ }
+ }
+
+ if(handlenum == num_handles && !running) {
+ break; /* done */
+ }
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&exc);
+
+ curl_multi_fdset(m, &rd, &wr, &exc, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ curl_multi_timeout(m, &timeout);
+
+ if(timeout < 0)
+ timeout = 1;
+
+ interval.tv_sec = timeout / 1000;
+ interval.tv_usec = (timeout % 1000) * 1000;
+
+ interval.tv_sec = 0;
+ interval.tv_usec = 1000;
+
+ select_test(maxfd+1, &rd, &wr, &exc, &interval);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ remove_handles();
+
+ /* undocumented cleanup sequence - type UB */
+
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+ free_urls();
+ return res;
+}