9417 lines
282 KiB
Diff
9417 lines
282 KiB
Diff
From 15a1c96494611dafd6444655bce0b13c64a6172f Mon Sep 17 00:00:00 2001
|
|
From: Kjetil Jacobsen <kjetilja@gmail.com>
|
|
Date: Tue, 9 Sep 2008 18:49:59 +0000
|
|
Subject: [PATCH 001/112] whitespace
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
ChangeLog | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/ChangeLog b/ChangeLog
|
|
index 0fb7f8c..3d68424 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -1,7 +1,7 @@
|
|
Version 7.19.0 [requires libcurl-7.19.0 or better]
|
|
--------------
|
|
|
|
- * Added CURLFILE, ADDRESS_SCOPE and ISSUERCERT options,
|
|
+ * Added CURLFILE, ADDRESS_SCOPE and ISSUERCERT options,
|
|
as well as the APPCONNECT_TIME info.
|
|
|
|
* Added PRIMARY_IP info (patch by
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From f79d0ea41bad7ea25cf949ca5398ed61b87de722 Mon Sep 17 00:00:00 2001
|
|
From: Kjetil Jacobsen <kjetilja@gmail.com>
|
|
Date: Mon, 29 Sep 2008 10:56:57 +0000
|
|
Subject: [PATCH 002/112] No longer keep copies of string options since this is managed by libcurl
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
ChangeLog | 10 +++++++++-
|
|
src/pycurl.c | 58 +---------------------------------------------------------
|
|
2 files changed, 10 insertions(+), 58 deletions(-)
|
|
|
|
diff --git a/ChangeLog b/ChangeLog
|
|
index 3d68424..618654d 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -1,4 +1,12 @@
|
|
-Version 7.19.0 [requires libcurl-7.19.0 or better]
|
|
+Version 7.19.1 [requires libcurl-7.19.0 or better]
|
|
+--------------
|
|
+
|
|
+ * No longer keep string options copies in the
|
|
+ Curl Python objects, since string options are
|
|
+ now managed by libcurl.
|
|
+
|
|
+
|
|
+Version 7.19.0
|
|
--------------
|
|
|
|
* Added CURLFILE, ADDRESS_SCOPE and ISSUERCERT options,
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index 50ec9ce..189f5d6 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -97,12 +97,6 @@ static void pycurl_ssl_cleanup(void);
|
|
/* Calculate the number of OBJECTPOINT options we need to store */
|
|
#define OPTIONS_SIZE ((int)CURLOPT_LASTENTRY % 10000)
|
|
#define MOPTIONS_SIZE ((int)CURLMOPT_LASTENTRY % 10000)
|
|
-static int OPT_INDEX(int o)
|
|
-{
|
|
- assert(o >= CURLOPTTYPE_OBJECTPOINT);
|
|
- assert(o < CURLOPTTYPE_OBJECTPOINT + OPTIONS_SIZE);
|
|
- return o - CURLOPTTYPE_OBJECTPOINT;
|
|
-}
|
|
|
|
/* Type objects */
|
|
static PyObject *ErrorObject = NULL;
|
|
@@ -161,7 +155,6 @@ typedef struct {
|
|
PyObject *writedata_fp;
|
|
PyObject *writeheader_fp;
|
|
/* misc */
|
|
- void *options[OPTIONS_SIZE]; /* for OBJECTPOINT options */
|
|
char error[CURL_ERROR_SIZE+1];
|
|
} CurlObject;
|
|
|
|
@@ -741,7 +734,6 @@ util_curl_new(void)
|
|
self->writeheader_fp = NULL;
|
|
|
|
/* Zero string pointer memory buffer used by setopt */
|
|
- memset(self->options, 0, sizeof(self->options));
|
|
memset(self->error, 0, sizeof(self->error));
|
|
|
|
return self;
|
|
@@ -804,7 +796,6 @@ do_curl_new(PyObject *dummy)
|
|
free(s);
|
|
goto error;
|
|
}
|
|
- self->options[ OPT_INDEX(CURLOPT_USERAGENT) ] = s; s = NULL;
|
|
|
|
/* Success - return new object */
|
|
return self;
|
|
@@ -872,7 +863,6 @@ static void
|
|
util_curl_close(CurlObject *self)
|
|
{
|
|
CURL *handle;
|
|
- int i;
|
|
|
|
/* Zero handle and thread-state to disallow any operations to be run
|
|
* from now on */
|
|
@@ -916,16 +906,6 @@ util_curl_close(CurlObject *self)
|
|
SFREE(self->postquote);
|
|
SFREE(self->prequote);
|
|
#undef SFREE
|
|
-
|
|
- /* Last, free the options. This must be done after the curl handle
|
|
- * is closed since libcurl assumes that some options are valid when
|
|
- * invoking curl_easy_cleanup(). */
|
|
- for (i = 0; i < OPTIONS_SIZE; i++) {
|
|
- if (self->options[i] != NULL) {
|
|
- free(self->options[i]);
|
|
- self->options[i] = NULL;
|
|
- }
|
|
- }
|
|
}
|
|
|
|
|
|
@@ -1424,8 +1404,6 @@ verbose_error:
|
|
static PyObject*
|
|
do_curl_reset(CurlObject *self)
|
|
{
|
|
- unsigned int i;
|
|
-
|
|
curl_easy_reset(self->handle);
|
|
|
|
/* Decref callbacks and file handles */
|
|
@@ -1443,15 +1421,6 @@ do_curl_reset(CurlObject *self)
|
|
SFREE(self->postquote);
|
|
SFREE(self->prequote);
|
|
#undef SFREE
|
|
-
|
|
- /* Last, free the options */
|
|
- for (i = 0; i < OPTIONS_SIZE; i++) {
|
|
- if (self->options[i] != NULL) {
|
|
- free(self->options[i]);
|
|
- self->options[i] = NULL;
|
|
- }
|
|
- }
|
|
-
|
|
return Py_None;
|
|
}
|
|
|
|
@@ -1461,7 +1430,6 @@ static PyObject *
|
|
util_curl_unsetopt(CurlObject *self, int option)
|
|
{
|
|
int res;
|
|
- int opt_index = -1;
|
|
|
|
#define SETOPT2(o,x) \
|
|
if ((res = curl_easy_setopt(self->handle, (o), (x))) != CURLE_OK) goto error
|
|
@@ -1502,7 +1470,6 @@ util_curl_unsetopt(CurlObject *self, int option)
|
|
case CURLOPT_SSL_CIPHER_LIST:
|
|
case CURLOPT_USERPWD:
|
|
SETOPT((char *) 0);
|
|
- opt_index = OPT_INDEX(option);
|
|
break;
|
|
|
|
/* info: we explicitly list unsupported options here */
|
|
@@ -1512,11 +1479,6 @@ util_curl_unsetopt(CurlObject *self, int option)
|
|
return NULL;
|
|
}
|
|
|
|
- if (opt_index >= 0 && self->options[opt_index] != NULL) {
|
|
- free(self->options[opt_index]);
|
|
- self->options[opt_index] = NULL;
|
|
- }
|
|
-
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
|
|
@@ -1587,8 +1549,6 @@ do_curl_setopt(CurlObject *self, PyObject *args)
|
|
if (PyString_Check(obj)) {
|
|
char *str = NULL;
|
|
Py_ssize_t len = -1;
|
|
- char *buf;
|
|
- int opt_index;
|
|
|
|
/* Check that the option specified a string as well as the input */
|
|
switch (option) {
|
|
@@ -1651,28 +1611,12 @@ do_curl_setopt(CurlObject *self, PyObject *args)
|
|
}
|
|
/* Allocate memory to hold the string */
|
|
assert(str != NULL);
|
|
- if (len <= 0)
|
|
- buf = strdup(str);
|
|
- else {
|
|
- buf = (char *) malloc(len);
|
|
- if (buf) memcpy(buf, str, len);
|
|
- }
|
|
- if (buf == NULL)
|
|
- return PyErr_NoMemory();
|
|
/* Call setopt */
|
|
- res = curl_easy_setopt(self->handle, (CURLoption)option, buf);
|
|
+ res = curl_easy_setopt(self->handle, (CURLoption)option, str);
|
|
/* Check for errors */
|
|
if (res != CURLE_OK) {
|
|
- free(buf);
|
|
CURLERROR_RETVAL();
|
|
}
|
|
- /* Save allocated option buffer */
|
|
- opt_index = OPT_INDEX(option);
|
|
- if (self->options[opt_index] != NULL) {
|
|
- free(self->options[opt_index]);
|
|
- self->options[opt_index] = NULL;
|
|
- }
|
|
- self->options[opt_index] = buf;
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5267a6278f4b3993811a5eacf068942e01416d29 Mon Sep 17 00:00:00 2001
|
|
From: Christopher Warner <cwarner@kernelcode.com>
|
|
Date: Fri, 23 Apr 2010 16:06:41 +0000
|
|
Subject: [PATCH 003/112] Fixes https://sourceforge.net/tracker/?func=detail&aid=2812016&group_id=28236&atid=392777 with applied patch from sourceforge user dbprice1.
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
setup.py | 21 +++++++++++++++++----
|
|
1 files changed, 17 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/setup.py b/setup.py
|
|
index 1c3831b..632399d 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -9,7 +9,7 @@ PACKAGE = "pycurl"
|
|
PY_PACKAGE = "curl"
|
|
VERSION = "7.19.0"
|
|
|
|
-import glob, os, re, sys, string
|
|
+import glob, os, re, sys, string, subprocess
|
|
import distutils
|
|
from distutils.core import setup
|
|
from distutils.extension import Extension
|
|
@@ -96,9 +96,22 @@ else:
|
|
include_dirs.append(e[2:])
|
|
else:
|
|
extra_compile_args.append(e)
|
|
- libs = split_quoted(
|
|
- os.popen("'%s' --libs" % CURL_CONFIG).read()+\
|
|
- os.popen("'%s' --static-libs" % CURL_CONFIG).read())
|
|
+
|
|
+ # Run curl-config --libs and --static-libs. Some platforms may not
|
|
+ # support one or the other of these curl-config options, so gracefully
|
|
+ # tolerate failure of either, but not both.
|
|
+ optbuf = ""
|
|
+ for option in ["--libs", "--static-libs"]:
|
|
+ p = subprocess.Popen("'%s' %s" % (CURL_CONFIG, option), shell=True,
|
|
+ stdout=subprocess.PIPE)
|
|
+ (stdout, stderr) = p.communicate()
|
|
+ if p.wait() == 0:
|
|
+ optbuf += stdout
|
|
+ if optbuf == "":
|
|
+ raise Exception, ("Neither of curl-config --libs or --static-libs" +
|
|
+ "produced output")
|
|
+ libs = split_quoted(optbuf)
|
|
+
|
|
for e in libs:
|
|
if e[:2] == "-l":
|
|
libraries.append(e[2:])
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From efeb6581db4c6fd8980bb4007d14afce96ce4642 Mon Sep 17 00:00:00 2001
|
|
From: Christopher Warner <cwarner@kernelcode.com>
|
|
Date: Wed, 28 Apr 2010 16:02:41 +0000
|
|
Subject: [PATCH 004/112] Fixes refcount bug and provides better organization of PyCurl object. Submitted by dbprice1.
|
|
|
|
https://sourceforge.net/tracker/?func=detail&aid=2893665&group_id=28236&atid=392777
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 87 ++++++++++++++++++++++++++++++++++++++--------------------
|
|
1 files changed, 57 insertions(+), 30 deletions(-)
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index 189f5d6..47de850 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -739,64 +739,80 @@ util_curl_new(void)
|
|
return self;
|
|
}
|
|
|
|
-
|
|
-/* constructor - this is a module-level function returning a new instance */
|
|
-static CurlObject *
|
|
-do_curl_new(PyObject *dummy)
|
|
+/* initializer - used to intialize curl easy handles for use with pycurl */
|
|
+static int
|
|
+util_curl_init(CurlObject *self)
|
|
{
|
|
- CurlObject *self = NULL;
|
|
int res;
|
|
char *s = NULL;
|
|
|
|
- UNUSED(dummy);
|
|
-
|
|
- /* Allocate python curl object */
|
|
- self = util_curl_new();
|
|
- if (self == NULL)
|
|
- return NULL;
|
|
-
|
|
- /* Initialize curl handle */
|
|
- self->handle = curl_easy_init();
|
|
- if (self->handle == NULL)
|
|
- goto error;
|
|
-
|
|
/* Set curl error buffer and zero it */
|
|
res = curl_easy_setopt(self->handle, CURLOPT_ERRORBUFFER, self->error);
|
|
- if (res != CURLE_OK)
|
|
- goto error;
|
|
+ if (res != CURLE_OK) {
|
|
+ return (-1);
|
|
+ }
|
|
memset(self->error, 0, sizeof(self->error));
|
|
|
|
/* Set backreference */
|
|
res = curl_easy_setopt(self->handle, CURLOPT_PRIVATE, (char *) self);
|
|
- if (res != CURLE_OK)
|
|
- goto error;
|
|
+ if (res != CURLE_OK) {
|
|
+ return (-1);
|
|
+ }
|
|
|
|
/* Enable NOPROGRESS by default, i.e. no progress output */
|
|
res = curl_easy_setopt(self->handle, CURLOPT_NOPROGRESS, (long)1);
|
|
- if (res != CURLE_OK)
|
|
- goto error;
|
|
+ if (res != CURLE_OK) {
|
|
+ return (-1);
|
|
+ }
|
|
|
|
/* Disable VERBOSE by default, i.e. no verbose output */
|
|
res = curl_easy_setopt(self->handle, CURLOPT_VERBOSE, (long)0);
|
|
- if (res != CURLE_OK)
|
|
- goto error;
|
|
+ if (res != CURLE_OK) {
|
|
+ return (-1);
|
|
+ }
|
|
|
|
/* Set FTP_ACCOUNT to NULL by default */
|
|
res = curl_easy_setopt(self->handle, CURLOPT_FTP_ACCOUNT, NULL);
|
|
- if (res != CURLE_OK)
|
|
- goto error;
|
|
+ if (res != CURLE_OK) {
|
|
+ return (-1);
|
|
+ }
|
|
|
|
/* Set default USERAGENT */
|
|
s = (char *) malloc(7 + strlen(LIBCURL_VERSION) + 1);
|
|
- if (s == NULL)
|
|
- goto error;
|
|
+ if (s == NULL) {
|
|
+ return (-1);
|
|
+ }
|
|
strcpy(s, "PycURL/"); strcpy(s+7, LIBCURL_VERSION);
|
|
res = curl_easy_setopt(self->handle, CURLOPT_USERAGENT, (char *) s);
|
|
if (res != CURLE_OK) {
|
|
free(s);
|
|
- goto error;
|
|
+ return (-1);
|
|
}
|
|
+ return (0);
|
|
+}
|
|
+
|
|
+/* constructor - this is a module-level function returning a new instance */
|
|
+static CurlObject *
|
|
+do_curl_new(PyObject *dummy)
|
|
+{
|
|
+ CurlObject *self = NULL;
|
|
+ int res;
|
|
+
|
|
+ UNUSED(dummy);
|
|
+
|
|
+ /* Allocate python curl object */
|
|
+ self = util_curl_new();
|
|
+ if (self == NULL)
|
|
+ return NULL;
|
|
+
|
|
+ /* Initialize curl handle */
|
|
+ self->handle = curl_easy_init();
|
|
+ if (self->handle == NULL)
|
|
+ goto error;
|
|
|
|
+ res = util_curl_init(self);
|
|
+ if (res < 0)
|
|
+ goto error;
|
|
/* Success - return new object */
|
|
return self;
|
|
|
|
@@ -1404,6 +1420,8 @@ verbose_error:
|
|
static PyObject*
|
|
do_curl_reset(CurlObject *self)
|
|
{
|
|
+ int res;
|
|
+
|
|
curl_easy_reset(self->handle);
|
|
|
|
/* Decref callbacks and file handles */
|
|
@@ -1421,10 +1439,19 @@ do_curl_reset(CurlObject *self)
|
|
SFREE(self->postquote);
|
|
SFREE(self->prequote);
|
|
#undef SFREE
|
|
+ res = util_curl_init(self);
|
|
+ if (res < 0) {
|
|
+ Py_DECREF(self); /* this also closes self->handle */
|
|
+ PyErr_SetString(ErrorObject, "resetting curl failed");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
/* --------------- unsetopt/setopt/getinfo --------------- */
|
|
+ int res;
|
|
|
|
static PyObject *
|
|
util_curl_unsetopt(CurlObject *self, int option)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 6c8f676e53cf3a54836134ddc11d7a707793414d Mon Sep 17 00:00:00 2001
|
|
From: Christopher Warner <cwarner@kernelcode.com>
|
|
Date: Wed, 28 Apr 2010 16:03:40 +0000
|
|
Subject: [PATCH 005/112] Test for reset fixes refcount bug
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/test_reset.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 75 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/test_reset.py
|
|
|
|
diff --git a/tests/test_reset.py b/tests/test_reset.py
|
|
new file mode 100644
|
|
index 0000000..1addcfe
|
|
--- /dev/null
|
|
+++ b/tests/test_reset.py
|
|
@@ -0,0 +1,75 @@
|
|
+#!/usr/bin/python
|
|
+
|
|
+import sys
|
|
+import pycurl
|
|
+
|
|
+saw_error = 1
|
|
+
|
|
+def main():
|
|
+ global saw_error
|
|
+
|
|
+ pycurl.global_init(pycurl.GLOBAL_DEFAULT)
|
|
+
|
|
+ outf = file("/dev/null", "rb+")
|
|
+ cm = pycurl.CurlMulti()
|
|
+
|
|
+ # Set multi handle's options
|
|
+ cm.setopt(pycurl.M_PIPELINING, 1)
|
|
+
|
|
+ eh = pycurl.Curl()
|
|
+
|
|
+ for x in range(1, 20):
|
|
+
|
|
+ eh.setopt(pycurl.WRITEDATA, outf)
|
|
+ eh.setopt(pycurl.URL, sys.argv[1])
|
|
+ cm.add_handle(eh)
|
|
+
|
|
+ while 1:
|
|
+ ret, active_handles = cm.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ while active_handles:
|
|
+ ret = cm.select(1.0)
|
|
+ if ret == -1:
|
|
+ continue
|
|
+ while 1:
|
|
+ ret, active_handles = cm.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ count, good, bad = cm.info_read()
|
|
+
|
|
+ for h, en, em in bad:
|
|
+ print "Transfer to %s failed with %d, %s\n" % \
|
|
+ (h.getinfo(pycurl.EFFECTIVE_URL), en, em)
|
|
+ raise RuntimeError
|
|
+
|
|
+ for h in good:
|
|
+ httpcode = h.getinfo(pycurl.RESPONSE_CODE)
|
|
+ if httpcode != 200:
|
|
+ print "Transfer to %s failed with code %d\n" %\
|
|
+ (h.getinfo(pycurl.EFFECTIVE_URL), httpcode)
|
|
+ raise RuntimeError
|
|
+
|
|
+ else:
|
|
+ print "Recd %d bytes from %s" % \
|
|
+ (h.getinfo(pycurl.SIZE_DOWNLOAD),
|
|
+ h.getinfo(pycurl.EFFECTIVE_URL))
|
|
+
|
|
+ cm.remove_handle(eh)
|
|
+ eh.reset()
|
|
+
|
|
+ eh.close()
|
|
+ cm.close()
|
|
+ outf.close()
|
|
+
|
|
+ pycurl.global_cleanup()
|
|
+
|
|
+
|
|
+if __name__ == '__main__':
|
|
+ if len(sys.argv) != 2:
|
|
+ print "Usage: %s <url>" % sys.argv[0]
|
|
+ sys.exit(2)
|
|
+ main()
|
|
+
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5c2023a7a9373d7ca816c2546fd2db63432bba0c Mon Sep 17 00:00:00 2001
|
|
From: Christopher Warner <cwarner@kernelcode.com>
|
|
Date: Wed, 28 Apr 2010 16:06:35 +0000
|
|
Subject: [PATCH 006/112] Added myself to the list of maintainers
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
setup.py | 4 ++--
|
|
1 files changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/setup.py b/setup.py
|
|
index 632399d..33704ef 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -197,8 +197,8 @@ setup_args = get_kw(
|
|
description="PycURL -- cURL library module for Python",
|
|
author="Kjetil Jacobsen, Markus F.X.J. Oberhumer",
|
|
author_email="kjetilja at gmail.com, markus at oberhumer.com",
|
|
- maintainer="Kjetil Jacobsen, Markus F.X.J. Oberhumer",
|
|
- maintainer_email="kjetilja at gmail.com, markus at oberhumer.com",
|
|
+ maintainer="Kjetil Jacobsen, Markus F.X.J. Oberhumer, Christopher Warner",
|
|
+ maintainer_email="kjetilja at gmail.com, markus at oberhumer.com, cwarner at kernelcode.com",
|
|
url="http://pycurl.sourceforge.net/",
|
|
license="LGPL/MIT",
|
|
data_files=get_data_files(),
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 86777baedfac6c10ec0edd4e1e68519be83740e1 Mon Sep 17 00:00:00 2001
|
|
From: Christopher Warner <cwarner@kernelcode.com>
|
|
Date: Tue, 4 May 2010 18:47:08 +0000
|
|
Subject: [PATCH 007/112] Updating ChangeLog with relevant changes
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
ChangeLog | 11 +++++++++++
|
|
1 files changed, 11 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/ChangeLog b/ChangeLog
|
|
index 618654d..885c8b0 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -1,3 +1,14 @@
|
|
+Version 7.19.2
|
|
+--------------
|
|
+
|
|
+ * Cleaned up website
|
|
+
|
|
+ * Fix pycurl.reset() (patch by <johansen at sun.com>).
|
|
+
|
|
+ * Fix install routine in setup.py where
|
|
+ certain platforms (Solaris, Mac OSX, etc)
|
|
+ would search for a static copy of libcurl (dbp)
|
|
+
|
|
Version 7.19.1 [requires libcurl-7.19.0 or better]
|
|
--------------
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From f42d34b86ce7c4d93bde71d7d1c56486bd98afa3 Mon Sep 17 00:00:00 2001
|
|
From: Christopher Warner <cwarner@kernelcode.com>
|
|
Date: Wed, 13 Oct 2010 15:53:40 +0000
|
|
Subject: [PATCH 008/112] Added CURLOPT_SEEKFUNCTION, CURLOPT_SEEKDATA
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
1 files changed, 88 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index 47de850..ac448b0 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -150,6 +150,7 @@ typedef struct {
|
|
PyObject *debug_cb;
|
|
PyObject *ioctl_cb;
|
|
PyObject *opensocket_cb;
|
|
+ PyObject *seek_cb;
|
|
/* file objects */
|
|
PyObject *readdata_fp;
|
|
PyObject *writedata_fp;
|
|
@@ -727,6 +728,7 @@ util_curl_new(void)
|
|
self->debug_cb = NULL;
|
|
self->ioctl_cb = NULL;
|
|
self->opensocket_cb = NULL;
|
|
+ self->seek_cb = NULL;
|
|
|
|
/* Set file object pointers to NULL by default */
|
|
self->readdata_fp = NULL;
|
|
@@ -1181,6 +1183,82 @@ verbose_error:
|
|
goto silent_error;
|
|
}
|
|
|
|
+static int
|
|
+seek_callback(void *stream, curl_off_t offset, int origin)
|
|
+{
|
|
+ CurlObject *self;
|
|
+ PyThreadState *tmp_state;
|
|
+ PyObject *arglist;
|
|
+ PyObject *result = NULL;
|
|
+ int ret = 2; /* assume error 2 (can't seek, libcurl free to work around). */
|
|
+ PyObject *cb;
|
|
+ int source = 0; /* assume beginning */
|
|
+
|
|
+ /* acquire thread */
|
|
+ self = (CurlObject *)stream;
|
|
+ tmp_state = get_thread_state(self);
|
|
+ if (tmp_state == NULL)
|
|
+ return ret;
|
|
+ PyEval_AcquireThread(tmp_state);
|
|
+
|
|
+ /* check arguments */
|
|
+ switch (origin)
|
|
+ {
|
|
+ case SEEK_SET:
|
|
+ source = 0;
|
|
+ break;
|
|
+ case SEEK_CUR:
|
|
+ source = 1;
|
|
+ break;
|
|
+ case SEEK_END:
|
|
+ source = 2;
|
|
+ break;
|
|
+ default:
|
|
+ source = origin;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* run callback */
|
|
+ cb = self->seek_cb;
|
|
+ if (cb == NULL)
|
|
+ goto silent_error;
|
|
+ arglist = Py_BuildValue("(i,i)", offset, source);
|
|
+ if (arglist == NULL)
|
|
+ goto verbose_error;
|
|
+ result = PyEval_CallObject(cb, arglist);
|
|
+ Py_DECREF(arglist);
|
|
+ if (result == NULL)
|
|
+ goto verbose_error;
|
|
+
|
|
+ /* handle result */
|
|
+ if (result == Py_None) {
|
|
+ ret = 0; /* None means success */
|
|
+ }
|
|
+ else if (PyInt_Check(result)) {
|
|
+ int ret_code = PyInt_AsLong(result);
|
|
+ if (ret_code < 0 || ret_code > 2) {
|
|
+ PyErr_Format(ErrorObject, "invalid return value for seek callback %d not in (0, 1, 2)", ret_code);
|
|
+ goto verbose_error;
|
|
+ }
|
|
+ ret = ret_code; /* pass the return code from the callback */
|
|
+ }
|
|
+ else {
|
|
+ PyErr_SetString(ErrorObject, "seek callback must return 0 (CURL_SEEKFUNC_OK), 1 (CURL_SEEKFUNC_FAIL), 2 (CURL_SEEKFUNC_CANTSEEK) or None");
|
|
+ goto verbose_error;
|
|
+ }
|
|
+
|
|
+silent_error:
|
|
+ Py_XDECREF(result);
|
|
+ PyEval_ReleaseThread(tmp_state);
|
|
+ return ret;
|
|
+verbose_error:
|
|
+ PyErr_Print();
|
|
+ goto silent_error;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
static size_t
|
|
read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
|
|
{
|
|
@@ -1988,7 +2066,8 @@ do_curl_setopt(CurlObject *self, PyObject *args)
|
|
const curl_progress_callback pro_cb = progress_callback;
|
|
const curl_debug_callback debug_cb = debug_callback;
|
|
const curl_ioctl_callback ioctl_cb = ioctl_callback;
|
|
- const curl_opensocket_callback opensocket_cb = opensocket_callback;
|
|
+ const curl_opensocket_callback opensocket_cb = opensocket_callback;
|
|
+ const curl_seek_callback seek_cb = seek_callback;
|
|
|
|
switch(option) {
|
|
case CURLOPT_WRITEFUNCTION:
|
|
@@ -2046,6 +2125,13 @@ do_curl_setopt(CurlObject *self, PyObject *args)
|
|
curl_easy_setopt(self->handle, CURLOPT_OPENSOCKETFUNCTION, opensocket_cb);
|
|
curl_easy_setopt(self->handle, CURLOPT_OPENSOCKETDATA, self);
|
|
break;
|
|
+ case CURLOPT_SEEKFUNCTION:
|
|
+ Py_INCREF(obj);
|
|
+ ZAP(self->seek_cb);
|
|
+ self->seek_cb = obj;
|
|
+ curl_easy_setopt(self->handle, CURLOPT_SEEKFUNCTION, seek_cb);
|
|
+ curl_easy_setopt(self->handle, CURLOPT_SEEKDATA, self);
|
|
+ break;
|
|
|
|
default:
|
|
/* None of the function options were recognized, throw exception */
|
|
@@ -3616,6 +3702,7 @@ initpycurl(void)
|
|
insint_c(d, "PREQUOTE", CURLOPT_PREQUOTE);
|
|
insint_c(d, "WRITEHEADER", CURLOPT_WRITEHEADER);
|
|
insint_c(d, "HEADERFUNCTION", CURLOPT_HEADERFUNCTION);
|
|
+ insint_c(d, "SEEKFUNCTION", CURLOPT_SEEKFUNCTION);
|
|
insint_c(d, "COOKIEFILE", CURLOPT_COOKIEFILE);
|
|
insint_c(d, "SSLVERSION", CURLOPT_SSLVERSION);
|
|
insint_c(d, "TIMECONDITION", CURLOPT_TIMECONDITION);
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From cd16f58fd7e2a089408ad0275bdcac6d6e5e1b7e Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Tue, 26 Feb 2013 09:13:24 +0100
|
|
Subject: [PATCH 009/112] pycurl.c: remove a left-over global variable introduced in r150
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 1 -
|
|
1 files changed, 0 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index ac448b0..094bc60 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -1529,7 +1529,6 @@ do_curl_reset(CurlObject *self)
|
|
}
|
|
|
|
/* --------------- unsetopt/setopt/getinfo --------------- */
|
|
- int res;
|
|
|
|
static PyObject *
|
|
util_curl_unsetopt(CurlObject *self, int option)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 802240d937867454026b6d8baaded841f6f32057 Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Mon, 25 Feb 2013 19:50:18 +0100
|
|
Subject: [PATCH 010/112] test_internals.py: add a test for ref-counting in reset()
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/test_internals.py | 5 +++++
|
|
1 files changed, 5 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/test_internals.py b/tests/test_internals.py
|
|
index a1a6533..3f5eefd 100644
|
|
--- a/tests/test_internals.py
|
|
+++ b/tests/test_internals.py
|
|
@@ -245,6 +245,11 @@ if 1 and gc:
|
|
if opts.verbose >= 1:
|
|
print "Tracked objects:", len(gc.get_objects())
|
|
|
|
+if 1:
|
|
+ # Ensure that the refcounting error in "reset" is fixed:
|
|
+ for i in xrange(100000):
|
|
+ c = Curl()
|
|
+ c.reset()
|
|
|
|
# /***********************************************************************
|
|
# // done
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 2baf0fab555c9f0f292e400222c79b01f9211abf Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 01:15:00 -0500
|
|
Subject: [PATCH 011/112] Add gitignore
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.gitignore | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
create mode 100644 .gitignore
|
|
|
|
diff --git a/.gitignore b/.gitignore
|
|
new file mode 100644
|
|
index 0000000..796b96d
|
|
--- /dev/null
|
|
+++ b/.gitignore
|
|
@@ -0,0 +1 @@
|
|
+/build
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 53a2bfa7c8f381a4d4465d204fc3e4f7133a2db6 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 1 Mar 2013 00:11:47 -0500
|
|
Subject: [PATCH 012/112] A much simpler request test, in unittest format
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/request_test.py | 31 +++++++++++++++++++++++++++++++
|
|
1 files changed, 31 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/request_test.py
|
|
|
|
diff --git a/tests/request_test.py b/tests/request_test.py
|
|
new file mode 100644
|
|
index 0000000..0761d6c
|
|
--- /dev/null
|
|
+++ b/tests/request_test.py
|
|
@@ -0,0 +1,31 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+try:
|
|
+ from cStringIO import StringIO
|
|
+except ImportError:
|
|
+ try:
|
|
+ from StringIO import StringIO
|
|
+ except ImportError:
|
|
+ from io import StringIO
|
|
+
|
|
+class RequestTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_perform_get(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost')
|
|
+ self.curl.perform()
|
|
+
|
|
+ def test_perform_get_with_write_function(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost')
|
|
+ sio = StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+ print(sio.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 127442bead3a274cc5239e6389682d239c1fcbca Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 1 Mar 2013 13:35:59 -0500
|
|
Subject: [PATCH 013/112] init.py for test package
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
0 files changed, 0 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/__init__.py
|
|
|
|
diff --git a/tests/__init__.py b/tests/__init__.py
|
|
new file mode 100644
|
|
index 0000000..e69de29
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 97ac029a9e925bd4903bd7a41e69110e158ec897 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 1 Mar 2013 13:36:08 -0500
|
|
Subject: [PATCH 014/112] wsgi application runner
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/runwsgi.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 82 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/runwsgi.py
|
|
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
new file mode 100644
|
|
index 0000000..d658614
|
|
--- /dev/null
|
|
+++ b/tests/runwsgi.py
|
|
@@ -0,0 +1,82 @@
|
|
+# Run a WSGI application in a daemon thread
|
|
+
|
|
+import bottle
|
|
+import threading
|
|
+import socket
|
|
+import time as _time
|
|
+
|
|
+class Server(bottle.WSGIRefServer):
|
|
+ def run(self, handler): # pragma: no cover
|
|
+ from wsgiref.simple_server import make_server, WSGIRequestHandler
|
|
+ if self.quiet:
|
|
+ base = self.options.get('handler_class', WSGIRequestHandler)
|
|
+ class QuietHandler(base):
|
|
+ def log_request(*args, **kw): pass
|
|
+ self.options['handler_class'] = QuietHandler
|
|
+ self.srv = make_server(self.host, self.port, handler, **self.options)
|
|
+ self.srv.serve_forever(poll_interval=0.1)
|
|
+
|
|
+def start_bottle_server(app, port, **kwargs):
|
|
+ server_thread = ServerThread(app, port, kwargs)
|
|
+ server_thread.daemon = True
|
|
+ server_thread.start()
|
|
+
|
|
+ ok = False
|
|
+ for i in range(10):
|
|
+ try:
|
|
+ conn = socket.create_connection(('127.0.0.1', port), 0.1)
|
|
+ except socket.error as e:
|
|
+ _time.sleep(0.1)
|
|
+ else:
|
|
+ conn.close()
|
|
+ ok = True
|
|
+ break
|
|
+ if not ok:
|
|
+ import warnings
|
|
+ warnings.warn('Server did not start after 1 second')
|
|
+
|
|
+ return server_thread.server
|
|
+
|
|
+class ServerThread(threading.Thread):
|
|
+ def __init__(self, app, port, server_kwargs):
|
|
+ threading.Thread.__init__(self)
|
|
+ self.app = app
|
|
+ self.port = port
|
|
+ self.server_kwargs = server_kwargs
|
|
+ self.server = Server(host='localhost', port=self.port, **self.server_kwargs)
|
|
+
|
|
+ def run(self):
|
|
+ bottle.run(self.app, server=self.server, quiet=True)
|
|
+
|
|
+def app_runner_setup(*specs):
|
|
+ '''Returns setup and teardown methods for running a list of WSGI
|
|
+ applications in a daemon thread.
|
|
+
|
|
+ Each argument is an (app, port) pair.
|
|
+
|
|
+ Return value is a (setup, teardown) function pair.
|
|
+
|
|
+ The setup and teardown functions expect to be called with an argument
|
|
+ on which server state will be stored.
|
|
+
|
|
+ Example usage with nose:
|
|
+
|
|
+ >>> setup_module, teardown_module = \
|
|
+ runwsgi.app_runner_setup((app_module.app, 8050))
|
|
+ '''
|
|
+
|
|
+ def setup(self):
|
|
+ self.servers = []
|
|
+ for spec in specs:
|
|
+ if len(spec) == 2:
|
|
+ app, port = spec
|
|
+ kwargs = {}
|
|
+ else:
|
|
+ app, port, kwargs = spec
|
|
+ self.servers.append(start_bottle_server(app, port, **kwargs))
|
|
+
|
|
+ def teardown(self):
|
|
+ for server in self.servers:
|
|
+ server.srv.shutdown()
|
|
+
|
|
+ return [setup, teardown]
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 766e9a77708953c56b33d087561eddab853a08da Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 1 Mar 2013 14:06:42 -0500
|
|
Subject: [PATCH 015/112] Test application to be on the server side
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/app.py | 7 +++++++
|
|
1 files changed, 7 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/app.py
|
|
|
|
diff --git a/tests/app.py b/tests/app.py
|
|
new file mode 100644
|
|
index 0000000..b173fd6
|
|
--- /dev/null
|
|
+++ b/tests/app.py
|
|
@@ -0,0 +1,7 @@
|
|
+import bottle
|
|
+
|
|
+app = bottle.Bottle()
|
|
+
|
|
+@app.route('/success')
|
|
+def ok():
|
|
+ return 'success'
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From a1449f4986686920904d7f781327e3ca520e4933 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 1 Mar 2013 14:07:04 -0500
|
|
Subject: [PATCH 016/112] Use the test application in request test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/request_test.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++--
|
|
1 files changed, 56 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/tests/request_test.py b/tests/request_test.py
|
|
index 0761d6c..127fbeb 100644
|
|
--- a/tests/request_test.py
|
|
+++ b/tests/request_test.py
|
|
@@ -2,8 +2,12 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
+import os
|
|
+import sys
|
|
+import tempfile
|
|
import pycurl
|
|
import unittest
|
|
+import io
|
|
try:
|
|
from cStringIO import StringIO
|
|
except ImportError:
|
|
@@ -12,6 +16,11 @@ except ImportError:
|
|
except ImportError:
|
|
from io import StringIO
|
|
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
class RequestTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.curl = pycurl.Curl()
|
|
@@ -20,12 +29,56 @@ class RequestTest(unittest.TestCase):
|
|
self.curl.close()
|
|
|
|
def test_perform_get(self):
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost')
|
|
+ # This test performs a GET request without doing anything else.
|
|
+ # Unfortunately, the default curl behavior is to print response
|
|
+ # body to standard output, which spams test output.
|
|
+ # As a result this test is commented out. Uncomment for debugging.
|
|
+ # test_perform_get_with_default_write_function is the test
|
|
+ # which exercises default curl write handler.
|
|
+ return
|
|
+
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
self.curl.perform()
|
|
|
|
def test_perform_get_with_write_function(self):
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost')
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
sio = StringIO()
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
self.curl.perform()
|
|
- print(sio.getvalue())
|
|
+ self.assertEqual('success', sio.getvalue())
|
|
+
|
|
+ def test_perform_get_with_default_write_function(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ #with tempfile.NamedTemporaryFile() as f:
|
|
+ with open('w', 'w+') as f:
|
|
+ # nose output capture plugin replaces sys.stdout with a StringIO
|
|
+ # instance. We want to redirect the underlying file descriptor
|
|
+ # anyway because underlying C code uses it.
|
|
+ # But keep track of whether we replace sys.stdout.
|
|
+ perform_dup = False
|
|
+ if hasattr(sys.stdout, 'fileno'):
|
|
+ try:
|
|
+ sys.stdout.fileno()
|
|
+ perform_dup = True
|
|
+ except io.UnsupportedOperation:
|
|
+ # stdout is a StringIO
|
|
+ pass
|
|
+ if perform_dup:
|
|
+ saved_stdout_fd = os.dup(sys.stdout.fileno())
|
|
+ os.dup2(f.fileno(), sys.stdout.fileno())
|
|
+ else:
|
|
+ saved_stdout = sys.stdout
|
|
+ sys.stdout = f
|
|
+ try:
|
|
+ self.curl.perform()
|
|
+ finally:
|
|
+ sys.stdout.flush()
|
|
+ if perform_dup:
|
|
+ os.fsync(sys.stdout.fileno())
|
|
+ os.dup2(saved_stdout_fd, sys.stdout.fileno())
|
|
+ os.close(saved_stdout_fd)
|
|
+ else:
|
|
+ sys.stdout = saved_stdout
|
|
+ f.seek(0)
|
|
+ body = f.read()
|
|
+ self.assertEqual('success', body)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From b332c2265bd3958a964bd2e69f9eeda96bafc814 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sat, 2 Mar 2013 02:23:27 -0500
|
|
Subject: [PATCH 017/112] Put stringio import into util
|
|
|
|
This way all tests can simply import stringio from util in one line.
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/util.py | 8 ++++++++
|
|
1 files changed, 8 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/util.py b/tests/util.py
|
|
index a1a9978..891da44 100644
|
|
--- a/tests/util.py
|
|
+++ b/tests/util.py
|
|
@@ -4,6 +4,14 @@
|
|
|
|
import os, sys
|
|
|
|
+try:
|
|
+ from cStringIO import StringIO
|
|
+except ImportError:
|
|
+ try:
|
|
+ from StringIO import StringIO
|
|
+ except ImportError:
|
|
+ from io import StringIO
|
|
+
|
|
#
|
|
# prepare sys.path in case we are still in the build directory
|
|
# see also: distutils/command/build.py (build_platlib)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c912395f00df7a91f3d9c0fcc16821c7cc25bf63 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sat, 2 Mar 2013 02:24:11 -0500
|
|
Subject: [PATCH 018/112] Debug test, ported from the old debug test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/debug_test.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 46 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/debug_test.py
|
|
|
|
diff --git a/tests/debug_test.py b/tests/debug_test.py
|
|
new file mode 100644
|
|
index 0000000..dd00719
|
|
--- /dev/null
|
|
+++ b/tests/debug_test.py
|
|
@@ -0,0 +1,46 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class DebugTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+ self.debug_entries = []
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def debug_function(self, t, b):
|
|
+ self.debug_entries.append((t, b))
|
|
+
|
|
+ def test_perform_get_with_debug_function(self):
|
|
+ self.curl.setopt(pycurl.VERBOSE, 1)
|
|
+ self.curl.setopt(pycurl.DEBUGFUNCTION, self.debug_function)
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ self.curl.perform()
|
|
+
|
|
+ # Some checks with no particular intent
|
|
+ self.check(0, 'About to connect')
|
|
+ self.check(0, 'Connected to localhost')
|
|
+ self.check(0, 'port 8380')
|
|
+ # request
|
|
+ self.check(2, 'GET /success HTTP/1.1')
|
|
+ # response
|
|
+ self.check(1, 'HTTP/1.0 200 OK')
|
|
+ self.check(1, 'Content-Length: 7')
|
|
+ # result
|
|
+ self.check(3, 'success')
|
|
+
|
|
+ def check(self, wanted_t, wanted_b):
|
|
+ for t, b in self.debug_entries:
|
|
+ if t == wanted_t and wanted_b in b:
|
|
+ return
|
|
+ assert False, "%d: %s not found in debug entries" % (wanted_t, wanted_b)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From d3133de193791e731867c0ab02c49cd3f88422c0 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sat, 2 Mar 2013 02:43:57 -0500
|
|
Subject: [PATCH 019/112] Write output to a stringio to avoid stdout spam
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/debug_test.py | 3 +++
|
|
1 files changed, 3 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/debug_test.py b/tests/debug_test.py
|
|
index dd00719..8005239 100644
|
|
--- a/tests/debug_test.py
|
|
+++ b/tests/debug_test.py
|
|
@@ -7,6 +7,7 @@ import unittest
|
|
|
|
from . import app
|
|
from . import runwsgi
|
|
+from . import util
|
|
|
|
setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
@@ -25,6 +26,8 @@ class DebugTest(unittest.TestCase):
|
|
self.curl.setopt(pycurl.VERBOSE, 1)
|
|
self.curl.setopt(pycurl.DEBUGFUNCTION, self.debug_function)
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
self.curl.perform()
|
|
|
|
# Some checks with no particular intent
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From ff2df7b5ef851c29328dfb1ff501ff610690c63b Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sat, 2 Mar 2013 02:44:24 -0500
|
|
Subject: [PATCH 020/112] Use stringio from util in request test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/request_test.py | 10 ++--------
|
|
1 files changed, 2 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/tests/request_test.py b/tests/request_test.py
|
|
index 127fbeb..afd8566 100644
|
|
--- a/tests/request_test.py
|
|
+++ b/tests/request_test.py
|
|
@@ -8,16 +8,10 @@ import tempfile
|
|
import pycurl
|
|
import unittest
|
|
import io
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- try:
|
|
- from StringIO import StringIO
|
|
- except ImportError:
|
|
- from io import StringIO
|
|
|
|
from . import app
|
|
from . import runwsgi
|
|
+from . import util
|
|
|
|
setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
@@ -42,7 +36,7 @@ class RequestTest(unittest.TestCase):
|
|
|
|
def test_perform_get_with_write_function(self):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
- sio = StringIO()
|
|
+ sio = util.StringIO()
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
self.curl.perform()
|
|
self.assertEqual('success', sio.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 8121df921a0615d1f5c6793ad86e17dc20e00902 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sat, 2 Mar 2013 04:06:00 -0500
|
|
Subject: [PATCH 021/112] Add a test that writes response to a file
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/request_test.py | 9 +++++++++
|
|
1 files changed, 9 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/request_test.py b/tests/request_test.py
|
|
index afd8566..7386a51 100644
|
|
--- a/tests/request_test.py
|
|
+++ b/tests/request_test.py
|
|
@@ -41,6 +41,15 @@ class RequestTest(unittest.TestCase):
|
|
self.curl.perform()
|
|
self.assertEqual('success', sio.getvalue())
|
|
|
|
+ def test_write_to_file(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ with tempfile.NamedTemporaryFile() as f:
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, f.write)
|
|
+ self.curl.perform()
|
|
+ f.seek(0)
|
|
+ body = f.read()
|
|
+ self.assertEqual('success', body)
|
|
+
|
|
def test_perform_get_with_default_write_function(self):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
#with tempfile.NamedTemporaryFile() as f:
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5c59850b231cc0e9d38c7d56e67d55500e024577 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:14:26 -0500
|
|
Subject: [PATCH 022/112] Account for the case of nose running no tests
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/runwsgi.py | 4 +++-
|
|
1 files changed, 3 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
index d658614..7b39358 100644
|
|
--- a/tests/runwsgi.py
|
|
+++ b/tests/runwsgi.py
|
|
@@ -77,6 +77,8 @@ def app_runner_setup(*specs):
|
|
|
|
def teardown(self):
|
|
for server in self.servers:
|
|
- server.srv.shutdown()
|
|
+ # if no tests from module were run, there is no server to shut down
|
|
+ if hasattr(server, 'srv'):
|
|
+ server.srv.shutdown()
|
|
|
|
return [setup, teardown]
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 48ac39062e8cd19ee4ddf590278aa6e35477a8d3 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:14:41 -0500
|
|
Subject: [PATCH 023/112] Split request test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 70 +++++++++++++++++++++++++++
|
|
tests/request_test.py | 87 ----------------------------------
|
|
tests/write_to_file_test.py | 29 +++++++++++
|
|
tests/write_to_stringio_test.py | 30 ++++++++++++
|
|
4 files changed, 129 insertions(+), 87 deletions(-)
|
|
create mode 100644 tests/default_write_function_test.py
|
|
delete mode 100644 tests/request_test.py
|
|
create mode 100644 tests/write_to_file_test.py
|
|
create mode 100644 tests/write_to_stringio_test.py
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
new file mode 100644
|
|
index 0000000..2efc579
|
|
--- /dev/null
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -0,0 +1,70 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import unittest
|
|
+import pycurl
|
|
+import sys
|
|
+import tempfile
|
|
+import io
|
|
+import os
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class RequestTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_perform_get(self):
|
|
+ # This test performs a GET request without doing anything else.
|
|
+ # Unfortunately, the default curl behavior is to print response
|
|
+ # body to standard output, which spams test output.
|
|
+ # As a result this test is commented out. Uncomment for debugging.
|
|
+ # test_perform_get_with_default_write_function is the test
|
|
+ # which exercises default curl write handler.
|
|
+
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ self.curl.perform()
|
|
+
|
|
+ def test_perform_get_with_default_write_function(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ #with tempfile.NamedTemporaryFile() as f:
|
|
+ with open('w', 'w+') as f:
|
|
+ # nose output capture plugin replaces sys.stdout with a StringIO
|
|
+ # instance. We want to redirect the underlying file descriptor
|
|
+ # anyway because underlying C code uses it.
|
|
+ # But keep track of whether we replace sys.stdout.
|
|
+ perform_dup = False
|
|
+ if hasattr(sys.stdout, 'fileno'):
|
|
+ try:
|
|
+ sys.stdout.fileno()
|
|
+ perform_dup = True
|
|
+ except io.UnsupportedOperation:
|
|
+ # stdout is a StringIO
|
|
+ pass
|
|
+ if perform_dup:
|
|
+ saved_stdout_fd = os.dup(sys.stdout.fileno())
|
|
+ os.dup2(f.fileno(), sys.stdout.fileno())
|
|
+ else:
|
|
+ saved_stdout = sys.stdout
|
|
+ sys.stdout = f
|
|
+ try:
|
|
+ self.curl.perform()
|
|
+ finally:
|
|
+ sys.stdout.flush()
|
|
+ if perform_dup:
|
|
+ os.fsync(sys.stdout.fileno())
|
|
+ os.dup2(saved_stdout_fd, sys.stdout.fileno())
|
|
+ os.close(saved_stdout_fd)
|
|
+ else:
|
|
+ sys.stdout = saved_stdout
|
|
+ f.seek(0)
|
|
+ body = f.read()
|
|
+ self.assertEqual('success', body)
|
|
diff --git a/tests/request_test.py b/tests/request_test.py
|
|
deleted file mode 100644
|
|
index 7386a51..0000000
|
|
--- a/tests/request_test.py
|
|
+++ /dev/null
|
|
@@ -1,87 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-
|
|
-import os
|
|
-import sys
|
|
-import tempfile
|
|
-import pycurl
|
|
-import unittest
|
|
-import io
|
|
-
|
|
-from . import app
|
|
-from . import runwsgi
|
|
-from . import util
|
|
-
|
|
-setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
-
|
|
-class RequestTest(unittest.TestCase):
|
|
- def setUp(self):
|
|
- self.curl = pycurl.Curl()
|
|
-
|
|
- def tearDown(self):
|
|
- self.curl.close()
|
|
-
|
|
- def test_perform_get(self):
|
|
- # This test performs a GET request without doing anything else.
|
|
- # Unfortunately, the default curl behavior is to print response
|
|
- # body to standard output, which spams test output.
|
|
- # As a result this test is commented out. Uncomment for debugging.
|
|
- # test_perform_get_with_default_write_function is the test
|
|
- # which exercises default curl write handler.
|
|
- return
|
|
-
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
- self.curl.perform()
|
|
-
|
|
- def test_perform_get_with_write_function(self):
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
- sio = util.StringIO()
|
|
- self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
- self.curl.perform()
|
|
- self.assertEqual('success', sio.getvalue())
|
|
-
|
|
- def test_write_to_file(self):
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
- with tempfile.NamedTemporaryFile() as f:
|
|
- self.curl.setopt(pycurl.WRITEFUNCTION, f.write)
|
|
- self.curl.perform()
|
|
- f.seek(0)
|
|
- body = f.read()
|
|
- self.assertEqual('success', body)
|
|
-
|
|
- def test_perform_get_with_default_write_function(self):
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
- #with tempfile.NamedTemporaryFile() as f:
|
|
- with open('w', 'w+') as f:
|
|
- # nose output capture plugin replaces sys.stdout with a StringIO
|
|
- # instance. We want to redirect the underlying file descriptor
|
|
- # anyway because underlying C code uses it.
|
|
- # But keep track of whether we replace sys.stdout.
|
|
- perform_dup = False
|
|
- if hasattr(sys.stdout, 'fileno'):
|
|
- try:
|
|
- sys.stdout.fileno()
|
|
- perform_dup = True
|
|
- except io.UnsupportedOperation:
|
|
- # stdout is a StringIO
|
|
- pass
|
|
- if perform_dup:
|
|
- saved_stdout_fd = os.dup(sys.stdout.fileno())
|
|
- os.dup2(f.fileno(), sys.stdout.fileno())
|
|
- else:
|
|
- saved_stdout = sys.stdout
|
|
- sys.stdout = f
|
|
- try:
|
|
- self.curl.perform()
|
|
- finally:
|
|
- sys.stdout.flush()
|
|
- if perform_dup:
|
|
- os.fsync(sys.stdout.fileno())
|
|
- os.dup2(saved_stdout_fd, sys.stdout.fileno())
|
|
- os.close(saved_stdout_fd)
|
|
- else:
|
|
- sys.stdout = saved_stdout
|
|
- f.seek(0)
|
|
- body = f.read()
|
|
- self.assertEqual('success', body)
|
|
diff --git a/tests/write_to_file_test.py b/tests/write_to_file_test.py
|
|
new file mode 100644
|
|
index 0000000..6528f81
|
|
--- /dev/null
|
|
+++ b/tests/write_to_file_test.py
|
|
@@ -0,0 +1,29 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import unittest
|
|
+import pycurl
|
|
+import tempfile
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class RequestTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_get_to_file(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ with tempfile.NamedTemporaryFile() as f:
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, f.write)
|
|
+ self.curl.perform()
|
|
+ f.seek(0)
|
|
+ body = f.read()
|
|
+ self.assertEqual('success', body)
|
|
diff --git a/tests/write_to_stringio_test.py b/tests/write_to_stringio_test.py
|
|
new file mode 100644
|
|
index 0000000..fd1c28d
|
|
--- /dev/null
|
|
+++ b/tests/write_to_stringio_test.py
|
|
@@ -0,0 +1,30 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import os
|
|
+import sys
|
|
+import tempfile
|
|
+import pycurl
|
|
+import unittest
|
|
+import io
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class WriteToStringioTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_get(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+ self.assertEqual('success', sio.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 3f765182563497ed5dc0348474e8e9f30618576e Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:22:05 -0500
|
|
Subject: [PATCH 024/112] Need to flush when using default write function
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 5 ++++-
|
|
1 files changed, 4 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index 2efc579..afbba33 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -32,6 +32,9 @@ class RequestTest(unittest.TestCase):
|
|
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
self.curl.perform()
|
|
+ # If this flush is not done, stdout output bleeds into the next test
|
|
+ # that is executed
|
|
+ sys.stdout.flush()
|
|
|
|
def test_perform_get_with_default_write_function(self):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
@@ -57,8 +60,8 @@ class RequestTest(unittest.TestCase):
|
|
sys.stdout = f
|
|
try:
|
|
self.curl.perform()
|
|
- finally:
|
|
sys.stdout.flush()
|
|
+ finally:
|
|
if perform_dup:
|
|
os.fsync(sys.stdout.fileno())
|
|
os.dup2(saved_stdout_fd, sys.stdout.fileno())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 8515cd10d9ead70ce306fcf2de96b0d34a402d88 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:34:39 -0500
|
|
Subject: [PATCH 025/112] Trying to get the default write function test to work with nose output capture, but no luck so far
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 52 +++++++++++++++++----------------
|
|
1 files changed, 27 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index afbba33..853992b 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -15,6 +15,8 @@ from . import util
|
|
|
|
setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
+STDOUT_FD_NUM = 1
|
|
+
|
|
class RequestTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.curl = pycurl.Curl()
|
|
@@ -33,41 +35,41 @@ class RequestTest(unittest.TestCase):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
self.curl.perform()
|
|
# If this flush is not done, stdout output bleeds into the next test
|
|
- # that is executed
|
|
+ # that is executed (without nose output capture)
|
|
sys.stdout.flush()
|
|
+ os.fsync(STDOUT_FD_NUM)
|
|
|
|
- def test_perform_get_with_default_write_function(self):
|
|
+ # I have a really hard time getting this to work with nose output capture
|
|
+ def skip_test_perform_get_with_default_write_function(self):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
- #with tempfile.NamedTemporaryFile() as f:
|
|
- with open('w', 'w+') as f:
|
|
+ with tempfile.NamedTemporaryFile() as f:
|
|
+ #with open('w', 'w+') as f:
|
|
# nose output capture plugin replaces sys.stdout with a StringIO
|
|
# instance. We want to redirect the underlying file descriptor
|
|
# anyway because underlying C code uses it.
|
|
- # But keep track of whether we replace sys.stdout.
|
|
- perform_dup = False
|
|
- if hasattr(sys.stdout, 'fileno'):
|
|
- try:
|
|
- sys.stdout.fileno()
|
|
- perform_dup = True
|
|
- except io.UnsupportedOperation:
|
|
- # stdout is a StringIO
|
|
- pass
|
|
- if perform_dup:
|
|
- saved_stdout_fd = os.dup(sys.stdout.fileno())
|
|
- os.dup2(f.fileno(), sys.stdout.fileno())
|
|
- else:
|
|
- saved_stdout = sys.stdout
|
|
- sys.stdout = f
|
|
+ # Therefore:
|
|
+ # 1. Use file descriptor 1 rather than sys.stdout.fileno() to
|
|
+ # reference the standard output file descriptor.
|
|
+ # 2. We do not touch sys.stdout. This means anything written to
|
|
+ # sys.stdout will be captured by nose, and not make it to our code.
|
|
+ # But the output we care about happens at libcurl level, below
|
|
+ # nose, therefore this is fine.
|
|
+ saved_stdout_fd = os.dup(STDOUT_FD_NUM)
|
|
+ os.dup2(f.fileno(), STDOUT_FD_NUM)
|
|
+ #os.dup2(1, 100)
|
|
+ #os.dup2(2, 1)
|
|
+ # We also need to flush the output that libcurl wrote to stdout.
|
|
+ # Since sys.stdout might be nose's StringIO instance, open the
|
|
+ # stdout file descriptor manually.
|
|
+
|
|
try:
|
|
self.curl.perform()
|
|
sys.stdout.flush()
|
|
finally:
|
|
- if perform_dup:
|
|
- os.fsync(sys.stdout.fileno())
|
|
- os.dup2(saved_stdout_fd, sys.stdout.fileno())
|
|
- os.close(saved_stdout_fd)
|
|
- else:
|
|
- sys.stdout = saved_stdout
|
|
+ os.fsync(STDOUT_FD_NUM)
|
|
+ os.dup2(saved_stdout_fd, STDOUT_FD_NUM)
|
|
+ os.close(saved_stdout_fd)
|
|
+ #os.dup2(100, 1)
|
|
f.seek(0)
|
|
body = f.read()
|
|
self.assertEqual('success', body)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From a43c72743b7a191622da9b1a933600c92b892529 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:35:25 -0500
|
|
Subject: [PATCH 026/112] Fix test class names
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 2 +-
|
|
tests/write_to_file_test.py | 2 +-
|
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index 853992b..a0de66e 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -17,7 +17,7 @@ setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
STDOUT_FD_NUM = 1
|
|
|
|
-class RequestTest(unittest.TestCase):
|
|
+class DefaultWriteFunctionTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.curl = pycurl.Curl()
|
|
|
|
diff --git a/tests/write_to_file_test.py b/tests/write_to_file_test.py
|
|
index 6528f81..67c9c63 100644
|
|
--- a/tests/write_to_file_test.py
|
|
+++ b/tests/write_to_file_test.py
|
|
@@ -12,7 +12,7 @@ from . import util
|
|
|
|
setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
-class RequestTest(unittest.TestCase):
|
|
+class WriteToFileTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.curl = pycurl.Curl()
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 748ffdb26baef8fa43e8da7e086325e5a77dafee Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:36:34 -0500
|
|
Subject: [PATCH 027/112] Delete unused imports
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/write_to_stringio_test.py | 3 ---
|
|
1 files changed, 0 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/tests/write_to_stringio_test.py b/tests/write_to_stringio_test.py
|
|
index fd1c28d..018800d 100644
|
|
--- a/tests/write_to_stringio_test.py
|
|
+++ b/tests/write_to_stringio_test.py
|
|
@@ -2,9 +2,6 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
-import os
|
|
-import sys
|
|
-import tempfile
|
|
import pycurl
|
|
import unittest
|
|
import io
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From da193274e430029a18b1f9b28729d9e165196f29 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 00:41:35 -0500
|
|
Subject: [PATCH 028/112] Test for header function
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/header_function_test.py | 50 +++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 50 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/header_function_test.py
|
|
|
|
diff --git a/tests/header_function_test.py b/tests/header_function_test.py
|
|
new file mode 100644
|
|
index 0000000..bfe7173
|
|
--- /dev/null
|
|
+++ b/tests/header_function_test.py
|
|
@@ -0,0 +1,50 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+import io
|
|
+import time as _time
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class HeaderFunctionTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+ self.header_lines = []
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def header_function(self, line):
|
|
+ self.header_lines.append(line)
|
|
+
|
|
+ def test_get(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.setopt(pycurl.HEADERFUNCTION, self.header_function)
|
|
+ self.curl.perform()
|
|
+ self.assertEqual('success', sio.getvalue())
|
|
+
|
|
+ assert len(self.header_lines) > 0
|
|
+ self.assertEqual("HTTP/1.0 200 OK\r\n", self.header_lines[0])
|
|
+ # day of week
|
|
+ todays_day = _time.strftime('%a')
|
|
+ # Date: Sun, 03 Mar 2013 05:38:12 GMT\r\n
|
|
+ self.check('Date: %s' % todays_day)
|
|
+ # Server: WSGIServer/0.1 Python/2.7.3\r\n
|
|
+ self.check('Server: WSGIServer')
|
|
+ self.check('Content-Length: 7')
|
|
+ self.check('Content-Type: text/html')
|
|
+
|
|
+ def check(self, wanted_text):
|
|
+ for line in self.header_lines:
|
|
+ if wanted_text in line:
|
|
+ return
|
|
+ assert False, "%s not found in header lines" % wanted_text
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 040b13d56a0eb2a9c8e5ee7e35142c4e240d48db Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 01:35:21 -0500
|
|
Subject: [PATCH 029/112] FTP test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/ftp_test.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 48 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/ftp_test.py
|
|
|
|
diff --git a/tests/ftp_test.py b/tests/ftp_test.py
|
|
new file mode 100644
|
|
index 0000000..d215b6e
|
|
--- /dev/null
|
|
+++ b/tests/ftp_test.py
|
|
@@ -0,0 +1,48 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+
|
|
+from . import util
|
|
+
|
|
+class FtpTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_get_ftp(self):
|
|
+ self.curl.setopt(pycurl.URL, 'ftp://localhost:8921')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+
|
|
+ result = sio.getvalue()
|
|
+ assert 'README' in result
|
|
+ assert 'bin -> usr/bin' in result
|
|
+
|
|
+ # XXX this test needs to be fixed
|
|
+ def test_quote(self):
|
|
+ self.curl.setopt(pycurl.URL, 'ftp://localhost:8921')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.setopt(pycurl.QUOTE, ['CWD pub'])
|
|
+ self.curl.perform()
|
|
+
|
|
+ result = sio.getvalue()
|
|
+ assert 'README' in result
|
|
+ assert 'bin -> usr/bin' in result
|
|
+
|
|
+ def test_epsv(self):
|
|
+ self.curl.setopt(pycurl.URL, 'ftp://localhost:8921')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.setopt(pycurl.FTP_USE_EPSV, 1)
|
|
+ self.curl.perform()
|
|
+
|
|
+ result = sio.getvalue()
|
|
+ assert 'README' in result
|
|
+ assert 'bin -> usr/bin' in result
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From eb36d56c850ed14a52d0a1f3afb62165444f9b84 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 01:44:22 -0500
|
|
Subject: [PATCH 030/112] Getinfo test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/getinfo_test.py | 43 +++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 43 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/getinfo_test.py
|
|
|
|
diff --git a/tests/getinfo_test.py b/tests/getinfo_test.py
|
|
new file mode 100644
|
|
index 0000000..39dff2f
|
|
--- /dev/null
|
|
+++ b/tests/getinfo_test.py
|
|
@@ -0,0 +1,43 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class GetinfoTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_getinfo(self):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+ self.assertEqual('success', sio.getvalue())
|
|
+
|
|
+ self.assertEqual(200, self.curl.getinfo(pycurl.HTTP_CODE))
|
|
+ assert type(self.curl.getinfo(pycurl.TOTAL_TIME)) is float
|
|
+ assert self.curl.getinfo(pycurl.TOTAL_TIME) > 0
|
|
+ assert self.curl.getinfo(pycurl.TOTAL_TIME) < 1
|
|
+ assert type(self.curl.getinfo(pycurl.SPEED_DOWNLOAD)) is float
|
|
+ assert self.curl.getinfo(pycurl.SPEED_DOWNLOAD) > 0
|
|
+ self.assertEqual(7, self.curl.getinfo(pycurl.SIZE_DOWNLOAD))
|
|
+ self.assertEqual('http://localhost:8380/success', self.curl.getinfo(pycurl.EFFECTIVE_URL))
|
|
+ self.assertEqual('text/html; charset=utf-8', self.curl.getinfo(pycurl.CONTENT_TYPE).lower())
|
|
+ assert type(self.curl.getinfo(pycurl.NAMELOOKUP_TIME)) is float
|
|
+ assert self.curl.getinfo(pycurl.NAMELOOKUP_TIME) > 0
|
|
+ assert self.curl.getinfo(pycurl.NAMELOOKUP_TIME) < 1
|
|
+ self.assertEqual(0, self.curl.getinfo(pycurl.REDIRECT_TIME))
|
|
+ self.assertEqual(0, self.curl.getinfo(pycurl.REDIRECT_COUNT))
|
|
+ # time not requested
|
|
+ self.assertEqual(-1, self.curl.getinfo(pycurl.INFO_FILETIME))
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From ca2118da041f15f5bbb2bf6a0e12b7bd57d16332 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 02:05:30 -0500
|
|
Subject: [PATCH 031/112] Ported internals test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/internals_test.py | 224 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 224 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/internals_test.py
|
|
|
|
diff --git a/tests/internals_test.py b/tests/internals_test.py
|
|
new file mode 100644
|
|
index 0000000..34d4eb8
|
|
--- /dev/null
|
|
+++ b/tests/internals_test.py
|
|
@@ -0,0 +1,224 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+from .util import StringIO
|
|
+try:
|
|
+ import cPickle
|
|
+except ImportError:
|
|
+ cPickle = None
|
|
+import pickle
|
|
+import gc
|
|
+import copy
|
|
+
|
|
+class InternalsTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+ del self.curl
|
|
+
|
|
+ # /***********************************************************************
|
|
+ # // test misc
|
|
+ # ************************************************************************/
|
|
+
|
|
+ def test_constant_aliasing(self):
|
|
+ assert self.curl.URL is pycurl.URL
|
|
+
|
|
+ # /***********************************************************************
|
|
+ # // test handles
|
|
+ # ************************************************************************/
|
|
+
|
|
+ def test_remove_invalid_handle(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ try:
|
|
+ m.remove_handle(self.curl)
|
|
+ except pycurl.error:
|
|
+ pass
|
|
+ else:
|
|
+ assert False, "No exception when trying to remove a handle that is not in CurlMulti"
|
|
+ del m
|
|
+
|
|
+ def test_remove_invalid_closed_handle(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ c = pycurl.Curl()
|
|
+ c.close()
|
|
+ m.remove_handle(c)
|
|
+ del m, c
|
|
+
|
|
+ def test_add_closed_handle(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ c = pycurl.Curl()
|
|
+ c.close()
|
|
+ try:
|
|
+ m.add_handle(c)
|
|
+ except pycurl.error:
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to add a close handle to CurlMulti"
|
|
+ m.close()
|
|
+ del m, c
|
|
+
|
|
+ def test_add_handle_twice(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.add_handle(self.curl)
|
|
+ try:
|
|
+ m.add_handle(self.curl)
|
|
+ except pycurl.error:
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to add the same handle twice"
|
|
+ del m
|
|
+
|
|
+ def test_add_handle_on_multiple_stacks(self):
|
|
+ m1 = pycurl.CurlMulti()
|
|
+ m2 = pycurl.CurlMulti()
|
|
+ m1.add_handle(self.curl)
|
|
+ try:
|
|
+ m2.add_handle(self.curl)
|
|
+ except pycurl.error:
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to add the same handle on multiple stacks"
|
|
+ del m1, m2
|
|
+
|
|
+ def test_move_handle(self):
|
|
+ m1 = pycurl.CurlMulti()
|
|
+ m2 = pycurl.CurlMulti()
|
|
+ m1.add_handle(self.curl)
|
|
+ m1.remove_handle(self.curl)
|
|
+ m2.add_handle(self.curl)
|
|
+ del m1, m2
|
|
+
|
|
+ # /***********************************************************************
|
|
+ # // test copying and pickling - copying and pickling of
|
|
+ # // instances of Curl and CurlMulti is not allowed
|
|
+ # ************************************************************************/
|
|
+
|
|
+ def test_copy_curl(self):
|
|
+ try:
|
|
+ copy.copy(self.curl)
|
|
+ # python 2 raises copy.Error, python 3 raises TypeError
|
|
+ except (copy.Error, TypeError):
|
|
+ pass
|
|
+ else:
|
|
+ assert False, "No exception when trying to copy a Curl handle"
|
|
+
|
|
+ def test_copy_multi(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ try:
|
|
+ copy.copy(m)
|
|
+ except (copy.Error, TypeError):
|
|
+ pass
|
|
+ else:
|
|
+ assert False, "No exception when trying to copy a CurlMulti handle"
|
|
+
|
|
+ def test_pickle_curl(self):
|
|
+ fp = StringIO()
|
|
+ p = pickle.Pickler(fp, 1)
|
|
+ try:
|
|
+ p.dump(self.curl)
|
|
+ # python 2 raises pickle.PicklingError, python 3 raises TypeError
|
|
+ except (pickle.PicklingError, TypeError):
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to pickle a Curl handle"
|
|
+ del fp, p
|
|
+
|
|
+ def test_pickle_multi(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ fp = StringIO()
|
|
+ p = pickle.Pickler(fp, 1)
|
|
+ try:
|
|
+ p.dump(m)
|
|
+ except (pickle.PicklingError, TypeError):
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to pickle a CurlMulti handle"
|
|
+ del m, fp, p
|
|
+
|
|
+ if cPickle is not None:
|
|
+ def test_cpickle_curl(self):
|
|
+ fp = StringIO()
|
|
+ p = cPickle.Pickler(fp, 1)
|
|
+ try:
|
|
+ p.dump(self.curl)
|
|
+ except cPickle.PicklingError:
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to pickle a Curl handle via cPickle"
|
|
+ del fp, p
|
|
+
|
|
+ def test_cpickle_multi(self):
|
|
+ m = pycurl.CurlMulti()
|
|
+ fp = StringIO()
|
|
+ p = cPickle.Pickler(fp, 1)
|
|
+ try:
|
|
+ p.dump(m)
|
|
+ except cPickle.PicklingError:
|
|
+ pass
|
|
+ else:
|
|
+ assert 0, "No exception when trying to pickle a CurlMulti handle via cPickle"
|
|
+ del m, fp, p
|
|
+
|
|
+ # /***********************************************************************
|
|
+ # // test refcounts
|
|
+ # ************************************************************************/
|
|
+
|
|
+ # basic check of reference counting (use a memory checker like valgrind)
|
|
+ def test_reference_counting(self):
|
|
+ c = pycurl.Curl()
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.add_handle(c)
|
|
+ del m
|
|
+ m = pycurl.CurlMulti()
|
|
+ c.close()
|
|
+ del m, c
|
|
+
|
|
+ def test_cyclic_gc(self):
|
|
+ gc.collect()
|
|
+ c = pycurl.Curl()
|
|
+ c.m = pycurl.CurlMulti()
|
|
+ c.m.add_handle(c)
|
|
+ # create some nasty cyclic references
|
|
+ c.c = c
|
|
+ c.c.c1 = c
|
|
+ c.c.c2 = c
|
|
+ c.c.c3 = c.c
|
|
+ c.c.c4 = c.m
|
|
+ c.m.c = c
|
|
+ c.m.m = c.m
|
|
+ c.m.c = c
|
|
+ # delete
|
|
+ gc.collect()
|
|
+ flags = gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE
|
|
+ # python 3 has no DEBUG_OBJECTS
|
|
+ #if hasattr(gc, 'DEBUG_OBJECTS'):
|
|
+ #flags |= gc.DEBUG_OBJECTS
|
|
+ #if opts.verbose >= 1:
|
|
+ #flags = flags | gc.DEBUG_STATS
|
|
+ gc.set_debug(flags)
|
|
+ gc.collect()
|
|
+ ##print gc.get_referrers(c)
|
|
+ ##print gc.get_objects()
|
|
+ #if opts.verbose >= 1:
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+ # The `del' below should delete these 4 objects:
|
|
+ # Curl + internal dict, CurlMulti + internal dict
|
|
+ del c
|
|
+ gc.collect()
|
|
+ #if opts.verbose >= 1:
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+
|
|
+ def test_refcounting_bug_in_reset(self):
|
|
+ try:
|
|
+ range_generator = xrange
|
|
+ except NameError:
|
|
+ range_generator = range
|
|
+ # Ensure that the refcounting error in "reset" is fixed:
|
|
+ for i in range_generator(100000):
|
|
+ c = pycurl.Curl()
|
|
+ c.reset()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5400bd486457b34d8c49ca3ad1f74f03143172bd Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 02:16:10 -0500
|
|
Subject: [PATCH 032/112] Make cyclic gc test actually check that cycles are collected
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/internals_test.py | 9 +++++++++
|
|
1 files changed, 9 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/internals_test.py b/tests/internals_test.py
|
|
index 34d4eb8..fb451df 100644
|
|
--- a/tests/internals_test.py
|
|
+++ b/tests/internals_test.py
|
|
@@ -12,6 +12,7 @@ except ImportError:
|
|
import pickle
|
|
import gc
|
|
import copy
|
|
+import re
|
|
|
|
class InternalsTest(unittest.TestCase):
|
|
def setUp(self):
|
|
@@ -179,6 +180,7 @@ class InternalsTest(unittest.TestCase):
|
|
del m, c
|
|
|
|
def test_cyclic_gc(self):
|
|
+ regexp = re.compile(r'at (0x\d+)')
|
|
gc.collect()
|
|
c = pycurl.Curl()
|
|
c.m = pycurl.CurlMulti()
|
|
@@ -206,10 +208,17 @@ class InternalsTest(unittest.TestCase):
|
|
##print gc.get_objects()
|
|
#if opts.verbose >= 1:
|
|
#print("Tracked objects:", len(gc.get_objects()))
|
|
+ match = regexp.search(repr(c))
|
|
+ assert match is not None
|
|
+ address = match.group(1)
|
|
# The `del' below should delete these 4 objects:
|
|
# Curl + internal dict, CurlMulti + internal dict
|
|
del c
|
|
gc.collect()
|
|
+ objects = gc.get_objects()
|
|
+ search = 'at %s' % address
|
|
+ for object in objects:
|
|
+ assert search not in repr(object)
|
|
#if opts.verbose >= 1:
|
|
#print("Tracked objects:", len(gc.get_objects()))
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From b0c490027c63d5f8eb5dfc81c646e5edfb79635c Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 03:00:20 -0500
|
|
Subject: [PATCH 033/112] Ported memleak test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/memleak_test.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 59 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/memleak_test.py
|
|
|
|
diff --git a/tests/memleak_test.py b/tests/memleak_test.py
|
|
new file mode 100644
|
|
index 0000000..6e9f76c
|
|
--- /dev/null
|
|
+++ b/tests/memleak_test.py
|
|
@@ -0,0 +1,59 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+import gc
|
|
+import re
|
|
+
|
|
+class MemleakTest(unittest.TestCase):
|
|
+ def test_collection(self):
|
|
+ regexp = re.compile(r'at (0x\d+)')
|
|
+
|
|
+ gc.collect()
|
|
+ flags = gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE
|
|
+ # python 3 has no DEBUG_OBJECTS
|
|
+ #if hasattr(gc, 'DEBUG_OBJECTS'):
|
|
+ #flags |= gc.DEBUG_OBJECTS
|
|
+ #if 1:
|
|
+ #flags = flags | gc.DEBUG_STATS
|
|
+ #gc.set_debug(flags)
|
|
+ gc.collect()
|
|
+
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+
|
|
+ multi = pycurl.CurlMulti()
|
|
+ t = []
|
|
+ searches = []
|
|
+ for a in range(100):
|
|
+ curl = pycurl.Curl()
|
|
+ multi.add_handle(curl)
|
|
+ t.append(curl)
|
|
+
|
|
+ match = regexp.search(repr(curl))
|
|
+ assert match is not None
|
|
+ searches.append(match.group(1))
|
|
+ match = regexp.search(repr(multi))
|
|
+ assert match
|
|
+ searches.append(match.group(1))
|
|
+
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+
|
|
+ for curl in t:
|
|
+ curl.close()
|
|
+ multi.remove_handle(curl)
|
|
+
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+
|
|
+ del curl
|
|
+ del t
|
|
+ del multi
|
|
+
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+ gc.collect()
|
|
+ #print("Tracked objects:", len(gc.get_objects()))
|
|
+
|
|
+ objects = gc.get_objects()
|
|
+ for search in searches:
|
|
+ assert 'at %s' % search not in repr(object)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From dd5650bb58e60c27fa32c27b5d39dbf5ad13c132 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 03:06:26 -0500
|
|
Subject: [PATCH 034/112] Ported the first multi test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 56 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/multi_test.py
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
new file mode 100644
|
|
index 0000000..4c0bdaf
|
|
--- /dev/null
|
|
+++ b/tests/multi_test.py
|
|
@@ -0,0 +1,56 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module_1, teardown_module_1 = runwsgi.app_runner_setup((app.app, 8380))
|
|
+setup_module_2, teardown_module_2 = runwsgi.app_runner_setup((app.app, 8381))
|
|
+
|
|
+def setup_module(mod):
|
|
+ setup_module_1(mod)
|
|
+ setup_module_2(mod)
|
|
+
|
|
+def teardown_module(mod):
|
|
+ teardown_module_2(mod)
|
|
+ teardown_module_1(mod)
|
|
+
|
|
+class MultiTest(unittest.TestCase):
|
|
+ def test_multi(self):
|
|
+ io1 = util.StringIO()
|
|
+ io2 = util.StringIO()
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.handles = []
|
|
+ c1 = pycurl.Curl()
|
|
+ c2 = pycurl.Curl()
|
|
+ c1.setopt(c1.URL, 'http://localhost:8380/success')
|
|
+ c1.setopt(c1.WRITEFUNCTION, io1.write)
|
|
+ c2.setopt(c2.URL, 'http://localhost:8381/success')
|
|
+ c2.setopt(c1.WRITEFUNCTION, io2.write)
|
|
+ m.add_handle(c1)
|
|
+ m.add_handle(c2)
|
|
+ m.handles.append(c1)
|
|
+ m.handles.append(c2)
|
|
+
|
|
+ num_handles = len(m.handles)
|
|
+ while num_handles:
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+ m.select(1.0)
|
|
+
|
|
+ m.remove_handle(c2)
|
|
+ m.remove_handle(c1)
|
|
+ del m.handles
|
|
+ m.close()
|
|
+ c1.close()
|
|
+ c2.close()
|
|
+
|
|
+ self.assertEqual('success', io1.getvalue())
|
|
+ self.assertEqual('success', io2.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c651e8ab37cc21ab790b293ad00ad43a8a5e608f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 12:55:42 -0500
|
|
Subject: [PATCH 035/112] Port multi2 test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/app.py | 8 +++++++
|
|
tests/multi_test.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 62 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/app.py b/tests/app.py
|
|
index b173fd6..3b9303b 100644
|
|
--- a/tests/app.py
|
|
+++ b/tests/app.py
|
|
@@ -5,3 +5,11 @@ app = bottle.Bottle()
|
|
@app.route('/success')
|
|
def ok():
|
|
return 'success'
|
|
+
|
|
+@app.route('/status/403')
|
|
+def forbidden():
|
|
+ bottle.abort(403, 'forbidden')
|
|
+
|
|
+@app.route('/status/404')
|
|
+def not_found():
|
|
+ bottle.abort(404, 'not found')
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index 4c0bdaf..fd96e51 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -11,12 +11,15 @@ from . import util
|
|
|
|
setup_module_1, teardown_module_1 = runwsgi.app_runner_setup((app.app, 8380))
|
|
setup_module_2, teardown_module_2 = runwsgi.app_runner_setup((app.app, 8381))
|
|
+setup_module_3, teardown_module_3 = runwsgi.app_runner_setup((app.app, 8382))
|
|
|
|
def setup_module(mod):
|
|
setup_module_1(mod)
|
|
setup_module_2(mod)
|
|
+ setup_module_3(mod)
|
|
|
|
def teardown_module(mod):
|
|
+ teardown_module_3(mod)
|
|
teardown_module_2(mod)
|
|
teardown_module_1(mod)
|
|
|
|
@@ -54,3 +57,54 @@ class MultiTest(unittest.TestCase):
|
|
|
|
self.assertEqual('success', io1.getvalue())
|
|
self.assertEqual('success', io2.getvalue())
|
|
+
|
|
+ def test_multi_status_codes(self):
|
|
+ # init
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.handles = []
|
|
+ urls = [
|
|
+ 'http://localhost:8380/success',
|
|
+ 'http://localhost:8381/status/403',
|
|
+ 'http://localhost:8382/status/404',
|
|
+ ]
|
|
+ for url in urls:
|
|
+ c = pycurl.Curl()
|
|
+ # save info in standard Python attributes
|
|
+ c.url = url.rstrip()
|
|
+ c.body = util.StringIO()
|
|
+ c.http_code = -1
|
|
+ m.handles.append(c)
|
|
+ # pycurl API calls
|
|
+ c.setopt(c.URL, c.url)
|
|
+ c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
+ m.add_handle(c)
|
|
+
|
|
+ # get data
|
|
+ num_handles = len(m.handles)
|
|
+ while num_handles:
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+ # currently no more I/O is pending, could do something in the meantime
|
|
+ # (display a progress bar, etc.)
|
|
+ m.select(0.1)
|
|
+
|
|
+ # close handles
|
|
+ for c in m.handles:
|
|
+ # save info in standard Python attributes
|
|
+ c.http_code = c.getinfo(c.HTTP_CODE)
|
|
+ # pycurl API calls
|
|
+ m.remove_handle(c)
|
|
+ c.close()
|
|
+ m.close()
|
|
+
|
|
+ # check result
|
|
+ self.assertEqual('success', m.handles[0].body.getvalue())
|
|
+ self.assertEqual(200, m.handles[0].http_code)
|
|
+ # bottle generated response body
|
|
+ assert 'Error 403: Forbidden' in m.handles[1].body.getvalue()
|
|
+ self.assertEqual(403, m.handles[1].http_code)
|
|
+ # bottle generated response body
|
|
+ assert 'Error 404: Not Found' in m.handles[2].body.getvalue()
|
|
+ self.assertEqual(404, m.handles[2].http_code)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 18212fb2181a57e67988e7a336ac4b9c90e17d1a Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 14:05:49 -0500
|
|
Subject: [PATCH 036/112] Porting multi3 test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 71 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index fd96e51..1c13f70 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -108,3 +108,74 @@ class MultiTest(unittest.TestCase):
|
|
# bottle generated response body
|
|
assert 'Error 404: Not Found' in m.handles[2].body.getvalue()
|
|
self.assertEqual(404, m.handles[2].http_code)
|
|
+
|
|
+ def test_adding_closed_handle(self):
|
|
+ # init
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.handles = []
|
|
+ urls = [
|
|
+ 'http://localhost:8380/success',
|
|
+ 'http://localhost:8381/status/403',
|
|
+ 'http://localhost:8382/status/404',
|
|
+ ]
|
|
+ for url in urls:
|
|
+ c = pycurl.Curl()
|
|
+ # save info in standard Python attributes
|
|
+ c.url = url
|
|
+ c.body = util.StringIO()
|
|
+ c.http_code = -1
|
|
+ c.debug = 0
|
|
+ m.handles.append(c)
|
|
+ # pycurl API calls
|
|
+ c.setopt(c.URL, c.url)
|
|
+ c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
+ m.add_handle(c)
|
|
+
|
|
+ # debug - close a handle
|
|
+ c = m.handles[2]
|
|
+ c.debug = 1
|
|
+ c.close()
|
|
+
|
|
+ # get data
|
|
+ num_handles = len(m.handles)
|
|
+ while num_handles:
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+ # currently no more I/O is pending, could do something in the meantime
|
|
+ # (display a progress bar, etc.)
|
|
+ m.select(0.1)
|
|
+
|
|
+ # close handles
|
|
+ for c in m.handles:
|
|
+ # save info in standard Python attributes
|
|
+ try:
|
|
+ c.http_code = c.getinfo(c.HTTP_CODE)
|
|
+ except pycurl.error:
|
|
+ # handle already closed - see debug above
|
|
+ assert c.debug
|
|
+ c.http_code = -1
|
|
+ # pycurl API calls
|
|
+ if 0:
|
|
+ m.remove_handle(c)
|
|
+ c.close()
|
|
+ elif 0:
|
|
+ # in the C API this is the wrong calling order, but pycurl
|
|
+ # handles this automatically
|
|
+ c.close()
|
|
+ m.remove_handle(c)
|
|
+ else:
|
|
+ # actually, remove_handle is called automatically on close
|
|
+ c.close()
|
|
+ m.close()
|
|
+
|
|
+ # check result
|
|
+ self.assertEqual('success', m.handles[0].body.getvalue())
|
|
+ self.assertEqual(200, m.handles[0].http_code)
|
|
+ # bottle generated response body
|
|
+ assert 'Error 403: Forbidden' in m.handles[1].body.getvalue()
|
|
+ self.assertEqual(403, m.handles[1].http_code)
|
|
+ # bottle generated response body
|
|
+ self.assertEqual('', m.handles[2].body.getvalue())
|
|
+ self.assertEqual(-1, m.handles[2].http_code)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 55b38bfbba56f6179633dc90f7cf3e72c3433b9f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 14:15:13 -0500
|
|
Subject: [PATCH 037/112] Exercise all 3 possibilites in ported multi3 test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 37 +++++++++++++++++++++++++------------
|
|
1 files changed, 25 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index 1c13f70..e1fec05 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -109,7 +109,7 @@ class MultiTest(unittest.TestCase):
|
|
assert 'Error 404: Not Found' in m.handles[2].body.getvalue()
|
|
self.assertEqual(404, m.handles[2].http_code)
|
|
|
|
- def test_adding_closed_handle(self):
|
|
+ def check_adding_closed_handle(self, close_fn):
|
|
# init
|
|
m = pycurl.CurlMulti()
|
|
m.handles = []
|
|
@@ -157,17 +157,7 @@ class MultiTest(unittest.TestCase):
|
|
assert c.debug
|
|
c.http_code = -1
|
|
# pycurl API calls
|
|
- if 0:
|
|
- m.remove_handle(c)
|
|
- c.close()
|
|
- elif 0:
|
|
- # in the C API this is the wrong calling order, but pycurl
|
|
- # handles this automatically
|
|
- c.close()
|
|
- m.remove_handle(c)
|
|
- else:
|
|
- # actually, remove_handle is called automatically on close
|
|
- c.close()
|
|
+ close_fn(m, c)
|
|
m.close()
|
|
|
|
# check result
|
|
@@ -179,3 +169,26 @@ class MultiTest(unittest.TestCase):
|
|
# bottle generated response body
|
|
self.assertEqual('', m.handles[2].body.getvalue())
|
|
self.assertEqual(-1, m.handles[2].http_code)
|
|
+
|
|
+ def _remove_then_close(self, m, c):
|
|
+ m.remove_handle(c)
|
|
+ c.close()
|
|
+
|
|
+ def _close_then_remove(self, m, c):
|
|
+ # in the C API this is the wrong calling order, but pycurl
|
|
+ # handles this automatically
|
|
+ c.close()
|
|
+ m.remove_handle(c)
|
|
+
|
|
+ def _close_without_removing(self, m, c):
|
|
+ # actually, remove_handle is called automatically on close
|
|
+ c.close
|
|
+
|
|
+ def test_adding_closed_handle_remove_then_close(self):
|
|
+ self.check_adding_closed_handle(self._remove_then_close)
|
|
+
|
|
+ def test_adding_closed_handle_close_then_remove(self):
|
|
+ self.check_adding_closed_handle(self._close_then_remove)
|
|
+
|
|
+ def test_adding_closed_handle_close_without_removing(self):
|
|
+ self.check_adding_closed_handle(self._close_without_removing)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 6ec826f66a9a86a2c1701e60a094d1f0004f9dff Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Sun, 3 Mar 2013 14:21:33 -0500
|
|
Subject: [PATCH 038/112] Port mulit4 test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 50 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index e1fec05..a508809 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -4,6 +4,7 @@
|
|
|
|
import pycurl
|
|
import unittest
|
|
+import select
|
|
|
|
from . import app
|
|
from . import runwsgi
|
|
@@ -58,6 +59,55 @@ class MultiTest(unittest.TestCase):
|
|
self.assertEqual('success', io1.getvalue())
|
|
self.assertEqual('success', io2.getvalue())
|
|
|
|
+ def test_multi_select_fdset(self):
|
|
+ c1 = pycurl.Curl()
|
|
+ c2 = pycurl.Curl()
|
|
+ c3 = pycurl.Curl()
|
|
+ c1.setopt(c1.URL, "http://localhost:8380/success")
|
|
+ c2.setopt(c2.URL, "http://localhost:8381/success")
|
|
+ c3.setopt(c3.URL, "http://localhost:8382/success")
|
|
+ c1.body = util.StringIO()
|
|
+ c2.body = util.StringIO()
|
|
+ c3.body = util.StringIO()
|
|
+ c1.setopt(c1.WRITEFUNCTION, c1.body.write)
|
|
+ c2.setopt(c2.WRITEFUNCTION, c2.body.write)
|
|
+ c3.setopt(c3.WRITEFUNCTION, c3.body.write)
|
|
+
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.add_handle(c1)
|
|
+ m.add_handle(c2)
|
|
+ m.add_handle(c3)
|
|
+
|
|
+ # Number of seconds to wait for a timeout to happen
|
|
+ SELECT_TIMEOUT = 0.1
|
|
+
|
|
+ # Stir the state machine into action
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ # Keep going until all the connections have terminated
|
|
+ while num_handles:
|
|
+ select.select(*m.fdset() + (SELECT_TIMEOUT,))
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ # Cleanup
|
|
+ m.remove_handle(c3)
|
|
+ m.remove_handle(c2)
|
|
+ m.remove_handle(c1)
|
|
+ m.close()
|
|
+ c1.close()
|
|
+ c2.close()
|
|
+ c3.close()
|
|
+
|
|
+ self.assertEqual('success', c1.body.getvalue())
|
|
+ self.assertEqual('success', c2.body.getvalue())
|
|
+ self.assertEqual('success', c3.body.getvalue())
|
|
+
|
|
def test_multi_status_codes(self):
|
|
# init
|
|
m = pycurl.CurlMulti()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From b29ff271843da14e9b008e8853a3b84b06ed6ecc Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 00:24:44 -0500
|
|
Subject: [PATCH 039/112] Port multit6 test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 55 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index a508809..e83ce48 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -242,3 +242,58 @@ class MultiTest(unittest.TestCase):
|
|
|
|
def test_adding_closed_handle_close_without_removing(self):
|
|
self.check_adding_closed_handle(self._close_without_removing)
|
|
+
|
|
+ def test_multi_info_read(self):
|
|
+ c1 = pycurl.Curl()
|
|
+ c2 = pycurl.Curl()
|
|
+ c3 = pycurl.Curl()
|
|
+ c1.setopt(c1.URL, "http://localhost:8380/success")
|
|
+ c2.setopt(c2.URL, "http://localhost:8381/success")
|
|
+ c3.setopt(c3.URL, "http://localhost:8382/success")
|
|
+ c1.body = util.StringIO()
|
|
+ c2.body = util.StringIO()
|
|
+ c3.body = util.StringIO()
|
|
+ c1.setopt(c1.WRITEFUNCTION, c1.body.write)
|
|
+ c2.setopt(c2.WRITEFUNCTION, c2.body.write)
|
|
+ c3.setopt(c3.WRITEFUNCTION, c3.body.write)
|
|
+
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.add_handle(c1)
|
|
+ m.add_handle(c2)
|
|
+ m.add_handle(c3)
|
|
+
|
|
+ # Number of seconds to wait for a timeout to happen
|
|
+ SELECT_TIMEOUT = 1.0
|
|
+
|
|
+ # Stir the state machine into action
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ # Keep going until all the connections have terminated
|
|
+ while num_handles:
|
|
+ # The select method uses fdset internally to determine which file descriptors
|
|
+ # to check.
|
|
+ m.select(SELECT_TIMEOUT)
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ # Print the message, if any
|
|
+ while True:
|
|
+ info = m.info_read()
|
|
+ print info
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ # Cleanup
|
|
+ m.remove_handle(c3)
|
|
+ m.remove_handle(c2)
|
|
+ m.remove_handle(c1)
|
|
+ m.close()
|
|
+ c1.close()
|
|
+ c2.close()
|
|
+ c3.close()
|
|
+
|
|
+ self.assertEqual('success', c1.body.getvalue())
|
|
+ self.assertEqual('success', c2.body.getvalue())
|
|
+ self.assertEqual('success', c3.body.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From a14adcb02e78aa26e1f6b326815a7a0ae824fc4d Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 00:38:59 -0500
|
|
Subject: [PATCH 040/112] Improve info_read test to test info_read
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 19 +++++++++++++++----
|
|
1 files changed, 15 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index e83ce48..10af44c 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -271,6 +271,7 @@ class MultiTest(unittest.TestCase):
|
|
if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
break
|
|
|
|
+ infos = []
|
|
# Keep going until all the connections have terminated
|
|
while num_handles:
|
|
# The select method uses fdset internally to determine which file descriptors
|
|
@@ -278,13 +279,23 @@ class MultiTest(unittest.TestCase):
|
|
m.select(SELECT_TIMEOUT)
|
|
while 1:
|
|
ret, num_handles = m.perform()
|
|
- # Print the message, if any
|
|
- while True:
|
|
- info = m.info_read()
|
|
- print info
|
|
+ info = m.info_read()
|
|
+ infos.append(info)
|
|
if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
break
|
|
|
|
+ all_handles = []
|
|
+ for info in infos:
|
|
+ handles = info[1]
|
|
+ # last info is an empty array
|
|
+ if handles:
|
|
+ all_handles.extend(handles)
|
|
+
|
|
+ self.assertEqual(3, len(all_handles))
|
|
+ assert c1 in all_handles
|
|
+ assert c2 in all_handles
|
|
+ assert c3 in all_handles
|
|
+
|
|
# Cleanup
|
|
m.remove_handle(c3)
|
|
m.remove_handle(c2)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From ef1510a4b5426b2fb0458ae244be17a578407fc7 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 00:40:25 -0500
|
|
Subject: [PATCH 041/112] Port multi5 test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 51 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index 10af44c..d9c6174 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -243,6 +243,57 @@ class MultiTest(unittest.TestCase):
|
|
def test_adding_closed_handle_close_without_removing(self):
|
|
self.check_adding_closed_handle(self._close_without_removing)
|
|
|
|
+ def test_multi_select(self):
|
|
+ c1 = pycurl.Curl()
|
|
+ c2 = pycurl.Curl()
|
|
+ c3 = pycurl.Curl()
|
|
+ c1.setopt(c1.URL, "http://localhost:8380/success")
|
|
+ c2.setopt(c2.URL, "http://localhost:8381/success")
|
|
+ c3.setopt(c3.URL, "http://localhost:8382/success")
|
|
+ c1.body = util.StringIO()
|
|
+ c2.body = util.StringIO()
|
|
+ c3.body = util.StringIO()
|
|
+ c1.setopt(c1.WRITEFUNCTION, c1.body.write)
|
|
+ c2.setopt(c2.WRITEFUNCTION, c2.body.write)
|
|
+ c3.setopt(c3.WRITEFUNCTION, c3.body.write)
|
|
+
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.add_handle(c1)
|
|
+ m.add_handle(c2)
|
|
+ m.add_handle(c3)
|
|
+
|
|
+ # Number of seconds to wait for a timeout to happen
|
|
+ SELECT_TIMEOUT = 1.0
|
|
+
|
|
+ # Stir the state machine into action
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ # Keep going until all the connections have terminated
|
|
+ while num_handles:
|
|
+ # The select method uses fdset internally to determine which file descriptors
|
|
+ # to check.
|
|
+ m.select(SELECT_TIMEOUT)
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ # Cleanup
|
|
+ m.remove_handle(c3)
|
|
+ m.remove_handle(c2)
|
|
+ m.remove_handle(c1)
|
|
+ m.close()
|
|
+ c1.close()
|
|
+ c2.close()
|
|
+ c3.close()
|
|
+
|
|
+ self.assertEqual('success', c1.body.getvalue())
|
|
+ self.assertEqual('success', c2.body.getvalue())
|
|
+ self.assertEqual('success', c3.body.getvalue())
|
|
+
|
|
def test_multi_info_read(self):
|
|
c1 = pycurl.Curl()
|
|
c2 = pycurl.Curl()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 2a6f3d5ff191f6709fddfac3a2e0a6794a66f75d Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 22:05:34 -0500
|
|
Subject: [PATCH 042/112] Ported test_multi_socket.py
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_socket_test.py | 110 ++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 110 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/multi_socket_test.py
|
|
|
|
diff --git a/tests/multi_socket_test.py b/tests/multi_socket_test.py
|
|
new file mode 100644
|
|
index 0000000..2586569
|
|
--- /dev/null
|
|
+++ b/tests/multi_socket_test.py
|
|
@@ -0,0 +1,110 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+import select
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module_1, teardown_module_1 = runwsgi.app_runner_setup((app.app, 8380))
|
|
+setup_module_2, teardown_module_2 = runwsgi.app_runner_setup((app.app, 8381))
|
|
+setup_module_3, teardown_module_3 = runwsgi.app_runner_setup((app.app, 8382))
|
|
+
|
|
+def setup_module(mod):
|
|
+ setup_module_1(mod)
|
|
+ setup_module_2(mod)
|
|
+ setup_module_3(mod)
|
|
+
|
|
+def teardown_module(mod):
|
|
+ teardown_module_3(mod)
|
|
+ teardown_module_2(mod)
|
|
+ teardown_module_1(mod)
|
|
+
|
|
+class MultiSocketTest(unittest.TestCase):
|
|
+ def test_multi_socket(self):
|
|
+ urls = [
|
|
+ 'http://localhost:8380/success',
|
|
+ 'http://localhost:8381/success',
|
|
+ 'http://localhost:8382/success',
|
|
+ ]
|
|
+
|
|
+ timers = []
|
|
+
|
|
+ # timer callback
|
|
+ def timer(msecs):
|
|
+ #print('Timer callback msecs:', msecs)
|
|
+ timers.append(msecs)
|
|
+
|
|
+ socket_events = []
|
|
+
|
|
+ # socket callback
|
|
+ def socket(event, socket, multi, data):
|
|
+ #print(event, socket, multi, data)
|
|
+ # multi.assign(socket, timer)
|
|
+ socket_events.append((event, multi))
|
|
+
|
|
+ # init
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.setopt(pycurl.M_PIPELINING, 1)
|
|
+ m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
+ m.setopt(pycurl.M_SOCKETFUNCTION, socket)
|
|
+ m.handles = []
|
|
+ for url in urls:
|
|
+ c = pycurl.Curl()
|
|
+ # save info in standard Python attributes
|
|
+ c.url = url
|
|
+ c.body = util.StringIO()
|
|
+ c.http_code = -1
|
|
+ m.handles.append(c)
|
|
+ # pycurl API calls
|
|
+ c.setopt(c.URL, c.url)
|
|
+ c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
+ m.add_handle(c)
|
|
+
|
|
+ # get data
|
|
+ num_handles = len(m.handles)
|
|
+ while num_handles:
|
|
+ while 1:
|
|
+ ret, num_handles = m.socket_all()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+ # currently no more I/O is pending, could do something in the meantime
|
|
+ # (display a progress bar, etc.)
|
|
+ m.select(0.1)
|
|
+
|
|
+ for c in m.handles:
|
|
+ # save info in standard Python attributes
|
|
+ c.http_code = c.getinfo(c.HTTP_CODE)
|
|
+
|
|
+ # at least in and remove events per socket
|
|
+ assert len(socket_events) >= 6
|
|
+
|
|
+ # print result
|
|
+ for c in m.handles:
|
|
+ self.assertEqual('success', c.body.getvalue())
|
|
+ self.assertEqual(200, c.http_code)
|
|
+
|
|
+ # multi, not curl handle
|
|
+ self.check(pycurl.POLL_IN, m, socket_events)
|
|
+ self.check(pycurl.POLL_REMOVE, m, socket_events)
|
|
+
|
|
+ assert len(timers) > 0
|
|
+ assert timers[0] > 0
|
|
+ self.assertEqual(-1, timers[-1])
|
|
+
|
|
+ # close handles
|
|
+ for c in m.handles:
|
|
+ # pycurl API calls
|
|
+ m.remove_handle(c)
|
|
+ c.close()
|
|
+ m.close()
|
|
+
|
|
+ def check(self, event, multi, socket_events):
|
|
+ for event_, multi_ in socket_events:
|
|
+ if event == event_ and multi == multi_:
|
|
+ return
|
|
+ assert False, '%d %s not found in socket events' % (event, multi)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 408772865075a389e89441afc44ae402bf87cae7 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 22:29:45 -0500
|
|
Subject: [PATCH 043/112] Ported test_multi_socket_select.py
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_socket_select_test.py | 130 +++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 130 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/multi_socket_select_test.py
|
|
|
|
diff --git a/tests/multi_socket_select_test.py b/tests/multi_socket_select_test.py
|
|
new file mode 100644
|
|
index 0000000..b9ba950
|
|
--- /dev/null
|
|
+++ b/tests/multi_socket_select_test.py
|
|
@@ -0,0 +1,130 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+import select
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module_1, teardown_module_1 = runwsgi.app_runner_setup((app.app, 8380))
|
|
+setup_module_2, teardown_module_2 = runwsgi.app_runner_setup((app.app, 8381))
|
|
+setup_module_3, teardown_module_3 = runwsgi.app_runner_setup((app.app, 8382))
|
|
+
|
|
+def setup_module(mod):
|
|
+ setup_module_1(mod)
|
|
+ setup_module_2(mod)
|
|
+ setup_module_3(mod)
|
|
+
|
|
+def teardown_module(mod):
|
|
+ teardown_module_3(mod)
|
|
+ teardown_module_2(mod)
|
|
+ teardown_module_1(mod)
|
|
+
|
|
+class MultiSocketSelectTest(unittest.TestCase):
|
|
+ def test_multi_socket_select(self):
|
|
+ sockets = set()
|
|
+ timeout = 0
|
|
+
|
|
+ urls = [
|
|
+ 'http://localhost:8380/success',
|
|
+ 'http://localhost:8381/success',
|
|
+ 'http://localhost:8382/success',
|
|
+ ]
|
|
+
|
|
+ timers = []
|
|
+
|
|
+ # timer callback
|
|
+ def timer(msecs):
|
|
+ #print('Timer callback msecs:', msecs)
|
|
+ timers.append(msecs)
|
|
+
|
|
+ socket_events = []
|
|
+
|
|
+ # socket callback
|
|
+ def socket(event, socket, multi, data):
|
|
+ if event == pycurl.POLL_REMOVE:
|
|
+ #print("Remove Socket %d"%socket)
|
|
+ sockets.remove(socket)
|
|
+ else:
|
|
+ if socket not in sockets:
|
|
+ #print("Add socket %d"%socket)
|
|
+ sockets.add(socket)
|
|
+ socket_events.append((event, multi))
|
|
+
|
|
+ # init
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.setopt(pycurl.M_PIPELINING, 1)
|
|
+ m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
+ m.setopt(pycurl.M_SOCKETFUNCTION, socket)
|
|
+ m.handles = []
|
|
+ for url in urls:
|
|
+ c = pycurl.Curl()
|
|
+ # save info in standard Python attributes
|
|
+ c.url = url
|
|
+ c.body = util.StringIO()
|
|
+ c.http_code = -1
|
|
+ m.handles.append(c)
|
|
+ # pycurl API calls
|
|
+ c.setopt(c.URL, c.url)
|
|
+ c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
+ m.add_handle(c)
|
|
+
|
|
+ # get data
|
|
+ num_handles = len(m.handles)
|
|
+
|
|
+ while (pycurl.E_CALL_MULTI_PERFORM==m.socket_all()[0]):
|
|
+ pass
|
|
+
|
|
+ timeout = m.timeout()
|
|
+
|
|
+
|
|
+ while True:
|
|
+ (rr, wr, er) = select.select(sockets,sockets,sockets,timeout/1000.0)
|
|
+ socketSet = set(rr+wr+er)
|
|
+ if socketSet:
|
|
+ for s in socketSet:
|
|
+ while True:
|
|
+ (ret,running) = m.socket_action(s,0)
|
|
+ if ret!=pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+ else:
|
|
+ (ret,running) = m.socket_action(pycurl.SOCKET_TIMEOUT,0)
|
|
+ if running==0:
|
|
+ break
|
|
+
|
|
+ for c in m.handles:
|
|
+ # save info in standard Python attributes
|
|
+ c.http_code = c.getinfo(c.HTTP_CODE)
|
|
+
|
|
+ # at least in and remove events per socket
|
|
+ assert len(socket_events) >= 6
|
|
+
|
|
+ # print result
|
|
+ for c in m.handles:
|
|
+ self.assertEqual('success', c.body.getvalue())
|
|
+ self.assertEqual(200, c.http_code)
|
|
+
|
|
+ # multi, not curl handle
|
|
+ self.check(pycurl.POLL_IN, m, socket_events)
|
|
+ self.check(pycurl.POLL_REMOVE, m, socket_events)
|
|
+
|
|
+ assert len(timers) > 0
|
|
+ assert timers[0] > 0
|
|
+ self.assertEqual(-1, timers[-1])
|
|
+
|
|
+ # close handles
|
|
+ for c in m.handles:
|
|
+ # pycurl API calls
|
|
+ m.remove_handle(c)
|
|
+ c.close()
|
|
+ m.close()
|
|
+
|
|
+ def check(self, event, multi, socket_events):
|
|
+ for event_, multi_ in socket_events:
|
|
+ if event == event_ and multi == multi_:
|
|
+ return
|
|
+ assert False, '%d %s not found in socket events' % (event, multi)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From b9fc3bbb01affc790d94801556275e853d03c2c0 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:15:47 -0500
|
|
Subject: [PATCH 044/112] Ported test_multi_timer.py
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_timer_test.py | 88 +++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 88 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/multi_timer_test.py
|
|
|
|
diff --git a/tests/multi_timer_test.py b/tests/multi_timer_test.py
|
|
new file mode 100644
|
|
index 0000000..e961780
|
|
--- /dev/null
|
|
+++ b/tests/multi_timer_test.py
|
|
@@ -0,0 +1,88 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+import select
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module_1, teardown_module_1 = runwsgi.app_runner_setup((app.app, 8380))
|
|
+setup_module_2, teardown_module_2 = runwsgi.app_runner_setup((app.app, 8381))
|
|
+setup_module_3, teardown_module_3 = runwsgi.app_runner_setup((app.app, 8382))
|
|
+
|
|
+def setup_module(mod):
|
|
+ setup_module_1(mod)
|
|
+ setup_module_2(mod)
|
|
+ setup_module_3(mod)
|
|
+
|
|
+def teardown_module(mod):
|
|
+ teardown_module_3(mod)
|
|
+ teardown_module_2(mod)
|
|
+ teardown_module_1(mod)
|
|
+
|
|
+class MultiSocketTest(unittest.TestCase):
|
|
+ def test_multi_timer(self):
|
|
+ urls = [
|
|
+ 'http://localhost:8380/success',
|
|
+ 'http://localhost:8381/success',
|
|
+ 'http://localhost:8382/success',
|
|
+ ]
|
|
+
|
|
+ timers = []
|
|
+
|
|
+ # timer callback
|
|
+ def timer(msecs):
|
|
+ #print('Timer callback msecs:', msecs)
|
|
+ timers.append(msecs)
|
|
+
|
|
+ # init
|
|
+ m = pycurl.CurlMulti()
|
|
+ m.setopt(pycurl.M_PIPELINING, 1)
|
|
+ m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
+ m.handles = []
|
|
+ for url in urls:
|
|
+ c = pycurl.Curl()
|
|
+ # save info in standard Python attributes
|
|
+ c.url = url
|
|
+ c.body = util.StringIO()
|
|
+ c.http_code = -1
|
|
+ m.handles.append(c)
|
|
+ # pycurl API calls
|
|
+ c.setopt(c.URL, c.url)
|
|
+ c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
+ m.add_handle(c)
|
|
+
|
|
+ # get data
|
|
+ num_handles = len(m.handles)
|
|
+ while num_handles:
|
|
+ while 1:
|
|
+ ret, num_handles = m.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+ # currently no more I/O is pending, could do something in the meantime
|
|
+ # (display a progress bar, etc.)
|
|
+ m.select(1.0)
|
|
+
|
|
+ for c in m.handles:
|
|
+ # save info in standard Python attributes
|
|
+ c.http_code = c.getinfo(c.HTTP_CODE)
|
|
+
|
|
+ # print result
|
|
+ for c in m.handles:
|
|
+ self.assertEqual('success', c.body.getvalue())
|
|
+ self.assertEqual(200, c.http_code)
|
|
+
|
|
+ assert len(timers) > 0
|
|
+ assert timers[0] > 0
|
|
+ self.assertEqual(-1, timers[-1])
|
|
+
|
|
+ # close handles
|
|
+ for c in m.handles:
|
|
+ # pycurl API calls
|
|
+ m.remove_handle(c)
|
|
+ c.close()
|
|
+ m.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 1411a22bd02d30b7a0dc884ad406fdb4169e1307 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:17:14 -0500
|
|
Subject: [PATCH 045/112] Timers are tested in multi_timer test, delete them from other multi tests
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_socket_select_test.py | 12 ------------
|
|
tests/multi_socket_test.py | 13 -------------
|
|
2 files changed, 0 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/tests/multi_socket_select_test.py b/tests/multi_socket_select_test.py
|
|
index b9ba950..0c472cf 100644
|
|
--- a/tests/multi_socket_select_test.py
|
|
+++ b/tests/multi_socket_select_test.py
|
|
@@ -35,13 +35,6 @@ class MultiSocketSelectTest(unittest.TestCase):
|
|
'http://localhost:8382/success',
|
|
]
|
|
|
|
- timers = []
|
|
-
|
|
- # timer callback
|
|
- def timer(msecs):
|
|
- #print('Timer callback msecs:', msecs)
|
|
- timers.append(msecs)
|
|
-
|
|
socket_events = []
|
|
|
|
# socket callback
|
|
@@ -58,7 +51,6 @@ class MultiSocketSelectTest(unittest.TestCase):
|
|
# init
|
|
m = pycurl.CurlMulti()
|
|
m.setopt(pycurl.M_PIPELINING, 1)
|
|
- m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
m.setopt(pycurl.M_SOCKETFUNCTION, socket)
|
|
m.handles = []
|
|
for url in urls:
|
|
@@ -112,10 +104,6 @@ class MultiSocketSelectTest(unittest.TestCase):
|
|
self.check(pycurl.POLL_IN, m, socket_events)
|
|
self.check(pycurl.POLL_REMOVE, m, socket_events)
|
|
|
|
- assert len(timers) > 0
|
|
- assert timers[0] > 0
|
|
- self.assertEqual(-1, timers[-1])
|
|
-
|
|
# close handles
|
|
for c in m.handles:
|
|
# pycurl API calls
|
|
diff --git a/tests/multi_socket_test.py b/tests/multi_socket_test.py
|
|
index 2586569..2cce7ae 100644
|
|
--- a/tests/multi_socket_test.py
|
|
+++ b/tests/multi_socket_test.py
|
|
@@ -32,25 +32,16 @@ class MultiSocketTest(unittest.TestCase):
|
|
'http://localhost:8382/success',
|
|
]
|
|
|
|
- timers = []
|
|
-
|
|
- # timer callback
|
|
- def timer(msecs):
|
|
- #print('Timer callback msecs:', msecs)
|
|
- timers.append(msecs)
|
|
-
|
|
socket_events = []
|
|
|
|
# socket callback
|
|
def socket(event, socket, multi, data):
|
|
#print(event, socket, multi, data)
|
|
- # multi.assign(socket, timer)
|
|
socket_events.append((event, multi))
|
|
|
|
# init
|
|
m = pycurl.CurlMulti()
|
|
m.setopt(pycurl.M_PIPELINING, 1)
|
|
- m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
m.setopt(pycurl.M_SOCKETFUNCTION, socket)
|
|
m.handles = []
|
|
for url in urls:
|
|
@@ -92,10 +83,6 @@ class MultiSocketTest(unittest.TestCase):
|
|
self.check(pycurl.POLL_IN, m, socket_events)
|
|
self.check(pycurl.POLL_REMOVE, m, socket_events)
|
|
|
|
- assert len(timers) > 0
|
|
- assert timers[0] > 0
|
|
- self.assertEqual(-1, timers[-1])
|
|
-
|
|
# close handles
|
|
for c in m.handles:
|
|
# pycurl API calls
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From dae1d75a3c083cc5c37cefff47d185ed0bf16af6 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:30:48 -0500
|
|
Subject: [PATCH 046/112] Ported post test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/app.py | 5 +++++
|
|
tests/post_test.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 54 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/post_test.py
|
|
|
|
diff --git a/tests/app.py b/tests/app.py
|
|
index 3b9303b..1fa09a6 100644
|
|
--- a/tests/app.py
|
|
+++ b/tests/app.py
|
|
@@ -1,4 +1,5 @@
|
|
import bottle
|
|
+import json
|
|
|
|
app = bottle.Bottle()
|
|
|
|
@@ -13,3 +14,7 @@ def forbidden():
|
|
@app.route('/status/404')
|
|
def not_found():
|
|
bottle.abort(404, 'not found')
|
|
+
|
|
+@app.route('/postfields', method='post')
|
|
+def postfields():
|
|
+ return json.dumps(dict(bottle.request.forms))
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
new file mode 100644
|
|
index 0000000..183c4c9
|
|
--- /dev/null
|
|
+++ b/tests/post_test.py
|
|
@@ -0,0 +1,49 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import pycurl
|
|
+import unittest
|
|
+import io
|
|
+import json
|
|
+try:
|
|
+ import urllib.parse as urllib_parse
|
|
+except ImportError:
|
|
+ import urllib as urllib_parse
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class PostTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_post_single_field(self):
|
|
+ pf = {'field1': 'value1'}
|
|
+ self.check(pf)
|
|
+
|
|
+ def test_post_multiple_fields(self):
|
|
+ pf = {'field1':'value1', 'field2':'value2 with blanks', 'field3':'value3'}
|
|
+ self.check(pf)
|
|
+
|
|
+ def test_post_fields_with_ampersand(self):
|
|
+ pf = {'field1':'value1', 'field2':'value2 with blanks and & chars',
|
|
+ 'field3':'value3'}
|
|
+ self.check(pf)
|
|
+
|
|
+ def check(self, pf):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/postfields')
|
|
+ self.curl.setopt(pycurl.POSTFIELDS, urllib_parse.urlencode(pf))
|
|
+ #self.curl.setopt(pycurl.VERBOSE, 1)
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+ body = sio.getvalue()
|
|
+ returned_fields = json.loads(body)
|
|
+ self.assertEqual(pf, returned_fields)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 453c605a6a0ab5b04d5d1e2cf70cd99a4fd9db18 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:35:02 -0500
|
|
Subject: [PATCH 047/112] Port test_post2.py null byte test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/post_test.py | 28 ++++++++++++++++++++++++----
|
|
1 files changed, 24 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index 183c4c9..6f9cf80 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -26,18 +26,18 @@ class PostTest(unittest.TestCase):
|
|
|
|
def test_post_single_field(self):
|
|
pf = {'field1': 'value1'}
|
|
- self.check(pf)
|
|
+ self.urlencode_and_check(pf)
|
|
|
|
def test_post_multiple_fields(self):
|
|
pf = {'field1':'value1', 'field2':'value2 with blanks', 'field3':'value3'}
|
|
- self.check(pf)
|
|
+ self.urlencode_and_check(pf)
|
|
|
|
def test_post_fields_with_ampersand(self):
|
|
pf = {'field1':'value1', 'field2':'value2 with blanks and & chars',
|
|
'field3':'value3'}
|
|
- self.check(pf)
|
|
+ self.urlencode_and_check(pf)
|
|
|
|
- def check(self, pf):
|
|
+ def urlencode_and_check(self, pf):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/postfields')
|
|
self.curl.setopt(pycurl.POSTFIELDS, urllib_parse.urlencode(pf))
|
|
#self.curl.setopt(pycurl.VERBOSE, 1)
|
|
@@ -47,3 +47,23 @@ class PostTest(unittest.TestCase):
|
|
body = sio.getvalue()
|
|
returned_fields = json.loads(body)
|
|
self.assertEqual(pf, returned_fields)
|
|
+
|
|
+ def test_post_with_null_byte(self):
|
|
+ send = [
|
|
+ ('field3', (pycurl.FORM_CONTENTS, 'this is wei\000rd, but null-bytes are okay'))
|
|
+ ]
|
|
+ expect = {
|
|
+ 'field3': 'this is wei\000rd, but null-bytes are okay',
|
|
+ }
|
|
+ self.check_post(send, expect)
|
|
+
|
|
+ def check_post(self, send, expect):
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/postfields')
|
|
+ self.curl.setopt(pycurl.HTTPPOST, send)
|
|
+ #self.curl.setopt(pycurl.VERBOSE, 1)
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+ body = sio.getvalue()
|
|
+ returned_fields = json.loads(body)
|
|
+ self.assertEqual(expect, returned_fields)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 7b1e54bf72d209964ba47f5bfa8f8b192b697632 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:50:51 -0500
|
|
Subject: [PATCH 048/112] Port test_post2.py file upload test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/app.py | 24 ++++++++++++++++++++++++
|
|
tests/post_test.py | 22 +++++++++++++++++++---
|
|
2 files changed, 43 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/tests/app.py b/tests/app.py
|
|
index 1fa09a6..a83e628 100644
|
|
--- a/tests/app.py
|
|
+++ b/tests/app.py
|
|
@@ -18,3 +18,27 @@ def not_found():
|
|
@app.route('/postfields', method='post')
|
|
def postfields():
|
|
return json.dumps(dict(bottle.request.forms))
|
|
+
|
|
+# XXX file is not a bottle FileUpload instance, but FieldStorage?
|
|
+def convert_file(key, file):
|
|
+ return {
|
|
+ 'key': key,
|
|
+ 'name': file.name,
|
|
+ 'raw_filename': file.raw_filename,
|
|
+ 'headers': file.headers,
|
|
+ 'content_type': file.content_type,
|
|
+ 'content_length': file.content_length,
|
|
+ 'data': file.read(),
|
|
+ }
|
|
+
|
|
+def convert_file(key, file):
|
|
+ return {
|
|
+ 'name': file.name,
|
|
+ 'filename': file.filename,
|
|
+ 'data': file.file.read(),
|
|
+ }
|
|
+
|
|
+@app.route('/files', method='post')
|
|
+def files():
|
|
+ files = [convert_file(key, bottle.request.files[key]) for key in bottle.request.files]
|
|
+ return json.dumps(files)
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index 6f9cf80..7df0f3b 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -2,6 +2,7 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
+import os.path
|
|
import pycurl
|
|
import unittest
|
|
import io
|
|
@@ -55,10 +56,25 @@ class PostTest(unittest.TestCase):
|
|
expect = {
|
|
'field3': 'this is wei\000rd, but null-bytes are okay',
|
|
}
|
|
- self.check_post(send, expect)
|
|
+ self.check_post(send, expect, 'http://localhost:8380/postfields')
|
|
|
|
- def check_post(self, send, expect):
|
|
- self.curl.setopt(pycurl.URL, 'http://localhost:8380/postfields')
|
|
+ def test_post_file(self):
|
|
+ path = os.path.join(os.path.dirname(__file__), '..', 'README')
|
|
+ with open(path) as f:
|
|
+ contents = f.read()
|
|
+ send = [
|
|
+ #('field2', (pycurl.FORM_FILE, 'test_post.py', pycurl.FORM_FILE, 'test_post2.py')),
|
|
+ ('field2', (pycurl.FORM_FILE, path)),
|
|
+ ]
|
|
+ expect = [{
|
|
+ 'name': 'field2',
|
|
+ 'filename': 'README',
|
|
+ 'data': contents,
|
|
+ }]
|
|
+ self.check_post(send, expect, 'http://localhost:8380/files')
|
|
+
|
|
+ def check_post(self, send, expect, endpoint):
|
|
+ self.curl.setopt(pycurl.URL, endpoint)
|
|
self.curl.setopt(pycurl.HTTPPOST, send)
|
|
#self.curl.setopt(pycurl.VERBOSE, 1)
|
|
sio = util.StringIO()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From f48bdb27952ad5e38f8c259711a514e146ff454c Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:51:45 -0500
|
|
Subject: [PATCH 049/112] Add a note that this test takes forever to run
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/post_test.py | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index 7df0f3b..564d043 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -73,6 +73,7 @@ class PostTest(unittest.TestCase):
|
|
}]
|
|
self.check_post(send, expect, 'http://localhost:8380/files')
|
|
|
|
+ # XXX this test takes about a second to run, check keep-alives?
|
|
def check_post(self, send, expect, endpoint):
|
|
self.curl.setopt(pycurl.URL, endpoint)
|
|
self.curl.setopt(pycurl.HTTPPOST, send)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From e276465088c1bfa8141417c1d8375de2c5a969a2 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 5 Mar 2013 23:59:04 -0500
|
|
Subject: [PATCH 050/112] Ported test_post3.py
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/post_with_read_callback_test.py | 60 +++++++++++++++++++++++++++++++++
|
|
1 files changed, 60 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/post_with_read_callback_test.py
|
|
|
|
diff --git a/tests/post_with_read_callback_test.py b/tests/post_with_read_callback_test.py
|
|
new file mode 100644
|
|
index 0000000..a09e83a
|
|
--- /dev/null
|
|
+++ b/tests/post_with_read_callback_test.py
|
|
@@ -0,0 +1,60 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import os.path
|
|
+import pycurl
|
|
+import unittest
|
|
+import io
|
|
+import json
|
|
+try:
|
|
+ import urllib.parse as urllib_parse
|
|
+except ImportError:
|
|
+ import urllib as urllib_parse
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+POSTFIELDS = {
|
|
+ 'field1':'value1',
|
|
+ 'field2':'value2 with blanks',
|
|
+ 'field3':'value3',
|
|
+}
|
|
+POSTSTRING = urllib_parse.urlencode(POSTFIELDS)
|
|
+
|
|
+class DataProvider(object):
|
|
+ def __init__(self):
|
|
+ self.finished = False
|
|
+
|
|
+ def read_cb(self, size):
|
|
+ assert len(POSTSTRING) <= size
|
|
+ if not self.finished:
|
|
+ self.finished = True
|
|
+ return POSTSTRING
|
|
+ else:
|
|
+ # Nothing more to read
|
|
+ return ""
|
|
+
|
|
+class PostWithReadCallbackTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_post_with_read_callback(self):
|
|
+ d = DataProvider()
|
|
+ self.curl.setopt(self.curl.URL, 'http://localhost:8380/postfields')
|
|
+ self.curl.setopt(self.curl.POST, 1)
|
|
+ self.curl.setopt(self.curl.POSTFIELDSIZE, len(POSTSTRING))
|
|
+ self.curl.setopt(self.curl.READFUNCTION, d.read_cb)
|
|
+ #self.curl.setopt(self.curl.VERBOSE, 1)
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+
|
|
+ actual = json.loads(sio.getvalue())
|
|
+ self.assertEqual(POSTFIELDS, actual)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From bff1fa53c2c59ee0a31e3bb73d20eb56cf0305d4 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:10:41 -0500
|
|
Subject: [PATCH 051/112] Ported test_socketopen.py
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/socket_open_test.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 45 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/socket_open_test.py
|
|
|
|
diff --git a/tests/socket_open_test.py b/tests/socket_open_test.py
|
|
new file mode 100644
|
|
index 0000000..dff3f65
|
|
--- /dev/null
|
|
+++ b/tests/socket_open_test.py
|
|
@@ -0,0 +1,45 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import socket
|
|
+import pycurl
|
|
+import unittest
|
|
+try:
|
|
+ import urllib.parse as urllib_parse
|
|
+except ImportError:
|
|
+ import urllib as urllib_parse
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+socket_open_called = False
|
|
+
|
|
+def socket_open(family, socktype, protocol):
|
|
+ global socket_open_called
|
|
+ socket_open_called = True
|
|
+
|
|
+ #print(family, socktype, protocol)
|
|
+ s = socket.socket(family, socktype, protocol)
|
|
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
+ return s
|
|
+
|
|
+class SocketOpenTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_socket_open(self):
|
|
+ self.curl.setopt(pycurl.OPENSOCKETFUNCTION, socket_open)
|
|
+ self.curl.setopt(self.curl.URL, 'http://localhost:8380/success')
|
|
+ sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
+ self.curl.perform()
|
|
+
|
|
+ assert socket_open_called
|
|
+ self.assertEqual('success', sio.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 3336fa0310f6f030f8a9e27009c42e1b560d3a43 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:13:46 -0500
|
|
Subject: [PATCH 052/112] Ported test_share.py
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/share_test.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 51 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/share_test.py
|
|
|
|
diff --git a/tests/share_test.py b/tests/share_test.py
|
|
new file mode 100644
|
|
index 0000000..7b5da77
|
|
--- /dev/null
|
|
+++ b/tests/share_test.py
|
|
@@ -0,0 +1,51 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import threading
|
|
+import pycurl
|
|
+import unittest
|
|
+try:
|
|
+ import urllib.parse as urllib_parse
|
|
+except ImportError:
|
|
+ import urllib as urllib_parse
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class WorkerThread(threading.Thread):
|
|
+
|
|
+ def __init__(self, share):
|
|
+ threading.Thread.__init__(self)
|
|
+ self.curl = pycurl.Curl()
|
|
+ self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ self.curl.setopt(pycurl.SHARE, share)
|
|
+ self.sio = util.StringIO()
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, self.sio.write)
|
|
+
|
|
+ def run(self):
|
|
+ self.curl.perform()
|
|
+ self.curl.close()
|
|
+
|
|
+class ShareTest(unittest.TestCase):
|
|
+ def test_share(self):
|
|
+ s = pycurl.CurlShare()
|
|
+ s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_COOKIE)
|
|
+ s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_DNS)
|
|
+
|
|
+ t1 = WorkerThread(s)
|
|
+ t2 = WorkerThread(s)
|
|
+
|
|
+ t1.start()
|
|
+ t2.start()
|
|
+
|
|
+ t1.join()
|
|
+ t2.join()
|
|
+
|
|
+ del s
|
|
+
|
|
+ self.assertEqual('success', t1.sio.getvalue())
|
|
+ self.assertEqual('success', t2.sio.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 1a601a915a969434e1c707e3d17e302b1c7421a5 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:26:45 -0500
|
|
Subject: [PATCH 053/112] Port test_reset.py, which appears to be broken; skip the ported version for now
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/reset_test.py | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 76 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/reset_test.py
|
|
|
|
diff --git a/tests/reset_test.py b/tests/reset_test.py
|
|
new file mode 100644
|
|
index 0000000..66b7108
|
|
--- /dev/null
|
|
+++ b/tests/reset_test.py
|
|
@@ -0,0 +1,76 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import sys
|
|
+import pycurl
|
|
+import unittest
|
|
+try:
|
|
+ import urllib.parse as urllib_parse
|
|
+except ImportError:
|
|
+ import urllib as urllib_parse
|
|
+
|
|
+from . import app
|
|
+from . import runwsgi
|
|
+from . import util
|
|
+
|
|
+setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
+
|
|
+class ResetTest(unittest.TestCase):
|
|
+ # XXX this test was broken when it was test_reset.py
|
|
+ def skip_test_reset(self):
|
|
+ outf = util.StringIO()
|
|
+ cm = pycurl.CurlMulti()
|
|
+
|
|
+ # Set multi handle's options
|
|
+ cm.setopt(pycurl.M_PIPELINING, 1)
|
|
+
|
|
+ eh = pycurl.Curl()
|
|
+
|
|
+ for x in range(1, 20):
|
|
+
|
|
+ eh.setopt(pycurl.WRITEFUNCTION, outf.write)
|
|
+ eh.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
+ cm.add_handle(eh)
|
|
+
|
|
+ while 1:
|
|
+ ret, active_handles = cm.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ while active_handles:
|
|
+ ret = cm.select(1.0)
|
|
+ if ret == -1:
|
|
+ continue
|
|
+ while 1:
|
|
+ ret, active_handles = cm.perform()
|
|
+ if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
+ break
|
|
+
|
|
+ count, good, bad = cm.info_read()
|
|
+
|
|
+ for h, en, em in bad:
|
|
+ print("Transfer to %s failed with %d, %s\n" % \
|
|
+ (h.getinfo(pycurl.EFFECTIVE_URL), en, em))
|
|
+ raise RuntimeError
|
|
+
|
|
+ for h in good:
|
|
+ httpcode = h.getinfo(pycurl.RESPONSE_CODE)
|
|
+ if httpcode != 200:
|
|
+ print("Transfer to %s failed with code %d\n" %\
|
|
+ (h.getinfo(pycurl.EFFECTIVE_URL), httpcode))
|
|
+ raise RuntimeError
|
|
+
|
|
+ else:
|
|
+ print("Recd %d bytes from %s" % \
|
|
+ (h.getinfo(pycurl.SIZE_DOWNLOAD),
|
|
+ h.getinfo(pycurl.EFFECTIVE_URL)))
|
|
+
|
|
+ cm.remove_handle(eh)
|
|
+ eh.reset()
|
|
+
|
|
+ eh.close()
|
|
+ cm.close()
|
|
+ outf.close()
|
|
+
|
|
+ pycurl.global_cleanup()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 4c6a41a2156ef35f9f06f604101bc12422806eed Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:55:41 -0500
|
|
Subject: [PATCH 054/112] Start a server on each port once, different servers should go on different ports
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/runwsgi.py | 9 ++++++++-
|
|
1 files changed, 8 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
index 7b39358..6d3b69f 100644
|
|
--- a/tests/runwsgi.py
|
|
+++ b/tests/runwsgi.py
|
|
@@ -48,6 +48,8 @@ class ServerThread(threading.Thread):
|
|
def run(self):
|
|
bottle.run(self.app, server=self.server, quiet=True)
|
|
|
|
+started_servers = {}
|
|
+
|
|
def app_runner_setup(*specs):
|
|
'''Returns setup and teardown methods for running a list of WSGI
|
|
applications in a daemon thread.
|
|
@@ -73,9 +75,14 @@ def app_runner_setup(*specs):
|
|
kwargs = {}
|
|
else:
|
|
app, port, kwargs = spec
|
|
- self.servers.append(start_bottle_server(app, port, **kwargs))
|
|
+ if port in started_servers:
|
|
+ assert started_servers[port] == (app, kwargs)
|
|
+ else:
|
|
+ self.servers.append(start_bottle_server(app, port, **kwargs))
|
|
+ started_servers[port] = (app, kwargs)
|
|
|
|
def teardown(self):
|
|
+ return
|
|
for server in self.servers:
|
|
# if no tests from module were run, there is no server to shut down
|
|
if hasattr(server, 'srv'):
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5e561de2fcf5cab18d29063b778ea24d61ce8b0e Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:56:44 -0500
|
|
Subject: [PATCH 055/112] Need to skip more aggressively it would seem
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 2 +-
|
|
tests/reset_test.py | 2 +-
|
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index a0de66e..c0d256b 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -40,7 +40,7 @@ class DefaultWriteFunctionTest(unittest.TestCase):
|
|
os.fsync(STDOUT_FD_NUM)
|
|
|
|
# I have a really hard time getting this to work with nose output capture
|
|
- def skip_test_perform_get_with_default_write_function(self):
|
|
+ def skip_perform_get_with_default_write_function(self):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/success')
|
|
with tempfile.NamedTemporaryFile() as f:
|
|
#with open('w', 'w+') as f:
|
|
diff --git a/tests/reset_test.py b/tests/reset_test.py
|
|
index 66b7108..cc55f86 100644
|
|
--- a/tests/reset_test.py
|
|
+++ b/tests/reset_test.py
|
|
@@ -18,7 +18,7 @@ setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
class ResetTest(unittest.TestCase):
|
|
# XXX this test was broken when it was test_reset.py
|
|
- def skip_test_reset(self):
|
|
+ def skip_reset(self):
|
|
outf = util.StringIO()
|
|
cm = pycurl.CurlMulti()
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 136485fea353fb6b2c63bf8ea313187835852d11 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 01:29:59 -0500
|
|
Subject: [PATCH 056/112] Store urlencode result in a local variable, otherwise things break in a highly weird way
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/post_test.py | 24 +++++++++++++++++++++++-
|
|
1 files changed, 23 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index 564d043..e8b0675 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -40,11 +40,33 @@ class PostTest(unittest.TestCase):
|
|
|
|
def urlencode_and_check(self, pf):
|
|
self.curl.setopt(pycurl.URL, 'http://localhost:8380/postfields')
|
|
- self.curl.setopt(pycurl.POSTFIELDS, urllib_parse.urlencode(pf))
|
|
+ postfields = urllib_parse.urlencode(pf)
|
|
+ self.curl.setopt(pycurl.POSTFIELDS, postfields)
|
|
+
|
|
+ # But directly passing urlencode result into setopt call:
|
|
+ #self.curl.setopt(pycurl.POSTFIELDS, urllib_parse.urlencode(pf))
|
|
+ # produces:
|
|
+ # {'\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00': ''}
|
|
+ # Traceback (most recent call last):
|
|
+ # File "/usr/local/bin/bottle.py", line 744, in _handle
|
|
+ # return route.call(**args)
|
|
+ # File "/usr/local/bin/bottle.py", line 1479, in wrapper
|
|
+ # rv = callback(*a, **ka)
|
|
+ # File "/home/pie/apps/pycurl/tests/app.py", line 21, in postfields
|
|
+ # return json.dumps(dict(bottle.request.forms))
|
|
+ # File "/usr/local/lib/python2.7/json/__init__.py", line 231, in dumps
|
|
+ # return _default_encoder.encode(obj)
|
|
+ # File "/usr/local/lib/python2.7/json/encoder.py", line 201, in encode
|
|
+ # chunks = self.iterencode(o, _one_shot=True)
|
|
+ # File "/usr/local/lib/python2.7/json/encoder.py", line 264, in iterencode
|
|
+ # return _iterencode(o, 0)
|
|
+ # UnicodeDecodeError: 'utf8' codec can't decode byte 0x80 in position 4: invalid start byte
|
|
+
|
|
#self.curl.setopt(pycurl.VERBOSE, 1)
|
|
sio = util.StringIO()
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
self.curl.perform()
|
|
+ self.assertEqual(200, self.curl.getinfo(pycurl.HTTP_CODE))
|
|
body = sio.getvalue()
|
|
returned_fields = json.loads(body)
|
|
self.assertEqual(pf, returned_fields)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From f456a8e787078a333c2465a1bb4b4bae2a76be9f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 01:32:33 -0500
|
|
Subject: [PATCH 057/112] Fix regular expression to allow all hex chars like it should
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/internals_test.py | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/internals_test.py b/tests/internals_test.py
|
|
index fb451df..f628ab2 100644
|
|
--- a/tests/internals_test.py
|
|
+++ b/tests/internals_test.py
|
|
@@ -180,7 +180,7 @@ class InternalsTest(unittest.TestCase):
|
|
del m, c
|
|
|
|
def test_cyclic_gc(self):
|
|
- regexp = re.compile(r'at (0x\d+)')
|
|
+ regexp = re.compile(r'at (0x[\da-f]+)')
|
|
gc.collect()
|
|
c = pycurl.Curl()
|
|
c.m = pycurl.CurlMulti()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c321100736f098850b3b6c2b75fbf7355ae635ce Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 01:36:48 -0500
|
|
Subject: [PATCH 058/112] Rewrite cyclic gc test to use id()
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/internals_test.py | 9 ++-------
|
|
1 files changed, 2 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/tests/internals_test.py b/tests/internals_test.py
|
|
index f628ab2..0133da0 100644
|
|
--- a/tests/internals_test.py
|
|
+++ b/tests/internals_test.py
|
|
@@ -12,7 +12,6 @@ except ImportError:
|
|
import pickle
|
|
import gc
|
|
import copy
|
|
-import re
|
|
|
|
class InternalsTest(unittest.TestCase):
|
|
def setUp(self):
|
|
@@ -180,7 +179,6 @@ class InternalsTest(unittest.TestCase):
|
|
del m, c
|
|
|
|
def test_cyclic_gc(self):
|
|
- regexp = re.compile(r'at (0x[\da-f]+)')
|
|
gc.collect()
|
|
c = pycurl.Curl()
|
|
c.m = pycurl.CurlMulti()
|
|
@@ -208,17 +206,14 @@ class InternalsTest(unittest.TestCase):
|
|
##print gc.get_objects()
|
|
#if opts.verbose >= 1:
|
|
#print("Tracked objects:", len(gc.get_objects()))
|
|
- match = regexp.search(repr(c))
|
|
- assert match is not None
|
|
- address = match.group(1)
|
|
+ c_id = id(c)
|
|
# The `del' below should delete these 4 objects:
|
|
# Curl + internal dict, CurlMulti + internal dict
|
|
del c
|
|
gc.collect()
|
|
objects = gc.get_objects()
|
|
- search = 'at %s' % address
|
|
for object in objects:
|
|
- assert search not in repr(object)
|
|
+ assert id(object) != c_id
|
|
#if opts.verbose >= 1:
|
|
#print("Tracked objects:", len(gc.get_objects()))
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5b644f3685a8af09b39a0b94b718a2fc7c33b22e Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 03:25:34 -0500
|
|
Subject: [PATCH 059/112] Adjust ftp test to work with vsftpd started from project root
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/ftp_test.py | 18 ++++++++++--------
|
|
1 files changed, 10 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/tests/ftp_test.py b/tests/ftp_test.py
|
|
index d215b6e..1d382ed 100644
|
|
--- a/tests/ftp_test.py
|
|
+++ b/tests/ftp_test.py
|
|
@@ -2,6 +2,8 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
+# Note: this test is meant to be run from pycurl project root.
|
|
+
|
|
import pycurl
|
|
import unittest
|
|
|
|
@@ -15,29 +17,29 @@ class FtpTest(unittest.TestCase):
|
|
self.curl.close()
|
|
|
|
def test_get_ftp(self):
|
|
- self.curl.setopt(pycurl.URL, 'ftp://localhost:8921')
|
|
+ self.curl.setopt(pycurl.URL, 'ftp://localhost:8321')
|
|
sio = util.StringIO()
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
self.curl.perform()
|
|
|
|
result = sio.getvalue()
|
|
assert 'README' in result
|
|
- assert 'bin -> usr/bin' in result
|
|
+ assert 'INSTALL' in result
|
|
|
|
# XXX this test needs to be fixed
|
|
def test_quote(self):
|
|
- self.curl.setopt(pycurl.URL, 'ftp://localhost:8921')
|
|
+ self.curl.setopt(pycurl.URL, 'ftp://localhost:8321')
|
|
sio = util.StringIO()
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
- self.curl.setopt(pycurl.QUOTE, ['CWD pub'])
|
|
+ self.curl.setopt(pycurl.QUOTE, ['CWD tests'])
|
|
self.curl.perform()
|
|
|
|
result = sio.getvalue()
|
|
- assert 'README' in result
|
|
- assert 'bin -> usr/bin' in result
|
|
+ assert 'README' not in result
|
|
+ assert 'ftp_test.py' in result
|
|
|
|
def test_epsv(self):
|
|
- self.curl.setopt(pycurl.URL, 'ftp://localhost:8921')
|
|
+ self.curl.setopt(pycurl.URL, 'ftp://localhost:8321')
|
|
sio = util.StringIO()
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
self.curl.setopt(pycurl.FTP_USE_EPSV, 1)
|
|
@@ -45,4 +47,4 @@ class FtpTest(unittest.TestCase):
|
|
|
|
result = sio.getvalue()
|
|
assert 'README' in result
|
|
- assert 'bin -> usr/bin' in result
|
|
+ assert 'INSTALL' in result
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 758ab367deff461fdd9c631ee4128bd7a4a0b1b3 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:01:13 -0500
|
|
Subject: [PATCH 060/112] Execute vsftpd as test ftp server
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/ftp_test.py | 3 ++
|
|
tests/procmgr.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
tests/runwsgi.py | 20 ++++++++------
|
|
tests/vsftpd.conf | 10 +++++++
|
|
4 files changed, 98 insertions(+), 8 deletions(-)
|
|
create mode 100644 tests/procmgr.py
|
|
create mode 100644 tests/vsftpd.conf
|
|
|
|
diff --git a/tests/ftp_test.py b/tests/ftp_test.py
|
|
index 1d382ed..fa2ef79 100644
|
|
--- a/tests/ftp_test.py
|
|
+++ b/tests/ftp_test.py
|
|
@@ -8,6 +8,9 @@ import pycurl
|
|
import unittest
|
|
|
|
from . import util
|
|
+from . import procmgr
|
|
+
|
|
+setup_module, teardown_module = procmgr.vsftpd_setup()
|
|
|
|
class FtpTest(unittest.TestCase):
|
|
def setUp(self):
|
|
diff --git a/tests/procmgr.py b/tests/procmgr.py
|
|
new file mode 100644
|
|
index 0000000..8d5c0cc
|
|
--- /dev/null
|
|
+++ b/tests/procmgr.py
|
|
@@ -0,0 +1,73 @@
|
|
+import threading
|
|
+import subprocess
|
|
+import os
|
|
+import signal
|
|
+
|
|
+from . import runwsgi
|
|
+
|
|
+class ProcessManager(object):
|
|
+ def __init__(self, cmd):
|
|
+ self.cmd = cmd
|
|
+
|
|
+ def start(self):
|
|
+ self.process = subprocess.Popen(self.cmd)
|
|
+
|
|
+ self.thread = threading.Thread(target=self.run)
|
|
+ self.thread.daemon = True
|
|
+ self.thread.start()
|
|
+
|
|
+ def run(self):
|
|
+ self.process.communicate()
|
|
+
|
|
+managers = {}
|
|
+
|
|
+def start(cmd):
|
|
+ if str(cmd) in managers:
|
|
+ # already started
|
|
+ return
|
|
+
|
|
+ manager = ProcessManager(cmd)
|
|
+ managers[str(cmd)] = manager
|
|
+ manager.start()
|
|
+
|
|
+def start_setup(cmd):
|
|
+ def do_start():
|
|
+ start(cmd)
|
|
+ return do_start
|
|
+
|
|
+# Example on FreeBSD:
|
|
+# PYCURL_VSFTPD_PATH=/usr/local/libexec/vsftpd nosetests
|
|
+
|
|
+if 'PYCURL_VSFTPD_PATH' in os.environ:
|
|
+ vsftpd_path = os.environ['PYCURL_VSFTPD_PATH']
|
|
+else:
|
|
+ vsftpd_path = 'vsftpd'
|
|
+
|
|
+def vsftpd_setup():
|
|
+ config_file_path = os.path.join(os.path.dirname(__file__), 'vsftpd.conf')
|
|
+ root_path = os.path.join(os.path.dirname(__file__), '..')
|
|
+ cmd = [
|
|
+ vsftpd_path,
|
|
+ config_file_path,
|
|
+ '-oanon_root=%s' % root_path,
|
|
+ ]
|
|
+ setup_module = start_setup(cmd)
|
|
+ def do_setup_module():
|
|
+ setup_module()
|
|
+ ok = runwsgi.wait_for_network_service(('127.0.0.1', 8321), 0.1, 10)
|
|
+ if not ok:
|
|
+ import warnings
|
|
+ warnings.warn('vsftpd did not start after 1 second')
|
|
+
|
|
+ def teardown_module():
|
|
+ try:
|
|
+ manager = managers[str(cmd)]
|
|
+ except KeyError:
|
|
+ pass
|
|
+ else:
|
|
+ try:
|
|
+ os.kill(manager.process.pid, signal.SIGTERM)
|
|
+ except OSError:
|
|
+ pass
|
|
+
|
|
+ return do_setup_module, teardown_module
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
index 6d3b69f..5217a3f 100644
|
|
--- a/tests/runwsgi.py
|
|
+++ b/tests/runwsgi.py
|
|
@@ -16,21 +16,25 @@ class Server(bottle.WSGIRefServer):
|
|
self.srv = make_server(self.host, self.port, handler, **self.options)
|
|
self.srv.serve_forever(poll_interval=0.1)
|
|
|
|
-def start_bottle_server(app, port, **kwargs):
|
|
- server_thread = ServerThread(app, port, kwargs)
|
|
- server_thread.daemon = True
|
|
- server_thread.start()
|
|
-
|
|
+def wait_for_network_service(netloc, check_interval, num_attempts):
|
|
ok = False
|
|
- for i in range(10):
|
|
+ for i in range(num_attempts):
|
|
try:
|
|
- conn = socket.create_connection(('127.0.0.1', port), 0.1)
|
|
+ conn = socket.create_connection(netloc, check_interval)
|
|
except socket.error as e:
|
|
- _time.sleep(0.1)
|
|
+ _time.sleep(check_interval)
|
|
else:
|
|
conn.close()
|
|
ok = True
|
|
break
|
|
+ return ok
|
|
+
|
|
+def start_bottle_server(app, port, **kwargs):
|
|
+ server_thread = ServerThread(app, port, kwargs)
|
|
+ server_thread.daemon = True
|
|
+ server_thread.start()
|
|
+
|
|
+ ok = wait_for_network_service(('127.0.0.1', port), 0.1, 10)
|
|
if not ok:
|
|
import warnings
|
|
warnings.warn('Server did not start after 1 second')
|
|
diff --git a/tests/vsftpd.conf b/tests/vsftpd.conf
|
|
new file mode 100644
|
|
index 0000000..0abb39f
|
|
--- /dev/null
|
|
+++ b/tests/vsftpd.conf
|
|
@@ -0,0 +1,10 @@
|
|
+anon_world_readable_only=yes
|
|
+anonymous_enable=yes
|
|
+# currently we only list files
|
|
+download_enable=no
|
|
+listen=yes
|
|
+run_as_launching_user=yes
|
|
+write_enable=no
|
|
+listen_port=8321
|
|
+# should be supplied on command line
|
|
+anon_root=/var/empty
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 67495d01da3e8875a9b5882ecdca50c96ee47b15 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:37:19 -0500
|
|
Subject: [PATCH 061/112] Move gtk and xmlrpc tests to examples as they do not test anything not already tested by the test suite
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
examples/tests/test_gtk.py | 98 +++++++++++++++++++++++++++++++++++++++++
|
|
examples/tests/test_xmlrpc.py | 29 ++++++++++++
|
|
tests/test_gtk.py | 98 -----------------------------------------
|
|
tests/test_xmlrpc.py | 29 ------------
|
|
4 files changed, 127 insertions(+), 127 deletions(-)
|
|
create mode 100644 examples/tests/test_gtk.py
|
|
create mode 100644 examples/tests/test_xmlrpc.py
|
|
delete mode 100644 tests/test_gtk.py
|
|
delete mode 100644 tests/test_xmlrpc.py
|
|
|
|
diff --git a/examples/tests/test_gtk.py b/examples/tests/test_gtk.py
|
|
new file mode 100644
|
|
index 0000000..7104439
|
|
--- /dev/null
|
|
+++ b/examples/tests/test_gtk.py
|
|
@@ -0,0 +1,98 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+# $Id$
|
|
+
|
|
+import sys, threading
|
|
+import pycurl
|
|
+import pygtk
|
|
+pygtk.require('2.0')
|
|
+import gtk
|
|
+
|
|
+# We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
|
|
+# the libcurl tutorial for more info.
|
|
+try:
|
|
+ import signal
|
|
+ from signal import SIGPIPE, SIG_IGN
|
|
+ signal.signal(signal.SIGPIPE, signal.SIG_IGN)
|
|
+except ImportError:
|
|
+ pass
|
|
+
|
|
+
|
|
+class ProgressBar:
|
|
+ def __init__(self, uri):
|
|
+ self.round = 0.0
|
|
+ win = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
|
+ win.set_title("PycURL progress")
|
|
+ win.show()
|
|
+ vbox = gtk.VBox(spacing=5)
|
|
+ vbox.set_border_width(10)
|
|
+ win.add(vbox)
|
|
+ win.set_default_size(200, 20)
|
|
+ vbox.show()
|
|
+ label = gtk.Label("Downloading %s" % uri)
|
|
+ label.set_alignment(0, 0.5)
|
|
+ vbox.pack_start(label)
|
|
+ label.show()
|
|
+ pbar = gtk.ProgressBar()
|
|
+ pbar.show()
|
|
+ self.pbar = pbar
|
|
+ vbox.pack_start(pbar)
|
|
+ win.connect("destroy", self.close_app)
|
|
+
|
|
+ def progress(self, download_t, download_d, upload_t, upload_d):
|
|
+ if download_t == 0:
|
|
+ self.round = self.round + 0.1
|
|
+ if self.round >= 1.0: self.round = 0.0
|
|
+ else:
|
|
+ self.round = float(download_d) / float(download_t)
|
|
+ gtk.threads_enter()
|
|
+ self.pbar.set_fraction(self.round)
|
|
+ gtk.threads_leave()
|
|
+
|
|
+ def mainloop(self):
|
|
+ gtk.threads_enter()
|
|
+ gtk.main()
|
|
+ gtk.threads_leave()
|
|
+
|
|
+ def close_app(self, *args):
|
|
+ args[0].destroy()
|
|
+ gtk.main_quit()
|
|
+
|
|
+
|
|
+class Test(threading.Thread):
|
|
+ def __init__(self, url, target_file, progress):
|
|
+ threading.Thread.__init__(self)
|
|
+ self.target_file = target_file
|
|
+ self.progress = progress
|
|
+ self.curl = pycurl.Curl()
|
|
+ self.curl.setopt(pycurl.URL, url)
|
|
+ self.curl.setopt(pycurl.WRITEDATA, self.target_file)
|
|
+ self.curl.setopt(pycurl.FOLLOWLOCATION, 1)
|
|
+ self.curl.setopt(pycurl.NOPROGRESS, 0)
|
|
+ self.curl.setopt(pycurl.PROGRESSFUNCTION, self.progress)
|
|
+ self.curl.setopt(pycurl.MAXREDIRS, 5)
|
|
+ self.curl.setopt(pycurl.NOSIGNAL, 1)
|
|
+
|
|
+ def run(self):
|
|
+ self.curl.perform()
|
|
+ self.curl.close()
|
|
+ self.target_file.close()
|
|
+ self.progress(1.0, 1.0, 0, 0)
|
|
+
|
|
+
|
|
+# Check command line args
|
|
+if len(sys.argv) < 3:
|
|
+ print "Usage: %s <URL> <filename>" % sys.argv[0]
|
|
+ raise SystemExit
|
|
+
|
|
+# Make a progress bar window
|
|
+p = ProgressBar(sys.argv[1])
|
|
+# Start thread for fetching url
|
|
+Test(sys.argv[1], open(sys.argv[2], 'wb'), p.progress).start()
|
|
+# Enter the GTK mainloop
|
|
+gtk.threads_init()
|
|
+try:
|
|
+ p.mainloop()
|
|
+except KeyboardInterrupt:
|
|
+ pass
|
|
diff --git a/examples/tests/test_xmlrpc.py b/examples/tests/test_xmlrpc.py
|
|
new file mode 100644
|
|
index 0000000..bc5953e
|
|
--- /dev/null
|
|
+++ b/examples/tests/test_xmlrpc.py
|
|
@@ -0,0 +1,29 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+# $Id$
|
|
+
|
|
+## XML-RPC lib included in python2.2
|
|
+import xmlrpclib
|
|
+import pycurl
|
|
+
|
|
+# Header fields passed in request
|
|
+xmlrpc_header = [
|
|
+ "User-Agent: PycURL XML-RPC Test", "Content-Type: text/xml"
|
|
+ ]
|
|
+
|
|
+# XML-RPC request template
|
|
+xmlrpc_template = """
|
|
+<?xml version='1.0'?><methodCall><methodName>%s</methodName>%s</methodCall>
|
|
+"""
|
|
+
|
|
+# Engage
|
|
+c = pycurl.Curl()
|
|
+c.setopt(c.URL, 'http://betty.userland.com/RPC2')
|
|
+c.setopt(c.POST, 1)
|
|
+c.setopt(c.HTTPHEADER, xmlrpc_header)
|
|
+c.setopt(c.POSTFIELDS, xmlrpc_template % ("examples.getStateName", xmlrpclib.dumps((5,))))
|
|
+
|
|
+print 'Response from http://betty.userland.com/'
|
|
+c.perform()
|
|
+c.close()
|
|
diff --git a/tests/test_gtk.py b/tests/test_gtk.py
|
|
deleted file mode 100644
|
|
index 7104439..0000000
|
|
--- a/tests/test_gtk.py
|
|
+++ /dev/null
|
|
@@ -1,98 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys, threading
|
|
-import pycurl
|
|
-import pygtk
|
|
-pygtk.require('2.0')
|
|
-import gtk
|
|
-
|
|
-# We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
|
|
-# the libcurl tutorial for more info.
|
|
-try:
|
|
- import signal
|
|
- from signal import SIGPIPE, SIG_IGN
|
|
- signal.signal(signal.SIGPIPE, signal.SIG_IGN)
|
|
-except ImportError:
|
|
- pass
|
|
-
|
|
-
|
|
-class ProgressBar:
|
|
- def __init__(self, uri):
|
|
- self.round = 0.0
|
|
- win = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
|
- win.set_title("PycURL progress")
|
|
- win.show()
|
|
- vbox = gtk.VBox(spacing=5)
|
|
- vbox.set_border_width(10)
|
|
- win.add(vbox)
|
|
- win.set_default_size(200, 20)
|
|
- vbox.show()
|
|
- label = gtk.Label("Downloading %s" % uri)
|
|
- label.set_alignment(0, 0.5)
|
|
- vbox.pack_start(label)
|
|
- label.show()
|
|
- pbar = gtk.ProgressBar()
|
|
- pbar.show()
|
|
- self.pbar = pbar
|
|
- vbox.pack_start(pbar)
|
|
- win.connect("destroy", self.close_app)
|
|
-
|
|
- def progress(self, download_t, download_d, upload_t, upload_d):
|
|
- if download_t == 0:
|
|
- self.round = self.round + 0.1
|
|
- if self.round >= 1.0: self.round = 0.0
|
|
- else:
|
|
- self.round = float(download_d) / float(download_t)
|
|
- gtk.threads_enter()
|
|
- self.pbar.set_fraction(self.round)
|
|
- gtk.threads_leave()
|
|
-
|
|
- def mainloop(self):
|
|
- gtk.threads_enter()
|
|
- gtk.main()
|
|
- gtk.threads_leave()
|
|
-
|
|
- def close_app(self, *args):
|
|
- args[0].destroy()
|
|
- gtk.main_quit()
|
|
-
|
|
-
|
|
-class Test(threading.Thread):
|
|
- def __init__(self, url, target_file, progress):
|
|
- threading.Thread.__init__(self)
|
|
- self.target_file = target_file
|
|
- self.progress = progress
|
|
- self.curl = pycurl.Curl()
|
|
- self.curl.setopt(pycurl.URL, url)
|
|
- self.curl.setopt(pycurl.WRITEDATA, self.target_file)
|
|
- self.curl.setopt(pycurl.FOLLOWLOCATION, 1)
|
|
- self.curl.setopt(pycurl.NOPROGRESS, 0)
|
|
- self.curl.setopt(pycurl.PROGRESSFUNCTION, self.progress)
|
|
- self.curl.setopt(pycurl.MAXREDIRS, 5)
|
|
- self.curl.setopt(pycurl.NOSIGNAL, 1)
|
|
-
|
|
- def run(self):
|
|
- self.curl.perform()
|
|
- self.curl.close()
|
|
- self.target_file.close()
|
|
- self.progress(1.0, 1.0, 0, 0)
|
|
-
|
|
-
|
|
-# Check command line args
|
|
-if len(sys.argv) < 3:
|
|
- print "Usage: %s <URL> <filename>" % sys.argv[0]
|
|
- raise SystemExit
|
|
-
|
|
-# Make a progress bar window
|
|
-p = ProgressBar(sys.argv[1])
|
|
-# Start thread for fetching url
|
|
-Test(sys.argv[1], open(sys.argv[2], 'wb'), p.progress).start()
|
|
-# Enter the GTK mainloop
|
|
-gtk.threads_init()
|
|
-try:
|
|
- p.mainloop()
|
|
-except KeyboardInterrupt:
|
|
- pass
|
|
diff --git a/tests/test_xmlrpc.py b/tests/test_xmlrpc.py
|
|
deleted file mode 100644
|
|
index bc5953e..0000000
|
|
--- a/tests/test_xmlrpc.py
|
|
+++ /dev/null
|
|
@@ -1,29 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-## XML-RPC lib included in python2.2
|
|
-import xmlrpclib
|
|
-import pycurl
|
|
-
|
|
-# Header fields passed in request
|
|
-xmlrpc_header = [
|
|
- "User-Agent: PycURL XML-RPC Test", "Content-Type: text/xml"
|
|
- ]
|
|
-
|
|
-# XML-RPC request template
|
|
-xmlrpc_template = """
|
|
-<?xml version='1.0'?><methodCall><methodName>%s</methodName>%s</methodCall>
|
|
-"""
|
|
-
|
|
-# Engage
|
|
-c = pycurl.Curl()
|
|
-c.setopt(c.URL, 'http://betty.userland.com/RPC2')
|
|
-c.setopt(c.POST, 1)
|
|
-c.setopt(c.HTTPHEADER, xmlrpc_header)
|
|
-c.setopt(c.POSTFIELDS, xmlrpc_template % ("examples.getStateName", xmlrpclib.dumps((5,))))
|
|
-
|
|
-print 'Response from http://betty.userland.com/'
|
|
-c.perform()
|
|
-c.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 8519dd18dd06138ed48eebfef966e3740e7737ef Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 00:37:41 -0500
|
|
Subject: [PATCH 062/112] Delete old tests
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/test.py | 74 -----------
|
|
tests/test_cb.py | 28 ----
|
|
tests/test_debug.py | 16 ---
|
|
tests/test_ftp.py | 13 --
|
|
tests/test_getinfo.py | 49 -------
|
|
tests/test_internals.py | 258 ------------------------------------
|
|
tests/test_memleak.py | 53 --------
|
|
tests/test_multi.py | 33 -----
|
|
tests/test_multi2.py | 72 ----------
|
|
tests/test_multi3.py | 87 ------------
|
|
tests/test_multi4.py | 57 --------
|
|
tests/test_multi5.py | 60 ---------
|
|
tests/test_multi6.py | 62 ---------
|
|
tests/test_multi_socket.py | 82 ------------
|
|
tests/test_multi_socket_select.py | 105 ---------------
|
|
tests/test_multi_timer.py | 76 -----------
|
|
tests/test_multi_vs_thread.py | 262 -------------------------------------
|
|
tests/test_post.py | 24 ----
|
|
tests/test_post2.py | 18 ---
|
|
tests/test_post3.py | 32 -----
|
|
tests/test_reset.py | 75 -----------
|
|
tests/test_share.py | 34 -----
|
|
tests/test_socketopen.py | 17 ---
|
|
tests/test_stringio.py | 25 ----
|
|
24 files changed, 0 insertions(+), 1612 deletions(-)
|
|
delete mode 100644 tests/test.py
|
|
delete mode 100644 tests/test_cb.py
|
|
delete mode 100644 tests/test_debug.py
|
|
delete mode 100644 tests/test_ftp.py
|
|
delete mode 100644 tests/test_getinfo.py
|
|
delete mode 100644 tests/test_internals.py
|
|
delete mode 100644 tests/test_memleak.py
|
|
delete mode 100644 tests/test_multi.py
|
|
delete mode 100644 tests/test_multi2.py
|
|
delete mode 100644 tests/test_multi3.py
|
|
delete mode 100644 tests/test_multi4.py
|
|
delete mode 100644 tests/test_multi5.py
|
|
delete mode 100644 tests/test_multi6.py
|
|
delete mode 100644 tests/test_multi_socket.py
|
|
delete mode 100644 tests/test_multi_socket_select.py
|
|
delete mode 100644 tests/test_multi_timer.py
|
|
delete mode 100644 tests/test_multi_vs_thread.py
|
|
delete mode 100644 tests/test_post.py
|
|
delete mode 100644 tests/test_post2.py
|
|
delete mode 100644 tests/test_post3.py
|
|
delete mode 100644 tests/test_reset.py
|
|
delete mode 100644 tests/test_share.py
|
|
delete mode 100644 tests/test_socketopen.py
|
|
delete mode 100644 tests/test_stringio.py
|
|
|
|
diff --git a/tests/test.py b/tests/test.py
|
|
deleted file mode 100644
|
|
index 5cd9740..0000000
|
|
--- a/tests/test.py
|
|
+++ /dev/null
|
|
@@ -1,74 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys, threading, time
|
|
-import pycurl
|
|
-
|
|
-# We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
|
|
-# the libcurl tutorial for more info.
|
|
-try:
|
|
- import signal
|
|
- from signal import SIGPIPE, SIG_IGN
|
|
- signal.signal(signal.SIGPIPE, signal.SIG_IGN)
|
|
-except ImportError:
|
|
- pass
|
|
-
|
|
-
|
|
-class Test(threading.Thread):
|
|
- def __init__(self, url, ofile):
|
|
- threading.Thread.__init__(self)
|
|
- self.curl = pycurl.Curl()
|
|
- self.curl.setopt(pycurl.URL, url)
|
|
- self.curl.setopt(pycurl.WRITEDATA, ofile)
|
|
- self.curl.setopt(pycurl.FOLLOWLOCATION, 1)
|
|
- self.curl.setopt(pycurl.MAXREDIRS, 5)
|
|
- self.curl.setopt(pycurl.NOSIGNAL, 1)
|
|
-
|
|
- def run(self):
|
|
- self.curl.perform()
|
|
- self.curl.close()
|
|
- sys.stdout.write(".")
|
|
- sys.stdout.flush()
|
|
-
|
|
-
|
|
-# Read list of URIs from file specified on commandline
|
|
-try:
|
|
- urls = open(sys.argv[1]).readlines()
|
|
-except IndexError:
|
|
- # No file was specified, show usage string
|
|
- print "Usage: %s <file with uris to fetch>" % sys.argv[0]
|
|
- raise SystemExit
|
|
-
|
|
-# Initialize thread array and the file number
|
|
-threads = []
|
|
-fileno = 0
|
|
-
|
|
-# Start one thread per URI in parallel
|
|
-t1 = time.time()
|
|
-for url in urls:
|
|
- f = open(str(fileno), "wb")
|
|
- t = Test(url.rstrip(), f)
|
|
- t.start()
|
|
- threads.append((t, f))
|
|
- fileno = fileno + 1
|
|
-# Wait for all threads to finish
|
|
-for thread, file in threads:
|
|
- thread.join()
|
|
- file.close()
|
|
-t2 = time.time()
|
|
-print "\n** Multithreading, %d seconds elapsed for %d uris" % (int(t2-t1), len(urls))
|
|
-
|
|
-# Start one thread per URI in sequence
|
|
-fileno = 0
|
|
-t1 = time.time()
|
|
-for url in urls:
|
|
- f = open(str(fileno), "wb")
|
|
- t = Test(url.rstrip(), f)
|
|
- t.start()
|
|
- fileno = fileno + 1
|
|
- t.join()
|
|
- f.close()
|
|
-t2 = time.time()
|
|
-print "\n** Singlethreading, %d seconds elapsed for %d uris" % (int(t2-t1), len(urls))
|
|
diff --git a/tests/test_cb.py b/tests/test_cb.py
|
|
deleted file mode 100644
|
|
index 1be305c..0000000
|
|
--- a/tests/test_cb.py
|
|
+++ /dev/null
|
|
@@ -1,28 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys
|
|
-import pycurl
|
|
-
|
|
-## Callback function invoked when body data is ready
|
|
-def body(buf):
|
|
- # Print body data to stdout
|
|
- sys.stdout.write(buf)
|
|
-
|
|
-## Callback function invoked when header data is ready
|
|
-def header(buf):
|
|
- # Print header data to stderr
|
|
- sys.stderr.write(buf)
|
|
-
|
|
-c = pycurl.Curl()
|
|
-c.setopt(pycurl.URL, 'http://www.python.org/')
|
|
-c.setopt(pycurl.WRITEFUNCTION, body)
|
|
-c.setopt(pycurl.HEADERFUNCTION, header)
|
|
-c.setopt(pycurl.FOLLOWLOCATION, 1)
|
|
-c.setopt(pycurl.MAXREDIRS, 5)
|
|
-c.perform()
|
|
-c.setopt(pycurl.URL, 'http://curl.haxx.se/')
|
|
-c.perform()
|
|
-c.close()
|
|
diff --git a/tests/test_debug.py b/tests/test_debug.py
|
|
deleted file mode 100644
|
|
index d439b16..0000000
|
|
--- a/tests/test_debug.py
|
|
+++ /dev/null
|
|
@@ -1,16 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import pycurl
|
|
-
|
|
-def test(t, b):
|
|
- print "debug(%d): %s" % (t, b)
|
|
-
|
|
-c = pycurl.Curl()
|
|
-c.setopt(pycurl.URL, 'http://curl.haxx.se/')
|
|
-c.setopt(pycurl.VERBOSE, 1)
|
|
-c.setopt(pycurl.DEBUGFUNCTION, test)
|
|
-c.perform()
|
|
-c.close()
|
|
diff --git a/tests/test_ftp.py b/tests/test_ftp.py
|
|
deleted file mode 100644
|
|
index 2d4d358..0000000
|
|
--- a/tests/test_ftp.py
|
|
+++ /dev/null
|
|
@@ -1,13 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import pycurl
|
|
-
|
|
-c = pycurl.Curl()
|
|
-c.setopt(c.URL, 'ftp://ftp.sunet.se/')
|
|
-c.setopt(c.FTP_USE_EPSV, 1)
|
|
-c.setopt(c.QUOTE, ['cwd pub', 'type i'])
|
|
-c.perform()
|
|
-c.close()
|
|
diff --git a/tests/test_getinfo.py b/tests/test_getinfo.py
|
|
deleted file mode 100644
|
|
index ed64594..0000000
|
|
--- a/tests/test_getinfo.py
|
|
+++ /dev/null
|
|
@@ -1,49 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import time
|
|
-import pycurl
|
|
-
|
|
-
|
|
-## Callback function invoked when progress information is updated
|
|
-def progress(download_t, download_d, upload_t, upload_d):
|
|
- print "Total to download %d bytes, have %d bytes so far" % \
|
|
- (download_t, download_d)
|
|
-
|
|
-url = "http://www.cnn.com"
|
|
-
|
|
-print "Starting downloading", url
|
|
-print
|
|
-f = open("body", "wb")
|
|
-h = open("header", "wb")
|
|
-c = pycurl.Curl()
|
|
-c.setopt(c.URL, url)
|
|
-c.setopt(c.WRITEDATA, f)
|
|
-c.setopt(c.NOPROGRESS, 0)
|
|
-c.setopt(c.PROGRESSFUNCTION, progress)
|
|
-c.setopt(c.FOLLOWLOCATION, 1)
|
|
-c.setopt(c.MAXREDIRS, 5)
|
|
-c.setopt(c.WRITEHEADER, h)
|
|
-c.setopt(c.OPT_FILETIME, 1)
|
|
-c.perform()
|
|
-
|
|
-print
|
|
-print "HTTP-code:", c.getinfo(c.HTTP_CODE)
|
|
-print "Total-time:", c.getinfo(c.TOTAL_TIME)
|
|
-print "Download speed: %.2f bytes/second" % c.getinfo(c.SPEED_DOWNLOAD)
|
|
-print "Document size: %d bytes" % c.getinfo(c.SIZE_DOWNLOAD)
|
|
-print "Effective URL:", c.getinfo(c.EFFECTIVE_URL)
|
|
-print "Content-type:", c.getinfo(c.CONTENT_TYPE)
|
|
-print "Namelookup-time:", c.getinfo(c.NAMELOOKUP_TIME)
|
|
-print "Redirect-time:", c.getinfo(c.REDIRECT_TIME)
|
|
-print "Redirect-count:", c.getinfo(c.REDIRECT_COUNT)
|
|
-epoch = c.getinfo(c.INFO_FILETIME)
|
|
-print "Filetime: %d (%s)" % (epoch, time.ctime(epoch))
|
|
-print
|
|
-print "Header is in file 'header', body is in file 'body'"
|
|
-
|
|
-c.close()
|
|
-f.close()
|
|
-h.close()
|
|
diff --git a/tests/test_internals.py b/tests/test_internals.py
|
|
deleted file mode 100644
|
|
index 3f5eefd..0000000
|
|
--- a/tests/test_internals.py
|
|
+++ /dev/null
|
|
@@ -1,258 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-#
|
|
-# a simple self-test
|
|
-#
|
|
-
|
|
-try:
|
|
- # need Python 2.2 or better for garbage collection
|
|
- from gc import get_objects
|
|
- import gc
|
|
- del get_objects
|
|
- gc.enable()
|
|
-except ImportError:
|
|
- gc = None
|
|
-import copy, os, sys
|
|
-from StringIO import StringIO
|
|
-try:
|
|
- import cPickle
|
|
-except ImportError:
|
|
- cPickle = None
|
|
-try:
|
|
- import pickle
|
|
-except ImportError:
|
|
- pickle = None
|
|
-
|
|
-# update sys.path when running in the build directory
|
|
-from util import get_sys_path
|
|
-sys.path = get_sys_path()
|
|
-
|
|
-import pycurl
|
|
-from pycurl import Curl, CurlMulti
|
|
-
|
|
-
|
|
-class opts:
|
|
- verbose = 1
|
|
-
|
|
-if "-q" in sys.argv:
|
|
- opts.verbose = opts.verbose - 1
|
|
-
|
|
-
|
|
-print "Python", sys.version
|
|
-print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
|
|
-print "PycURL version info", pycurl.version_info()
|
|
-print " %s, compiled %s" % (pycurl.__file__, pycurl.COMPILE_DATE)
|
|
-
|
|
-
|
|
-# /***********************************************************************
|
|
-# // test misc
|
|
-# ************************************************************************/
|
|
-
|
|
-if 1:
|
|
- c = Curl()
|
|
- assert c.URL is pycurl.URL
|
|
- del c
|
|
-
|
|
-
|
|
-# /***********************************************************************
|
|
-# // test handles
|
|
-# ************************************************************************/
|
|
-
|
|
-# remove an invalid handle: this should fail
|
|
-if 1:
|
|
- m = CurlMulti()
|
|
- c = Curl()
|
|
- try:
|
|
- m.remove_handle(c)
|
|
- except pycurl.error:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error"
|
|
- del m, c
|
|
-
|
|
-
|
|
-# remove an invalid but closed handle
|
|
-if 1:
|
|
- m = CurlMulti()
|
|
- c = Curl()
|
|
- c.close()
|
|
- m.remove_handle(c)
|
|
- del m, c
|
|
-
|
|
-
|
|
-# add a closed handle: this should fail
|
|
-if 1:
|
|
- m = CurlMulti()
|
|
- c = Curl()
|
|
- c.close()
|
|
- try:
|
|
- m.add_handle(c)
|
|
- except pycurl.error:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error"
|
|
- m.close()
|
|
- del m, c
|
|
-
|
|
-
|
|
-# add a handle twice: this should fail
|
|
-if 1:
|
|
- m = CurlMulti()
|
|
- c = Curl()
|
|
- m.add_handle(c)
|
|
- try:
|
|
- m.add_handle(c)
|
|
- except pycurl.error:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error"
|
|
- del m, c
|
|
-
|
|
-
|
|
-# add a handle on multiple stacks: this should fail
|
|
-if 1:
|
|
- m1 = CurlMulti()
|
|
- m2 = CurlMulti()
|
|
- c = Curl()
|
|
- m1.add_handle(c)
|
|
- try:
|
|
- m2.add_handle(c)
|
|
- except pycurl.error:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error"
|
|
- del m1, m2, c
|
|
-
|
|
-
|
|
-# move a handle
|
|
-if 1:
|
|
- m1 = CurlMulti()
|
|
- m2 = CurlMulti()
|
|
- c = Curl()
|
|
- m1.add_handle(c)
|
|
- m1.remove_handle(c)
|
|
- m2.add_handle(c)
|
|
- del m1, m2, c
|
|
-
|
|
-
|
|
-# /***********************************************************************
|
|
-# // test copying and pickling - copying and pickling of
|
|
-# // instances of Curl and CurlMulti is not allowed
|
|
-# ************************************************************************/
|
|
-
|
|
-if 1 and copy:
|
|
- c = Curl()
|
|
- m = CurlMulti()
|
|
- try:
|
|
- copy.copy(c)
|
|
- except copy.Error:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error - copying should fail"
|
|
- try:
|
|
- copy.copy(m)
|
|
- except copy.Error:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error - copying should fail"
|
|
-
|
|
-if 1 and pickle:
|
|
- c = Curl()
|
|
- m = CurlMulti()
|
|
- fp = StringIO()
|
|
- p = pickle.Pickler(fp, 1)
|
|
- try:
|
|
- p.dump(c)
|
|
- except pickle.PicklingError:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error - pickling should fail"
|
|
- try:
|
|
- p.dump(m)
|
|
- except pickle.PicklingError:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error - pickling should fail"
|
|
- del c, m, fp, p
|
|
-
|
|
-if 1 and cPickle:
|
|
- c = Curl()
|
|
- m = CurlMulti()
|
|
- fp = StringIO()
|
|
- p = cPickle.Pickler(fp, 1)
|
|
- try:
|
|
- p.dump(c)
|
|
- except cPickle.PicklingError:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error - pickling should fail"
|
|
- try:
|
|
- p.dump(m)
|
|
- except cPickle.PicklingError:
|
|
- pass
|
|
- else:
|
|
- assert 0, "internal error - pickling should fail"
|
|
- del c, m, fp, p
|
|
-
|
|
-
|
|
-# /***********************************************************************
|
|
-# // test refcounts
|
|
-# ************************************************************************/
|
|
-
|
|
-# basic check of reference counting (use a memory checker like valgrind)
|
|
-if 1:
|
|
- c = Curl()
|
|
- m = CurlMulti()
|
|
- m.add_handle(c)
|
|
- del m
|
|
- m = CurlMulti()
|
|
- c.close()
|
|
- del m, c
|
|
-
|
|
-# basic check of cyclic garbage collection
|
|
-if 1 and gc:
|
|
- gc.collect()
|
|
- c = Curl()
|
|
- c.m = CurlMulti()
|
|
- c.m.add_handle(c)
|
|
- # create some nasty cyclic references
|
|
- c.c = c
|
|
- c.c.c1 = c
|
|
- c.c.c2 = c
|
|
- c.c.c3 = c.c
|
|
- c.c.c4 = c.m
|
|
- c.m.c = c
|
|
- c.m.m = c.m
|
|
- c.m.c = c
|
|
- # delete
|
|
- gc.collect()
|
|
- flags = gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_OBJECTS
|
|
- if opts.verbose >= 1:
|
|
- flags = flags | gc.DEBUG_STATS
|
|
- gc.set_debug(flags)
|
|
- gc.collect()
|
|
- ##print gc.get_referrers(c)
|
|
- ##print gc.get_objects()
|
|
- if opts.verbose >= 1:
|
|
- print "Tracked objects:", len(gc.get_objects())
|
|
- # The `del' below should delete these 4 objects:
|
|
- # Curl + internal dict, CurlMulti + internal dict
|
|
- del c
|
|
- gc.collect()
|
|
- if opts.verbose >= 1:
|
|
- print "Tracked objects:", len(gc.get_objects())
|
|
-
|
|
-if 1:
|
|
- # Ensure that the refcounting error in "reset" is fixed:
|
|
- for i in xrange(100000):
|
|
- c = Curl()
|
|
- c.reset()
|
|
-
|
|
-# /***********************************************************************
|
|
-# // done
|
|
-# ************************************************************************/
|
|
-
|
|
-print "All tests passed."
|
|
diff --git a/tests/test_memleak.py b/tests/test_memleak.py
|
|
deleted file mode 100644
|
|
index 8577b97..0000000
|
|
--- a/tests/test_memleak.py
|
|
+++ /dev/null
|
|
@@ -1,53 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-#
|
|
-# just a simple self-test
|
|
-# need Python 2.2 or better for garbage collection
|
|
-#
|
|
-
|
|
-import gc, pycurl, sys
|
|
-gc.enable()
|
|
-
|
|
-
|
|
-print "Python", sys.version
|
|
-print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
|
|
-##print "PycURL version info", pycurl.version_info()
|
|
-print " %s, compiled %s" % (pycurl.__file__, pycurl.COMPILE_DATE)
|
|
-
|
|
-
|
|
-gc.collect()
|
|
-flags = gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_OBJECTS
|
|
-if 1:
|
|
- flags = flags | gc.DEBUG_STATS
|
|
-gc.set_debug(flags)
|
|
-gc.collect()
|
|
-
|
|
-print "Tracked objects:", len(gc.get_objects())
|
|
-
|
|
-multi = pycurl.CurlMulti()
|
|
-t = []
|
|
-for a in range(100):
|
|
- curl = pycurl.Curl()
|
|
- multi.add_handle(curl)
|
|
- t.append(curl)
|
|
-
|
|
-print "Tracked objects:", len(gc.get_objects())
|
|
-
|
|
-for curl in t:
|
|
- curl.close()
|
|
- multi.remove_handle(curl)
|
|
-
|
|
-print "Tracked objects:", len(gc.get_objects())
|
|
-
|
|
-del curl
|
|
-del t
|
|
-del multi
|
|
-
|
|
-print "Tracked objects:", len(gc.get_objects())
|
|
-gc.collect()
|
|
-print "Tracked objects:", len(gc.get_objects())
|
|
-
|
|
-
|
|
diff --git a/tests/test_multi.py b/tests/test_multi.py
|
|
deleted file mode 100644
|
|
index 9193986..0000000
|
|
--- a/tests/test_multi.py
|
|
+++ /dev/null
|
|
@@ -1,33 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import pycurl
|
|
-
|
|
-m = pycurl.CurlMulti()
|
|
-m.handles = []
|
|
-c1 = pycurl.Curl()
|
|
-c2 = pycurl.Curl()
|
|
-c1.setopt(c1.URL, 'http://curl.haxx.se')
|
|
-c2.setopt(c2.URL, 'http://cnn.com')
|
|
-c2.setopt(c2.FOLLOWLOCATION, 1)
|
|
-m.add_handle(c1)
|
|
-m.add_handle(c2)
|
|
-m.handles.append(c1)
|
|
-m.handles.append(c2)
|
|
-
|
|
-num_handles = len(m.handles)
|
|
-while num_handles:
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
- m.select(1.0)
|
|
-
|
|
-m.remove_handle(c2)
|
|
-m.remove_handle(c1)
|
|
-del m.handles
|
|
-m.close()
|
|
-c1.close()
|
|
-c2.close()
|
|
diff --git a/tests/test_multi2.py b/tests/test_multi2.py
|
|
deleted file mode 100644
|
|
index 4b96789..0000000
|
|
--- a/tests/test_multi2.py
|
|
+++ /dev/null
|
|
@@ -1,72 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import os, sys
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-
|
|
-
|
|
-urls = (
|
|
- "http://curl.haxx.se",
|
|
- "http://www.python.org",
|
|
- "http://pycurl.sourceforge.net",
|
|
- "http://pycurl.sourceforge.net/tests/403_FORBIDDEN", # that actually exists ;-)
|
|
- "http://pycurl.sourceforge.net/tests/404_NOT_FOUND",
|
|
-)
|
|
-
|
|
-# Read list of URIs from file specified on commandline
|
|
-try:
|
|
- urls = open(sys.argv[1], "rb").readlines()
|
|
-except IndexError:
|
|
- # No file was specified
|
|
- pass
|
|
-
|
|
-# init
|
|
-m = pycurl.CurlMulti()
|
|
-m.handles = []
|
|
-for url in urls:
|
|
- c = pycurl.Curl()
|
|
- # save info in standard Python attributes
|
|
- c.url = url.rstrip()
|
|
- c.body = StringIO()
|
|
- c.http_code = -1
|
|
- m.handles.append(c)
|
|
- # pycurl API calls
|
|
- c.setopt(c.URL, c.url)
|
|
- c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
- m.add_handle(c)
|
|
-
|
|
-# get data
|
|
-num_handles = len(m.handles)
|
|
-while num_handles:
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
- # currently no more I/O is pending, could do something in the meantime
|
|
- # (display a progress bar, etc.)
|
|
- m.select(1.0)
|
|
-
|
|
-# close handles
|
|
-for c in m.handles:
|
|
- # save info in standard Python attributes
|
|
- c.http_code = c.getinfo(c.HTTP_CODE)
|
|
- # pycurl API calls
|
|
- m.remove_handle(c)
|
|
- c.close()
|
|
-m.close()
|
|
-
|
|
-# print result
|
|
-for c in m.handles:
|
|
- data = c.body.getvalue()
|
|
- if 0:
|
|
- print "**********", c.url, "**********"
|
|
- print data
|
|
- else:
|
|
- print "%-53s http_code %3d, %6d bytes" % (c.url, c.http_code, len(data))
|
|
-
|
|
diff --git a/tests/test_multi3.py b/tests/test_multi3.py
|
|
deleted file mode 100644
|
|
index 5b7ea6e..0000000
|
|
--- a/tests/test_multi3.py
|
|
+++ /dev/null
|
|
@@ -1,87 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-# same as test_multi2.py, but enforce some debugging and strange API-calls
|
|
-
|
|
-import os, sys
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-
|
|
-
|
|
-urls = (
|
|
- "http://curl.haxx.se",
|
|
- "http://www.python.org",
|
|
- "http://pycurl.sourceforge.net",
|
|
- "http://pycurl.sourceforge.net/THIS_HANDLE_IS_CLOSED",
|
|
-)
|
|
-
|
|
-# init
|
|
-m = pycurl.CurlMulti()
|
|
-m.handles = []
|
|
-for url in urls:
|
|
- c = pycurl.Curl()
|
|
- # save info in standard Python attributes
|
|
- c.url = url
|
|
- c.body = StringIO()
|
|
- c.http_code = -1
|
|
- c.debug = 0
|
|
- m.handles.append(c)
|
|
- # pycurl API calls
|
|
- c.setopt(c.URL, c.url)
|
|
- c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
- m.add_handle(c)
|
|
-
|
|
-# debug - close a handle
|
|
-if 1:
|
|
- c = m.handles[3]
|
|
- c.debug = 1
|
|
- c.close()
|
|
-
|
|
-# get data
|
|
-num_handles = len(m.handles)
|
|
-while num_handles:
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
- # currently no more I/O is pending, could do something in the meantime
|
|
- # (display a progress bar, etc.)
|
|
- m.select(1.0)
|
|
-
|
|
-# close handles
|
|
-for c in m.handles:
|
|
- # save info in standard Python attributes
|
|
- try:
|
|
- c.http_code = c.getinfo(c.HTTP_CODE)
|
|
- except pycurl.error:
|
|
- # handle already closed - see debug above
|
|
- assert c.debug
|
|
- c.http_code = -1
|
|
- # pycurl API calls
|
|
- if 0:
|
|
- m.remove_handle(c)
|
|
- c.close()
|
|
- elif 0:
|
|
- # in the C API this is the wrong calling order, but pycurl
|
|
- # handles this automatically
|
|
- c.close()
|
|
- m.remove_handle(c)
|
|
- else:
|
|
- # actually, remove_handle is called automatically on close
|
|
- c.close()
|
|
-m.close()
|
|
-
|
|
-# print result
|
|
-for c in m.handles:
|
|
- data = c.body.getvalue()
|
|
- if 0:
|
|
- print "**********", c.url, "**********"
|
|
- print data
|
|
- else:
|
|
- print "%-53s http_code %3d, %6d bytes" % (c.url, c.http_code, len(data))
|
|
-
|
|
diff --git a/tests/test_multi4.py b/tests/test_multi4.py
|
|
deleted file mode 100644
|
|
index f37ea26..0000000
|
|
--- a/tests/test_multi4.py
|
|
+++ /dev/null
|
|
@@ -1,57 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys, select, time
|
|
-import pycurl
|
|
-
|
|
-c1 = pycurl.Curl()
|
|
-c2 = pycurl.Curl()
|
|
-c3 = pycurl.Curl()
|
|
-c1.setopt(c1.URL, "http://www.python.org")
|
|
-c2.setopt(c2.URL, "http://curl.haxx.se")
|
|
-c3.setopt(c3.URL, "http://slashdot.org")
|
|
-c1.body = open("doc1", "wb")
|
|
-c2.body = open("doc2", "wb")
|
|
-c3.body = open("doc3", "wb")
|
|
-c1.setopt(c1.WRITEFUNCTION, c1.body.write)
|
|
-c2.setopt(c2.WRITEFUNCTION, c2.body.write)
|
|
-c3.setopt(c3.WRITEFUNCTION, c3.body.write)
|
|
-
|
|
-m = pycurl.CurlMulti()
|
|
-m.add_handle(c1)
|
|
-m.add_handle(c2)
|
|
-m.add_handle(c3)
|
|
-
|
|
-# Number of seconds to wait for a timeout to happen
|
|
-SELECT_TIMEOUT = 1.0
|
|
-
|
|
-# Stir the state machine into action
|
|
-while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
-# Keep going until all the connections have terminated
|
|
-while num_handles:
|
|
- apply(select.select, m.fdset() + (SELECT_TIMEOUT,))
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
-# Cleanup
|
|
-m.remove_handle(c3)
|
|
-m.remove_handle(c2)
|
|
-m.remove_handle(c1)
|
|
-m.close()
|
|
-c1.body.close()
|
|
-c2.body.close()
|
|
-c3.body.close()
|
|
-c1.close()
|
|
-c2.close()
|
|
-c3.close()
|
|
-print "http://www.python.org is in file doc1"
|
|
-print "http://curl.haxx.se is in file doc2"
|
|
-print "http://slashdot.org is in file doc3"
|
|
diff --git a/tests/test_multi5.py b/tests/test_multi5.py
|
|
deleted file mode 100644
|
|
index 3f0c8df..0000000
|
|
--- a/tests/test_multi5.py
|
|
+++ /dev/null
|
|
@@ -1,60 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys, select, time
|
|
-import pycurl
|
|
-
|
|
-c1 = pycurl.Curl()
|
|
-c2 = pycurl.Curl()
|
|
-c3 = pycurl.Curl()
|
|
-c1.setopt(c1.URL, "http://www.python.org")
|
|
-c2.setopt(c2.URL, "http://curl.haxx.se")
|
|
-c3.setopt(c3.URL, "http://slashdot.org")
|
|
-c1.body = open("doc1", "wb")
|
|
-c2.body = open("doc2", "wb")
|
|
-c3.body = open("doc3", "wb")
|
|
-c1.setopt(c1.WRITEFUNCTION, c1.body.write)
|
|
-c2.setopt(c2.WRITEFUNCTION, c2.body.write)
|
|
-c3.setopt(c3.WRITEFUNCTION, c3.body.write)
|
|
-
|
|
-m = pycurl.CurlMulti()
|
|
-m.add_handle(c1)
|
|
-m.add_handle(c2)
|
|
-m.add_handle(c3)
|
|
-
|
|
-# Number of seconds to wait for a timeout to happen
|
|
-SELECT_TIMEOUT = 1.0
|
|
-
|
|
-# Stir the state machine into action
|
|
-while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
-# Keep going until all the connections have terminated
|
|
-while num_handles:
|
|
- # The select method uses fdset internally to determine which file descriptors
|
|
- # to check.
|
|
- m.select(SELECT_TIMEOUT)
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
-# Cleanup
|
|
-m.remove_handle(c3)
|
|
-m.remove_handle(c2)
|
|
-m.remove_handle(c1)
|
|
-m.close()
|
|
-c1.body.close()
|
|
-c2.body.close()
|
|
-c3.body.close()
|
|
-c1.close()
|
|
-c2.close()
|
|
-c3.close()
|
|
-print "http://www.python.org is in file doc1"
|
|
-print "http://curl.haxx.se is in file doc2"
|
|
-print "http://slashdot.org is in file doc3"
|
|
-
|
|
diff --git a/tests/test_multi6.py b/tests/test_multi6.py
|
|
deleted file mode 100644
|
|
index 35a284f..0000000
|
|
--- a/tests/test_multi6.py
|
|
+++ /dev/null
|
|
@@ -1,62 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys, select, time
|
|
-import pycurl
|
|
-
|
|
-c1 = pycurl.Curl()
|
|
-c2 = pycurl.Curl()
|
|
-c3 = pycurl.Curl()
|
|
-c1.setopt(c1.URL, "http://www.python.org")
|
|
-c2.setopt(c2.URL, "http://curl.haxx.se")
|
|
-c3.setopt(c3.URL, "http://slashdot.org")
|
|
-c1.body = open("doc1", "wb")
|
|
-c2.body = open("doc2", "wb")
|
|
-c3.body = open("doc3", "wb")
|
|
-c1.setopt(c1.WRITEFUNCTION, c1.body.write)
|
|
-c2.setopt(c2.WRITEFUNCTION, c2.body.write)
|
|
-c3.setopt(c3.WRITEFUNCTION, c3.body.write)
|
|
-
|
|
-m = pycurl.CurlMulti()
|
|
-m.add_handle(c1)
|
|
-m.add_handle(c2)
|
|
-m.add_handle(c3)
|
|
-
|
|
-# Number of seconds to wait for a timeout to happen
|
|
-SELECT_TIMEOUT = 1.0
|
|
-
|
|
-# Stir the state machine into action
|
|
-while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
-# Keep going until all the connections have terminated
|
|
-while num_handles:
|
|
- # The select method uses fdset internally to determine which file descriptors
|
|
- # to check.
|
|
- m.select(SELECT_TIMEOUT)
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- # Print the message, if any
|
|
- print m.info_read(1)
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
-# Cleanup
|
|
-m.remove_handle(c3)
|
|
-m.remove_handle(c2)
|
|
-m.remove_handle(c1)
|
|
-m.close()
|
|
-c1.body.close()
|
|
-c2.body.close()
|
|
-c3.body.close()
|
|
-c1.close()
|
|
-c2.close()
|
|
-c3.close()
|
|
-print "http://www.python.org is in file doc1"
|
|
-print "http://curl.haxx.se is in file doc2"
|
|
-print "http://slashdot.org is in file doc3"
|
|
-
|
|
diff --git a/tests/test_multi_socket.py b/tests/test_multi_socket.py
|
|
deleted file mode 100644
|
|
index 6768061..0000000
|
|
--- a/tests/test_multi_socket.py
|
|
+++ /dev/null
|
|
@@ -1,82 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import os, sys
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-
|
|
-
|
|
-urls = (
|
|
- "http://curl.haxx.se",
|
|
- "http://www.python.org",
|
|
- "http://pycurl.sourceforge.net",
|
|
-)
|
|
-
|
|
-# Read list of URIs from file specified on commandline
|
|
-try:
|
|
- urls = open(sys.argv[1], "rb").readlines()
|
|
-except IndexError:
|
|
- # No file was specified
|
|
- pass
|
|
-
|
|
-# timer callback
|
|
-def timer(msecs):
|
|
- print 'Timer callback msecs:', msecs
|
|
-
|
|
-# socket callback
|
|
-def socket(event, socket, multi, data):
|
|
- print event, socket, multi, data
|
|
-# multi.assign(socket, timer)
|
|
-
|
|
-# init
|
|
-m = pycurl.CurlMulti()
|
|
-m.setopt(pycurl.M_PIPELINING, 1)
|
|
-m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
-m.setopt(pycurl.M_SOCKETFUNCTION, socket)
|
|
-m.handles = []
|
|
-for url in urls:
|
|
- c = pycurl.Curl()
|
|
- # save info in standard Python attributes
|
|
- c.url = url
|
|
- c.body = StringIO()
|
|
- c.http_code = -1
|
|
- m.handles.append(c)
|
|
- # pycurl API calls
|
|
- c.setopt(c.URL, c.url)
|
|
- c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
- m.add_handle(c)
|
|
-
|
|
-# get data
|
|
-num_handles = len(m.handles)
|
|
-while num_handles:
|
|
- while 1:
|
|
- ret, num_handles = m.socket_all()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
- # currently no more I/O is pending, could do something in the meantime
|
|
- # (display a progress bar, etc.)
|
|
- m.select(1.0)
|
|
-
|
|
-# close handles
|
|
-for c in m.handles:
|
|
- # save info in standard Python attributes
|
|
- c.http_code = c.getinfo(c.HTTP_CODE)
|
|
- # pycurl API calls
|
|
- m.remove_handle(c)
|
|
- c.close()
|
|
-m.close()
|
|
-
|
|
-# print result
|
|
-for c in m.handles:
|
|
- data = c.body.getvalue()
|
|
- if 0:
|
|
- print "**********", c.url, "**********"
|
|
- print data
|
|
- else:
|
|
- print "%-53s http_code %3d, %6d bytes" % (c.url, c.http_code, len(data))
|
|
-
|
|
diff --git a/tests/test_multi_socket_select.py b/tests/test_multi_socket_select.py
|
|
deleted file mode 100644
|
|
index 1f56d1d..0000000
|
|
--- a/tests/test_multi_socket_select.py
|
|
+++ /dev/null
|
|
@@ -1,105 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import os, sys
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-import select
|
|
-
|
|
-sockets = set()
|
|
-timeout = 0
|
|
-
|
|
-urls = (
|
|
- "http://curl.haxx.se",
|
|
- "http://www.python.org",
|
|
- "http://pycurl.sourceforge.net",
|
|
-)
|
|
-
|
|
-# Read list of URIs from file specified on commandline
|
|
-try:
|
|
- urls = open(sys.argv[1], "rb").readlines()
|
|
-except IndexError:
|
|
- # No file was specified
|
|
- pass
|
|
-
|
|
-# timer callback
|
|
-def timer(msecs):
|
|
- global timeout
|
|
- timeout = msecs
|
|
- print 'Timer callback msecs:', msecs
|
|
-
|
|
-# socket callback
|
|
-def socket(event, socket, multi, data):
|
|
- if event == pycurl.POLL_REMOVE:
|
|
- print "Remove Socket %d"%socket
|
|
- sockets.remove(socket)
|
|
- else:
|
|
- if socket not in sockets:
|
|
- print "Add socket %d"%socket
|
|
- sockets.add(socket)
|
|
- print event, socket, multi, data
|
|
-
|
|
-# init
|
|
-m = pycurl.CurlMulti()
|
|
-m.setopt(pycurl.M_PIPELINING, 1)
|
|
-m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
-m.setopt(pycurl.M_SOCKETFUNCTION, socket)
|
|
-m.handles = []
|
|
-for url in urls:
|
|
- c = pycurl.Curl()
|
|
- # save info in standard Python attributes
|
|
- c.url = url
|
|
- c.body = StringIO()
|
|
- c.http_code = -1
|
|
- m.handles.append(c)
|
|
- # pycurl API calls
|
|
- c.setopt(c.URL, c.url)
|
|
- c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
- m.add_handle(c)
|
|
-
|
|
-# get data
|
|
-num_handles = len(m.handles)
|
|
-
|
|
-while (pycurl.E_CALL_MULTI_PERFORM==m.socket_all()[0]):
|
|
- pass
|
|
-
|
|
-timeout = m.timeout()
|
|
-
|
|
-
|
|
-while True:
|
|
- (rr, wr, er) = select.select(sockets,sockets,sockets,timeout/1000.0)
|
|
- socketSet = set(rr+wr+er)
|
|
- if socketSet:
|
|
- for s in socketSet:
|
|
- while True:
|
|
- (ret,running) = m.socket_action(s,0)
|
|
- if ret!=pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
- else:
|
|
- (ret,running) = m.socket_action(pycurl.SOCKET_TIMEOUT,0)
|
|
- if running==0:
|
|
- break
|
|
-
|
|
-# close handles
|
|
-for c in m.handles:
|
|
- # save info in standard Python attributes
|
|
- c.http_code = c.getinfo(c.HTTP_CODE)
|
|
- # pycurl API calls
|
|
- m.remove_handle(c)
|
|
- c.close()
|
|
-m.close()
|
|
-
|
|
-# print result
|
|
-for c in m.handles:
|
|
- data = c.body.getvalue()
|
|
- if 0:
|
|
- print "**********", c.url, "**********"
|
|
- print data
|
|
- else:
|
|
- print "%-53s http_code %3d, %6d bytes" % (c.url, c.http_code, len(data))
|
|
-
|
|
diff --git a/tests/test_multi_timer.py b/tests/test_multi_timer.py
|
|
deleted file mode 100644
|
|
index 17371d3..0000000
|
|
--- a/tests/test_multi_timer.py
|
|
+++ /dev/null
|
|
@@ -1,76 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import os, sys
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-
|
|
-
|
|
-urls = (
|
|
- "http://curl.haxx.se",
|
|
- "http://www.python.org",
|
|
- "http://pycurl.sourceforge.net",
|
|
-)
|
|
-
|
|
-# Read list of URIs from file specified on commandline
|
|
-try:
|
|
- urls = open(sys.argv[1], "rb").readlines()
|
|
-except IndexError:
|
|
- # No file was specified
|
|
- pass
|
|
-
|
|
-# timer callback
|
|
-def timer(msecs):
|
|
- print 'Timer callback msecs:', msecs
|
|
-
|
|
-# init
|
|
-m = pycurl.CurlMulti()
|
|
-m.setopt(pycurl.M_PIPELINING, 1)
|
|
-m.setopt(pycurl.M_TIMERFUNCTION, timer)
|
|
-m.handles = []
|
|
-for url in urls:
|
|
- c = pycurl.Curl()
|
|
- # save info in standard Python attributes
|
|
- c.url = url
|
|
- c.body = StringIO()
|
|
- c.http_code = -1
|
|
- m.handles.append(c)
|
|
- # pycurl API calls
|
|
- c.setopt(c.URL, c.url)
|
|
- c.setopt(c.WRITEFUNCTION, c.body.write)
|
|
- m.add_handle(c)
|
|
-
|
|
-# get data
|
|
-num_handles = len(m.handles)
|
|
-while num_handles:
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
- # currently no more I/O is pending, could do something in the meantime
|
|
- # (display a progress bar, etc.)
|
|
- m.select(1.0)
|
|
-
|
|
-# close handles
|
|
-for c in m.handles:
|
|
- # save info in standard Python attributes
|
|
- c.http_code = c.getinfo(c.HTTP_CODE)
|
|
- # pycurl API calls
|
|
- m.remove_handle(c)
|
|
- c.close()
|
|
-m.close()
|
|
-
|
|
-# print result
|
|
-for c in m.handles:
|
|
- data = c.body.getvalue()
|
|
- if 0:
|
|
- print "**********", c.url, "**********"
|
|
- print data
|
|
- else:
|
|
- print "%-53s http_code %3d, %6d bytes" % (c.url, c.http_code, len(data))
|
|
-
|
|
diff --git a/tests/test_multi_vs_thread.py b/tests/test_multi_vs_thread.py
|
|
deleted file mode 100644
|
|
index 0caed60..0000000
|
|
--- a/tests/test_multi_vs_thread.py
|
|
+++ /dev/null
|
|
@@ -1,262 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import os, sys, time
|
|
-from threading import Thread, RLock
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-
|
|
-# We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
|
|
-# the libcurl tutorial for more info.
|
|
-try:
|
|
- import signal
|
|
- from signal import SIGPIPE, SIG_IGN
|
|
- signal.signal(signal.SIGPIPE, signal.SIG_IGN)
|
|
-except ImportError:
|
|
- pass
|
|
-
|
|
-# The conclusion is: the multi interface is fastest!
|
|
-
|
|
-NUM_PAGES = 30
|
|
-NUM_THREADS = 10
|
|
-assert NUM_PAGES % NUM_THREADS == 0
|
|
-
|
|
-##URL = "http://pycurl.sourceforge.net/tests/testgetvars.php?%d"
|
|
-URL = "http://pycurl.sourceforge.net/tests/teststaticpage.html?%d"
|
|
-
|
|
-
|
|
-#
|
|
-# util
|
|
-#
|
|
-
|
|
-class Curl:
|
|
- def __init__(self, url):
|
|
- self.url = url
|
|
- self.body = StringIO()
|
|
- self.http_code = -1
|
|
- # pycurl API calls
|
|
- self._curl = pycurl.Curl()
|
|
- self._curl.setopt(pycurl.URL, self.url)
|
|
- self._curl.setopt(pycurl.WRITEFUNCTION, self.body.write)
|
|
- self._curl.setopt(pycurl.NOSIGNAL, 1)
|
|
-
|
|
- def perform(self):
|
|
- self._curl.perform()
|
|
-
|
|
- def close(self):
|
|
- self.http_code = self._curl.getinfo(pycurl.HTTP_CODE)
|
|
- self._curl.close()
|
|
-
|
|
-
|
|
-def print_result(items):
|
|
- return # DO NOTHING
|
|
- #
|
|
- for c in items:
|
|
- data = c.body.getvalue()
|
|
- if 0:
|
|
- print "**********", c.url, "**********"
|
|
- print data
|
|
- elif 1:
|
|
- print "%-60s %3d %6d" % (c.url, c.http_code, len(data))
|
|
-
|
|
-
|
|
-###
|
|
-### 1) multi
|
|
-###
|
|
-
|
|
-def test_multi():
|
|
- clock1 = time.time()
|
|
-
|
|
- # init
|
|
- handles = []
|
|
- m = pycurl.CurlMulti()
|
|
- for i in range(NUM_PAGES):
|
|
- c = Curl(URL %i)
|
|
- m.add_handle(c._curl)
|
|
- handles.append(c)
|
|
-
|
|
- clock2 = time.time()
|
|
-
|
|
- # stir state machine into action
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
- # get data
|
|
- while num_handles:
|
|
- m.select(1.0)
|
|
- while 1:
|
|
- ret, num_handles = m.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
- clock3 = time.time()
|
|
-
|
|
- # close handles
|
|
- for c in handles:
|
|
- c.close()
|
|
- m.close()
|
|
-
|
|
- clock4 = time.time()
|
|
- print "multi interface: %d pages: perform %5.2f secs, total %5.2f secs" % (NUM_PAGES, clock3 - clock2, clock4 - clock1)
|
|
-
|
|
- # print result
|
|
- print_result(handles)
|
|
-
|
|
-
|
|
-
|
|
-###
|
|
-### 2) thread
|
|
-###
|
|
-
|
|
-class Test(Thread):
|
|
- def __init__(self, lock=None):
|
|
- Thread.__init__(self)
|
|
- self.lock = lock
|
|
- self.items = []
|
|
-
|
|
- def run(self):
|
|
- if self.lock:
|
|
- self.lock.acquire()
|
|
- self.lock.release()
|
|
- for c in self.items:
|
|
- c.perform()
|
|
-
|
|
-
|
|
-def test_threads(lock=None):
|
|
- clock1 = time.time()
|
|
-
|
|
- # create and start threads, but block them
|
|
- if lock:
|
|
- lock.acquire()
|
|
-
|
|
- # init (FIXME - this is ugly)
|
|
- threads = []
|
|
- handles = []
|
|
- t = None
|
|
- for i in range(NUM_PAGES):
|
|
- if i % (NUM_PAGES / NUM_THREADS) == 0:
|
|
- t = Test(lock)
|
|
- if lock:
|
|
- t.start()
|
|
- threads.append(t)
|
|
- c = Curl(URL % i)
|
|
- t.items.append(c)
|
|
- handles.append(c)
|
|
- assert len(handles) == NUM_PAGES
|
|
- assert len(threads) == NUM_THREADS
|
|
-
|
|
- clock2 = time.time()
|
|
-
|
|
- #
|
|
- if lock:
|
|
- # release lock to let the blocked threads run
|
|
- lock.release()
|
|
- else:
|
|
- # start threads
|
|
- for t in threads:
|
|
- t.start()
|
|
- # wait for threads to finish
|
|
- for t in threads:
|
|
- t.join()
|
|
-
|
|
- clock3 = time.time()
|
|
-
|
|
- # close handles
|
|
- for c in handles:
|
|
- c.close()
|
|
-
|
|
- clock4 = time.time()
|
|
- if lock:
|
|
- print "thread interface [lock]: %d pages: perform %5.2f secs, total %5.2f secs" % (NUM_PAGES, clock3 - clock2, clock4 - clock1)
|
|
- else:
|
|
- print "thread interface: %d pages: perform %5.2f secs, total %5.2f secs" % (NUM_PAGES, clock3 - clock2, clock4 - clock1)
|
|
-
|
|
- # print result
|
|
- print_result(handles)
|
|
-
|
|
-
|
|
-
|
|
-###
|
|
-### 3) thread - threads grab curl objects on demand from a shared pool
|
|
-###
|
|
-
|
|
-class TestPool(Thread):
|
|
- def __init__(self, lock, pool):
|
|
- Thread.__init__(self)
|
|
- self.lock = lock
|
|
- self.pool = pool
|
|
-
|
|
- def run(self):
|
|
- while 1:
|
|
- self.lock.acquire()
|
|
- c = None
|
|
- if self.pool:
|
|
- c = self.pool.pop()
|
|
- self.lock.release()
|
|
- if c is None:
|
|
- break
|
|
- c.perform()
|
|
-
|
|
-
|
|
-def test_thread_pool(lock):
|
|
- clock1 = time.time()
|
|
-
|
|
- # init
|
|
- handles = []
|
|
- for i in range(NUM_PAGES):
|
|
- c = Curl(URL %i)
|
|
- handles.append(c)
|
|
-
|
|
- # create and start threads, but block them
|
|
- lock.acquire()
|
|
- threads = []
|
|
- pool = handles[:] # shallow copy of the list, shared for pop()
|
|
- for i in range(NUM_THREADS):
|
|
- t = TestPool(lock, pool)
|
|
- t.start()
|
|
- threads.append(t)
|
|
- assert len(pool) == NUM_PAGES
|
|
- assert len(threads) == NUM_THREADS
|
|
-
|
|
- clock2 = time.time()
|
|
-
|
|
- # release lock to let the blocked threads run
|
|
- lock.release()
|
|
-
|
|
- # wait for threads to finish
|
|
- for t in threads:
|
|
- t.join()
|
|
-
|
|
- clock3 = time.time()
|
|
-
|
|
- # close handles
|
|
- for c in handles:
|
|
- c.close()
|
|
-
|
|
- clock4 = time.time()
|
|
- print "thread interface [pool]: %d pages: perform %5.2f secs, total %5.2f secs" % (NUM_PAGES, clock3 - clock2, clock4 - clock1)
|
|
-
|
|
- # print result
|
|
- print_result(handles)
|
|
-
|
|
-
|
|
-
|
|
-lock = RLock()
|
|
-if 1:
|
|
- test_multi()
|
|
- test_threads()
|
|
- test_threads(lock)
|
|
- test_thread_pool(lock)
|
|
-else:
|
|
- test_thread_pool(lock)
|
|
- test_threads(lock)
|
|
- test_threads()
|
|
- test_multi()
|
|
-
|
|
diff --git a/tests/test_post.py b/tests/test_post.py
|
|
deleted file mode 100644
|
|
index f0a8ad0..0000000
|
|
--- a/tests/test_post.py
|
|
+++ /dev/null
|
|
@@ -1,24 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import urllib
|
|
-import pycurl
|
|
-
|
|
-# simple
|
|
-pf = {'field1': 'value1'}
|
|
-
|
|
-# multiple fields
|
|
-pf = {'field1':'value1', 'field2':'value2 with blanks', 'field3':'value3'}
|
|
-
|
|
-# multiple fields with & in field
|
|
-pf = {'field1':'value1', 'field2':'value2 with blanks and & chars',
|
|
- 'field3':'value3'}
|
|
-
|
|
-c = pycurl.Curl()
|
|
-c.setopt(c.URL, 'http://pycurl.sourceforge.net/tests/testpostvars.php')
|
|
-c.setopt(c.POSTFIELDS, urllib.urlencode(pf))
|
|
-c.setopt(c.VERBOSE, 1)
|
|
-c.perform()
|
|
-c.close()
|
|
diff --git a/tests/test_post2.py b/tests/test_post2.py
|
|
deleted file mode 100644
|
|
index 74a6eca..0000000
|
|
--- a/tests/test_post2.py
|
|
+++ /dev/null
|
|
@@ -1,18 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import pycurl
|
|
-
|
|
-pf = [('field1', 'this is a test using httppost & stuff'),
|
|
- ('field2', (pycurl.FORM_FILE, 'test_post.py', pycurl.FORM_FILE, 'test_post2.py')),
|
|
- ('field3', (pycurl.FORM_CONTENTS, 'this is wei\000rd, but null-bytes are okay'))
|
|
- ]
|
|
-
|
|
-c = pycurl.Curl()
|
|
-c.setopt(c.URL, 'http://www.contactor.se/~dast/postit.cgi')
|
|
-c.setopt(c.HTTPPOST, pf)
|
|
-c.setopt(c.VERBOSE, 1)
|
|
-c.perform()
|
|
-c.close()
|
|
diff --git a/tests/test_post3.py b/tests/test_post3.py
|
|
deleted file mode 100644
|
|
index 617eba2..0000000
|
|
--- a/tests/test_post3.py
|
|
+++ /dev/null
|
|
@@ -1,32 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import urllib
|
|
-POSTSTRING = urllib.urlencode({'field1':'value1', 'field2':'value2 with blanks', 'field3':'value3'})
|
|
-
|
|
-class test:
|
|
-
|
|
- def __init__(self):
|
|
- self.finished = False
|
|
-
|
|
- def read_cb(self, size):
|
|
- assert len(POSTSTRING) <= size
|
|
- if not self.finished:
|
|
- self.finished = True
|
|
- return POSTSTRING
|
|
- else:
|
|
- # Nothing more to read
|
|
- return ""
|
|
-
|
|
-import pycurl
|
|
-c = pycurl.Curl()
|
|
-t = test()
|
|
-c.setopt(c.URL, 'http://pycurl.sourceforge.net/tests/testpostvars.php')
|
|
-c.setopt(c.POST, 1)
|
|
-c.setopt(c.POSTFIELDSIZE, len(POSTSTRING))
|
|
-c.setopt(c.READFUNCTION, t.read_cb)
|
|
-c.setopt(c.VERBOSE, 1)
|
|
-c.perform()
|
|
-c.close()
|
|
diff --git a/tests/test_reset.py b/tests/test_reset.py
|
|
deleted file mode 100644
|
|
index 1addcfe..0000000
|
|
--- a/tests/test_reset.py
|
|
+++ /dev/null
|
|
@@ -1,75 +0,0 @@
|
|
-#!/usr/bin/python
|
|
-
|
|
-import sys
|
|
-import pycurl
|
|
-
|
|
-saw_error = 1
|
|
-
|
|
-def main():
|
|
- global saw_error
|
|
-
|
|
- pycurl.global_init(pycurl.GLOBAL_DEFAULT)
|
|
-
|
|
- outf = file("/dev/null", "rb+")
|
|
- cm = pycurl.CurlMulti()
|
|
-
|
|
- # Set multi handle's options
|
|
- cm.setopt(pycurl.M_PIPELINING, 1)
|
|
-
|
|
- eh = pycurl.Curl()
|
|
-
|
|
- for x in range(1, 20):
|
|
-
|
|
- eh.setopt(pycurl.WRITEDATA, outf)
|
|
- eh.setopt(pycurl.URL, sys.argv[1])
|
|
- cm.add_handle(eh)
|
|
-
|
|
- while 1:
|
|
- ret, active_handles = cm.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
- while active_handles:
|
|
- ret = cm.select(1.0)
|
|
- if ret == -1:
|
|
- continue
|
|
- while 1:
|
|
- ret, active_handles = cm.perform()
|
|
- if ret != pycurl.E_CALL_MULTI_PERFORM:
|
|
- break
|
|
-
|
|
- count, good, bad = cm.info_read()
|
|
-
|
|
- for h, en, em in bad:
|
|
- print "Transfer to %s failed with %d, %s\n" % \
|
|
- (h.getinfo(pycurl.EFFECTIVE_URL), en, em)
|
|
- raise RuntimeError
|
|
-
|
|
- for h in good:
|
|
- httpcode = h.getinfo(pycurl.RESPONSE_CODE)
|
|
- if httpcode != 200:
|
|
- print "Transfer to %s failed with code %d\n" %\
|
|
- (h.getinfo(pycurl.EFFECTIVE_URL), httpcode)
|
|
- raise RuntimeError
|
|
-
|
|
- else:
|
|
- print "Recd %d bytes from %s" % \
|
|
- (h.getinfo(pycurl.SIZE_DOWNLOAD),
|
|
- h.getinfo(pycurl.EFFECTIVE_URL))
|
|
-
|
|
- cm.remove_handle(eh)
|
|
- eh.reset()
|
|
-
|
|
- eh.close()
|
|
- cm.close()
|
|
- outf.close()
|
|
-
|
|
- pycurl.global_cleanup()
|
|
-
|
|
-
|
|
-if __name__ == '__main__':
|
|
- if len(sys.argv) != 2:
|
|
- print "Usage: %s <url>" % sys.argv[0]
|
|
- sys.exit(2)
|
|
- main()
|
|
-
|
|
diff --git a/tests/test_share.py b/tests/test_share.py
|
|
deleted file mode 100644
|
|
index 3332cda..0000000
|
|
--- a/tests/test_share.py
|
|
+++ /dev/null
|
|
@@ -1,34 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys
|
|
-import pycurl
|
|
-import threading
|
|
-
|
|
-print >>sys.stderr, 'Testing', pycurl.version
|
|
-
|
|
-
|
|
-class Test(threading.Thread):
|
|
-
|
|
- def __init__(self, share):
|
|
- threading.Thread.__init__(self)
|
|
- self.curl = pycurl.Curl()
|
|
- self.curl.setopt(pycurl.URL, 'http://curl.haxx.se')
|
|
- self.curl.setopt(pycurl.SHARE, share)
|
|
-
|
|
- def run(self):
|
|
- self.curl.perform()
|
|
- self.curl.close()
|
|
-
|
|
-s = pycurl.CurlShare()
|
|
-s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_COOKIE)
|
|
-s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_DNS)
|
|
-
|
|
-t1 = Test(s)
|
|
-t2 = Test(s)
|
|
-
|
|
-t1.start()
|
|
-t2.start()
|
|
-del s
|
|
diff --git a/tests/test_socketopen.py b/tests/test_socketopen.py
|
|
deleted file mode 100644
|
|
index d3f0a62..0000000
|
|
--- a/tests/test_socketopen.py
|
|
+++ /dev/null
|
|
@@ -1,17 +0,0 @@
|
|
-import pycurl
|
|
-import StringIO
|
|
-import socket
|
|
-
|
|
-def socketopen(family, socktype, protocol):
|
|
- print family, socktype, protocol
|
|
- s = socket.socket(family, socktype, protocol)
|
|
- s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
- return s
|
|
-
|
|
-sio = StringIO.StringIO()
|
|
-
|
|
-c = pycurl.Curl()
|
|
-c.setopt(pycurl.OPENSOCKETFUNCTION, socketopen)
|
|
-c.setopt(pycurl.URL, 'http://camvine.com')
|
|
-c.setopt(pycurl.WRITEFUNCTION, sio.write)
|
|
-c.perform()
|
|
diff --git a/tests/test_stringio.py b/tests/test_stringio.py
|
|
deleted file mode 100644
|
|
index 25e639b..0000000
|
|
--- a/tests/test_stringio.py
|
|
+++ /dev/null
|
|
@@ -1,25 +0,0 @@
|
|
-#! /usr/bin/env python
|
|
-# -*- coding: iso-8859-1 -*-
|
|
-# vi:ts=4:et
|
|
-# $Id$
|
|
-
|
|
-import sys
|
|
-try:
|
|
- from cStringIO import StringIO
|
|
-except ImportError:
|
|
- from StringIO import StringIO
|
|
-import pycurl
|
|
-
|
|
-url = "http://curl.haxx.se/dev/"
|
|
-
|
|
-print "Testing", pycurl.version
|
|
-
|
|
-body = StringIO()
|
|
-c = pycurl.Curl()
|
|
-c.setopt(c.URL, url)
|
|
-c.setopt(c.WRITEFUNCTION, body.write)
|
|
-c.perform()
|
|
-c.close()
|
|
-
|
|
-contents = body.getvalue()
|
|
-print contents
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 217287f1378ef018fae789f748470a170515a3ea Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 13:36:38 -0500
|
|
Subject: [PATCH 063/112] Fix make test to run nosetests (closes #5)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
Makefile | 4 +++-
|
|
1 files changed, 3 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 9b2369d..9475250 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -7,6 +7,7 @@ SHELL = /bin/sh
|
|
|
|
PYTHON = python2.3
|
|
PYTHON = python
|
|
+NOSETESTS = nosetests
|
|
|
|
all build:
|
|
$(PYTHON) setup.py build
|
|
@@ -15,7 +16,8 @@ build-7.10.8:
|
|
$(PYTHON) setup.py build --curl-config=/home/hosts/localhost/packages/curl-7.10.8/bin/curl-config
|
|
|
|
test: build
|
|
- $(PYTHON) tests/test_internals.py -q
|
|
+ PYTHONPATH=$$(ls -d build/lib.*):$$PYTHONPATH \
|
|
+ $(NOSETESTS)
|
|
|
|
# (needs GNU binutils)
|
|
strip: build
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From dd6cb3db28d4960e5a5902731bd989b918a018ce Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:25:47 -0500
|
|
Subject: [PATCH 064/112] First stab at travis configuration
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.travis.yml | 11 +++++++++++
|
|
requirements-dev.txt | 1 +
|
|
2 files changed, 12 insertions(+), 0 deletions(-)
|
|
create mode 100644 .travis.yml
|
|
create mode 100644 requirements-dev.txt
|
|
|
|
diff --git a/.travis.yml b/.travis.yml
|
|
new file mode 100644
|
|
index 0000000..2350dfb
|
|
--- /dev/null
|
|
+++ b/.travis.yml
|
|
@@ -0,0 +1,11 @@
|
|
+language: python
|
|
+python:
|
|
+ - "2.5"
|
|
+ - "2.6"
|
|
+ - "2.7"
|
|
+install: >
|
|
+ pip install -r requirements-dev.txt --use-mirrors &&
|
|
+ sudo apt-get install vsftpd
|
|
+script: >
|
|
+ export PYCURL_VSFTPD_PATH=/usr/sbin/vsftpd &&
|
|
+ nosetests
|
|
diff --git a/requirements-dev.txt b/requirements-dev.txt
|
|
new file mode 100644
|
|
index 0000000..f3c7e8e
|
|
--- /dev/null
|
|
+++ b/requirements-dev.txt
|
|
@@ -0,0 +1 @@
|
|
+nose
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 6d4f146d910400dfcfe9ea758024fbf0a118242f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:37:47 -0500
|
|
Subject: [PATCH 065/112] Building the C module will help
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.travis.yml | 2 ++
|
|
1 files changed, 2 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/.travis.yml b/.travis.yml
|
|
index 2350dfb..ae17929 100644
|
|
--- a/.travis.yml
|
|
+++ b/.travis.yml
|
|
@@ -7,5 +7,7 @@ install: >
|
|
pip install -r requirements-dev.txt --use-mirrors &&
|
|
sudo apt-get install vsftpd
|
|
script: >
|
|
+ make &&
|
|
+ export PYTHONPATH=build/lib.* &&
|
|
export PYCURL_VSFTPD_PATH=/usr/sbin/vsftpd &&
|
|
nosetests
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 08975482a2e8f09128e261c352866049b1b3b928 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:45:46 -0500
|
|
Subject: [PATCH 066/112] Go through more hoops (/bin/dash in play?)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.travis.yml | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/.travis.yml b/.travis.yml
|
|
index ae17929..4afdff9 100644
|
|
--- a/.travis.yml
|
|
+++ b/.travis.yml
|
|
@@ -8,6 +8,6 @@ install: >
|
|
sudo apt-get install vsftpd
|
|
script: >
|
|
make &&
|
|
- export PYTHONPATH=build/lib.* &&
|
|
+ export PYTHONPATH=$(ls -d build/lib.*) &&
|
|
export PYCURL_VSFTPD_PATH=/usr/sbin/vsftpd &&
|
|
nosetests
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From b55b5ace06a87a7bd1464b3be888a9d71b204a58 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:50:21 -0500
|
|
Subject: [PATCH 067/112] Forgot about bottle
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
requirements-dev.txt | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/requirements-dev.txt b/requirements-dev.txt
|
|
index f3c7e8e..36b0b24 100644
|
|
--- a/requirements-dev.txt
|
|
+++ b/requirements-dev.txt
|
|
@@ -1 +1,2 @@
|
|
+bottle
|
|
nose
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From cbf6fd82722d6db1a6bf8c20b2a95bc04373a31d Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:20:25 -0500
|
|
Subject: [PATCH 068/112] Python 2.5 needs simplejson
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.travis.yml | 6 +++++-
|
|
requirements-dev-2.5.txt | 2 ++
|
|
2 files changed, 7 insertions(+), 1 deletions(-)
|
|
create mode 100644 requirements-dev-2.5.txt
|
|
|
|
diff --git a/.travis.yml b/.travis.yml
|
|
index 4afdff9..4268895 100644
|
|
--- a/.travis.yml
|
|
+++ b/.travis.yml
|
|
@@ -4,7 +4,11 @@ python:
|
|
- "2.6"
|
|
- "2.7"
|
|
install: >
|
|
- pip install -r requirements-dev.txt --use-mirrors &&
|
|
+ if test -e requirements-dev-$TRAVIS_PYTHON_VERSION.txt; then
|
|
+ pip install -r requirements-dev-$TRAVIS_PYTHON_VERSION.txt --use-mirrors
|
|
+ else
|
|
+ pip install -r requirements-dev.txt --use-mirrors
|
|
+ fi &&
|
|
sudo apt-get install vsftpd
|
|
script: >
|
|
make &&
|
|
diff --git a/requirements-dev-2.5.txt b/requirements-dev-2.5.txt
|
|
new file mode 100644
|
|
index 0000000..52e3460
|
|
--- /dev/null
|
|
+++ b/requirements-dev-2.5.txt
|
|
@@ -0,0 +1,2 @@
|
|
+-r requirements-dev.txt
|
|
+simplejson
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c90d60edd47a2a3ef20b3a09f2c2c3dc59938746 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Thu, 7 Mar 2013 04:23:52 -0500
|
|
Subject: [PATCH 069/112] Expand readme (mostly borrowed from @Lispython's fork)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
README | 13 --------
|
|
README.rst | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 93 insertions(+), 13 deletions(-)
|
|
delete mode 100644 README
|
|
create mode 100644 README.rst
|
|
|
|
diff --git a/README b/README
|
|
deleted file mode 100644
|
|
index 6b3e1d4..0000000
|
|
--- a/README
|
|
+++ /dev/null
|
|
@@ -1,13 +0,0 @@
|
|
-License
|
|
--------
|
|
-
|
|
-Copyright (C) 2001-2008 by Kjetil Jacobsen <kjetilja at gmail.com>
|
|
-Copyright (C) 2001-2008 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
|
|
-
|
|
-All rights reserved.
|
|
-
|
|
-PycURL is dual licensed under the LGPL and an MIT/X derivative license
|
|
-based on the cURL license. A full copy of the LGPL license is included
|
|
-in the file COPYING. A full copy of the MIT/X derivative license is
|
|
-included in the file COPYING2. You can redistribute and/or modify PycURL
|
|
-according to the terms of either license.
|
|
diff --git a/README.rst b/README.rst
|
|
new file mode 100644
|
|
index 0000000..3518d9d
|
|
--- /dev/null
|
|
+++ b/README.rst
|
|
@@ -0,0 +1,93 @@
|
|
+PycURL: Python interface to libcurl
|
|
+====================================
|
|
+
|
|
+PycURL is a Python interface to `libcurl`_. PycURL can be used to fetch objects
|
|
+identified by a URL from a Python program, similar to the `urllib`_ Python module.
|
|
+PycURL is mature, very fast, and supports a lot of features.
|
|
+
|
|
+Overview
|
|
+--------
|
|
+
|
|
+- libcurl is a free and easy-to-use client-side URL transfer library, supporting
|
|
+ FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, IMAP,
|
|
+ SMTP, POP3 and RTSP. libcurl supports SSL certificates, HTTP POST, HTTP PUT,
|
|
+ FTP uploading, HTTP form based upload, proxies, cookies, user+password
|
|
+ authentication (Basic, Digest, NTLM, Negotiate, Kerberos4), file transfer
|
|
+ resume, http proxy tunneling and more!
|
|
+
|
|
+- libcurl is highly portable, it builds and works identically on numerous
|
|
+ platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX,
|
|
+ AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X,
|
|
+ Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS and more...
|
|
+
|
|
+- libcurl is `free`_, `thread-safe`_, `IPv6 compatible`_, `feature rich`_,
|
|
+ `well supported`_, `fast`_, `thoroughly documented`_ and is already used by
|
|
+ many known, big and successful `companies`_ and numerous `applications`_.
|
|
+
|
|
+.. _free: http://curl.haxx.se/docs/copyright.html
|
|
+.. _thread-safe: http://curl.haxx.se/libcurl/features.html#thread
|
|
+.. _`IPv6 compatible`: http://curl.haxx.se/libcurl/features.html#ipv6
|
|
+.. _`feature rich`: http://curl.haxx.se/libcurl/features.html#features
|
|
+.. _`well supported`: http://curl.haxx.se/libcurl/features.html#support
|
|
+.. _`fast`: http://curl.haxx.se/libcurl/features.html#fast
|
|
+.. _`thoroughly documented`: http://curl.haxx.se/libcurl/features.html#docs
|
|
+.. _companies: http://curl.haxx.se/docs/companies.html
|
|
+.. _applications: http://curl.haxx.se/libcurl/using/apps.html
|
|
+
|
|
+Installation
|
|
+------------
|
|
+
|
|
+You can install the most recent PycURL version using `easy_install`_::
|
|
+
|
|
+ easy_install pycurl
|
|
+
|
|
+or `pip`_::
|
|
+
|
|
+ pip install pycurl
|
|
+
|
|
+
|
|
+.. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall
|
|
+.. _pip: http://pypi.python.org/pypi/pip
|
|
+
|
|
+Contribute
|
|
+----------
|
|
+
|
|
+For smaller changes:
|
|
+
|
|
+#. Fork `the repository`_ on Github.
|
|
+#. Create a branch off **master**.
|
|
+#. Make your changes.
|
|
+#. Write a test which shows that the bug was fixed or that the feature
|
|
+ works as expected.
|
|
+#. Send a pull request.
|
|
+
|
|
+For larger changes:
|
|
+
|
|
+#. Join the `mailing list`_.
|
|
+#. Discuss your proposal on the mailing list.
|
|
+#. When consensus is reached, implement it as described above.
|
|
+
|
|
+.. image:: https://api.travis-ci.org/p/pycurl.png
|
|
+ :target: https://travis-ci.org/p/pycurl
|
|
+
|
|
+License
|
|
+-------
|
|
+
|
|
+::
|
|
+
|
|
+ Copyright (C) 2001-2008 by Kjetil Jacobsen <kjetilja at gmail.com>
|
|
+ Copyright (C) 2001-2008 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
|
|
+
|
|
+ All rights reserved.
|
|
+
|
|
+ PycURL is dual licensed under the LGPL and an MIT/X derivative license
|
|
+ based on the cURL license. A full copy of the LGPL license is included
|
|
+ in the file COPYING. A full copy of the MIT/X derivative license is
|
|
+ included in the file COPYING2. You can redistribute and/or modify PycURL
|
|
+ according to the terms of either license.
|
|
+
|
|
+.. _PycURL: http://pycurl.sourceforge.net/
|
|
+.. _libcurl: http://curl.haxx.se/libcurl/
|
|
+.. _urllib: http://docs.python.org/library/urllib.html
|
|
+.. _`the repository`: https://github.com/p/pycurl
|
|
+.. _`mailing list`: http://cool.haxx.se/mailman/listinfo/curl-and-python
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 27c1817d13b1773558d5a7b6b327c14c5b4ffdf9 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Thu, 7 Mar 2013 04:30:23 -0500
|
|
Subject: [PATCH 070/112] Readme -> readme.rst elsewhere
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
MANIFEST.in | 2 +-
|
|
setup.py | 2 +-
|
|
tests/ftp_test.py | 6 +++---
|
|
tests/post_test.py | 4 ++--
|
|
4 files changed, 7 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/MANIFEST.in b/MANIFEST.in
|
|
index 7d5aaf5..11ce1fe 100644
|
|
--- a/MANIFEST.in
|
|
+++ b/MANIFEST.in
|
|
@@ -8,7 +8,7 @@ include COPYING
|
|
include COPYING2
|
|
include INSTALL
|
|
include Makefile
|
|
-include README
|
|
+include README.rst
|
|
include TODO
|
|
include MANIFEST.in
|
|
include src/Makefile
|
|
diff --git a/setup.py b/setup.py
|
|
index 33704ef..235e4c9 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -166,7 +166,7 @@ def get_data_files():
|
|
else:
|
|
datadir = os.path.join("share", "doc", PACKAGE)
|
|
#
|
|
- files = ["ChangeLog", "COPYING", "COPYING2", "INSTALL", "README", "TODO",]
|
|
+ files = ["ChangeLog", "COPYING", "COPYING2", "INSTALL", "README.rst", "TODO",]
|
|
if files:
|
|
data_files.append((os.path.join(datadir), files))
|
|
files = glob.glob(os.path.join("doc", "*.html"))
|
|
diff --git a/tests/ftp_test.py b/tests/ftp_test.py
|
|
index fa2ef79..5ee380c 100644
|
|
--- a/tests/ftp_test.py
|
|
+++ b/tests/ftp_test.py
|
|
@@ -26,7 +26,7 @@ class FtpTest(unittest.TestCase):
|
|
self.curl.perform()
|
|
|
|
result = sio.getvalue()
|
|
- assert 'README' in result
|
|
+ assert 'README.rst' in result
|
|
assert 'INSTALL' in result
|
|
|
|
# XXX this test needs to be fixed
|
|
@@ -38,7 +38,7 @@ class FtpTest(unittest.TestCase):
|
|
self.curl.perform()
|
|
|
|
result = sio.getvalue()
|
|
- assert 'README' not in result
|
|
+ assert 'README.rst' not in result
|
|
assert 'ftp_test.py' in result
|
|
|
|
def test_epsv(self):
|
|
@@ -49,5 +49,5 @@ class FtpTest(unittest.TestCase):
|
|
self.curl.perform()
|
|
|
|
result = sio.getvalue()
|
|
- assert 'README' in result
|
|
+ assert 'README.rst' in result
|
|
assert 'INSTALL' in result
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index e8b0675..6f9d8d4 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -81,7 +81,7 @@ class PostTest(unittest.TestCase):
|
|
self.check_post(send, expect, 'http://localhost:8380/postfields')
|
|
|
|
def test_post_file(self):
|
|
- path = os.path.join(os.path.dirname(__file__), '..', 'README')
|
|
+ path = os.path.join(os.path.dirname(__file__), '..', 'README.rst')
|
|
with open(path) as f:
|
|
contents = f.read()
|
|
send = [
|
|
@@ -90,7 +90,7 @@ class PostTest(unittest.TestCase):
|
|
]
|
|
expect = [{
|
|
'name': 'field2',
|
|
- 'filename': 'README',
|
|
+ 'filename': 'README.rst',
|
|
'data': contents,
|
|
}]
|
|
self.check_post(send, expect, 'http://localhost:8380/files')
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From b3a7a67683458b9b5f7d8a68df533319b6bfbcd6 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:50:34 -0500
|
|
Subject: [PATCH 071/112] Python 2.5 compatibility: with statement
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 2 ++
|
|
tests/post_test.py | 2 ++
|
|
tests/write_to_file_test.py | 2 ++
|
|
3 files changed, 6 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index c0d256b..1d31e97 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -2,6 +2,8 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
+from __future__ import with_statement
|
|
+
|
|
import unittest
|
|
import pycurl
|
|
import sys
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index 6f9d8d4..804104e 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -2,6 +2,8 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
+from __future__ import with_statement
|
|
+
|
|
import os.path
|
|
import pycurl
|
|
import unittest
|
|
diff --git a/tests/write_to_file_test.py b/tests/write_to_file_test.py
|
|
index 67c9c63..c3c8822 100644
|
|
--- a/tests/write_to_file_test.py
|
|
+++ b/tests/write_to_file_test.py
|
|
@@ -2,6 +2,8 @@
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
+from __future__ import with_statement
|
|
+
|
|
import unittest
|
|
import pycurl
|
|
import tempfile
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 370806caa376039f9ba97b9e79e7565b54a4b6f0 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:10:22 -0500
|
|
Subject: [PATCH 072/112] Python 2.5 compatibility: json/simplejson
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/app.py | 5 ++++-
|
|
tests/post_test.py | 5 ++++-
|
|
tests/post_with_read_callback_test.py | 5 ++++-
|
|
3 files changed, 12 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/tests/app.py b/tests/app.py
|
|
index a83e628..eb10668 100644
|
|
--- a/tests/app.py
|
|
+++ b/tests/app.py
|
|
@@ -1,5 +1,8 @@
|
|
import bottle
|
|
-import json
|
|
+try:
|
|
+ import json
|
|
+except ImportError:
|
|
+ import simplejson as json
|
|
|
|
app = bottle.Bottle()
|
|
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index 804104e..a36a677 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -8,7 +8,10 @@ import os.path
|
|
import pycurl
|
|
import unittest
|
|
import io
|
|
-import json
|
|
+try:
|
|
+ import json
|
|
+except ImportError:
|
|
+ import simplejson as json
|
|
try:
|
|
import urllib.parse as urllib_parse
|
|
except ImportError:
|
|
diff --git a/tests/post_with_read_callback_test.py b/tests/post_with_read_callback_test.py
|
|
index a09e83a..4d8f261 100644
|
|
--- a/tests/post_with_read_callback_test.py
|
|
+++ b/tests/post_with_read_callback_test.py
|
|
@@ -6,7 +6,10 @@ import os.path
|
|
import pycurl
|
|
import unittest
|
|
import io
|
|
-import json
|
|
+try:
|
|
+ import json
|
|
+except ImportError:
|
|
+ import simplejson as json
|
|
try:
|
|
import urllib.parse as urllib_parse
|
|
except ImportError:
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From d1128e970d6427e16f9eb4909531427a0c799d2e Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:18:02 -0500
|
|
Subject: [PATCH 073/112] Python 2.5 compatibility: except as
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/runwsgi.py | 4 +++-
|
|
1 files changed, 3 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
index 5217a3f..8a978ec 100644
|
|
--- a/tests/runwsgi.py
|
|
+++ b/tests/runwsgi.py
|
|
@@ -1,5 +1,6 @@
|
|
# Run a WSGI application in a daemon thread
|
|
|
|
+import sys
|
|
import bottle
|
|
import threading
|
|
import socket
|
|
@@ -21,7 +22,8 @@ def wait_for_network_service(netloc, check_interval, num_attempts):
|
|
for i in range(num_attempts):
|
|
try:
|
|
conn = socket.create_connection(netloc, check_interval)
|
|
- except socket.error as e:
|
|
+ except socket.error:
|
|
+ e = sys.exc_info()[1]
|
|
_time.sleep(check_interval)
|
|
else:
|
|
conn.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 64a832f50f7063cce2df5507b69ac2f216e22f59 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:23:08 -0500
|
|
Subject: [PATCH 074/112] Delete unused io imports
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 1 -
|
|
tests/header_function_test.py | 1 -
|
|
tests/post_test.py | 1 -
|
|
tests/post_with_read_callback_test.py | 1 -
|
|
tests/write_to_stringio_test.py | 1 -
|
|
5 files changed, 0 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index 1d31e97..27a3d04 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -8,7 +8,6 @@ import unittest
|
|
import pycurl
|
|
import sys
|
|
import tempfile
|
|
-import io
|
|
import os
|
|
|
|
from . import app
|
|
diff --git a/tests/header_function_test.py b/tests/header_function_test.py
|
|
index bfe7173..00080ba 100644
|
|
--- a/tests/header_function_test.py
|
|
+++ b/tests/header_function_test.py
|
|
@@ -4,7 +4,6 @@
|
|
|
|
import pycurl
|
|
import unittest
|
|
-import io
|
|
import time as _time
|
|
|
|
from . import app
|
|
diff --git a/tests/post_test.py b/tests/post_test.py
|
|
index a36a677..c11c3c8 100644
|
|
--- a/tests/post_test.py
|
|
+++ b/tests/post_test.py
|
|
@@ -7,7 +7,6 @@ from __future__ import with_statement
|
|
import os.path
|
|
import pycurl
|
|
import unittest
|
|
-import io
|
|
try:
|
|
import json
|
|
except ImportError:
|
|
diff --git a/tests/post_with_read_callback_test.py b/tests/post_with_read_callback_test.py
|
|
index 4d8f261..f0776ea 100644
|
|
--- a/tests/post_with_read_callback_test.py
|
|
+++ b/tests/post_with_read_callback_test.py
|
|
@@ -5,7 +5,6 @@
|
|
import os.path
|
|
import pycurl
|
|
import unittest
|
|
-import io
|
|
try:
|
|
import json
|
|
except ImportError:
|
|
diff --git a/tests/write_to_stringio_test.py b/tests/write_to_stringio_test.py
|
|
index 018800d..e9ab0c7 100644
|
|
--- a/tests/write_to_stringio_test.py
|
|
+++ b/tests/write_to_stringio_test.py
|
|
@@ -4,7 +4,6 @@
|
|
|
|
import pycurl
|
|
import unittest
|
|
-import io
|
|
|
|
from . import app
|
|
from . import runwsgi
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 6c9103dd1769a91967dc9f5d2d0ac3a48fa9528f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:54:35 -0500
|
|
Subject: [PATCH 075/112] Ignore fsync of stdout failures on travis
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/default_write_function_test.py | 13 +++++++++++--
|
|
1 files changed, 11 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/default_write_function_test.py b/tests/default_write_function_test.py
|
|
index 27a3d04..1c8ec16 100644
|
|
--- a/tests/default_write_function_test.py
|
|
+++ b/tests/default_write_function_test.py
|
|
@@ -18,6 +18,15 @@ setup_module, teardown_module = runwsgi.app_runner_setup((app.app, 8380))
|
|
|
|
STDOUT_FD_NUM = 1
|
|
|
|
+def try_fsync(fd):
|
|
+ try:
|
|
+ os.fsync(fd)
|
|
+ except OSError:
|
|
+ # On travis:
|
|
+ # OSError: [Errno 22] Invalid argument
|
|
+ # ignore
|
|
+ pass
|
|
+
|
|
class DefaultWriteFunctionTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.curl = pycurl.Curl()
|
|
@@ -38,7 +47,7 @@ class DefaultWriteFunctionTest(unittest.TestCase):
|
|
# If this flush is not done, stdout output bleeds into the next test
|
|
# that is executed (without nose output capture)
|
|
sys.stdout.flush()
|
|
- os.fsync(STDOUT_FD_NUM)
|
|
+ try_fsync(STDOUT_FD_NUM)
|
|
|
|
# I have a really hard time getting this to work with nose output capture
|
|
def skip_perform_get_with_default_write_function(self):
|
|
@@ -67,7 +76,7 @@ class DefaultWriteFunctionTest(unittest.TestCase):
|
|
self.curl.perform()
|
|
sys.stdout.flush()
|
|
finally:
|
|
- os.fsync(STDOUT_FD_NUM)
|
|
+ try_fsync(STDOUT_FD_NUM)
|
|
os.dup2(saved_stdout_fd, STDOUT_FD_NUM)
|
|
os.close(saved_stdout_fd)
|
|
#os.dup2(100, 1)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 560621974748957f45da26461184ace7bbf05919 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 04:58:42 -0500
|
|
Subject: [PATCH 076/112] My vps says timeout might be -1 there
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_socket_select_test.py | 5 +++--
|
|
1 files changed, 3 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/multi_socket_select_test.py b/tests/multi_socket_select_test.py
|
|
index 0c472cf..6db8b44 100644
|
|
--- a/tests/multi_socket_select_test.py
|
|
+++ b/tests/multi_socket_select_test.py
|
|
@@ -73,8 +73,9 @@ class MultiSocketSelectTest(unittest.TestCase):
|
|
|
|
timeout = m.timeout()
|
|
|
|
-
|
|
- while True:
|
|
+ # timeout might be -1, indicating that all work is done
|
|
+ # XXX make sure there is always work to be done here?
|
|
+ while timeout >= 0:
|
|
(rr, wr, er) = select.select(sockets,sockets,sockets,timeout/1000.0)
|
|
socketSet = set(rr+wr+er)
|
|
if socketSet:
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 9de0de72ea5134d0e3976b0044936ed42e422fc4 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:14:57 -0500
|
|
Subject: [PATCH 077/112] Show pycurl versions in package setup
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/__init__.py | 4 ++++
|
|
1 files changed, 4 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/__init__.py b/tests/__init__.py
|
|
index e69de29..c1ff976 100644
|
|
--- a/tests/__init__.py
|
|
+++ b/tests/__init__.py
|
|
@@ -0,0 +1,4 @@
|
|
+import pycurl
|
|
+
|
|
+def setup_package():
|
|
+ print('Testing %s' % pycurl.version)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 37b493365811d2809927163de3809ac80d1bfc9a Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:07:19 -0500
|
|
Subject: [PATCH 078/112] Show what the entries are if assertion fails
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/debug_test.py | 3 ++-
|
|
1 files changed, 2 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/debug_test.py b/tests/debug_test.py
|
|
index 8005239..d74bed9 100644
|
|
--- a/tests/debug_test.py
|
|
+++ b/tests/debug_test.py
|
|
@@ -46,4 +46,5 @@ class DebugTest(unittest.TestCase):
|
|
for t, b in self.debug_entries:
|
|
if t == wanted_t and wanted_b in b:
|
|
return
|
|
- assert False, "%d: %s not found in debug entries" % (wanted_t, wanted_b)
|
|
+ assert False, "%d: %s not found in debug entries\nEntries are:\n%s" % \
|
|
+ (wanted_t, wanted_b, repr(self.debug_entries))
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 54c08110d132bcc1f79d0484154854f7fedbe6d1 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:09:22 -0500
|
|
Subject: [PATCH 079/112] More informative failure message
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_test.py | 5 ++++-
|
|
1 files changed, 4 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index d9c6174..8701649 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -214,7 +214,10 @@ class MultiTest(unittest.TestCase):
|
|
self.assertEqual('success', m.handles[0].body.getvalue())
|
|
self.assertEqual(200, m.handles[0].http_code)
|
|
# bottle generated response body
|
|
- assert 'Error 403: Forbidden' in m.handles[1].body.getvalue()
|
|
+ body = m.handles[1].body.getvalue()
|
|
+ search = 'Error 403: Forbidden'
|
|
+ if search not in body:
|
|
+ assert False, "'%s' not found in body:\n%s" % (search, body)
|
|
self.assertEqual(403, m.handles[1].http_code)
|
|
# bottle generated response body
|
|
self.assertEqual('', m.handles[2].body.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 8870f4272ba3bb0042168e597a32e3c22b80dc6f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 06:34:39 -0500
|
|
Subject: [PATCH 080/112] Return complete response bodies for 403 and 404 responses as it looks like exact wording varies between bottle versions
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/app.py | 4 ++--
|
|
tests/multi_test.py | 9 +++------
|
|
2 files changed, 5 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/tests/app.py b/tests/app.py
|
|
index eb10668..9b56ace 100644
|
|
--- a/tests/app.py
|
|
+++ b/tests/app.py
|
|
@@ -12,11 +12,11 @@ def ok():
|
|
|
|
@app.route('/status/403')
|
|
def forbidden():
|
|
- bottle.abort(403, 'forbidden')
|
|
+ return bottle.HTTPResponse('forbidden', 403)
|
|
|
|
@app.route('/status/404')
|
|
def not_found():
|
|
- bottle.abort(404, 'not found')
|
|
+ return bottle.HTTPResponse('not found', 404)
|
|
|
|
@app.route('/postfields', method='post')
|
|
def postfields():
|
|
diff --git a/tests/multi_test.py b/tests/multi_test.py
|
|
index 8701649..d540413 100644
|
|
--- a/tests/multi_test.py
|
|
+++ b/tests/multi_test.py
|
|
@@ -153,10 +153,10 @@ class MultiTest(unittest.TestCase):
|
|
self.assertEqual('success', m.handles[0].body.getvalue())
|
|
self.assertEqual(200, m.handles[0].http_code)
|
|
# bottle generated response body
|
|
- assert 'Error 403: Forbidden' in m.handles[1].body.getvalue()
|
|
+ self.assertEqual('forbidden', m.handles[1].body.getvalue())
|
|
self.assertEqual(403, m.handles[1].http_code)
|
|
# bottle generated response body
|
|
- assert 'Error 404: Not Found' in m.handles[2].body.getvalue()
|
|
+ self.assertEqual('not found', m.handles[2].body.getvalue())
|
|
self.assertEqual(404, m.handles[2].http_code)
|
|
|
|
def check_adding_closed_handle(self, close_fn):
|
|
@@ -214,10 +214,7 @@ class MultiTest(unittest.TestCase):
|
|
self.assertEqual('success', m.handles[0].body.getvalue())
|
|
self.assertEqual(200, m.handles[0].http_code)
|
|
# bottle generated response body
|
|
- body = m.handles[1].body.getvalue()
|
|
- search = 'Error 403: Forbidden'
|
|
- if search not in body:
|
|
- assert False, "'%s' not found in body:\n%s" % (search, body)
|
|
+ self.assertEqual('forbidden', m.handles[1].body.getvalue())
|
|
self.assertEqual(403, m.handles[1].http_code)
|
|
# bottle generated response body
|
|
self.assertEqual('', m.handles[2].body.getvalue())
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 567ab2309e67aecda5ba7e46069b1cb85b9bea73 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 22:15:47 -0500
|
|
Subject: [PATCH 081/112] Debug messages originated by curl 7.22 are different
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/debug_test.py | 6 +++++-
|
|
1 files changed, 5 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/debug_test.py b/tests/debug_test.py
|
|
index d74bed9..70e121c 100644
|
|
--- a/tests/debug_test.py
|
|
+++ b/tests/debug_test.py
|
|
@@ -32,7 +32,11 @@ class DebugTest(unittest.TestCase):
|
|
|
|
# Some checks with no particular intent
|
|
self.check(0, 'About to connect')
|
|
- self.check(0, 'Connected to localhost')
|
|
+ version = map(int, pycurl.version_info()[1].split('.'))
|
|
+ if version[0] < 7 or version[0] == 7 and version[1] <= 22:
|
|
+ self.check(0, 'connected')
|
|
+ else:
|
|
+ self.check(0, 'Connected to localhost')
|
|
self.check(0, 'port 8380')
|
|
# request
|
|
self.check(2, 'GET /success HTTP/1.1')
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From d3e6168efb78f643677693afc607abd9e635dd07 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 22:17:48 -0500
|
|
Subject: [PATCH 082/112] Times in http headers are in UTC
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/header_function_test.py | 3 ++-
|
|
1 files changed, 2 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/header_function_test.py b/tests/header_function_test.py
|
|
index 00080ba..7ca564d 100644
|
|
--- a/tests/header_function_test.py
|
|
+++ b/tests/header_function_test.py
|
|
@@ -34,7 +34,8 @@ class HeaderFunctionTest(unittest.TestCase):
|
|
assert len(self.header_lines) > 0
|
|
self.assertEqual("HTTP/1.0 200 OK\r\n", self.header_lines[0])
|
|
# day of week
|
|
- todays_day = _time.strftime('%a')
|
|
+ # important: must be in utc
|
|
+ todays_day = _time.strftime('%a', _time.gmtime())
|
|
# Date: Sun, 03 Mar 2013 05:38:12 GMT\r\n
|
|
self.check('Date: %s' % todays_day)
|
|
# Server: WSGIServer/0.1 Python/2.7.3\r\n
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c223f392fde2b40bb5d88763bcfd9e6883de36c0 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 22:26:19 -0500
|
|
Subject: [PATCH 083/112] Create a generalized function for curl version comparisons
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/util.py | 15 +++++++++++++++
|
|
tests/version_comparison_test.py | 15 +++++++++++++++
|
|
2 files changed, 30 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/version_comparison_test.py
|
|
|
|
diff --git a/tests/util.py b/tests/util.py
|
|
index 891da44..46ac59f 100644
|
|
--- a/tests/util.py
|
|
+++ b/tests/util.py
|
|
@@ -3,6 +3,7 @@
|
|
# $Id$
|
|
|
|
import os, sys
|
|
+import pycurl
|
|
|
|
try:
|
|
from cStringIO import StringIO
|
|
@@ -12,6 +13,20 @@ except ImportError:
|
|
except ImportError:
|
|
from io import StringIO
|
|
|
|
+def version_less_than_spec(version_tuple, spec_tuple):
|
|
+ # spec_tuple may have 2 elements, expect version_tuple to have 3 elements
|
|
+ assert len(version_tuple) >= len(spec_tuple)
|
|
+ for i in range(len(spec_tuple)):
|
|
+ if version_tuple[i] < spec_tuple[i]:
|
|
+ return True
|
|
+ if version_tuple[i] > spec_tuple[i]:
|
|
+ return False
|
|
+ return False
|
|
+
|
|
+def pycurl_version_less_than(spec_tuple):
|
|
+ version = map(int, pycurl.version_info()[1].split('.'))
|
|
+ return version_less_than_spec(version, spec_tuple)
|
|
+
|
|
#
|
|
# prepare sys.path in case we are still in the build directory
|
|
# see also: distutils/command/build.py (build_platlib)
|
|
diff --git a/tests/version_comparison_test.py b/tests/version_comparison_test.py
|
|
new file mode 100644
|
|
index 0000000..80e780c
|
|
--- /dev/null
|
|
+++ b/tests/version_comparison_test.py
|
|
@@ -0,0 +1,15 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import unittest
|
|
+
|
|
+from . import util
|
|
+
|
|
+class VersionComparisonTest(unittest.TestCase):
|
|
+ def test_comparison(self):
|
|
+ assert util.version_less_than_spec((7, 22, 0), (7, 23, 0))
|
|
+ assert util.version_less_than_spec((7, 22, 0), (7, 23))
|
|
+ assert util.version_less_than_spec((7, 22, 0), (7, 22, 1))
|
|
+ assert not util.version_less_than_spec((7, 22, 0), (7, 22, 0))
|
|
+ assert not util.version_less_than_spec((7, 22, 0), (7, 22))
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From e7e7a0f047d88409d9355dab3fab2316b809e5ae Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 22:27:25 -0500
|
|
Subject: [PATCH 084/112] Use version comparison helper in debug test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/debug_test.py | 3 +--
|
|
tests/util.py | 4 ++--
|
|
2 files changed, 3 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/tests/debug_test.py b/tests/debug_test.py
|
|
index 70e121c..e81d653 100644
|
|
--- a/tests/debug_test.py
|
|
+++ b/tests/debug_test.py
|
|
@@ -32,8 +32,7 @@ class DebugTest(unittest.TestCase):
|
|
|
|
# Some checks with no particular intent
|
|
self.check(0, 'About to connect')
|
|
- version = map(int, pycurl.version_info()[1].split('.'))
|
|
- if version[0] < 7 or version[0] == 7 and version[1] <= 22:
|
|
+ if util.pycurl_version_less_than(7, 24):
|
|
self.check(0, 'connected')
|
|
else:
|
|
self.check(0, 'Connected to localhost')
|
|
diff --git a/tests/util.py b/tests/util.py
|
|
index 46ac59f..b8e22ec 100644
|
|
--- a/tests/util.py
|
|
+++ b/tests/util.py
|
|
@@ -23,9 +23,9 @@ def version_less_than_spec(version_tuple, spec_tuple):
|
|
return False
|
|
return False
|
|
|
|
-def pycurl_version_less_than(spec_tuple):
|
|
+def pycurl_version_less_than(*spec):
|
|
version = map(int, pycurl.version_info()[1].split('.'))
|
|
- return version_less_than_spec(version, spec_tuple)
|
|
+ return version_less_than_spec(version, spec)
|
|
|
|
#
|
|
# prepare sys.path in case we are still in the build directory
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From ee31a65de12bea5d00f0720eb8b5ec5be796c322 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 6 Mar 2013 22:30:44 -0500
|
|
Subject: [PATCH 085/112] libcurl 7.23.0 produces different results
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_timer_test.py | 7 +++++--
|
|
1 files changed, 5 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/multi_timer_test.py b/tests/multi_timer_test.py
|
|
index e961780..c4b3df4 100644
|
|
--- a/tests/multi_timer_test.py
|
|
+++ b/tests/multi_timer_test.py
|
|
@@ -77,8 +77,11 @@ class MultiSocketTest(unittest.TestCase):
|
|
self.assertEqual(200, c.http_code)
|
|
|
|
assert len(timers) > 0
|
|
- assert timers[0] > 0
|
|
- self.assertEqual(-1, timers[-1])
|
|
+ # libcurl 7.23.0 produces a 0 timer
|
|
+ assert timers[0] >= 0
|
|
+ # this assertion does not appear to hold on older libcurls
|
|
+ if not util.pycurl_version_less_than(7, 24):
|
|
+ self.assertEqual(-1, timers[-1])
|
|
|
|
# close handles
|
|
for c in m.handles:
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From f510b505c4e497904e3591696c7d8985baea409b Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Thu, 7 Mar 2013 00:16:21 -0500
|
|
Subject: [PATCH 086/112] Change memleak test to use id() rather than regexp match of addresses (closes #12)
|
|
|
|
This commit also fixes the test to check objects that GC tracks
|
|
rather than the object type repeatedly.
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/memleak_test.py | 16 ++++++----------
|
|
1 files changed, 6 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/tests/memleak_test.py b/tests/memleak_test.py
|
|
index 6e9f76c..1b1bbd5 100644
|
|
--- a/tests/memleak_test.py
|
|
+++ b/tests/memleak_test.py
|
|
@@ -5,12 +5,9 @@
|
|
import pycurl
|
|
import unittest
|
|
import gc
|
|
-import re
|
|
|
|
class MemleakTest(unittest.TestCase):
|
|
def test_collection(self):
|
|
- regexp = re.compile(r'at (0x\d+)')
|
|
-
|
|
gc.collect()
|
|
flags = gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE
|
|
# python 3 has no DEBUG_OBJECTS
|
|
@@ -31,12 +28,10 @@ class MemleakTest(unittest.TestCase):
|
|
multi.add_handle(curl)
|
|
t.append(curl)
|
|
|
|
- match = regexp.search(repr(curl))
|
|
- assert match is not None
|
|
- searches.append(match.group(1))
|
|
- match = regexp.search(repr(multi))
|
|
- assert match
|
|
- searches.append(match.group(1))
|
|
+ c_id = id(curl)
|
|
+ searches.append(c_id)
|
|
+ m_id = id(multi)
|
|
+ searches.append(m_id)
|
|
|
|
#print("Tracked objects:", len(gc.get_objects()))
|
|
|
|
@@ -56,4 +51,5 @@ class MemleakTest(unittest.TestCase):
|
|
|
|
objects = gc.get_objects()
|
|
for search in searches:
|
|
- assert 'at %s' % search not in repr(object)
|
|
+ for object in objects:
|
|
+ assert search != id(object)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 70206193e5219fac1da3e3d27167ed070fdff7b9 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Mon, 11 Mar 2013 22:19:14 -0400
|
|
Subject: [PATCH 087/112] More informative exception message when vsftpd is missing or not in PATH (closes #6)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/procmgr.py | 12 +++++++++++-
|
|
1 files changed, 11 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/procmgr.py b/tests/procmgr.py
|
|
index 8d5c0cc..ce08da9 100644
|
|
--- a/tests/procmgr.py
|
|
+++ b/tests/procmgr.py
|
|
@@ -1,6 +1,7 @@
|
|
import threading
|
|
import subprocess
|
|
import os
|
|
+import sys
|
|
import signal
|
|
|
|
from . import runwsgi
|
|
@@ -53,7 +54,16 @@ def vsftpd_setup():
|
|
]
|
|
setup_module = start_setup(cmd)
|
|
def do_setup_module():
|
|
- setup_module()
|
|
+ try:
|
|
+ setup_module()
|
|
+ except OSError:
|
|
+ import errno
|
|
+ e = sys.exc_info()[1]
|
|
+ if e.errno == errno.ENOENT:
|
|
+ msg = "Tried to execute `%s`\nTry specifying path to vsftpd via PYCURL_VSFTPD_PATH environment variable\n" % vsftpd_path
|
|
+ raise OSError(e.errno, e.strerror + "\n" + msg)
|
|
+ else:
|
|
+ raise
|
|
ok = runwsgi.wait_for_network_service(('127.0.0.1', 8321), 0.1, 10)
|
|
if not ok:
|
|
import warnings
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c42d5555e33105b8ea2317e63ac4b80b0c152be9 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Mon, 11 Mar 2013 22:22:02 -0400
|
|
Subject: [PATCH 088/112] Delete -1 timer assertion from multi timer test (closes #19)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_timer_test.py | 6 ++++--
|
|
1 files changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/multi_timer_test.py b/tests/multi_timer_test.py
|
|
index c4b3df4..ff856d7 100644
|
|
--- a/tests/multi_timer_test.py
|
|
+++ b/tests/multi_timer_test.py
|
|
@@ -80,8 +80,10 @@ class MultiSocketTest(unittest.TestCase):
|
|
# libcurl 7.23.0 produces a 0 timer
|
|
assert timers[0] >= 0
|
|
# this assertion does not appear to hold on older libcurls
|
|
- if not util.pycurl_version_less_than(7, 24):
|
|
- self.assertEqual(-1, timers[-1])
|
|
+ # or apparently on any linuxes, see
|
|
+ # https://github.com/p/pycurl/issues/19
|
|
+ #if not util.pycurl_version_less_than(7, 24):
|
|
+ # self.assertEqual(-1, timers[-1])
|
|
|
|
# close handles
|
|
for c in m.handles:
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From ccc7c66b76cef1ad3a00448d08f4aec7e21eaf69 Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Mon, 11 Mar 2013 14:00:04 +0100
|
|
Subject: [PATCH 089/112] remove .cvsignore files, add *.pyc and *.pyo to .gitignore
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.gitignore | 2 ++
|
|
1 files changed, 2 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/.gitignore b/.gitignore
|
|
index 796b96d..899daba 100644
|
|
--- a/.gitignore
|
|
+++ b/.gitignore
|
|
@@ -1 +1,3 @@
|
|
+*.pyc
|
|
+*.pyo
|
|
/build
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From bed41e852cb37b23b2cfc4513b701f3463a97c86 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Mon, 11 Mar 2013 22:40:12 -0400
|
|
Subject: [PATCH 090/112] Readd cvsignore contents and empty directories
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
.gitignore | 6 ++++++
|
|
1 files changed, 6 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/.gitignore b/.gitignore
|
|
index 899daba..c873e32 100644
|
|
--- a/.gitignore
|
|
+++ b/.gitignore
|
|
@@ -1,3 +1,9 @@
|
|
*.pyc
|
|
*.pyo
|
|
+/MANIFEST
|
|
/build
|
|
+/dist
|
|
+/www/htdocs/download/*.bz2
|
|
+/www/htdocs/download/*.exe
|
|
+/www/htdocs/download/*.gz
|
|
+/www/upload/*
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 49e560395f55efa3bb9ec09f44b5c893f0571404 Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Mon, 11 Mar 2013 14:03:06 +0100
|
|
Subject: [PATCH 091/112] vsftpd.conf: add background=no to allow for proper shutdown
|
|
|
|
When the "background" directive in the vsftpd.conf configuration file is
|
|
set to "YES", the vsftpd startup script forks, creating a child process
|
|
(the vsftpd daemon) which immediately sends the SIGUSR1 signal to its
|
|
parent process, which exits upon receiving it. The teardown routine in
|
|
procmgr.py would then send the SIGTERM signal to a process that does not
|
|
exist anymore.
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/vsftpd.conf | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/tests/vsftpd.conf b/tests/vsftpd.conf
|
|
index 0abb39f..b4e4972 100644
|
|
--- a/tests/vsftpd.conf
|
|
+++ b/tests/vsftpd.conf
|
|
@@ -1,5 +1,6 @@
|
|
anon_world_readable_only=yes
|
|
anonymous_enable=yes
|
|
+background=no
|
|
# currently we only list files
|
|
download_enable=no
|
|
listen=yes
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 2d1e91297f6d56286b9172090e6c16d9e509de0a Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Tue, 26 Feb 2013 14:49:47 +0100
|
|
Subject: [PATCH 092/112] pycurl.c: eliminate duplicated code in util_write_callback()
|
|
|
|
Suggested by Zdenek Pavlas <https://bugzilla.redhat.com/857875#c8>.
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 10 +---------
|
|
1 files changed, 1 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index 094bc60..f701543 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -1082,15 +1082,7 @@ util_write_callback(int flags, char *ptr, size_t size, size_t nmemb, void *strea
|
|
if (result == Py_None) {
|
|
ret = total_size; /* None means success */
|
|
}
|
|
- else if (PyInt_Check(result)) {
|
|
- long obj_size = PyInt_AsLong(result);
|
|
- if (obj_size < 0 || obj_size > total_size) {
|
|
- PyErr_Format(ErrorObject, "invalid return value for write callback %ld %ld", (long)obj_size, (long)total_size);
|
|
- goto verbose_error;
|
|
- }
|
|
- ret = (size_t) obj_size; /* success */
|
|
- }
|
|
- else if (PyLong_Check(result)) {
|
|
+ else if (PyInt_Check(result) || PyLong_Check(result)) {
|
|
long obj_size = PyLong_AsLong(result);
|
|
if (obj_size < 0 || obj_size > total_size) {
|
|
PyErr_Format(ErrorObject, "invalid return value for write callback %ld %ld", (long)obj_size, (long)total_size);
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From a3ab87495c91bf9b88ed5b8e8b4369d7adab96c2 Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Tue, 26 Feb 2013 16:58:55 +0100
|
|
Subject: [PATCH 093/112] pycurl.c: allow to return -1 from write callback
|
|
|
|
... to abort the transfer and WRITEFUNC_PAUSE to pause the transfer
|
|
|
|
Reported By: Zdenek Pavlas
|
|
Bug: https://bugzilla.redhat.com/857875
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 11 +++++------
|
|
1 files changed, 5 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index f701543..a30c339 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -1083,12 +1083,8 @@ util_write_callback(int flags, char *ptr, size_t size, size_t nmemb, void *strea
|
|
ret = total_size; /* None means success */
|
|
}
|
|
else if (PyInt_Check(result) || PyLong_Check(result)) {
|
|
- long obj_size = PyLong_AsLong(result);
|
|
- if (obj_size < 0 || obj_size > total_size) {
|
|
- PyErr_Format(ErrorObject, "invalid return value for write callback %ld %ld", (long)obj_size, (long)total_size);
|
|
- goto verbose_error;
|
|
- }
|
|
- ret = (size_t) obj_size; /* success */
|
|
+ /* if the cast to long fails, PyLong_AsLong() returns -1L */
|
|
+ ret = (size_t) PyLong_AsLong(result);
|
|
}
|
|
else {
|
|
PyErr_SetString(ErrorObject, "write callback must return int or None");
|
|
@@ -3509,6 +3505,9 @@ initpycurl(void)
|
|
/* Abort curl_read_callback(). */
|
|
insint_c(d, "READFUNC_ABORT", CURL_READFUNC_ABORT);
|
|
|
|
+ /* Pause curl_write_callback(). */
|
|
+ insint_c(d, "WRITEFUNC_PAUSE", CURL_WRITEFUNC_PAUSE);
|
|
+
|
|
/* constants for ioctl callback return values */
|
|
insint_c(d, "IOE_OK", CURLIOE_OK);
|
|
insint_c(d, "IOE_UNKNOWNCMD", CURLIOE_UNKNOWNCMD);
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 1ca0c365f45526d625fe79475c74b92818e9889d Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Wed, 6 Mar 2013 14:38:01 +0100
|
|
Subject: [PATCH 094/112] write_abort_test.py: test returning -1 from write callback
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/write_abort_test.py | 35 +++++++++++++++++++++++++++++++++++
|
|
1 files changed, 35 insertions(+), 0 deletions(-)
|
|
create mode 100755 tests/write_abort_test.py
|
|
|
|
diff --git a/tests/write_abort_test.py b/tests/write_abort_test.py
|
|
new file mode 100755
|
|
index 0000000..73e8245
|
|
--- /dev/null
|
|
+++ b/tests/write_abort_test.py
|
|
@@ -0,0 +1,35 @@
|
|
+#!/usr/bin/python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import os.path
|
|
+import pycurl
|
|
+import sys
|
|
+import unittest
|
|
+
|
|
+class WriteAbortTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ pycurl.global_init(pycurl.GLOBAL_DEFAULT)
|
|
+
|
|
+ def tearDown(self):
|
|
+ pycurl.global_cleanup()
|
|
+
|
|
+ def test_write_abort(self):
|
|
+ def write_cb(_):
|
|
+ # this should cause pycurl.WRITEFUNCTION (without any range errors)
|
|
+ return -1
|
|
+
|
|
+ # download the script itself through the file:// protocol into write_cb
|
|
+ c = pycurl.Curl()
|
|
+ c.setopt(pycurl.URL, 'file://' + os.path.abspath(sys.argv[0]))
|
|
+ c.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
+ try:
|
|
+ c.perform()
|
|
+ except pycurl.error, (err, msg):
|
|
+ # we expect pycurl.E_WRITE_ERROR as the response
|
|
+ assert pycurl.E_WRITE_ERROR == err
|
|
+
|
|
+ # no additional errors should be reported
|
|
+ assert not hasattr(sys, 'last_value')
|
|
+
|
|
+ c.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 671bb961f3c16821684ac92f1ae6de9138b92d0f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Mon, 11 Mar 2013 23:48:10 -0400
|
|
Subject: [PATCH 095/112] setup/teardown consistent with other tests
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/write_abort_test.py | 13 +++++--------
|
|
1 files changed, 5 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/tests/write_abort_test.py b/tests/write_abort_test.py
|
|
index 73e8245..f720882 100755
|
|
--- a/tests/write_abort_test.py
|
|
+++ b/tests/write_abort_test.py
|
|
@@ -9,10 +9,10 @@ import unittest
|
|
|
|
class WriteAbortTest(unittest.TestCase):
|
|
def setUp(self):
|
|
- pycurl.global_init(pycurl.GLOBAL_DEFAULT)
|
|
+ self.curl = pycurl.Curl()
|
|
|
|
def tearDown(self):
|
|
- pycurl.global_cleanup()
|
|
+ self.curl.close()
|
|
|
|
def test_write_abort(self):
|
|
def write_cb(_):
|
|
@@ -20,16 +20,13 @@ class WriteAbortTest(unittest.TestCase):
|
|
return -1
|
|
|
|
# download the script itself through the file:// protocol into write_cb
|
|
- c = pycurl.Curl()
|
|
- c.setopt(pycurl.URL, 'file://' + os.path.abspath(sys.argv[0]))
|
|
- c.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
+ self.curl.setopt(pycurl.URL, 'file://' + os.path.abspath(sys.argv[0]))
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
try:
|
|
- c.perform()
|
|
+ self.curl.perform()
|
|
except pycurl.error, (err, msg):
|
|
# we expect pycurl.E_WRITE_ERROR as the response
|
|
assert pycurl.E_WRITE_ERROR == err
|
|
|
|
# no additional errors should be reported
|
|
assert not hasattr(sys, 'last_value')
|
|
-
|
|
- c.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 0ddb01d99c34fa5ae7581697edeb2de49decc442 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Mon, 11 Mar 2013 23:48:41 -0400
|
|
Subject: [PATCH 096/112] Correct shebang
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/write_abort_test.py | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/write_abort_test.py b/tests/write_abort_test.py
|
|
index f720882..3272961 100755
|
|
--- a/tests/write_abort_test.py
|
|
+++ b/tests/write_abort_test.py
|
|
@@ -1,4 +1,4 @@
|
|
-#!/usr/bin/python
|
|
+#! /usr/bin/env python
|
|
# -*- coding: iso-8859-1 -*-
|
|
# vi:ts=4:et
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 165d6e5e332a20ceca178b105aa165aa6873b662 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Mon, 11 Mar 2013 23:56:36 -0400
|
|
Subject: [PATCH 097/112] Check that bogus return values from write callback are correctly handled (still)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/write_cb_bogus_test.py | 44 ++++++++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 44 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/write_cb_bogus_test.py
|
|
|
|
diff --git a/tests/write_cb_bogus_test.py b/tests/write_cb_bogus_test.py
|
|
new file mode 100644
|
|
index 0000000..4bec2ad
|
|
--- /dev/null
|
|
+++ b/tests/write_cb_bogus_test.py
|
|
@@ -0,0 +1,44 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import os.path
|
|
+import pycurl
|
|
+import sys
|
|
+import unittest
|
|
+
|
|
+class WriteAbortTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def write_cb_returning_string(self, data):
|
|
+ return 'foo'
|
|
+
|
|
+ def write_cb_returning_float(self, data):
|
|
+ return 0.5
|
|
+
|
|
+ def test_write_cb_returning_string(self):
|
|
+ self.check(self.write_cb_returning_string)
|
|
+
|
|
+ def test_write_cb_returning_float(self):
|
|
+ self.check(self.write_cb_returning_float)
|
|
+
|
|
+ def check(self, write_cb):
|
|
+ # download the script itself through the file:// protocol into write_cb
|
|
+ c = pycurl.Curl()
|
|
+ self.curl.setopt(pycurl.URL, 'file://' + os.path.abspath(sys.argv[0]))
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
+ try:
|
|
+ self.curl.perform()
|
|
+ except pycurl.error, (err, msg):
|
|
+ # we expect pycurl.E_WRITE_ERROR as the response
|
|
+ assert pycurl.E_WRITE_ERROR == err
|
|
+
|
|
+ # actual error
|
|
+ assert hasattr(sys, 'last_type')
|
|
+ self.assertEqual(pycurl.error, sys.last_type)
|
|
+ assert hasattr(sys, 'last_value')
|
|
+ self.assertEqual('write callback must return int or None', str(sys.last_value))
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From cafe4e74ebd12a2c571319e0cfeb6d64f48abe08 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 12 Mar 2013 00:00:40 -0400
|
|
Subject: [PATCH 098/112] Fix mode on write abort test
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
0 files changed, 0 insertions(+), 0 deletions(-)
|
|
mode change 100755 => 100644 tests/write_abort_test.py
|
|
|
|
diff --git a/tests/write_abort_test.py b/tests/write_abort_test.py
|
|
old mode 100755
|
|
new mode 100644
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From c84e139df96307aff908f69949cbe123fc40a14f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 12 Mar 2013 00:02:56 -0400
|
|
Subject: [PATCH 099/112] This test fails intermittently, add diagnostics
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/multi_socket_select_test.py | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/multi_socket_select_test.py b/tests/multi_socket_select_test.py
|
|
index 6db8b44..9546169 100644
|
|
--- a/tests/multi_socket_select_test.py
|
|
+++ b/tests/multi_socket_select_test.py
|
|
@@ -94,7 +94,7 @@ class MultiSocketSelectTest(unittest.TestCase):
|
|
c.http_code = c.getinfo(c.HTTP_CODE)
|
|
|
|
# at least in and remove events per socket
|
|
- assert len(socket_events) >= 6
|
|
+ assert len(socket_events) >= 6, 'Less than 6 socket events: %s' % repr(socket_events)
|
|
|
|
# print result
|
|
for c in m.handles:
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 47db8853813888148a4bc91754de8a83de4e8c0b Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 12 Mar 2013 22:43:47 -0400
|
|
Subject: [PATCH 100/112] Python 2.5 compatibility: socket.create_connection
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/runwsgi.py | 14 +++++++++++++-
|
|
1 files changed, 13 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
index 8a978ec..be05dfa 100644
|
|
--- a/tests/runwsgi.py
|
|
+++ b/tests/runwsgi.py
|
|
@@ -6,6 +6,18 @@ import threading
|
|
import socket
|
|
import time as _time
|
|
|
|
+try:
|
|
+ create_connection = socket.create_connection
|
|
+except AttributeError:
|
|
+ # python 2.5
|
|
+ def create_connection(netloc, timeout=None):
|
|
+ # XXX ipv4 only
|
|
+ s = socket.socket()
|
|
+ if timeout is not None:
|
|
+ s.settimeout(timeout)
|
|
+ s.connect(netloc)
|
|
+ return s
|
|
+
|
|
class Server(bottle.WSGIRefServer):
|
|
def run(self, handler): # pragma: no cover
|
|
from wsgiref.simple_server import make_server, WSGIRequestHandler
|
|
@@ -21,7 +33,7 @@ def wait_for_network_service(netloc, check_interval, num_attempts):
|
|
ok = False
|
|
for i in range(num_attempts):
|
|
try:
|
|
- conn = socket.create_connection(netloc, check_interval)
|
|
+ conn = create_connection(netloc, check_interval)
|
|
except socket.error:
|
|
e = sys.exc_info()[1]
|
|
_time.sleep(check_interval)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 94f689b61e1675f3ab9b4cc74ad53ae960d0a1b0 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 12 Mar 2013 22:55:08 -0400
|
|
Subject: [PATCH 101/112] Python 2.5 compatibility: poll_interval in SocketServer
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/runwsgi.py | 17 +++++++++++++++--
|
|
1 files changed, 15 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/runwsgi.py b/tests/runwsgi.py
|
|
index be05dfa..114ce42 100644
|
|
--- a/tests/runwsgi.py
|
|
+++ b/tests/runwsgi.py
|
|
@@ -18,6 +18,8 @@ except AttributeError:
|
|
s.connect(netloc)
|
|
return s
|
|
|
|
+global_stop = False
|
|
+
|
|
class Server(bottle.WSGIRefServer):
|
|
def run(self, handler): # pragma: no cover
|
|
from wsgiref.simple_server import make_server, WSGIRequestHandler
|
|
@@ -27,7 +29,13 @@ class Server(bottle.WSGIRefServer):
|
|
def log_request(*args, **kw): pass
|
|
self.options['handler_class'] = QuietHandler
|
|
self.srv = make_server(self.host, self.port, handler, **self.options)
|
|
- self.srv.serve_forever(poll_interval=0.1)
|
|
+ if sys.version_info[0] == 2 and sys.version_info[1] < 6:
|
|
+ # python 2.5 has no poll_interval
|
|
+ # and thus no way to stop the server
|
|
+ while not global_stop:
|
|
+ self.srv.handle_request()
|
|
+ else:
|
|
+ self.srv.serve_forever(poll_interval=0.1)
|
|
|
|
def wait_for_network_service(netloc, check_interval, num_attempts):
|
|
ok = False
|
|
@@ -104,6 +112,11 @@ def app_runner_setup(*specs):
|
|
for server in self.servers:
|
|
# if no tests from module were run, there is no server to shut down
|
|
if hasattr(server, 'srv'):
|
|
- server.srv.shutdown()
|
|
+ if hasattr(server.srv, 'shutdown'):
|
|
+ server.srv.shutdown()
|
|
+ else:
|
|
+ # python 2.5
|
|
+ global global_stop
|
|
+ global_stop = True
|
|
|
|
return [setup, teardown]
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From d8dda1c31521d338b9119dd679c25257232a8656 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 15 Mar 2013 12:28:11 -0400
|
|
Subject: [PATCH 102/112] Tests do not call global cleanup for now
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/reset_test.py | 2 --
|
|
1 files changed, 0 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/reset_test.py b/tests/reset_test.py
|
|
index cc55f86..61a692a 100644
|
|
--- a/tests/reset_test.py
|
|
+++ b/tests/reset_test.py
|
|
@@ -72,5 +72,3 @@ class ResetTest(unittest.TestCase):
|
|
eh.close()
|
|
cm.close()
|
|
outf.close()
|
|
-
|
|
- pycurl.global_cleanup()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 8e307f81488c66a02516204cb7566f159b065371 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 15 Mar 2013 17:01:35 -0400
|
|
Subject: [PATCH 103/112] Python 3 compatibility: except syntax
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/write_abort_test.py | 3 ++-
|
|
tests/write_cb_bogus_test.py | 3 ++-
|
|
2 files changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/write_abort_test.py b/tests/write_abort_test.py
|
|
index 3272961..957fe78 100644
|
|
--- a/tests/write_abort_test.py
|
|
+++ b/tests/write_abort_test.py
|
|
@@ -24,7 +24,8 @@ class WriteAbortTest(unittest.TestCase):
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
try:
|
|
self.curl.perform()
|
|
- except pycurl.error, (err, msg):
|
|
+ except pycurl.error:
|
|
+ err, msg = sys.exc_info()[1]
|
|
# we expect pycurl.E_WRITE_ERROR as the response
|
|
assert pycurl.E_WRITE_ERROR == err
|
|
|
|
diff --git a/tests/write_cb_bogus_test.py b/tests/write_cb_bogus_test.py
|
|
index 4bec2ad..ef709db 100644
|
|
--- a/tests/write_cb_bogus_test.py
|
|
+++ b/tests/write_cb_bogus_test.py
|
|
@@ -33,7 +33,8 @@ class WriteAbortTest(unittest.TestCase):
|
|
self.curl.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
try:
|
|
self.curl.perform()
|
|
- except pycurl.error, (err, msg):
|
|
+ except pycurl.error:
|
|
+ err, msg = sys.exc_info()[1]
|
|
# we expect pycurl.E_WRITE_ERROR as the response
|
|
assert pycurl.E_WRITE_ERROR == err
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From f1674b26ef4094d20c46dbfc0cb7ae3026fce525 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 15 Mar 2013 21:21:50 -0400
|
|
Subject: [PATCH 104/112] Python 3 compatibility: map
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
tests/util.py | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/tests/util.py b/tests/util.py
|
|
index b8e22ec..1e9f406 100644
|
|
--- a/tests/util.py
|
|
+++ b/tests/util.py
|
|
@@ -24,7 +24,7 @@ def version_less_than_spec(version_tuple, spec_tuple):
|
|
return False
|
|
|
|
def pycurl_version_less_than(*spec):
|
|
- version = map(int, pycurl.version_info()[1].split('.'))
|
|
+ version = [int(part) for part in pycurl.version_info()[1].split('.')]
|
|
return version_less_than_spec(version, spec)
|
|
|
|
#
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 5797557b27a19c247967f8fc3cf8b1068139fecf Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Fri, 15 Mar 2013 21:27:58 -0400
|
|
Subject: [PATCH 105/112] Python 3 compatibility: apply no longer exists
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
python/curl/__init__.py | 4 ++--
|
|
setup.py | 3 +--
|
|
setup_win32_ssl.py | 2 +-
|
|
3 files changed, 4 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/python/curl/__init__.py b/python/curl/__init__.py
|
|
index b002618..5b6b549 100644
|
|
--- a/python/curl/__init__.py
|
|
+++ b/python/curl/__init__.py
|
|
@@ -63,7 +63,7 @@ class Curl:
|
|
|
|
def set_option(self, *args):
|
|
"Set an option on the retrieval."
|
|
- apply(self.handle.setopt, args)
|
|
+ self.handle.setopt(*args)
|
|
|
|
def set_verbosity(self, level):
|
|
"Set verbosity to 1 to see transactions."
|
|
@@ -103,7 +103,7 @@ class Curl:
|
|
|
|
def get_info(self, *args):
|
|
"Get information about retrieval."
|
|
- return apply(self.handle.getinfo, args)
|
|
+ return self.handle.getinfo(*args)
|
|
|
|
def info(self):
|
|
"Return a dictionary with all info on the last response."
|
|
diff --git a/setup.py b/setup.py
|
|
index 235e4c9..013bd11 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -221,5 +221,4 @@ if LooseVersion(distutils.__version__) < LooseVersion("1.0.3"):
|
|
if __name__ == "__main__":
|
|
for o in ext.extra_objects:
|
|
assert os.path.isfile(o), o
|
|
- # We can live with the deprecationwarning for a while
|
|
- apply(setup, (), setup_args)
|
|
+ setup(**setup_args)
|
|
diff --git a/setup_win32_ssl.py b/setup_win32_ssl.py
|
|
index 332c04c..0ecc399 100644
|
|
--- a/setup_win32_ssl.py
|
|
+++ b/setup_win32_ssl.py
|
|
@@ -32,5 +32,5 @@ ext.extra_objects.append(r"c:\src\pool\libidn-0.5.15" + pool + "idn.lib")
|
|
if __name__ == "__main__":
|
|
for o in ext.extra_objects:
|
|
assert os.path.isfile(o), o
|
|
- apply(setup, (), setup_args)
|
|
+ setup(**setup_args)
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 94c63e7fe049d893a455b944c0deebe0f0c3ed37 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 26 Feb 2013 16:40:28 -0500
|
|
Subject: [PATCH 106/112] Python 3 compatibility: exception raising syntax
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
setup.py | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/setup.py b/setup.py
|
|
index 013bd11..725007c 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -108,7 +108,7 @@ else:
|
|
if p.wait() == 0:
|
|
optbuf += stdout
|
|
if optbuf == "":
|
|
- raise Exception, ("Neither of curl-config --libs or --static-libs" +
|
|
+ raise Exception("Neither of curl-config --libs or --static-libs" +
|
|
"produced output")
|
|
libs = split_quoted(optbuf)
|
|
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 530d280486742612cdbf7b306ce20e0200195adc Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 27 Feb 2013 20:23:28 -0500
|
|
Subject: [PATCH 107/112] Python 3 compatibility: print syntax (src)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
python/curl/__init__.py | 8 ++++----
|
|
1 files changed, 4 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/python/curl/__init__.py b/python/curl/__init__.py
|
|
index 5b6b549..5617262 100644
|
|
--- a/python/curl/__init__.py
|
|
+++ b/python/curl/__init__.py
|
|
@@ -164,10 +164,10 @@ if __name__ == "__main__":
|
|
url = sys.argv[1]
|
|
c = Curl()
|
|
c.get(url)
|
|
- print c.body()
|
|
- print '='*74 + '\n'
|
|
+ print(c.body())
|
|
+ print('='*74 + '\n')
|
|
import pprint
|
|
pprint.pprint(c.info())
|
|
- print c.get_info(pycurl.OS_ERRNO)
|
|
- print c.info()['os-errno']
|
|
+ print(c.get_info(pycurl.OS_ERRNO))
|
|
+ print(c.info()['os-errno'])
|
|
c.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 8f47e45b2814f03400f5f42aa67527147981b67f Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Tue, 26 Feb 2013 16:49:09 -0500
|
|
Subject: [PATCH 108/112] Python 3 compatibility: print syntax (former tests)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
examples/tests/test_gtk.py | 2 +-
|
|
examples/tests/test_xmlrpc.py | 2 +-
|
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/examples/tests/test_gtk.py b/examples/tests/test_gtk.py
|
|
index 7104439..da8c22a 100644
|
|
--- a/examples/tests/test_gtk.py
|
|
+++ b/examples/tests/test_gtk.py
|
|
@@ -83,7 +83,7 @@ class Test(threading.Thread):
|
|
|
|
# Check command line args
|
|
if len(sys.argv) < 3:
|
|
- print "Usage: %s <URL> <filename>" % sys.argv[0]
|
|
+ print("Usage: %s <URL> <filename>" % sys.argv[0])
|
|
raise SystemExit
|
|
|
|
# Make a progress bar window
|
|
diff --git a/examples/tests/test_xmlrpc.py b/examples/tests/test_xmlrpc.py
|
|
index bc5953e..3a5469a 100644
|
|
--- a/examples/tests/test_xmlrpc.py
|
|
+++ b/examples/tests/test_xmlrpc.py
|
|
@@ -24,6 +24,6 @@ c.setopt(c.POST, 1)
|
|
c.setopt(c.HTTPHEADER, xmlrpc_header)
|
|
c.setopt(c.POSTFIELDS, xmlrpc_template % ("examples.getStateName", xmlrpclib.dumps((5,))))
|
|
|
|
-print 'Response from http://betty.userland.com/'
|
|
+print('Response from http://betty.userland.com/')
|
|
c.perform()
|
|
c.close()
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From a69c0133c05d1a8b059514b58c369f69db53faa9 Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Wed, 27 Feb 2013 20:23:39 -0500
|
|
Subject: [PATCH 109/112] Python 3 compatibility: print syntax (examples)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
examples/basicfirst.py | 4 +-
|
|
examples/file_upload.py | 6 +-
|
|
examples/linksys.py | 182 +++++++++++++++++++++---------------------
|
|
examples/retriever-multi.py | 10 +-
|
|
examples/retriever.py | 6 +-
|
|
examples/sfquery.py | 2 +-
|
|
examples/xmlrpc_curl.py | 6 +-
|
|
7 files changed, 108 insertions(+), 108 deletions(-)
|
|
|
|
diff --git a/examples/basicfirst.py b/examples/basicfirst.py
|
|
index af59405..44060af 100644
|
|
--- a/examples/basicfirst.py
|
|
+++ b/examples/basicfirst.py
|
|
@@ -13,7 +13,7 @@ class Test:
|
|
def body_callback(self, buf):
|
|
self.contents = self.contents + buf
|
|
|
|
-print >>sys.stderr, 'Testing', pycurl.version
|
|
+sys.stderr.write("Testing %s\n" % pycurl.version)
|
|
|
|
t = Test()
|
|
c = pycurl.Curl()
|
|
@@ -22,4 +22,4 @@ c.setopt(c.WRITEFUNCTION, t.body_callback)
|
|
c.perform()
|
|
c.close()
|
|
|
|
-print t.contents
|
|
+print(t.contents)
|
|
diff --git a/examples/file_upload.py b/examples/file_upload.py
|
|
index a514c1c..7750865 100644
|
|
--- a/examples/file_upload.py
|
|
+++ b/examples/file_upload.py
|
|
@@ -15,13 +15,13 @@ class FileReader:
|
|
|
|
# Check commandline arguments
|
|
if len(sys.argv) < 3:
|
|
- print "Usage: %s <url> <file to upload>" % sys.argv[0]
|
|
+ print("Usage: %s <url> <file to upload>" % sys.argv[0])
|
|
raise SystemExit
|
|
url = sys.argv[1]
|
|
filename = sys.argv[2]
|
|
|
|
if not os.path.exists(filename):
|
|
- print "Error: the file '%s' does not exist" % filename
|
|
+ print("Error: the file '%s' does not exist" % filename)
|
|
raise SystemExit
|
|
|
|
# Initialize pycurl
|
|
@@ -41,6 +41,6 @@ filesize = os.path.getsize(filename)
|
|
c.setopt(pycurl.INFILESIZE, filesize)
|
|
|
|
# Start transfer
|
|
-print 'Uploading file %s to url %s' % (filename, url)
|
|
+print('Uploading file %s to url %s' % (filename, url))
|
|
c.perform()
|
|
c.close()
|
|
diff --git a/examples/linksys.py b/examples/linksys.py
|
|
index 5304886..24cb2a9 100755
|
|
--- a/examples/linksys.py
|
|
+++ b/examples/linksys.py
|
|
@@ -224,11 +224,11 @@ if __name__ == "__main__":
|
|
self.session = LinksysSession()
|
|
if os.isatty(0):
|
|
import readline
|
|
- print "Type ? or `help' for help."
|
|
+ print("Type ? or `help' for help.")
|
|
self.prompt = self.session.host + ": "
|
|
else:
|
|
self.prompt = ""
|
|
- print "Bar1"
|
|
+ print("Bar1")
|
|
|
|
def flag_command(self, func, line):
|
|
if line.strip() in ("on", "enable", "yes"):
|
|
@@ -246,96 +246,96 @@ if __name__ == "__main__":
|
|
self.session.cache_flush()
|
|
self.prompt = self.session.host + ": "
|
|
else:
|
|
- print self.session.host
|
|
+ print(self.session.host)
|
|
return 0
|
|
def help_connect(self):
|
|
- print "Usage: connect [<hostname-or-IP>]"
|
|
- print "Connect to a Linksys by name or IP address."
|
|
- print "If no argument is given, print the current host."
|
|
+ print("Usage: connect [<hostname-or-IP>]")
|
|
+ print("Connect to a Linksys by name or IP address.")
|
|
+ print("If no argument is given, print the current host.")
|
|
|
|
def do_status(self, line):
|
|
self.session.cache_load("")
|
|
if "" in self.session.pagecache:
|
|
- print "Firmware:", self.session.get_firmware_version()
|
|
- print "LAN MAC:", self.session.get_LAN_MAC()
|
|
- print "Wireless MAC:", self.session.get_Wireless_MAC()
|
|
- print "WAN MAC:", self.session.get_WAN_MAC()
|
|
- print "."
|
|
+ print("Firmware:", self.session.get_firmware_version())
|
|
+ print("LAN MAC:", self.session.get_LAN_MAC())
|
|
+ print("Wireless MAC:", self.session.get_Wireless_MAC())
|
|
+ print("WAN MAC:", self.session.get_WAN_MAC())
|
|
+ print(".")
|
|
return 0
|
|
def help_status(self):
|
|
- print "Usage: status"
|
|
- print "The status command shows the status of the Linksys."
|
|
- print "It is mainly useful as a sanity check to make sure"
|
|
- print "the box is responding correctly."
|
|
+ print("Usage: status")
|
|
+ print("The status command shows the status of the Linksys.")
|
|
+ print("It is mainly useful as a sanity check to make sure")
|
|
+ print("the box is responding correctly.")
|
|
|
|
def do_verbose(self, line):
|
|
self.flag_command(self.session.set_verbosity, line)
|
|
def help_verbose(self):
|
|
- print "Usage: verbose {on|off|enable|disable|yes|no}"
|
|
- print "Enables display of HTTP requests."
|
|
+ print("Usage: verbose {on|off|enable|disable|yes|no}")
|
|
+ print("Enables display of HTTP requests.")
|
|
|
|
def do_host(self, line):
|
|
self.session.set_host_name(line)
|
|
return 0
|
|
def help_host(self):
|
|
- print "Usage: host <hostname>"
|
|
- print "Sets the Host field to be queried by the ISP."
|
|
+ print("Usage: host <hostname>")
|
|
+ print("Sets the Host field to be queried by the ISP.")
|
|
|
|
def do_domain(self, line):
|
|
- print "Usage: host <domainname>"
|
|
+ print("Usage: host <domainname>")
|
|
self.session.set_domain_name(line)
|
|
return 0
|
|
def help_domain(self):
|
|
- print "Sets the Domain field to be queried by the ISP."
|
|
+ print("Sets the Domain field to be queried by the ISP.")
|
|
|
|
def do_lan_address(self, line):
|
|
self.session.set_LAN_IP(line)
|
|
return 0
|
|
def help_lan_address(self):
|
|
- print "Usage: lan_address <ip-address>"
|
|
- print "Sets the LAN IP address."
|
|
+ print("Usage: lan_address <ip-address>")
|
|
+ print("Sets the LAN IP address.")
|
|
|
|
def do_lan_netmask(self, line):
|
|
self.session.set_LAN_netmask(line)
|
|
return 0
|
|
def help_lan_netmask(self):
|
|
- print "Usage: lan_netmask <ip-mask>"
|
|
- print "Sets the LAN subnetwork mask."
|
|
+ print("Usage: lan_netmask <ip-mask>")
|
|
+ print("Sets the LAN subnetwork mask.")
|
|
|
|
def do_wireless(self, line):
|
|
self.flag_command(self.session.set_wireless, line)
|
|
return 0
|
|
def help_wireless(self):
|
|
- print "Usage: wireless {on|off|enable|disable|yes|no}"
|
|
- print "Switch to enable or disable wireless features."
|
|
+ print("Usage: wireless {on|off|enable|disable|yes|no}")
|
|
+ print("Switch to enable or disable wireless features.")
|
|
|
|
def do_ssid(self, line):
|
|
self.session.set_SSID(line)
|
|
return 0
|
|
def help_ssid(self):
|
|
- print "Usage: ssid <string>"
|
|
- print "Sets the SSID used to control wireless access."
|
|
+ print("Usage: ssid <string>")
|
|
+ print("Sets the SSID used to control wireless access.")
|
|
|
|
def do_ssid_broadcast(self, line):
|
|
self.flag_command(self.session.set_SSID_broadcast, line)
|
|
return 0
|
|
def help_ssid_broadcast(self):
|
|
- print "Usage: ssid_broadcast {on|off|enable|disable|yes|no}"
|
|
- print "Switch to enable or disable SSID broadcast."
|
|
+ print("Usage: ssid_broadcast {on|off|enable|disable|yes|no}")
|
|
+ print("Switch to enable or disable SSID broadcast.")
|
|
|
|
def do_channel(self, line):
|
|
self.session.set_channel(line)
|
|
return 0
|
|
def help_channel(self):
|
|
- print "Usage: channel <number>"
|
|
- print "Sets the wireless channel."
|
|
+ print("Usage: channel <number>")
|
|
+ print("Sets the wireless channel.")
|
|
|
|
def do_wep(self, line):
|
|
self.flag_command(self.session.set_WEP, line)
|
|
return 0
|
|
def help_wep(self):
|
|
- print "Usage: wep {on|off|enable|disable|yes|no}"
|
|
- print "Switch to enable or disable WEP security."
|
|
+ print("Usage: wep {on|off|enable|disable|yes|no}")
|
|
+ print("Switch to enable or disable WEP security.")
|
|
|
|
def do_wan_type(self, line):
|
|
try:
|
|
@@ -345,29 +345,29 @@ if __name__ == "__main__":
|
|
print >>sys.stderr, "linksys: unknown connection type."
|
|
return 0
|
|
def help_wan_type(self):
|
|
- print "Usage: wan_type {auto|static|ppoe|ras|pptp|heartbeat}"
|
|
- print "Set the WAN connection type."
|
|
+ print("Usage: wan_type {auto|static|ppoe|ras|pptp|heartbeat}")
|
|
+ print("Set the WAN connection type.")
|
|
|
|
def do_wan_address(self, line):
|
|
self.session.set_WAN_IP(line)
|
|
return 0
|
|
def help_wan_address(self):
|
|
- print "Usage: wan_address <ip-address>"
|
|
- print "Sets the WAN IP address."
|
|
+ print("Usage: wan_address <ip-address>")
|
|
+ print("Sets the WAN IP address.")
|
|
|
|
def do_wan_netmask(self, line):
|
|
self.session.set_WAN_netmask(line)
|
|
return 0
|
|
def help_wan_netmask(self):
|
|
- print "Usage: wan_netmask <ip-mask>"
|
|
- print "Sets the WAN subnetwork mask."
|
|
+ print("Usage: wan_netmask <ip-mask>")
|
|
+ print("Sets the WAN subnetwork mask.")
|
|
|
|
def do_wan_gateway(self, line):
|
|
self.session.set_WAN_gateway(line)
|
|
return 0
|
|
def help_wan_gateway(self):
|
|
- print "Usage: wan_gateway <ip-address>"
|
|
- print "Sets the LAN subnetwork mask."
|
|
+ print("Usage: wan_gateway <ip-address>")
|
|
+ print("Sets the LAN subnetwork mask.")
|
|
|
|
def do_dns(self, line):
|
|
(index, address) = line.split()
|
|
@@ -377,52 +377,52 @@ if __name__ == "__main__":
|
|
print >>sys.stderr, "linksys: server index out of bounds."
|
|
return 0
|
|
def help_dns(self):
|
|
- print "Usage: dns {1|2|3} <ip-mask>"
|
|
- print "Sets a primary, secondary, or tertiary DNS server address."
|
|
+ print("Usage: dns {1|2|3} <ip-mask>")
|
|
+ print("Sets a primary, secondary, or tertiary DNS server address.")
|
|
|
|
def do_password(self, line):
|
|
self.session.set_password(line)
|
|
return 0
|
|
def help_password(self):
|
|
- print "Usage: password <string>"
|
|
- print "Sets the router password."
|
|
+ print("Usage: password <string>")
|
|
+ print("Sets the router password.")
|
|
|
|
def do_upnp(self, line):
|
|
self.flag_command(self.session.set_UPnP, line)
|
|
return 0
|
|
def help_upnp(self):
|
|
- print "Usage: upnp {on|off|enable|disable|yes|no}"
|
|
- print "Switch to enable or disable Universal Plug and Play."
|
|
+ print("Usage: upnp {on|off|enable|disable|yes|no}")
|
|
+ print("Switch to enable or disable Universal Plug and Play.")
|
|
|
|
def do_reset(self, line):
|
|
self.session.reset()
|
|
def help_reset(self):
|
|
- print "Usage: reset"
|
|
- print "Reset Linksys settings to factory defaults."
|
|
+ print("Usage: reset")
|
|
+ print("Reset Linksys settings to factory defaults.")
|
|
|
|
def do_dhcp(self, line):
|
|
self.flag_command(self.session.set_DHCP, line)
|
|
def help_dhcp(self):
|
|
- print "Usage: dhcp {on|off|enable|disable|yes|no}"
|
|
- print "Switch to enable or disable DHCP features."
|
|
+ print("Usage: dhcp {on|off|enable|disable|yes|no}")
|
|
+ print("Switch to enable or disable DHCP features.")
|
|
|
|
def do_dhcp_start(self, line):
|
|
self.session.set_DHCP_starting_IP(line)
|
|
def help_dhcp_start(self):
|
|
- print "Usage: dhcp_start <number>"
|
|
- print "Set the start address of the DHCP pool."
|
|
+ print("Usage: dhcp_start <number>")
|
|
+ print("Set the start address of the DHCP pool.")
|
|
|
|
def do_dhcp_users(self, line):
|
|
self.session.set_DHCP_users(line)
|
|
def help_dhcp_users(self):
|
|
- print "Usage: dhcp_users <number>"
|
|
- print "Set number of address slots to allocate in the DHCP pool."
|
|
+ print("Usage: dhcp_users <number>")
|
|
+ print("Set number of address slots to allocate in the DHCP pool.")
|
|
|
|
def do_dhcp_lease(self, line):
|
|
self.session.set_DHCP_lease(line)
|
|
def help_dhcp_lease(self):
|
|
- print "Usage: dhcp_lease <number>"
|
|
- print "Set number of address slots to allocate in the DHCP pool."
|
|
+ print("Usage: dhcp_lease <number>")
|
|
+ print("Set number of address slots to allocate in the DHCP pool.")
|
|
|
|
def do_dhcp_dns(self, line):
|
|
(index, address) = line.split()
|
|
@@ -432,46 +432,46 @@ if __name__ == "__main__":
|
|
print >>sys.stderr, "linksys: server index out of bounds."
|
|
return 0
|
|
def help_dhcp_dns(self):
|
|
- print "Usage: dhcp_dns {1|2|3} <ip-mask>"
|
|
- print "Sets primary, secondary, or tertiary DNS server address."
|
|
+ print("Usage: dhcp_dns {1|2|3} <ip-mask>")
|
|
+ print("Sets primary, secondary, or tertiary DNS server address.")
|
|
|
|
def do_logging(self, line):
|
|
self.flag_command(self.session.set_logging, line)
|
|
def help_logging(self):
|
|
- print "Usage: logging {on|off|enable|disable|yes|no}"
|
|
- print "Switch to enable or disable session logging."
|
|
+ print("Usage: logging {on|off|enable|disable|yes|no}")
|
|
+ print("Switch to enable or disable session logging.")
|
|
|
|
def do_log_address(self, line):
|
|
self.session.set_Log_address(line)
|
|
def help_log_address(self):
|
|
- print "Usage: log_address <number>"
|
|
- print "Set the last quad of the address to which to log."
|
|
+ print("Usage: log_address <number>")
|
|
+ print("Set the last quad of the address to which to log.")
|
|
|
|
def do_configure(self, line):
|
|
self.session.configure()
|
|
return 0
|
|
def help_configure(self):
|
|
- print "Usage: configure"
|
|
- print "Writes the configuration to the Linksys."
|
|
+ print("Usage: configure")
|
|
+ print("Writes the configuration to the Linksys.")
|
|
|
|
def do_cache(self, line):
|
|
- print self.session.pagecache
|
|
+ print(self.session.pagecache)
|
|
def help_cache(self):
|
|
- print "Usage: cache"
|
|
- print "Display the page cache."
|
|
+ print("Usage: cache")
|
|
+ print("Display the page cache.")
|
|
|
|
def do_quit(self, line):
|
|
return 1
|
|
def help_quit(self, line):
|
|
- print "The quit command ends your linksys session without"
|
|
- print "writing configuration changes to the Linksys."
|
|
+ print("The quit command ends your linksys session without")
|
|
+ print("writing configuration changes to the Linksys.")
|
|
def do_EOF(self, line):
|
|
- print ""
|
|
+ print("")
|
|
self.session.configure()
|
|
return 1
|
|
def help_EOF(self):
|
|
- print "The EOF command writes the configuration to the linksys"
|
|
- print "and ends your session."
|
|
+ print("The EOF command writes the configuration to the linksys")
|
|
+ print("and ends your session.")
|
|
|
|
def default(self, line):
|
|
"""Pass the command through to be executed by the shell."""
|
|
@@ -479,11 +479,11 @@ if __name__ == "__main__":
|
|
return 0
|
|
|
|
def help_help(self):
|
|
- print "On-line help is available through this command."
|
|
- print "? is a convenience alias for help."
|
|
+ print("On-line help is available through this command.")
|
|
+ print("? is a convenience alias for help.")
|
|
|
|
def help_introduction(self):
|
|
- print """\
|
|
+ print("""\
|
|
|
|
This program supports changing the settings on Linksys blue-box routers. This
|
|
capability may come in handy when they freeze up and have to be reset. Though
|
|
@@ -506,16 +506,16 @@ will be shipped to the Linksys at the end of session (e.g. when the program
|
|
running in batch mode encounters end-of-file or you type a control-D). If you
|
|
end the session with `quit', pending changes will be discarded.
|
|
|
|
-For more help, read the topics 'wan', 'lan', and 'wireless'."""
|
|
+For more help, read the topics 'wan', 'lan', and 'wireless'.""")
|
|
|
|
def help_lan(self):
|
|
- print """\
|
|
+ print("""\
|
|
The `lan_address' and `lan_netmask' commands let you set the IP location of
|
|
the Linksys on your LAN, or inside. Normally you'll want to leave these
|
|
-untouched."""
|
|
+untouched.""")
|
|
|
|
def help_wan(self):
|
|
- print """\
|
|
+ print("""\
|
|
The WAN commands become significant if you are using the BEFSR41 or any of
|
|
the other Linksys boxes designed as DSL or cable-modem gateways. You will
|
|
need to use `wan_type' to declare how you expect to get your address.
|
|
@@ -527,22 +527,22 @@ need to use the `dns' command to declare which remote servers your DNS
|
|
requests should be forwarded to.
|
|
|
|
Some ISPs may require you to set host and domain for use with dynamic-address
|
|
-allocation."""
|
|
+allocation.""")
|
|
|
|
def help_wireless(self):
|
|
- print """\
|
|
+ print("""\
|
|
The channel, ssid, ssid_broadcast, wep, and wireless commands control
|
|
-wireless routing."""
|
|
+wireless routing.""")
|
|
|
|
def help_switches(self):
|
|
- print "Switches may be turned on with 'on', 'enable', or 'yes'."
|
|
- print "Switches may be turned off with 'off', 'disable', or 'no'."
|
|
- print "Switch commands include: wireless, ssid_broadcast."
|
|
+ print("Switches may be turned on with 'on', 'enable', or 'yes'.")
|
|
+ print("Switches may be turned off with 'off', 'disable', or 'no'.")
|
|
+ print("Switch commands include: wireless, ssid_broadcast.")
|
|
|
|
def help_addresses(self):
|
|
- print "An address argument must be a valid IP address;"
|
|
- print "four decimal numbers separated by dots, each "
|
|
- print "between 0 and 255."
|
|
+ print("An address argument must be a valid IP address;")
|
|
+ print("four decimal numbers separated by dots, each ")
|
|
+ print("between 0 and 255.")
|
|
|
|
def emptyline(self):
|
|
pass
|
|
diff --git a/examples/retriever-multi.py b/examples/retriever-multi.py
|
|
index 1a941be..ad4cebd 100644
|
|
--- a/examples/retriever-multi.py
|
|
+++ b/examples/retriever-multi.py
|
|
@@ -31,7 +31,7 @@ try:
|
|
if len(sys.argv) >= 3:
|
|
num_conn = int(sys.argv[2])
|
|
except:
|
|
- print "Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0]
|
|
+ print("Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0])
|
|
raise SystemExit
|
|
|
|
|
|
@@ -50,8 +50,8 @@ assert queue, "no URLs given"
|
|
num_urls = len(queue)
|
|
num_conn = min(num_conn, num_urls)
|
|
assert 1 <= num_conn <= 10000, "invalid number of concurrent connections"
|
|
-print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
|
|
-print "----- Getting", num_urls, "URLs using", num_conn, "connections -----"
|
|
+print("PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM))
|
|
+print("----- Getting", num_urls, "URLs using", num_conn, "connections -----")
|
|
|
|
|
|
# Pre-allocate a list of curl objects
|
|
@@ -95,13 +95,13 @@ while num_processed < num_urls:
|
|
c.fp.close()
|
|
c.fp = None
|
|
m.remove_handle(c)
|
|
- print "Success:", c.filename, c.url, c.getinfo(pycurl.EFFECTIVE_URL)
|
|
+ print("Success:", c.filename, c.url, c.getinfo(pycurl.EFFECTIVE_URL))
|
|
freelist.append(c)
|
|
for c, errno, errmsg in err_list:
|
|
c.fp.close()
|
|
c.fp = None
|
|
m.remove_handle(c)
|
|
- print "Failed: ", c.filename, c.url, errno, errmsg
|
|
+ print("Failed: ", c.filename, c.url, errno, errmsg)
|
|
freelist.append(c)
|
|
num_processed = num_processed + len(ok_list) + len(err_list)
|
|
if num_q == 0:
|
|
diff --git a/examples/retriever.py b/examples/retriever.py
|
|
index 2c91d07..be1b6ea 100644
|
|
--- a/examples/retriever.py
|
|
+++ b/examples/retriever.py
|
|
@@ -31,7 +31,7 @@ try:
|
|
if len(sys.argv) >= 3:
|
|
num_conn = int(sys.argv[2])
|
|
except:
|
|
- print "Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0]
|
|
+ print("Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0])
|
|
raise SystemExit
|
|
|
|
|
|
@@ -50,8 +50,8 @@ assert queue.queue, "no URLs given"
|
|
num_urls = len(queue.queue)
|
|
num_conn = min(num_conn, num_urls)
|
|
assert 1 <= num_conn <= 10000, "invalid number of concurrent connections"
|
|
-print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
|
|
-print "----- Getting", num_urls, "URLs using", num_conn, "connections -----"
|
|
+print("PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM))
|
|
+print("----- Getting", num_urls, "URLs using", num_conn, "connections -----")
|
|
|
|
|
|
class WorkerThread(threading.Thread):
|
|
diff --git a/examples/sfquery.py b/examples/sfquery.py
|
|
index 741feb0..16aa9d4 100644
|
|
--- a/examples/sfquery.py
|
|
+++ b/examples/sfquery.py
|
|
@@ -40,7 +40,7 @@ if __name__ == "__main__":
|
|
name, account, password = auth
|
|
except:
|
|
if len(sys.argv) < 4:
|
|
- print "Usage: %s <project id> <username> <password>" % sys.argv[0]
|
|
+ print("Usage: %s <project id> <username> <password>" % sys.argv[0])
|
|
raise SystemExit
|
|
name = sys.argv[2]
|
|
password = sys.argv[3]
|
|
diff --git a/examples/xmlrpc_curl.py b/examples/xmlrpc_curl.py
|
|
index ec0df50..a9a7d9e 100644
|
|
--- a/examples/xmlrpc_curl.py
|
|
+++ b/examples/xmlrpc_curl.py
|
|
@@ -55,8 +55,8 @@ if __name__ == "__main__":
|
|
## Test
|
|
server = xmlrpclib.ServerProxy("http://betty.userland.com",
|
|
transport=CURLTransport())
|
|
- print server
|
|
+ print(server)
|
|
try:
|
|
- print server.examples.getStateName(41)
|
|
+ print(server.examples.getStateName(41))
|
|
except xmlrpclib.Error, v:
|
|
- print "ERROR", v
|
|
+ print("ERROR", v)
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 41478f926b683d2141732936cad1855a7632552a Mon Sep 17 00:00:00 2001
|
|
From: Oleg Pudeyev <oleg@bsdpower.com>
|
|
Date: Thu, 28 Feb 2013 00:30:00 -0500
|
|
Subject: [PATCH 110/112] Python 3 compatibility: printing to stderr (linksys example)
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
examples/linksys.py | 14 +++++++++-----
|
|
1 files changed, 9 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/examples/linksys.py b/examples/linksys.py
|
|
index 24cb2a9..f66ff0d 100755
|
|
--- a/examples/linksys.py
|
|
+++ b/examples/linksys.py
|
|
@@ -34,6 +34,10 @@
|
|
|
|
import sys, re, copy, curl, exceptions
|
|
|
|
+def print_stderr(arg):
|
|
+ sys.stderr.write(arg)
|
|
+ sys.stderr.write("\n")
|
|
+
|
|
class LinksysError(exceptions.Exception):
|
|
def __init__(self, *args):
|
|
self.args = args
|
|
@@ -202,7 +206,7 @@ class LinksysSession:
|
|
for (page, field, value) in self.actions:
|
|
self.cache_load(page)
|
|
if self.pagecache[page].find(field) == -1:
|
|
- print >>sys.stderr, "linksys: field %s not found where expected in page %s!" % (field, os.path.join(self.host, page))
|
|
+ print_stderr("linksys: field %s not found where expected in page %s!" % (field, os.path.join(self.host, page)))
|
|
continue
|
|
else:
|
|
fields.append((field, value))
|
|
@@ -236,7 +240,7 @@ if __name__ == "__main__":
|
|
elif line.strip() in ("off", "disable", "no"):
|
|
func(False)
|
|
else:
|
|
- print >>sys.stderr, "linksys: unknown switch value"
|
|
+ print_stderr("linksys: unknown switch value")
|
|
return 0
|
|
|
|
def do_connect(self, line):
|
|
@@ -342,7 +346,7 @@ if __name__ == "__main__":
|
|
type=eval("LinksysSession.WAN_CONNECT_"+line.strip().upper())
|
|
self.session.set_connection_type(type)
|
|
except ValueError:
|
|
- print >>sys.stderr, "linksys: unknown connection type."
|
|
+ print_stderr("linksys: unknown connection type.")
|
|
return 0
|
|
def help_wan_type(self):
|
|
print("Usage: wan_type {auto|static|ppoe|ras|pptp|heartbeat}")
|
|
@@ -374,7 +378,7 @@ if __name__ == "__main__":
|
|
if index in ("1", "2", "3"):
|
|
self.session.set_DNS_server(eval(index), address)
|
|
else:
|
|
- print >>sys.stderr, "linksys: server index out of bounds."
|
|
+ print_stderr("linksys: server index out of bounds.")
|
|
return 0
|
|
def help_dns(self):
|
|
print("Usage: dns {1|2|3} <ip-mask>")
|
|
@@ -429,7 +433,7 @@ if __name__ == "__main__":
|
|
if index in ("1", "2", "3"):
|
|
self.session.set_DHCP_DNS_server(eval(index), address)
|
|
else:
|
|
- print >>sys.stderr, "linksys: server index out of bounds."
|
|
+ print_stderr("linksys: server index out of bounds.")
|
|
return 0
|
|
def help_dhcp_dns(self):
|
|
print("Usage: dhcp_dns {1|2|3} <ip-mask>")
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From a20b726b10b5e1bc27ba95808ef11154973b6403 Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Mon, 8 Apr 2013 14:25:26 +0200
|
|
Subject: [PATCH 111/112] allow to unset a previously set RANGE value
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
... and add the unset_range_test.py unit test exercising it
|
|
|
|
Reported by: Zdeněk Pavlas
|
|
Bug: https://bugzilla.redhat.com/928370
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 1 +
|
|
tests/unset_range_test.py | 39 +++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 40 insertions(+), 0 deletions(-)
|
|
create mode 100644 tests/unset_range_test.py
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index a30c339..bd28b81 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -1561,6 +1561,7 @@ util_curl_unsetopt(CurlObject *self, int option)
|
|
case CURLOPT_RANDOM_FILE:
|
|
case CURLOPT_SSL_CIPHER_LIST:
|
|
case CURLOPT_USERPWD:
|
|
+ case CURLOPT_RANGE:
|
|
SETOPT((char *) 0);
|
|
break;
|
|
|
|
diff --git a/tests/unset_range_test.py b/tests/unset_range_test.py
|
|
new file mode 100644
|
|
index 0000000..4400851
|
|
--- /dev/null
|
|
+++ b/tests/unset_range_test.py
|
|
@@ -0,0 +1,39 @@
|
|
+#! /usr/bin/env python
|
|
+# -*- coding: iso-8859-1 -*-
|
|
+# vi:ts=4:et
|
|
+
|
|
+import os.path
|
|
+import pycurl
|
|
+import sys
|
|
+import unittest
|
|
+
|
|
+class UnsetRangeTest(unittest.TestCase):
|
|
+ def setUp(self):
|
|
+ self.curl = pycurl.Curl()
|
|
+
|
|
+ def tearDown(self):
|
|
+ self.curl.close()
|
|
+
|
|
+ def test_unset_range(self):
|
|
+ def write_cb(data):
|
|
+ self.read += len(data)
|
|
+ return None
|
|
+
|
|
+ # download bytes 0-9 of the script itself through the file:// protocol
|
|
+ self.read = 0
|
|
+ self.curl.setopt(pycurl.URL, 'file://' + os.path.abspath(sys.argv[0]))
|
|
+ self.curl.setopt(pycurl.WRITEFUNCTION, write_cb)
|
|
+ self.curl.setopt(pycurl.RANGE, '0-9')
|
|
+ self.curl.perform()
|
|
+ assert 10 == self.read
|
|
+
|
|
+ # the RANGE setting should be preserved from the previous transfer
|
|
+ self.read = 0
|
|
+ self.curl.perform()
|
|
+ assert 10 == self.read
|
|
+
|
|
+ # drop the RANGE setting using unsetopt() and download entire script
|
|
+ self.read = 0
|
|
+ self.curl.unsetopt(pycurl.RANGE)
|
|
+ self.curl.perform()
|
|
+ assert 10 < self.read
|
|
--
|
|
1.7.1
|
|
|
|
|
|
From 6d43dc15185016b0e2dd993e18bd124f87554445 Mon Sep 17 00:00:00 2001
|
|
From: Kamil Dudka <kdudka@redhat.com>
|
|
Date: Mon, 8 Apr 2013 14:31:30 +0200
|
|
Subject: [PATCH 112/112] allow to use setopt(..., None) as unsetopt()
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
... and extend the unset_range_test.py unit test to exercise it
|
|
|
|
Reported by: Zdeněk Pavlas
|
|
Bug: https://bugzilla.redhat.com/928370
|
|
|
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
---
|
|
src/pycurl.c | 4 +---
|
|
tests/unset_range_test.py | 12 ++++++++++++
|
|
2 files changed, 13 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/src/pycurl.c b/src/pycurl.c
|
|
index bd28b81..619ca20 100644
|
|
--- a/src/pycurl.c
|
|
+++ b/src/pycurl.c
|
|
@@ -1631,12 +1631,10 @@ do_curl_setopt(CurlObject *self, PyObject *args)
|
|
if (option % 10000 >= OPTIONS_SIZE)
|
|
goto error;
|
|
|
|
-#if 0 /* XXX - should we ??? */
|
|
- /* Handle the case of None */
|
|
+ /* Handle the case of None as the call of unsetopt() */
|
|
if (obj == Py_None) {
|
|
return util_curl_unsetopt(self, option);
|
|
}
|
|
-#endif
|
|
|
|
/* Handle the case of string arguments */
|
|
if (PyString_Check(obj)) {
|
|
diff --git a/tests/unset_range_test.py b/tests/unset_range_test.py
|
|
index 4400851..10ee801 100644
|
|
--- a/tests/unset_range_test.py
|
|
+++ b/tests/unset_range_test.py
|
|
@@ -37,3 +37,15 @@ class UnsetRangeTest(unittest.TestCase):
|
|
self.curl.unsetopt(pycurl.RANGE)
|
|
self.curl.perform()
|
|
assert 10 < self.read
|
|
+
|
|
+ # now set the RANGE again and check that pycurl takes it into account
|
|
+ self.read = 0
|
|
+ self.curl.setopt(pycurl.RANGE, '0-9')
|
|
+ self.curl.perform()
|
|
+ assert 10 == self.read
|
|
+
|
|
+ # now drop the RANGE setting using setopt(..., None)
|
|
+ self.read = 0
|
|
+ self.curl.setopt(pycurl.RANGE, None)
|
|
+ self.curl.perform()
|
|
+ assert 10 < self.read
|
|
--
|
|
1.7.1
|
|
|