Bunch of minor test fixes (#1726)

* Bunch of minor test fixes

* Fix linter and multiproc

* Remove missed os.environ

* Rename and move stop_debugging

* Add evaluate helper

* Add exit_code property

* Enable pytest and flake8 in workspace

* Fix test failure

* Set ptvsd python path in tests

* Rename exit_code to expected_exit_code
This commit is contained in:
Karthik Nadig 2019-08-29 00:19:50 -07:00 committed by GitHub
parent 20d0f1a0bc
commit 2a367b2f4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 140 additions and 235 deletions

View file

@ -7,6 +7,7 @@
"settings": {
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.envFile": "${workspaceFolder}/.env",
"python.formatting.provider": "black",
@ -15,6 +16,7 @@
"**/__pycache__": true,
".tox": true,
"src/ptvsd.egg-info": true,
}
},
"python.testing.pytestEnabled": true,
},
}

View file

@ -759,10 +759,7 @@ class PyDevdAPI(object):
reset_caches = True
def custom_dont_trace_external_files(abs_path):
for p in start_patterns:
if p in abs_path:
return True
return abs_path.endswith(end_patterns)
return abs_path.startswith(start_patterns) or abs_path.endswith(end_patterns)
custom_dont_trace_external_files.start_patterns = start_patterns
custom_dont_trace_external_files.end_patterns = end_patterns

View file

@ -14,7 +14,7 @@ import threading
import traceback
import ptvsd
from ptvsd.common import compat, fmt, options, timestamp
from ptvsd.common import compat, fmt, options, timestamp, util
LEVELS = ("debug", "info", "warning", "error")
@ -223,7 +223,7 @@ def describe_environment(header):
expr = None
if not callable(get_paths):
expr = get_paths
get_paths = lambda: eval(expr, {}, sys.modules)
get_paths = lambda: util.evaluate(expr)
try:
paths = get_paths()
except AttributeError:

View file

@ -5,6 +5,7 @@
from __future__ import absolute_import, print_function, unicode_literals
import threading
import sys
def new_hidden_thread(name, target, prefix='ptvsd.common.', daemon=True, **kwargs):
@ -21,3 +22,12 @@ def new_hidden_thread(name, target, prefix='ptvsd.common.', daemon=True, **kwarg
if daemon:
t.daemon = False
return t
def evaluate(code, path=__file__, mode="eval"):
# Setting file path here to avoid breaking here if users have set
# "break on exception raised" setting. This code can potentially run
# in user process and is indistinguishable if the path is not set.
# We use the path internally to skip exception inside the debugger.
expr = compile(code, path, "eval")
return eval(expr, {}, sys.modules)

View file

@ -13,10 +13,7 @@ import ptvsd
from ptvsd.common import log, options as common_opts
from ptvsd.server import options as server_opts
from _pydevd_bundle.pydevd_constants import get_global_debugger
from pydevd_file_utils import (
get_abs_path_real_path_and_base_from_file,
get_abs_path_real_path_and_base_from_frame,
)
from pydevd_file_utils import get_abs_path_real_path_and_base_from_file
def wait_for_attach():
@ -107,9 +104,7 @@ def break_into_debugger():
stop_at_frame = sys._getframe().f_back
while (
stop_at_frame is not None
and global_debugger.get_file_type(
stop_at_frame, get_abs_path_real_path_and_base_from_frame(stop_at_frame)
)
and global_debugger.get_file_type(stop_at_frame)
== global_debugger.PYDEV_FILE
):
stop_at_frame = stop_at_frame.f_back

View file

@ -27,8 +27,7 @@ StopInfo = collections.namedtuple(
PTVSD_DIR = py.path.local(ptvsd.__file__) / ".."
PTVSD_ADAPTER_DIR = PTVSD_DIR / "adapter"
# Added to the environment variables of every new debug.Session - after copying
# os.environ(), but before setting any session-specific variables.
# Added to the environment variables of every new debug.Session
PTVSD_ENV = {"PYTHONUNBUFFERED": "1"}
@ -120,6 +119,11 @@ class Session(object):
# Log the error, in case another one happens during shutdown.
log.exception(exc_info=(exc_type, exc_val, exc_tb))
try:
self.wait_for_exit()
except Exception:
raise log.exception()
self._stop_adapter()
if self.backchannel:
@ -128,12 +132,24 @@ class Session(object):
@property
def process(self):
return self.start_method.debugee_process
return self.start_method.debuggee_process
@property
def pid(self):
return self.process.pid
@property
def ignore_unobserved(self):
return self.timeline.ignore_unobserved
@property
def expected_exit_code(self):
return self.start_method.expected_exit_code
@expected_exit_code.setter
def expected_exit_code(self, value):
self.start_method.expected_exit_code = value
def request(self, *args, **kwargs):
freeze = kwargs.pop("freeze", True)
raise_if_failed = kwargs.pop("raise_if_failed", True)
@ -257,6 +273,7 @@ class Session(object):
if pythonpath:
pythonpath += os.pathsep
pythonpath += (tests.root / "DEBUGGEE_PYTHONPATH").strpath
pythonpath += os.pathsep + (PTVSD_DIR / "..").strpath
env["PYTHONPATH"] = pythonpath
env["PTVSD_SESSION_ID"] = str(self.id)
@ -395,6 +412,7 @@ class Session(object):
"exception",
"breakpoint",
"entry",
"goto"
]:
expected_stopped["preserveFocusHint"] = True
assert stopped == some.dict.containing(expected_stopped)
@ -431,6 +449,6 @@ class Session(object):
def captured_stderr(self, encoding=None):
return self.start_method.captured_output.stderr(encoding)
def stop_debugging(self, exit_code=None):
self.start_method.wait_for_debuggee(exit_code)
def wait_for_exit(self):
self.start_method.wait_for_debuggee()
self.request_disconnect()

View file

@ -28,5 +28,3 @@ def test_args(pyfile, start_method, run_as):
argv = session.backchannel.receive()
assert argv == [some.str] + expected
session.stop_debugging()

View file

@ -53,7 +53,6 @@ def test_attach(run_as, wait_for_attach, is_attached, stop_method):
pytest.fail(stop_method)
session.request_continue()
session.stop_debugging()
@pytest.mark.parametrize(
@ -129,5 +128,3 @@ def test_attaching_by_pid(pyfile, run_as, start_method):
session.wait_for_next(
Event("output", some.dict.containing({"category": "stdout"}))
)
session.stop_debugging()

View file

@ -27,7 +27,6 @@ def test_with_wait_for_attach(pyfile, start_method, run_as):
assert hit.frames[0]["line"] == code_to_debug.lines["break"]
session.request_continue()
session.stop_debugging()
@pytest.mark.parametrize("run_as", ["program", "module", "code"])
@ -52,4 +51,3 @@ def test_breakpoint_function(pyfile, start_method, run_as):
assert hit.frames[0]["line"] == code_to_debug.lines["break"]
session.request_continue()
session.stop_debugging()

View file

@ -34,7 +34,6 @@ def test_path_with_ampersand(start_method, run_as):
)
session.request_continue()
session.stop_debugging()
@pytest.mark.skipif(
@ -58,7 +57,6 @@ def test_path_with_unicode(start_method, run_as):
)
session.request_continue()
session.stop_debugging()
@pytest.mark.parametrize(
@ -122,7 +120,6 @@ def test_conditional_breakpoint(pyfile, start_method, run_as, condition_kind):
for i in range(1, hits):
session.wait_for_stop()
session.request_continue()
session.stop_debugging()
def test_crossfile_breakpoint(pyfile, start_method, run_as):
@ -154,7 +151,6 @@ def test_crossfile_breakpoint(pyfile, start_method, run_as):
session.wait_for_stop(expected_frames=[some.dap.frame(script1, line="bp")])
session.request_continue()
session.stop_debugging()
@pytest.mark.parametrize("error_name", ["NameError", ""])
@ -188,15 +184,14 @@ def test_error_in_condition(pyfile, start_method, run_as, error_name):
},
)
session.start_debugging()
session.stop_debugging()
assert not session.captured_stdout()
assert not session.captured_stdout()
error_name = error_name.encode("ascii")
if expect_traceback:
assert error_name in session.captured_stderr()
else:
assert error_name not in session.captured_stderr()
error_name = error_name.encode("ascii")
if expect_traceback:
assert error_name in session.captured_stderr()
else:
assert error_name not in session.captured_stderr()
@pytest.mark.parametrize("condition", ["condition", ""])
@ -248,17 +243,16 @@ def test_log_point(pyfile, start_method, run_as, condition):
],
)
session.request_continue()
session.stop_debugging()
assert not session.captured_stderr()
assert not session.captured_stderr()
expected_stdout = "".join(
(
fmt(r"{0}\r?\n{1}\r?\n", re.escape(str(i)), re.escape(str(i * 10)))
for i in range(0, 10)
)
expected_stdout = "".join(
(
fmt(r"{0}\r?\n{1}\r?\n", re.escape(str(i)), re.escape(str(i * 10)))
for i in range(0, 10)
)
assert session.output("stdout") == some.str.matching(expected_stdout)
)
assert session.output("stdout") == some.str.matching(expected_stdout)
def test_package_launch():
@ -266,6 +260,7 @@ def test_package_launch():
test_py = cwd / "pkg1" / "__main__.py"
with debug.Session(start_methods.Launch) as session:
session.expected_exit_code = 42
session.configure("module", "pkg1", cwd=cwd)
session.set_breakpoints(test_py, ["two"])
session.start_debugging()
@ -278,7 +273,6 @@ def test_package_launch():
)
session.request_continue()
session.stop_debugging(exitCode=42)
def test_add_and_remove_breakpoint(pyfile, start_method, run_as):
@ -313,10 +307,9 @@ def test_add_and_remove_breakpoint(pyfile, start_method, run_as):
],
)
session.request_continue()
session.stop_debugging()
expected_stdout = "".join((fmt("{0}\n", i) for i in range(0, 10)))
assert session.output("stdout") == expected_stdout
expected_stdout = "".join((fmt("{0}\n", i) for i in range(0, 10)))
assert session.output("stdout") == expected_stdout
def test_invalid_breakpoints(pyfile, start_method, run_as):
@ -375,8 +368,6 @@ def test_invalid_breakpoints(pyfile, start_method, run_as):
)
session.request_continue()
session.stop_debugging()
def test_deep_stacks(pyfile, start_method, run_as):
@pyfile
@ -417,4 +408,3 @@ def test_deep_stacks(pyfile, start_method, run_as):
assert stop.frames == frames
session.request_continue()
session.stop_debugging()

