Fix Python 3 support for eventlet monkey-patching
Use eventlet.green.subprocess if eventlet is used and enable eventlet tests on Python 3. This change adds oslo_rootwrap.subprocess which is eventlet.green.subprocess if eventlet monkey-patching is enabled or if the TEST_EVENTLET environment variable is set, or subprocess of the Python standard library otherwise. When eventlet is used (with monkey-patching or not), it's more reliable to use eventlet.green.subprocess instead of using directly subprocess from the Python standard library. On Python 2, it "works" to use directly subprocess: subprocess.Popen calls os.pipe() and os.fdopen(fd) which are both monkey-patched. On Python 3, it doesn't work because subprocess uses os.pipe() and io.open(fd), and the io module is *not* monkey-patched at all. Change-Id: Ib859bebe52612b35f0f1f53aedf76222683795e7
This commit is contained in:
parent
6f424f73cd
commit
31cfdbd407
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (c) 2015 Red Hat.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
import eventlet.patcher
|
||||||
|
except ImportError:
|
||||||
|
_patched_socket = False
|
||||||
|
else:
|
||||||
|
# In tests patching happens later, so we'll rely on environment variable
|
||||||
|
_patched_socket = (eventlet.patcher.is_monkey_patched('socket') or
|
||||||
|
os.environ.get('TEST_EVENTLET', False))
|
||||||
|
|
||||||
|
if not _patched_socket:
|
||||||
|
import subprocess
|
||||||
|
else:
|
||||||
|
from eventlet.green import subprocess # noqa
|
@ -16,24 +16,15 @@
|
|||||||
import logging
|
import logging
|
||||||
from multiprocessing import managers
|
from multiprocessing import managers
|
||||||
from multiprocessing import util as mp_util
|
from multiprocessing import util as mp_util
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import threading
|
import threading
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
try:
|
import oslo_rootwrap
|
||||||
import eventlet.patcher
|
|
||||||
except ImportError:
|
|
||||||
patched_socket = False
|
|
||||||
else:
|
|
||||||
# In tests patching happens later, so we'll rely on environment variable
|
|
||||||
patched_socket = (eventlet.patcher.is_monkey_patched('socket') or
|
|
||||||
os.environ.get('TEST_EVENTLET', False))
|
|
||||||
|
|
||||||
from oslo_rootwrap import daemon
|
from oslo_rootwrap import daemon
|
||||||
from oslo_rootwrap import jsonrpc
|
from oslo_rootwrap import jsonrpc
|
||||||
|
from oslo_rootwrap import subprocess
|
||||||
|
|
||||||
if patched_socket:
|
if oslo_rootwrap._patched_socket:
|
||||||
# We have to use slow version of recvall with eventlet because of a bug in
|
# We have to use slow version of recvall with eventlet because of a bug in
|
||||||
# GreenSocket.recv_into:
|
# GreenSocket.recv_into:
|
||||||
# https://bitbucket.org/eventlet/eventlet/pull-request/41
|
# https://bitbucket.org/eventlet/eventlet/pull-request/41
|
||||||
|
@ -22,12 +22,12 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import signal
|
import signal
|
||||||
import stat
|
import stat
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from oslo_rootwrap import jsonrpc
|
from oslo_rootwrap import jsonrpc
|
||||||
|
from oslo_rootwrap import subprocess
|
||||||
from oslo_rootwrap import wrapper
|
from oslo_rootwrap import wrapper
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from oslo_rootwrap import cmd
|
from oslo_rootwrap import cmd
|
||||||
|
from oslo_rootwrap import subprocess
|
||||||
|
|
||||||
|
|
||||||
def forward_stream(fr, to):
|
def forward_stream(fr, to):
|
||||||
|
@ -19,7 +19,6 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
@ -35,6 +34,7 @@ import testtools
|
|||||||
from testtools import content
|
from testtools import content
|
||||||
|
|
||||||
from oslo_rootwrap import client
|
from oslo_rootwrap import client
|
||||||
|
from oslo_rootwrap import subprocess
|
||||||
from oslo_rootwrap.tests import run_daemon
|
from oslo_rootwrap.tests import run_daemon
|
||||||
from oslo_rootwrap import wrapper
|
from oslo_rootwrap import wrapper
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ class RootwrapDaemonTest(_FunctionalBase, testtools.TestCase):
|
|||||||
|
|
||||||
# Collect daemon logs
|
# Collect daemon logs
|
||||||
daemon_log = io.BytesIO()
|
daemon_log = io.BytesIO()
|
||||||
p = mock.patch('subprocess.Popen',
|
p = mock.patch('oslo_rootwrap.subprocess.Popen',
|
||||||
run_daemon.forwarding_popen(daemon_log))
|
run_daemon.forwarding_popen(daemon_log))
|
||||||
p.start()
|
p.start()
|
||||||
self.addCleanup(p.stop)
|
self.addCleanup(p.stop)
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
@ -26,6 +25,7 @@ import testtools
|
|||||||
from oslo_rootwrap import cmd
|
from oslo_rootwrap import cmd
|
||||||
from oslo_rootwrap import daemon
|
from oslo_rootwrap import daemon
|
||||||
from oslo_rootwrap import filters
|
from oslo_rootwrap import filters
|
||||||
|
from oslo_rootwrap import subprocess
|
||||||
from oslo_rootwrap import wrapper
|
from oslo_rootwrap import wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@ import logging.handlers
|
|||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from six import moves
|
from six import moves
|
||||||
|
|
||||||
from oslo_rootwrap import filters
|
from oslo_rootwrap import filters
|
||||||
|
from oslo_rootwrap import subprocess
|
||||||
|
|
||||||
|
|
||||||
class NoFilterMatched(Exception):
|
class NoFilterMatched(Exception):
|
||||||
|
6
tox.ini
6
tox.ini
@ -16,12 +16,6 @@ commands =
|
|||||||
python setup.py testr --slowest --testr-args='(?!tests.test_functional_eventlet)tests {posargs}'
|
python setup.py testr --slowest --testr-args='(?!tests.test_functional_eventlet)tests {posargs}'
|
||||||
env TEST_EVENTLET=1 python setup.py testr --slowest --testr-args='tests.test_functional_eventlet'
|
env TEST_EVENTLET=1 python setup.py testr --slowest --testr-args='tests.test_functional_eventlet'
|
||||||
|
|
||||||
[testenv:py34]
|
|
||||||
commands =
|
|
||||||
python setup.py testr --slowest --testr-args='{posargs}'
|
|
||||||
# FIXME: Eventlet tests does not work yet here
|
|
||||||
# env TEST_EVENTLET=1 python setup.py testr --slowest --testr-args='tests.test_functional_eventlet'
|
|
||||||
|
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
commands = flake8
|
commands = flake8
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user