Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Commit

Permalink
Merged master
Browse files Browse the repository at this point in the history
  • Loading branch information
DonJayamanne committed Jul 10, 2018
1 parent 5daaf90 commit ef49dd1
Show file tree
Hide file tree
Showing 30 changed files with 217 additions and 18 deletions.
7 changes: 7 additions & 0 deletions tests/helpers/debugadapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@
]


try:
ConnectionRefusedError
except Exception:
class ConnectionRefusedError(Exception):
pass


def _copy_env(verbose=False, env=None):
variables = {k: v for k, v in os.environ.items() if k in COPIED_ENV}
# TODO: Be smarter about the seed?
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import mypkg_bar.bar


def do_foo():
mypkg_bar.bar.do_bar()


do_foo()
11 changes: 11 additions & 0 deletions tests/resources/system_tests/test_forever/attach_forever.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ptvsd
import sys
import time

ptvsd.enable_attach((sys.argv[1], sys.argv[2]))

i = 0
while True:
time.sleep(0.1)
print(i)
i += 1
38 changes: 31 additions & 7 deletions tests/system_tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import os
import ptvsd
import signal
import sys
import time
import traceback
import unittest

from collections import namedtuple
Expand Down Expand Up @@ -234,24 +236,46 @@ def _kill_proc(pid):
pass
time.sleep(1) # wait for socket connections to die out.

def _wrap_and_reraise(ex, session):
def _wrap_and_reraise(session, ex, exc_type, exc_value, exc_traceback):
"""If we have connetion errors, then re-raised wrapped in
ConnectionTimeoutError. If using py3, then chain exceptions so
we do not loose the original exception, else try hack approach
for py27."""
messages = []
formatted_ex = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)) # noqa
try:
messages = [str(msg) for msg in
_strip_newline_output_events(session.received)]
except Exception:
pass

messages = os.linesep.join(messages)
fmt = {
"sep": os.linesep,
"messages": os.linesep.join(messages),
"error": ''.join(traceback.format_exception_only(exc_type, exc_value)) # noqa
}
message = """
Session Messages:
-----------------
%(messages)s
Original Error:
---------------
%(error)s""" % fmt

try:
raise Exception(messages) from ex
except Exception:
print(messages)
raise ex
# Chain the original exception for py3.
exec('raise Exception(message) from ex', globals(), locals())
except SyntaxError:
# This happens when using py27.
message = message + os.linesep + formatted_ex
exec("raise Exception(message)", globals(), locals())

def _handle_exception(ex, adapter, session):
exc_type, exc_value, exc_traceback = sys.exc_info()
_kill_proc(adapter.pid)
_wrap_and_reraise(ex, session)
_wrap_and_reraise(session, ex, exc_type, exc_value, exc_traceback)

if debug_info.attachtype == 'import' and \
debug_info.modulename is not None:
Expand Down
163 changes: 160 additions & 3 deletions tests/system_tests/test_remote.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import os.path
import time

from tests.helpers.resource import TestResources
from tests.helpers.socket import resolve_hostname
Expand Down Expand Up @@ -28,6 +29,39 @@ def run_test_attach(self, debug_info):
self.new_event('output', category='stderr', output='no'),
])

def run_test_source_references(self,
debug_info,
expected_stacktrace,
path_mappings=[],
debug_options=[]):
options = {
"debugOptions": ["RedirectOutput"] + debug_options,
"pathMappings": path_mappings
}

with self.start_debugging(debug_info) as dbg:
(_, req_attach, _, _, _, req_threads) = lifecycle_handshake(
dbg.session,
debug_info.starttype,
options=options,
threads=True)

# wait till we enter the for loop.
time.sleep(1)
Awaitable.wait_all(req_attach, req_threads)
with dbg.session.wait_for_event("stopped") as result:
dbg.session.send_request('pause')
sdf
tid = result["msg"].body["threadId"]
stacktrace = dbg.session.send_request("stackTrace", threadId=tid)
stacktrace.wait()
dbg.session.send_request("continue", threadId=tid).wait()

# Kill remove program.
os.kill(dbg.adapter.pid, signal.SIGKILL)

self.assert_is_subset(stacktrace.resp, expected_stacktrace)


class AttachFileTests(RemoteTests):

Expand Down Expand Up @@ -86,6 +120,129 @@ def test_attach_byip(self):
host=ip,
cwd=cwd,
starttype='attach',
argv=argv,
),
)
argv=argv))

def test_source_references_should_be_returned_without_path_mappings(self):
filename = os.path.join(TEST_FORVER_FILES_DIR, 'attach_forever.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
expected_stacktrace = {
"stackFrames": [{
"source": {
"path": filename,
"sourceReference": 1
}
}],
}
self.run_test_source_references(
DebugInfo(
filename=filename,
attachtype='import',
cwd=cwd,
starttype='attach',
argv=argv), expected_stacktrace)

def test_source_references_should_not_be_returned_with_path_mappings(self):
filename = os.path.join(TEST_FORVER_FILES_DIR, 'attach_forever.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
path_mappings = [{
"localRoot": os.path.dirname(filename),
"remoteRoot": os.path.dirname(filename)
}]
expected_stacktrace = {
"stackFrames": [{
"source": {
"path": filename,
"sourceReference": 0
}
}],
}
self.run_test_source_references(
DebugInfo(
filename=filename,
attachtype='import',
cwd=cwd,
starttype='attach',
argv=argv), expected_stacktrace, path_mappings)

def test_source_references_should_be_returned_with_invalid_path_mappings(
self):
filename = os.path.join(TEST_FORVER_FILES_DIR, 'attach_forever.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
path_mappings = [{
"localRoot": TEST_FILES_DIR,
"remoteRoot": TEST_FILES_DIR
}]
expected_stacktrace = {
"stackFrames": [{
"source": {
"path": filename,
"sourceReference": 1
}
}],
}
self.run_test_source_references(
DebugInfo(
filename=filename,
attachtype='import',
cwd=cwd,
starttype='attach',
argv=argv), expected_stacktrace, path_mappings)

def test_source_references_should_be_returned_with_win_client(self):
filename = os.path.join(TEST_FORVER_FILES_DIR, 'attach_forever.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
client_dir = 'C:\\Development\\Projects\\src\\sub dir'
path_mappings = [{
"localRoot": client_dir,
"remoteRoot": os.path.dirname(filename)
}]
expected_stacktrace = {
"stackFrames": [{
"source": {
"path": client_dir + '\\' + os.path.basename(filename),
"sourceReference": 0
}
}],
}
self.run_test_source_references(
DebugInfo(
filename=filename,
attachtype='import',
cwd=cwd,
starttype='attach',
argv=argv),
expected_stacktrace,
path_mappings=path_mappings,
debug_options=['WindowsClient'])

@unittest.skipIf(sys.platform == 'win32', 'Run only on Unix clients')
def test_source_references_should_be_returned_with_unix_client(self):
filename = os.path.join(TEST_FORVER_FILES_DIR, 'attach_forever.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
client_dir = '/Users/PeterSmith/projects/src/sub dir'
path_mappings = [{
"localRoot": client_dir,
"remoteRoot": os.path.dirname(filename)
}]
expected_stacktrace = {
"stackFrames": [{
"source": {
"path": client_dir + '/' + os.path.basename(filename),
"sourceReference": 0
}
}],
}
self.run_test_source_references(
DebugInfo(
filename=filename,
attachtype='import',
cwd=cwd,
starttype='attach',
argv=argv),
expected_stacktrace,
path_mappings=path_mappings)

0 comments on commit ef49dd1

Please sign in to comment.