View file

@ -66,11 +66,9 @@ def test_completions_scope(pyfile, bp_label, start_method, run_as):
session.request_continue()
targets.sort(key=lambda t: t["label"])
expected.sort(key=lambda t: t["label"])
assert targets == expected
session.stop_debugging()
targets.sort(key=lambda t: t["label"])
expected.sort(key=lambda t: t["label"])
assert targets == expected
def test_completions_cases(pyfile, start_method, run_as):
@ -132,4 +130,3 @@ def test_completions_cases(pyfile, start_method, run_as):
assert "Wrong ID sent from the client:" in str(error)
session.request_continue()
session.stop_debugging()

View file

@ -29,12 +29,10 @@ def test_continue_on_disconnect_for_attach(pyfile, start_method, run_as):
hit = session.wait_for_stop("breakpoint")
assert hit.frames[0]["line"] == code_to_debug.lines["bp"]
session.send_request("disconnect").wait_for_response()
session.wait_for_disconnect()
assert "continued" == backchannel.receive()
@pytest.mark.parametrize("start_method", [start_methods.Launch])
@pytest.mark.skip(reason="Bug #1052")
def test_exit_on_disconnect_for_launch(pyfile, start_method, run_as):
@pyfile
def code_to_debug():
@ -47,12 +45,13 @@ def test_exit_on_disconnect_for_launch(pyfile, start_method, run_as):
print("Should not continue after disconnect on launch", file=f)
with debug.Session(start_method) as session:
session.expected_exit_code = some.int
session.configure(run_as, code_to_debug)
session.set_breakpoints(code_to_debug, code_to_debug.lines["bp"])
session.start_debugging()
hit = session.wait_for_stop("breakpoint")
assert hit.frames[0]["line"] == code_to_debug.lines["bp"]
session.send_request("disconnect").wait_for_response()
session.stop_debugging(exitCode=some.int)
fp = os.join(os.path.dirname(os.path.abspath(code_to_debug)), "here.txt")
assert not os.path.exists(fp)
fp = os.join(os.path.dirname(os.path.abspath(code_to_debug)), "here.txt")
assert not os.path.exists(fp)

View file

@ -25,18 +25,19 @@ class lines:
app_py = code.get_marked_line_numbers(paths.app_py)
def _initialize_session(session, multiprocess=False):
session.program_args = ["runserver", "--", str(django.port)]
def _initialize_session(session, multiprocess=False, exit_code=0):
args = ["runserver"]
if not multiprocess:
session.program_args[1:1] = ["--noreload"]
session.debug_options |= {"Django"}
if multiprocess:
session.debug_options |= {"Multiprocess"}
args += ["--noreload"]
args += ["--", str(django.port)]
session.expected_exit_code = exit_code
session.configure(
"program", paths.app_py,
cwd=paths.django1,
multiprocess=multiprocess,
args=args,
django=True
)
@ -50,7 +51,7 @@ def test_django_breakpoint_no_multiproc(start_method, bp_target):
bp_var_content = compat.force_str("Django-Django-Test")
with debug.Session(start_method) as session:
_initialize_session(session)
_initialize_session(session, exit_code=some.int)
session.set_breakpoints(bp_file, [bp_line])
session.start_debugging()
@ -82,15 +83,11 @@ def test_django_breakpoint_no_multiproc(start_method, bp_target):
session.request_continue()
assert bp_var_content in home_request.response_text()
session.stop_debugging(
exitCode=some.int, # No clean way to kill Django server
)
@pytest.mark.parametrize("start_method", [start_methods.Launch, start_methods.AttachSocketCmdLine])
def test_django_template_exception_no_multiproc(start_method):
with debug.Session(start_method) as session:
_initialize_session(session)
_initialize_session(session, exit_code=some.int)
session.request("setExceptionBreakpoints", {"filters": ["raised", "uncaught"]})
session.start_debugging()
@ -131,10 +128,6 @@ def test_django_template_exception_no_multiproc(start_method):
session.wait_for_stop("exception")
session.request_continue()
session.stop_debugging(
exitCode=some.int, # No clean way to kill Django server
)
@pytest.mark.parametrize("start_method", [start_methods.Launch, start_methods.AttachSocketCmdLine])
@pytest.mark.parametrize("exc_type", ["handled", "unhandled"])
@ -142,7 +135,7 @@ def test_django_exception_no_multiproc(start_method, exc_type):
exc_line = lines.app_py["exc_" + exc_type]
with debug.Session(start_method) as session:
_initialize_session(session)
_initialize_session(session, exit_code=some.int)
session.request("setExceptionBreakpoints", {"filters": ["raised", "uncaught"]})
session.start_debugging()
@ -185,10 +178,6 @@ def test_django_exception_no_multiproc(start_method, exc_type):
session.request_continue()
session.stop_debugging(
exitCode=some.int, # No clean way to kill Django server
)
@pytest.mark.parametrize("start_method", [start_methods.Launch])
def test_django_breakpoint_multiproc(start_method):
@ -196,7 +185,7 @@ def test_django_breakpoint_multiproc(start_method):
bp_var_content = compat.force_str("Django-Django-Test")
with debug.Session(start_method) as parent_session:
_initialize_session(parent_session, multiprocess=True)
_initialize_session(parent_session, multiprocess=True, exit_code=some.int)
parent_session.set_breakpoints(paths.app_py, [bp_line])
parent_session.start_debugging()
@ -228,6 +217,3 @@ def test_django_breakpoint_multiproc(start_method):
child_session.request_continue()
assert bp_var_content in home_request.response_text()
child_session.stop_debugging()
parent_session.stop_debugging(exitCode=some.int)

