Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
9177c3af
Commit
9177c3af
authored
Dec 01, 2013
by
Denis Bilenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drop support for Python 2.5
parent
ed74f199
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
22 additions
and
6462 deletions
+22
-6462
.travis.yml
.travis.yml
+0
-2
README.rst
README.rst
+1
-1
doc/intro.rst
doc/intro.rst
+1
-1
gevent/monkey.py
gevent/monkey.py
+1
-8
gevent/pywsgi.py
gevent/pywsgi.py
+17
-40
gevent/socket.py
gevent/socket.py
+0
-15
gevent/ssl.py
gevent/ssl.py
+0
-4
gevent/timeout.py
gevent/timeout.py
+1
-14
greentest/2.5/test_httplib.py
greentest/2.5/test_httplib.py
+0
-172
greentest/2.5/test_queue.py
greentest/2.5/test_queue.py
+0
-281
greentest/2.5/test_select.py
greentest/2.5/test_select.py
+0
-70
greentest/2.5/test_signal.py
greentest/2.5/test_signal.py
+0
-167
greentest/2.5/test_socket.py
greentest/2.5/test_socket.py
+0
-1026
greentest/2.5/test_socket_ssl.py
greentest/2.5/test_socket_ssl.py
+0
-131
greentest/2.5/test_socketserver.py
greentest/2.5/test_socketserver.py
+0
-218
greentest/2.5/test_subprocess.py
greentest/2.5/test_subprocess.py
+0
-669
greentest/2.5/test_thread.py
greentest/2.5/test_thread.py
+0
-160
greentest/2.5/test_threading.py
greentest/2.5/test_threading.py
+0
-311
greentest/2.5/test_threading_local.py
greentest/2.5/test_threading_local.py
+0
-94
greentest/2.5/test_timeout.py
greentest/2.5/test_timeout.py
+0
-198
greentest/2.5/test_urllib.py
greentest/2.5/test_urllib.py
+0
-574
greentest/2.5/test_urllib2.py
greentest/2.5/test_urllib2.py
+0
-1087
greentest/2.5/test_urllib2_localnet.py
greentest/2.5/test_urllib2_localnet.py
+0
-301
greentest/2.5/test_urllib2net.py
greentest/2.5/test_urllib2net.py
+0
-295
greentest/2.5/test_wsgiref.py
greentest/2.5/test_wsgiref.py
+0
-615
greentest/2.5/version
greentest/2.5/version
+0
-1
known_failures.txt
known_failures.txt
+1
-6
setup.py
setup.py
+0
-1
No files found.
.travis.yml
View file @
9177c3af
...
...
@@ -6,7 +6,6 @@ env:
matrix
:
include
:
-
python
:
2.6
-
python
:
2.5
-
python
:
2.7
env
:
DEBUGPY=-dbg GEVENTSETUP_EV_VERIFY=3
-
python
:
2.6
...
...
@@ -17,7 +16,6 @@ install:
-
pip install --use-mirrors cython
-
cython --version
-
pip install --use-mirrors greenlet psycopg2 pysendfile web.py
-
if [ "x$TRAVIS_PYTHON_VERSION" == "x2.5" ]; then sudo apt-get install libssl-dev libkrb5-dev libbluetooth-dev; pip install --use-mirrors sslfix; fi
-
if [ "x$TRAVIS_PYTHON_VERSION" == "x2.7" ]; then pip install --use-mirrors -q pep8; fi
-
python -c 'import greenlet; print greenlet, greenlet.__version__; import psycopg2; print psycopg2, psycopg2.__version__; import web; print web, web.__version__'
-
export CYTHON=`which cython`
...
...
README.rst
View file @
9177c3af
...
...
@@ -20,7 +20,7 @@ gevent_ is written and maintained by `Denis Bilenko`_ and is licensed under MIT
get gevent
----------
Install Python 2.
5
or newer and greenlet_ extension.
Install Python 2.
6
or newer and greenlet_ extension.
Download the latest release from `Python Package Index`_ or clone `the repository`_.
...
...
doc/intro.rst
View file @
9177c3af
...
...
@@ -19,7 +19,7 @@ Features include:
Installation
------------
gevent runs on Python 2.
5
and newer and requires
gevent runs on Python 2.
6
and newer and requires
* greenlet__ which can be installed with ``pip install greenlet``.
...
...
gevent/monkey.py
View file @
9177c3af
...
...
@@ -2,7 +2,6 @@
"""Make the standard library cooperative."""
from
__future__
import
absolute_import
import
sys
from
sys
import
version_info
__all__
=
[
'patch_all'
,
'patch_socket'
,
...
...
@@ -186,13 +185,7 @@ def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=Tru
if
select
:
patch_select
(
aggressive
=
aggressive
)
if
ssl
:
if
version_info
[:
2
]
>
(
2
,
5
):
patch_ssl
()
else
:
try
:
patch_ssl
()
except
ImportError
:
pass
# in Python 2.5, 'ssl' is a standalone package not included in stdlib
patch_ssl
()
if
httplib
:
raise
ValueError
(
'gevent.httplib is no longer provided, httplib must be False'
)
if
subprocess
:
...
...
gevent/pywsgi.py
View file @
9177c3af
...
...
@@ -379,46 +379,23 @@ class WSGIHandler(object):
raise
AssertionError
(
"The application did not call start_response()"
)
self
.
_write_with_headers
(
data
)
if
sys
.
version_info
[:
2
]
>=
(
2
,
6
):
def
_write_with_headers
(
self
,
data
):
towrite
=
bytearray
()
self
.
headers_sent
=
True
self
.
finalize_headers
()
towrite
.
extend
(
'HTTP/1.1 %s
\
r
\
n
'
%
self
.
status
)
for
header
in
self
.
response_headers
:
towrite
.
extend
(
'%s: %s
\
r
\
n
'
%
header
)
towrite
.
extend
(
'
\
r
\
n
'
)
if
data
:
if
self
.
response_use_chunked
:
## Write the chunked encoding
towrite
.
extend
(
"%x
\
r
\
n
%s
\
r
\
n
"
%
(
len
(
data
),
data
))
else
:
towrite
.
extend
(
data
)
self
.
_sendall
(
towrite
)
else
:
# Python 2.5 does not have bytearray
def
_write_with_headers
(
self
,
data
):
towrite
=
[]
self
.
headers_sent
=
True
self
.
finalize_headers
()
towrite
.
append
(
'HTTP/1.1 %s
\
r
\
n
'
%
self
.
status
)
for
header
in
self
.
response_headers
:
towrite
.
append
(
'%s: %s
\
r
\
n
'
%
header
)
towrite
.
append
(
'
\
r
\
n
'
)
if
data
:
if
self
.
response_use_chunked
:
## Write the chunked encoding
towrite
.
append
(
"%x
\
r
\
n
%s
\
r
\
n
"
%
(
len
(
data
),
data
))
else
:
towrite
.
append
(
data
)
self
.
_sendall
(
''
.
join
(
towrite
))
def
_write_with_headers
(
self
,
data
):
towrite
=
bytearray
()
self
.
headers_sent
=
True
self
.
finalize_headers
()
towrite
.
extend
(
'HTTP/1.1 %s
\
r
\
n
'
%
self
.
status
)
for
header
in
self
.
response_headers
:
towrite
.
extend
(
'%s: %s
\
r
\
n
'
%
header
)
towrite
.
extend
(
'
\
r
\
n
'
)
if
data
:
if
self
.
response_use_chunked
:
## Write the chunked encoding
towrite
.
extend
(
"%x
\
r
\
n
%s
\
r
\
n
"
%
(
len
(
data
),
data
))
else
:
towrite
.
extend
(
data
)
self
.
_sendall
(
towrite
)
def
start_response
(
self
,
status
,
headers
,
exc_info
=
None
):
if
exc_info
:
...
...
gevent/socket.py
View file @
9177c3af
...
...
@@ -73,10 +73,6 @@ __imports__ = ['error',
'getservbyport'
,
'getdefaulttimeout'
,
'setdefaulttimeout'
,
# Python 2.5 and older:
'RAND_add'
,
'RAND_egd'
,
'RAND_status'
,
# Windows:
'errorTab'
]
...
...
@@ -655,15 +651,4 @@ def getfqdn(name=''):
return
name
try
:
from
gevent.ssl
import
sslwrap_simple
as
ssl
,
SSLError
as
sslerror
,
SSLSocket
as
SSLType
_have_ssl
=
True
except
ImportError
:
_have_ssl
=
False
if
sys
.
version_info
[:
2
]
<=
(
2
,
5
)
and
_have_ssl
:
__implements__
.
extend
([
'ssl'
,
'sslerror'
,
'SSLType'
])
__all__
=
__implements__
+
__extensions__
+
__imports__
gevent/ssl.py
View file @
9177c3af
...
...
@@ -5,10 +5,6 @@
For the documentation, refer to :mod:`ssl` module manual.
This module implements cooperative SSL socket wrappers.
On Python 2.6 and newer it uses Python's native :mod:`ssl` module. On Python 2.5 and 2.4
it requires `ssl package`_ to be installed.
.. _`ssl package`: http://pypi.python.org/pypi/ssl
"""
from
__future__
import
absolute_import
...
...
gevent/timeout.py
View file @
9177c3af
...
...
@@ -20,16 +20,6 @@ __all__ = ['Timeout',
'with_timeout'
]
try
:
BaseException
except
NameError
:
# Python < 2.5
class
BaseException
:
# not subclassing from object() intentionally, because in
# that case "raise Timeout" fails with TypeError.
pass
class
Timeout
(
BaseException
):
"""Raise *exception* in the current greenlet after given time period::
...
...
@@ -129,10 +119,7 @@ class Timeout(BaseException):
self
.
timer
.
stop
()
def
__repr__
(
self
):
try
:
classname
=
self
.
__class__
.
__name__
except
AttributeError
:
# Python < 2.5
classname
=
'Timeout'
classname
=
type
(
self
).
__name__
if
self
.
pending
:
pending
=
' pending'
else
:
...
...
greentest/2.5/test_httplib.py
deleted
100644 → 0
View file @
ed74f199
import
httplib
import
StringIO
import
sys
from
unittest
import
TestCase
from
test
import
test_support
class
FakeSocket
:
def
__init__
(
self
,
text
,
fileclass
=
StringIO
.
StringIO
):
self
.
text
=
text
self
.
fileclass
=
fileclass
def
sendall
(
self
,
data
):
self
.
data
=
data
def
makefile
(
self
,
mode
,
bufsize
=
None
):
if
mode
!=
'r'
and
mode
!=
'rb'
:
raise
httplib
.
UnimplementedFileMode
()
return
self
.
fileclass
(
self
.
text
)
class
NoEOFStringIO
(
StringIO
.
StringIO
):
"""Like StringIO, but raises AssertionError on EOF.
This is used below to test that httplib doesn't try to read
more from the underlying file than it should.
"""
def
read
(
self
,
n
=-
1
):
data
=
StringIO
.
StringIO
.
read
(
self
,
n
)
if
data
==
''
:
raise
AssertionError
(
'caller tried to read past EOF'
)
return
data
def
readline
(
self
,
length
=
None
):
data
=
StringIO
.
StringIO
.
readline
(
self
,
length
)
if
data
==
''
:
raise
AssertionError
(
'caller tried to read past EOF'
)
return
data
class
HeaderTests
(
TestCase
):
def
test_auto_headers
(
self
):
# Some headers are added automatically, but should not be added by
# .request() if they are explicitly set.
import
httplib
class
HeaderCountingBuffer
(
list
):
def
__init__
(
self
):
self
.
count
=
{}
def
append
(
self
,
item
):
kv
=
item
.
split
(
':'
)
if
len
(
kv
)
>
1
:
# item is a 'Key: Value' header string
lcKey
=
kv
[
0
].
lower
()
self
.
count
.
setdefault
(
lcKey
,
0
)
self
.
count
[
lcKey
]
+=
1
list
.
append
(
self
,
item
)
for
explicit_header
in
True
,
False
:
for
header
in
'Content-length'
,
'Host'
,
'Accept-encoding'
:
conn
=
httplib
.
HTTPConnection
(
'example.com'
)
conn
.
sock
=
FakeSocket
(
'blahblahblah'
)
conn
.
_buffer
=
HeaderCountingBuffer
()
body
=
'spamspamspam'
headers
=
{}
if
explicit_header
:
headers
[
header
]
=
str
(
len
(
body
))
conn
.
request
(
'POST'
,
'/'
,
body
,
headers
)
self
.
assertEqual
(
conn
.
_buffer
.
count
[
header
.
lower
()],
1
)
# Collect output to a buffer so that we don't have to cope with line-ending
# issues across platforms. Specifically, the headers will have \r\n pairs
# and some platforms will strip them from the output file.
def
test
():
buf
=
StringIO
.
StringIO
()
_stdout
=
sys
.
stdout
try
:
sys
.
stdout
=
buf
_test
()
finally
:
sys
.
stdout
=
_stdout
# print individual lines with endings stripped
s
=
buf
.
getvalue
()
for
line
in
s
.
split
(
"
\
n
"
):
print
line
.
strip
()
def
_test
():
# Test HTTP status lines
body
=
"HTTP/1.1 200 Ok
\
r
\
n
\
r
\
n
Text"
sock
=
FakeSocket
(
body
)
resp
=
httplib
.
HTTPResponse
(
sock
,
1
)
resp
.
begin
()
print
resp
.
read
()
resp
.
close
()
body
=
"HTTP/1.1 400.100 Not Ok
\
r
\
n
\
r
\
n
Text"
sock
=
FakeSocket
(
body
)
resp
=
httplib
.
HTTPResponse
(
sock
,
1
)
try
:
resp
.
begin
()
except
httplib
.
BadStatusLine
:
print
"BadStatusLine raised as expected"
else
:
print
"Expect BadStatusLine"
# Check invalid host_port
for
hp
in
(
"www.python.org:abc"
,
"www.python.org:"
):
try
:
h
=
httplib
.
HTTP
(
hp
)
except
httplib
.
InvalidURL
:
print
"InvalidURL raised as expected"
else
:
print
"Expect InvalidURL"
for
hp
,
h
,
p
in
((
"[fe80::207:e9ff:fe9b]:8000"
,
"fe80::207:e9ff:fe9b"
,
8000
),
(
"www.python.org:80"
,
"www.python.org"
,
80
),
(
"www.python.org"
,
"www.python.org"
,
80
),
(
"[fe80::207:e9ff:fe9b]"
,
"fe80::207:e9ff:fe9b"
,
80
)):
try
:
http
=
httplib
.
HTTP
(
hp
)
except
httplib
.
InvalidURL
:
print
"InvalidURL raised erroneously"
c
=
http
.
_conn
if
h
!=
c
.
host
:
raise
AssertionError
,
(
"Host incorrectly parsed"
,
h
,
c
.
host
)
if
p
!=
c
.
port
:
raise
AssertionError
,
(
"Port incorrectly parsed"
,
p
,
c
.
host
)
# test response with multiple message headers with the same field name.
text
=
(
'HTTP/1.1 200 OK
\
r
\
n
'
'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
\
r
\
n
'
'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
' Path="/acme"
\
r
\
n
'
'
\
r
\
n
'
'No body
\
r
\
n
'
)
hdr
=
(
'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
', '
'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"'
)
s
=
FakeSocket
(
text
)
r
=
httplib
.
HTTPResponse
(
s
,
1
)
r
.
begin
()
cookies
=
r
.
getheader
(
"Set-Cookie"
)
if
cookies
!=
hdr
:
raise
AssertionError
,
"multiple headers not combined properly"
# Test that the library doesn't attempt to read any data
# from a HEAD request. (Tickles SF bug #622042.)
sock
=
FakeSocket
(
'HTTP/1.1 200 OK
\
r
\
n
'
'Content-Length: 14432
\
r
\
n
'
'
\
r
\
n
'
,
NoEOFStringIO
)
resp
=
httplib
.
HTTPResponse
(
sock
,
1
,
method
=
"HEAD"
)
resp
.
begin
()
if
resp
.
read
()
!=
""
:
raise
AssertionError
,
"Did not expect response from HEAD request"
resp
.
close
()
class
OfflineTest
(
TestCase
):
def
test_responses
(
self
):
self
.
assertEquals
(
httplib
.
responses
[
httplib
.
NOT_FOUND
],
"Not Found"
)
def
test_main
(
verbose
=
None
):
tests
=
[
HeaderTests
,
OfflineTest
]
test_support
.
run_unittest
(
*
tests
)
test
()
greentest/2.5/test_queue.py
deleted
100644 → 0
View file @
ed74f199
# Some simple Queue module tests, plus some failure conditions
# to ensure the Queue locks remain stable.
import
Queue
import
sys
import
threading
import
time
from
test.test_support
import
verify
,
TestFailed
,
verbose
QUEUE_SIZE
=
5
# A thread to run a function that unclogs a blocked Queue.
class
_TriggerThread
(
threading
.
Thread
):
def
__init__
(
self
,
fn
,
args
):
self
.
fn
=
fn
self
.
args
=
args
self
.
startedEvent
=
threading
.
Event
()
threading
.
Thread
.
__init__
(
self
)
def
run
(
self
):
# The sleep isn't necessary, but is intended to give the blocking
# function in the main thread a chance at actually blocking before
# we unclog it. But if the sleep is longer than the timeout-based
# tests wait in their blocking functions, those tests will fail.
# So we give them much longer timeout values compared to the
# sleep here (I aimed at 10 seconds for blocking functions --
# they should never actually wait that long - they should make
# progress as soon as we call self.fn()).
time
.
sleep
(
0.1
)
self
.
startedEvent
.
set
()
self
.
fn
(
*
self
.
args
)
# Execute a function that blocks, and in a separate thread, a function that
# triggers the release. Returns the result of the blocking function.
# Caution: block_func must guarantee to block until trigger_func is
# called, and trigger_func must guarantee to change queue state so that
# block_func can make enough progress to return. In particular, a
# block_func that just raises an exception regardless of whether trigger_func
# is called will lead to timing-dependent sporadic failures, and one of
# those went rarely seen but undiagnosed for years. Now block_func
# must be unexceptional. If block_func is supposed to raise an exception,
# call _doExceptionalBlockingTest() instead.
def
_doBlockingTest
(
block_func
,
block_args
,
trigger_func
,
trigger_args
):
t
=
_TriggerThread
(
trigger_func
,
trigger_args
)
t
.
start
()
result
=
block_func
(
*
block_args
)
# If block_func returned before our thread made the call, we failed!
if
not
t
.
startedEvent
.
isSet
():
raise
TestFailed
(
"blocking function '%r' appeared not to block"
%
block_func
)
t
.
join
(
10
)
# make sure the thread terminates
if
t
.
isAlive
():
raise
TestFailed
(
"trigger function '%r' appeared to not return"
%
trigger_func
)
return
result
# Call this instead if block_func is supposed to raise an exception.
def
_doExceptionalBlockingTest
(
block_func
,
block_args
,
trigger_func
,
trigger_args
,
expected_exception_class
):
t
=
_TriggerThread
(
trigger_func
,
trigger_args
)
t
.
start
()
try
:
try
:
block_func
(
*
block_args
)
except
expected_exception_class
:
raise
else
:
raise
TestFailed
(
"expected exception of kind %r"
%
expected_exception_class
)
finally
:
t
.
join
(
10
)
# make sure the thread terminates
if
t
.
isAlive
():
raise
TestFailed
(
"trigger function '%r' appeared to not return"
%
trigger_func
)
if
not
t
.
startedEvent
.
isSet
():
raise
TestFailed
(
"trigger thread ended but event never set"
)
# A Queue subclass that can provoke failure at a moment's notice :)
class
FailingQueueException
(
Exception
):
pass
class
FailingQueue
(
Queue
.
Queue
):
def
__init__
(
self
,
*
args
):
self
.
fail_next_put
=
False
self
.
fail_next_get
=
False
Queue
.
Queue
.
__init__
(
self
,
*
args
)
def
_put
(
self
,
item
):
if
self
.
fail_next_put
:
self
.
fail_next_put
=
False
raise
FailingQueueException
,
"You Lose"
return
Queue
.
Queue
.
_put
(
self
,
item
)
def
_get
(
self
):
if
self
.
fail_next_get
:
self
.
fail_next_get
=
False
raise
FailingQueueException
,
"You Lose"
return
Queue
.
Queue
.
_get
(
self
)
def
FailingQueueTest
(
q
):
if
not
q
.
empty
():
raise
RuntimeError
,
"Call this function with an empty queue"
for
i
in
range
(
QUEUE_SIZE
-
1
):
q
.
put
(
i
)
# Test a failing non-blocking put.
q
.
fail_next_put
=
True
try
:
q
.
put
(
"oops"
,
block
=
0
)
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
q
.
fail_next_put
=
True
try
:
q
.
put
(
"oops"
,
timeout
=
0.1
)
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
q
.
put
(
"last"
)
verify
(
q
.
full
(),
"Queue should be full"
)
# Test a failing blocking put
q
.
fail_next_put
=
True
try
:
_doBlockingTest
(
q
.
put
,
(
"full"
,),
q
.
get
,
())
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
# Check the Queue isn't damaged.
# put failed, but get succeeded - re-add
q
.
put
(
"last"
)
# Test a failing timeout put
q
.
fail_next_put
=
True
try
:
_doExceptionalBlockingTest
(
q
.
put
,
(
"full"
,
True
,
10
),
q
.
get
,
(),
FailingQueueException
)
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
# Check the Queue isn't damaged.
# put failed, but get succeeded - re-add
q
.
put
(
"last"
)
verify
(
q
.
full
(),
"Queue should be full"
)
q
.
get
()
verify
(
not
q
.
full
(),
"Queue should not be full"
)
q
.
put
(
"last"
)
verify
(
q
.
full
(),
"Queue should be full"
)
# Test a blocking put
_doBlockingTest
(
q
.
put
,
(
"full"
,),
q
.
get
,
())
# Empty it
for
i
in
range
(
QUEUE_SIZE
):
q
.
get
()
verify
(
q
.
empty
(),
"Queue should be empty"
)
q
.
put
(
"first"
)
q
.
fail_next_get
=
True
try
:
q
.
get
()
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
verify
(
not
q
.
empty
(),
"Queue should not be empty"
)
q
.
fail_next_get
=
True
try
:
q
.
get
(
timeout
=
0.1
)
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
verify
(
not
q
.
empty
(),
"Queue should not be empty"
)
q
.
get
()
verify
(
q
.
empty
(),
"Queue should be empty"
)
q
.
fail_next_get
=
True
try
:
_doExceptionalBlockingTest
(
q
.
get
,
(),
q
.
put
,
(
'empty'
,),
FailingQueueException
)
raise
TestFailed
(
"The queue didn't fail when it should have"
)
except
FailingQueueException
:
pass
# put succeeded, but get failed.
verify
(
not
q
.
empty
(),
"Queue should not be empty"
)
q
.
get
()
verify
(
q
.
empty
(),
"Queue should be empty"
)
def
SimpleQueueTest
(
q
):
if
not
q
.
empty
():
raise
RuntimeError
,
"Call this function with an empty queue"
# I guess we better check things actually queue correctly a little :)
q
.
put
(
111
)
q
.
put
(
222
)
verify
(
q
.
get
()
==
111
and
q
.
get
()
==
222
,
"Didn't seem to queue the correct data!"
)
for
i
in
range
(
QUEUE_SIZE
-
1
):
q
.
put
(
i
)
verify
(
not
q
.
empty
(),
"Queue should not be empty"
)
verify
(
not
q
.
full
(),
"Queue should not be full"
)
q
.
put
(
"last"
)
verify
(
q
.
full
(),
"Queue should be full"
)
try
:
q
.
put
(
"full"
,
block
=
0
)
raise
TestFailed
(
"Didn't appear to block with a full queue"
)
except
Queue
.
Full
:
pass
try
:
q
.
put
(
"full"
,
timeout
=
0.01
)
raise
TestFailed
(
"Didn't appear to time-out with a full queue"
)
except
Queue
.
Full
:
pass
# Test a blocking put
_doBlockingTest
(
q
.
put
,
(
"full"
,),
q
.
get
,
())
_doBlockingTest
(
q
.
put
,
(
"full"
,
True
,
10
),
q
.
get
,
())
# Empty it
for
i
in
range
(
QUEUE_SIZE
):
q
.
get
()
verify
(
q
.
empty
(),
"Queue should be empty"
)
try
:
q
.
get
(
block
=
0
)
raise
TestFailed
(
"Didn't appear to block with an empty queue"
)
except
Queue
.
Empty
:
pass
try
:
q
.
get
(
timeout
=
0.01
)
raise
TestFailed
(
"Didn't appear to time-out with an empty queue"
)
except
Queue
.
Empty
:
pass
# Test a blocking get
_doBlockingTest
(
q
.
get
,
(),
q
.
put
,
(
'empty'
,))
_doBlockingTest
(
q
.
get
,
(
True
,
10
),
q
.
put
,
(
'empty'
,))
cum
=
0
cumlock
=
threading
.
Lock
()
def
worker
(
q
):
global
cum
while
True
:
x
=
q
.
get
()
if
x
is
None
:
q
.
task_done
()
return
cumlock
.
acquire
()
try
:
cum
+=
x
finally
:
cumlock
.
release
()
q
.
task_done
()
def
QueueJoinTest
(
q
):
global
cum
cum
=
0
for
i
in
(
0
,
1
):
threading
.
Thread
(
target
=
worker
,
args
=
(
q
,)).
start
()
for
i
in
xrange
(
100
):
q
.
put
(
i
)
q
.
join
()
verify
(
cum
==
sum
(
range
(
100
)),
"q.join() did not block until all tasks were done"
)
for
i
in
(
0
,
1
):
q
.
put
(
None
)
# instruct the threads to close
q
.
join
()
# verify that you can join twice
def
QueueTaskDoneTest
(
q
):
try
:
q
.
task_done
()
except
ValueError
:
pass
else
:
raise
TestFailed
(
"Did not detect task count going negative"
)
def
test
():
q
=
Queue
.
Queue
()
QueueTaskDoneTest
(
q
)
QueueJoinTest
(
q
)
QueueJoinTest
(
q
)
QueueTaskDoneTest
(
q
)
q
=
Queue
.
Queue
(
QUEUE_SIZE
)
# Do it a couple of times on the same queue
SimpleQueueTest
(
q
)
SimpleQueueTest
(
q
)
if
verbose
:
print
"Simple Queue tests seemed to work"
q
=
FailingQueue
(
QUEUE_SIZE
)
FailingQueueTest
(
q
)
FailingQueueTest
(
q
)
if
verbose
:
print
"Failing Queue tests seemed to work"
test
()
greentest/2.5/test_select.py
deleted
100644 → 0
View file @
ed74f199
# Testing select module
from
test.test_support
import
verbose
,
reap_children
import
select
import
os
# test some known error conditions
try
:
rfd
,
wfd
,
xfd
=
select
.
select
(
1
,
2
,
3
)
except
TypeError
:
pass
else
:
print
'expected TypeError exception not raised'
class
Nope
:
pass
class
Almost
:
def
fileno
(
self
):
return
'fileno'
try
:
rfd
,
wfd
,
xfd
=
select
.
select
([
Nope
()],
[],
[])
except
TypeError
:
pass
else
:
print
'expected TypeError exception not raised'
try
:
rfd
,
wfd
,
xfd
=
select
.
select
([
Almost
()],
[],
[])
except
TypeError
:
pass
else
:
print
'expected TypeError exception not raised'
try
:
rfd
,
wfd
,
xfd
=
select
.
select
([],
[],
[],
'not a number'
)
except
TypeError
:
pass
else
:
print
'expected TypeError exception not raised'
def
test
():
import
sys
if
sys
.
platform
[:
3
]
in
(
'win'
,
'mac'
,
'os2'
,
'riscos'
):
if
verbose
:
print
"Can't test select easily on"
,
sys
.
platform
return
cmd
=
'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 0.1; done'
p
=
os
.
popen
(
cmd
,
'r'
)
for
tout
in
(
0
,
0.1
,
0.2
,
0.4
,
0.8
,
1.6
)
+
(
None
,)
*
10
:
if
verbose
:
print
'timeout ='
,
tout
rfd
,
wfd
,
xfd
=
select
.
select
([
p
],
[],
[],
tout
)
if
(
rfd
,
wfd
,
xfd
)
==
([],
[],
[]):
continue
if
(
rfd
,
wfd
,
xfd
)
==
([
p
],
[],
[]):
line
=
p
.
readline
()
if
verbose
:
print
repr
(
line
)
if
not
line
:
if
verbose
:
print
'EOF'
break
continue
print
'Unexpected return values from select():'
,
rfd
,
wfd
,
xfd
p
.
close
()
reap_children
()
test
()
greentest/2.5/test_signal.py
deleted
100644 → 0
View file @
ed74f199
# Test the signal module
from
test.test_support
import
verbose
,
TestSkipped
,
TestFailed
,
vereq
import
signal
import
os
,
sys
,
time
if
sys
.
platform
[:
3
]
in
(
'win'
,
'os2'
)
or
sys
.
platform
==
'riscos'
:
raise
TestSkipped
,
"Can't test signal on %s"
%
sys
.
platform
MAX_DURATION
=
20
# Entire test should last at most 20 sec.
if
verbose
:
x
=
'-x'
else
:
x
=
'+x'
pid
=
os
.
getpid
()
if
verbose
:
print
"test runner's pid is"
,
pid
# Shell script that will send us asynchronous signals
script
=
"""
(
set %(x)s
sleep 2
kill -HUP %(pid)d
sleep 2
kill -USR1 %(pid)d
sleep 2
kill -USR2 %(pid)d
) &
"""
%
vars
()
a_called
=
b_called
=
False
def
handlerA
(
*
args
):
global
a_called
a_called
=
True
if
verbose
:
print
"handlerA invoked"
,
args
class
HandlerBCalled
(
Exception
):
pass
def
handlerB
(
*
args
):
global
b_called
b_called
=
True
if
verbose
:
print
"handlerB invoked"
,
args
raise
HandlerBCalled
,
args
# Set up a child to send signals to us (the parent) after waiting long
# enough to receive the alarm. It seems we miss the alarm for some
# reason. This will hopefully stop the hangs on Tru64/Alpha.
# Alas, it doesn't. Tru64 appears to miss all the signals at times, or
# seemingly random subsets of them, and nothing done in force_test_exit
# so far has actually helped.
def
force_test_exit
():
# Sigh, both imports seem necessary to avoid errors.
import
os
fork_pid
=
os
.
fork
()
if
fork_pid
:
# In parent.
return
fork_pid
# In child.
import
os
,
time
try
:
# Wait 5 seconds longer than the expected alarm to give enough
# time for the normal sequence of events to occur. This is
# just a stop-gap to try to prevent the test from hanging.
time
.
sleep
(
MAX_DURATION
+
5
)
print
>>
sys
.
__stdout__
,
' child should not have to kill parent'
for
signame
in
"SIGHUP"
,
"SIGUSR1"
,
"SIGUSR2"
,
"SIGALRM"
:
os
.
kill
(
pid
,
getattr
(
signal
,
signame
))
print
>>
sys
.
__stdout__
,
" child sent"
,
signame
,
"to"
,
pid
time
.
sleep
(
1
)
finally
:
os
.
_exit
(
0
)
# Install handlers.
hup
=
signal
.
signal
(
signal
.
SIGHUP
,
handlerA
)
usr1
=
signal
.
signal
(
signal
.
SIGUSR1
,
handlerB
)
usr2
=
signal
.
signal
(
signal
.
SIGUSR2
,
signal
.
SIG_IGN
)
alrm
=
signal
.
signal
(
signal
.
SIGALRM
,
signal
.
default_int_handler
)
try
:
signal
.
alarm
(
MAX_DURATION
)
vereq
(
signal
.
getsignal
(
signal
.
SIGHUP
),
handlerA
)
vereq
(
signal
.
getsignal
(
signal
.
SIGUSR1
),
handlerB
)
vereq
(
signal
.
getsignal
(
signal
.
SIGUSR2
),
signal
.
SIG_IGN
)
vereq
(
signal
.
getsignal
(
signal
.
SIGALRM
),
signal
.
default_int_handler
)
# Try to ensure this test exits even if there is some problem with alarm.
# Tru64/Alpha often hangs and is ultimately killed by the buildbot.
fork_pid
=
force_test_exit
()
try
:
signal
.
getsignal
(
4242
)
raise
TestFailed
(
'expected ValueError for invalid signal # to '
'getsignal()'
)
except
ValueError
:
pass
try
:
signal
.
signal
(
4242
,
handlerB
)
raise
TestFailed
(
'expected ValueError for invalid signal # to '
'signal()'
)
except
ValueError
:
pass
try
:
signal
.
signal
(
signal
.
SIGUSR1
,
None
)
raise
TestFailed
(
'expected TypeError for non-callable'
)
except
TypeError
:
pass
# Launch an external script to send us signals.
# We expect the external script to:
# send HUP, which invokes handlerA to set a_called
# send USR1, which invokes handlerB to set b_called and raise
# HandlerBCalled
# send USR2, which is ignored
#
# Then we expect the alarm to go off, and its handler raises
# KeyboardInterrupt, finally getting us out of the loop.
os
.
system
(
script
)
try
:
print
"starting pause() loop..."
while
1
:
try
:
if
verbose
:
print
"call pause()..."
signal
.
pause
()
if
verbose
:
print
"pause() returned"
except
HandlerBCalled
:
if
verbose
:
print
"HandlerBCalled exception caught"
except
KeyboardInterrupt
:
if
verbose
:
print
"KeyboardInterrupt (the alarm() went off)"
if
not
a_called
:
print
'HandlerA not called'
if
not
b_called
:
print
'HandlerB not called'
finally
:
# Forcibly kill the child we created to ping us if there was a test error.
try
:
# Make sure we don't kill ourself if there was a fork error.
if
fork_pid
>
0
:
os
.
kill
(
fork_pid
,
signal
.
SIGKILL
)
except
:
# If the child killed us, it has probably exited. Killing a
# non-existent process will raise an error which we don't care about.
pass
# Restore handlers.
signal
.
alarm
(
0
)
# cancel alarm in case we died early
signal
.
signal
(
signal
.
SIGHUP
,
hup
)
signal
.
signal
(
signal
.
SIGUSR1
,
usr1
)
signal
.
signal
(
signal
.
SIGUSR2
,
usr2
)
signal
.
signal
(
signal
.
SIGALRM
,
alrm
)
greentest/2.5/test_socket.py
deleted
100644 → 0
View file @
ed74f199
#!/usr/bin/env python
import
unittest
from
test
import
test_support
import
socket
import
select
import
time
import
thread
,
threading
import
Queue
import
sys
import
array
from
weakref
import
proxy
import
signal
PORT
=
50007
HOST
=
'localhost'
MSG
=
'Michael Gilfix was here
\
n
'
class
SocketTCPTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
serv
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
serv
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
global
PORT
PORT
=
test_support
.
bind_port
(
self
.
serv
,
HOST
,
PORT
)
self
.
serv
.
listen
(
1
)
def
tearDown
(
self
):
self
.
serv
.
close
()
self
.
serv
=
None
class
SocketUDPTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
serv
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_DGRAM
)
self
.
serv
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
global
PORT
PORT
=
test_support
.
bind_port
(
self
.
serv
,
HOST
,
PORT
)
def
tearDown
(
self
):
self
.
serv
.
close
()
self
.
serv
=
None
class
ThreadableTest
:
"""Threadable Test class
The ThreadableTest class makes it easy to create a threaded
client/server pair from an existing unit test. To create a
new threaded class from an existing unit test, use multiple
inheritance:
class NewClass (OldClass, ThreadableTest):
pass
This class defines two new fixture functions with obvious
purposes for overriding:
clientSetUp ()
clientTearDown ()
Any new test functions within the class must then define
tests in pairs, where the test name is preceeded with a
'_' to indicate the client portion of the test. Ex:
def testFoo(self):
# Server portion
def _testFoo(self):
# Client portion
Any exceptions raised by the clients during their tests
are caught and transferred to the main thread to alert
the testing framework.
Note, the server setup function cannot call any blocking
functions that rely on the client thread during setup,
unless serverExplicityReady() is called just before
the blocking call (such as in setting up a client/server
connection and performing the accept() in setUp().
"""
def
__init__
(
self
):
# Swap the true setup function
self
.
__setUp
=
self
.
setUp
self
.
__tearDown
=
self
.
tearDown
self
.
setUp
=
self
.
_setUp
self
.
tearDown
=
self
.
_tearDown
def
serverExplicitReady
(
self
):
"""This method allows the server to explicitly indicate that
it wants the client thread to proceed. This is useful if the
server is about to execute a blocking routine that is
dependent upon the client thread during its setup routine."""
self
.
server_ready
.
set
()
def
_setUp
(
self
):
self
.
server_ready
=
threading
.
Event
()
self
.
client_ready
=
threading
.
Event
()
self
.
done
=
threading
.
Event
()
self
.
queue
=
Queue
.
Queue
(
1
)
# Do some munging to start the client test.
methodname
=
self
.
id
()
i
=
methodname
.
rfind
(
'.'
)
methodname
=
methodname
[
i
+
1
:]
test_method
=
getattr
(
self
,
'_'
+
methodname
)
self
.
client_thread
=
thread
.
start_new_thread
(
self
.
clientRun
,
(
test_method
,))
self
.
__setUp
()
if
not
self
.
server_ready
.
isSet
():
self
.
server_ready
.
set
()
self
.
client_ready
.
wait
()
def
_tearDown
(
self
):
self
.
__tearDown
()
self
.
done
.
wait
()
if
not
self
.
queue
.
empty
():
msg
=
self
.
queue
.
get
()
self
.
fail
(
msg
)
def
clientRun
(
self
,
test_func
):
self
.
server_ready
.
wait
()
self
.
client_ready
.
set
()
self
.
clientSetUp
()
if
not
callable
(
test_func
):
raise
TypeError
,
"test_func must be a callable function"
try
:
test_func
()
except
Exception
,
strerror
:
self
.
queue
.
put
(
strerror
)
self
.
clientTearDown
()
def
clientSetUp
(
self
):
raise
NotImplementedError
,
"clientSetUp must be implemented."
def
clientTearDown
(
self
):
self
.
done
.
set
()
thread
.
exit
()
class
ThreadedTCPSocketTest
(
SocketTCPTest
,
ThreadableTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketTCPTest
.
__init__
(
self
,
methodName
=
methodName
)
ThreadableTest
.
__init__
(
self
)
def
clientSetUp
(
self
):
self
.
cli
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
def
clientTearDown
(
self
):
self
.
cli
.
close
()
self
.
cli
=
None
ThreadableTest
.
clientTearDown
(
self
)
class
ThreadedUDPSocketTest
(
SocketUDPTest
,
ThreadableTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketUDPTest
.
__init__
(
self
,
methodName
=
methodName
)
ThreadableTest
.
__init__
(
self
)
def
clientSetUp
(
self
):
self
.
cli
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_DGRAM
)
class
SocketConnectedTest
(
ThreadedTCPSocketTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
ThreadedTCPSocketTest
.
__init__
(
self
,
methodName
=
methodName
)
def
setUp
(
self
):
ThreadedTCPSocketTest
.
setUp
(
self
)
# Indicate explicitly we're ready for the client thread to
# proceed and then perform the blocking call to accept
self
.
serverExplicitReady
()
conn
,
addr
=
self
.
serv
.
accept
()
self
.
cli_conn
=
conn
def
tearDown
(
self
):
self
.
cli_conn
.
close
()
self
.
cli_conn
=
None
ThreadedTCPSocketTest
.
tearDown
(
self
)
def
clientSetUp
(
self
):
ThreadedTCPSocketTest
.
clientSetUp
(
self
)
self
.
cli
.
connect
((
HOST
,
PORT
))
self
.
serv_conn
=
self
.
cli
def
clientTearDown
(
self
):
self
.
serv_conn
.
close
()
self
.
serv_conn
=
None
ThreadedTCPSocketTest
.
clientTearDown
(
self
)
class
SocketPairTest
(
unittest
.
TestCase
,
ThreadableTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
unittest
.
TestCase
.
__init__
(
self
,
methodName
=
methodName
)
ThreadableTest
.
__init__
(
self
)
def
setUp
(
self
):
self
.
serv
,
self
.
cli
=
socket
.
socketpair
()
def
tearDown
(
self
):
self
.
serv
.
close
()
self
.
serv
=
None
def
clientSetUp
(
self
):
pass
def
clientTearDown
(
self
):
self
.
cli
.
close
()
self
.
cli
=
None
ThreadableTest
.
clientTearDown
(
self
)
#######################################################################
## Begin Tests
class
GeneralModuleTests
(
unittest
.
TestCase
):
def
test_weakref
(
self
):
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
p
=
proxy
(
s
)
self
.
assertEqual
(
p
.
fileno
(),
s
.
fileno
())
s
.
close
()
s
=
None
try
:
p
.
fileno
()
except
ReferenceError
:
pass
else
:
self
.
fail
(
'Socket proxy still exists'
)
def
testSocketError
(
self
):
# Testing socket module exceptions
def
raise_error
(
*
args
,
**
kwargs
):
raise
socket
.
error
def
raise_herror
(
*
args
,
**
kwargs
):
raise
socket
.
herror
def
raise_gaierror
(
*
args
,
**
kwargs
):
raise
socket
.
gaierror
self
.
failUnlessRaises
(
socket
.
error
,
raise_error
,
"Error raising socket exception."
)
self
.
failUnlessRaises
(
socket
.
error
,
raise_herror
,
"Error raising socket exception."
)
self
.
failUnlessRaises
(
socket
.
error
,
raise_gaierror
,
"Error raising socket exception."
)
def
testCrucialConstants
(
self
):
# Testing for mission critical constants
socket
.
AF_INET
socket
.
SOCK_STREAM
socket
.
SOCK_DGRAM
socket
.
SOCK_RAW
socket
.
SOCK_RDM
socket
.
SOCK_SEQPACKET
socket
.
SOL_SOCKET
socket
.
SO_REUSEADDR
def
testHostnameRes
(
self
):
# Testing hostname resolution mechanisms
hostname
=
socket
.
gethostname
()
try
:
ip
=
socket
.
gethostbyname
(
hostname
)
except
socket
.
error
:
# Probably name lookup wasn't set up right; skip this test
return
self
.
assert_
(
ip
.
find
(
'.'
)
>=
0
,
"Error resolving host to ip."
)
try
:
hname
,
aliases
,
ipaddrs
=
socket
.
gethostbyaddr
(
ip
)
except
socket
.
error
:
# Probably a similar problem as above; skip this test
return
all_host_names
=
[
hostname
,
hname
]
+
aliases
fqhn
=
socket
.
getfqdn
(
ip
)
if
not
fqhn
in
all_host_names
:
self
.
fail
(
"Error testing host resolution mechanisms. (fqdn: %s, all: %s)"
%
(
fqhn
,
repr
(
all_host_names
)))
def
testRefCountGetNameInfo
(
self
):
# Testing reference count for getnameinfo
import
sys
if
hasattr
(
sys
,
"getrefcount"
):
try
:
# On some versions, this loses a reference
orig
=
sys
.
getrefcount
(
__name__
)
socket
.
getnameinfo
(
__name__
,
0
)
except
SystemError
:
if
sys
.
getrefcount
(
__name__
)
<>
orig
:
self
.
fail
(
"socket.getnameinfo loses a reference"
)
def
testInterpreterCrash
(
self
):
# Making sure getnameinfo doesn't crash the interpreter
try
:
# On some versions, this crashes the interpreter.
socket
.
getnameinfo
((
'x'
,
0
,
0
,
0
),
0
)
except
socket
.
error
:
pass
def
testNtoH
(
self
):
# This just checks that htons etc. are their own inverse,
# when looking at the lower 16 or 32 bits.
sizes
=
{
socket
.
htonl
:
32
,
socket
.
ntohl
:
32
,
socket
.
htons
:
16
,
socket
.
ntohs
:
16
}
for
func
,
size
in
sizes
.
items
():
mask
=
(
1L
<<
size
)
-
1
for
i
in
(
0
,
1
,
0xffff
,
~
0xffff
,
2
,
0x01234567
,
0x76543210
):
self
.
assertEqual
(
i
&
mask
,
func
(
func
(
i
&
mask
))
&
mask
)
swapped
=
func
(
mask
)
self
.
assertEqual
(
swapped
&
mask
,
mask
)
self
.
assertRaises
(
OverflowError
,
func
,
1L
<<
34
)
def
testGetServBy
(
self
):
eq
=
self
.
assertEqual
# Find one service that exists, then check all the related interfaces.
# I've ordered this by protocols that have both a tcp and udp
# protocol, at least for modern Linuxes.
if
sys
.
platform
in
(
'linux2'
,
'freebsd4'
,
'freebsd5'
,
'freebsd6'
,
'freebsd7'
,
'darwin'
):
# avoid the 'echo' service on this platform, as there is an
# assumption breaking non-standard port/protocol entry
services
=
(
'daytime'
,
'qotd'
,
'domain'
)
else
:
services
=
(
'echo'
,
'daytime'
,
'domain'
)
for
service
in
services
:
try
:
port
=
socket
.
getservbyname
(
service
,
'tcp'
)
break
except
socket
.
error
:
pass
else
:
raise
socket
.
error
# Try same call with optional protocol omitted
port2
=
socket
.
getservbyname
(
service
)
eq
(
port
,
port2
)
# Try udp, but don't barf it it doesn't exist
try
:
udpport
=
socket
.
getservbyname
(
service
,
'udp'
)
except
socket
.
error
:
udpport
=
None
else
:
eq
(
udpport
,
port
)
# Now make sure the lookup by port returns the same service name
eq
(
socket
.
getservbyport
(
port2
),
service
)
eq
(
socket
.
getservbyport
(
port
,
'tcp'
),
service
)
if
udpport
is
not
None
:
eq
(
socket
.
getservbyport
(
udpport
,
'udp'
),
service
)
def
testDefaultTimeout
(
self
):
# Testing default timeout
# The default timeout should initially be None
self
.
assertEqual
(
socket
.
getdefaulttimeout
(),
None
)
s
=
socket
.
socket
()
self
.
assertEqual
(
s
.
gettimeout
(),
None
)
s
.
close
()
# Set the default timeout to 10, and see if it propagates
socket
.
setdefaulttimeout
(
10
)
self
.
assertEqual
(
socket
.
getdefaulttimeout
(),
10
)
s
=
socket
.
socket
()
self
.
assertEqual
(
s
.
gettimeout
(),
10
)
s
.
close
()
# Reset the default timeout to None, and see if it propagates
socket
.
setdefaulttimeout
(
None
)
self
.
assertEqual
(
socket
.
getdefaulttimeout
(),
None
)
s
=
socket
.
socket
()
self
.
assertEqual
(
s
.
gettimeout
(),
None
)
s
.
close
()
# Check that setting it to an invalid value raises ValueError
self
.
assertRaises
(
ValueError
,
socket
.
setdefaulttimeout
,
-
1
)
# Check that setting it to an invalid type raises TypeError
self
.
assertRaises
(
TypeError
,
socket
.
setdefaulttimeout
,
"spam"
)
def
testIPv4toString
(
self
):
if
not
hasattr
(
socket
,
'inet_pton'
):
return
# No inet_pton() on this platform
from
socket
import
inet_aton
as
f
,
inet_pton
,
AF_INET
g
=
lambda
a
:
inet_pton
(
AF_INET
,
a
)
self
.
assertEquals
(
'
\
x00
\
x00
\
x00
\
x00
'
,
f
(
'0.0.0.0'
))
self
.
assertEquals
(
'
\
xff
\
x00
\
xff
\
x00
'
,
f
(
'255.0.255.0'
))
self
.
assertEquals
(
'
\
xaa
\
xaa
\
xaa
\
xaa
'
,
f
(
'170.170.170.170'
))
self
.
assertEquals
(
'
\
x01
\
x02
\
x03
\
x04
'
,
f
(
'1.2.3.4'
))
self
.
assertEquals
(
'
\
xff
\
xff
\
xff
\
xff
'
,
f
(
'255.255.255.255'
))
self
.
assertEquals
(
'
\
x00
\
x00
\
x00
\
x00
'
,
g
(
'0.0.0.0'
))
self
.
assertEquals
(
'
\
xff
\
x00
\
xff
\
x00
'
,
g
(
'255.0.255.0'
))
self
.
assertEquals
(
'
\
xaa
\
xaa
\
xaa
\
xaa
'
,
g
(
'170.170.170.170'
))
self
.
assertEquals
(
'
\
xff
\
xff
\
xff
\
xff
'
,
g
(
'255.255.255.255'
))
def
testIPv6toString
(
self
):
if
not
hasattr
(
socket
,
'inet_pton'
):
return
# No inet_pton() on this platform
try
:
from
socket
import
inet_pton
,
AF_INET6
,
has_ipv6
if
not
has_ipv6
:
return
except
ImportError
:
return
f
=
lambda
a
:
inet_pton
(
AF_INET6
,
a
)
self
.
assertEquals
(
'
\
x00
'
*
16
,
f
(
'::'
))
self
.
assertEquals
(
'
\
x00
'
*
16
,
f
(
'0::0'
))
self
.
assertEquals
(
'
\
x00
\
x01
'
+
'
\
x00
'
*
14
,
f
(
'1::'
))
self
.
assertEquals
(
'
\
x45
\
xef
\
x76
\
xcb
\
x00
\
x1a
\
x56
\
xef
\
xaf
\
xeb
\
x0b
\
xac
\
x19
\
x24
\
xae
\
xae
'
,
f
(
'45ef:76cb:1a:56ef:afeb:bac:1924:aeae'
)
)
def
testStringToIPv4
(
self
):
if
not
hasattr
(
socket
,
'inet_ntop'
):
return
# No inet_ntop() on this platform
from
socket
import
inet_ntoa
as
f
,
inet_ntop
,
AF_INET
g
=
lambda
a
:
inet_ntop
(
AF_INET
,
a
)
self
.
assertEquals
(
'1.0.1.0'
,
f
(
'
\
x01
\
x00
\
x01
\
x00
'
))
self
.
assertEquals
(
'170.85.170.85'
,
f
(
'
\
xaa
\
x55
\
xaa
\
x55
'
))
self
.
assertEquals
(
'255.255.255.255'
,
f
(
'
\
xff
\
xff
\
xff
\
xff
'
))
self
.
assertEquals
(
'1.2.3.4'
,
f
(
'
\
x01
\
x02
\
x03
\
x04
'
))
self
.
assertEquals
(
'1.0.1.0'
,
g
(
'
\
x01
\
x00
\
x01
\
x00
'
))
self
.
assertEquals
(
'170.85.170.85'
,
g
(
'
\
xaa
\
x55
\
xaa
\
x55
'
))
self
.
assertEquals
(
'255.255.255.255'
,
g
(
'
\
xff
\
xff
\
xff
\
xff
'
))
def
testStringToIPv6
(
self
):
if
not
hasattr
(
socket
,
'inet_ntop'
):
return
# No inet_ntop() on this platform
try
:
from
socket
import
inet_ntop
,
AF_INET6
,
has_ipv6
if
not
has_ipv6
:
return
except
ImportError
:
return
f
=
lambda
a
:
inet_ntop
(
AF_INET6
,
a
)
self
.
assertEquals
(
'::'
,
f
(
'
\
x00
'
*
16
))
self
.
assertEquals
(
'::1'
,
f
(
'
\
x00
'
*
15
+
'
\
x01
'
))
self
.
assertEquals
(
'aef:b01:506:1001:ffff:9997:55:170'
,
f
(
'
\
x0a
\
xef
\
x0b
\
x01
\
x05
\
x06
\
x10
\
x01
\
xff
\
xff
\
x99
\
x97
\
x00
\
x55
\
x01
\
x70
'
)
)
# XXX The following don't test module-level functionality...
def
testSockName
(
self
):
# Testing getsockname()
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
sock
.
bind
((
"0.0.0.0"
,
PORT
+
1
))
name
=
sock
.
getsockname
()
# XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate
# it reasonable to get the host's addr in addition to 0.0.0.0.
# At least for eCos. This is required for the S/390 to pass.
try
:
my_ip_addr
=
socket
.
gethostbyname
(
socket
.
gethostname
())
except
socket
.
error
:
# Probably name lookup wasn't set up right; skip this test
return
self
.
assert_
(
name
[
0
]
in
(
"0.0.0.0"
,
my_ip_addr
),
'%s invalid'
%
name
[
0
])
self
.
assertEqual
(
name
[
1
],
PORT
+
1
)
def
testGetSockOpt
(
self
):
# Testing getsockopt()
# We know a socket should start without reuse==0
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
reuse
=
sock
.
getsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
)
self
.
failIf
(
reuse
!=
0
,
"initial mode is reuse"
)
def
testSetSockOpt
(
self
):
# Testing setsockopt()
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
sock
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
reuse
=
sock
.
getsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
)
self
.
failIf
(
reuse
==
0
,
"failed to set reuse mode"
)
def
testSendAfterClose
(
self
):
# testing send() after close() with timeout
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
sock
.
settimeout
(
1
)
sock
.
close
()
self
.
assertRaises
(
socket
.
error
,
sock
.
send
,
"spam"
)
def
testNewAttributes
(
self
):
# testing .family, .type and .protocol
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
assertEqual
(
sock
.
family
,
socket
.
AF_INET
)
self
.
assertEqual
(
sock
.
type
,
socket
.
SOCK_STREAM
)
self
.
assertEqual
(
sock
.
proto
,
0
)
sock
.
close
()
class
BasicTCPTest
(
SocketConnectedTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketConnectedTest
.
__init__
(
self
,
methodName
=
methodName
)
def
testRecv
(
self
):
# Testing large receive over TCP
msg
=
self
.
cli_conn
.
recv
(
1024
)
self
.
assertEqual
(
msg
,
MSG
)
def
_testRecv
(
self
):
self
.
serv_conn
.
send
(
MSG
)
def
testOverFlowRecv
(
self
):
# Testing receive in chunks over TCP
seg1
=
self
.
cli_conn
.
recv
(
len
(
MSG
)
-
3
)
seg2
=
self
.
cli_conn
.
recv
(
1024
)
msg
=
seg1
+
seg2
self
.
assertEqual
(
msg
,
MSG
)
def
_testOverFlowRecv
(
self
):
self
.
serv_conn
.
send
(
MSG
)
def
testRecvFrom
(
self
):
# Testing large recvfrom() over TCP
msg
,
addr
=
self
.
cli_conn
.
recvfrom
(
1024
)
self
.
assertEqual
(
msg
,
MSG
)
def
_testRecvFrom
(
self
):
self
.
serv_conn
.
send
(
MSG
)
def
testOverFlowRecvFrom
(
self
):
# Testing recvfrom() in chunks over TCP
seg1
,
addr
=
self
.
cli_conn
.
recvfrom
(
len
(
MSG
)
-
3
)
seg2
,
addr
=
self
.
cli_conn
.
recvfrom
(
1024
)
msg
=
seg1
+
seg2
self
.
assertEqual
(
msg
,
MSG
)
def
_testOverFlowRecvFrom
(
self
):
self
.
serv_conn
.
send
(
MSG
)
def
testSendAll
(
self
):
# Testing sendall() with a 2048 byte string over TCP
msg
=
''
while
1
:
read
=
self
.
cli_conn
.
recv
(
1024
)
if
not
read
:
break
msg
+=
read
self
.
assertEqual
(
msg
,
'f'
*
2048
)
def
_testSendAll
(
self
):
big_chunk
=
'f'
*
2048
self
.
serv_conn
.
sendall
(
big_chunk
)
def
testFromFd
(
self
):
# Testing fromfd()
if
not
hasattr
(
socket
,
"fromfd"
):
return
# On Windows, this doesn't exist
fd
=
self
.
cli_conn
.
fileno
()
sock
=
socket
.
fromfd
(
fd
,
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
msg
=
sock
.
recv
(
1024
)
self
.
assertEqual
(
msg
,
MSG
)
def
_testFromFd
(
self
):
self
.
serv_conn
.
send
(
MSG
)
def
testShutdown
(
self
):
# Testing shutdown()
msg
=
self
.
cli_conn
.
recv
(
1024
)
self
.
assertEqual
(
msg
,
MSG
)
def
_testShutdown
(
self
):
self
.
serv_conn
.
send
(
MSG
)
self
.
serv_conn
.
shutdown
(
2
)
class
BasicUDPTest
(
ThreadedUDPSocketTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
ThreadedUDPSocketTest
.
__init__
(
self
,
methodName
=
methodName
)
def
testSendtoAndRecv
(
self
):
# Testing sendto() and Recv() over UDP
msg
=
self
.
serv
.
recv
(
len
(
MSG
))
self
.
assertEqual
(
msg
,
MSG
)
def
_testSendtoAndRecv
(
self
):
self
.
cli
.
sendto
(
MSG
,
0
,
(
HOST
,
PORT
))
def
testRecvFrom
(
self
):
# Testing recvfrom() over UDP
msg
,
addr
=
self
.
serv
.
recvfrom
(
len
(
MSG
))
self
.
assertEqual
(
msg
,
MSG
)
def
_testRecvFrom
(
self
):
self
.
cli
.
sendto
(
MSG
,
0
,
(
HOST
,
PORT
))
def
testRecvFromNegative
(
self
):
# Negative lengths passed to recvfrom should give ValueError.
self
.
assertRaises
(
ValueError
,
self
.
serv
.
recvfrom
,
-
1
)
def
_testRecvFromNegative
(
self
):
self
.
cli
.
sendto
(
MSG
,
0
,
(
HOST
,
PORT
))
class
TCPCloserTest
(
ThreadedTCPSocketTest
):
def
testClose
(
self
):
conn
,
addr
=
self
.
serv
.
accept
()
conn
.
close
()
sd
=
self
.
cli
read
,
write
,
err
=
select
.
select
([
sd
],
[],
[],
1.0
)
self
.
assertEqual
(
read
,
[
sd
])
self
.
assertEqual
(
sd
.
recv
(
1
),
''
)
def
_testClose
(
self
):
self
.
cli
.
connect
((
HOST
,
PORT
))
time
.
sleep
(
1.0
)
class
BasicSocketPairTest
(
SocketPairTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketPairTest
.
__init__
(
self
,
methodName
=
methodName
)
def
testRecv
(
self
):
msg
=
self
.
serv
.
recv
(
1024
)
self
.
assertEqual
(
msg
,
MSG
)
def
_testRecv
(
self
):
self
.
cli
.
send
(
MSG
)
def
testSend
(
self
):
self
.
serv
.
send
(
MSG
)
def
_testSend
(
self
):
msg
=
self
.
cli
.
recv
(
1024
)
self
.
assertEqual
(
msg
,
MSG
)
class
NonBlockingTCPTests
(
ThreadedTCPSocketTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
ThreadedTCPSocketTest
.
__init__
(
self
,
methodName
=
methodName
)
def
testSetBlocking
(
self
):
# Testing whether set blocking works
self
.
serv
.
setblocking
(
0
)
start
=
time
.
time
()
try
:
self
.
serv
.
accept
()
except
socket
.
error
:
pass
end
=
time
.
time
()
self
.
assert_
((
end
-
start
)
<
1.0
,
"Error setting non-blocking mode."
)
def
_testSetBlocking
(
self
):
pass
def
testAccept
(
self
):
# Testing non-blocking accept
self
.
serv
.
setblocking
(
0
)
try
:
conn
,
addr
=
self
.
serv
.
accept
()
except
socket
.
error
:
pass
else
:
self
.
fail
(
"Error trying to do non-blocking accept."
)
read
,
write
,
err
=
select
.
select
([
self
.
serv
],
[],
[])
if
self
.
serv
in
read
:
conn
,
addr
=
self
.
serv
.
accept
()
else
:
self
.
fail
(
"Error trying to do accept after select."
)
def
_testAccept
(
self
):
time
.
sleep
(
0.1
)
self
.
cli
.
connect
((
HOST
,
PORT
))
def
testConnect
(
self
):
# Testing non-blocking connect
conn
,
addr
=
self
.
serv
.
accept
()
def
_testConnect
(
self
):
self
.
cli
.
settimeout
(
10
)
self
.
cli
.
connect
((
HOST
,
PORT
))
def
testRecv
(
self
):
# Testing non-blocking recv
conn
,
addr
=
self
.
serv
.
accept
()
conn
.
setblocking
(
0
)
try
:
msg
=
conn
.
recv
(
len
(
MSG
))
except
socket
.
error
:
pass
else
:
self
.
fail
(
"Error trying to do non-blocking recv."
)
read
,
write
,
err
=
select
.
select
([
conn
],
[],
[])
if
conn
in
read
:
msg
=
conn
.
recv
(
len
(
MSG
))
self
.
assertEqual
(
msg
,
MSG
)
else
:
self
.
fail
(
"Error during select call to non-blocking socket."
)
def
_testRecv
(
self
):
self
.
cli
.
connect
((
HOST
,
PORT
))
time
.
sleep
(
0.1
)
self
.
cli
.
send
(
MSG
)
class
FileObjectClassTestCase
(
SocketConnectedTest
):
bufsize
=
-
1
# Use default buffer size
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketConnectedTest
.
__init__
(
self
,
methodName
=
methodName
)
def
setUp
(
self
):
SocketConnectedTest
.
setUp
(
self
)
self
.
serv_file
=
self
.
cli_conn
.
makefile
(
'rb'
,
self
.
bufsize
)
def
tearDown
(
self
):
self
.
serv_file
.
close
()
self
.
assert_
(
self
.
serv_file
.
closed
)
self
.
serv_file
=
None
SocketConnectedTest
.
tearDown
(
self
)
def
clientSetUp
(
self
):
SocketConnectedTest
.
clientSetUp
(
self
)
self
.
cli_file
=
self
.
serv_conn
.
makefile
(
'wb'
)
def
clientTearDown
(
self
):
self
.
cli_file
.
close
()
self
.
assert_
(
self
.
cli_file
.
closed
)
self
.
cli_file
=
None
SocketConnectedTest
.
clientTearDown
(
self
)
def
testSmallRead
(
self
):
# Performing small file read test
first_seg
=
self
.
serv_file
.
read
(
len
(
MSG
)
-
3
)
second_seg
=
self
.
serv_file
.
read
(
3
)
msg
=
first_seg
+
second_seg
self
.
assertEqual
(
msg
,
MSG
)
def
_testSmallRead
(
self
):
self
.
cli_file
.
write
(
MSG
)
self
.
cli_file
.
flush
()
def
testFullRead
(
self
):
# read until EOF
msg
=
self
.
serv_file
.
read
()
self
.
assertEqual
(
msg
,
MSG
)
def
_testFullRead
(
self
):
self
.
cli_file
.
write
(
MSG
)
self
.
cli_file
.
close
()
def
testUnbufferedRead
(
self
):
# Performing unbuffered file read test
buf
=
''
while
1
:
char
=
self
.
serv_file
.
read
(
1
)
if
not
char
:
break
buf
+=
char
self
.
assertEqual
(
buf
,
MSG
)
def
_testUnbufferedRead
(
self
):
self
.
cli_file
.
write
(
MSG
)
self
.
cli_file
.
flush
()
def
testReadline
(
self
):
# Performing file readline test
line
=
self
.
serv_file
.
readline
()
self
.
assertEqual
(
line
,
MSG
)
def
_testReadline
(
self
):
self
.
cli_file
.
write
(
MSG
)
self
.
cli_file
.
flush
()
def
testReadlineAfterRead
(
self
):
a_baloo_is
=
self
.
serv_file
.
read
(
len
(
"A baloo is"
))
self
.
assertEqual
(
"A baloo is"
,
a_baloo_is
)
_a_bear
=
self
.
serv_file
.
read
(
len
(
" a bear"
))
self
.
assertEqual
(
" a bear"
,
_a_bear
)
line
=
self
.
serv_file
.
readline
()
self
.
assertEqual
(
"
\
n
"
,
line
)
line
=
self
.
serv_file
.
readline
()
self
.
assertEqual
(
"A BALOO IS A BEAR.
\
n
"
,
line
)
line
=
self
.
serv_file
.
readline
()
self
.
assertEqual
(
MSG
,
line
)
def
_testReadlineAfterRead
(
self
):
self
.
cli_file
.
write
(
"A baloo is a bear
\
n
"
)
self
.
cli_file
.
write
(
"A BALOO IS A BEAR.
\
n
"
)
self
.
cli_file
.
write
(
MSG
)
self
.
cli_file
.
flush
()
def
testReadlineAfterReadNoNewline
(
self
):
end_of_
=
self
.
serv_file
.
read
(
len
(
"End Of "
))
self
.
assertEqual
(
"End Of "
,
end_of_
)
line
=
self
.
serv_file
.
readline
()
self
.
assertEqual
(
"Line"
,
line
)
def
_testReadlineAfterReadNoNewline
(
self
):
self
.
cli_file
.
write
(
"End Of Line"
)
def
testClosedAttr
(
self
):
self
.
assert_
(
not
self
.
serv_file
.
closed
)
def
_testClosedAttr
(
self
):
self
.
assert_
(
not
self
.
cli_file
.
closed
)
class
UnbufferedFileObjectClassTestCase
(
FileObjectClassTestCase
):
"""Repeat the tests from FileObjectClassTestCase with bufsize==0.
In this case (and in this case only), it should be possible to
create a file object, read a line from it, create another file
object, read another line from it, without loss of data in the
first file object's buffer. Note that httplib relies on this
when reading multiple requests from the same socket."""
bufsize
=
0
# Use unbuffered mode
def
testUnbufferedReadline
(
self
):
# Read a line, create a new file object, read another line with it
line
=
self
.
serv_file
.
readline
()
# first line
self
.
assertEqual
(
line
,
"A. "
+
MSG
)
# first line
self
.
serv_file
=
self
.
cli_conn
.
makefile
(
'rb'
,
0
)
line
=
self
.
serv_file
.
readline
()
# second line
self
.
assertEqual
(
line
,
"B. "
+
MSG
)
# second line
def
_testUnbufferedReadline
(
self
):
self
.
cli_file
.
write
(
"A. "
+
MSG
)
self
.
cli_file
.
write
(
"B. "
+
MSG
)
self
.
cli_file
.
flush
()
class
LineBufferedFileObjectClassTestCase
(
FileObjectClassTestCase
):
bufsize
=
1
# Default-buffered for reading; line-buffered for writing
class
SmallBufferedFileObjectClassTestCase
(
FileObjectClassTestCase
):
bufsize
=
2
# Exercise the buffering code
class
Urllib2FileobjectTest
(
unittest
.
TestCase
):
# urllib2.HTTPHandler has "borrowed" socket._fileobject, and requires that
# it close the socket if the close c'tor argument is true
def
testClose
(
self
):
class
MockSocket
:
closed
=
False
def
flush
(
self
):
pass
def
close
(
self
):
self
.
closed
=
True
# must not close unless we request it: the original use of _fileobject
# by module socket requires that the underlying socket not be closed until
# the _socketobject that created the _fileobject is closed
s
=
MockSocket
()
f
=
socket
.
_fileobject
(
s
)
f
.
close
()
self
.
assert_
(
not
s
.
closed
)
s
=
MockSocket
()
f
=
socket
.
_fileobject
(
s
,
close
=
True
)
f
.
close
()
self
.
assert_
(
s
.
closed
)
class
TCPTimeoutTest
(
SocketTCPTest
):
def
testTCPTimeout
(
self
):
def
raise_timeout
(
*
args
,
**
kwargs
):
self
.
serv
.
settimeout
(
1.0
)
self
.
serv
.
accept
()
self
.
failUnlessRaises
(
socket
.
timeout
,
raise_timeout
,
"Error generating a timeout exception (TCP)"
)
def
testTimeoutZero
(
self
):
ok
=
False
try
:
self
.
serv
.
settimeout
(
0.0
)
foo
=
self
.
serv
.
accept
()
except
socket
.
timeout
:
self
.
fail
(
"caught timeout instead of error (TCP)"
)
except
socket
.
error
:
ok
=
True
except
:
self
.
fail
(
"caught unexpected exception (TCP)"
)
if
not
ok
:
self
.
fail
(
"accept() returned success when we did not expect it"
)
def
testInterruptedTimeout
(
self
):
# XXX I don't know how to do this test on MSWindows or any other
# plaform that doesn't support signal.alarm() or os.kill(), though
# the bug should have existed on all platforms.
if
not
hasattr
(
signal
,
"alarm"
):
return
# can only test on *nix
self
.
serv
.
settimeout
(
5.0
)
# must be longer than alarm
class
Alarm
(
Exception
):
pass
def
alarm_handler
(
signal
,
frame
):
raise
Alarm
old_alarm
=
signal
.
signal
(
signal
.
SIGALRM
,
alarm_handler
)
try
:
signal
.
alarm
(
2
)
# POSIX allows alarm to be up to 1 second early
try
:
foo
=
self
.
serv
.
accept
()
except
socket
.
timeout
:
self
.
fail
(
"caught timeout instead of Alarm"
)
except
Alarm
:
pass
except
:
self
.
fail
(
"caught other exception instead of Alarm"
)
else
:
self
.
fail
(
"nothing caught"
)
signal
.
alarm
(
0
)
# shut off alarm
except
Alarm
:
self
.
fail
(
"got Alarm in wrong place"
)
finally
:
# no alarm can be pending. Safe to restore old handler.
signal
.
signal
(
signal
.
SIGALRM
,
old_alarm
)
class
UDPTimeoutTest
(
SocketTCPTest
):
def
testUDPTimeout
(
self
):
def
raise_timeout
(
*
args
,
**
kwargs
):
self
.
serv
.
settimeout
(
1.0
)
self
.
serv
.
recv
(
1024
)
self
.
failUnlessRaises
(
socket
.
timeout
,
raise_timeout
,
"Error generating a timeout exception (UDP)"
)
def
testTimeoutZero
(
self
):
ok
=
False
try
:
self
.
serv
.
settimeout
(
0.0
)
foo
=
self
.
serv
.
recv
(
1024
)
except
socket
.
timeout
:
self
.
fail
(
"caught timeout instead of error (UDP)"
)
except
socket
.
error
:
ok
=
True
except
:
self
.
fail
(
"caught unexpected exception (UDP)"
)
if
not
ok
:
self
.
fail
(
"recv() returned success when we did not expect it"
)
class
TestExceptions
(
unittest
.
TestCase
):
def
testExceptionTree
(
self
):
self
.
assert_
(
issubclass
(
socket
.
error
,
Exception
))
self
.
assert_
(
issubclass
(
socket
.
herror
,
socket
.
error
))
self
.
assert_
(
issubclass
(
socket
.
gaierror
,
socket
.
error
))
self
.
assert_
(
issubclass
(
socket
.
timeout
,
socket
.
error
))
class
TestLinuxAbstractNamespace
(
unittest
.
TestCase
):
UNIX_PATH_MAX
=
108
def
testLinuxAbstractNamespace
(
self
):
address
=
"
\
x00
python-test-hello
\
x00
\
xff
"
s1
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
s1
.
bind
(
address
)
s1
.
listen
(
1
)
s2
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
s2
.
connect
(
s1
.
getsockname
())
s1
.
accept
()
self
.
assertEqual
(
s1
.
getsockname
(),
address
)
self
.
assertEqual
(
s2
.
getpeername
(),
address
)
def
testMaxName
(
self
):
address
=
"
\
x00
"
+
"h"
*
(
self
.
UNIX_PATH_MAX
-
1
)
s
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
s
.
bind
(
address
)
self
.
assertEqual
(
s
.
getsockname
(),
address
)
def
testNameOverflow
(
self
):
address
=
"
\
x00
"
+
"h"
*
self
.
UNIX_PATH_MAX
s
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
self
.
assertRaises
(
socket
.
error
,
s
.
bind
,
address
)
class
BufferIOTest
(
SocketConnectedTest
):
"""
Test the buffer versions of socket.recv() and socket.send().
"""
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketConnectedTest
.
__init__
(
self
,
methodName
=
methodName
)
def
testRecvInto
(
self
):
buf
=
array
.
array
(
'c'
,
' '
*
1024
)
nbytes
=
self
.
cli_conn
.
recv_into
(
buf
)
self
.
assertEqual
(
nbytes
,
len
(
MSG
))
msg
=
buf
.
tostring
()[:
len
(
MSG
)]
self
.
assertEqual
(
msg
,
MSG
)
def
_testRecvInto
(
self
):
buf
=
buffer
(
MSG
)
self
.
serv_conn
.
send
(
buf
)
def
testRecvFromInto
(
self
):
buf
=
array
.
array
(
'c'
,
' '
*
1024
)
nbytes
,
addr
=
self
.
cli_conn
.
recvfrom_into
(
buf
)
self
.
assertEqual
(
nbytes
,
len
(
MSG
))
msg
=
buf
.
tostring
()[:
len
(
MSG
)]
self
.
assertEqual
(
msg
,
MSG
)
def
_testRecvFromInto
(
self
):
buf
=
buffer
(
MSG
)
self
.
serv_conn
.
send
(
buf
)
def
test_main
():
tests
=
[
GeneralModuleTests
,
BasicTCPTest
,
TCPCloserTest
,
TCPTimeoutTest
,
TestExceptions
,
BufferIOTest
]
if
sys
.
platform
!=
'mac'
:
tests
.
extend
([
BasicUDPTest
,
UDPTimeoutTest
])
tests
.
extend
([
NonBlockingTCPTests
,
FileObjectClassTestCase
,
UnbufferedFileObjectClassTestCase
,
LineBufferedFileObjectClassTestCase
,
SmallBufferedFileObjectClassTestCase
,
Urllib2FileobjectTest
,
])
if
hasattr
(
socket
,
"socketpair"
):
tests
.
append
(
BasicSocketPairTest
)
if
sys
.
platform
==
'linux2'
:
tests
.
append
(
TestLinuxAbstractNamespace
)
thread_info
=
test_support
.
threading_setup
()
test_support
.
run_unittest
(
*
tests
)
test_support
.
threading_cleanup
(
*
thread_info
)
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_socket_ssl.py
deleted
100644 → 0
View file @
ed74f199
# Test just the SSL support in the socket module, in a moderately bogus way.
import
sys
from
test
import
test_support
import
socket
import
errno
# Optionally test SSL support. This requires the 'network' resource as given
# on the regrtest command line.
skip_expected
=
not
(
test_support
.
is_resource_enabled
(
'network'
)
and
hasattr
(
socket
,
"ssl"
))
def
test_basic
():
test_support
.
requires
(
'network'
)
import
urllib
if
test_support
.
verbose
:
print
"test_basic ..."
socket
.
RAND_status
()
try
:
socket
.
RAND_egd
(
1
)
except
TypeError
:
pass
else
:
print
"didn't raise TypeError"
socket
.
RAND_add
(
"this is a random string"
,
75.0
)
try
:
f
=
urllib
.
urlopen
(
'https://sf.net'
)
except
IOError
,
exc
:
if
exc
.
errno
==
errno
.
ETIMEDOUT
:
raise
test_support
.
ResourceDenied
(
'HTTPS connection is timing out'
)
else
:
raise
buf
=
f
.
read
()
f
.
close
()
def
test_timeout
():
test_support
.
requires
(
'network'
)
def
error_msg
(
extra_msg
):
print
>>
sys
.
stderr
,
"""
\
WARNING: an attempt to connect to %r %s, in
test_timeout. That may be legitimate, but is not the outcome we hoped
for. If this message is seen often, test_timeout should be changed to
use a more reliable address."""
%
(
ADDR
,
extra_msg
)
if
test_support
.
verbose
:
print
"test_timeout ..."
# A service which issues a welcome banner (without need to write
# anything).
ADDR
=
"pop.gmail.com"
,
995
s
=
socket
.
socket
()
s
.
settimeout
(
30.0
)
try
:
s
.
connect
(
ADDR
)
except
socket
.
timeout
:
error_msg
(
'timed out'
)
return
except
socket
.
error
,
exc
:
# In case connection is refused.
if
exc
.
args
[
0
]
==
errno
.
ECONNREFUSED
:
error_msg
(
'was refused'
)
return
else
:
raise
ss
=
socket
.
ssl
(
s
)
# Read part of return welcome banner twice.
ss
.
read
(
1
)
ss
.
read
(
1
)
s
.
close
()
def
test_rude_shutdown
():
if
test_support
.
verbose
:
print
"test_rude_shutdown ..."
try
:
import
threading
except
ImportError
:
return
# Some random port to connect to.
PORT
=
[
9934
]
listener_ready
=
threading
.
Event
()
listener_gone
=
threading
.
Event
()
# `listener` runs in a thread. It opens a socket listening on PORT, and
# sits in an accept() until the main thread connects. Then it rudely
# closes the socket, and sets Event `listener_gone` to let the main thread
# know the socket is gone.
def
listener
():
s
=
socket
.
socket
()
PORT
[
0
]
=
test_support
.
bind_port
(
s
,
''
,
PORT
[
0
])
s
.
listen
(
5
)
listener_ready
.
set
()
s
.
accept
()
s
=
None
# reclaim the socket object, which also closes it
listener_gone
.
set
()
def
connector
():
listener_ready
.
wait
()
s
=
socket
.
socket
()
s
.
connect
((
'localhost'
,
PORT
[
0
]))
listener_gone
.
wait
()
try
:
ssl_sock
=
socket
.
ssl
(
s
)
except
socket
.
sslerror
:
pass
else
:
raise
test_support
.
TestFailed
(
'connecting to closed SSL socket should have failed'
)
t
=
threading
.
Thread
(
target
=
listener
)
t
.
start
()
connector
()
t
.
join
()
def
test_main
():
if
not
hasattr
(
socket
,
"ssl"
):
raise
test_support
.
TestSkipped
(
"socket module has no ssl support"
)
test_rude_shutdown
()
test_basic
()
test_timeout
()
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_socketserver.py
deleted
100644 → 0
View file @
ed74f199
# Test suite for SocketServer.py
from
test
import
test_support
from
test.test_support
import
(
verbose
,
verify
,
TESTFN
,
TestSkipped
,
reap_children
)
test_support
.
requires
(
'network'
)
from
SocketServer
import
*
import
socket
import
errno
import
select
import
time
import
threading
import
os
NREQ
=
3
DELAY
=
0.5
class
MyMixinHandler
:
def
handle
(
self
):
time
.
sleep
(
DELAY
)
line
=
self
.
rfile
.
readline
()
time
.
sleep
(
DELAY
)
self
.
wfile
.
write
(
line
)
class
MyStreamHandler
(
MyMixinHandler
,
StreamRequestHandler
):
pass
class
MyDatagramHandler
(
MyMixinHandler
,
DatagramRequestHandler
):
pass
class
MyMixinServer
:
def
serve_a_few
(
self
):
for
i
in
range
(
NREQ
):
self
.
handle_request
()
def
handle_error
(
self
,
request
,
client_address
):
self
.
close_request
(
request
)
self
.
server_close
()
raise
teststring
=
"hello world
\
n
"
def
receive
(
sock
,
n
,
timeout
=
20
):
r
,
w
,
x
=
select
.
select
([
sock
],
[],
[],
timeout
)
if
sock
in
r
:
return
sock
.
recv
(
n
)
else
:
raise
RuntimeError
,
"timed out on %r"
%
(
sock
,)
def
testdgram
(
proto
,
addr
):
s
=
socket
.
socket
(
proto
,
socket
.
SOCK_DGRAM
)
s
.
sendto
(
teststring
,
addr
)
buf
=
data
=
receive
(
s
,
100
)
while
data
and
'
\
n
'
not
in
buf
:
data
=
receive
(
s
,
100
)
buf
+=
data
verify
(
buf
==
teststring
)
s
.
close
()
def
teststream
(
proto
,
addr
):
s
=
socket
.
socket
(
proto
,
socket
.
SOCK_STREAM
)
s
.
connect
(
addr
)
s
.
sendall
(
teststring
)
buf
=
data
=
receive
(
s
,
100
)
while
data
and
'
\
n
'
not
in
buf
:
data
=
receive
(
s
,
100
)
buf
+=
data
verify
(
buf
==
teststring
)
s
.
close
()
class
ServerThread
(
threading
.
Thread
):
def
__init__
(
self
,
addr
,
svrcls
,
hdlrcls
):
threading
.
Thread
.
__init__
(
self
)
self
.
__addr
=
addr
self
.
__svrcls
=
svrcls
self
.
__hdlrcls
=
hdlrcls
def
run
(
self
):
class
svrcls
(
MyMixinServer
,
self
.
__svrcls
):
pass
if
verbose
:
print
"thread: creating server"
svr
=
svrcls
(
self
.
__addr
,
self
.
__hdlrcls
)
# pull the address out of the server in case it changed
# this can happen if another process is using the port
addr
=
svr
.
server_address
if
addr
:
self
.
__addr
=
addr
if
self
.
__addr
!=
svr
.
socket
.
getsockname
():
raise
RuntimeError
(
'server_address was %s, expected %s'
%
(
self
.
__addr
,
svr
.
socket
.
getsockname
()))
if
verbose
:
print
"thread: serving three times"
svr
.
serve_a_few
()
if
verbose
:
print
"thread: done"
seed
=
0
def
pickport
():
global
seed
seed
+=
1
return
10000
+
(
os
.
getpid
()
%
1000
)
*
10
+
seed
host
=
"localhost"
testfiles
=
[]
def
pickaddr
(
proto
):
if
proto
==
socket
.
AF_INET
:
return
(
host
,
pickport
())
else
:
fn
=
TESTFN
+
str
(
pickport
())
if
os
.
name
==
'os2'
:
# AF_UNIX socket names on OS/2 require a specific prefix
# which can't include a drive letter and must also use
# backslashes as directory separators
if
fn
[
1
]
==
':'
:
fn
=
fn
[
2
:]
if
fn
[
0
]
in
(
os
.
sep
,
os
.
altsep
):
fn
=
fn
[
1
:]
fn
=
os
.
path
.
join
(
'
\
socke
t
'
,
fn
)
if
os
.
sep
==
'/'
:
fn
=
fn
.
replace
(
os
.
sep
,
os
.
altsep
)
else
:
fn
=
fn
.
replace
(
os
.
altsep
,
os
.
sep
)
testfiles
.
append
(
fn
)
return
fn
def
cleanup
():
for
fn
in
testfiles
:
try
:
os
.
remove
(
fn
)
except
os
.
error
:
pass
testfiles
[:]
=
[]
def
testloop
(
proto
,
servers
,
hdlrcls
,
testfunc
):
for
svrcls
in
servers
:
addr
=
pickaddr
(
proto
)
if
verbose
:
print
"ADDR ="
,
addr
print
"CLASS ="
,
svrcls
t
=
ServerThread
(
addr
,
svrcls
,
hdlrcls
)
if
verbose
:
print
"server created"
t
.
start
()
if
verbose
:
print
"server running"
for
i
in
range
(
NREQ
):
time
.
sleep
(
DELAY
)
if
verbose
:
print
"test client"
,
i
testfunc
(
proto
,
addr
)
if
verbose
:
print
"waiting for server"
t
.
join
()
if
verbose
:
print
"done"
class
ForgivingTCPServer
(
TCPServer
):
# prevent errors if another process is using the port we want
def
server_bind
(
self
):
host
,
default_port
=
self
.
server_address
# this code shamelessly stolen from test.test_support
# the ports were changed to protect the innocent
import
sys
for
port
in
[
default_port
,
3434
,
8798
,
23833
]:
try
:
self
.
server_address
=
host
,
port
TCPServer
.
server_bind
(
self
)
break
except
socket
.
error
,
(
err
,
msg
):
if
err
!=
errno
.
EADDRINUSE
:
raise
print
>>
sys
.
__stderr__
,
\
' WARNING: failed to listen on port %d, trying another'
%
port
tcpservers
=
[
ForgivingTCPServer
,
ThreadingTCPServer
]
if
hasattr
(
os
,
'fork'
)
and
os
.
name
not
in
(
'os2'
,):
tcpservers
.
append
(
ForkingTCPServer
)
udpservers
=
[
UDPServer
,
ThreadingUDPServer
]
if
hasattr
(
os
,
'fork'
)
and
os
.
name
not
in
(
'os2'
,):
udpservers
.
append
(
ForkingUDPServer
)
if
not
hasattr
(
socket
,
'AF_UNIX'
):
streamservers
=
[]
dgramservers
=
[]
else
:
class
ForkingUnixStreamServer
(
ForkingMixIn
,
UnixStreamServer
):
pass
streamservers
=
[
UnixStreamServer
,
ThreadingUnixStreamServer
]
if
hasattr
(
os
,
'fork'
)
and
os
.
name
not
in
(
'os2'
,):
streamservers
.
append
(
ForkingUnixStreamServer
)
class
ForkingUnixDatagramServer
(
ForkingMixIn
,
UnixDatagramServer
):
pass
dgramservers
=
[
UnixDatagramServer
,
ThreadingUnixDatagramServer
]
if
hasattr
(
os
,
'fork'
)
and
os
.
name
not
in
(
'os2'
,):
dgramservers
.
append
(
ForkingUnixDatagramServer
)
def
sloppy_cleanup
():
# See http://python.org/sf/1540386
# We need to reap children here otherwise a child from one server
# can be left running for the next server and cause a test failure.
time
.
sleep
(
DELAY
)
reap_children
()
def
testall
():
testloop
(
socket
.
AF_INET
,
tcpservers
,
MyStreamHandler
,
teststream
)
sloppy_cleanup
()
testloop
(
socket
.
AF_INET
,
udpservers
,
MyDatagramHandler
,
testdgram
)
if
hasattr
(
socket
,
'AF_UNIX'
):
sloppy_cleanup
()
testloop
(
socket
.
AF_UNIX
,
streamservers
,
MyStreamHandler
,
teststream
)
# Alas, on Linux (at least) recvfrom() doesn't return a meaningful
# client address so this cannot work:
##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram)
def
test_main
():
import
imp
if
imp
.
lock_held
():
# If the import lock is held, the threads will hang.
raise
TestSkipped
(
"can't run when import lock is held"
)
try
:
testall
()
finally
:
cleanup
()
reap_children
()
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_subprocess.py
deleted
100644 → 0
View file @
ed74f199
import
unittest
from
test
import
test_support
import
subprocess
import
sys
import
signal
import
os
import
tempfile
import
time
import
re
mswindows
=
(
sys
.
platform
==
"win32"
)
#
# Depends on the following external programs: Python
#
if
mswindows
:
SETBINARY
=
(
'import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
'os.O_BINARY);'
)
else
:
SETBINARY
=
''
# In a debug build, stuff like "[6580 refs]" is printed to stderr at
# shutdown time. That frustrates tests trying to check stderr produced
# from a spawned Python process.
def
remove_stderr_debug_decorations
(
stderr
):
return
re
.
sub
(
r"\
[
\d+ refs\
]
\r?\n?$"
,
""
,
stderr
)
class
ProcessTestCase
(
unittest
.
TestCase
):
def
setUp
(
self
):
# Try to minimize the number of children we have so this test
# doesn't crash on some buildbots (Alphas in particular).
if
hasattr
(
test_support
,
"reap_children"
):
test_support
.
reap_children
()
def
tearDown
(
self
):
# Try to minimize the number of children we have so this test
# doesn't crash on some buildbots (Alphas in particular).
if
hasattr
(
test_support
,
"reap_children"
):
test_support
.
reap_children
()
def
mkstemp
(
self
):
"""wrapper for mkstemp, calling mktemp if mkstemp is not available"""
if
hasattr
(
tempfile
,
"mkstemp"
):
return
tempfile
.
mkstemp
()
else
:
fname
=
tempfile
.
mktemp
()
return
os
.
open
(
fname
,
os
.
O_RDWR
|
os
.
O_CREAT
),
fname
#
# Generic tests
#
def
test_call_seq
(
self
):
# call() function with sequence argument
rc
=
subprocess
.
call
([
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
])
self
.
assertEqual
(
rc
,
47
)
def
test_check_call_zero
(
self
):
# check_call() function with zero return code
rc
=
subprocess
.
check_call
([
sys
.
executable
,
"-c"
,
"import sys; sys.exit(0)"
])
self
.
assertEqual
(
rc
,
0
)
def
test_check_call_nonzero
(
self
):
# check_call() function with non-zero return code
try
:
subprocess
.
check_call
([
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
])
except
subprocess
.
CalledProcessError
,
e
:
self
.
assertEqual
(
e
.
returncode
,
47
)
else
:
self
.
fail
(
"Expected CalledProcessError"
)
def
test_call_kwargs
(
self
):
# call() function with keyword args
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"banana"
rc
=
subprocess
.
call
([
sys
.
executable
,
"-c"
,
'import sys, os;'
\
'sys.exit(os.getenv("FRUIT")=="banana")'
],
env
=
newenv
)
self
.
assertEqual
(
rc
,
1
)
def
test_stdin_none
(
self
):
# .stdin is None when not redirected
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'print "banana"'
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
p
.
wait
()
self
.
assertEqual
(
p
.
stdin
,
None
)
def
test_stdout_none
(
self
):
# .stdout is None when not redirected
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'print " this bit of output is from a '
'test of stdout in a different '
'process ..."'
],
stdin
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
p
.
wait
()
self
.
assertEqual
(
p
.
stdout
,
None
)
def
test_stderr_none
(
self
):
# .stderr is None when not redirected
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'print "banana"'
],
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
)
p
.
wait
()
self
.
assertEqual
(
p
.
stderr
,
None
)
def
test_executable
(
self
):
p
=
subprocess
.
Popen
([
"somethingyoudonthave"
,
"-c"
,
"import sys; sys.exit(47)"
],
executable
=
sys
.
executable
)
p
.
wait
()
self
.
assertEqual
(
p
.
returncode
,
47
)
def
test_stdin_pipe
(
self
):
# stdin redirection
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.exit(sys.stdin.read() == "pear")'
],
stdin
=
subprocess
.
PIPE
)
p
.
stdin
.
write
(
"pear"
)
p
.
stdin
.
close
()
p
.
wait
()
self
.
assertEqual
(
p
.
returncode
,
1
)
def
test_stdin_filedes
(
self
):
# stdin is set to open file descriptor
tf
=
tempfile
.
TemporaryFile
()
d
=
tf
.
fileno
()
os
.
write
(
d
,
"pear"
)
os
.
lseek
(
d
,
0
,
0
)
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.exit(sys.stdin.read() == "pear")'
],
stdin
=
d
)
p
.
wait
()
self
.
assertEqual
(
p
.
returncode
,
1
)
def
test_stdin_fileobj
(
self
):
# stdin is set to open file object
tf
=
tempfile
.
TemporaryFile
()
tf
.
write
(
"pear"
)
tf
.
seek
(
0
)
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.exit(sys.stdin.read() == "pear")'
],
stdin
=
tf
)
p
.
wait
()
self
.
assertEqual
(
p
.
returncode
,
1
)
def
test_stdout_pipe
(
self
):
# stdout redirection
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stdout.write("orange")'
],
stdout
=
subprocess
.
PIPE
)
self
.
assertEqual
(
p
.
stdout
.
read
(),
"orange"
)
def
test_stdout_filedes
(
self
):
# stdout is set to open file descriptor
tf
=
tempfile
.
TemporaryFile
()
d
=
tf
.
fileno
()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stdout.write("orange")'
],
stdout
=
d
)
p
.
wait
()
os
.
lseek
(
d
,
0
,
0
)
self
.
assertEqual
(
os
.
read
(
d
,
1024
),
"orange"
)
def
test_stdout_fileobj
(
self
):
# stdout is set to open file object
tf
=
tempfile
.
TemporaryFile
()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stdout.write("orange")'
],
stdout
=
tf
)
p
.
wait
()
tf
.
seek
(
0
)
self
.
assertEqual
(
tf
.
read
(),
"orange"
)
def
test_stderr_pipe
(
self
):
# stderr redirection
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stderr.write("strawberry")'
],
stderr
=
subprocess
.
PIPE
)
self
.
assertEqual
(
remove_stderr_debug_decorations
(
p
.
stderr
.
read
()),
"strawberry"
)
def
test_stderr_filedes
(
self
):
# stderr is set to open file descriptor
tf
=
tempfile
.
TemporaryFile
()
d
=
tf
.
fileno
()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stderr.write("strawberry")'
],
stderr
=
d
)
p
.
wait
()
os
.
lseek
(
d
,
0
,
0
)
self
.
assertEqual
(
remove_stderr_debug_decorations
(
os
.
read
(
d
,
1024
)),
"strawberry"
)
def
test_stderr_fileobj
(
self
):
# stderr is set to open file object
tf
=
tempfile
.
TemporaryFile
()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stderr.write("strawberry")'
],
stderr
=
tf
)
p
.
wait
()
tf
.
seek
(
0
)
self
.
assertEqual
(
remove_stderr_debug_decorations
(
tf
.
read
()),
"strawberry"
)
def
test_stdout_stderr_pipe
(
self
):
# capture stdout and stderr to the same pipe
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys;'
\
'sys.stdout.write("apple");'
\
'sys.stdout.flush();'
\
'sys.stderr.write("orange")'
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
STDOUT
)
output
=
p
.
stdout
.
read
()
stripped
=
remove_stderr_debug_decorations
(
output
)
self
.
assertEqual
(
stripped
,
"appleorange"
)
def
test_stdout_stderr_file
(
self
):
# capture stdout and stderr to the same open file
tf
=
tempfile
.
TemporaryFile
()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys;'
\
'sys.stdout.write("apple");'
\
'sys.stdout.flush();'
\
'sys.stderr.write("orange")'
],
stdout
=
tf
,
stderr
=
tf
)
p
.
wait
()
tf
.
seek
(
0
)
output
=
tf
.
read
()
stripped
=
remove_stderr_debug_decorations
(
output
)
self
.
assertEqual
(
stripped
,
"appleorange"
)
def
test_stdout_filedes_of_stdout
(
self
):
# stdout is set to 1 (#1531862).
cmd
=
r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
rc
=
subprocess
.
call
([
sys
.
executable
,
"-c"
,
cmd
],
stdout
=
1
)
self
.
assertEquals
(
rc
,
2
)
def
test_cwd
(
self
):
tmpdir
=
os
.
getenv
(
"TEMP"
,
"/tmp"
)
# We cannot use os.path.realpath to canonicalize the path,
# since it doesn't expand Tru64 {memb} strings. See bug 1063571.
cwd
=
os
.
getcwd
()
os
.
chdir
(
tmpdir
)
tmpdir
=
os
.
getcwd
()
os
.
chdir
(
cwd
)
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
\
'sys.stdout.write(os.getcwd())'
],
stdout
=
subprocess
.
PIPE
,
cwd
=
tmpdir
)
normcase
=
os
.
path
.
normcase
self
.
assertEqual
(
normcase
(
p
.
stdout
.
read
()),
normcase
(
tmpdir
))
def
test_env
(
self
):
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"orange"
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
\
'sys.stdout.write(os.getenv("FRUIT"))'
],
stdout
=
subprocess
.
PIPE
,
env
=
newenv
)
self
.
assertEqual
(
p
.
stdout
.
read
(),
"orange"
)
def
test_communicate_stdin
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.exit(sys.stdin.read() == "pear")'
],
stdin
=
subprocess
.
PIPE
)
p
.
communicate
(
"pear"
)
self
.
assertEqual
(
p
.
returncode
,
1
)
def
test_communicate_stdout
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stdout.write("pineapple")'
],
stdout
=
subprocess
.
PIPE
)
(
stdout
,
stderr
)
=
p
.
communicate
()
self
.
assertEqual
(
stdout
,
"pineapple"
)
self
.
assertEqual
(
stderr
,
None
)
def
test_communicate_stderr
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys; sys.stderr.write("pineapple")'
],
stderr
=
subprocess
.
PIPE
)
(
stdout
,
stderr
)
=
p
.
communicate
()
self
.
assertEqual
(
stdout
,
None
)
# When running with a pydebug build, the # of references is outputted
# to stderr, so just check if stderr at least started with "pinapple"
self
.
assert_
(
stderr
.
startswith
(
"pineapple"
))
def
test_communicate
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
\
'sys.stderr.write("pineapple");'
\
'sys.stdout.write(sys.stdin.read())'
],
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
(
stdout
,
stderr
)
=
p
.
communicate
(
"banana"
)
self
.
assertEqual
(
stdout
,
"banana"
)
self
.
assertEqual
(
remove_stderr_debug_decorations
(
stderr
),
"pineapple"
)
# This test is Linux specific for simplicity to at least have
# some coverage. It is not a platform specific bug.
if
os
.
path
.
isdir
(
'/proc/%d/fd'
%
os
.
getpid
()):
# Test for the fd leak reported in http://bugs.python.org/issue2791.
def
test_communicate_pipe_fd_leak
(
self
):
fd_directory
=
'/proc/%d/fd'
%
os
.
getpid
()
num_fds_before_popen
=
len
(
os
.
listdir
(
fd_directory
))
p
=
subprocess
.
Popen
([
sys
.
executable
,
'-c'
,
'print()'
],
stdout
=
subprocess
.
PIPE
)
p
.
communicate
()
num_fds_after_communicate
=
len
(
os
.
listdir
(
fd_directory
))
del
p
num_fds_after_destruction
=
len
(
os
.
listdir
(
fd_directory
))
self
.
assertEqual
(
num_fds_before_popen
,
num_fds_after_destruction
)
self
.
assertEqual
(
num_fds_before_popen
,
num_fds_after_communicate
)
def
test_communicate_returns
(
self
):
# communicate() should return None if no redirection is active
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
])
(
stdout
,
stderr
)
=
p
.
communicate
()
self
.
assertEqual
(
stdout
,
None
)
self
.
assertEqual
(
stderr
,
None
)
def
test_communicate_pipe_buf
(
self
):
# communicate() with writes larger than pipe_buf
# This test will probably deadlock rather than fail, if
# communicate() does not work properly.
x
,
y
=
os
.
pipe
()
if
mswindows
:
pipe_buf
=
512
else
:
pipe_buf
=
os
.
fpathconf
(
x
,
"PC_PIPE_BUF"
)
os
.
close
(
x
)
os
.
close
(
y
)
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
'sys.stdout.write(sys.stdin.read(47));'
\
'sys.stderr.write("xyz"*%d);'
\
'sys.stdout.write(sys.stdin.read())'
%
pipe_buf
],
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
string_to_write
=
"abc"
*
pipe_buf
(
stdout
,
stderr
)
=
p
.
communicate
(
string_to_write
)
self
.
assertEqual
(
stdout
,
string_to_write
)
def
test_writes_before_communicate
(
self
):
# stdin.write before communicate()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
\
'sys.stdout.write(sys.stdin.read())'
],
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
p
.
stdin
.
write
(
"banana"
)
(
stdout
,
stderr
)
=
p
.
communicate
(
"split"
)
self
.
assertEqual
(
stdout
,
"bananasplit"
)
self
.
assertEqual
(
remove_stderr_debug_decorations
(
stderr
),
""
)
def
test_universal_newlines
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
+
SETBINARY
+
'sys.stdout.write("line1
\
\
n");'
'sys.stdout.flush();'
'sys.stdout.write("line2
\
\
r");'
'sys.stdout.flush();'
'sys.stdout.write("line3
\
\
r
\
\
n");'
'sys.stdout.flush();'
'sys.stdout.write("line4
\
\
r");'
'sys.stdout.flush();'
'sys.stdout.write("
\
\
nline5");'
'sys.stdout.flush();'
'sys.stdout.write("
\
\
nline6");'
],
stdout
=
subprocess
.
PIPE
,
universal_newlines
=
1
)
stdout
=
p
.
stdout
.
read
()
if
hasattr
(
file
,
'newlines'
):
# Interpreter with universal newline support
self
.
assertEqual
(
stdout
,
"line1
\
n
line2
\
n
line3
\
n
line4
\
n
line5
\
n
line6"
)
else
:
# Interpreter without universal newline support
self
.
assertEqual
(
stdout
,
"line1
\
n
line2
\
r
line3
\
r
\
n
line4
\
r
\
n
line5
\
n
line6"
)
def
test_universal_newlines_communicate
(
self
):
# universal newlines through communicate()
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
+
SETBINARY
+
'sys.stdout.write("line1
\
\
n");'
'sys.stdout.flush();'
'sys.stdout.write("line2
\
\
r");'
'sys.stdout.flush();'
'sys.stdout.write("line3
\
\
r
\
\
n");'
'sys.stdout.flush();'
'sys.stdout.write("line4
\
\
r");'
'sys.stdout.flush();'
'sys.stdout.write("
\
\
nline5");'
'sys.stdout.flush();'
'sys.stdout.write("
\
\
nline6");'
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
universal_newlines
=
1
)
(
stdout
,
stderr
)
=
p
.
communicate
()
if
hasattr
(
file
,
'newlines'
):
# Interpreter with universal newline support
self
.
assertEqual
(
stdout
,
"line1
\
n
line2
\
n
line3
\
n
line4
\
n
line5
\
n
line6"
)
else
:
# Interpreter without universal newline support
self
.
assertEqual
(
stdout
,
"line1
\
n
line2
\
r
line3
\
r
\
n
line4
\
r
\
n
line5
\
n
line6"
)
def
test_no_leaking
(
self
):
# Make sure we leak no resources
if
not
hasattr
(
test_support
,
"is_resource_enabled"
)
\
or
test_support
.
is_resource_enabled
(
"subprocess"
)
and
not
mswindows
:
max_handles
=
1026
# too much for most UNIX systems
else
:
max_handles
=
65
for
i
in
range
(
max_handles
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
"import sys;sys.stdout.write(sys.stdin.read())"
],
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
data
=
p
.
communicate
(
"lime"
)[
0
]
self
.
assertEqual
(
data
,
"lime"
)
def
test_list2cmdline
(
self
):
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'a b c'
,
'd'
,
'e'
]),
'"a b c" d e'
)
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'ab"c'
,
'
\
\
'
,
'd'
]),
'ab
\
\
"c
\
\
d'
)
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'a
\
\
\
\
\
\
b'
,
'de fg'
,
'h'
]),
'a
\
\
\
\
\
\
b "de fg" h'
)
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'a
\
\
"b'
,
'c'
,
'd'
]),
'a
\
\
\
\
\
\
"b c d'
)
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'a
\
\
\
\
b c'
,
'd'
,
'e'
]),
'"a
\
\
\
\
b c" d e'
)
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'a
\
\
\
\
b
\
\
c'
,
'd'
,
'e'
]),
'"a
\
\
\
\
b
\
\
c" d e'
)
self
.
assertEqual
(
subprocess
.
list2cmdline
([
'ab'
,
''
]),
'ab ""'
)
def
test_poll
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
"import time; time.sleep(1)"
])
count
=
0
while
p
.
poll
()
is
None
:
time
.
sleep
(
0.1
)
count
+=
1
# We expect that the poll loop probably went around about 10 times,
# but, based on system scheduling we can't control, it's possible
# poll() never returned None. It "should be" very rare that it
# didn't go around at least twice.
self
.
assert_
(
count
>=
2
)
# Subsequent invocations should just return the returncode
self
.
assertEqual
(
p
.
poll
(),
0
)
def
test_wait
(
self
):
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
"import time; time.sleep(2)"
])
self
.
assertEqual
(
p
.
wait
(),
0
)
# Subsequent invocations should just return the returncode
self
.
assertEqual
(
p
.
wait
(),
0
)
def
test_invalid_bufsize
(
self
):
# an invalid type of the bufsize argument should raise
# TypeError.
try
:
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
"pass"
],
"orange"
)
except
TypeError
:
pass
else
:
self
.
fail
(
"Expected TypeError"
)
#
# POSIX tests
#
if
not
mswindows
:
def
test_exceptions
(
self
):
# catched & re-raised exceptions
try
:
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
""
],
cwd
=
"/this/path/does/not/exist"
)
except
OSError
,
e
:
# The attribute child_traceback should contain "os.chdir"
# somewhere.
self
.
assertNotEqual
(
e
.
child_traceback
.
find
(
"os.chdir"
),
-
1
)
else
:
self
.
fail
(
"Expected OSError"
)
def
_suppress_core_files
(
self
):
"""Try to prevent core files from being created.
Returns previous ulimit if successful, else None.
"""
try
:
import
resource
old_limit
=
resource
.
getrlimit
(
resource
.
RLIMIT_CORE
)
resource
.
setrlimit
(
resource
.
RLIMIT_CORE
,
(
0
,
0
))
return
old_limit
except
(
ImportError
,
ValueError
,
resource
.
error
):
return
None
def
_unsuppress_core_files
(
self
,
old_limit
):
"""Return core file behavior to default."""
if
old_limit
is
None
:
return
try
:
import
resource
resource
.
setrlimit
(
resource
.
RLIMIT_CORE
,
old_limit
)
except
(
ImportError
,
ValueError
,
resource
.
error
):
return
def
test_run_abort
(
self
):
# returncode handles signal termination
old_limit
=
self
.
_suppress_core_files
()
try
:
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
"import os; os.abort()"
])
finally
:
self
.
_unsuppress_core_files
(
old_limit
)
p
.
wait
()
self
.
assertEqual
(
-
p
.
returncode
,
signal
.
SIGABRT
)
def
test_preexec
(
self
):
# preexec function
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
\
'sys.stdout.write(os.getenv("FRUIT"))'
],
stdout
=
subprocess
.
PIPE
,
preexec_fn
=
lambda
:
os
.
putenv
(
"FRUIT"
,
"apple"
))
self
.
assertEqual
(
p
.
stdout
.
read
(),
"apple"
)
def
test_args_string
(
self
):
# args is a string
f
,
fname
=
self
.
mkstemp
()
os
.
write
(
f
,
"#!/bin/sh
\
n
"
)
os
.
write
(
f
,
"exec %s -c 'import sys; sys.exit(47)'
\
n
"
%
sys
.
executable
)
os
.
close
(
f
)
os
.
chmod
(
fname
,
0700
)
p
=
subprocess
.
Popen
(
fname
)
p
.
wait
()
os
.
remove
(
fname
)
self
.
assertEqual
(
p
.
returncode
,
47
)
def
test_invalid_args
(
self
):
# invalid arguments should raise ValueError
self
.
assertRaises
(
ValueError
,
subprocess
.
call
,
[
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
],
startupinfo
=
47
)
self
.
assertRaises
(
ValueError
,
subprocess
.
call
,
[
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
],
creationflags
=
47
)
def
test_shell_sequence
(
self
):
# Run command through the shell (sequence)
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"apple"
p
=
subprocess
.
Popen
([
"echo $FRUIT"
],
shell
=
1
,
stdout
=
subprocess
.
PIPE
,
env
=
newenv
)
self
.
assertEqual
(
p
.
stdout
.
read
().
strip
(),
"apple"
)
def
test_shell_string
(
self
):
# Run command through the shell (string)
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"apple"
p
=
subprocess
.
Popen
(
"echo $FRUIT"
,
shell
=
1
,
stdout
=
subprocess
.
PIPE
,
env
=
newenv
)
self
.
assertEqual
(
p
.
stdout
.
read
().
strip
(),
"apple"
)
def
test_call_string
(
self
):
# call() function with string argument on UNIX
f
,
fname
=
self
.
mkstemp
()
os
.
write
(
f
,
"#!/bin/sh
\
n
"
)
os
.
write
(
f
,
"exec %s -c 'import sys; sys.exit(47)'
\
n
"
%
sys
.
executable
)
os
.
close
(
f
)
os
.
chmod
(
fname
,
0700
)
rc
=
subprocess
.
call
(
fname
)
os
.
remove
(
fname
)
self
.
assertEqual
(
rc
,
47
)
#
# Windows tests
#
if
mswindows
:
def
test_startupinfo
(
self
):
# startupinfo argument
# We uses hardcoded constants, because we do not want to
# depend on win32all.
STARTF_USESHOWWINDOW
=
1
SW_MAXIMIZE
=
3
startupinfo
=
subprocess
.
STARTUPINFO
()
startupinfo
.
dwFlags
=
STARTF_USESHOWWINDOW
startupinfo
.
wShowWindow
=
SW_MAXIMIZE
# Since Python is a console process, it won't be affected
# by wShowWindow, but the argument should be silently
# ignored
subprocess
.
call
([
sys
.
executable
,
"-c"
,
"import sys; sys.exit(0)"
],
startupinfo
=
startupinfo
)
def
test_creationflags
(
self
):
# creationflags argument
CREATE_NEW_CONSOLE
=
16
sys
.
stderr
.
write
(
" a DOS box should flash briefly ...
\
n
"
)
subprocess
.
call
(
sys
.
executable
+
' -c "import time; time.sleep(0.25)"'
,
creationflags
=
CREATE_NEW_CONSOLE
)
def
test_invalid_args
(
self
):
# invalid arguments should raise ValueError
self
.
assertRaises
(
ValueError
,
subprocess
.
call
,
[
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
],
preexec_fn
=
lambda
:
1
)
self
.
assertRaises
(
ValueError
,
subprocess
.
call
,
[
sys
.
executable
,
"-c"
,
"import sys; sys.exit(47)"
],
close_fds
=
True
)
def
test_shell_sequence
(
self
):
# Run command through the shell (sequence)
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"physalis"
p
=
subprocess
.
Popen
([
"set"
],
shell
=
1
,
stdout
=
subprocess
.
PIPE
,
env
=
newenv
)
self
.
assertNotEqual
(
p
.
stdout
.
read
().
find
(
"physalis"
),
-
1
)
def
test_shell_string
(
self
):
# Run command through the shell (string)
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"physalis"
p
=
subprocess
.
Popen
(
"set"
,
shell
=
1
,
stdout
=
subprocess
.
PIPE
,
env
=
newenv
)
self
.
assertNotEqual
(
p
.
stdout
.
read
().
find
(
"physalis"
),
-
1
)
def
test_call_string
(
self
):
# call() function with string argument on Windows
rc
=
subprocess
.
call
(
sys
.
executable
+
' -c "import sys; sys.exit(47)"'
)
self
.
assertEqual
(
rc
,
47
)
def
test_main
():
test_support
.
run_unittest
(
ProcessTestCase
)
if
hasattr
(
test_support
,
"reap_children"
):
test_support
.
reap_children
()
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_thread.py
deleted
100644 → 0
View file @
ed74f199
# Very rudimentary test of thread module
# Create a bunch of threads, let each do some work, wait until all are done
from
test.test_support
import
verbose
import
random
import
thread
import
time
mutex
=
thread
.
allocate_lock
()
rmutex
=
thread
.
allocate_lock
()
# for calls to random
running
=
0
done
=
thread
.
allocate_lock
()
done
.
acquire
()
numtasks
=
10
def
task
(
ident
):
global
running
rmutex
.
acquire
()
delay
=
random
.
random
()
*
numtasks
/
10.
rmutex
.
release
()
if
verbose
:
print
'task'
,
ident
,
'will run for'
,
round
(
delay
,
1
),
'sec'
time
.
sleep
(
delay
)
if
verbose
:
print
'task'
,
ident
,
'done'
mutex
.
acquire
()
running
=
running
-
1
if
running
==
0
:
done
.
release
()
mutex
.
release
()
next_ident
=
0
def
newtask
():
global
next_ident
,
running
mutex
.
acquire
()
next_ident
=
next_ident
+
1
if
verbose
:
print
'creating task'
,
next_ident
thread
.
start_new_thread
(
task
,
(
next_ident
,))
running
=
running
+
1
mutex
.
release
()
for
i
in
range
(
numtasks
):
newtask
()
print
'waiting for all tasks to complete'
done
.
acquire
()
print
'all tasks done'
class
barrier
:
def
__init__
(
self
,
n
):
self
.
n
=
n
self
.
waiting
=
0
self
.
checkin
=
thread
.
allocate_lock
()
self
.
checkout
=
thread
.
allocate_lock
()
self
.
checkout
.
acquire
()
def
enter
(
self
):
checkin
,
checkout
=
self
.
checkin
,
self
.
checkout
checkin
.
acquire
()
self
.
waiting
=
self
.
waiting
+
1
if
self
.
waiting
==
self
.
n
:
self
.
waiting
=
self
.
n
-
1
checkout
.
release
()
return
checkin
.
release
()
checkout
.
acquire
()
self
.
waiting
=
self
.
waiting
-
1
if
self
.
waiting
==
0
:
checkin
.
release
()
return
checkout
.
release
()
numtrips
=
3
def
task2
(
ident
):
global
running
for
i
in
range
(
numtrips
):
if
ident
==
0
:
# give it a good chance to enter the next
# barrier before the others are all out
# of the current one
delay
=
0.001
else
:
rmutex
.
acquire
()
delay
=
random
.
random
()
*
numtasks
/
10.
rmutex
.
release
()
if
verbose
:
print
'task'
,
ident
,
'will run for'
,
round
(
delay
,
1
),
'sec'
time
.
sleep
(
delay
)
if
verbose
:
print
'task'
,
ident
,
'entering barrier'
,
i
bar
.
enter
()
if
verbose
:
print
'task'
,
ident
,
'leaving barrier'
,
i
mutex
.
acquire
()
running
-=
1
# Must release mutex before releasing done, else the main thread can
# exit and set mutex to None as part of global teardown; then
# mutex.release() raises AttributeError.
finished
=
running
==
0
mutex
.
release
()
if
finished
:
done
.
release
()
print
'
\
n
*** Barrier Test ***'
if
done
.
acquire
(
0
):
raise
ValueError
,
"'done' should have remained acquired"
bar
=
barrier
(
numtasks
)
running
=
numtasks
for
i
in
range
(
numtasks
):
thread
.
start_new_thread
(
task2
,
(
i
,))
done
.
acquire
()
print
'all tasks done'
# not all platforms support changing thread stack size
print
'
\
n
*** Changing thread stack size ***'
if
thread
.
stack_size
()
!=
0
:
raise
ValueError
,
"initial stack_size not 0"
thread
.
stack_size
(
0
)
if
thread
.
stack_size
()
!=
0
:
raise
ValueError
,
"stack_size not reset to default"
from
os
import
name
as
os_name
if
os_name
in
(
"nt"
,
"os2"
,
"posix"
):
tss_supported
=
1
try
:
thread
.
stack_size
(
4096
)
except
ValueError
:
print
'caught expected ValueError setting stack_size(4096)'
except
thread
.
error
:
tss_supported
=
0
print
'platform does not support changing thread stack size'
if
tss_supported
:
failed
=
lambda
s
,
e
:
s
!=
e
fail_msg
=
"stack_size(%d) failed - should succeed"
for
tss
in
(
262144
,
0x100000
,
0
):
thread
.
stack_size
(
tss
)
if
failed
(
thread
.
stack_size
(),
tss
):
raise
ValueError
,
fail_msg
%
tss
print
'successfully set stack_size(%d)'
%
tss
for
tss
in
(
262144
,
0x100000
):
print
'trying stack_size = %d'
%
tss
next_ident
=
0
for
i
in
range
(
numtasks
):
newtask
()
print
'waiting for all tasks to complete'
done
.
acquire
()
print
'all tasks done'
# reset stack size to default
thread
.
stack_size
(
0
)
greentest/2.5/test_threading.py
deleted
100644 → 0
View file @
ed74f199
# Very rudimentary test of threading module
import
test.test_support
from
test.test_support
import
verbose
import
random
import
sys
import
threading
import
thread
import
time
import
unittest
# A trivial mutable counter.
class
Counter
(
object
):
def
__init__
(
self
):
self
.
value
=
0
def
inc
(
self
):
self
.
value
+=
1
def
dec
(
self
):
self
.
value
-=
1
def
get
(
self
):
return
self
.
value
class
TestThread
(
threading
.
Thread
):
def
__init__
(
self
,
name
,
testcase
,
sema
,
mutex
,
nrunning
):
threading
.
Thread
.
__init__
(
self
,
name
=
name
)
self
.
testcase
=
testcase
self
.
sema
=
sema
self
.
mutex
=
mutex
self
.
nrunning
=
nrunning
def
run
(
self
):
delay
=
random
.
random
()
*
2
if
verbose
:
print
'task'
,
self
.
getName
(),
'will run for'
,
delay
,
'sec'
self
.
sema
.
acquire
()
self
.
mutex
.
acquire
()
self
.
nrunning
.
inc
()
if
verbose
:
print
self
.
nrunning
.
get
(),
'tasks are running'
self
.
testcase
.
assert_
(
self
.
nrunning
.
get
()
<=
3
)
self
.
mutex
.
release
()
time
.
sleep
(
delay
)
if
verbose
:
print
'task'
,
self
.
getName
(),
'done'
self
.
mutex
.
acquire
()
self
.
nrunning
.
dec
()
self
.
testcase
.
assert_
(
self
.
nrunning
.
get
()
>=
0
)
if
verbose
:
print
self
.
getName
(),
'is finished.'
,
self
.
nrunning
.
get
(),
\
'tasks are running'
self
.
mutex
.
release
()
self
.
sema
.
release
()
class
ThreadTests
(
unittest
.
TestCase
):
# Create a bunch of threads, let each do some work, wait until all are
# done.
def
test_various_ops
(
self
):
# This takes about n/3 seconds to run (about n/3 clumps of tasks,
# times about 1 second per clump).
NUMTASKS
=
10
# no more than 3 of the 10 can run at once
sema
=
threading
.
BoundedSemaphore
(
value
=
3
)
mutex
=
threading
.
RLock
()
numrunning
=
Counter
()
threads
=
[]
for
i
in
range
(
NUMTASKS
):
t
=
TestThread
(
"<thread %d>"
%
i
,
self
,
sema
,
mutex
,
numrunning
)
threads
.
append
(
t
)
t
.
start
()
if
verbose
:
print
'waiting for all tasks to complete'
for
t
in
threads
:
t
.
join
(
NUMTASKS
)
self
.
assert_
(
not
t
.
isAlive
())
if
verbose
:
print
'all tasks done'
self
.
assertEqual
(
numrunning
.
get
(),
0
)
# run with a small(ish) thread stack size (256kB)
def
test_various_ops_small_stack
(
self
):
if
verbose
:
print
'with 256kB thread stack size...'
try
:
threading
.
stack_size
(
262144
)
except
thread
.
error
:
if
verbose
:
print
'platform does not support changing thread stack size'
return
self
.
test_various_ops
()
threading
.
stack_size
(
0
)
# run with a large thread stack size (1MB)
def
test_various_ops_large_stack
(
self
):
if
verbose
:
print
'with 1MB thread stack size...'
try
:
threading
.
stack_size
(
0x100000
)
except
thread
.
error
:
if
verbose
:
print
'platform does not support changing thread stack size'
return
self
.
test_various_ops
()
threading
.
stack_size
(
0
)
def
test_foreign_thread
(
self
):
# Check that a "foreign" thread can use the threading module.
def
f
(
mutex
):
# Acquiring an RLock forces an entry for the foreign
# thread to get made in the threading._active map.
r
=
threading
.
RLock
()
r
.
acquire
()
r
.
release
()
mutex
.
release
()
mutex
=
threading
.
Lock
()
mutex
.
acquire
()
tid
=
thread
.
start_new_thread
(
f
,
(
mutex
,))
# Wait for the thread to finish.
mutex
.
acquire
()
self
.
assert_
(
tid
in
threading
.
_active
)
self
.
assert_
(
isinstance
(
threading
.
_active
[
tid
],
threading
.
_DummyThread
))
del
threading
.
_active
[
tid
]
# PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently)
# exposed at the Python level. This test relies on ctypes to get at it.
def
test_PyThreadState_SetAsyncExc
(
self
):
try
:
import
ctypes
except
ImportError
:
if
verbose
:
print
"test_PyThreadState_SetAsyncExc can't import ctypes"
return
# can't do anything
set_async_exc
=
ctypes
.
pythonapi
.
PyThreadState_SetAsyncExc
class
AsyncExc
(
Exception
):
pass
exception
=
ctypes
.
py_object
(
AsyncExc
)
# `worker_started` is set by the thread when it's inside a try/except
# block waiting to catch the asynchronously set AsyncExc exception.
# `worker_saw_exception` is set by the thread upon catching that
# exception.
worker_started
=
threading
.
Event
()
worker_saw_exception
=
threading
.
Event
()
class
Worker
(
threading
.
Thread
):
def
run
(
self
):
self
.
id
=
thread
.
get_ident
()
self
.
finished
=
False
try
:
while
True
:
worker_started
.
set
()
time
.
sleep
(
0.1
)
except
AsyncExc
:
self
.
finished
=
True
worker_saw_exception
.
set
()
t
=
Worker
()
t
.
setDaemon
(
True
)
# so if this fails, we don't hang Python at shutdown
t
.
start
()
if
verbose
:
print
" started worker thread"
# Try a thread id that doesn't make sense.
if
verbose
:
print
" trying nonsensical thread id"
result
=
set_async_exc
(
ctypes
.
c_long
(
-
1
),
exception
)
self
.
assertEqual
(
result
,
0
)
# no thread states modified
# Now raise an exception in the worker thread.
if
verbose
:
print
" waiting for worker thread to get started"
worker_started
.
wait
()
if
verbose
:
print
" verifying worker hasn't exited"
self
.
assert_
(
not
t
.
finished
)
if
verbose
:
print
" attempting to raise asynch exception in worker"
result
=
set_async_exc
(
ctypes
.
c_long
(
t
.
id
),
exception
)
self
.
assertEqual
(
result
,
1
)
# one thread state modified
if
verbose
:
print
" waiting for worker to say it caught the exception"
worker_saw_exception
.
wait
(
timeout
=
10
)
self
.
assert_
(
t
.
finished
)
if
verbose
:
print
" all OK -- joining worker"
if
t
.
finished
:
t
.
join
()
# else the thread is still running, and we have no way to kill it
def
test_enumerate_after_join
(
self
):
# Try hard to trigger #1703448: a thread is still returned in
# threading.enumerate() after it has been join()ed.
enum
=
threading
.
enumerate
old_interval
=
sys
.
getcheckinterval
()
sys
.
setcheckinterval
(
1
)
try
:
for
i
in
xrange
(
1
,
1000
):
t
=
threading
.
Thread
(
target
=
lambda
:
None
)
t
.
start
()
t
.
join
()
l
=
enum
()
self
.
assertFalse
(
t
in
l
,
"#1703448 triggered after %d trials: %s"
%
(
i
,
l
))
finally
:
sys
.
setcheckinterval
(
old_interval
)
class
ThreadJoinOnShutdown
(
unittest
.
TestCase
):
def
_run_and_join
(
self
,
script
):
script
=
"""if 1:
import sys, os, time, threading
# a thread, which waits for the main program to terminate
def joiningfunc(mainthread):
mainthread.join()
print 'end of thread'
\
n
"""
+
script
import
subprocess
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
script
],
stdout
=
subprocess
.
PIPE
)
rc
=
p
.
wait
()
data
=
p
.
stdout
.
read
().
replace
(
'
\
r
'
,
''
)
self
.
assertEqual
(
data
,
"end of main
\
n
end of thread
\
n
"
)
self
.
failIf
(
rc
==
2
,
"interpreter was blocked"
)
self
.
failUnless
(
rc
==
0
,
"Unexpected error"
)
def
test_1_join_on_shutdown
(
self
):
# The usual case: on exit, wait for a non-daemon thread
script
=
"""if 1:
import os
t = threading.Thread(target=joiningfunc,
args=(threading.currentThread(),))
t.start()
time.sleep(0.1)
print 'end of main'
"""
self
.
_run_and_join
(
script
)
def
test_2_join_in_forked_process
(
self
):
# Like the test above, but from a forked interpreter
import
os
if
not
hasattr
(
os
,
'fork'
):
return
script
=
"""if 1:
childpid = os.fork()
if childpid != 0:
os.waitpid(childpid, 0)
sys.exit(0)
t = threading.Thread(target=joiningfunc,
args=(threading.currentThread(),))
t.start()
print 'end of main'
"""
self
.
_run_and_join
(
script
)
def
test_3_join_in_forked_from_thread
(
self
):
# Like the test above, but fork() was called from a worker thread
# In the forked process, the main Thread object must be marked as stopped.
import
os
if
not
hasattr
(
os
,
'fork'
):
return
# Skip platforms with known problems forking from a worker thread.
# See http://bugs.python.org/issue3863.
if
sys
.
platform
in
(
'freebsd4'
,
'freebsd5'
,
'freebsd6'
,
'os2emx'
):
print
>>
sys
.
stderr
,
(
'Skipping test_3_join_in_forked_from_thread'
' due to known OS bugs on'
),
sys
.
platform
return
script
=
"""if 1:
main_thread = threading.currentThread()
def worker():
childpid = os.fork()
if childpid != 0:
os.waitpid(childpid, 0)
sys.exit(0)
t = threading.Thread(target=joiningfunc,
args=(main_thread,))
print 'end of main'
t.start()
t.join() # Should not block: main_thread is already stopped
w = threading.Thread(target=worker)
w.start()
"""
self
.
_run_and_join
(
script
)
def
test_main
():
test
.
test_support
.
run_unittest
(
ThreadTests
,
ThreadJoinOnShutdown
)
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_threading_local.py
deleted
100644 → 0
View file @
ed74f199
import
gc
import
threading
import
unittest
from
doctest
import
DocTestSuite
from
test
import
test_support
class
ThreadingLocalTest
(
unittest
.
TestCase
):
def
test_derived
(
self
):
# Issue 3088: if there is a threads switch inside the __init__
# of a threading.local derived class, the per-thread dictionary
# is created but not correctly set on the object.
# The first member set may be bogus.
import
time
class
Local
(
threading
.
local
):
def
__init__
(
self
):
time
.
sleep
(
0.01
)
local
=
Local
()
def
f
(
i
):
local
.
x
=
i
# Simply check that the variable is correctly set
self
.
assertEqual
(
local
.
x
,
i
)
threads
=
[]
for
i
in
range
(
10
):
t
=
threading
.
Thread
(
target
=
f
,
args
=
(
i
,))
t
.
start
()
threads
.
append
(
t
)
for
t
in
threads
:
t
.
join
()
def
test_derived_cycle_dealloc
(
self
):
# http://bugs.python.org/issue6990
class
Local
(
threading
.
local
):
pass
locals
=
None
passed
=
[
False
]
e1
=
threading
.
Event
()
e2
=
threading
.
Event
()
def
f
():
# 1) Involve Local in a cycle
cycle
=
[
Local
()]
cycle
.
append
(
cycle
)
cycle
[
0
].
foo
=
'bar'
# 2) GC the cycle (triggers threadmodule.c::local_clear
# before local_dealloc)
del
cycle
gc
.
collect
()
e1
.
set
()
e2
.
wait
()
# 4) New Locals should be empty
passed
[
0
]
=
all
(
not
hasattr
(
local
,
'foo'
)
for
local
in
locals
)
t
=
threading
.
Thread
(
target
=
f
)
t
.
start
()
e1
.
wait
()
# 3) New Locals should recycle the original's address. Creating
# them in the thread overwrites the thread state and avoids the
# bug
locals
=
[
Local
()
for
i
in
range
(
10
)]
e2
.
set
()
t
.
join
()
self
.
assertTrue
(
passed
[
0
])
def
test_main
():
suite
=
DocTestSuite
(
'_threading_local'
)
try
:
from
thread
import
_local
except
ImportError
:
pass
else
:
import
_threading_local
local_orig
=
_threading_local
.
local
def
setUp
(
test
):
_threading_local
.
local
=
_local
def
tearDown
(
test
):
_threading_local
.
local
=
local_orig
suite
.
addTest
(
DocTestSuite
(
'_threading_local'
,
setUp
=
setUp
,
tearDown
=
tearDown
)
)
suite
.
addTest
(
unittest
.
makeSuite
(
ThreadingLocalTest
))
test_support
.
run_suite
(
suite
)
if
__name__
==
'__main__'
:
test_main
()
greentest/2.5/test_timeout.py
deleted
100644 → 0
View file @
ed74f199
"""Unit tests for socket timeout feature."""
import
unittest
from
test
import
test_support
# This requires the 'network' resource as given on the regrtest command line.
skip_expected
=
not
test_support
.
is_resource_enabled
(
'network'
)
import
time
import
socket
class
CreationTestCase
(
unittest
.
TestCase
):
"""Test case for socket.gettimeout() and socket.settimeout()"""
def
setUp
(
self
):
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
def
tearDown
(
self
):
self
.
sock
.
close
()
def
testObjectCreation
(
self
):
# Test Socket creation
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
None
,
"timeout not disabled by default"
)
def
testFloatReturnValue
(
self
):
# Test return value of gettimeout()
self
.
sock
.
settimeout
(
7.345
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
7.345
)
self
.
sock
.
settimeout
(
3
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
3
)
self
.
sock
.
settimeout
(
None
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
None
)
def
testReturnType
(
self
):
# Test return type of gettimeout()
self
.
sock
.
settimeout
(
1
)
self
.
assertEqual
(
type
(
self
.
sock
.
gettimeout
()),
type
(
1.0
))
self
.
sock
.
settimeout
(
3.9
)
self
.
assertEqual
(
type
(
self
.
sock
.
gettimeout
()),
type
(
1.0
))
def
testTypeCheck
(
self
):
# Test type checking by settimeout()
self
.
sock
.
settimeout
(
0
)
self
.
sock
.
settimeout
(
0L
)
self
.
sock
.
settimeout
(
0.0
)
self
.
sock
.
settimeout
(
None
)
self
.
assertRaises
(
TypeError
,
self
.
sock
.
settimeout
,
""
)
self
.
assertRaises
(
TypeError
,
self
.
sock
.
settimeout
,
u""
)
self
.
assertRaises
(
TypeError
,
self
.
sock
.
settimeout
,
())
self
.
assertRaises
(
TypeError
,
self
.
sock
.
settimeout
,
[])
self
.
assertRaises
(
TypeError
,
self
.
sock
.
settimeout
,
{})
self
.
assertRaises
(
TypeError
,
self
.
sock
.
settimeout
,
0j
)
def
testRangeCheck
(
self
):
# Test range checking by settimeout()
self
.
assertRaises
(
ValueError
,
self
.
sock
.
settimeout
,
-
1
)
self
.
assertRaises
(
ValueError
,
self
.
sock
.
settimeout
,
-
1L
)
self
.
assertRaises
(
ValueError
,
self
.
sock
.
settimeout
,
-
1.0
)
def
testTimeoutThenBlocking
(
self
):
# Test settimeout() followed by setblocking()
self
.
sock
.
settimeout
(
10
)
self
.
sock
.
setblocking
(
1
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
None
)
self
.
sock
.
setblocking
(
0
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
0.0
)
self
.
sock
.
settimeout
(
10
)
self
.
sock
.
setblocking
(
0
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
0.0
)
self
.
sock
.
setblocking
(
1
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
None
)
def
testBlockingThenTimeout
(
self
):
# Test setblocking() followed by settimeout()
self
.
sock
.
setblocking
(
0
)
self
.
sock
.
settimeout
(
1
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
1
)
self
.
sock
.
setblocking
(
1
)
self
.
sock
.
settimeout
(
1
)
self
.
assertEqual
(
self
.
sock
.
gettimeout
(),
1
)
class
TimeoutTestCase
(
unittest
.
TestCase
):
"""Test case for socket.socket() timeout functions"""
# There are a number of tests here trying to make sure that an operation
# doesn't take too much longer than expected. But competing machine
# activity makes it inevitable that such tests will fail at times.
# When fuzz was at 1.0, I (tim) routinely saw bogus failures on Win2K
# and Win98SE. Boosting it to 2.0 helped a lot, but isn't a real
# solution.
fuzz
=
2.0
def
setUp
(
self
):
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
addr_remote
=
(
'www.python.org.'
,
80
)
self
.
addr_local
=
(
'127.0.0.1'
,
25339
)
def
tearDown
(
self
):
self
.
sock
.
close
()
def
testConnectTimeout
(
self
):
# Test connect() timeout
_timeout
=
0.001
self
.
sock
.
settimeout
(
_timeout
)
# If we are too close to www.python.org, this test will fail.
# Pick a host that should be farther away.
if
(
socket
.
getfqdn
().
split
(
'.'
)[
-
2
:]
==
[
'python'
,
'org'
]
or
socket
.
getfqdn
().
split
(
'.'
)[
-
2
:
-
1
]
==
[
'xs4all'
]):
self
.
addr_remote
=
(
'tut.fi'
,
80
)
_t1
=
time
.
time
()
self
.
failUnlessRaises
(
socket
.
error
,
self
.
sock
.
connect
,
self
.
addr_remote
)
_t2
=
time
.
time
()
_delta
=
abs
(
_t1
-
_t2
)
self
.
assert_
(
_delta
<
_timeout
+
self
.
fuzz
,
"timeout (%g) is more than %g seconds more than expected (%g)"
%
(
_delta
,
self
.
fuzz
,
_timeout
))
def
testRecvTimeout
(
self
):
# Test recv() timeout
_timeout
=
0.02
self
.
sock
.
connect
(
self
.
addr_remote
)
self
.
sock
.
settimeout
(
_timeout
)
_t1
=
time
.
time
()
self
.
failUnlessRaises
(
socket
.
error
,
self
.
sock
.
recv
,
1024
)
_t2
=
time
.
time
()
_delta
=
abs
(
_t1
-
_t2
)
self
.
assert_
(
_delta
<
_timeout
+
self
.
fuzz
,
"timeout (%g) is %g seconds more than expected (%g)"
%
(
_delta
,
self
.
fuzz
,
_timeout
))
def
testAcceptTimeout
(
self
):
# Test accept() timeout
_timeout
=
2
self
.
sock
.
settimeout
(
_timeout
)
self
.
sock
.
bind
(
self
.
addr_local
)
self
.
sock
.
listen
(
5
)
_t1
=
time
.
time
()
self
.
failUnlessRaises
(
socket
.
error
,
self
.
sock
.
accept
)
_t2
=
time
.
time
()
_delta
=
abs
(
_t1
-
_t2
)
self
.
assert_
(
_delta
<
_timeout
+
self
.
fuzz
,
"timeout (%g) is %g seconds more than expected (%g)"
%
(
_delta
,
self
.
fuzz
,
_timeout
))
def
testRecvfromTimeout
(
self
):
# Test recvfrom() timeout
_timeout
=
2
self
.
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_DGRAM
)
self
.
sock
.
settimeout
(
_timeout
)
self
.
sock
.
bind
(
self
.
addr_local
)
_t1
=
time
.
time
()
self
.
failUnlessRaises
(
socket
.
error
,
self
.
sock
.
recvfrom
,
8192
)
_t2
=
time
.
time
()
_delta
=
abs
(
_t1
-
_t2
)
self
.
assert_
(
_delta
<
_timeout
+
self
.
fuzz
,
"timeout (%g) is %g seconds more than expected (%g)"
%
(
_delta
,
self
.
fuzz
,
_timeout
))
def
testSend
(
self
):
# Test send() timeout
# couldn't figure out how to test it
pass
def
testSendto
(
self
):
# Test sendto() timeout
# couldn't figure out how to test it
pass
def
testSendall
(
self
):
# Test sendall() timeout
# couldn't figure out how to test it
pass
def
test_main
():
test_support
.
requires
(
'network'
)
test_support
.
run_unittest
(
CreationTestCase
,
TimeoutTestCase
)
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_urllib.py
deleted
100644 → 0
View file @
ed74f199
"""Regresssion tests for urllib"""
import
urllib
import
httplib
import
unittest
from
test
import
test_support
import
os
import
mimetools
import
tempfile
import
StringIO
def
hexescape
(
char
):
"""Escape char as RFC 2396 specifies"""
hex_repr
=
hex
(
ord
(
char
))[
2
:].
upper
()
if
len
(
hex_repr
)
==
1
:
hex_repr
=
"0%s"
%
hex_repr
return
"%"
+
hex_repr
class
urlopen_FileTests
(
unittest
.
TestCase
):
"""Test urlopen() opening a temporary file.
Try to test as much functionality as possible so as to cut down on reliance
on connecting to the Net for testing.
"""
def
setUp
(
self
):
"""Setup of a temp file to use for testing"""
self
.
text
=
"test_urllib: %s
\
n
"
%
self
.
__class__
.
__name__
FILE
=
file
(
test_support
.
TESTFN
,
'wb'
)
try
:
FILE
.
write
(
self
.
text
)
finally
:
FILE
.
close
()
self
.
pathname
=
test_support
.
TESTFN
self
.
returned_obj
=
urllib
.
urlopen
(
"file:%s"
%
self
.
pathname
)
def
tearDown
(
self
):
"""Shut down the open object"""
self
.
returned_obj
.
close
()
os
.
remove
(
test_support
.
TESTFN
)
def
test_interface
(
self
):
# Make sure object returned by urlopen() has the specified methods
for
attr
in
(
"read"
,
"readline"
,
"readlines"
,
"fileno"
,
"close"
,
"info"
,
"geturl"
,
"__iter__"
):
self
.
assert_
(
hasattr
(
self
.
returned_obj
,
attr
),
"object returned by urlopen() lacks %s attribute"
%
attr
)
def
test_read
(
self
):
self
.
assertEqual
(
self
.
text
,
self
.
returned_obj
.
read
())
def
test_readline
(
self
):
self
.
assertEqual
(
self
.
text
,
self
.
returned_obj
.
readline
())
self
.
assertEqual
(
''
,
self
.
returned_obj
.
readline
(),
"calling readline() after exhausting the file did not"
" return an empty string"
)
def
test_readlines
(
self
):
lines_list
=
self
.
returned_obj
.
readlines
()
self
.
assertEqual
(
len
(
lines_list
),
1
,
"readlines() returned the wrong number of lines"
)
self
.
assertEqual
(
lines_list
[
0
],
self
.
text
,
"readlines() returned improper text"
)
def
test_fileno
(
self
):
file_num
=
self
.
returned_obj
.
fileno
()
self
.
assert_
(
isinstance
(
file_num
,
int
),
"fileno() did not return an int"
)
self
.
assertEqual
(
os
.
read
(
file_num
,
len
(
self
.
text
)),
self
.
text
,
"Reading on the file descriptor returned by fileno() "
"did not return the expected text"
)
def
test_close
(
self
):
# Test close() by calling it hear and then having it be called again
# by the tearDown() method for the test
self
.
returned_obj
.
close
()
def
test_info
(
self
):
self
.
assert_
(
isinstance
(
self
.
returned_obj
.
info
(),
mimetools
.
Message
))
def
test_geturl
(
self
):
self
.
assertEqual
(
self
.
returned_obj
.
geturl
(),
self
.
pathname
)
def
test_iter
(
self
):
# Test iterator
# Don't need to count number of iterations since test would fail the
# instant it returned anything beyond the first line from the
# comparison
for
line
in
self
.
returned_obj
.
__iter__
():
self
.
assertEqual
(
line
,
self
.
text
)
class
urlopen_HttpTests
(
unittest
.
TestCase
):
"""Test urlopen() opening a fake http connection."""
def
fakehttp
(
self
,
fakedata
):
class
FakeSocket
(
StringIO
.
StringIO
):
def
sendall
(
self
,
str
):
pass
def
makefile
(
self
,
mode
,
name
):
return
self
def
read
(
self
,
amt
=
None
):
if
self
.
closed
:
return
''
return
StringIO
.
StringIO
.
read
(
self
,
amt
)
def
readline
(
self
,
length
=
None
):
if
self
.
closed
:
return
''
return
StringIO
.
StringIO
.
readline
(
self
,
length
)
class
FakeHTTPConnection
(
httplib
.
HTTPConnection
):
def
connect
(
self
):
self
.
sock
=
FakeSocket
(
fakedata
)
assert
httplib
.
HTTP
.
_connection_class
==
httplib
.
HTTPConnection
httplib
.
HTTP
.
_connection_class
=
FakeHTTPConnection
def
unfakehttp
(
self
):
httplib
.
HTTP
.
_connection_class
=
httplib
.
HTTPConnection
def
test_read
(
self
):
self
.
fakehttp
(
'Hello!'
)
try
:
fp
=
urllib
.
urlopen
(
"http://python.org/"
)
self
.
assertEqual
(
fp
.
readline
(),
'Hello!'
)
self
.
assertEqual
(
fp
.
readline
(),
''
)
finally
:
self
.
unfakehttp
()
def
test_invalid_redirect
(
self
):
# urlopen() should raise IOError for many error codes.
self
.
fakehttp
(
"""HTTP/1.1 302 Found
Date: Wed, 02 Jan 2008 03:03:54 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
Location: file:README
Connection: close
Content-Type: text/html; charset=iso-8859-1
"""
)
try
:
self
.
assertRaises
(
IOError
,
urllib
.
urlopen
,
"http://python.org/"
)
finally
:
self
.
unfakehttp
()
def
test_empty_socket
(
self
):
"""urlopen() raises IOError if the underlying socket does not send any
data. (#1680230) """
self
.
fakehttp
(
''
)
try
:
self
.
assertRaises
(
IOError
,
urllib
.
urlopen
,
'http://something'
)
finally
:
self
.
unfakehttp
()
class
urlretrieve_FileTests
(
unittest
.
TestCase
):
"""Test urllib.urlretrieve() on local files"""
def
setUp
(
self
):
# Create a list of temporary files. Each item in the list is a file
# name (absolute path or relative to the current working directory).
# All files in this list will be deleted in the tearDown method. Note,
# this only helps to makes sure temporary files get deleted, but it
# does nothing about trying to close files that may still be open. It
# is the responsibility of the developer to properly close files even
# when exceptional conditions occur.
self
.
tempFiles
=
[]
# Create a temporary file.
self
.
registerFileForCleanUp
(
test_support
.
TESTFN
)
self
.
text
=
'testing urllib.urlretrieve'
try
:
FILE
=
file
(
test_support
.
TESTFN
,
'wb'
)
FILE
.
write
(
self
.
text
)
FILE
.
close
()
finally
:
try
:
FILE
.
close
()
except
:
pass
def
tearDown
(
self
):
# Delete the temporary files.
for
each
in
self
.
tempFiles
:
try
:
os
.
remove
(
each
)
except
:
pass
def
constructLocalFileUrl
(
self
,
filePath
):
return
"file://%s"
%
urllib
.
pathname2url
(
os
.
path
.
abspath
(
filePath
))
def
createNewTempFile
(
self
,
data
=
""
):
"""Creates a new temporary file containing the specified data,
registers the file for deletion during the test fixture tear down, and
returns the absolute path of the file."""
newFd
,
newFilePath
=
tempfile
.
mkstemp
()
try
:
self
.
registerFileForCleanUp
(
newFilePath
)
newFile
=
os
.
fdopen
(
newFd
,
"wb"
)
newFile
.
write
(
data
)
newFile
.
close
()
finally
:
try
:
newFile
.
close
()
except
:
pass
return
newFilePath
def
registerFileForCleanUp
(
self
,
fileName
):
self
.
tempFiles
.
append
(
fileName
)
def
test_basic
(
self
):
# Make sure that a local file just gets its own location returned and
# a headers value is returned.
result
=
urllib
.
urlretrieve
(
"file:%s"
%
test_support
.
TESTFN
)
self
.
assertEqual
(
result
[
0
],
test_support
.
TESTFN
)
self
.
assert_
(
isinstance
(
result
[
1
],
mimetools
.
Message
),
"did not get a mimetools.Message instance as second "
"returned value"
)
def
test_copy
(
self
):
# Test that setting the filename argument works.
second_temp
=
"%s.2"
%
test_support
.
TESTFN
self
.
registerFileForCleanUp
(
second_temp
)
result
=
urllib
.
urlretrieve
(
self
.
constructLocalFileUrl
(
test_support
.
TESTFN
),
second_temp
)
self
.
assertEqual
(
second_temp
,
result
[
0
])
self
.
assert_
(
os
.
path
.
exists
(
second_temp
),
"copy of the file was not "
"made"
)
FILE
=
file
(
second_temp
,
'rb'
)
try
:
text
=
FILE
.
read
()
FILE
.
close
()
finally
:
try
:
FILE
.
close
()
except
:
pass
self
.
assertEqual
(
self
.
text
,
text
)
def
test_reporthook
(
self
):
# Make sure that the reporthook works.
def
hooktester
(
count
,
block_size
,
total_size
,
count_holder
=
[
0
]):
self
.
assert_
(
isinstance
(
count
,
int
))
self
.
assert_
(
isinstance
(
block_size
,
int
))
self
.
assert_
(
isinstance
(
total_size
,
int
))
self
.
assertEqual
(
count
,
count_holder
[
0
])
count_holder
[
0
]
=
count_holder
[
0
]
+
1
second_temp
=
"%s.2"
%
test_support
.
TESTFN
self
.
registerFileForCleanUp
(
second_temp
)
urllib
.
urlretrieve
(
self
.
constructLocalFileUrl
(
test_support
.
TESTFN
),
second_temp
,
hooktester
)
def
test_reporthook_0_bytes
(
self
):
# Test on zero length file. Should call reporthook only 1 time.
report
=
[]
def
hooktester
(
count
,
block_size
,
total_size
,
_report
=
report
):
_report
.
append
((
count
,
block_size
,
total_size
))
srcFileName
=
self
.
createNewTempFile
()
urllib
.
urlretrieve
(
self
.
constructLocalFileUrl
(
srcFileName
),
test_support
.
TESTFN
,
hooktester
)
self
.
assertEqual
(
len
(
report
),
1
)
self
.
assertEqual
(
report
[
0
][
2
],
0
)
def
test_reporthook_5_bytes
(
self
):
# Test on 5 byte file. Should call reporthook only 2 times (once when
# the "network connection" is established and once when the block is
# read). Since the block size is 8192 bytes, only one block read is
# required to read the entire file.
report
=
[]
def
hooktester
(
count
,
block_size
,
total_size
,
_report
=
report
):
_report
.
append
((
count
,
block_size
,
total_size
))
srcFileName
=
self
.
createNewTempFile
(
"x"
*
5
)
urllib
.
urlretrieve
(
self
.
constructLocalFileUrl
(
srcFileName
),
test_support
.
TESTFN
,
hooktester
)
self
.
assertEqual
(
len
(
report
),
2
)
self
.
assertEqual
(
report
[
0
][
1
],
8192
)
self
.
assertEqual
(
report
[
0
][
2
],
5
)
def
test_reporthook_8193_bytes
(
self
):
# Test on 8193 byte file. Should call reporthook only 3 times (once
# when the "network connection" is established, once for the next 8192
# bytes, and once for the last byte).
report
=
[]
def
hooktester
(
count
,
block_size
,
total_size
,
_report
=
report
):
_report
.
append
((
count
,
block_size
,
total_size
))
srcFileName
=
self
.
createNewTempFile
(
"x"
*
8193
)
urllib
.
urlretrieve
(
self
.
constructLocalFileUrl
(
srcFileName
),
test_support
.
TESTFN
,
hooktester
)
self
.
assertEqual
(
len
(
report
),
3
)
self
.
assertEqual
(
report
[
0
][
1
],
8192
)
self
.
assertEqual
(
report
[
0
][
2
],
8193
)
class
QuotingTests
(
unittest
.
TestCase
):
"""Tests for urllib.quote() and urllib.quote_plus()
According to RFC 2396 ("Uniform Resource Identifiers), to escape a
character you write it as '%' + <2 character US-ASCII hex value>. The Python
code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
Case does not matter on the hex letters.
The various character sets specified are:
Reserved characters : ";/?:@&=+$,"
Have special meaning in URIs and must be escaped if not being used for
their special meaning
Data characters : letters, digits, and "-_.!~*'()"
Unreserved and do not need to be escaped; can be, though, if desired
Control characters : 0x00 - 0x1F, 0x7F
Have no use in URIs so must be escaped
space : 0x20
Must be escaped
Delimiters : '<>#%"'
Must be escaped
Unwise : "{}|
\
^[]`
"
Must be escaped
"""
def
test_never_quote
(
self
):
# Make sure quote() does not quote letters, digits, and "_,.-"
do_not_quote
=
''
.
join
([
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
,
"abcdefghijklmnopqrstuvwxyz"
,
"0123456789"
,
"_.-"
])
result
=
urllib
.
quote
(
do_not_quote
)
self
.
assertEqual
(
do_not_quote
,
result
,
"using quote(): %s != %s"
%
(
do_not_quote
,
result
))
result
=
urllib
.
quote_plus
(
do_not_quote
)
self
.
assertEqual
(
do_not_quote
,
result
,
"using quote_plus(): %s != %s"
%
(
do_not_quote
,
result
))
def
test_default_safe
(
self
):
# Test '/' is default value for 'safe' parameter
self
.
assertEqual
(
urllib
.
quote
.
func_defaults
[
0
],
'/'
)
def
test_safe
(
self
):
# Test setting 'safe' parameter does what it should do
quote_by_default
=
"<>"
result
=
urllib
.
quote
(
quote_by_default
,
safe
=
quote_by_default
)
self
.
assertEqual
(
quote_by_default
,
result
,
"using quote(): %s != %s"
%
(
quote_by_default
,
result
))
result
=
urllib
.
quote_plus
(
quote_by_default
,
safe
=
quote_by_default
)
self
.
assertEqual
(
quote_by_default
,
result
,
"using quote_plus(): %s != %s"
%
(
quote_by_default
,
result
))
def
test_default_quoting
(
self
):
# Make sure all characters that should be quoted are by default sans
# space (separate test for that).
should_quote
=
[
chr
(
num
)
for
num
in
range
(
32
)]
# For 0x00 - 0x1F
should_quote
.
append
(
'<>#%"{}|
\
^[]`
'
)
should_quote.append(chr(127)) # For 0x7F
should_quote = ''.join(should_quote)
for char in should_quote:
result = urllib.quote(char)
self.assertEqual(hexescape(char), result,
"using quote(): %s should be escaped to %s, not %s" %
(char, hexescape(char), result))
result = urllib.quote_plus(char)
self.assertEqual(hexescape(char), result,
"using quote_plus(): "
"%s should be escapes to %s, not %s" %
(char, hexescape(char), result))
del should_quote
partial_quote = "ab[]cd"
expected = "ab%5B%5Dcd"
result = urllib.quote(partial_quote)
self.assertEqual(expected, result,
"using quote(): %s != %s" % (expected, result))
self.assertEqual(expected, result,
"using quote_plus(): %s != %s" % (expected, result))
def test_quoting_space(self):
# Make sure quote() and quote_plus() handle spaces as specified in
# their unique way
result = urllib.quote('
')
self.assertEqual(result, hexescape('
'),
"using quote(): %s != %s" % (result, hexescape('
')))
result = urllib.quote_plus('
')
self.assertEqual(result, '
+
',
"using quote_plus(): %s != +" % result)
given = "a b cd e f"
expect = given.replace('
', hexescape('
'))
result = urllib.quote(given)
self.assertEqual(expect, result,
"using quote(): %s != %s" % (expect, result))
expect = given.replace('
', '
+
')
result = urllib.quote_plus(given)
self.assertEqual(expect, result,
"using quote_plus(): %s != %s" % (expect, result))
def test_quoting_plus(self):
self.assertEqual(urllib.quote_plus('
alpha
+
beta
gamma
'),
'
alpha
%
2
Bbeta
+
gamma
')
self.assertEqual(urllib.quote_plus('
alpha
+
beta
gamma
', '
+
'),
'
alpha
+
beta
+
gamma
')
class UnquotingTests(unittest.TestCase):
"""Tests for unquote() and unquote_plus()
See the doc string for quoting_Tests for details on quoting and such.
"""
def test_unquoting(self):
# Make sure unquoting of all ASCII values works
escape_list = []
for num in range(128):
given = hexescape(chr(num))
expect = chr(num)
result = urllib.unquote(given)
self.assertEqual(expect, result,
"using unquote(): %s != %s" % (expect, result))
result = urllib.unquote_plus(given)
self.assertEqual(expect, result,
"using unquote_plus(): %s != %s" %
(expect, result))
escape_list.append(given)
escape_string = ''.join(escape_list)
del escape_list
result = urllib.unquote(escape_string)
self.assertEqual(result.count('
%
'), 1,
"using quote(): not all characters escaped; %s" %
result)
result = urllib.unquote(escape_string)
self.assertEqual(result.count('
%
'), 1,
"using unquote(): not all characters escaped: "
"%s" % result)
def test_unquoting_parts(self):
# Make sure unquoting works when have non-quoted characters
# interspersed
given = '
ab
%
sd
' % hexescape('
c
')
expect = "abcd"
result = urllib.unquote(given)
self.assertEqual(expect, result,
"using quote(): %s != %s" % (expect, result))
result = urllib.unquote_plus(given)
self.assertEqual(expect, result,
"using unquote_plus(): %s != %s" % (expect, result))
def test_unquoting_plus(self):
# Test difference between unquote() and unquote_plus()
given = "are+there+spaces..."
expect = given
result = urllib.unquote(given)
self.assertEqual(expect, result,
"using unquote(): %s != %s" % (expect, result))
expect = given.replace('
+
', '
')
result = urllib.unquote_plus(given)
self.assertEqual(expect, result,
"using unquote_plus(): %s != %s" % (expect, result))
def test_unquote_with_unicode(self):
r = urllib.unquote(u'
br
%
C3
%
BCckner_sapporo_20050930
.
doc
')
self.assertEqual(r, u'
br
\
xc3
\
xbcckner_sapporo_20050930
.
doc
')
class urlencode_Tests(unittest.TestCase):
"""Tests for urlencode()"""
def help_inputtype(self, given, test_type):
"""Helper method for testing different input types.
'
given
' must lead to only the pairs:
* 1st, 1
* 2nd, 2
* 3rd, 3
Test cannot assume anything about order. Docs make no guarantee and
have possible dictionary input.
"""
expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
result = urllib.urlencode(given)
for expected in expect_somewhere:
self.assert_(expected in result,
"testing %s: %s not found in %s" %
(test_type, expected, result))
self.assertEqual(result.count('
&
'), 2,
"testing %s: expected 2 '
&
's; got %s" %
(test_type, result.count('
&
')))
amp_location = result.index('
&
')
on_amp_left = result[amp_location - 1]
on_amp_right = result[amp_location + 1]
self.assert_(on_amp_left.isdigit() and on_amp_right.isdigit(),
"testing %s: '
&
' not located in proper place in %s" %
(test_type, result))
self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
"testing %s: "
"unexpected number of characters: %s != %s" %
(test_type, len(result), (5 * 3) + 2))
def test_using_mapping(self):
# Test passing in a mapping object as an argument.
self.help_inputtype({"1st":'
1
', "2nd":'
2
', "3rd":'
3
'},
"using dict as input type")
def test_using_sequence(self):
# Test passing in a sequence of two-item sequences as an argument.
self.help_inputtype([('
1
st
', '
1
'), ('
2
nd
', '
2
'), ('
3
rd
', '
3
')],
"using sequence of two-item tuples as input")
def test_quoting(self):
# Make sure keys and values are quoted using quote_plus()
given = {"&":"="}
expect = "%s=%s" % (hexescape('
&
'), hexescape('
=
'))
result = urllib.urlencode(given)
self.assertEqual(expect, result)
given = {"key name":"A bunch of pluses"}
expect = "key+name=A+bunch+of+pluses"
result = urllib.urlencode(given)
self.assertEqual(expect, result)
def test_doseq(self):
# Test that passing True for '
doseq
' parameter works correctly
given = {'
sequence
':['
1
', '
2
', '
3
']}
expect = "sequence=%s" % urllib.quote_plus(str(['
1
', '
2
', '
3
']))
result = urllib.urlencode(given)
self.assertEqual(expect, result)
result = urllib.urlencode(given, True)
for value in given["sequence"]:
expect = "sequence=%s" % value
self.assert_(expect in result,
"%s not found in %s" % (expect, result))
self.assertEqual(result.count('
&
'), 2,
"Expected 2 '
&
's, got %s" % result.count('
&
'))
class Pathname_Tests(unittest.TestCase):
"""Test pathname2url() and url2pathname()"""
def test_basic(self):
# Make sure simple tests pass
expected_path = os.path.join("parts", "of", "a", "path")
expected_url = "parts/of/a/path"
result = urllib.pathname2url(expected_path)
self.assertEqual(expected_url, result,
"pathname2url() failed; %s != %s" %
(result, expected_url))
result = urllib.url2pathname(expected_url)
self.assertEqual(expected_path, result,
"url2pathame() failed; %s != %s" %
(result, expected_path))
def test_quoting(self):
# Test automatic quoting and unquoting works for pathnam2url() and
# url2pathname() respectively
given = os.path.join("needs", "quot=ing", "here")
expect = "needs/%s/here" % urllib.quote("quot=ing")
result = urllib.pathname2url(given)
self.assertEqual(expect, result,
"pathname2url() failed; %s != %s" %
(expect, result))
expect = given
result = urllib.url2pathname(result)
self.assertEqual(expect, result,
"url2pathname() failed; %s != %s" %
(expect, result))
given = os.path.join("make sure", "using_quote")
expect = "%s/using_quote" % urllib.quote("make sure")
result = urllib.pathname2url(given)
self.assertEqual(expect, result,
"pathname2url() failed; %s != %s" %
(expect, result))
given = "make+sure/using_unquote"
expect = os.path.join("make+sure", "using_unquote")
result = urllib.url2pathname(given)
self.assertEqual(expect, result,
"url2pathname() failed; %s != %s" %
(expect, result))
def test_main():
test_support.run_unittest(
urlopen_FileTests,
urlopen_HttpTests,
urlretrieve_FileTests,
QuotingTests,
UnquotingTests,
urlencode_Tests,
Pathname_Tests
)
if __name__ == '
__main__
':
test_main()
greentest/2.5/test_urllib2.py
deleted
100644 → 0
View file @
ed74f199
import
unittest
from
test
import
test_support
import
os
,
socket
import
StringIO
import
urllib2
from
urllib2
import
Request
,
OpenerDirector
# XXX
# Request
# CacheFTPHandler (hard to write)
# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler
class
TrivialTests
(
unittest
.
TestCase
):
def
test_trivial
(
self
):
# A couple trivial tests
self
.
assertRaises
(
ValueError
,
urllib2
.
urlopen
,
'bogus url'
)
# XXX Name hacking to get this to work on Windows.
fname
=
os
.
path
.
abspath
(
urllib2
.
__file__
).
replace
(
'
\
\
'
,
'/'
)
if
fname
[
1
:
2
]
==
":"
:
fname
=
fname
[
2
:]
# And more hacking to get it to work on MacOS. This assumes
# urllib.pathname2url works, unfortunately...
if
os
.
name
==
'mac'
:
fname
=
'/'
+
fname
.
replace
(
':'
,
'/'
)
elif
os
.
name
==
'riscos'
:
import
string
fname
=
os
.
expand
(
fname
)
fname
=
fname
.
translate
(
string
.
maketrans
(
"/."
,
"./"
))
file_url
=
"file://%s"
%
fname
f
=
urllib2
.
urlopen
(
file_url
)
buf
=
f
.
read
()
f
.
close
()
def
test_parse_http_list
(
self
):
tests
=
[(
'a,b,c'
,
[
'a'
,
'b'
,
'c'
]),
(
'path"o,l"og"i"cal, example'
,
[
'path"o,l"og"i"cal'
,
'example'
]),
(
'a, b, "c", "d", "e,f", g, h'
,
[
'a'
,
'b'
,
'"c"'
,
'"d"'
,
'"e,f"'
,
'g'
,
'h'
]),
(
'a="b
\
\
"c", d="e
\
\
,f", g="h
\
\
\
\
i"'
,
[
'a="b"c"'
,
'd="e,f"'
,
'g="h
\
\
i"'
])]
for
string
,
list
in
tests
:
self
.
assertEquals
(
urllib2
.
parse_http_list
(
string
),
list
)
def
test_request_headers_dict
():
"""
The Request.headers dictionary is not a documented interface. It should
stay that way, because the complete set of headers are only accessible
through the .get_header(), .has_header(), .header_items() interface.
However, .headers pre-dates those methods, and so real code will be using
the dictionary.
The introduction in 2.4 of those methods was a mistake for the same reason:
code that previously saw all (urllib2 user)-provided headers in .headers
now sees only a subset (and the function interface is ugly and incomplete).
A better change would have been to replace .headers dict with a dict
subclass (or UserDict.DictMixin instance?) that preserved the .headers
interface and also provided access to the "unredirected" headers. It's
probably too late to fix that, though.
Check .capitalize() case normalization:
>>> url = "http://example.com"
>>> Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
'blah'
>>> Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
'blah'
Currently, Request(url, "Spam-eggs").headers["Spam-Eggs"] raises KeyError,
but that could be changed in future.
"""
def
test_request_headers_methods
():
"""
Note the case normalization of header names here, to .capitalize()-case.
This should be preserved for backwards-compatibility. (In the HTTP case,
normalization to .title()-case is done by urllib2 before sending headers to
httplib).
>>> url = "http://example.com"
>>> r = Request(url, headers={"Spam-eggs": "blah"})
>>> r.has_header("Spam-eggs")
True
>>> r.header_items()
[('Spam-eggs', 'blah')]
>>> r.add_header("Foo-Bar", "baz")
>>> items = r.header_items()
>>> items.sort()
>>> items
[('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
Note that e.g. r.has_header("spam-EggS") is currently False, and
r.get_header("spam-EggS") returns None, but that could be changed in
future.
>>> r.has_header("Not-there")
False
>>> print r.get_header("Not-there")
None
>>> r.get_header("Not-there", "default")
'default'
"""
def
test_password_manager
(
self
):
"""
>>> mgr = urllib2.HTTPPasswordMgr()
>>> add = mgr.add_password
>>> add("Some Realm", "http://example.com/", "joe", "password")
>>> add("Some Realm", "http://example.com/ni", "ni", "ni")
>>> add("c", "http://example.com/foo", "foo", "ni")
>>> add("c", "http://example.com/bar", "bar", "nini")
>>> add("b", "http://example.com/", "first", "blah")
>>> add("b", "http://example.com/", "second", "spam")
>>> add("a", "http://example.com", "1", "a")
>>> add("Some Realm", "http://c.example.com:3128", "3", "c")
>>> add("Some Realm", "d.example.com", "4", "d")
>>> add("Some Realm", "e.example.com:3128", "5", "e")
>>> mgr.find_user_password("Some Realm", "example.com")
('joe', 'password')
>>> mgr.find_user_password("Some Realm", "http://example.com")
('joe', 'password')
>>> mgr.find_user_password("Some Realm", "http://example.com/")
('joe', 'password')
>>> mgr.find_user_password("Some Realm", "http://example.com/spam")
('joe', 'password')
>>> mgr.find_user_password("Some Realm", "http://example.com/spam/spam")
('joe', 'password')
>>> mgr.find_user_password("c", "http://example.com/foo")
('foo', 'ni')
>>> mgr.find_user_password("c", "http://example.com/bar")
('bar', 'nini')
Actually, this is really undefined ATM
## Currently, we use the highest-level path where more than one match:
## >>> mgr.find_user_password("Some Realm", "http://example.com/ni")
## ('joe', 'password')
Use latest add_password() in case of conflict:
>>> mgr.find_user_password("b", "http://example.com/")
('second', 'spam')
No special relationship between a.example.com and example.com:
>>> mgr.find_user_password("a", "http://example.com/")
('1', 'a')
>>> mgr.find_user_password("a", "http://a.example.com/")
(None, None)
Ports:
>>> mgr.find_user_password("Some Realm", "c.example.com")
(None, None)
>>> mgr.find_user_password("Some Realm", "c.example.com:3128")
('3', 'c')
>>> mgr.find_user_password("Some Realm", "http://c.example.com:3128")
('3', 'c')
>>> mgr.find_user_password("Some Realm", "d.example.com")
('4', 'd')
>>> mgr.find_user_password("Some Realm", "e.example.com:3128")
('5', 'e')
"""
pass
def
test_password_manager_default_port
(
self
):
"""
>>> mgr = urllib2.HTTPPasswordMgr()
>>> add = mgr.add_password
The point to note here is that we can't guess the default port if there's
no scheme. This applies to both add_password and find_user_password.
>>> add("f", "http://g.example.com:80", "10", "j")
>>> add("g", "http://h.example.com", "11", "k")
>>> add("h", "i.example.com:80", "12", "l")
>>> add("i", "j.example.com", "13", "m")
>>> mgr.find_user_password("f", "g.example.com:100")
(None, None)
>>> mgr.find_user_password("f", "g.example.com:80")
('10', 'j')
>>> mgr.find_user_password("f", "g.example.com")
(None, None)
>>> mgr.find_user_password("f", "http://g.example.com:100")
(None, None)
>>> mgr.find_user_password("f", "http://g.example.com:80")
('10', 'j')
>>> mgr.find_user_password("f", "http://g.example.com")
('10', 'j')
>>> mgr.find_user_password("g", "h.example.com")
('11', 'k')
>>> mgr.find_user_password("g", "h.example.com:80")
('11', 'k')
>>> mgr.find_user_password("g", "http://h.example.com:80")
('11', 'k')
>>> mgr.find_user_password("h", "i.example.com")
(None, None)
>>> mgr.find_user_password("h", "i.example.com:80")
('12', 'l')
>>> mgr.find_user_password("h", "http://i.example.com:80")
('12', 'l')
>>> mgr.find_user_password("i", "j.example.com")
('13', 'm')
>>> mgr.find_user_password("i", "j.example.com:80")
(None, None)
>>> mgr.find_user_password("i", "http://j.example.com")
('13', 'm')
>>> mgr.find_user_password("i", "http://j.example.com:80")
(None, None)
"""
class
MockOpener
:
addheaders
=
[]
def
open
(
self
,
req
,
data
=
None
):
self
.
req
,
self
.
data
=
req
,
data
def
error
(
self
,
proto
,
*
args
):
self
.
proto
,
self
.
args
=
proto
,
args
class
MockFile
:
def
read
(
self
,
count
=
None
):
pass
def
readline
(
self
,
count
=
None
):
pass
def
close
(
self
):
pass
class
MockHeaders
(
dict
):
def
getheaders
(
self
,
name
):
return
self
.
values
()
class
MockResponse
(
StringIO
.
StringIO
):
def
__init__
(
self
,
code
,
msg
,
headers
,
data
,
url
=
None
):
StringIO
.
StringIO
.
__init__
(
self
,
data
)
self
.
code
,
self
.
msg
,
self
.
headers
,
self
.
url
=
code
,
msg
,
headers
,
url
def
info
(
self
):
return
self
.
headers
def
geturl
(
self
):
return
self
.
url
class
MockCookieJar
:
def
add_cookie_header
(
self
,
request
):
self
.
ach_req
=
request
def
extract_cookies
(
self
,
response
,
request
):
self
.
ec_req
,
self
.
ec_r
=
request
,
response
class
FakeMethod
:
def
__init__
(
self
,
meth_name
,
action
,
handle
):
self
.
meth_name
=
meth_name
self
.
handle
=
handle
self
.
action
=
action
def
__call__
(
self
,
*
args
):
return
self
.
handle
(
self
.
meth_name
,
self
.
action
,
*
args
)
class
MockHandler
:
# useful for testing handler machinery
# see add_ordered_mock_handlers() docstring
handler_order
=
500
def
__init__
(
self
,
methods
):
self
.
_define_methods
(
methods
)
def
_define_methods
(
self
,
methods
):
for
spec
in
methods
:
if
len
(
spec
)
==
2
:
name
,
action
=
spec
else
:
name
,
action
=
spec
,
None
meth
=
FakeMethod
(
name
,
action
,
self
.
handle
)
setattr
(
self
.
__class__
,
name
,
meth
)
def
handle
(
self
,
fn_name
,
action
,
*
args
,
**
kwds
):
self
.
parent
.
calls
.
append
((
self
,
fn_name
,
args
,
kwds
))
if
action
is
None
:
return
None
elif
action
==
"return self"
:
return
self
elif
action
==
"return response"
:
res
=
MockResponse
(
200
,
"OK"
,
{},
""
)
return
res
elif
action
==
"return request"
:
return
Request
(
"http://blah/"
)
elif
action
.
startswith
(
"error"
):
code
=
action
[
action
.
rfind
(
" "
)
+
1
:]
try
:
code
=
int
(
code
)
except
ValueError
:
pass
res
=
MockResponse
(
200
,
"OK"
,
{},
""
)
return
self
.
parent
.
error
(
"http"
,
args
[
0
],
res
,
code
,
""
,
{})
elif
action
==
"raise"
:
raise
urllib2
.
URLError
(
"blah"
)
assert
False
def
close
(
self
):
pass
def
add_parent
(
self
,
parent
):
self
.
parent
=
parent
self
.
parent
.
calls
=
[]
def
__lt__
(
self
,
other
):
if
not
hasattr
(
other
,
"handler_order"
):
# No handler_order, leave in original order. Yuck.
return
True
return
self
.
handler_order
<
other
.
handler_order
def
add_ordered_mock_handlers
(
opener
,
meth_spec
):
"""Create MockHandlers and add them to an OpenerDirector.
meth_spec: list of lists of tuples and strings defining methods to define
on handlers. eg:
[["http_error", "ftp_open"], ["http_open"]]
defines methods .http_error() and .ftp_open() on one handler, and
.http_open() on another. These methods just record their arguments and
return None. Using a tuple instead of a string causes the method to
perform some action (see MockHandler.handle()), eg:
[["http_error"], [("http_open", "return request")]]
defines .http_error() on one handler (which simply returns None), and
.http_open() on another handler, which returns a Request object.
"""
handlers
=
[]
count
=
0
for
meths
in
meth_spec
:
class
MockHandlerSubclass
(
MockHandler
):
pass
h
=
MockHandlerSubclass
(
meths
)
h
.
handler_order
+=
count
h
.
add_parent
(
opener
)
count
=
count
+
1
handlers
.
append
(
h
)
opener
.
add_handler
(
h
)
return
handlers
def
build_test_opener
(
*
handler_instances
):
opener
=
OpenerDirector
()
for
h
in
handler_instances
:
opener
.
add_handler
(
h
)
return
opener
class
MockHTTPHandler
(
urllib2
.
BaseHandler
):
# useful for testing redirections and auth
# sends supplied headers and code as first response
# sends 200 OK as second response
def
__init__
(
self
,
code
,
headers
):
self
.
code
=
code
self
.
headers
=
headers
self
.
reset
()
def
reset
(
self
):
self
.
_count
=
0
self
.
requests
=
[]
def
http_open
(
self
,
req
):
import
mimetools
,
httplib
,
copy
from
StringIO
import
StringIO
self
.
requests
.
append
(
copy
.
deepcopy
(
req
))
if
self
.
_count
==
0
:
self
.
_count
=
self
.
_count
+
1
name
=
httplib
.
responses
[
self
.
code
]
msg
=
mimetools
.
Message
(
StringIO
(
self
.
headers
))
return
self
.
parent
.
error
(
"http"
,
req
,
MockFile
(),
self
.
code
,
name
,
msg
)
else
:
self
.
req
=
req
msg
=
mimetools
.
Message
(
StringIO
(
"
\
r
\
n
\
r
\
n
"
))
return
MockResponse
(
200
,
"OK"
,
msg
,
""
,
req
.
get_full_url
())
class
MockPasswordManager
:
def
add_password
(
self
,
realm
,
uri
,
user
,
password
):
self
.
realm
=
realm
self
.
url
=
uri
self
.
user
=
user
self
.
password
=
password
def
find_user_password
(
self
,
realm
,
authuri
):
self
.
target_realm
=
realm
self
.
target_url
=
authuri
return
self
.
user
,
self
.
password
class
OpenerDirectorTests
(
unittest
.
TestCase
):
def
test_add_non_handler
(
self
):
class
NonHandler
(
object
):
pass
self
.
assertRaises
(
TypeError
,
OpenerDirector
().
add_handler
,
NonHandler
())
def
test_badly_named_methods
(
self
):
# test work-around for three methods that accidentally follow the
# naming conventions for handler methods
# (*_open() / *_request() / *_response())
# These used to call the accidentally-named methods, causing a
# TypeError in real code; here, returning self from these mock
# methods would either cause no exception, or AttributeError.
from
urllib2
import
URLError
o
=
OpenerDirector
()
meth_spec
=
[
[(
"do_open"
,
"return self"
),
(
"proxy_open"
,
"return self"
)],
[(
"redirect_request"
,
"return self"
)],
]
handlers
=
add_ordered_mock_handlers
(
o
,
meth_spec
)
o
.
add_handler
(
urllib2
.
UnknownHandler
())
for
scheme
in
"do"
,
"proxy"
,
"redirect"
:
self
.
assertRaises
(
URLError
,
o
.
open
,
scheme
+
"://example.com/"
)
def
test_handled
(
self
):
# handler returning non-None means no more handlers will be called
o
=
OpenerDirector
()
meth_spec
=
[
[
"http_open"
,
"ftp_open"
,
"http_error_302"
],
[
"ftp_open"
],
[(
"http_open"
,
"return self"
)],
[(
"http_open"
,
"return self"
)],
]
handlers
=
add_ordered_mock_handlers
(
o
,
meth_spec
)
req
=
Request
(
"http://example.com/"
)
r
=
o
.
open
(
req
)
# Second .http_open() gets called, third doesn't, since second returned
# non-None. Handlers without .http_open() never get any methods called
# on them.
# In fact, second mock handler defining .http_open() returns self
# (instead of response), which becomes the OpenerDirector's return
# value.
self
.
assertEqual
(
r
,
handlers
[
2
])
calls
=
[(
handlers
[
0
],
"http_open"
),
(
handlers
[
2
],
"http_open"
)]
for
expected
,
got
in
zip
(
calls
,
o
.
calls
):
handler
,
name
,
args
,
kwds
=
got
self
.
assertEqual
((
handler
,
name
),
expected
)
self
.
assertEqual
(
args
,
(
req
,))
def
test_handler_order
(
self
):
o
=
OpenerDirector
()
handlers
=
[]
for
meths
,
handler_order
in
[
([(
"http_open"
,
"return self"
)],
500
),
([
"http_open"
],
0
),
]:
class
MockHandlerSubclass
(
MockHandler
):
pass
h
=
MockHandlerSubclass
(
meths
)
h
.
handler_order
=
handler_order
handlers
.
append
(
h
)
o
.
add_handler
(
h
)
r
=
o
.
open
(
"http://example.com/"
)
# handlers called in reverse order, thanks to their sort order
self
.
assertEqual
(
o
.
calls
[
0
][
0
],
handlers
[
1
])
self
.
assertEqual
(
o
.
calls
[
1
][
0
],
handlers
[
0
])
def
test_raise
(
self
):
# raising URLError stops processing of request
o
=
OpenerDirector
()
meth_spec
=
[
[(
"http_open"
,
"raise"
)],
[(
"http_open"
,
"return self"
)],
]
handlers
=
add_ordered_mock_handlers
(
o
,
meth_spec
)
req
=
Request
(
"http://example.com/"
)
self
.
assertRaises
(
urllib2
.
URLError
,
o
.
open
,
req
)
self
.
assertEqual
(
o
.
calls
,
[(
handlers
[
0
],
"http_open"
,
(
req
,),
{})])
## def test_error(self):
## # XXX this doesn't actually seem to be used in standard library,
## # but should really be tested anyway...
def
test_http_error
(
self
):
# XXX http_error_default
# http errors are a special case
o
=
OpenerDirector
()
meth_spec
=
[
[(
"http_open"
,
"error 302"
)],
[(
"http_error_400"
,
"raise"
),
"http_open"
],
[(
"http_error_302"
,
"return response"
),
"http_error_303"
,
"http_error"
],
[(
"http_error_302"
)],
]
handlers
=
add_ordered_mock_handlers
(
o
,
meth_spec
)
class
Unknown
:
def
__eq__
(
self
,
other
):
return
True
req
=
Request
(
"http://example.com/"
)
r
=
o
.
open
(
req
)
assert
len
(
o
.
calls
)
==
2
calls
=
[(
handlers
[
0
],
"http_open"
,
(
req
,)),
(
handlers
[
2
],
"http_error_302"
,
(
req
,
Unknown
(),
302
,
""
,
{}))]
for
expected
,
got
in
zip
(
calls
,
o
.
calls
):
handler
,
method_name
,
args
=
expected
self
.
assertEqual
((
handler
,
method_name
),
got
[:
2
])
self
.
assertEqual
(
args
,
got
[
2
])
def
test_processors
(
self
):
# *_request / *_response methods get called appropriately
o
=
OpenerDirector
()
meth_spec
=
[
[(
"http_request"
,
"return request"
),
(
"http_response"
,
"return response"
)],
[(
"http_request"
,
"return request"
),
(
"http_response"
,
"return response"
)],
]
handlers
=
add_ordered_mock_handlers
(
o
,
meth_spec
)
req
=
Request
(
"http://example.com/"
)
r
=
o
.
open
(
req
)
# processor methods are called on *all* handlers that define them,
# not just the first handler that handles the request
calls
=
[
(
handlers
[
0
],
"http_request"
),
(
handlers
[
1
],
"http_request"
),
(
handlers
[
0
],
"http_response"
),
(
handlers
[
1
],
"http_response"
)]
for
i
,
(
handler
,
name
,
args
,
kwds
)
in
enumerate
(
o
.
calls
):
if
i
<
2
:
# *_request
self
.
assertEqual
((
handler
,
name
),
calls
[
i
])
self
.
assertEqual
(
len
(
args
),
1
)
self
.
assert_
(
isinstance
(
args
[
0
],
Request
))
else
:
# *_response
self
.
assertEqual
((
handler
,
name
),
calls
[
i
])
self
.
assertEqual
(
len
(
args
),
2
)
self
.
assert_
(
isinstance
(
args
[
0
],
Request
))
# response from opener.open is None, because there's no
# handler that defines http_open to handle it
self
.
assert_
(
args
[
1
]
is
None
or
isinstance
(
args
[
1
],
MockResponse
))
def
sanepathname2url
(
path
):
import
urllib
urlpath
=
urllib
.
pathname2url
(
path
)
if
os
.
name
==
"nt"
and
urlpath
.
startswith
(
"///"
):
urlpath
=
urlpath
[
2
:]
# XXX don't ask me about the mac...
return
urlpath
class
HandlerTests
(
unittest
.
TestCase
):
def
test_ftp
(
self
):
class
MockFTPWrapper
:
def
__init__
(
self
,
data
):
self
.
data
=
data
def
retrfile
(
self
,
filename
,
filetype
):
self
.
filename
,
self
.
filetype
=
filename
,
filetype
return
StringIO
.
StringIO
(
self
.
data
),
len
(
self
.
data
)
class
NullFTPHandler
(
urllib2
.
FTPHandler
):
def
__init__
(
self
,
data
):
self
.
data
=
data
def
connect_ftp
(
self
,
user
,
passwd
,
host
,
port
,
dirs
):
self
.
user
,
self
.
passwd
=
user
,
passwd
self
.
host
,
self
.
port
=
host
,
port
self
.
dirs
=
dirs
self
.
ftpwrapper
=
MockFTPWrapper
(
self
.
data
)
return
self
.
ftpwrapper
import
ftplib
,
socket
data
=
"rheum rhaponicum"
h
=
NullFTPHandler
(
data
)
o
=
h
.
parent
=
MockOpener
()
for
url
,
host
,
port
,
type_
,
dirs
,
filename
,
mimetype
in
[
(
"ftp://localhost/foo/bar/baz.html"
,
"localhost"
,
ftplib
.
FTP_PORT
,
"I"
,
[
"foo"
,
"bar"
],
"baz.html"
,
"text/html"
),
(
"ftp://localhost:80/foo/bar/"
,
"localhost"
,
80
,
"D"
,
[
"foo"
,
"bar"
],
""
,
None
),
(
"ftp://localhost/baz.gif;type=a"
,
"localhost"
,
ftplib
.
FTP_PORT
,
"A"
,
[],
"baz.gif"
,
None
),
# XXX really this should guess image/gif
]:
r
=
h
.
ftp_open
(
Request
(
url
))
# ftp authentication not yet implemented by FTPHandler
self
.
assert_
(
h
.
user
==
h
.
passwd
==
""
)
self
.
assertEqual
(
h
.
host
,
socket
.
gethostbyname
(
host
))
self
.
assertEqual
(
h
.
port
,
port
)
self
.
assertEqual
(
h
.
dirs
,
dirs
)
self
.
assertEqual
(
h
.
ftpwrapper
.
filename
,
filename
)
self
.
assertEqual
(
h
.
ftpwrapper
.
filetype
,
type_
)
headers
=
r
.
info
()
self
.
assertEqual
(
headers
.
get
(
"Content-type"
),
mimetype
)
self
.
assertEqual
(
int
(
headers
[
"Content-length"
]),
len
(
data
))
def
test_file
(
self
):
import
time
,
rfc822
,
socket
h
=
urllib2
.
FileHandler
()
o
=
h
.
parent
=
MockOpener
()
TESTFN
=
test_support
.
TESTFN
urlpath
=
sanepathname2url
(
os
.
path
.
abspath
(
TESTFN
))
towrite
=
"hello, world
\
n
"
urls
=
[
"file://localhost%s"
%
urlpath
,
"file://%s"
%
urlpath
,
"file://%s%s"
%
(
socket
.
gethostbyname
(
'localhost'
),
urlpath
),
]
try
:
localaddr
=
socket
.
gethostbyname
(
socket
.
gethostname
())
except
socket
.
gaierror
:
localaddr
=
''
if
localaddr
:
urls
.
append
(
"file://%s%s"
%
(
localaddr
,
urlpath
))
for
url
in
urls
:
f
=
open
(
TESTFN
,
"wb"
)
try
:
try
:
f
.
write
(
towrite
)
finally
:
f
.
close
()
r
=
h
.
file_open
(
Request
(
url
))
try
:
data
=
r
.
read
()
headers
=
r
.
info
()
newurl
=
r
.
geturl
()
finally
:
r
.
close
()
stats
=
os
.
stat
(
TESTFN
)
modified
=
rfc822
.
formatdate
(
stats
.
st_mtime
)
finally
:
os
.
remove
(
TESTFN
)
self
.
assertEqual
(
data
,
towrite
)
self
.
assertEqual
(
headers
[
"Content-type"
],
"text/plain"
)
self
.
assertEqual
(
headers
[
"Content-length"
],
"13"
)
self
.
assertEqual
(
headers
[
"Last-modified"
],
modified
)
for
url
in
[
"file://localhost:80%s"
%
urlpath
,
# XXXX bug: these fail with socket.gaierror, should be URLError
## "file://%s:80%s/%s" % (socket.gethostbyname('localhost'),
## os.getcwd(), TESTFN),
## "file://somerandomhost.ontheinternet.com%s/%s" %
## (os.getcwd(), TESTFN),
]:
try
:
f
=
open
(
TESTFN
,
"wb"
)
try
:
f
.
write
(
towrite
)
finally
:
f
.
close
()
self
.
assertRaises
(
urllib2
.
URLError
,
h
.
file_open
,
Request
(
url
))
finally
:
os
.
remove
(
TESTFN
)
h
=
urllib2
.
FileHandler
()
o
=
h
.
parent
=
MockOpener
()
# XXXX why does // mean ftp (and /// mean not ftp!), and where
# is file: scheme specified? I think this is really a bug, and
# what was intended was to distinguish between URLs like:
# file:/blah.txt (a file)
# file://localhost/blah.txt (a file)
# file:///blah.txt (a file)
# file://ftp.example.com/blah.txt (an ftp URL)
for
url
,
ftp
in
[
(
"file://ftp.example.com//foo.txt"
,
True
),
(
"file://ftp.example.com///foo.txt"
,
False
),
# XXXX bug: fails with OSError, should be URLError
(
"file://ftp.example.com/foo.txt"
,
False
),
]:
req
=
Request
(
url
)
try
:
h
.
file_open
(
req
)
# XXXX remove OSError when bug fixed
except
(
urllib2
.
URLError
,
OSError
):
self
.
assert_
(
not
ftp
)
else
:
self
.
assert_
(
o
.
req
is
req
)
self
.
assertEqual
(
req
.
type
,
"ftp"
)
def
test_http
(
self
):
class
MockHTTPResponse
:
def
__init__
(
self
,
fp
,
msg
,
status
,
reason
):
self
.
fp
=
fp
self
.
msg
=
msg
self
.
status
=
status
self
.
reason
=
reason
def
read
(
self
):
return
''
class
MockHTTPClass
:
def
__init__
(
self
):
self
.
req_headers
=
[]
self
.
data
=
None
self
.
raise_on_endheaders
=
False
def
__call__
(
self
,
host
):
self
.
host
=
host
return
self
def
set_debuglevel
(
self
,
level
):
self
.
level
=
level
def
request
(
self
,
method
,
url
,
body
=
None
,
headers
=
{}):
self
.
method
=
method
self
.
selector
=
url
self
.
req_headers
+=
headers
.
items
()
self
.
req_headers
.
sort
()
if
body
:
self
.
data
=
body
if
self
.
raise_on_endheaders
:
import
socket
raise
socket
.
error
()
def
getresponse
(
self
):
return
MockHTTPResponse
(
MockFile
(),
{},
200
,
"OK"
)
h
=
urllib2
.
AbstractHTTPHandler
()
o
=
h
.
parent
=
MockOpener
()
url
=
"http://example.com/"
for
method
,
data
in
[(
"GET"
,
None
),
(
"POST"
,
"blah"
)]:
req
=
Request
(
url
,
data
,
{
"Foo"
:
"bar"
})
req
.
add_unredirected_header
(
"Spam"
,
"eggs"
)
http
=
MockHTTPClass
()
r
=
h
.
do_open
(
http
,
req
)
# result attributes
r
.
read
;
r
.
readline
# wrapped MockFile methods
r
.
info
;
r
.
geturl
# addinfourl methods
r
.
code
,
r
.
msg
==
200
,
"OK"
# added from MockHTTPClass.getreply()
hdrs
=
r
.
info
()
hdrs
.
get
;
hdrs
.
has_key
# r.info() gives dict from .getreply()
self
.
assertEqual
(
r
.
geturl
(),
url
)
self
.
assertEqual
(
http
.
host
,
"example.com"
)
self
.
assertEqual
(
http
.
level
,
0
)
self
.
assertEqual
(
http
.
method
,
method
)
self
.
assertEqual
(
http
.
selector
,
"/"
)
self
.
assertEqual
(
http
.
req_headers
,
[(
"Connection"
,
"close"
),
(
"Foo"
,
"bar"
),
(
"Spam"
,
"eggs"
)])
self
.
assertEqual
(
http
.
data
,
data
)
# check socket.error converted to URLError
http
.
raise_on_endheaders
=
True
self
.
assertRaises
(
urllib2
.
URLError
,
h
.
do_open
,
http
,
req
)
# check adding of standard headers
o
.
addheaders
=
[(
"Spam"
,
"eggs"
)]
for
data
in
""
,
None
:
# POST, GET
req
=
Request
(
"http://example.com/"
,
data
)
r
=
MockResponse
(
200
,
"OK"
,
{},
""
)
newreq
=
h
.
do_request_
(
req
)
if
data
is
None
:
# GET
self
.
assert_
(
"Content-length"
not
in
req
.
unredirected_hdrs
)
self
.
assert_
(
"Content-type"
not
in
req
.
unredirected_hdrs
)
else
:
# POST
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Content-length"
],
"0"
)
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Content-type"
],
"application/x-www-form-urlencoded"
)
# XXX the details of Host could be better tested
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Host"
],
"example.com"
)
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Spam"
],
"eggs"
)
# don't clobber existing headers
req
.
add_unredirected_header
(
"Content-length"
,
"foo"
)
req
.
add_unredirected_header
(
"Content-type"
,
"bar"
)
req
.
add_unredirected_header
(
"Host"
,
"baz"
)
req
.
add_unredirected_header
(
"Spam"
,
"foo"
)
newreq
=
h
.
do_request_
(
req
)
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Content-length"
],
"foo"
)
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Content-type"
],
"bar"
)
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Host"
],
"baz"
)
self
.
assertEqual
(
req
.
unredirected_hdrs
[
"Spam"
],
"foo"
)
def
test_errors
(
self
):
h
=
urllib2
.
HTTPErrorProcessor
()
o
=
h
.
parent
=
MockOpener
()
url
=
"http://example.com/"
req
=
Request
(
url
)
# 200 OK is passed through
r
=
MockResponse
(
200
,
"OK"
,
{},
""
,
url
)
newr
=
h
.
http_response
(
req
,
r
)
self
.
assert_
(
r
is
newr
)
self
.
assert_
(
not
hasattr
(
o
,
"proto"
))
# o.error not called
# anything else calls o.error (and MockOpener returns None, here)
r
=
MockResponse
(
201
,
"Created"
,
{},
""
,
url
)
self
.
assert_
(
h
.
http_response
(
req
,
r
)
is
None
)
self
.
assertEqual
(
o
.
proto
,
"http"
)
# o.error called
self
.
assertEqual
(
o
.
args
,
(
req
,
r
,
201
,
"Created"
,
{}))
def
test_cookies
(
self
):
cj
=
MockCookieJar
()
h
=
urllib2
.
HTTPCookieProcessor
(
cj
)
o
=
h
.
parent
=
MockOpener
()
req
=
Request
(
"http://example.com/"
)
r
=
MockResponse
(
200
,
"OK"
,
{},
""
)
newreq
=
h
.
http_request
(
req
)
self
.
assert_
(
cj
.
ach_req
is
req
is
newreq
)
self
.
assertEquals
(
req
.
get_origin_req_host
(),
"example.com"
)
self
.
assert_
(
not
req
.
is_unverifiable
())
newr
=
h
.
http_response
(
req
,
r
)
self
.
assert_
(
cj
.
ec_req
is
req
)
self
.
assert_
(
cj
.
ec_r
is
r
is
newr
)
def
test_redirect
(
self
):
from_url
=
"http://example.com/a.html"
to_url
=
"http://example.com/b.html"
h
=
urllib2
.
HTTPRedirectHandler
()
o
=
h
.
parent
=
MockOpener
()
# ordinary redirect behaviour
for
code
in
301
,
302
,
303
,
307
:
for
data
in
None
,
"blah
\
n
blah
\
n
"
:
method
=
getattr
(
h
,
"http_error_%s"
%
code
)
req
=
Request
(
from_url
,
data
)
req
.
add_header
(
"Nonsense"
,
"viking=withhold"
)
req
.
add_unredirected_header
(
"Spam"
,
"spam"
)
try
:
method
(
req
,
MockFile
(),
code
,
"Blah"
,
MockHeaders
({
"location"
:
to_url
}))
except
urllib2
.
HTTPError
:
# 307 in response to POST requires user OK
self
.
assert_
(
code
==
307
and
data
is
not
None
)
self
.
assertEqual
(
o
.
req
.
get_full_url
(),
to_url
)
try
:
self
.
assertEqual
(
o
.
req
.
get_method
(),
"GET"
)
except
AttributeError
:
self
.
assert_
(
not
o
.
req
.
has_data
())
self
.
assertEqual
(
o
.
req
.
headers
[
"Nonsense"
],
"viking=withhold"
)
self
.
assert_
(
"Spam"
not
in
o
.
req
.
headers
)
self
.
assert_
(
"Spam"
not
in
o
.
req
.
unredirected_hdrs
)
# loop detection
req
=
Request
(
from_url
)
def
redirect
(
h
,
req
,
url
=
to_url
):
h
.
http_error_302
(
req
,
MockFile
(),
302
,
"Blah"
,
MockHeaders
({
"location"
:
url
}))
# Note that the *original* request shares the same record of
# redirections with the sub-requests caused by the redirections.
# detect infinite loop redirect of a URL to itself
req
=
Request
(
from_url
,
origin_req_host
=
"example.com"
)
count
=
0
try
:
while
1
:
redirect
(
h
,
req
,
"http://example.com/"
)
count
=
count
+
1
except
urllib2
.
HTTPError
:
# don't stop until max_repeats, because cookies may introduce state
self
.
assertEqual
(
count
,
urllib2
.
HTTPRedirectHandler
.
max_repeats
)
# detect endless non-repeating chain of redirects
req
=
Request
(
from_url
,
origin_req_host
=
"example.com"
)
count
=
0
try
:
while
1
:
redirect
(
h
,
req
,
"http://example.com/%d"
%
count
)
count
=
count
+
1
except
urllib2
.
HTTPError
:
self
.
assertEqual
(
count
,
urllib2
.
HTTPRedirectHandler
.
max_redirections
)
def
test_invalid_redirect
(
self
):
from_url
=
"http://example.com/a.html"
valid_schemes
=
[
'http'
,
'https'
,
'ftp'
]
invalid_schemes
=
[
'file'
,
'imap'
,
'ldap'
]
schemeless_url
=
"example.com/b.html"
h
=
urllib2
.
HTTPRedirectHandler
()
o
=
h
.
parent
=
MockOpener
()
req
=
Request
(
from_url
)
for
scheme
in
invalid_schemes
:
invalid_url
=
scheme
+
'://'
+
schemeless_url
self
.
assertRaises
(
urllib2
.
HTTPError
,
h
.
http_error_302
,
req
,
MockFile
(),
302
,
"Security Loophole"
,
MockHeaders
({
"location"
:
invalid_url
}))
for
scheme
in
valid_schemes
:
valid_url
=
scheme
+
'://'
+
schemeless_url
h
.
http_error_302
(
req
,
MockFile
(),
302
,
"That's fine"
,
MockHeaders
({
"location"
:
valid_url
}))
self
.
assertEqual
(
o
.
req
.
get_full_url
(),
valid_url
)
def
test_cookie_redirect
(
self
):
# cookies shouldn't leak into redirected requests
from
cookielib
import
CookieJar
from
test_cookielib
import
interact_netscape
cj
=
CookieJar
()
interact_netscape
(
cj
,
"http://www.example.com/"
,
"spam=eggs"
)
hh
=
MockHTTPHandler
(
302
,
"Location: http://www.cracker.com/
\
r
\
n
\
r
\
n
"
)
hdeh
=
urllib2
.
HTTPDefaultErrorHandler
()
hrh
=
urllib2
.
HTTPRedirectHandler
()
cp
=
urllib2
.
HTTPCookieProcessor
(
cj
)
o
=
build_test_opener
(
hh
,
hdeh
,
hrh
,
cp
)
o
.
open
(
"http://www.example.com/"
)
self
.
assert_
(
not
hh
.
req
.
has_header
(
"Cookie"
))
def
test_proxy
(
self
):
o
=
OpenerDirector
()
ph
=
urllib2
.
ProxyHandler
(
dict
(
http
=
"proxy.example.com:3128"
))
o
.
add_handler
(
ph
)
meth_spec
=
[
[(
"http_open"
,
"return response"
)]
]
handlers
=
add_ordered_mock_handlers
(
o
,
meth_spec
)
req
=
Request
(
"http://acme.example.com/"
)
self
.
assertEqual
(
req
.
get_host
(),
"acme.example.com"
)
r
=
o
.
open
(
req
)
self
.
assertEqual
(
req
.
get_host
(),
"proxy.example.com:3128"
)
self
.
assertEqual
([(
handlers
[
0
],
"http_open"
)],
[
tup
[
0
:
2
]
for
tup
in
o
.
calls
])
def
test_basic_auth
(
self
):
opener
=
OpenerDirector
()
password_manager
=
MockPasswordManager
()
auth_handler
=
urllib2
.
HTTPBasicAuthHandler
(
password_manager
)
realm
=
"ACME Widget Store"
http_handler
=
MockHTTPHandler
(
401
,
'WWW-Authenticate: Basic realm="%s"
\
r
\
n
\
r
\
n
'
%
realm
)
opener
.
add_handler
(
auth_handler
)
opener
.
add_handler
(
http_handler
)
self
.
_test_basic_auth
(
opener
,
auth_handler
,
"Authorization"
,
realm
,
http_handler
,
password_manager
,
"http://acme.example.com/protected"
,
"http://acme.example.com/protected"
,
)
def
test_proxy_basic_auth
(
self
):
opener
=
OpenerDirector
()
ph
=
urllib2
.
ProxyHandler
(
dict
(
http
=
"proxy.example.com:3128"
))
opener
.
add_handler
(
ph
)
password_manager
=
MockPasswordManager
()
auth_handler
=
urllib2
.
ProxyBasicAuthHandler
(
password_manager
)
realm
=
"ACME Networks"
http_handler
=
MockHTTPHandler
(
407
,
'Proxy-Authenticate: Basic realm="%s"
\
r
\
n
\
r
\
n
'
%
realm
)
opener
.
add_handler
(
auth_handler
)
opener
.
add_handler
(
http_handler
)
self
.
_test_basic_auth
(
opener
,
auth_handler
,
"Proxy-authorization"
,
realm
,
http_handler
,
password_manager
,
"http://acme.example.com:3128/protected"
,
"proxy.example.com:3128"
,
)
def
test_basic_and_digest_auth_handlers
(
self
):
# HTTPDigestAuthHandler threw an exception if it couldn't handle a 40*
# response (http://python.org/sf/1479302), where it should instead
# return None to allow another handler (especially
# HTTPBasicAuthHandler) to handle the response.
# Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must
# try digest first (since it's the strongest auth scheme), so we record
# order of calls here to check digest comes first:
class
RecordingOpenerDirector
(
OpenerDirector
):
def
__init__
(
self
):
OpenerDirector
.
__init__
(
self
)
self
.
recorded
=
[]
def
record
(
self
,
info
):
self
.
recorded
.
append
(
info
)
class
TestDigestAuthHandler
(
urllib2
.
HTTPDigestAuthHandler
):
def
http_error_401
(
self
,
*
args
,
**
kwds
):
self
.
parent
.
record
(
"digest"
)
urllib2
.
HTTPDigestAuthHandler
.
http_error_401
(
self
,
*
args
,
**
kwds
)
class
TestBasicAuthHandler
(
urllib2
.
HTTPBasicAuthHandler
):
def
http_error_401
(
self
,
*
args
,
**
kwds
):
self
.
parent
.
record
(
"basic"
)
urllib2
.
HTTPBasicAuthHandler
.
http_error_401
(
self
,
*
args
,
**
kwds
)
opener
=
RecordingOpenerDirector
()
password_manager
=
MockPasswordManager
()
digest_handler
=
TestDigestAuthHandler
(
password_manager
)
basic_handler
=
TestBasicAuthHandler
(
password_manager
)
realm
=
"ACME Networks"
http_handler
=
MockHTTPHandler
(
401
,
'WWW-Authenticate: Basic realm="%s"
\
r
\
n
\
r
\
n
'
%
realm
)
opener
.
add_handler
(
basic_handler
)
opener
.
add_handler
(
digest_handler
)
opener
.
add_handler
(
http_handler
)
# check basic auth isn't blocked by digest handler failing
self
.
_test_basic_auth
(
opener
,
basic_handler
,
"Authorization"
,
realm
,
http_handler
,
password_manager
,
"http://acme.example.com/protected"
,
"http://acme.example.com/protected"
,
)
# check digest was tried before basic (twice, because
# _test_basic_auth called .open() twice)
self
.
assertEqual
(
opener
.
recorded
,
[
"digest"
,
"basic"
]
*
2
)
def
_test_basic_auth
(
self
,
opener
,
auth_handler
,
auth_header
,
realm
,
http_handler
,
password_manager
,
request_url
,
protected_url
):
import
base64
,
httplib
user
,
password
=
"wile"
,
"coyote"
# .add_password() fed through to password manager
auth_handler
.
add_password
(
realm
,
request_url
,
user
,
password
)
self
.
assertEqual
(
realm
,
password_manager
.
realm
)
self
.
assertEqual
(
request_url
,
password_manager
.
url
)
self
.
assertEqual
(
user
,
password_manager
.
user
)
self
.
assertEqual
(
password
,
password_manager
.
password
)
r
=
opener
.
open
(
request_url
)
# should have asked the password manager for the username/password
self
.
assertEqual
(
password_manager
.
target_realm
,
realm
)
self
.
assertEqual
(
password_manager
.
target_url
,
protected_url
)
# expect one request without authorization, then one with
self
.
assertEqual
(
len
(
http_handler
.
requests
),
2
)
self
.
assertFalse
(
http_handler
.
requests
[
0
].
has_header
(
auth_header
))
userpass
=
'%s:%s'
%
(
user
,
password
)
auth_hdr_value
=
'Basic '
+
base64
.
encodestring
(
userpass
).
strip
()
self
.
assertEqual
(
http_handler
.
requests
[
1
].
get_header
(
auth_header
),
auth_hdr_value
)
# if the password manager can't find a password, the handler won't
# handle the HTTP auth error
password_manager
.
user
=
password_manager
.
password
=
None
http_handler
.
reset
()
r
=
opener
.
open
(
request_url
)
self
.
assertEqual
(
len
(
http_handler
.
requests
),
1
)
self
.
assertFalse
(
http_handler
.
requests
[
0
].
has_header
(
auth_header
))
class
MiscTests
(
unittest
.
TestCase
):
def
test_build_opener
(
self
):
class
MyHTTPHandler
(
urllib2
.
HTTPHandler
):
pass
class
FooHandler
(
urllib2
.
BaseHandler
):
def
foo_open
(
self
):
pass
class
BarHandler
(
urllib2
.
BaseHandler
):
def
bar_open
(
self
):
pass
build_opener
=
urllib2
.
build_opener
o
=
build_opener
(
FooHandler
,
BarHandler
)
self
.
opener_has_handler
(
o
,
FooHandler
)
self
.
opener_has_handler
(
o
,
BarHandler
)
# can take a mix of classes and instances
o
=
build_opener
(
FooHandler
,
BarHandler
())
self
.
opener_has_handler
(
o
,
FooHandler
)
self
.
opener_has_handler
(
o
,
BarHandler
)
# subclasses of default handlers override default handlers
o
=
build_opener
(
MyHTTPHandler
)
self
.
opener_has_handler
(
o
,
MyHTTPHandler
)
# a particular case of overriding: default handlers can be passed
# in explicitly
o
=
build_opener
()
self
.
opener_has_handler
(
o
,
urllib2
.
HTTPHandler
)
o
=
build_opener
(
urllib2
.
HTTPHandler
)
self
.
opener_has_handler
(
o
,
urllib2
.
HTTPHandler
)
o
=
build_opener
(
urllib2
.
HTTPHandler
())
self
.
opener_has_handler
(
o
,
urllib2
.
HTTPHandler
)
# Issue2670: multiple handlers sharing the same base class
class
MyOtherHTTPHandler
(
urllib2
.
HTTPHandler
):
pass
o
=
build_opener
(
MyHTTPHandler
,
MyOtherHTTPHandler
)
self
.
opener_has_handler
(
o
,
MyHTTPHandler
)
self
.
opener_has_handler
(
o
,
MyOtherHTTPHandler
)
def
opener_has_handler
(
self
,
opener
,
handler_class
):
for
h
in
opener
.
handlers
:
if
h
.
__class__
==
handler_class
:
break
else
:
self
.
assert_
(
False
)
def
test_main
(
verbose
=
None
):
import
test_urllib2
test_support
.
run_doctest
(
test_urllib2
,
verbose
)
test_support
.
run_doctest
(
urllib2
,
verbose
)
tests
=
(
TrivialTests
,
OpenerDirectorTests
,
HandlerTests
,
MiscTests
)
test_support
.
run_unittest
(
*
tests
)
if
__name__
==
"__main__"
:
test_main
(
verbose
=
True
)
greentest/2.5/test_urllib2_localnet.py
deleted
100644 → 0
View file @
ed74f199
#!/usr/bin/env python
import
sys
import
threading
import
urlparse
import
urllib2
import
BaseHTTPServer
import
unittest
import
hashlib
from
test
import
test_support
# Loopback http server infrastructure
class
LoopbackHttpServer
(
BaseHTTPServer
.
HTTPServer
):
"""HTTP server w/ a few modifications that make it useful for
loopback testing purposes.
"""
def
__init__
(
self
,
server_address
,
RequestHandlerClass
):
BaseHTTPServer
.
HTTPServer
.
__init__
(
self
,
server_address
,
RequestHandlerClass
)
# Set the timeout of our listening socket really low so
# that we can stop the server easily.
self
.
socket
.
settimeout
(
0.1
)
def
get_request
(
self
):
"""BaseHTTPServer method, overridden."""
request
,
client_address
=
self
.
socket
.
accept
()
# It's a loopback connection, so setting the timeout
# really low shouldn't affect anything, but should make
# deadlocks less likely to occur.
request
.
settimeout
(
1.0
)
return
(
request
,
client_address
)
class
LoopbackHttpServerThread
(
threading
.
Thread
):
"""Stoppable thread that runs a loopback http server."""
def
__init__
(
self
,
port
,
RequestHandlerClass
):
threading
.
Thread
.
__init__
(
self
)
self
.
_RequestHandlerClass
=
RequestHandlerClass
self
.
_stop
=
False
self
.
_port
=
port
self
.
_server_address
=
(
'127.0.0.1'
,
self
.
_port
)
self
.
ready
=
threading
.
Event
()
def
stop
(
self
):
"""Stops the webserver if it's currently running."""
# Set the stop flag.
self
.
_stop
=
True
self
.
join
()
def
run
(
self
):
protocol
=
"HTTP/1.0"
self
.
_RequestHandlerClass
.
protocol_version
=
protocol
httpd
=
LoopbackHttpServer
(
self
.
_server_address
,
self
.
_RequestHandlerClass
)
sa
=
httpd
.
socket
.
getsockname
()
#print "Serving HTTP on", sa[0], "port", sa[1], "..."
self
.
ready
.
set
()
while
not
self
.
_stop
:
httpd
.
handle_request
()
# Authentication infrastructure
class
DigestAuthHandler
:
"""Handler for performing digest authentication."""
def
__init__
(
self
):
self
.
_request_num
=
0
self
.
_nonces
=
[]
self
.
_users
=
{}
self
.
_realm_name
=
"Test Realm"
self
.
_qop
=
"auth"
def
set_qop
(
self
,
qop
):
self
.
_qop
=
qop
def
set_users
(
self
,
users
):
assert
isinstance
(
users
,
dict
)
self
.
_users
=
users
def
set_realm
(
self
,
realm
):
self
.
_realm_name
=
realm
def
_generate_nonce
(
self
):
self
.
_request_num
+=
1
nonce
=
hashlib
.
md5
(
str
(
self
.
_request_num
)).
hexdigest
()
self
.
_nonces
.
append
(
nonce
)
return
nonce
def
_create_auth_dict
(
self
,
auth_str
):
first_space_index
=
auth_str
.
find
(
" "
)
auth_str
=
auth_str
[
first_space_index
+
1
:]
parts
=
auth_str
.
split
(
","
)
auth_dict
=
{}
for
part
in
parts
:
name
,
value
=
part
.
split
(
"="
)
name
=
name
.
strip
()
if
value
[
0
]
==
'"'
and
value
[
-
1
]
==
'"'
:
value
=
value
[
1
:
-
1
]
else
:
value
=
value
.
strip
()
auth_dict
[
name
]
=
value
return
auth_dict
def
_validate_auth
(
self
,
auth_dict
,
password
,
method
,
uri
):
final_dict
=
{}
final_dict
.
update
(
auth_dict
)
final_dict
[
"password"
]
=
password
final_dict
[
"method"
]
=
method
final_dict
[
"uri"
]
=
uri
HA1_str
=
"%(username)s:%(realm)s:%(password)s"
%
final_dict
HA1
=
hashlib
.
md5
(
HA1_str
).
hexdigest
()
HA2_str
=
"%(method)s:%(uri)s"
%
final_dict
HA2
=
hashlib
.
md5
(
HA2_str
).
hexdigest
()
final_dict
[
"HA1"
]
=
HA1
final_dict
[
"HA2"
]
=
HA2
response_str
=
"%(HA1)s:%(nonce)s:%(nc)s:"
\
"%(cnonce)s:%(qop)s:%(HA2)s"
%
final_dict
response
=
hashlib
.
md5
(
response_str
).
hexdigest
()
return
response
==
auth_dict
[
"response"
]
def
_return_auth_challenge
(
self
,
request_handler
):
request_handler
.
send_response
(
407
,
"Proxy Authentication Required"
)
request_handler
.
send_header
(
"Content-Type"
,
"text/html"
)
request_handler
.
send_header
(
'Proxy-Authenticate'
,
'Digest realm="%s", '
'qop="%s",'
'nonce="%s", '
%
\
(
self
.
_realm_name
,
self
.
_qop
,
self
.
_generate_nonce
()))
# XXX: Not sure if we're supposed to add this next header or
# not.
#request_handler.send_header('Connection', 'close')
request_handler
.
end_headers
()
request_handler
.
wfile
.
write
(
"Proxy Authentication Required."
)
return
False
def
handle_request
(
self
,
request_handler
):
"""Performs digest authentication on the given HTTP request
handler. Returns True if authentication was successful, False
otherwise.
If no users have been set, then digest auth is effectively
disabled and this method will always return True.
"""
if
len
(
self
.
_users
)
==
0
:
return
True
if
not
request_handler
.
headers
.
has_key
(
'Proxy-Authorization'
):
return
self
.
_return_auth_challenge
(
request_handler
)
else
:
auth_dict
=
self
.
_create_auth_dict
(
request_handler
.
headers
[
'Proxy-Authorization'
]
)
if
self
.
_users
.
has_key
(
auth_dict
[
"username"
]):
password
=
self
.
_users
[
auth_dict
[
"username"
]
]
else
:
return
self
.
_return_auth_challenge
(
request_handler
)
if
not
auth_dict
.
get
(
"nonce"
)
in
self
.
_nonces
:
return
self
.
_return_auth_challenge
(
request_handler
)
else
:
self
.
_nonces
.
remove
(
auth_dict
[
"nonce"
])
auth_validated
=
False
# MSIE uses short_path in its validation, but Python's
# urllib2 uses the full path, so we're going to see if
# either of them works here.
for
path
in
[
request_handler
.
path
,
request_handler
.
short_path
]:
if
self
.
_validate_auth
(
auth_dict
,
password
,
request_handler
.
command
,
path
):
auth_validated
=
True
if
not
auth_validated
:
return
self
.
_return_auth_challenge
(
request_handler
)
return
True
# Proxy test infrastructure
class
FakeProxyHandler
(
BaseHTTPServer
.
BaseHTTPRequestHandler
):
"""This is a 'fake proxy' that makes it look like the entire
internet has gone down due to a sudden zombie invasion. It main
utility is in providing us with authentication support for
testing.
"""
digest_auth_handler
=
DigestAuthHandler
()
def
log_message
(
self
,
format
,
*
args
):
# Uncomment the next line for debugging.
#sys.stderr.write(format % args)
pass
def
do_GET
(
self
):
(
scm
,
netloc
,
path
,
params
,
query
,
fragment
)
=
urlparse
.
urlparse
(
self
.
path
,
'http'
)
self
.
short_path
=
path
if
self
.
digest_auth_handler
.
handle_request
(
self
):
self
.
send_response
(
200
,
"OK"
)
self
.
send_header
(
"Content-Type"
,
"text/html"
)
self
.
end_headers
()
self
.
wfile
.
write
(
"You've reached %s!<BR>"
%
self
.
path
)
self
.
wfile
.
write
(
"Our apologies, but our server is down due to "
"a sudden zombie invasion."
)
# Test cases
class
ProxyAuthTests
(
unittest
.
TestCase
):
URL
=
"http://www.foo.com"
PORT
=
8080
USER
=
"tester"
PASSWD
=
"test123"
REALM
=
"TestRealm"
PROXY_URL
=
"http://127.0.0.1:%d"
%
PORT
def
setUp
(
self
):
FakeProxyHandler
.
digest_auth_handler
.
set_users
({
self
.
USER
:
self
.
PASSWD
})
FakeProxyHandler
.
digest_auth_handler
.
set_realm
(
self
.
REALM
)
self
.
server
=
LoopbackHttpServerThread
(
self
.
PORT
,
FakeProxyHandler
)
self
.
server
.
start
()
self
.
server
.
ready
.
wait
()
handler
=
urllib2
.
ProxyHandler
({
"http"
:
self
.
PROXY_URL
})
self
.
_digest_auth_handler
=
urllib2
.
ProxyDigestAuthHandler
()
self
.
opener
=
urllib2
.
build_opener
(
handler
,
self
.
_digest_auth_handler
)
def
tearDown
(
self
):
self
.
server
.
stop
()
def
test_proxy_with_bad_password_raises_httperror
(
self
):
self
.
_digest_auth_handler
.
add_password
(
self
.
REALM
,
self
.
URL
,
self
.
USER
,
self
.
PASSWD
+
"bad"
)
FakeProxyHandler
.
digest_auth_handler
.
set_qop
(
"auth"
)
self
.
assertRaises
(
urllib2
.
HTTPError
,
self
.
opener
.
open
,
self
.
URL
)
def
test_proxy_with_no_password_raises_httperror
(
self
):
FakeProxyHandler
.
digest_auth_handler
.
set_qop
(
"auth"
)
self
.
assertRaises
(
urllib2
.
HTTPError
,
self
.
opener
.
open
,
self
.
URL
)
def
test_proxy_qop_auth_works
(
self
):
self
.
_digest_auth_handler
.
add_password
(
self
.
REALM
,
self
.
URL
,
self
.
USER
,
self
.
PASSWD
)
FakeProxyHandler
.
digest_auth_handler
.
set_qop
(
"auth"
)
result
=
self
.
opener
.
open
(
self
.
URL
)
while
result
.
read
():
pass
result
.
close
()
def
test_proxy_qop_auth_int_works_or_throws_urlerror
(
self
):
self
.
_digest_auth_handler
.
add_password
(
self
.
REALM
,
self
.
URL
,
self
.
USER
,
self
.
PASSWD
)
FakeProxyHandler
.
digest_auth_handler
.
set_qop
(
"auth-int"
)
try
:
result
=
self
.
opener
.
open
(
self
.
URL
)
except
urllib2
.
URLError
:
# It's okay if we don't support auth-int, but we certainly
# shouldn't receive any kind of exception here other than
# a URLError.
result
=
None
if
result
:
while
result
.
read
():
pass
result
.
close
()
def
test_main
():
# We will NOT depend on the network resource flag
# (Lib/test/regrtest.py -u network) since all tests here are only
# localhost. However, if this is a bad rationale, then uncomment
# the next line.
#test_support.requires("network")
test_support
.
run_unittest
(
ProxyAuthTests
)
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_urllib2net.py
deleted
100644 → 0
View file @
ed74f199
#!/usr/bin/env python
import
unittest
from
test
import
test_support
from
test_urllib2
import
sanepathname2url
import
socket
import
urllib2
import
sys
import
os
import
mimetools
class
URLTimeoutTest
(
unittest
.
TestCase
):
TIMEOUT
=
10.0
def
setUp
(
self
):
socket
.
setdefaulttimeout
(
self
.
TIMEOUT
)
def
tearDown
(
self
):
socket
.
setdefaulttimeout
(
None
)
def
testURLread
(
self
):
f
=
urllib2
.
urlopen
(
"http://www.python.org/"
)
x
=
f
.
read
()
class
AuthTests
(
unittest
.
TestCase
):
"""Tests urllib2 authentication features."""
## Disabled at the moment since there is no page under python.org which
## could be used to HTTP authentication.
#
# def test_basic_auth(self):
# import httplib
#
# test_url = "http://www.python.org/test/test_urllib2/basic_auth"
# test_hostport = "www.python.org"
# test_realm = 'Test Realm'
# test_user = 'test.test_urllib2net'
# test_password = 'blah'
#
# # failure
# try:
# urllib2.urlopen(test_url)
# except urllib2.HTTPError, exc:
# self.assertEqual(exc.code, 401)
# else:
# self.fail("urlopen() should have failed with 401")
#
# # success
# auth_handler = urllib2.HTTPBasicAuthHandler()
# auth_handler.add_password(test_realm, test_hostport,
# test_user, test_password)
# opener = urllib2.build_opener(auth_handler)
# f = opener.open('http://localhost/')
# response = urllib2.urlopen("http://www.python.org/")
#
# # The 'userinfo' URL component is deprecated by RFC 3986 for security
# # reasons, let's not implement it! (it's already implemented for proxy
# # specification strings (that is, URLs or authorities specifying a
# # proxy), so we must keep that)
# self.assertRaises(httplib.InvalidURL,
# urllib2.urlopen, "http://evil:thing@example.com")
class
CloseSocketTest
(
unittest
.
TestCase
):
def
test_close
(
self
):
import
socket
,
httplib
,
gc
# calling .close() on urllib2's response objects should close the
# underlying socket
# delve deep into response to fetch socket._socketobject
response
=
urllib2
.
urlopen
(
"http://www.python.org/"
)
abused_fileobject
=
response
.
fp
self
.
assert_
(
abused_fileobject
.
__class__
is
socket
.
_fileobject
)
httpresponse
=
abused_fileobject
.
_sock
self
.
assert_
(
httpresponse
.
__class__
is
httplib
.
HTTPResponse
)
fileobject
=
httpresponse
.
fp
self
.
assert_
(
fileobject
.
__class__
is
socket
.
_fileobject
)
self
.
assert_
(
not
fileobject
.
closed
)
response
.
close
()
self
.
assert_
(
fileobject
.
closed
)
class
urlopenNetworkTests
(
unittest
.
TestCase
):
"""Tests urllib2.urlopen using the network.
These tests are not exhaustive. Assuming that testing using files does a
good job overall of some of the basic interface features. There are no
tests exercising the optional 'data' and 'proxies' arguments. No tests
for transparent redirection have been written.
setUp is not used for always constructing a connection to
http://www.python.org/ since there a few tests that don't use that address
and making a connection is expensive enough to warrant minimizing unneeded
connections.
"""
def
test_basic
(
self
):
# Simple test expected to pass.
open_url
=
urllib2
.
urlopen
(
"http://www.python.org/"
)
for
attr
in
(
"read"
,
"close"
,
"info"
,
"geturl"
):
self
.
assert_
(
hasattr
(
open_url
,
attr
),
"object returned from "
"urlopen lacks the %s attribute"
%
attr
)
try
:
self
.
assert_
(
open_url
.
read
(),
"calling 'read' failed"
)
finally
:
open_url
.
close
()
def
test_info
(
self
):
# Test 'info'.
open_url
=
urllib2
.
urlopen
(
"http://www.python.org/"
)
try
:
info_obj
=
open_url
.
info
()
finally
:
open_url
.
close
()
self
.
assert_
(
isinstance
(
info_obj
,
mimetools
.
Message
),
"object returned by 'info' is not an instance of "
"mimetools.Message"
)
self
.
assertEqual
(
info_obj
.
getsubtype
(),
"html"
)
def
test_geturl
(
self
):
# Make sure same URL as opened is returned by geturl.
URL
=
"http://www.python.org/"
open_url
=
urllib2
.
urlopen
(
URL
)
try
:
gotten_url
=
open_url
.
geturl
()
finally
:
open_url
.
close
()
self
.
assertEqual
(
gotten_url
,
URL
)
def
test_bad_address
(
self
):
# Make sure proper exception is raised when connecting to a bogus
# address.
self
.
assertRaises
(
IOError
,
# SF patch 809915: In Sep 2003, VeriSign started
# highjacking invalid .com and .net addresses to
# boost traffic to their own site. This test
# started failing then. One hopes the .invalid
# domain will be spared to serve its defined
# purpose.
# urllib2.urlopen, "http://www.sadflkjsasadf.com/")
urllib2
.
urlopen
,
"http://www.python.invalid./"
)
class
OtherNetworkTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
if
0
:
# for debugging
import
logging
logger
=
logging
.
getLogger
(
"test_urllib2net"
)
logger
.
addHandler
(
logging
.
StreamHandler
())
def
test_range
(
self
):
req
=
urllib2
.
Request
(
"http://www.python.org"
,
headers
=
{
'Range'
:
'bytes=20-39'
})
result
=
urllib2
.
urlopen
(
req
)
data
=
result
.
read
()
self
.
assertEqual
(
len
(
data
),
20
)
# XXX The rest of these tests aren't very good -- they don't check much.
# They do sometimes catch some major disasters, though.
def
test_ftp
(
self
):
urls
=
[
'ftp://www.python.org/pub/python/misc/sousa.au'
,
'ftp://www.python.org/pub/tmp/blat'
,
'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC'
'/research-reports/00README-Legal-Rules-Regs'
,
]
self
.
_test_urls
(
urls
,
self
.
_extra_handlers
())
def
test_gopher
(
self
):
import
warnings
warnings
.
filterwarnings
(
"ignore"
,
"the gopherlib module is deprecated"
,
DeprecationWarning
,
"urllib2$"
)
urls
=
[
# Thanks to Fred for finding these!
'gopher://gopher.lib.ncsu.edu./11/library/stacks/Alex'
,
'gopher://gopher.vt.edu.:10010/10/33'
,
]
self
.
_test_urls
(
urls
,
self
.
_extra_handlers
())
def
test_file
(
self
):
TESTFN
=
test_support
.
TESTFN
f
=
open
(
TESTFN
,
'w'
)
try
:
f
.
write
(
'hi there
\
n
'
)
f
.
close
()
urls
=
[
'file:'
+
sanepathname2url
(
os
.
path
.
abspath
(
TESTFN
)),
# XXX bug, should raise URLError
#('file://nonsensename/etc/passwd', None, urllib2.URLError)
(
'file://nonsensename/etc/passwd'
,
None
,
(
EnvironmentError
,
socket
.
error
))
]
self
.
_test_urls
(
urls
,
self
.
_extra_handlers
())
finally
:
os
.
remove
(
TESTFN
)
def
test_http
(
self
):
urls
=
[
'http://www.espn.com/'
,
# redirect
'http://www.python.org/Spanish/Inquistion/'
,
(
'http://www.python.org/cgi-bin/faqw.py'
,
'query=pythonistas&querytype=simple&casefold=yes&req=search'
,
None
),
'http://www.python.org/'
,
]
self
.
_test_urls
(
urls
,
self
.
_extra_handlers
())
# XXX Following test depends on machine configurations that are internal
# to CNRI. Need to set up a public server with the right authentication
# configuration for test purposes.
## def test_cnri(self):
## if socket.gethostname() == 'bitdiddle':
## localhost = 'bitdiddle.cnri.reston.va.us'
## elif socket.gethostname() == 'bitdiddle.concentric.net':
## localhost = 'localhost'
## else:
## localhost = None
## if localhost is not None:
## urls = [
## 'file://%s/etc/passwd' % localhost,
## 'http://%s/simple/' % localhost,
## 'http://%s/digest/' % localhost,
## 'http://%s/not/found.h' % localhost,
## ]
## bauth = HTTPBasicAuthHandler()
## bauth.add_password('basic_test_realm', localhost, 'jhylton',
## 'password')
## dauth = HTTPDigestAuthHandler()
## dauth.add_password('digest_test_realm', localhost, 'jhylton',
## 'password')
## self._test_urls(urls, self._extra_handlers()+[bauth, dauth])
def
_test_urls
(
self
,
urls
,
handlers
):
import
socket
import
time
import
logging
debug
=
logging
.
getLogger
(
"test_urllib2"
).
debug
urllib2
.
install_opener
(
urllib2
.
build_opener
(
*
handlers
))
for
url
in
urls
:
if
isinstance
(
url
,
tuple
):
url
,
req
,
expected_err
=
url
else
:
req
=
expected_err
=
None
debug
(
url
)
try
:
f
=
urllib2
.
urlopen
(
url
,
req
)
except
(
IOError
,
socket
.
error
,
OSError
),
err
:
debug
(
err
)
if
expected_err
:
msg
=
(
"Didn't get expected error(s) %s for %s %s, got %s"
%
(
expected_err
,
url
,
req
,
err
))
self
.
assert_
(
isinstance
(
err
,
expected_err
),
msg
)
else
:
buf
=
f
.
read
()
f
.
close
()
debug
(
"read %d bytes"
%
len
(
buf
))
debug
(
"******** next url coming up..."
)
time
.
sleep
(
0.1
)
def
_extra_handlers
(
self
):
handlers
=
[]
handlers
.
append
(
urllib2
.
GopherHandler
)
cfh
=
urllib2
.
CacheFTPHandler
()
cfh
.
setTimeout
(
1
)
handlers
.
append
(
cfh
)
return
handlers
def
test_main
():
test_support
.
requires
(
"network"
)
test_support
.
run_unittest
(
URLTimeoutTest
,
urlopenNetworkTests
,
AuthTests
,
OtherNetworkTests
,
CloseSocketTest
,
)
if
__name__
==
"__main__"
:
test_main
()
greentest/2.5/test_wsgiref.py
deleted
100755 → 0
View file @
ed74f199
from
__future__
import
nested_scopes
# Backward compat for 2.1
from
unittest
import
TestSuite
,
TestCase
,
makeSuite
from
wsgiref.util
import
setup_testing_defaults
from
wsgiref.headers
import
Headers
from
wsgiref.handlers
import
BaseHandler
,
BaseCGIHandler
from
wsgiref
import
util
from
wsgiref.validate
import
validator
from
wsgiref.simple_server
import
WSGIServer
,
WSGIRequestHandler
,
demo_app
from
wsgiref.simple_server
import
make_server
from
StringIO
import
StringIO
from
SocketServer
import
BaseServer
import
re
,
sys
class
MockServer
(
WSGIServer
):
"""Non-socket HTTP server"""
def
__init__
(
self
,
server_address
,
RequestHandlerClass
):
BaseServer
.
__init__
(
self
,
server_address
,
RequestHandlerClass
)
self
.
server_bind
()
def
server_bind
(
self
):
host
,
port
=
self
.
server_address
self
.
server_name
=
host
self
.
server_port
=
port
self
.
setup_environ
()
class
MockHandler
(
WSGIRequestHandler
):
"""Non-socket HTTP handler"""
def
setup
(
self
):
self
.
connection
=
self
.
request
self
.
rfile
,
self
.
wfile
=
self
.
connection
def
finish
(
self
):
pass
def
hello_app
(
environ
,
start_response
):
start_response
(
"200 OK"
,
[
(
'Content-Type'
,
'text/plain'
),
(
'Date'
,
'Mon, 05 Jun 2006 18:49:54 GMT'
)
])
return
[
"Hello, world!"
]
def
run_amock
(
app
=
hello_app
,
data
=
"GET / HTTP/1.0
\
n
\
n
"
):
server
=
make_server
(
""
,
80
,
app
,
MockServer
,
MockHandler
)
inp
,
out
,
err
,
olderr
=
StringIO
(
data
),
StringIO
(),
StringIO
(),
sys
.
stderr
sys
.
stderr
=
err
try
:
server
.
finish_request
((
inp
,
out
),
(
"127.0.0.1"
,
8888
))
finally
:
sys
.
stderr
=
olderr
return
out
.
getvalue
(),
err
.
getvalue
()
def
compare_generic_iter
(
make_it
,
match
):
"""Utility to compare a generic 2.1/2.2+ iterator with an iterable
If running under Python 2.2+, this tests the iterator using iter()/next(),
as well as __getitem__. 'make_it' must be a function returning a fresh
iterator to be tested (since this may test the iterator twice)."""
it
=
make_it
()
n
=
0
for
item
in
match
:
if
not
it
[
n
]
==
item
:
raise
AssertionError
n
+=
1
try
:
it
[
n
]
except
IndexError
:
pass
else
:
raise
AssertionError
(
"Too many items from __getitem__"
,
it
)
try
:
iter
,
StopIteration
except
NameError
:
pass
else
:
# Only test iter mode under 2.2+
it
=
make_it
()
if
not
iter
(
it
)
is
it
:
raise
AssertionError
for
item
in
match
:
if
not
it
.
next
()
==
item
:
raise
AssertionError
try
:
it
.
next
()
except
StopIteration
:
pass
else
:
raise
AssertionError
(
"Too many items from .next()"
,
it
)
class
IntegrationTests
(
TestCase
):
def
check_hello
(
self
,
out
,
has_length
=
True
):
self
.
assertEqual
(
out
,
"HTTP/1.0 200 OK
\
r
\
n
"
"Server: WSGIServer/0.1 Python/"
+
sys
.
version
.
split
()[
0
]
+
"
\
r
\
n
"
"Content-Type: text/plain
\
r
\
n
"
"Date: Mon, 05 Jun 2006 18:49:54 GMT
\
r
\
n
"
+
(
has_length
and
"Content-Length: 13
\
r
\
n
"
or
""
)
+
"
\
r
\
n
"
"Hello, world!"
)
def
test_plain_hello
(
self
):
out
,
err
=
run_amock
()
self
.
check_hello
(
out
)
def
test_validated_hello
(
self
):
out
,
err
=
run_amock
(
validator
(
hello_app
))
# the middleware doesn't support len(), so content-length isn't there
self
.
check_hello
(
out
,
has_length
=
False
)
def
test_simple_validation_error
(
self
):
def
bad_app
(
environ
,
start_response
):
start_response
(
"200 OK"
,
(
'Content-Type'
,
'text/plain'
))
return
[
"Hello, world!"
]
out
,
err
=
run_amock
(
validator
(
bad_app
))
self
.
failUnless
(
out
.
endswith
(
"A server error occurred. Please contact the administrator."
))
self
.
assertEqual
(
err
.
splitlines
()[
-
2
],
"AssertionError: Headers (('Content-Type', 'text/plain')) must"
" be of type list: <type 'tuple'>"
)
class
UtilityTests
(
TestCase
):
def
checkShift
(
self
,
sn_in
,
pi_in
,
part
,
sn_out
,
pi_out
):
env
=
{
'SCRIPT_NAME'
:
sn_in
,
'PATH_INFO'
:
pi_in
}
util
.
setup_testing_defaults
(
env
)
self
.
assertEqual
(
util
.
shift_path_info
(
env
),
part
)
self
.
assertEqual
(
env
[
'PATH_INFO'
],
pi_out
)
self
.
assertEqual
(
env
[
'SCRIPT_NAME'
],
sn_out
)
return
env
def
checkDefault
(
self
,
key
,
value
,
alt
=
None
):
# Check defaulting when empty
env
=
{}
util
.
setup_testing_defaults
(
env
)
if
isinstance
(
value
,
StringIO
):
self
.
failUnless
(
isinstance
(
env
[
key
],
StringIO
))
else
:
self
.
assertEqual
(
env
[
key
],
value
)
# Check existing value
env
=
{
key
:
alt
}
util
.
setup_testing_defaults
(
env
)
self
.
failUnless
(
env
[
key
]
is
alt
)
def
checkCrossDefault
(
self
,
key
,
value
,
**
kw
):
util
.
setup_testing_defaults
(
kw
)
self
.
assertEqual
(
kw
[
key
],
value
)
def
checkAppURI
(
self
,
uri
,
**
kw
):
util
.
setup_testing_defaults
(
kw
)
self
.
assertEqual
(
util
.
application_uri
(
kw
),
uri
)
def
checkReqURI
(
self
,
uri
,
query
=
1
,
**
kw
):
util
.
setup_testing_defaults
(
kw
)
self
.
assertEqual
(
util
.
request_uri
(
kw
,
query
),
uri
)
def
checkFW
(
self
,
text
,
size
,
match
):
def
make_it
(
text
=
text
,
size
=
size
):
return
util
.
FileWrapper
(
StringIO
(
text
),
size
)
compare_generic_iter
(
make_it
,
match
)
it
=
make_it
()
self
.
failIf
(
it
.
filelike
.
closed
)
for
item
in
it
:
pass
self
.
failIf
(
it
.
filelike
.
closed
)
it
.
close
()
self
.
failUnless
(
it
.
filelike
.
closed
)
def
testSimpleShifts
(
self
):
self
.
checkShift
(
''
,
'/'
,
''
,
'/'
,
''
)
self
.
checkShift
(
''
,
'/x'
,
'x'
,
'/x'
,
''
)
self
.
checkShift
(
'/'
,
''
,
None
,
'/'
,
''
)
self
.
checkShift
(
'/a'
,
'/x/y'
,
'x'
,
'/a/x'
,
'/y'
)
self
.
checkShift
(
'/a'
,
'/x/'
,
'x'
,
'/a/x'
,
'/'
)
def
testNormalizedShifts
(
self
):
self
.
checkShift
(
'/a/b'
,
'/../y'
,
'..'
,
'/a'
,
'/y'
)
self
.
checkShift
(
''
,
'/../y'
,
'..'
,
''
,
'/y'
)
self
.
checkShift
(
'/a/b'
,
'//y'
,
'y'
,
'/a/b/y'
,
''
)
self
.
checkShift
(
'/a/b'
,
'//y/'
,
'y'
,
'/a/b/y'
,
'/'
)
self
.
checkShift
(
'/a/b'
,
'/./y'
,
'y'
,
'/a/b/y'
,
''
)
self
.
checkShift
(
'/a/b'
,
'/./y/'
,
'y'
,
'/a/b/y'
,
'/'
)
self
.
checkShift
(
'/a/b'
,
'///./..//y/.//'
,
'..'
,
'/a'
,
'/y/'
)
self
.
checkShift
(
'/a/b'
,
'///'
,
''
,
'/a/b/'
,
''
)
self
.
checkShift
(
'/a/b'
,
'/.//'
,
''
,
'/a/b/'
,
''
)
self
.
checkShift
(
'/a/b'
,
'/x//'
,
'x'
,
'/a/b/x'
,
'/'
)
self
.
checkShift
(
'/a/b'
,
'/.'
,
None
,
'/a/b'
,
''
)
def
testDefaults
(
self
):
for
key
,
value
in
[
(
'SERVER_NAME'
,
'127.0.0.1'
),
(
'SERVER_PORT'
,
'80'
),
(
'SERVER_PROTOCOL'
,
'HTTP/1.0'
),
(
'HTTP_HOST'
,
'127.0.0.1'
),
(
'REQUEST_METHOD'
,
'GET'
),
(
'SCRIPT_NAME'
,
''
),
(
'PATH_INFO'
,
'/'
),
(
'wsgi.version'
,
(
1
,
0
)),
(
'wsgi.run_once'
,
0
),
(
'wsgi.multithread'
,
0
),
(
'wsgi.multiprocess'
,
0
),
(
'wsgi.input'
,
StringIO
(
""
)),
(
'wsgi.errors'
,
StringIO
()),
(
'wsgi.url_scheme'
,
'http'
),
]:
self
.
checkDefault
(
key
,
value
)
def
testCrossDefaults
(
self
):
self
.
checkCrossDefault
(
'HTTP_HOST'
,
"foo.bar"
,
SERVER_NAME
=
"foo.bar"
)
self
.
checkCrossDefault
(
'wsgi.url_scheme'
,
"https"
,
HTTPS
=
"on"
)
self
.
checkCrossDefault
(
'wsgi.url_scheme'
,
"https"
,
HTTPS
=
"1"
)
self
.
checkCrossDefault
(
'wsgi.url_scheme'
,
"https"
,
HTTPS
=
"yes"
)
self
.
checkCrossDefault
(
'wsgi.url_scheme'
,
"http"
,
HTTPS
=
"foo"
)
self
.
checkCrossDefault
(
'SERVER_PORT'
,
"80"
,
HTTPS
=
"foo"
)
self
.
checkCrossDefault
(
'SERVER_PORT'
,
"443"
,
HTTPS
=
"on"
)
def
testGuessScheme
(
self
):
self
.
assertEqual
(
util
.
guess_scheme
({}),
"http"
)
self
.
assertEqual
(
util
.
guess_scheme
({
'HTTPS'
:
"foo"
}),
"http"
)
self
.
assertEqual
(
util
.
guess_scheme
({
'HTTPS'
:
"on"
}),
"https"
)
self
.
assertEqual
(
util
.
guess_scheme
({
'HTTPS'
:
"yes"
}),
"https"
)
self
.
assertEqual
(
util
.
guess_scheme
({
'HTTPS'
:
"1"
}),
"https"
)
def
testAppURIs
(
self
):
self
.
checkAppURI
(
"http://127.0.0.1/"
)
self
.
checkAppURI
(
"http://127.0.0.1/spam"
,
SCRIPT_NAME
=
"/spam"
)
self
.
checkAppURI
(
"http://spam.example.com:2071/"
,
HTTP_HOST
=
"spam.example.com:2071"
,
SERVER_PORT
=
"2071"
)
self
.
checkAppURI
(
"http://spam.example.com/"
,
SERVER_NAME
=
"spam.example.com"
)
self
.
checkAppURI
(
"http://127.0.0.1/"
,
HTTP_HOST
=
"127.0.0.1"
,
SERVER_NAME
=
"spam.example.com"
)
self
.
checkAppURI
(
"https://127.0.0.1/"
,
HTTPS
=
"on"
)
self
.
checkAppURI
(
"http://127.0.0.1:8000/"
,
SERVER_PORT
=
"8000"
,
HTTP_HOST
=
None
)
def
testReqURIs
(
self
):
self
.
checkReqURI
(
"http://127.0.0.1/"
)
self
.
checkReqURI
(
"http://127.0.0.1/spam"
,
SCRIPT_NAME
=
"/spam"
)
self
.
checkReqURI
(
"http://127.0.0.1/spammity/spam"
,
SCRIPT_NAME
=
"/spammity"
,
PATH_INFO
=
"/spam"
)
self
.
checkReqURI
(
"http://127.0.0.1/spammity/spam?say=ni"
,
SCRIPT_NAME
=
"/spammity"
,
PATH_INFO
=
"/spam"
,
QUERY_STRING
=
"say=ni"
)
self
.
checkReqURI
(
"http://127.0.0.1/spammity/spam"
,
0
,
SCRIPT_NAME
=
"/spammity"
,
PATH_INFO
=
"/spam"
,
QUERY_STRING
=
"say=ni"
)
def
testFileWrapper
(
self
):
self
.
checkFW
(
"xyz"
*
50
,
120
,
[
"xyz"
*
40
,
"xyz"
*
10
])
def
testHopByHop
(
self
):
for
hop
in
(
"Connection Keep-Alive Proxy-Authenticate Proxy-Authorization "
"TE Trailers Transfer-Encoding Upgrade"
).
split
():
for
alt
in
hop
,
hop
.
title
(),
hop
.
upper
(),
hop
.
lower
():
self
.
failUnless
(
util
.
is_hop_by_hop
(
alt
))
# Not comprehensive, just a few random header names
for
hop
in
(
"Accept Cache-Control Date Pragma Trailer Via Warning"
).
split
():
for
alt
in
hop
,
hop
.
title
(),
hop
.
upper
(),
hop
.
lower
():
self
.
failIf
(
util
.
is_hop_by_hop
(
alt
))
class
HeaderTests
(
TestCase
):
def
testMappingInterface
(
self
):
test
=
[(
'x'
,
'y'
)]
self
.
assertEqual
(
len
(
Headers
([])),
0
)
self
.
assertEqual
(
len
(
Headers
(
test
[:])),
1
)
self
.
assertEqual
(
Headers
(
test
[:]).
keys
(),
[
'x'
])
self
.
assertEqual
(
Headers
(
test
[:]).
values
(),
[
'y'
])
self
.
assertEqual
(
Headers
(
test
[:]).
items
(),
test
)
self
.
failIf
(
Headers
(
test
).
items
()
is
test
)
# must be copy!
h
=
Headers
([])
del
h
[
'foo'
]
# should not raise an error
h
[
'Foo'
]
=
'bar'
for
m
in
h
.
has_key
,
h
.
__contains__
,
h
.
get
,
h
.
get_all
,
h
.
__getitem__
:
self
.
failUnless
(
m
(
'foo'
))
self
.
failUnless
(
m
(
'Foo'
))
self
.
failUnless
(
m
(
'FOO'
))
self
.
failIf
(
m
(
'bar'
))
self
.
assertEqual
(
h
[
'foo'
],
'bar'
)
h
[
'foo'
]
=
'baz'
self
.
assertEqual
(
h
[
'FOO'
],
'baz'
)
self
.
assertEqual
(
h
.
get_all
(
'foo'
),[
'baz'
])
self
.
assertEqual
(
h
.
get
(
"foo"
,
"whee"
),
"baz"
)
self
.
assertEqual
(
h
.
get
(
"zoo"
,
"whee"
),
"whee"
)
self
.
assertEqual
(
h
.
setdefault
(
"foo"
,
"whee"
),
"baz"
)
self
.
assertEqual
(
h
.
setdefault
(
"zoo"
,
"whee"
),
"whee"
)
self
.
assertEqual
(
h
[
"foo"
],
"baz"
)
self
.
assertEqual
(
h
[
"zoo"
],
"whee"
)
def
testRequireList
(
self
):
self
.
assertRaises
(
TypeError
,
Headers
,
"foo"
)
def
testExtras
(
self
):
h
=
Headers
([])
self
.
assertEqual
(
str
(
h
),
'
\
r
\
n
'
)
h
.
add_header
(
'foo'
,
'bar'
,
baz
=
"spam"
)
self
.
assertEqual
(
h
[
'foo'
],
'bar; baz="spam"'
)
self
.
assertEqual
(
str
(
h
),
'foo: bar; baz="spam"
\
r
\
n
\
r
\
n
'
)
h
.
add_header
(
'Foo'
,
'bar'
,
cheese
=
None
)
self
.
assertEqual
(
h
.
get_all
(
'foo'
),
[
'bar; baz="spam"'
,
'bar; cheese'
])
self
.
assertEqual
(
str
(
h
),
'foo: bar; baz="spam"
\
r
\
n
'
'Foo: bar; cheese
\
r
\
n
'
'
\
r
\
n
'
)
class
ErrorHandler
(
BaseCGIHandler
):
"""Simple handler subclass for testing BaseHandler"""
def
__init__
(
self
,
**
kw
):
setup_testing_defaults
(
kw
)
BaseCGIHandler
.
__init__
(
self
,
StringIO
(
''
),
StringIO
(),
StringIO
(),
kw
,
multithread
=
True
,
multiprocess
=
True
)
class
TestHandler
(
ErrorHandler
):
"""Simple handler subclass for testing BaseHandler, w/error passthru"""
def
handle_error
(
self
):
raise
# for testing, we want to see what's happening
class
HandlerTests
(
TestCase
):
def
checkEnvironAttrs
(
self
,
handler
):
env
=
handler
.
environ
for
attr
in
[
'version'
,
'multithread'
,
'multiprocess'
,
'run_once'
,
'file_wrapper'
]:
if
attr
==
'file_wrapper'
and
handler
.
wsgi_file_wrapper
is
None
:
continue
self
.
assertEqual
(
getattr
(
handler
,
'wsgi_'
+
attr
),
env
[
'wsgi.'
+
attr
])
def
checkOSEnviron
(
self
,
handler
):
empty
=
{};
setup_testing_defaults
(
empty
)
env
=
handler
.
environ
from
os
import
environ
for
k
,
v
in
environ
.
items
():
if
not
empty
.
has_key
(
k
):
self
.
assertEqual
(
env
[
k
],
v
)
for
k
,
v
in
empty
.
items
():
self
.
failUnless
(
env
.
has_key
(
k
))
def
testEnviron
(
self
):
h
=
TestHandler
(
X
=
"Y"
)
h
.
setup_environ
()
self
.
checkEnvironAttrs
(
h
)
self
.
checkOSEnviron
(
h
)
self
.
assertEqual
(
h
.
environ
[
"X"
],
"Y"
)
def
testCGIEnviron
(
self
):
h
=
BaseCGIHandler
(
None
,
None
,
None
,{})
h
.
setup_environ
()
for
key
in
'wsgi.url_scheme'
,
'wsgi.input'
,
'wsgi.errors'
:
self
.
assert_
(
h
.
environ
.
has_key
(
key
))
def
testScheme
(
self
):
h
=
TestHandler
(
HTTPS
=
"on"
);
h
.
setup_environ
()
self
.
assertEqual
(
h
.
environ
[
'wsgi.url_scheme'
],
'https'
)
h
=
TestHandler
();
h
.
setup_environ
()
self
.
assertEqual
(
h
.
environ
[
'wsgi.url_scheme'
],
'http'
)
def
testAbstractMethods
(
self
):
h
=
BaseHandler
()
for
name
in
[
'_flush'
,
'get_stdin'
,
'get_stderr'
,
'add_cgi_vars'
]:
self
.
assertRaises
(
NotImplementedError
,
getattr
(
h
,
name
))
self
.
assertRaises
(
NotImplementedError
,
h
.
_write
,
"test"
)
def
testContentLength
(
self
):
# Demo one reason iteration is better than write()... ;)
def
trivial_app1
(
e
,
s
):
s
(
'200 OK'
,[])
return
[
e
[
'wsgi.url_scheme'
]]
def
trivial_app2
(
e
,
s
):
s
(
'200 OK'
,[])(
e
[
'wsgi.url_scheme'
])
return
[]
h
=
TestHandler
()
h
.
run
(
trivial_app1
)
self
.
assertEqual
(
h
.
stdout
.
getvalue
(),
"Status: 200 OK
\
r
\
n
"
"Content-Length: 4
\
r
\
n
"
"
\
r
\
n
"
"http"
)
h
=
TestHandler
()
h
.
run
(
trivial_app2
)
self
.
assertEqual
(
h
.
stdout
.
getvalue
(),
"Status: 200 OK
\
r
\
n
"
"
\
r
\
n
"
"http"
)
def
testBasicErrorOutput
(
self
):
def
non_error_app
(
e
,
s
):
s
(
'200 OK'
,[])
return
[]
def
error_app
(
e
,
s
):
raise
AssertionError
(
"This should be caught by handler"
)
h
=
ErrorHandler
()
h
.
run
(
non_error_app
)
self
.
assertEqual
(
h
.
stdout
.
getvalue
(),
"Status: 200 OK
\
r
\
n
"
"Content-Length: 0
\
r
\
n
"
"
\
r
\
n
"
)
self
.
assertEqual
(
h
.
stderr
.
getvalue
(),
""
)
h
=
ErrorHandler
()
h
.
run
(
error_app
)
self
.
assertEqual
(
h
.
stdout
.
getvalue
(),
"Status: %s
\
r
\
n
"
"Content-Type: text/plain
\
r
\
n
"
"Content-Length: %d
\
r
\
n
"
"
\
r
\
n
%s"
%
(
h
.
error_status
,
len
(
h
.
error_body
),
h
.
error_body
))
self
.
failUnless
(
h
.
stderr
.
getvalue
().
find
(
"AssertionError"
)
<>-
1
)
def
testErrorAfterOutput
(
self
):
MSG
=
"Some output has been sent"
def
error_app
(
e
,
s
):
s
(
"200 OK"
,[])(
MSG
)
raise
AssertionError
(
"This should be caught by handler"
)
h
=
ErrorHandler
()
h
.
run
(
error_app
)
self
.
assertEqual
(
h
.
stdout
.
getvalue
(),
"Status: 200 OK
\
r
\
n
"
"
\
r
\
n
"
+
MSG
)
self
.
failUnless
(
h
.
stderr
.
getvalue
().
find
(
"AssertionError"
)
<>-
1
)
def
testHeaderFormats
(
self
):
def
non_error_app
(
e
,
s
):
s
(
'200 OK'
,[])
return
[]
stdpat
=
(
r"HTTP/%s 200 OK\r\n"
r"Date: \
w{
3}, [ 0123]\
d
\w{3} \
d{
4} \
d
\d:\
d
\d:\
d
\d GMT\r\n"
r"%s"
r"Content-Length: 0\r\n"
r"\r\n"
)
shortpat
=
(
"Status: 200 OK
\
r
\
n
"
"Content-Length: 0
\
r
\
n
"
"
\
r
\
n
"
)
for
ssw
in
"FooBar/1.0"
,
None
:
sw
=
ssw
and
"Server: %s
\
r
\
n
"
%
ssw
or
""
for
version
in
"1.0"
,
"1.1"
:
for
proto
in
"HTTP/0.9"
,
"HTTP/1.0"
,
"HTTP/1.1"
:
h
=
TestHandler
(
SERVER_PROTOCOL
=
proto
)
h
.
origin_server
=
False
h
.
http_version
=
version
h
.
server_software
=
ssw
h
.
run
(
non_error_app
)
self
.
assertEqual
(
shortpat
,
h
.
stdout
.
getvalue
())
h
=
TestHandler
(
SERVER_PROTOCOL
=
proto
)
h
.
origin_server
=
True
h
.
http_version
=
version
h
.
server_software
=
ssw
h
.
run
(
non_error_app
)
if
proto
==
"HTTP/0.9"
:
self
.
assertEqual
(
h
.
stdout
.
getvalue
(),
""
)
else
:
self
.
failUnless
(
re
.
match
(
stdpat
%
(
version
,
sw
),
h
.
stdout
.
getvalue
()),
(
stdpat
%
(
version
,
sw
),
h
.
stdout
.
getvalue
())
)
# This epilogue is needed for compatibility with the Python 2.5 regrtest module
def
test_main
():
import
unittest
from
test.test_support
import
run_suite
run_suite
(
unittest
.
defaultTestLoader
.
loadTestsFromModule
(
sys
.
modules
[
__name__
])
)
if
__name__
==
"__main__"
:
test_main
()
# the above lines intentionally left blank
greentest/2.5/version
deleted
100644 → 0
View file @
ed74f199
2.5.6
known_failures.txt
View file @
9177c3af
...
...
@@ -16,11 +16,6 @@ win32 * C:\Python27\python.exe -u -m monkey_test test_subprocess.py
win32 * C:\Python27\python.exe -u -m monkey_test --Event test_subprocess.py
# these need investigating:
* * .*/python2.5(-dbg)? -u -m monkey_test --Event test_urllib2net.py
* * .*/python2.5(-dbg)? -u -m monkey_test test_urllib2net.py
* * .*/python2.5(-dbg)? -u test__threading_vs_settrace.py
* * .*/python2.5(-dbg)? -u test__example_portforwarder.py
* * .*/python2.5(-dbg)? -u test__socket_close.py
* * * -u test__issue6.py
# bunch of SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
...
...
@@ -28,4 +23,4 @@ win32 * C:\Python27\python.exe -u -m monkey_test --Event test_subprocess.py
* * * -u -m monkey_test --Event test_ssl.py
* * * -u -m monkey_test test_ssl.py
* * /usr/bin/python2.[
5
67]-dbg -u test__backdoor.py
* * /usr/bin/python2.[67]-dbg -u test__backdoor.py
setup.py
View file @
9177c3af
...
...
@@ -300,7 +300,6 @@ def run_setup(ext_modules):
install_requires
=
[
'greenlet'
],
classifiers
=
[
"License :: OSI Approved :: MIT License"
,
"Programming Language :: Python :: 2.5"
,
"Programming Language :: Python :: 2.6"
,
"Programming Language :: Python :: 2.7"
,
"Operating System :: MacOS :: MacOS X"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment