Disable attach tests on macOS + Python 3.6 due to #1967

Gracefully handle server abruptly disconnecting from adapter for the initial connection.

Fix test_exclude_rules to wait until debuggee terminates.
This commit is contained in:
Pavel Minaev 2019-12-13 13:28:01 -08:00 committed by Pavel Minaev
parent a654c9834f
commit eb50bc29df
5 changed files with 28 additions and 6 deletions

View file

@ -43,6 +43,8 @@ class Connection(sockets.ClientConnection):
def __init__(self, sock):
from ptvsd.adapter import sessions
self.disconnected = False
self.server = None
"""The Server component, if this debug server belongs to Session.
"""
@ -101,6 +103,13 @@ if 'ptvsd' not in sys.modules:
log.exception("Failed to inject ptvsd into {0}:", self, level="warning")
with _lock:
# The server can disconnect concurrently before we get here, e.g. if
# it was force-killed. If the disconnect() handler has already run,
# don't register this server or report it, since there's nothing to
# deregister it.
if self.disconnected:
return
if any(conn.pid == self.pid for conn in _connections):
raise KeyError(
fmt("{0} is already connected to this adapter", self)
@ -110,10 +119,16 @@ if 'ptvsd' not in sys.modules:
except Exception:
log.exception("Failed to accept incoming server connection:")
self.channel.close()
# If this was the first server to connect, and the main thread is inside
# wait_until_disconnected(), we want to unblock it and allow it to exit.
with _lock:
_connections_changed.set()
# If we couldn't retrieve all the necessary info from the debug server,
# or there's a PID clash, we don't want to track this debuggee anymore,
# but we want to continue accepting connections.
self.channel.close()
return
parent_session = sessions.get(self.ppid)
@ -155,10 +170,11 @@ if 'ptvsd' not in sys.modules:
def disconnect(self):
with _lock:
# If the disconnect happened while Server was being instantiated, we need
# to tell it, so that it can clean up properly via Session.finalize(). It
# will also take care of deregistering the connection in that case.
self.disconnected = True
if self.server is not None:
# If the disconnect happened while Server was being instantiated,
# we need to tell it, so that it can clean up via Session.finalize().
# It will also take care of deregistering the connection in that case.
self.server.disconnect()
elif self in _connections:
_connections.remove(self)

View file

@ -9,6 +9,7 @@ import itertools
import os
import psutil
import py
import pytest
import subprocess
import sys
import time
@ -442,6 +443,10 @@ class Session(object):
)
def send_request(self, command, arguments=None, proceed=True):
if command == "attach":
if sys.version_info[:2] == (3, 6) and sys.platform == "darwin":
pytest.skip("https://github.com/microsoft/ptvsd/issues/1967")
self.before_request(command, arguments)
if self.timeline.is_frozen and proceed:

View file

@ -148,6 +148,7 @@ def test_attach_by_pid(pyfile, target, pid_type):
break
with debug.Session() as session:
def before_request(command, arguments):
if command == "attach":
assert isinstance(arguments["processId"], int)

View file

@ -57,6 +57,8 @@ def test_exceptions_and_exclude_rules(pyfile, target, run, scenario, exc_type):
)
# No exceptions should be seen.
session.wait_for_next_event("terminated")
session.proceed()
@pytest.mark.parametrize("scenario", ["exclude_code_to_debug", "exclude_callback_dir"])

View file

@ -13,8 +13,6 @@ from tests import debug
from tests.debug import runners
from tests.patterns import some
pytestmark = pytest.mark.timeout(30)
@pytest.fixture(params=[runners.launch, runners.attach_by_socket["api"]])
def run(request):