View file

@ -100,7 +100,6 @@ def test_variables_and_evaluate(pyfile, start_method, run_as):
)
session.request_continue()
session.stop_debugging()
def test_set_variable(pyfile, start_method, run_as):
@ -156,8 +155,6 @@ def test_set_variable(pyfile, start_method, run_as):
assert backchannel.receive() == 1000
session.stop_debugging()
def test_variable_sort(pyfile, start_method, run_as):
@pyfile
@ -245,7 +242,6 @@ def test_variable_sort(pyfile, start_method, run_as):
# assert variable_names[:3] == ['1', '2', '10']
session.request_continue()
session.stop_debugging()
def test_return_values(pyfile, start_method, run_as):
@ -333,7 +329,6 @@ def test_return_values(pyfile, start_method, run_as):
assert variables == [expected1, expected2]
session.send_request("continue").wait_for_response()
session.stop_debugging()
def test_unicode(pyfile, start_method, run_as):
@ -367,7 +362,6 @@ def test_unicode(pyfile, start_method, run_as):
assert resp_eval.body == some.dict.containing({"type": "SyntaxError"})
session.request_continue()
session.stop_debugging()
def test_hex_numbers(pyfile, start_method, run_as):
@ -592,4 +586,3 @@ def test_hex_numbers(pyfile, start_method, run_as):
]
session.request_continue()
session.stop_debugging()

View file

