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
e5b881b7
Commit
e5b881b7
authored
Jan 17, 2018
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor greentest.py into a package.
parent
e012980a
Changes
44
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
1845 additions
and
1398 deletions
+1845
-1398
src/gevent/util.py
src/gevent/util.py
+46
-0
src/greentest/greentest.py
src/greentest/greentest.py
+0
-1033
src/greentest/greentest/__init__.py
src/greentest/greentest/__init__.py
+107
-0
src/greentest/greentest/errorhandler.py
src/greentest/greentest/errorhandler.py
+50
-0
src/greentest/greentest/exception.py
src/greentest/greentest/exception.py
+23
-0
src/greentest/greentest/flaky.py
src/greentest/greentest/flaky.py
+77
-0
src/greentest/greentest/hub.py
src/greentest/greentest/hub.py
+35
-0
src/greentest/greentest/leakcheck.py
src/greentest/greentest/leakcheck.py
+133
-0
src/greentest/greentest/modules.py
src/greentest/greentest/modules.py
+73
-0
src/greentest/greentest/openfiles.py
src/greentest/greentest/openfiles.py
+125
-0
src/greentest/greentest/params.py
src/greentest/greentest/params.py
+67
-0
src/greentest/greentest/six.py
src/greentest/greentest/six.py
+0
-0
src/greentest/greentest/skipping.py
src/greentest/greentest/skipping.py
+79
-0
src/greentest/greentest/sockets.py
src/greentest/greentest/sockets.py
+40
-0
src/greentest/greentest/switching.py
src/greentest/greentest/switching.py
+64
-0
src/greentest/greentest/sysinfo.py
src/greentest/greentest/sysinfo.py
+112
-0
src/greentest/greentest/testcase.py
src/greentest/greentest/testcase.py
+295
-0
src/greentest/greentest/testrunner.py
src/greentest/greentest/testrunner.py
+321
-0
src/greentest/greentest/timing.py
src/greentest/greentest/timing.py
+127
-0
src/greentest/greentest/util.py
src/greentest/greentest/util.py
+1
-1
src/greentest/test___example_servers.py
src/greentest/test___example_servers.py
+2
-2
src/greentest/test___monkey_patching.py
src/greentest/test___monkey_patching.py
+2
-1
src/greentest/test__all__.py
src/greentest/test__all__.py
+5
-3
src/greentest/test__event.py
src/greentest/test__event.py
+1
-1
src/greentest/test__example_echoserver.py
src/greentest/test__example_echoserver.py
+1
-1
src/greentest/test__example_portforwarder.py
src/greentest/test__example_portforwarder.py
+5
-6
src/greentest/test__example_udp_client.py
src/greentest/test__example_udp_client.py
+3
-3
src/greentest/test__example_udp_server.py
src/greentest/test__example_udp_server.py
+4
-3
src/greentest/test__examples.py
src/greentest/test__examples.py
+2
-1
src/greentest/test__exc_info.py
src/greentest/test__exc_info.py
+1
-1
src/greentest/test__execmodules.py
src/greentest/test__execmodules.py
+9
-3
src/greentest/test__nondefaultloop.py
src/greentest/test__nondefaultloop.py
+1
-1
src/greentest/test__order.py
src/greentest/test__order.py
+1
-1
src/greentest/test__os.py
src/greentest/test__os.py
+4
-4
src/greentest/test__pool.py
src/greentest/test__pool.py
+1
-1
src/greentest/test__select.py
src/greentest/test__select.py
+1
-1
src/greentest/test__sleep0.py
src/greentest/test__sleep0.py
+1
-1
src/greentest/test__socket.py
src/greentest/test__socket.py
+1
-1
src/greentest/test__socket_dns.py
src/greentest/test__socket_dns.py
+4
-3
src/greentest/test__subprocess_poll.py
src/greentest/test__subprocess_poll.py
+1
-1
src/greentest/test__threadpool.py
src/greentest/test__threadpool.py
+15
-3
src/greentest/test_hub_join_timeout.py
src/greentest/test_hub_join_timeout.py
+1
-1
src/greentest/test_threading_2.py
src/greentest/test_threading_2.py
+1
-1
src/greentest/testrunner.py
src/greentest/testrunner.py
+3
-320
No files found.
src/gevent/util.py
View file @
e5b881b7
...
...
@@ -58,3 +58,49 @@ class wrap_errors(object):
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
__func
,
name
)
def
dump_stacks
():
"""
Request information about the running threads of the current process.
This is a debugging utility. Its output has no guarantees other than being
intended for human consumption.
:return: A sequence of text lines detailing the stacks of running
threads and greenlets. (One greenlet will duplicate one thread,
the current thread and greenlet.)
.. versionadded:: 1.3a1
"""
dump
=
[]
# threads
import
threading
# Late import this stuff because it may get monkey-patched
import
traceback
import
sys
import
gc
from
greenlet
import
greenlet
threads
=
{
th
.
ident
:
th
.
name
for
th
in
threading
.
enumerate
()}
for
thread
,
frame
in
sys
.
_current_frames
().
items
():
dump
.
append
(
'Thread 0x%x (%s)
\
n
'
%
(
thread
,
threads
.
get
(
thread
)))
dump
.
append
(
''
.
join
(
traceback
.
format_stack
(
frame
)))
dump
.
append
(
'
\
n
'
)
# greenlets
# if greenlet is present, let's dump each greenlet stack
# Use the gc module to inspect all objects to find the greenlets
# since there isn't a global registry
for
ob
in
gc
.
get_objects
():
if
not
isinstance
(
ob
,
greenlet
):
continue
if
not
ob
:
continue
# not running anymore or not started
dump
.
append
(
'Greenlet %s
\
n
'
%
ob
)
dump
.
append
(
''
.
join
(
traceback
.
format_stack
(
ob
.
gr_frame
)))
dump
.
append
(
'
\
n
'
)
return
dump
src/greentest/greentest.py
deleted
100644 → 0
View file @
e012980a
This diff is collapsed.
Click to expand it.
src/greentest/greentest/__init__.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2008-2009 AG Projects
# Copyright 2018 gevent community
# Author: Denis Bilenko
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# package is named greentest, not test, so it won't be confused with test in stdlib
import
unittest
# pylint:disable=unused-import
from
greentest.sysinfo
import
VERBOSE
from
greentest.sysinfo
import
WIN
from
greentest.sysinfo
import
LINUX
from
greentest.sysinfo
import
LIBUV
from
greentest.sysinfo
import
CFFI_BACKEND
from
greentest.sysinfo
import
DEBUG
from
greentest.sysinfo
import
RUN_LEAKCHECKS
from
greentest.sysinfo
import
PY2
from
greentest.sysinfo
import
PY3
from
greentest.sysinfo
import
PY34
from
greentest.sysinfo
import
PY36
from
greentest.sysinfo
import
PY37
from
greentest.sysinfo
import
PYPY
from
greentest.sysinfo
import
PYPY3
from
greentest.sysinfo
import
PLATFORM_SPECIFIC_SUFFIXES
from
greentest.sysinfo
import
NON_APPLICABLE_SUFFIXES
from
greentest.sysinfo
import
SHARED_OBJECT_EXTENSION
from
greentest.sysinfo
import
RUNNING_ON_TRAVIS
from
greentest.sysinfo
import
RUNNING_ON_APPVEYOR
from
greentest.sysinfo
import
RUNNING_ON_CI
from
greentest.sysinfo
import
EXPECT_POOR_TIMER_RESOLUTION
from
greentest.sysinfo
import
CONN_ABORTED_ERRORS
from
greentest.skipping
import
skipOnWindows
from
greentest.skipping
import
skipOnAppVeyor
from
greentest.skipping
import
skipOnPyPy3OnCI
from
greentest.skipping
import
skipOnPyPy
from
greentest.skipping
import
skipOnPyPy3
from
greentest.skipping
import
skipIf
from
greentest.skipping
import
skipOnLibuv
from
greentest.skipping
import
skipOnLibuvOnCI
from
greentest.skipping
import
skipOnLibuvOnCIOnPyPy
from
greentest.exception
import
ExpectedException
from
greentest.leakcheck
import
ignores_leakcheck
from
greentest.params
import
LARGE_TIMEOUT
from
greentest.params
import
DEFAULT_LOCAL_HOST_ADDR
from
greentest.params
import
DEFAULT_LOCAL_HOST_ADDR6
from
greentest.params
import
DEFAULT_BIND_ADDR
from
greentest.params
import
DEFAULT_SOCKET_TIMEOUT
from
greentest.params
import
DEFAULT_XPC_SOCKET_TIMEOUT
main
=
unittest
.
main
from
greentest.hub
import
QuietHub
import
gevent.hub
gevent
.
hub
.
Hub
=
QuietHub
from
greentest.sockets
import
bind_and_listen
from
greentest.sockets
import
tcp_listener
from
greentest.openfiles
import
get_number_open_files
from
greentest.openfiles
import
get_open_files
from
greentest.testcase
import
TestCase
from
greentest.timing
import
AbstractGenericGetTestCase
as
GenericGetTestCase
from
greentest.timing
import
AbstractGenericWaitTestCase
as
GenericWaitTestCase
from
greentest.modules
import
walk_modules
BaseTestCase
=
unittest
.
TestCase
src/greentest/greentest/errorhandler.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
functools
import
wraps
def
wrap_error_fatal
(
method
):
import
gevent
SYSTEM_ERROR
=
gevent
.
get_hub
().
SYSTEM_ERROR
@
wraps
(
method
)
def
wrapper
(
self
,
*
args
,
**
kwargs
):
# XXX should also be able to do gevent.SYSTEM_ERROR = object
# which is a global default to all hubs
gevent
.
get_hub
().
SYSTEM_ERROR
=
object
try
:
return
method
(
self
,
*
args
,
**
kwargs
)
finally
:
gevent
.
get_hub
().
SYSTEM_ERROR
=
SYSTEM_ERROR
return
wrapper
def
wrap_restore_handle_error
(
method
):
import
gevent
old
=
gevent
.
get_hub
().
handle_error
@
wraps
(
method
)
def
wrapper
(
self
,
*
args
,
**
kwargs
):
try
:
return
method
(
self
,
*
args
,
**
kwargs
)
finally
:
gevent
.
get_hub
().
handle_error
=
old
if
self
.
peek_error
()[
0
]
is
not
None
:
gevent
.
getcurrent
().
throw
(
*
self
.
peek_error
()[
1
:])
return
wrapper
src/greentest/greentest/exception.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
class
ExpectedException
(
Exception
):
"""An exception whose traceback should be ignored by the hub"""
src/greentest/greentest/flaky.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
import
sys
import
unittest
from
gevent.util
import
dump_stacks
from
greentest
import
sysinfo
from
greentest
import
six
# The next exceptions allow us to raise them in a highly
# greppable way so that we can debug them later.
class
FlakyTest
(
unittest
.
SkipTest
):
"""
A unittest exception that causes the test to be skipped when raised.
Use this carefully, it is a code smell and indicates an undebugged problem.
"""
class
FlakyTestRaceCondition
(
FlakyTest
):
"""
Use this when the flaky test is definitely caused by a race condition.
"""
class
FlakyTestTimeout
(
FlakyTest
):
"""
Use this when the flaky test is definitely caused by an
unexpected timeout.
"""
class
FlakyTestCrashes
(
FlakyTest
):
"""
Use this when the test sometimes crashes.
"""
def
reraiseFlakyTestRaceCondition
():
six
.
reraise
(
*
sys
.
exc_info
())
reraiseFlakyTestTimeout
=
reraiseFlakyTestRaceCondition
reraiseFlakyTestRaceConditionLibuv
=
reraiseFlakyTestRaceCondition
reraiseFlakyTestTimeoutLibuv
=
reraiseFlakyTestRaceCondition
if
sysinfo
.
RUNNING_ON_CI
:
# pylint: disable=function-redefined
def
reraiseFlakyTestRaceCondition
():
six
.
reraise
(
FlakyTestRaceCondition
,
FlakyTestRaceCondition
(
'
\
n
'
.
join
(
dump_stacks
())),
sys
.
exc_info
()[
2
])
def
reraiseFlakyTestTimeout
():
six
.
reraise
(
FlakyTestTimeout
,
FlakyTestTimeout
(),
sys
.
exc_info
()[
2
])
if
sysinfo
.
LIBUV
:
reraiseFlakyTestRaceConditionLibuv
=
reraiseFlakyTestRaceCondition
reraiseFlakyTestTimeoutLibuv
=
reraiseFlakyTestTimeout
src/greentest/greentest/hub.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
from
gevent.hub
import
Hub
from
greentest.exception
import
ExpectedException
class
QuietHub
(
Hub
):
EXPECTED_TEST_ERROR
=
(
ExpectedException
,)
def
handle_error
(
self
,
context
,
type
,
value
,
tb
):
if
issubclass
(
type
,
self
.
EXPECTED_TEST_ERROR
):
# Don't print these to cut down on the noise in the test logs
return
return
Hub
.
handle_error
(
self
,
context
,
type
,
value
,
tb
)
src/greentest/greentest/leakcheck.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import
gc
import
collections
import
types
import
gevent.core
def
ignores_leakcheck
(
func
):
func
.
ignore_leakcheck
=
True
return
func
def
wrap_refcount
(
method
):
if
getattr
(
method
,
'ignore_leakcheck'
,
False
):
return
method
# Some builtin things that we ignore
IGNORED_TYPES
=
(
tuple
,
dict
,
types
.
FrameType
,
types
.
TracebackType
)
try
:
callback_kind
=
gevent
.
core
.
callback
except
AttributeError
:
# Must be using FFI.
from
gevent._ffi.callback
import
callback
as
callback_kind
def
type_hist
():
d
=
collections
.
defaultdict
(
int
)
for
x
in
gc
.
get_objects
():
k
=
type
(
x
)
if
k
in
IGNORED_TYPES
:
continue
if
k
==
callback_kind
and
x
.
callback
is
None
and
x
.
args
is
None
:
# these represent callbacks that have been stopped, but
# the event loop hasn't cycled around to run them. The only
# known cause of this is killing greenlets before they get a chance
# to run for the first time.
continue
d
[
k
]
+=
1
return
d
def
report_diff
(
a
,
b
):
diff_lines
=
[]
for
k
,
v
in
sorted
(
a
.
items
(),
key
=
lambda
i
:
i
[
0
].
__name__
):
if
b
[
k
]
!=
v
:
diff_lines
.
append
(
"%s: %s != %s"
%
(
k
,
v
,
b
[
k
]))
if
not
diff_lines
:
return
None
diff
=
'
\
n
'
.
join
(
diff_lines
)
return
diff
@
wraps
(
method
)
def
wrapper
(
self
,
*
args
,
**
kwargs
):
gc
.
collect
()
gc
.
collect
()
gc
.
collect
()
deltas
=
[]
d
=
None
gc
.
disable
()
try
:
while
True
:
# Grab current snapshot
hist_before
=
type_hist
()
d
=
sum
(
hist_before
.
values
())
self
.
setUp
()
try
:
method
(
self
,
*
args
,
**
kwargs
)
finally
:
self
.
tearDown
()
# Grab post snapshot
if
'urlparse'
in
sys
.
modules
:
sys
.
modules
[
'urlparse'
].
clear_cache
()
if
'urllib.parse'
in
sys
.
modules
:
sys
.
modules
[
'urllib.parse'
].
clear_cache
()
hist_after
=
type_hist
()
d
=
sum
(
hist_after
.
values
())
-
d
deltas
.
append
(
d
)
# Reset and check for cycles
gc
.
collect
()
if
gc
.
garbage
:
raise
AssertionError
(
"Generated uncollectable garbage %r"
%
(
gc
.
garbage
,))
# the following configurations are classified as "no leak"
# [0, 0]
# [x, 0, 0]
# [... a, b, c, d] where a+b+c+d = 0
#
# the following configurations are classified as "leak"
# [... z, z, z] where z > 0
if
deltas
[
-
2
:]
==
[
0
,
0
]
and
len
(
deltas
)
in
(
2
,
3
):
break
elif
deltas
[
-
3
:]
==
[
0
,
0
,
0
]:
break
elif
len
(
deltas
)
>=
4
and
sum
(
deltas
[
-
4
:])
==
0
:
break
elif
len
(
deltas
)
>=
3
and
deltas
[
-
1
]
>
0
and
deltas
[
-
1
]
==
deltas
[
-
2
]
and
deltas
[
-
2
]
==
deltas
[
-
3
]:
diff
=
report_diff
(
hist_before
,
hist_after
)
raise
AssertionError
(
'refcount increased by %r
\
n
%s'
%
(
deltas
,
diff
))
# OK, we don't know for sure yet. Let's search for more
if
sum
(
deltas
[
-
3
:])
<=
0
or
sum
(
deltas
[
-
4
:])
<=
0
or
deltas
[
-
4
:].
count
(
0
)
>=
2
:
# this is suspicious, so give a few more runs
limit
=
11
else
:
limit
=
7
if
len
(
deltas
)
>=
limit
:
raise
AssertionError
(
'refcount increased by %r
\
n
%s'
%
(
deltas
,
report_diff
(
hist_before
,
hist_after
)))
finally
:
gc
.
enable
()
self
.
skipTearDown
=
True
return
wrapper
src/greentest/greentest/modules.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
import
os.path
import
gevent
from
greentest
import
sysinfo
from
greentest
import
six
OPTIONAL_MODULES
=
[
'resolver_ares'
]
def
walk_modules
(
basedir
=
None
,
modpath
=
None
,
include_so
=
False
,
recursive
=
False
):
# pylint:disable=too-many-branches
if
sysinfo
.
PYPY
:
include_so
=
False
if
basedir
is
None
:
basedir
=
os
.
path
.
dirname
(
gevent
.
__file__
)
if
modpath
is
None
:
modpath
=
'gevent.'
else
:
if
modpath
is
None
:
modpath
=
''
for
fn
in
sorted
(
os
.
listdir
(
basedir
)):
path
=
os
.
path
.
join
(
basedir
,
fn
)
if
os
.
path
.
isdir
(
path
):
if
not
recursive
:
continue
pkg_init
=
os
.
path
.
join
(
path
,
'__init__.py'
)
if
os
.
path
.
exists
(
pkg_init
):
yield
pkg_init
,
modpath
+
fn
for
p
,
m
in
walk_modules
(
path
,
modpath
+
fn
+
"."
):
yield
p
,
m
continue
if
fn
.
endswith
(
'.py'
):
x
=
fn
[:
-
3
]
if
x
.
endswith
(
'_d'
):
x
=
x
[:
-
2
]
if
x
in
[
'__init__'
,
'core'
,
'ares'
,
'_util'
,
'_semaphore'
,
'corecffi'
,
'_corecffi'
,
'_corecffi_build'
]:
continue
if
x
in
OPTIONAL_MODULES
:
try
:
six
.
exec_
(
"import %s"
%
x
,
{})
except
ImportError
:
continue
yield
path
,
modpath
+
x
elif
include_so
and
fn
.
endswith
(
sysinfo
.
SHARED_OBJECT_EXTENSION
):
if
'.pypy-'
in
fn
:
continue
if
fn
.
endswith
(
'_d.so'
):
yield
path
,
modpath
+
fn
[:
-
5
]
else
:
yield
path
,
modpath
+
fn
[:
-
3
]
src/greentest/greentest/openfiles.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
import
os
import
unittest
import
re
from
greentest
import
sysinfo
# Linux/OS X/BSD platforms can implement this by calling out to lsof
if
sysinfo
.
WIN
:
def
_run_lsof
():
raise
unittest
.
SkipTest
(
"lsof not expected on Windows"
)
else
:
def
_run_lsof
():
import
tempfile
pid
=
os
.
getpid
()
fd
,
tmpname
=
tempfile
.
mkstemp
(
'get_open_files'
)
os
.
close
(
fd
)
lsof_command
=
'lsof -p %s > %s'
%
(
pid
,
tmpname
)
if
os
.
system
(
lsof_command
):
# XXX: This prints to the console an annoying message: 'lsof is not recognized'
raise
unittest
.
SkipTest
(
"lsof failed"
)
with
open
(
tmpname
)
as
fobj
:
data
=
fobj
.
read
().
strip
()
os
.
remove
(
tmpname
)
return
data
def
default_get_open_files
(
pipes
=
False
):
data
=
_run_lsof
()
results
=
{}
for
line
in
data
.
split
(
'
\
n
'
):
line
=
line
.
strip
()
if
not
line
or
line
.
startswith
(
"COMMAND"
):
# Skip header and blank lines
continue
split
=
re
.
split
(
r'\
s+
', line)
_command, _pid, _user, fd = split[:4]
# Pipes (on OS X, at least) get an fd like "3" while normal files get an fd like "1u"
if fd[:-1].isdigit() or fd.isdigit():
if not pipes and fd[-1].isdigit():
continue
fd = int(fd[:-1]) if not fd[-1].isdigit() else int(fd)
if fd in results:
params = (fd, line, split, results.get(fd), data)
raise AssertionError('
error
when
parsing
lsof
output
:
duplicate
fd
=%
r
\
nline
=%
r
\
nsplit
=%
r
\
nprevious
=%
r
\
ndata
:
\
n
%
s
' % params)
results[fd] = line
if not results:
raise AssertionError('
failed
to
parse
lsof
:
\
n
%
s
' % (data, ))
results['
data
'] = data
return results
def default_get_number_open_files():
if os.path.exists('
/
proc
/
'):
# Linux only
fd_directory = '
/
proc
/%
d
/
fd
' % os.getpid()
return len(os.listdir(fd_directory))
else:
try:
return len(get_open_files(pipes=True)) - 1
except (OSError, AssertionError, unittest.SkipTest):
return 0
lsof_get_open_files = default_get_open_files
try:
# psutil import subprocess which on Python 3 imports selectors.
# This can expose issues with monkey-patching.
import psutil
except ImportError:
get_open_files = default_get_open_files
get_number_open_files = default_get_number_open_files
else:
# If psutil is available (it is cross-platform) use that.
# It is *much* faster than shelling out to lsof each time
# (Running 14 tests takes 3.964s with lsof and 0.046 with psutil)
# However, it still doesn'
t
completely
solve
the
issue
on
Windows
:
fds
are
reported
# as -1 there, so we can't fully check those.
def
get_open_files
():
"""
Return a list of popenfile and pconn objects.
Note that other than `fd`, they have different attributes.
.. important:: If you want to find open sockets, on Windows
and linux, it is important that the socket at least be listening
(socket.listen(1)). Unlike the lsof implementation, this will only
return sockets in a state like that.
"""
results
=
dict
()
process
=
psutil
.
Process
()
results
[
'data'
]
=
process
.
open_files
()
+
process
.
connections
(
'all'
)
for
x
in
results
[
'data'
]:
results
[
x
.
fd
]
=
x
results
[
'data'
]
+=
[
'From psutil'
,
process
]
return
results
def
get_number_open_files
():
process
=
psutil
.
Process
()
try
:
return
process
.
num_fds
()
except
AttributeError
:
# num_fds is unix only. Is num_handles close enough on Windows?
return
0
src/greentest/greentest/params.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
greentest.sysinfo
import
PY3
from
greentest.sysinfo
import
PYPY
from
greentest.sysinfo
import
WIN
from
greentest.sysinfo
import
LIBUV
from
greentest.sysinfo
import
RUNNING_ON_TRAVIS
from
greentest.sysinfo
import
EXPECT_POOR_TIMER_RESOLUTION
# Travis is slow and overloaded; Appveyor used to be faster, but
# as of Dec 2015 it's almost always slower and/or has much worse timer
# resolution
CI_TIMEOUT
=
10
if
(
PY3
and
PYPY
)
or
(
PYPY
and
WIN
and
LIBUV
):
# pypy3 is very slow right now,
# as is PyPy2 on windows (which only has libuv)
CI_TIMEOUT
=
15
if
PYPY
and
LIBUV
:
# slow and flaky timeouts
LOCAL_TIMEOUT
=
CI_TIMEOUT
else
:
LOCAL_TIMEOUT
=
1
LARGE_TIMEOUT
=
max
(
LOCAL_TIMEOUT
,
CI_TIMEOUT
)
DEFAULT_LOCAL_HOST_ADDR
=
'localhost'
DEFAULT_LOCAL_HOST_ADDR6
=
DEFAULT_LOCAL_HOST_ADDR
DEFAULT_BIND_ADDR
=
''
if
RUNNING_ON_TRAVIS
:
# As of November 2017 (probably Sept or Oct), after a
# Travis upgrade, using "localhost" no longer works,
# producing 'OSError: [Errno 99] Cannot assign
# requested address'. This is apparently something to do with
# docker containers. Sigh.
DEFAULT_LOCAL_HOST_ADDR
=
'127.0.0.1'
DEFAULT_LOCAL_HOST_ADDR6
=
'::1'
# Likewise, binding to '' appears to work, but it cannot be
# connected to with the same error.
DEFAULT_BIND_ADDR
=
'127.0.0.1'
# For in-process sockets
DEFAULT_SOCKET_TIMEOUT
=
0.1
if
not
EXPECT_POOR_TIMER_RESOLUTION
else
2.0
# For cross-process sockets
DEFAULT_XPC_SOCKET_TIMEOUT
=
2.0
if
not
EXPECT_POOR_TIMER_RESOLUTION
else
4.0
src/greentest/
_
six.py
→
src/greentest/
greentest/
six.py
View file @
e5b881b7
File moved
src/greentest/greentest/skipping.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
import
unittest
from
greentest
import
sysinfo
def
_do_not_skip
(
reason
):
assert
reason
def
dec
(
f
):
return
f
return
dec
if
sysinfo
.
WIN
:
skipOnWindows
=
unittest
.
skip
else
:
skipOnWindows
=
_do_not_skip
if
sysinfo
.
RUNNING_ON_APPVEYOR
:
# See comments scattered around about timeouts and the timer
# resolution available on appveyor (lots of jitter). this
# seems worse with the 62-bit builds.
# Note that we skip/adjust these tests only on AppVeyor, not
# win32---we don't think there's gevent related problems but
# environment related problems. These can be tested and debugged
# separately on windows in a more stable environment.
skipOnAppVeyor
=
unittest
.
skip
else
:
skipOnAppVeyor
=
_do_not_skip
if
sysinfo
.
PYPY3
and
sysinfo
.
RUNNING_ON_CI
:
# Same as above, for PyPy3.3-5.5-alpha and 3.5-5.7.1-beta and 3.5-5.8
skipOnPyPy3OnCI
=
unittest
.
skip
else
:
skipOnPyPy3OnCI
=
_do_not_skip
if
sysinfo
.
PYPY
:
skipOnPyPy
=
unittest
.
skip
else
:
skipOnPyPy
=
_do_not_skip
if
sysinfo
.
PYPY3
:
skipOnPyPy3
=
unittest
.
skip
else
:
skipOnPyPy3
=
_do_not_skip
skipIf
=
unittest
.
skipIf
skipOnLibuv
=
_do_not_skip
skipOnLibuvOnCI
=
_do_not_skip
skipOnLibuvOnCIOnPyPy
=
_do_not_skip
if
sysinfo
.
LIBUV
:
skipOnLibuv
=
unittest
.
skip
if
sysinfo
.
RUNNING_ON_CI
:
skipOnLibuvOnCI
=
unittest
.
skip
if
sysinfo
.
PYPY
:
skipOnLibuvOnCIOnPyPy
=
unittest
.
skip
src/greentest/greentest/sockets.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
def
bind_and_listen
(
sock
,
address
=
(
''
,
0
),
backlog
=
50
,
reuse_addr
=
True
):
from
socket
import
SOL_SOCKET
,
SO_REUSEADDR
,
error
if
reuse_addr
:
try
:
sock
.
setsockopt
(
SOL_SOCKET
,
SO_REUSEADDR
,
sock
.
getsockopt
(
SOL_SOCKET
,
SO_REUSEADDR
)
|
1
)
except
error
:
pass
sock
.
bind
(
address
)
sock
.
listen
(
backlog
)
def
tcp_listener
(
address
,
backlog
=
50
,
reuse_addr
=
True
):
"""A shortcut to create a TCP socket, bind it and put it into listening state."""
from
gevent
import
socket
sock
=
socket
.
socket
()
bind_and_listen
(
sock
,
address
,
backlog
=
backlog
,
reuse_addr
=
reuse_addr
)
return
sock
src/greentest/greentest/switching.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from
__future__
import
absolute_import
,
print_function
,
division
from
functools
import
wraps
from
gevent.hub
import
_get_hub
from
greentest.hub
import
QuietHub
from
patched_tests_setup
import
get_switch_expected
def
wrap_switch_count_check
(
method
):
@
wraps
(
method
)
def
wrapper
(
self
,
*
args
,
**
kwargs
):
initial_switch_count
=
getattr
(
_get_hub
(),
'switch_count'
,
None
)
self
.
switch_expected
=
getattr
(
self
,
'switch_expected'
,
True
)
if
initial_switch_count
is
not
None
:
fullname
=
getattr
(
self
,
'fullname'
,
None
)
if
self
.
switch_expected
==
'default'
and
fullname
:
self
.
switch_expected
=
get_switch_expected
(
fullname
)
result
=
method
(
self
,
*
args
,
**
kwargs
)
if
initial_switch_count
is
not
None
and
self
.
switch_expected
is
not
None
:
switch_count
=
_get_hub
().
switch_count
-
initial_switch_count
if
self
.
switch_expected
is
True
:
assert
switch_count
>=
0
if
not
switch_count
:
raise
AssertionError
(
'%s did not switch'
%
fullname
)
elif
self
.
switch_expected
is
False
:
if
switch_count
:
raise
AssertionError
(
'%s switched but not expected to'
%
fullname
)
else
:
raise
AssertionError
(
'Invalid value for switch_expected: %r'
%
(
self
.
switch_expected
,
))
return
result
return
wrapper
class
CountingHub
(
QuietHub
):
switch_count
=
0
def
switch
(
self
,
*
args
):
# pylint:disable=arguments-differ
self
.
switch_count
+=
1
return
QuietHub
.
switch
(
self
,
*
args
)
src/greentest/greentest/sysinfo.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import
os
import
sys
import
gevent.core
PYPY
=
hasattr
(
sys
,
'pypy_version_info'
)
VERBOSE
=
sys
.
argv
.
count
(
'-v'
)
>
1
WIN
=
sys
.
platform
.
startswith
(
"win"
)
LINUX
=
sys
.
platform
.
startswith
(
'linux'
)
# XXX: Formalize this better
LIBUV
=
os
.
getenv
(
'GEVENT_CORE_CFFI_ONLY'
)
==
'libuv'
or
(
PYPY
and
WIN
)
or
hasattr
(
gevent
.
core
,
'libuv'
)
CFFI_BACKEND
=
bool
(
os
.
getenv
(
'GEVENT_CORE_CFFI_ONLY'
))
or
PYPY
if
'--debug-greentest'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'--debug-greentest'
)
DEBUG
=
True
else
:
DEBUG
=
False
RUN_LEAKCHECKS
=
os
.
getenv
(
'GEVENTTEST_LEAKCHECK'
)
# Generally, ignore the portions that are only implemented
# on particular platforms; they generally contain partial
# implementations completed in different modules.
PLATFORM_SPECIFIC_SUFFIXES
=
[
'2'
,
'279'
,
'3'
]
if
WIN
:
PLATFORM_SPECIFIC_SUFFIXES
.
append
(
'posix'
)
PY2
=
None
PY3
=
None
PY34
=
None
PY36
=
None
PY37
=
None
NON_APPLICABLE_SUFFIXES
=
[]
if
sys
.
version_info
[
0
]
==
3
:
# Python 3
NON_APPLICABLE_SUFFIXES
.
extend
((
'2'
,
'279'
))
PY2
=
False
PY3
=
True
if
sys
.
version_info
[
1
]
>=
4
:
PY34
=
True
if
sys
.
version_info
[
1
]
>=
6
:
PY36
=
True
if
sys
.
version_info
[
1
]
>=
7
:
PY37
=
True
elif
sys
.
version_info
[
0
]
==
2
:
# Any python 2
PY3
=
False
PY2
=
True
NON_APPLICABLE_SUFFIXES
.
append
(
'3'
)
if
(
sys
.
version_info
[
1
]
<
7
or
(
sys
.
version_info
[
1
]
==
7
and
sys
.
version_info
[
2
]
<
9
)):
# Python 2, < 2.7.9
NON_APPLICABLE_SUFFIXES
.
append
(
'279'
)
PYPY3
=
PYPY
and
PY3
if
WIN
:
NON_APPLICABLE_SUFFIXES
.
append
(
"posix"
)
# This is intimately tied to FileObjectPosix
NON_APPLICABLE_SUFFIXES
.
append
(
"fileobject2"
)
SHARED_OBJECT_EXTENSION
=
".pyd"
else
:
SHARED_OBJECT_EXTENSION
=
".so"
RUNNING_ON_TRAVIS
=
os
.
environ
.
get
(
'TRAVIS'
)
RUNNING_ON_APPVEYOR
=
os
.
environ
.
get
(
'APPVEYOR'
)
RUNNING_ON_CI
=
RUNNING_ON_TRAVIS
or
RUNNING_ON_APPVEYOR
if
RUNNING_ON_APPVEYOR
:
# We can't exec corecext on appveyor if we haven't run setup.py in
# 'develop' mode (i.e., we install)
NON_APPLICABLE_SUFFIXES
.
append
(
'corecext'
)
EXPECT_POOR_TIMER_RESOLUTION
=
PYPY3
or
RUNNING_ON_APPVEYOR
or
(
LIBUV
and
PYPY
)
CONN_ABORTED_ERRORS
=
[]
try
:
from
errno
import
WSAECONNABORTED
CONN_ABORTED_ERRORS
.
append
(
WSAECONNABORTED
)
except
ImportError
:
pass
from
errno
import
ECONNRESET
CONN_ABORTED_ERRORS
.
append
(
ECONNRESET
)
CONN_ABORTED_ERRORS
=
frozenset
(
CONN_ABORTED_ERRORS
)
src/greentest/greentest/testcase.py
0 → 100644
View file @
e5b881b7
This diff is collapsed.
Click to expand it.
src/greentest/greentest/testrunner.py
0 → 100644
View file @
e5b881b7
This diff is collapsed.
Click to expand it.
src/greentest/greentest/timing.py
0 → 100644
View file @
e5b881b7
# Copyright (c) 2018 gevent community
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import
time
import
gevent
from
greentest
import
sysinfo
from
greentest
import
leakcheck
from
greentest.testcase
import
TestCase
class
_DelayWaitMixin
(
object
):
_default_wait_timeout
=
0.01
_default_delay_min_adj
=
0.001
if
not
sysinfo
.
RUNNING_ON_APPVEYOR
:
_default_delay_max_adj
=
0.11
else
:
# Timing resolution is extremely poor on Appveyor
# and subject to jitter.
_default_delay_max_adj
=
1.5
def
wait
(
self
,
timeout
):
raise
NotImplementedError
(
'override me in subclass'
)
def
_check_delay_bounds
(
self
,
timeout
,
delay
,
delay_min_adj
=
None
,
delay_max_adj
=
None
):
delay_min_adj
=
self
.
_default_delay_min_adj
if
not
delay_min_adj
else
delay_min_adj
delay_max_adj
=
self
.
_default_delay_max_adj
if
not
delay_max_adj
else
delay_max_adj
self
.
assertGreaterEqual
(
delay
,
timeout
-
delay_min_adj
)
self
.
assertLess
(
delay
,
timeout
+
delay_max_adj
)
def
_wait_and_check
(
self
,
timeout
=
None
):
if
timeout
is
None
:
timeout
=
self
.
_default_wait_timeout
# gevent.timer instances have a 'seconds' attribute,
# otherwise it's the raw number
seconds
=
getattr
(
timeout
,
'seconds'
,
timeout
)
start
=
time
.
time
()
try
:
result
=
self
.
wait
(
timeout
)
finally
:
self
.
_check_delay_bounds
(
seconds
,
time
.
time
()
-
start
,
self
.
_default_delay_min_adj
,
self
.
_default_delay_max_adj
)
return
result
def
test_outer_timeout_is_not_lost
(
self
):
timeout
=
gevent
.
Timeout
.
start_new
(
0.001
,
ref
=
False
)
try
:
with
self
.
assertRaises
(
gevent
.
Timeout
)
as
exc
:
self
.
wait
(
timeout
=
1
)
self
.
assertIs
(
exc
.
exception
,
timeout
)
finally
:
timeout
.
cancel
()
class
AbstractGenericWaitTestCase
(
_DelayWaitMixin
,
TestCase
):
# pylint:disable=abstract-method
_default_wait_timeout
=
0.2
_default_delay_min_adj
=
0.1
if
not
sysinfo
.
RUNNING_ON_APPVEYOR
:
_default_delay_max_adj
=
0.11
else
:
# Timing resolution is very poor on Appveyor
# and subject to jitter
_default_delay_max_adj
=
1.5
@
leakcheck
.
ignores_leakcheck
# waiting checks can be very sensitive to timing
def
test_returns_none_after_timeout
(
self
):
result
=
self
.
_wait_and_check
()
# join and wait simply return after timeout expires
self
.
assertIsNone
(
result
)
class
AbstractGenericGetTestCase
(
_DelayWaitMixin
,
TestCase
):
# pylint:disable=abstract-method
Timeout
=
gevent
.
Timeout
def
cleanup
(
self
):
pass
def
test_raises_timeout_number
(
self
):
with
self
.
assertRaises
(
self
.
Timeout
):
self
.
_wait_and_check
(
timeout
=
0.01
)
# get raises Timeout after timeout expired
self
.
cleanup
()
def
test_raises_timeout_Timeout
(
self
):
timeout
=
gevent
.
Timeout
(
self
.
_default_wait_timeout
)
try
:
self
.
_wait_and_check
(
timeout
=
timeout
)
except
gevent
.
Timeout
as
ex
:
self
.
assertIs
(
ex
,
timeout
)
self
.
cleanup
()
def
test_raises_timeout_Timeout_exc_customized
(
self
):
error
=
RuntimeError
(
'expected error'
)
timeout
=
gevent
.
Timeout
(
self
.
_default_wait_timeout
,
exception
=
error
)
with
self
.
assertRaises
(
RuntimeError
)
as
exc
:
self
.
_wait_and_check
(
timeout
=
timeout
)
self
.
assertIs
(
exc
.
exception
,
error
)
self
.
cleanup
()
src/greentest/util.py
→
src/greentest/
greentest/
util.py
View file @
e5b881b7
import
sys
import
os
import
_six
as
six
from
greentest
import
six
import
traceback
import
unittest
import
threading
...
...
src/greentest/test___example_servers.py
View file @
e5b881b7
...
...
@@ -5,13 +5,13 @@ try:
except
ImportError
:
import
urllib2
from
unittest
import
SkipTest
import
util
import
socket
import
ssl
from
greentest
import
DEFAULT_XPC_SOCKET_TIMEOUT
from
greentest
import
main
from
greentest
import
util
class
Test_wsgiserver
(
util
.
TestServer
):
server
=
'wsgiserver.py'
...
...
src/greentest/test___monkey_patching.py
View file @
e5b881b7
import
sys
import
os
import
glob
import
util
import
atexit
# subprocess: include in subprocess tests
from
greentest
import
util
TIMEOUT
=
120
directory
=
'%s.%s'
%
sys
.
version_info
[:
2
]
...
...
src/greentest/test__all__.py
View file @
e5b881b7
"""Check __all__, __implements__, __extensions__, __imports__ of the modules"""
from
__future__
import
print_function
import
_six
as
six
from
greentest
import
six
import
sys
import
unittest
import
types
from
greentest
import
walk_modules
from
greentest
import
PLATFORM_SPECIFIC_SUFFIXES
from
greentest
.modules
import
walk_modules
from
greentest
.sysinfo
import
PLATFORM_SPECIFIC_SUFFIXES
MAPPING
=
{
...
...
@@ -216,6 +216,8 @@ are missing from %r:
self
.
check_extensions_actually_extend
()
self
.
check_completeness
()
path
=
modname
=
orig_modname
=
None
for
path
,
modname
in
walk_modules
(
include_so
=
True
):
orig_modname
=
modname
modname
=
modname
.
replace
(
'gevent.'
,
''
).
split
(
'.'
)[
0
]
...
...
src/greentest/test__event.py
View file @
e5b881b7
import
greentest
import
gevent
from
gevent.event
import
Event
,
AsyncResult
from
_
six
import
xrange
from
greentest.
six
import
xrange
DELAY
=
0.01
...
...
src/greentest/test__example_echoserver.py
View file @
e5b881b7
...
...
@@ -2,7 +2,7 @@ from gevent.socket import create_connection, timeout
import
greentest
import
gevent
import
util
from
greentest
import
util
class
Test
(
util
.
TestServer
):
server
=
'echoserver.py'
...
...
src/greentest/test__example_portforwarder.py
View file @
e5b881b7
...
...
@@ -8,7 +8,7 @@ from time import sleep
import
gevent
from
gevent.server
import
StreamServer
import
util
from
greentest
import
util
class
Test
(
util
.
TestServer
):
...
...
@@ -23,16 +23,16 @@ class Test(util.TestServer):
def
after
(
self
):
if
sys
.
platform
==
'win32'
:
assert
self
.
popen
.
poll
()
is
not
None
self
.
assertIsNotNone
(
self
.
popen
.
poll
())
else
:
self
.
assertEqual
(
self
.
popen
.
poll
(),
0
)
def
_run_all_tests
(
self
):
log
=
[]
def
handle
(
sock
et
,
address
):
def
handle
(
sock
,
_
address
):
while
True
:
data
=
sock
et
.
recv
(
1024
)
data
=
sock
.
recv
(
1024
)
print
(
'got %r'
%
data
)
if
not
data
:
break
...
...
@@ -47,8 +47,7 @@ class Test(util.TestServer):
# On Windows, SIGTERM actually abruptly terminates the process;
# it can't be caught. However, CTRL_C_EVENT results in a KeyboardInterrupt
# being raised, so we can shut down properly.
self
.
popen
.
send_signal
(
getattr
(
signal
,
'CTRL_C_EVENT'
)
if
hasattr
(
signal
,
'CTRL_C_EVENT'
)
else
signal
.
SIGTERM
)
self
.
popen
.
send_signal
(
getattr
(
signal
,
'CTRL_C_EVENT'
,
signal
.
SIGTERM
))
sleep
(
0.1
)
conn
.
sendall
(
b'msg2'
)
...
...
src/greentest/test__example_udp_client.py
View file @
e5b881b7
from
gevent
import
monkey
;
monkey
.
patch_all
(
subprocess
=
True
)
import
sys
from
gevent.server
import
DatagramServer
from
unittest
import
TestCase
,
main
from
util
import
run
from
unittest
import
TestCase
from
greentest.
util
import
run
from
greentest
import
main
class
Test_udp_client
(
TestCase
):
...
...
src/greentest/test__example_udp_server.py
View file @
e5b881b7
import
socket
from
unittest
import
main
import
util
from
greentest
import
util
from
greentest
import
main
class
Test
(
util
.
TestServer
):
...
...
@@ -10,7 +11,7 @@ class Test(util.TestServer):
sock
=
socket
.
socket
(
type
=
socket
.
SOCK_DGRAM
)
sock
.
connect
((
'127.0.0.1'
,
9000
))
sock
.
send
(
b'Test udp_server'
)
data
,
address
=
sock
.
recvfrom
(
8192
)
data
,
_
address
=
sock
.
recvfrom
(
8192
)
self
.
assertEqual
(
data
,
b'Received 15 bytes'
)
sock
.
close
()
...
...
src/greentest/test__examples.py
View file @
e5b881b7
...
...
@@ -2,7 +2,8 @@ import sys
import
os
import
glob
import
time
import
util
from
greentest
import
util
cwd
=
'../../examples/'
...
...
src/greentest/test__exc_info.py
View file @
e5b881b7
import
gevent
import
sys
import
greentest
import
_six
as
six
from
greentest
import
six
if
not
six
.
PY3
:
sys
.
exc_clear
()
...
...
src/greentest/test__execmodules.py
View file @
e5b881b7
from
greentest
import
walk_modules
,
BaseTestCase
,
main
,
NON_APPLICABLE_SUFFIXES
import
_six
as
six
import
unittest
from
greentest.modules
import
walk_modules
from
greentest
import
main
from
greentest.sysinfo
import
NON_APPLICABLE_SUFFIXES
class
TestExec
(
BaseTestCase
):
from
greentest
import
six
class
TestExec
(
unittest
.
TestCase
):
pass
...
...
src/greentest/test__nondefaultloop.py
View file @
e5b881b7
# test for issue #210
from
gevent
import
core
from
util
import
alarm
from
greentest.
util
import
alarm
alarm
(
1
)
...
...
src/greentest/test__order.py
View file @
e5b881b7
import
gevent
import
greentest
from
_
six
import
xrange
from
greentest.
six
import
xrange
class
appender
(
object
):
...
...
src/greentest/test__os.py
View file @
e5b881b7
import
sys
import
_six
as
six
from
greentest
import
six
from
os
import
pipe
import
gevent
from
gevent
import
os
from
greentest
import
TestCase
,
main
,
CI
_TIMEOUT
from
greentest
import
TestCase
,
main
,
LARGE
_TIMEOUT
from
gevent
import
Greenlet
,
joinall
class
TestOS_tp
(
TestCase
):
__timeout__
=
CI
_TIMEOUT
__timeout__
=
LARGE
_TIMEOUT
def
pipe
(
self
):
return
pipe
()
...
...
@@ -83,7 +83,7 @@ if hasattr(os, 'fork_and_watch'):
class
TestForkAndWatch
(
TestCase
):
__timeout__
=
CI
_TIMEOUT
__timeout__
=
LARGE
_TIMEOUT
def
test_waitpid_all
(
self
):
# Cover this specific case.
...
...
src/greentest/test__pool.py
View file @
e5b881b7
...
...
@@ -7,7 +7,7 @@ from gevent.timeout import Timeout
import
greentest
import
random
from
greentest
import
ExpectedException
import
_six
as
six
from
greentest
import
six
import
unittest
...
...
src/greentest/test__select.py
View file @
e5b881b7
import
_six
as
six
from
greentest
import
six
import
sys
import
os
import
errno
...
...
src/greentest/test__sleep0.py
View file @
e5b881b7
import
gevent
from
util
import
alarm
from
greentest.
util
import
alarm
alarm
(
3
)
...
...
src/greentest/test__socket.py
View file @
e5b881b7
...
...
@@ -8,7 +8,7 @@ import time
import
unittest
import
greentest
from
functools
import
wraps
import
_six
as
six
from
greentest
import
six
# we use threading on purpose so that we can test both regular and gevent sockets with the same code
from
threading
import
Thread
as
_Thread
...
...
src/greentest/test__socket_dns.py
View file @
e5b881b7
#!/usr/bin/python
# -*- coding: utf-8 -*-
import
_six
as
six
import
re
import
greentest
import
unittest
...
...
@@ -8,8 +8,9 @@ import socket
from
time
import
time
import
gevent
import
gevent.socket
as
gevent_socket
from
util
import
log
from
_six
import
xrange
from
greentest.util
import
log
from
greentest
import
six
from
greentest.six
import
xrange
resolver
=
gevent
.
get_hub
().
resolver
...
...
src/greentest/test__subprocess_poll.py
View file @
e5b881b7
import
sys
from
gevent.subprocess
import
Popen
from
util
import
alarm
from
greentest.
util
import
alarm
alarm
(
3
)
...
...
src/greentest/test__threadpool.py
View file @
e5b881b7
import
sys
from
time
import
time
,
sleep
import
contextlib
import
random
import
weakref
import
greentest
...
...
@@ -7,16 +8,27 @@ import gevent.threadpool
from
gevent.threadpool
import
ThreadPool
import
gevent
from
greentest
import
ExpectedException
import
_six
as
six
from
greentest
import
six
import
gc
PYPY
=
hasattr
(
sys
,
'pypy_version_info'
)
@
contextlib
.
contextmanager
def
disabled_gc
():
was_enabled
=
gc
.
isenabled
()
gc
.
disable
()
try
:
yield
finally
:
if
was_enabled
:
gc
.
enable
()
class
TestCase
(
greentest
.
TestCase
):
# These generally need more time
__timeout__
=
greentest
.
CI
_TIMEOUT
__timeout__
=
greentest
.
LARGE
_TIMEOUT
pool
=
None
def
cleanup
(
self
):
...
...
@@ -402,7 +414,7 @@ class TestRef(TestCase):
func
=
obj
.
func
del
obj
with
greentest
.
disabled_gc
():
with
disabled_gc
():
# we do this:
# result = func(Object(), kwarg1=Object())
# but in a thread pool and see that arguments', result's and func's references are not leaked
...
...
src/greentest/test_hub_join_timeout.py
View file @
e5b881b7
...
...
@@ -3,7 +3,7 @@ import gevent
import
gevent.core
from
gevent.event
import
Event
from
time
import
time
from
_
six
import
xrange
from
greentest.
six
import
xrange
SMALL
=
0.1
...
...
src/greentest/test_threading_2.py
View file @
e5b881b7
# testing gevent's Event, Lock, RLock, Semaphore, BoundedSemaphore with standard test_threading
from
__future__
import
print_function
from
_
six
import
xrange
from
greentest.
six
import
xrange
import
greentest
setup_
=
'''from gevent import monkey; monkey.patch_all()
...
...
src/greentest/testrunner.py
View file @
e5b881b7
This diff is collapsed.
Click to expand it.
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