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
bb7cf8fb
Commit
bb7cf8fb
authored
Nov 13, 2018
by
Jason Madden
Committed by
GitHub
Nov 13, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1313 from gevent/issue1296
Refactoring to run tests from an install
parents
9560b486
5a252e03
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
304 additions
and
135 deletions
+304
-135
_setupares.py
_setupares.py
+10
-2
_setuputils.py
_setuputils.py
+3
-4
appveyor.yml
appveyor.yml
+1
-1
src/gevent/subprocess.py
src/gevent/subprocess.py
+25
-9
src/gevent/testing/patched_tests_setup.py
src/gevent/testing/patched_tests_setup.py
+4
-3
src/gevent/testing/testrunner.py
src/gevent/testing/testrunner.py
+30
-12
src/gevent/testing/util.py
src/gevent/testing/util.py
+97
-30
src/gevent/tests/test___monkey_patching.py
src/gevent/tests/test___monkey_patching.py
+47
-25
src/gevent/tests/test__doctests.py
src/gevent/tests/test__doctests.py
+32
-20
src/gevent/tests/test__examples.py
src/gevent/tests/test__examples.py
+51
-25
src/gevent/tests/test__threading_2.py
src/gevent/tests/test__threading_2.py
+1
-1
src/greentest/2.7/test_threading.py
src/greentest/2.7/test_threading.py
+1
-1
src/greentest/2.7pypy/test_threading.py
src/greentest/2.7pypy/test_threading.py
+1
-1
src/greentest/3.7/test_threading.py
src/greentest/3.7/test_threading.py
+1
-1
No files found.
_setupares.py
View file @
bb7cf8fb
...
...
@@ -24,6 +24,7 @@ from _setuputils import DEFINE_MACROS
from
_setuputils
import
glob_many
from
_setuputils
import
dep_abspath
from
_setuputils
import
RUNNING_ON_CI
from
_setuputils
import
RUNNING_FROM_CHECKOUT
from
_setuputils
import
cythonize1
...
...
@@ -51,14 +52,19 @@ ares_configure_command = ' '.join([
def
configure_ares
(
bext
,
ext
):
print
(
"Embedding c-ares"
,
bext
,
ext
)
bdir
=
os
.
path
.
join
(
bext
.
build_temp
,
'c-ares'
)
ext
.
include_dirs
.
insert
(
0
,
bdir
)
print
(
"Inserted "
,
bdir
,
"in include dirs"
,
ext
.
include_dirs
)
if
not
os
.
path
.
isdir
(
bdir
):
os
.
makedirs
(
bdir
)
if
WIN
:
shutil
.
copy
(
"deps
\
\
c-ares
\
\
ares_build.h.dist"
,
os
.
path
.
join
(
bdir
,
"ares_build.h"
))
src
=
"deps
\
\
c-ares
\
\
ares_build.h.dist"
dest
=
os
.
path
.
join
(
bdir
,
"ares_build.h"
)
print
(
"Copying %r to %r"
%
(
src
,
dest
))
shutil
.
copy
(
src
,
dest
)
return
cwd
=
os
.
getcwd
()
...
...
@@ -87,7 +93,8 @@ ARES = Extension(name='gevent.resolver.cares',
depends
=
glob_many
(
'src/gevent/resolver/dnshelper.c'
,
'src/gevent/resolver/cares_*.[ch]'
))
ARES
.
optional
=
not
RUNNING_ON_CI
ares_required
=
RUNNING_ON_CI
and
RUNNING_FROM_CHECKOUT
ARES
.
optional
=
not
ares_required
if
CARES_EMBED
:
...
...
@@ -108,5 +115,6 @@ if CARES_EMBED:
else
:
ARES
.
libraries
.
append
(
'cares'
)
ARES
.
define_macros
+=
[(
'HAVE_NETDB_H'
,
''
)]
ARES
.
configure
=
lambda
bext
,
ext
:
print
(
"c-ares not embedded, not configuring"
,
bext
,
ext
)
ARES
=
cythonize1
(
ARES
)
_setuputils.py
View file @
bb7cf8fb
...
...
@@ -15,6 +15,7 @@ from glob import glob
from
setuptools
import
Extension
as
_Extension
from
setuptools.command.build_ext
import
build_ext
THIS_DIR
=
os
.
path
.
dirname
(
__file__
)
## Exported configurations
...
...
@@ -24,7 +25,7 @@ WIN = sys.platform.startswith('win')
RUNNING_ON_TRAVIS
=
os
.
environ
.
get
(
'TRAVIS'
)
RUNNING_ON_APPVEYOR
=
os
.
environ
.
get
(
'APPVEYOR'
)
RUNNING_ON_CI
=
RUNNING_ON_TRAVIS
or
RUNNING_ON_APPVEYOR
RUNNING_FROM_CHECKOUT
=
os
.
path
.
isdir
(
os
.
path
.
join
(
THIS_DIR
,
".git"
))
LIBRARIES
=
[]
...
...
@@ -37,8 +38,6 @@ if WIN:
### File handling
THIS_DIR
=
os
.
path
.
dirname
(
__file__
)
def
quoted_abspath
(
*
segments
):
return
'"'
+
os
.
path
.
abspath
(
os
.
path
.
join
(
*
segments
))
+
'"'
...
...
@@ -78,7 +77,7 @@ def _parse_environ(key):
value
=
value
.
lower
().
strip
()
if
value
in
(
'1'
,
'true'
,
'on'
,
'yes'
):
return
True
el
if
value
in
(
'0'
,
'false'
,
'off'
,
'no'
):
if
value
in
(
'0'
,
'false'
,
'off'
,
'no'
):
return
False
raise
ValueError
(
'Environment variable %r has invalid value %r. '
'Please set it to 1, 0 or an empty string'
%
(
key
,
value
))
...
...
appveyor.yml
View file @
bb7cf8fb
...
...
@@ -138,7 +138,7 @@ cache:
-
'
%LOCALAPPDATA%\pip\Cache'
build_script
:
-
"
%PYEXE%
-m
pip
install
-U
--upgrade-strategy=eager
-e
.[test,events,dnspython]"
-
"
%PYEXE%
-m
pip
install
-U
--upgrade-strategy=eager
.[test,events,dnspython]"
test_script
:
# Run the project tests
...
...
src/gevent/subprocess.py
View file @
bb7cf8fb
...
...
@@ -26,8 +26,6 @@ Cooperative ``subprocess`` module.
from
__future__
import
absolute_import
,
print_function
# Can we split this up to make it cleaner? See https://github.com/gevent/gevent/issues/748
# pylint: disable=too-many-lines
# Import magic
# pylint: disable=undefined-all-variable,undefined-variable
# Most of this we inherit from the standard lib
# pylint: disable=bare-except,too-many-locals,too-many-statements,attribute-defined-outside-init
# pylint: disable=too-many-branches,too-many-instance-attributes
...
...
@@ -51,7 +49,7 @@ from gevent._compat import fspath
from
gevent._compat
import
fsencode
from
gevent._util
import
_NONE
from
gevent._util
import
copy_globals
from
gevent.fileobject
import
FileObject
from
gevent.greenlet
import
Greenlet
,
joinall
spawn
=
Greenlet
.
spawn
import
subprocess
as
__subprocess__
...
...
@@ -274,7 +272,7 @@ def check_call(*popenargs, **kwargs):
cmd
=
kwargs
.
get
(
"args"
)
if
cmd
is
None
:
cmd
=
popenargs
[
0
]
raise
CalledProcessError
(
retcode
,
cmd
)
raise
CalledProcessError
(
retcode
,
cmd
)
# pylint:disable=undefined-variable
return
0
def
check_output
(
*
popenargs
,
**
kwargs
):
...
...
@@ -297,10 +295,10 @@ def check_output(*popenargs, **kwargs):
To capture standard error in the result, use ``stderr=STDOUT``::
>>> check_output(["/bin/sh", "-c",
>>>
print(
check_output(["/bin/sh", "-c",
... "ls -l non_existent_file ; exit 0"],
... stderr=STDOUT)
'ls: non_existent_file: No such file or directory\n'
... stderr=STDOUT)
.decode('ascii').strip())
ls: non_existent_file: No such file or directory
There is an additional optional argument, "input", allowing you to
pass a string to the subprocess's stdin. If you use this argument
...
...
@@ -346,6 +344,7 @@ def check_output(*popenargs, **kwargs):
raise
retcode
=
process
.
poll
()
if
retcode
:
# pylint:disable=undefined-variable
raise
CalledProcessError
(
retcode
,
process
.
args
,
output
=
output
)
return
output
...
...
@@ -396,6 +395,13 @@ else:
_set_inheritable
=
lambda
i
,
v
:
True
def
FileObject
(
*
args
):
# Defer importing FileObject until we need it
# to allow it to be configured more easily.
from
gevent.fileobject
import
FileObject
as
_FileObject
globals
()[
'FileObject'
]
=
_FileObject
return
_FileObject
(
*
args
)
class
Popen
(
object
):
"""
The underlying process creation and management in this module is
...
...
@@ -516,6 +522,7 @@ class Popen(object):
# Validate the combinations of text and universal_newlines
if
(
text
is
not
None
and
universal_newlines
is
not
None
and
bool
(
universal_newlines
)
!=
bool
(
text
)):
# pylint:disable=undefined-variable
raise
SubprocessError
(
'Cannot disambiguate when both text '
'and universal_newlines are supplied but '
'different. Pass one or the other.'
)
...
...
@@ -566,6 +573,7 @@ class Popen(object):
# Python 3, so it's actually a unicode str
self
.
_communicate_empty_value
=
''
if
p2cwrite
!=
-
1
:
if
PY3
and
text_mode
:
# Under Python 3, if we left on the 'b' we'd get different results
...
...
@@ -814,6 +822,7 @@ class Popen(object):
"""Construct and return tuple with IO objects:
p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
"""
# pylint:disable=undefined-variable
if
stdin
is
None
and
stdout
is
None
and
stderr
is
None
:
return
(
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
)
...
...
@@ -896,12 +905,14 @@ class Popen(object):
def
_make_inheritable
(
self
,
handle
):
"""Return a duplicate of handle, which is inheritable"""
# pylint:disable=undefined-variable
return
DuplicateHandle
(
GetCurrentProcess
(),
handle
,
GetCurrentProcess
(),
0
,
1
,
DUPLICATE_SAME_ACCESS
)
def
_find_w9xpopen
(
self
):
"""Find and return absolute path to w9xpopen.exe"""
# pylint:disable=undefined-variable
w9xpopen
=
os
.
path
.
join
(
os
.
path
.
dirname
(
GetModuleFileName
(
0
)),
"w9xpopen.exe"
)
if
not
os
.
path
.
exists
(
w9xpopen
):
...
...
@@ -938,7 +949,7 @@ class Popen(object):
errread
,
errwrite
,
unused_restore_signals
,
unused_start_new_session
):
"""Execute program (MS Windows version)"""
# pylint:disable=undefined-variable
assert
not
pass_fds
,
"pass_fds not supported on Windows."
if
not
isinstance
(
args
,
string_types
):
...
...
@@ -1053,6 +1064,7 @@ class Popen(object):
"""Check if child process has terminated. Returns returncode
attribute.
"""
# pylint:disable=undefined-variable
if
self
.
returncode
is
None
:
if
WaitForSingleObject
(
self
.
_handle
,
0
)
==
WAIT_OBJECT_0
:
self
.
returncode
=
GetExitCodeProcess
(
self
.
_handle
)
...
...
@@ -1067,6 +1079,7 @@ class Popen(object):
# XXX unlink
def
_blocking_wait
(
self
):
# pylint:disable=undefined-variable
WaitForSingleObject
(
self
.
_handle
,
INFINITE
)
self
.
returncode
=
GetExitCodeProcess
(
self
.
_handle
)
return
self
.
returncode
...
...
@@ -1098,6 +1111,7 @@ class Popen(object):
def
terminate
(
self
):
"""Terminates the process
"""
# pylint:disable=undefined-variable
# Don't terminate a process that we know has already died.
if
self
.
returncode
is
not
None
:
return
...
...
@@ -1169,7 +1183,7 @@ class Popen(object):
pass
elif
stderr
==
PIPE
:
errread
,
errwrite
=
self
.
pipe_cloexec
()
elif
stderr
==
STDOUT
:
elif
stderr
==
STDOUT
:
# pylint:disable=undefined-variable
if
c2pwrite
!=
-
1
:
errwrite
=
c2pwrite
else
:
# child's stdout is not set, use parent's stdout
...
...
@@ -1599,6 +1613,7 @@ class CompletedProcess(object):
def
check_returncode
(
self
):
"""Raise CalledProcessError if the exit code is non-zero."""
if
self
.
returncode
:
# pylint:disable=undefined-variable
raise
_with_stdout_stderr
(
CalledProcessError
(
self
.
returncode
,
self
.
args
,
self
.
stdout
),
self
.
stderr
)
...
...
@@ -1667,6 +1682,7 @@ def run(*popenargs, **kwargs):
raise
retcode
=
process
.
poll
()
if
check
and
retcode
:
# pylint:disable=undefined-variable
raise
_with_stdout_stderr
(
CalledProcessError
(
retcode
,
process
.
args
,
stdout
),
stderr
)
return
CompletedProcess
(
process
.
args
,
retcode
,
stdout
,
stderr
)
src/gevent/testing/patched_tests_setup.py
View file @
bb7cf8fb
...
...
@@ -406,9 +406,6 @@ if LIBUV:
'test_httpservers.CGIHTTPServerTestCase.test_invaliduri'
,
'test_httpservers.CGIHTTPServerTestCase.test_issue19435'
,
# Sometimes raises LoopExit on CPython
'test_socket.BufferIOTest.testRecvFromIntoArray'
,
# Unexpected timeouts sometimes
'test_smtplib.TooLongLineTests.testLineTooLong'
,
'test_smtplib.GeneralTests.testTimeoutValue'
,
...
...
@@ -463,6 +460,10 @@ if LIBUV:
# This test winds up hanging a long time.
# Inserting GCs doesn't fix it.
'test_ssl.ThreadedTests.test_handshake_timeout'
,
# These sometimes raise LoopExit, for no apparent reason.
'test_socket.BufferIOTest.testRecvFromIntoBytearray'
,
'test_socket.BufferIOTest.testRecvFromIntoArray'
,
]
if
PY3
:
...
...
src/gevent/testing/testrunner.py
View file @
bb7cf8fb
...
...
@@ -75,11 +75,13 @@ def run_many(tests,
total
=
0
failed
=
{}
passed
=
{}
total_cases
=
[
0
]
total_skipped
=
[
0
]
NWORKERS
=
min
(
len
(
tests
),
NWORKERS
)
or
1
pool
=
ThreadPool
(
NWORKERS
)
util
.
BUFFER_OUTPUT
=
NWORKERS
>
1
util
.
BUFFER_OUTPUT
=
NWORKERS
>
1
or
quiet
def
run_one
(
cmd
,
**
kwargs
):
kwargs
[
'quiet'
]
=
quiet
...
...
@@ -90,6 +92,8 @@ def run_many(tests,
failed
[
result
.
name
]
=
[
cmd
,
kwargs
]
else
:
passed
[
result
.
name
]
=
True
total_cases
[
0
]
+=
result
.
run_count
total_skipped
[
0
]
+=
result
.
skipped_count
results
=
[]
...
...
@@ -143,7 +147,8 @@ def run_many(tests,
except
KeyboardInterrupt
:
pool
.
terminate
()
report
(
total
,
failed
,
passed
,
exit
=
False
,
took
=
time
.
time
()
-
start
,
configured_failing_tests
=
configured_failing_tests
)
configured_failing_tests
=
configured_failing_tests
,
total_cases
=
total_cases
[
0
],
total_skipped
=
total_skipped
[
0
])
log
(
'(partial results)
\
n
'
)
raise
except
:
...
...
@@ -153,7 +158,8 @@ def run_many(tests,
reap_all
()
report
(
total
,
failed
,
passed
,
took
=
time
.
time
()
-
start
,
configured_failing_tests
=
configured_failing_tests
)
configured_failing_tests
=
configured_failing_tests
,
total_cases
=
total_cases
[
0
],
total_skipped
=
total_skipped
[
0
])
def
discover
(
tests
=
None
,
ignore_files
=
None
,
...
...
@@ -194,7 +200,7 @@ def discover(
tests
=
sorted
(
tests
)
to_process
=
[]
to_import
=
[]
for
filename
in
tests
:
module_name
=
os
.
path
.
splitext
(
filename
)[
0
]
...
...
@@ -210,11 +216,7 @@ def discover(
contents
=
f
.
read
()
if
b'TESTRUNNER'
in
contents
:
# test__monkey_patching.py
# XXX: Rework this to avoid importing.
module
=
importlib
.
import_module
(
qualified_name
)
for
cmd
,
options
in
module
.
TESTRUNNER
():
if
remove_options
(
cmd
)[
-
1
]
in
ignore
:
continue
to_process
.
append
((
cmd
,
options
))
to_import
.
append
(
qualified_name
)
else
:
cmd
=
[
sys
.
executable
,
'-u'
]
if
PYPY
and
PY2
:
...
...
@@ -232,6 +234,15 @@ def discover(
to_process
.
append
((
cmd
,
options
))
os
.
chdir
(
olddir
)
# When we actually execute, do so from the original directory,
# this helps find setup.py
for
qualified_name
in
to_import
:
module
=
importlib
.
import_module
(
qualified_name
)
for
cmd
,
options
in
module
.
TESTRUNNER
():
if
remove_options
(
cmd
)[
-
1
]
in
ignore
:
continue
to_process
.
append
((
cmd
,
options
))
return
to_process
...
...
@@ -275,8 +286,9 @@ def format_seconds(seconds):
def
report
(
total
,
failed
,
passed
,
exit
=
True
,
took
=
None
,
configured_failing_tests
=
()):
# pylint:disable=redefined-builtin,too-many-branches
configured_failing_tests
=
(),
total_cases
=
0
,
total_skipped
=
0
):
# pylint:disable=redefined-builtin,too-many-branches,too-many-locals
runtimelog
=
util
.
runtimelog
if
runtimelog
:
log
(
'
\
n
Longest-running tests:'
)
...
...
@@ -319,7 +331,13 @@ def report(total, failed, passed, exit=True, took=None,
log
(
'
\
n
%s/%s unexpected failures'
,
len
(
failed_unexpected
),
total
,
color
=
'error'
)
print_list
(
failed_unexpected
)
else
:
log
(
'
\
n
%s tests passed%s'
,
total
,
took
)
log
(
'
\
n
Ran %s tests%s in %s files%s'
,
total_cases
,
util
.
_colorize
(
'skipped'
,
" (skipped=%d)"
%
total_skipped
)
if
total_skipped
else
''
,
total
,
took
,
)
if
exit
:
if
failed_unexpected
:
...
...
src/gevent/testing/util.py
View file @
bb7cf8fb
from
__future__
import
print_function
,
absolute_import
,
division
import
re
import
sys
import
os
from
.
import
six
...
...
@@ -220,10 +222,14 @@ def start(command, quiet=False, **kwargs):
class
RunResult
(
object
):
def
__init__
(
self
,
code
,
output
=
None
,
name
=
None
):
def
__init__
(
self
,
code
,
output
=
None
,
name
=
None
,
run_count
=
0
,
skipped_count
=
0
):
self
.
code
=
code
self
.
output
=
output
self
.
name
=
name
self
.
run_count
=
run_count
self
.
skipped_count
=
skipped_count
def
__bool__
(
self
):
...
...
@@ -236,29 +242,50 @@ class RunResult(object):
def
_should_show_warning_output
(
out
):
if
b
'Warning'
in
out
:
if
'Warning'
in
out
:
# Strip out some patterns we specifically do not
# care about.
# from test.support for monkey-patched tests
out
=
out
.
replace
(
b'Warning -- reap_children'
,
b
'NADA'
)
out
=
out
.
replace
(
b"Warning -- threading_cleanup"
,
b
'NADA'
)
out
=
out
.
replace
(
'Warning -- reap_children'
,
'NADA'
)
out
=
out
.
replace
(
"Warning -- threading_cleanup"
,
'NADA'
)
# The below *could* be done with sophisticated enough warning
# filters passed to the children
# collections.abc is the new home; setuptools uses the old one,
# as does dnspython
out
=
out
.
replace
(
b"DeprecationWarning: Using or importing the ABCs"
,
b
'NADA'
)
out
=
out
.
replace
(
"DeprecationWarning: Using or importing the ABCs"
,
'NADA'
)
# libuv poor timer resolution
out
=
out
.
replace
(
b'UserWarning: libuv only supports'
,
b
'NADA'
)
out
=
out
.
replace
(
'UserWarning: libuv only supports'
,
'NADA'
)
# Packages on Python 2
out
=
out
.
replace
(
b'ImportWarning: Not importing directory'
,
b
'NADA'
)
return
b
'Warning'
in
out
out
=
out
.
replace
(
'ImportWarning: Not importing directory'
,
'NADA'
)
return
'Warning'
in
out
output_lock
=
threading
.
Lock
()
def
run
(
command
,
**
kwargs
):
def
_find_test_status
(
took
,
out
):
status
=
'[took %.1fs%s]'
skipped
=
''
run_count
=
0
skipped_count
=
0
if
out
:
m
=
re
.
search
(
r"Ran (\
d+)
tests in"
,
out
)
if
m
:
result
=
out
[
m
.
start
():
m
.
end
()]
status
=
status
.
replace
(
'took'
,
result
)
run_count
=
int
(
out
[
m
.
start
(
1
):
m
.
end
(
1
)])
m
=
re
.
search
(
r' \
(skipped=(
\d+)\
)$
', out)
if m:
skipped = _colorize('
skipped
', out[m.start():m.end()])
skipped_count = int(out[m.start(1):m.end(1)])
status = status % (took, skipped)
if took > 10:
status = _colorize('
slow
-
test
', status)
return status, run_count, skipped_count
def run(command, **kwargs): # pylint:disable=too-many-locals
buffer_output = kwargs.pop('
buffer_output
', BUFFER_OUTPUT)
quiet = kwargs.pop('
quiet
', QUIET)
verbose = not quiet
...
...
@@ -282,21 +309,27 @@ def run(command, **kwargs):
assert not err
with output_lock: # pylint:disable=not-context-manager
failed = bool(result)
if out:
out = out.strip()
out = out if isinstance(out, str) else out.decode('
utf
-
8
', '
ignore
')
if out and (failed or verbose or _should_show_warning_output(out)):
out
=
out
.
strip
().
decode
(
'utf-8'
,
'ignore'
)
if out:
out = '
' + out.replace('
\
n
', '
\
n
')
out = out.rstrip()
out += '
\
n
'
log('
|
%
s
\
n
%
s
', name, out)
status, run_count, skipped_count = _find_test_status(took, out)
if result:
log
(
'! %s [code %s]
[took %.1fs]'
,
name
,
result
,
took
,
color
=
'error'
)
log('
!
%
s
[
code
%
s
]
%
s
', name, result, status
, color='
error
')
elif not nested:
log
(
'- %s
[took %.1fs]'
,
name
,
took
)
log('
-
%
s
%
s
', name, status
)
if took >= MIN_RUNTIME:
runtimelog.append((-took, name))
return
RunResult
(
result
,
out
,
name
)
return RunResult(result, out, name, run_count, skipped_count)
class NoSetupPyFound(Exception):
"Raised by find_setup_py_above"
def find_setup_py_above(a_file):
"Return the directory containing setup.py somewhere above *a_file*"
...
...
@@ -305,34 +338,68 @@ def find_setup_py_above(a_file):
prev, root = root, os.path.dirname(root)
if root == prev:
# Let'
s
avoid
infinite
loops
at
root
raise
AssertionError
(
'could not find my setup.py'
)
raise
NoSetupPyFound
(
'could not find my setup.py above %r'
%
(
a_file
,)
)
return
root
def
search_for_setup_py
(
a_file
=
None
,
a_module_name
=
None
,
a_class
=
None
,
climb_cwd
=
True
):
if
a_file
is
not
None
:
try
:
return
find_setup_py_above
(
a_file
)
except
NoSetupPyFound
:
pass
class
TestServer
(
unittest
.
TestCase
):
args
=
[]
before_delay
=
3
after_delay
=
0.5
popen
=
None
server
=
None
# subclasses define this to be the path to the server.py
start_kwargs
=
None
if
a_class
is
not
None
:
try
:
return
find_setup_py_above
(
sys
.
modules
[
a_class
.
__module__
].
__file__
)
except
NoSetupPyFound
:
pass
if
a_module_name
is
not
None
:
try
:
return
find_setup_py_above
(
sys
.
modules
[
a_module_name
].
__file__
)
except
NoSetupPyFound
:
pass
if
climb_cwd
:
return
find_setup_py_above
(
"./dne"
)
raise
NoSetupPyFound
(
"After checking %r"
%
(
locals
(),))
class
ExampleMixin
(
object
):
"Something that uses the examples/ directory"
def
find_setup_py
(
self
):
"Return the directory containing setup.py"
return
find_setup_py_above
(
__file__
)
# XXX: We need to extend this if we want it to be useful
# for other packages; our __file__ won't work for them.
# We can look at the CWD, and we can look at the __file__ of the
# sys.modules[type(self).__module__].
return
search_for_setup_py
(
a_file
=
__file__
,
a_class
=
type
(
self
)
)
@
property
def
cwd
(
self
):
root
=
self
.
find_setup_py
()
try
:
root
=
self
.
find_setup_py
()
except
NoSetupPyFound
as
e
:
raise
unittest
.
SkipTest
(
"Unable to locate file/dir to run: %s"
%
(
e
,))
return
os
.
path
.
join
(
root
,
'examples'
)
class
TestServer
(
ExampleMixin
,
unittest
.
TestCase
):
args
=
[]
before_delay
=
3
after_delay
=
0.5
popen
=
None
server
=
None
# subclasses define this to be the path to the server.py
start_kwargs
=
None
def
start
(
self
):
kwargs
=
self
.
start_kwargs
or
{}
return
start
([
sys
.
executable
,
'-u'
,
self
.
server
]
+
self
.
args
,
cwd
=
self
.
cwd
,
**
kwargs
)
try
:
kwargs
=
self
.
start_kwargs
or
{}
return
start
([
sys
.
executable
,
'-u'
,
self
.
server
]
+
self
.
args
,
cwd
=
self
.
cwd
,
**
kwargs
)
except
NoSetupPyFound
as
e
:
raise
unittest
.
SkipTest
(
"Unable to locate file/dir to run: %s"
%
(
e
,))
def
running_server
(
self
):
from
contextlib
import
contextmanager
...
...
src/gevent/tests/test___monkey_patching.py
View file @
bb7cf8fb
...
...
@@ -7,25 +7,34 @@ import atexit
from
gevent.testing
import
util
TIMEOUT
=
120
# XXX: Generalize this so other packages can use it.
setup_py
=
util
.
find_setup_py_above
(
__file__
)
greentest
=
os
.
path
.
join
(
setup_py
,
'src'
,
'greentest'
)
TIMEOUT
=
120
directory
=
'%s.%s'
%
sys
.
version_info
[:
2
]
full_directory
=
'%s.%s.%s'
%
sys
.
version_info
[:
3
]
if
hasattr
(
sys
,
'pypy_version_info'
):
directory
+=
'pypy'
full_directory
+=
'pypy'
def
find_stdlib_tests
():
setup_py
=
util
.
search_for_setup_py
(
a_file
=
__file__
)
greentest
=
os
.
path
.
join
(
setup_py
,
'src'
,
'greentest'
)
directory
=
'%s.%s'
%
sys
.
version_info
[:
2
]
full_directory
=
'%s.%s.%s'
%
sys
.
version_info
[:
3
]
if
hasattr
(
sys
,
'pypy_version_info'
):
directory
+=
'pypy'
full_directory
+=
'pypy'
directory
=
os
.
path
.
join
(
greentest
,
directory
)
full_directory
=
os
.
path
.
join
(
greentest
,
full_directory
)
directory
=
os
.
path
.
join
(
greentest
,
directory
)
full_directory
=
os
.
path
.
join
(
greentest
,
full_directory
)
return
directory
,
full_directory
version
=
'%s.%s.%s'
%
sys
.
version_info
[:
3
]
if
sys
.
version_info
[
3
]
==
'alpha'
:
version
+=
'a%s'
%
sys
.
version_info
[
4
]
elif
sys
.
version_info
[
3
]
==
'beta'
:
version
+=
'b%s'
%
sys
.
version_info
[
4
]
def
get_python_version
():
version
=
'%s.%s.%s'
%
sys
.
version_info
[:
3
]
if
sys
.
version_info
[
3
]
==
'alpha'
:
version
+=
'a%s'
%
sys
.
version_info
[
4
]
elif
sys
.
version_info
[
3
]
==
'beta'
:
version
+=
'b%s'
%
sys
.
version_info
[
4
]
return
version
def
get_absolute_pythonpath
():
paths
=
[
os
.
path
.
abspath
(
p
)
for
p
in
os
.
environ
.
get
(
'PYTHONPATH'
,
''
).
split
(
os
.
pathsep
)]
...
...
@@ -33,18 +42,31 @@ def get_absolute_pythonpath():
def
TESTRUNNER
(
tests
=
None
):
if
not
os
.
path
.
exists
(
directory
):
util
.
log
(
'WARNING: No test directory found at %s'
,
directory
)
try
:
test_dir
,
version_test_dir
=
find_stdlib_tests
()
except
util
.
NoSetupPyFound
as
e
:
util
.
log
(
"WARNING: No setup.py and src/greentest found: %r"
,
e
,
color
=
"suboptimal-behaviour"
)
return
if
not
os
.
path
.
exists
(
test_dir
):
util
.
log
(
'WARNING: No test directory found at %s'
,
test_dir
,
color
=
"suboptimal-behaviour"
)
return
with
open
(
os
.
path
.
join
(
directory
,
'version'
))
as
f
:
with
open
(
os
.
path
.
join
(
test_dir
,
'version'
))
as
f
:
preferred_version
=
f
.
read
().
strip
()
if
preferred_version
!=
version
:
util
.
log
(
'WARNING: The tests in %s/ are from version %s and your Python is %s'
,
directory
,
preferred_version
,
version
)
version_tests
=
glob
.
glob
(
'%s/test_*.py'
%
full_directory
)
running_version
=
get_python_version
()
if
preferred_version
!=
running_version
:
util
.
log
(
'WARNING: The tests in %s/ are from version %s and your Python is %s'
,
test_dir
,
preferred_version
,
running_version
,
color
=
"suboptimal-behaviour"
)
version_tests
=
glob
.
glob
(
'%s/test_*.py'
%
version_test_dir
)
version_tests
=
sorted
(
version_tests
)
if
not
tests
:
tests
=
glob
.
glob
(
'%s/test_*.py'
%
directory
)
tests
=
glob
.
glob
(
'%s/test_*.py'
%
test_dir
)
tests
=
sorted
(
tests
)
PYTHONPATH
=
(
os
.
getcwd
()
+
os
.
pathsep
+
get_absolute_pythonpath
()).
rstrip
(
':'
)
...
...
@@ -53,7 +75,7 @@ def TESTRUNNER(tests=None):
version_tests
=
[
os
.
path
.
basename
(
x
)
for
x
in
version_tests
]
options
=
{
'cwd'
:
directory
,
'cwd'
:
test_dir
,
'timeout'
:
TIMEOUT
,
'setenv'
:
{
'PYTHONPATH'
:
PYTHONPATH
,
...
...
@@ -73,11 +95,11 @@ def TESTRUNNER(tests=None):
basic_args
=
[
sys
.
executable
,
'-u'
,
'-W'
,
'ignore'
,
'-m'
'gevent.testing.monkey_test'
]
for
filename
in
tests
:
if
filename
in
version_tests
:
util
.
log
(
"Overriding %s from %s with file from %s"
,
filename
,
directory
,
full_directory
)
util
.
log
(
"Overriding %s from %s with file from %s"
,
filename
,
test_dir
,
version_test_dir
)
continue
yield
basic_args
+
[
filename
],
options
.
copy
()
options
[
'cwd'
]
=
full_directory
options
[
'cwd'
]
=
version_test_dir
for
filename
in
version_tests
:
yield
basic_args
+
[
filename
],
options
.
copy
()
...
...
src/gevent/tests/test__doctests.py
View file @
bb7cf8fb
...
...
@@ -7,11 +7,7 @@ import re
import
sys
import
unittest
import
gevent
from
gevent
import
socket
from
gevent.testing
import
walk_modules
from
gevent.testing
import
sysinfo
from
gevent.testing
import
util
# Ignore tracebacks: ZeroDivisionError
...
...
@@ -39,19 +35,16 @@ class RENormalizingOutputChecker(doctest.OutputChecker):
return
doctest
.
OutputChecker
.
check_output
(
self
,
want
,
got
,
optionflags
)
FORBIDDEN_MODULES
=
set
()
if
sysinfo
.
WIN
:
FORBIDDEN_MODULES
|=
{
# Uses commands only found on posix
'gevent.subprocess'
,
}
class
Modules
(
object
):
def
__init__
(
self
,
allowed_modules
):
from
gevent.testing
import
walk_modules
self
.
allowed_modules
=
allowed_modules
self
.
modules
=
set
()
for
path
,
module
in
walk_modules
():
for
path
,
module
in
walk_modules
(
recursive
=
True
):
self
.
add_module
(
module
,
path
)
...
...
@@ -71,19 +64,36 @@ class Modules(object):
return
iter
(
self
.
modules
)
def
main
():
def
main
():
# pylint:disable=too-many-locals
cwd
=
os
.
getcwd
()
# Use pure_python to get the correct module source and docstrings
os
.
environ
[
'PURE_PYTHON'
]
=
'1'
import
gevent
from
gevent
import
socket
from
gevent.testing
import
util
from
gevent.testing
import
sysinfo
if
sysinfo
.
WIN
:
FORBIDDEN_MODULES
.
update
({
# Uses commands only found on posix
'gevent.subprocess'
,
})
try
:
allowed_modules
=
sys
.
argv
[
1
:]
sys
.
path
.
append
(
'.'
)
os
.
chdir
(
util
.
find_setup_py_above
(
__file__
))
globs
=
{
'myfunction'
:
myfunction
,
'gevent'
:
gevent
,
'socket'
:
socket
}
globs
=
{
'myfunction'
:
myfunction
,
'gevent'
:
gevent
,
'socket'
:
socket
,
}
modules
=
Modules
(
allowed_modules
)
modules
.
add_module
(
'setup'
,
'setup.py'
)
if
not
modules
:
sys
.
exit
(
'No modules found matching %s'
%
' '
.
join
(
allowed_modules
))
...
...
@@ -91,8 +101,9 @@ def main():
checker
=
RENormalizingOutputChecker
((
# Normalize subprocess.py: BSD ls is in the example, gnu ls outputs
# 'cannot access'
(
re
.
compile
(
'cannot access non_existent_file: No such file or directory'
),
'non_existent_file: No such file or directory'
),
(
re
.
compile
(
"ls: cannot access 'non_existent_file': No such file or directory"
),
"ls: non_existent_file: No such file or directory"
),
# Python 3 bytes add a "b".
(
re
.
compile
(
r'b(".*?")'
),
r"\1"
),
(
re
.
compile
(
r"b('.*?')"
),
r"\1"
),
...
...
@@ -106,11 +117,12 @@ def main():
if
re
.
search
(
br'^\
s*>>>
', contents, re.M):
s = doctest.DocTestSuite(m, extraglobs=globs, checker=checker)
test_count = len(s._tests)
print('
%
s
(
from
%
s
):
%
s
tests
' % (m, path, test_count)
)
util.log('
%
s
(
from
%
s
):
%
s
tests
', m, path, test_count
)
suite.addTest(s)
modules_count += 1
tests_count += test_count
print('
Total
:
%
s
tests
in
%
s
modules
' % (tests_count, modules_count))
util.log('
Total
:
%
s
tests
in
%
s
modules
', tests_count, modules_count)
# TODO: Pass this off to unittest.main()
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
...
...
src/gevent/tests/test__examples.py
View file @
bb7cf8fb
...
...
@@ -2,23 +2,34 @@ import sys
import
os
import
glob
import
time
import
unittest
import
gevent.testing
as
greentest
from
gevent.testing
import
util
this_dir
=
os
.
path
.
dirname
(
__file__
)
cwd
=
'../../examples/'
ignore
=
[
'wsgiserver.py'
,
'wsgiserver_ssl.py'
,
'webproxy.py'
,
'webpy.py'
,
'unixsocket_server.py'
,
'unixsocket_client.py'
,
'psycopg2_pool.py'
,
'geventsendfile.py'
,
]
ignore
+=
[
x
[
14
:]
for
x
in
glob
.
glob
(
'test__example_*.py'
)]
def
_find_files_to_ignore
():
old_dir
=
os
.
getcwd
()
try
:
os
.
chdir
(
this_dir
)
result
=
[
'wsgiserver.py'
,
'wsgiserver_ssl.py'
,
'webproxy.py'
,
'webpy.py'
,
'unixsocket_server.py'
,
'unixsocket_client.py'
,
'psycopg2_pool.py'
,
'geventsendfile.py'
,
]
result
+=
[
x
[
14
:]
for
x
in
glob
.
glob
(
'test__example_*.py'
)]
finally
:
os
.
chdir
(
old_dir
)
return
result
default_time_range
=
(
2
,
4
)
time_ranges
=
{
...
...
@@ -26,7 +37,7 @@ time_ranges = {
'processes.py'
:
(
0
,
4
)
}
class
_AbstractTestMixin
(
object
):
class
_AbstractTestMixin
(
util
.
ExampleMixin
):
time_range
=
(
2
,
4
)
filename
=
None
...
...
@@ -35,7 +46,7 @@ class _AbstractTestMixin(object):
min_time
,
max_time
=
self
.
time_range
if
util
.
run
([
sys
.
executable
,
'-u'
,
self
.
filename
],
timeout
=
max_time
,
cwd
=
cwd
,
cwd
=
self
.
cwd
,
quiet
=
True
,
buffer_output
=
True
,
nested
=
True
,
...
...
@@ -45,17 +56,32 @@ class _AbstractTestMixin(object):
took
=
time
.
time
()
-
start
self
.
assertGreaterEqual
(
took
,
min_time
)
for
filename
in
glob
.
glob
(
cwd
+
'/*.py'
):
bn
=
os
.
path
.
basename
(
filename
)
if
bn
in
ignore
:
continue
tc
=
type
(
'Test_'
+
bn
,
(
_AbstractTestMixin
,
greentest
.
TestCase
),
{
'filename'
:
bn
,
'time_range'
:
time_ranges
.
get
(
bn
,
_AbstractTestMixin
.
time_range
)
})
locals
()[
tc
.
__name__
]
=
tc
def
_build_test_classes
():
result
=
{}
try
:
example_dir
=
util
.
ExampleMixin
().
cwd
except
unittest
.
SkipTest
:
util
.
log
(
"WARNING: No examples dir found"
,
color
=
'suboptimal-behaviour'
)
return
result
ignore
=
_find_files_to_ignore
()
for
filename
in
glob
.
glob
(
example_dir
+
'/*.py'
):
bn
=
os
.
path
.
basename
(
filename
)
if
bn
in
ignore
:
continue
tc
=
type
(
'Test_'
+
bn
,
(
_AbstractTestMixin
,
greentest
.
TestCase
),
{
'filename'
:
bn
,
'time_range'
:
time_ranges
.
get
(
bn
,
_AbstractTestMixin
.
time_range
)
}
)
result
[
tc
.
__name__
]
=
tc
return
result
for
k
,
v
in
_build_test_classes
().
items
():
locals
()[
k
]
=
v
if
__name__
==
'__main__'
:
greentest
.
main
()
src/gevent/tests/test__threading_2.py
View file @
bb7cf8fb
...
...
@@ -45,7 +45,7 @@ import time
import
unittest
import
weakref
import
lock_tests
from
gevent.tests
import
lock_tests
# A trivial mutable counter.
...
...
src/greentest/2.7/test_threading.py
View file @
bb7cf8fb
...
...
@@ -19,7 +19,7 @@ try:
except
ImportError
:
_testcapi
=
None
import
lock_tests
# gevent: use local copy
from
gevent.tests
import
lock_tests
# gevent: use local copy
# A trivial mutable counter.
class
Counter
(
object
):
...
...
src/greentest/2.7pypy/test_threading.py
View file @
bb7cf8fb
...
...
@@ -24,7 +24,7 @@ except:
# some lib_pypy/_testcapimodule.o file is truncated
_testcapi
=
None
import
lock_tests
# gevent: use local copy
from
gevent.tests
import
lock_tests
# gevent: use local copy
# A trivial mutable counter.
class
Counter
(
object
):
...
...
src/greentest/3.7/test_threading.py
View file @
bb7cf8fb
...
...
@@ -17,7 +17,7 @@ import weakref
import
os
import
subprocess
import
lock_tests
# gevent: use our local copy
from
gevent.tests
import
lock_tests
# gevent: use our local copy
from
test
import
support
...
...
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