@ -36,6 +36,7 @@ def test_vsc_exception_options_raise_with_except(
filters += ["uncaught"] if uncaught == "uncaughtOn" else []
with debug.Session(start_method) as session:
session.expected_exit_code = some.int
session.configure(run_as, code_to_debug)
session.request("setExceptionBreakpoints", {"filters": filters})
session.start_debugging()
@ -72,8 +73,6 @@ def test_vsc_exception_options_raise_with_except(
# uncaught should not 'stop' matter since the exception is caught
session.stop_debugging()
@pytest.mark.parametrize("raised", ["raisedOn", "raisedOff"])
@pytest.mark.parametrize("uncaught", ["uncaughtOn", "uncaughtOff"])
@ -95,6 +94,7 @@ def test_vsc_exception_options_raise_without_except(
filters += ["uncaught"] if uncaught == "uncaughtOn" else []
with debug.Session(start_method) as session:
session.ignore_unobserved += [Event("stopped")]
session.expected_exit_code = some.int
session.configure(run_as, code_to_debug)
session.send_request(
"setExceptionBreakpoints", {"filters": filters}
@ -160,8 +160,6 @@ def test_vsc_exception_options_raise_without_except(
assert resp_exc_info.body == expected
session.request_continue()
session.stop_debugging(exitCode=some.int)
@pytest.mark.parametrize("raised", ["raised", ""])
@pytest.mark.parametrize("uncaught", ["uncaught", ""])
@ -190,10 +188,8 @@ def test_systemexit(pyfile, start_method, run_as, raised, uncaught, zero, exit_c
filters += ["uncaught"]
with debug.Session(start_method) as session:
session.program_args = [repr(exit_code)]
if zero:
session.debug_options |= {"BreakOnSystemExitZero"}
session.configure(run_as, code_to_debug)
session.expected_exit_code = some.int
session.configure(run_as, code_to_debug, args=[repr(exit_code)], breakOnSystemExitZero=bool(zero))
session.send_request(
"setExceptionBreakpoints", {"filters": filters}
).wait_for_response()
@ -221,8 +217,6 @@ def test_systemexit(pyfile, start_method, run_as, raised, uncaught, zero, exit_c
assert hit.frames[0]["line"] == line_numbers["unhandled"]
session.request_continue()
session.stop_debugging(exitCode=some.int)
@pytest.mark.parametrize(
"break_mode", ["always", "never", "unhandled", "userUnhandled"]
@ -281,6 +275,7 @@ def test_raise_exception_options(pyfile, start_method, run_as, exceptions, break
with debug.Session(start_method) as session:
session.ignore_unobserved += [Event("stopped")]
session.expected_exit_code = some.int
session.configure(run_as, code_to_debug)
path = [{"names": ["Python Exceptions"]}]
if exceptions:
@ -305,8 +300,6 @@ def test_raise_exception_options(pyfile, start_method, run_as, exceptions, break
assert hit.frames[0]["line"] == code_to_debug.lines[expected_exception]
session.request_continue()
session.stop_debugging(exitCode=some.int)
@pytest.mark.parametrize("exit_code", [0, 3])
def test_success_exitcodes(pyfile, start_method, run_as, exit_code):
@ -320,6 +313,7 @@ def test_success_exitcodes(pyfile, start_method, run_as, exit_code):
sys.exit(exit_code)
with debug.Session(start_method) as session:
session.expected_exit_code = some.int
session.configure(run_as, code_to_debug, args=[repr(exit_code)], successExitCodes=[3])
session.send_request(
"setExceptionBreakpoints", {"filters": ["uncaught"]}
@ -330,8 +324,6 @@ def test_success_exitcodes(pyfile, start_method, run_as, exit_code):
session.wait_for_stop("exception")
session.request_continue()
session.stop_debugging(exitCode=some.int)
@pytest.mark.parametrize("max_frames", ["default", "all", 10])
def test_exception_stack(pyfile, start_method, run_as, max_frames):
@ -366,6 +358,7 @@ def test_exception_stack(pyfile, start_method, run_as, max_frames):
maxFrames = 10
with debug.Session(start_method) as session:
session.expected_exit_code = some.int
session.configure(
run_as, code_to_debug,
maxExceptionStackFrames=maxFrames,
@ -402,5 +395,3 @@ def test_exception_stack(pyfile, start_method, run_as, max_frames):
assert min_expected_lines <= stack_line_count <= max_expected_lines
session.request_continue()
session.stop_debugging(exitCode=some.int)

View file

@ -51,7 +51,6 @@ def test_exceptions_and_exclude_rules(
session.start_debugging()
# No exceptions should be seen.
session.stop_debugging()
@pytest.mark.parametrize("scenario", ["exclude_code_to_debug", "exclude_callback_dir"])
@ -188,5 +187,3 @@ def test_exceptions_and_partial_exclude_rules(pyfile, start_method, run_as, scen
else:
pytest.fail(scenario)
session.stop_debugging()

View file

@ -28,25 +28,23 @@ class lines:
app_py = code.get_marked_line_numbers(paths.app_py)
def _initialize_session(session, multiprocess=False):
session.env.update({
def _initialize_session(session, multiprocess=False, exit_code=0):
env = {
"FLASK_APP": paths.app_py,
"FLASK_ENV": "development",
"FLASK_DEBUG": "1" if multiprocess else "0",
})
}
if platform.system() != "Windows":
locale = "en_US.utf8" if platform.system() == "Linux" else "en_US.UTF-8"
session.env.update({"LC_ALL": locale, "LANG": locale})
env.update({"LC_ALL": locale, "LANG": locale})
session.program_args = ["run", "--port", str(flask.port)]
args = ["run"]
if not multiprocess:
session.program_args[1:1] = ["--no-debugger", "--no-reload", "--with-threads"]
args += ["--no-debugger", "--no-reload", "--with-threads"]
args += ["--port", str(flask.port)]
session.debug_options |= {"Jinja"}
if multiprocess:
session.debug_options |= {"Multiprocess"}
session.configure("module", "flask", cwd=paths.flask1)
session.expected_exit_code = exit_code
session.configure("module", "flask", cwd=paths.flask1, jinja=True, multiprocess=multiprocess, args=args, env=env)
@pytest.mark.parametrize("start_method", [start_methods.Launch, start_methods.AttachSocketCmdLine])
@ -59,7 +57,7 @@ def test_flask_breakpoint_no_multiproc(start_method, bp_target):
bp_var_content = compat.force_str("Flask-Jinja-Test")
with debug.Session(start_method) as session:
_initialize_session(session)
_initialize_session(session, exit_code=some.int) # No clean way to kill Flask server
session.set_breakpoints(bp_file, [bp_line])
session.start_debugging()
@ -91,15 +89,11 @@ def test_flask_breakpoint_no_multiproc(start_method, bp_target):
session.request_continue()
assert bp_var_content in home_request.response_text()
session.stop_debugging(
exitCode=some.int, # No clean way to kill Flask server
)
@pytest.mark.parametrize("start_method", [start_methods.Launch, start_methods.AttachSocketCmdLine])
def test_flask_template_exception_no_multiproc(start_method):
with debug.Session(start_method) as session:
_initialize_session(session)
_initialize_session(session, exit_code=some.int) # No clean way to kill Flask server
session.request("setExceptionBreakpoints", {"filters": ["raised", "uncaught"]})
session.start_debugging()
@ -148,10 +142,6 @@ def test_flask_template_exception_no_multiproc(start_method):
session.wait_for_stop("exception")
session.request_continue()
session.stop_debugging(
exitCode=some.int, # No clean way to kill Flask server
)
@pytest.mark.parametrize("start_method", [start_methods.Launch, start_methods.AttachSocketCmdLine])
@pytest.mark.parametrize("exc_type", ["handled", "unhandled"])
@ -159,7 +149,7 @@ def test_flask_exception_no_multiproc(start_method, exc_type):
exc_line = lines.app_py["exc_" + exc_type]
with debug.Session(start_method) as session:
_initialize_session(session)
_initialize_session(session, exit_code=some.int) # No clean way to kill Flask server
session.request("setExceptionBreakpoints", {"filters": ["raised", "uncaught"]})
session.start_debugging()
@ -202,10 +192,6 @@ def test_flask_exception_no_multiproc(start_method, exc_type):
session.request_continue()
session.stop_debugging(
exitCode=some.int, # No clean way to kill Flask server
)
@pytest.mark.parametrize("start_method", [start_methods.Launch])
def test_flask_breakpoint_multiproc(start_method):
@ -213,7 +199,8 @@ def test_flask_breakpoint_multiproc(start_method):
bp_var_content = compat.force_str("Flask-Jinja-Test")
with debug.Session(start_method) as parent_session:
_initialize_session(parent_session, multiprocess=True)
# No clean way to kill Flask server
_initialize_session(parent_session, multiprocess=True, exit_code=some.int)
parent_session.set_breakpoints(paths.app_py, [bp_line])
parent_session.start_debugging()
@ -248,8 +235,3 @@ def test_flask_breakpoint_multiproc(start_method):
child_session.request_continue()
assert bp_var_content in home_request.response_text()
child_session.stop_debugging()
parent_session.stop_debugging(
exitCode=some.int, # No clean way to kill Flask server
)

View file

@ -19,9 +19,7 @@ def test_justmycode_frames(pyfile, start_method, run_as, jmc):
print("break here") # @bp
with debug.Session(start_method) as session:
if not jmc:
session.debug_options |= {"DebugStdLib"}
session.configure(run_as, code_to_debug)
session.configure(run_as, code_to_debug, justMyCode=bool(jmc))
bp_line = code_to_debug.lines["bp"]
actual_bps = session.set_breakpoints(code_to_debug, [bp_line])
@ -54,5 +52,3 @@ def test_justmycode_frames(pyfile, start_method, run_as, jmc):
# 'continue' should terminate the debuggee
session.request_continue()
session.stop_debugging()

View file

@ -8,7 +8,7 @@ import contextlib
import pytest
from ptvsd.common import compat
from tests import debug
from tests import debug, start_methods
@contextlib.contextmanager
@ -37,10 +37,10 @@ def test_log_cli(pyfile, tmpdir, start_method, run_as, cli):
session.env["PTVSD_LOG_DIR"] = str(tmpdir)
session.configure(run_as, code_to_debug)
session.start_debugging()
session.stop_debugging()
def test_log_api(pyfile, tmpdir, run_as):
@pytest.mark.parametrize("start_method", [start_methods.CustomServer])
def test_log_api(pyfile, tmpdir, start_method, run_as):
@pyfile
def code_to_debug():
from debug_me import backchannel, ptvsd
@ -49,7 +49,7 @@ def test_log_api(pyfile, tmpdir, run_as):
ptvsd.wait_for_attach()
log_dir = compat.filename(tmpdir)
with debug.Session("custom_server", backchannel=True) as session:
with debug.Session(start_method, backchannel=True) as session:
backchannel = session.backchannel
@session.before_connect
@ -59,4 +59,3 @@ def test_log_api(pyfile, tmpdir, run_as):
with check_logs(tmpdir, session):
session.configure(run_as, code_to_debug)
session.start_debugging()
session.stop_debugging()

View file

@ -132,11 +132,7 @@ def test_multiprocessing(pyfile, start_method, run_as):
parent_backchannel.send("continue")
grandchild_session.stop_debugging()
child_session.stop_debugging()
assert parent_backchannel.receive() == "done"
parent_session.stop_debugging()
assert parent_backchannel.receive() == "done"
@pytest.mark.timeout(30)
@ -170,11 +166,9 @@ def test_subprocess(pyfile, start_method, run_as):
)
process.wait()
with debug.Session(start_method) as parent_session:
parent_backchannel = parent_session.setup_backchannel()
parent_session.program_args += [child]
parent_session.debug_options |= {"Multiprocess"}
parent_session.configure(run_as, parent)
with debug.Session(start_method, backchannel=True) as parent_session:
parent_backchannel = parent_session.backchannel
parent_session.configure(run_as, parent, subProcess=True, args=[child])
parent_session.start_debugging()
root_start_request, = parent_session.all_occurrences_of(
@ -207,9 +201,6 @@ def test_subprocess(pyfile, start_method, run_as):
child_argv = parent_backchannel.receive()
assert child_argv == [child, "--arg1", "--arg2", "--arg3"]
child_session.wait_for_termination()
parent_session.stop_debugging()
@pytest.mark.timeout(30)
@pytest.mark.skipif(
@ -242,20 +233,24 @@ def test_autokill(pyfile, start_method, run_as):
)
backchannel.receive()
with debug.Session(start_method) as parent_session:
parent_backchannel = parent_session.setup_backchannel()
parent_session.program_args += [child]
parent_session.debug_options |= {"Multiprocess"}
parent_session.configure(run_as, parent)
with debug.Session(start_method, backchannel=True) as parent_session:
parent_backchannel = parent_session.backchannel
expected_exit_code = some.int if parent_session.start_method.method == "launch" else 0
parent_session.expected_exit_code = expected_exit_code
parent_session.configure(
run_as,
parent,
subProcess=True,
args=[child],
)
parent_session.start_debugging()
expected_exit_code = 0
with parent_session.attach_to_next_subprocess() as child_session:
child_session.start_debugging()
if parent_session.start_method.method == "launch":
# In launch scenario, terminate the parent process by disconnecting from it.
expected_exit_code = some.int
try:
parent_session.request("disconnect")
except messaging.NoMoreMessages:
@ -264,12 +259,8 @@ def test_autokill(pyfile, start_method, run_as):
parent_session.wait_for_disconnect()
else:
# In attach scenario, just let the parent process run to completion.
expected_exit_code = 0
parent_backchannel.send(None)
child_session.stop_debugging()
parent_session.stop_debugging(exitCode=expected_exit_code)
@pytest.mark.skipif(
sys.version_info < (3, 0) and (platform.system() != "Windows"), reason="Bug #935"
@ -327,5 +318,3 @@ def test_argv_quoting(pyfile, start_method, run_as):
expected_args = backchannel.receive()
actual_args = backchannel.receive()
assert expected_args == actual_args
session.stop_debugging()

View file

@ -28,12 +28,11 @@ def test_with_no_output(pyfile, start_method, run_as):
session.start_debugging()
session.wait_for_stop("breakpoint")
session.request_continue()
session.stop_debugging()
assert not session.output("stdout")
assert not session.output("stderr")
assert not session.captured_stdout()
assert not session.captured_stderr()
assert not session.output("stdout")
assert not session.output("stderr")
assert not session.captured_stdout()
assert not session.captured_stderr()
def test_with_tab_in_output(pyfile, start_method, run_as):
@ -52,9 +51,8 @@ def test_with_tab_in_output(pyfile, start_method, run_as):
session.start_debugging()
session.wait_for_stop()
session.request_continue()
session.stop_debugging()
assert session.output("stdout").startswith("Hello\tWorld")
assert session.output("stdout").startswith("Hello\tWorld")
@pytest.mark.parametrize("redirect", ["enabled", "disabled"])
@ -77,9 +75,8 @@ def test_redirect_output(pyfile, start_method, run_as, redirect):
session.wait_for_stop()
session.request_continue()
session.stop_debugging()
if redirect == "enabled":
assert session.output("stdout") == "111\n222\n333\n444\n"
else:
assert not session.output("stdout")
if redirect == "enabled":
assert session.output("stdout") == "111\n222\n333\n444\n"
else:
assert not session.output("stdout")

View file

@ -62,7 +62,6 @@ def test_client_ide_from_path_mapping_linux_backend(
)
session.request_continue()
session.stop_debugging()
def test_with_dot_remote_root(pyfile, long_tmpdir, start_method, run_as):
@ -107,7 +106,6 @@ def test_with_dot_remote_root(pyfile, long_tmpdir, start_method, run_as):
)
session.request_continue()
session.stop_debugging()
def test_with_path_mappings(pyfile, long_tmpdir, start_method, run_as):
@ -192,4 +190,3 @@ def test_with_path_mappings(pyfile, long_tmpdir, start_method, run_as):
assert "def call_me_back(callback):" in source["content"]
session.request_continue()
session.stop_debugging()

View file

@ -51,8 +51,6 @@ def test_run(pyfile, start_method, run_as):
some.str.matching(re.escape(expected_ptvsd_path) + r"(c|o)?")
)
session.stop_debugging()
def test_run_submodule():
with debug.Session("launch") as session:
@ -64,7 +62,6 @@ def test_run_submodule():
some.dict.containing({"category": "stdout", "output": "three"}),
)
)
session.stop_debugging()
@pytest.mark.parametrize("run_as", ["program", "module", "code"])
@ -89,13 +86,12 @@ def test_nodebug(pyfile, run_as):
backchannel.send(None)
# Breakpoint shouldn't be hit.
session.stop_debugging()
session.expect_realized(
Event(
"output", some.dict.containing({"category": "stdout", "output": "ok"})
)
session.expect_realized(
Event(
"output", some.dict.containing({"category": "stdout", "output": "ok"})
)
)
@pytest.mark.parametrize("run_as", ["script", "module"])
@ -127,4 +123,3 @@ def test_run_vs(pyfile, run_as):
session.start_debugging()
assert backchannel.receive() == "ok"
session.stop_debugging()

View file

@ -57,5 +57,3 @@ def test_set_expression(pyfile, start_method, run_as):
session.request_continue()
assert backchannel.receive() == 1000
session.stop_debugging()

View file

@ -35,9 +35,8 @@ def test_wait_on_normal_exit_enabled(pyfile, start_method, run_as):
session.request_continue()
session.process.stdin.write(b" \r\n")
session.stop_debugging()
assert any(s.startswith("Press") for s in session.stdout_lines("utf-8"))
assert any(s.startswith("Press") for s in session.stdout_lines("utf-8"))
@pytest.mark.parametrize("start_method", [start_methods.Launch])
@ -57,6 +56,7 @@ def test_wait_on_abnormal_exit_enabled(pyfile, start_method, run_as):
with debug.Session(start_method, backchannel=True) as session:
backchannel = session.backchannel
session.expected_exit_code = 12345
session.configure(
run_as, code_to_debug,
waitOnAbnormalExit=True,
@ -69,9 +69,8 @@ def test_wait_on_abnormal_exit_enabled(pyfile, start_method, run_as):
assert backchannel.receive() == "done"
session.process.stdin.write(b" \r\n")
session.stop_debugging(exitCode=12345)
assert any(s.startswith("Press") for s in session.stdout_lines("utf-8"))
assert any(s.startswith("Press") for s in session.stdout_lines("utf-8"))
@pytest.mark.parametrize("start_method", [start_methods.Launch])
@ -96,4 +95,3 @@ def test_exit_normally_with_wait_on_abnormal_exit_enabled(pyfile, start_method,
session.wait_for_termination()
assert backchannel.receive() == "done"
session.stop_debugging()

View file

@ -78,4 +78,3 @@ def test_set_next_statement(pyfile, start_method, run_as):
assert line == line_numbers["inner2"]
session.send_request("continue").wait_for_response()
session.stop_debugging()

View file

@ -43,8 +43,4 @@ def test_stop_on_entry(pyfile, run_as, breakpoint):
assert hit.frames[0]["source"]["path"] == some.path(code_to_debug)
session.request_continue()
session.wait_for_termination()
assert backchannel.receive() == "done"
session.stop_debugging()

View file

@ -50,7 +50,6 @@ def test_thread_count(pyfile, start_method, run_as, count):
assert len(resp_threads.body["threads"]) == count
session.request_continue()
session.stop_debugging()
@pytest.mark.skipif(
@ -110,4 +109,3 @@ def test_debug_this_thread(pyfile, start_method, run_as):
session.wait_for_stop()
session.request_continue()
session.stop_debugging()

View file

@ -27,7 +27,6 @@ def test_stack_format(pyfile, start_method, run_as, module, line):
print("break here") # @bp
with debug.Session(start_method) as session:
session.ignore_unobserved += [Event("stopped")]
session.configure(run_as, code_to_debug)
session.set_breakpoints(test_module, [test_module.lines["bp"]])
session.start_debugging()
@ -50,7 +49,6 @@ def test_stack_format(pyfile, start_method, run_as, module, line):
assert module == (frames[0]["name"].find("test_module") > -1)
session.request_continue()
session.stop_debugging()
def test_module_events(pyfile, start_method, run_as):
@ -74,7 +72,6 @@ def test_module_events(pyfile, start_method, run_as):
do_something()
with debug.Session(start_method) as session:
session.ignore_unobserved += [Event("stopped")]
session.configure(run_as, test_code)
session.set_breakpoints(module2, [module2.lines["bp"]])
session.start_debugging()
@ -91,4 +88,3 @@ def test_module_events(pyfile, start_method, run_as):
]
session.request_continue()
session.stop_debugging()

View file

@ -40,17 +40,16 @@ class DebugStartBase(object):
self.method = method
self.captured_output = helpers.CapturedOutput(self.session)
self.debuggee_process = None
def configure(self, run_as, target, **kwargs):
pass
self.expected_exit_code = None
def start_debugging(self, **kwargs):
pass
def wait_for_debuggee(self, exit_code):
if exit_code is not None:
def wait_for_debuggee(self):
# TODO: Exit should not be restricted to launch tests only
if self.expected_exit_code is not None and 'launch' in self.method:
exited = self.session.wait_for_next_event("exited", freeze=False)
assert exited == some.dict.containing({"exitCode": exit_code})
assert exited == some.dict.containing({"exitCode": self.expected_exit_code})
self.session.wait_for_next_event("terminated")
@ -274,9 +273,6 @@ class Launch(DebugStartBase):
self._launch_request.wait_for_response(freeze=False)
self._wait_for_process_event()
def wait_for_debuggee(self, exit_code=0):
super(Launch, self).wait_for_debuggee(exit_code)
def run_in_terminal(self, request):
args = request("args", json.array(unicode))
cwd = request("cwd", unicode)
@ -503,9 +499,10 @@ class AttachSocketCmdLine(AttachBase):
pythonPath=sys.executable,
args=[],
cwd=None,
env=os.environ.copy(),
env=None,
**kwargs
):
env = {} if env is None else dict(env)
self._attach_args = self._build_attach_args({}, run_as, target, **kwargs)
cli_args = [pythonPath]