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

Commit

Permalink
System Tests for unhandled exceptions (#669)
Browse files Browse the repository at this point in the history
* tests for unhandled exceptions

* Test source and fix linter issues
  • Loading branch information
DonJayamanne authored and karthiknadig committed Jul 23, 2018
1 parent bf83758 commit 501d163
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
print('one')
raise ArithmeticError('Hello')
print('two')
192 changes: 156 additions & 36 deletions tests/system_tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,27 @@
from tests.helpers.debugsession import Awaitable
from tests.helpers.resource import TestResources
from . import (
_strip_newline_output_events, lifecycle_handshake,
LifecycleTestsBase, DebugInfo, PORT,
_strip_newline_output_events,
lifecycle_handshake,
LifecycleTestsBase,
DebugInfo,
PORT,
)


TEST_FILES = TestResources.from_module(__name__)


class ExceptionTests(LifecycleTestsBase):

def run_test_not_breaking_into_handled_exceptions(self, debug_info):
excbreakpoints = [{'filters': ['uncaught']}]
options = {'debugOptions': ['RedirectOutput']}

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

received = list(_strip_newline_output_events(dbg.session.received))
self.assert_contains(received, [
Expand All @@ -32,17 +34,44 @@ def run_test_not_breaking_into_handled_exceptions(self, debug_info):
self.new_event('terminated'),
])

def run_test_breaking_into_handled_exceptions(self, debug_info):
excbreakpoints = [{'filters': ['raised', 'uncaught']}]
def run_test_not_breaking_into_unhandled_exceptions(self, debug_info):
excbreakpoints = [{'filters': []}]
options = {'debugOptions': ['RedirectOutput']}

with self.start_debugging(debug_info) as dbg:
lifecycle_handshake(
dbg.session,
debug_info.starttype,
excbreakpoints=excbreakpoints,
options=options)

received = list(_strip_newline_output_events(dbg.session.received))
self.assertEqual(
len(self.find_events(received, 'output', {'category': 'stdout'})),
1)
std_errs = self.find_events(received, 'output', {'category': 'stderr'})
self.assertGreaterEqual(len(std_errs), 1)
std_err_msg = ''.join([msg.body['output'] for msg in std_errs])
self.assertIn('ArithmeticError: Hello', std_err_msg)
self.assert_contains(received, [
self.new_event('output', category='stdout', output='one'),
self.new_event('exited', exitCode=0),
self.new_event('terminated'),
])

def run_test_breaking_into_handled_exceptions(self, debug_info,
expected_source_name):
excbreakpoints = [{'filters': ['raised']}]
options = {'debugOptions': ['RedirectOutput']}

with self.start_debugging(debug_info) as dbg:
stopped = dbg.session.get_awaiter_for_event('stopped')
(_, req_launch_attach, _, _, _, _
) = lifecycle_handshake(dbg.session, debug_info.starttype,
excbreakpoints=excbreakpoints,
options=options,
threads=True)
(_, req_launch_attach, _, _, _, _) = lifecycle_handshake(
dbg.session,
debug_info.starttype,
excbreakpoints=excbreakpoints,
options=options,
threads=True)

Awaitable.wait_all(req_launch_attach, stopped)
self.assertEqual(stopped.event.body['text'], 'ArithmeticError')
Expand All @@ -57,14 +86,15 @@ def run_test_breaking_into_handled_exceptions(self, debug_info):
req_exc_info.wait()
exc_info = req_exc_info.resp.body

self.assert_is_subset(exc_info, {
'exceptionId': 'ArithmeticError',
'breakMode': 'always',
'details': {
'typeName': 'ArithmeticError',
# 'source': debug_info.filename
}
})
self.assert_is_subset(
exc_info, {
'exceptionId': 'ArithmeticError',
'breakMode': 'always',
'details': {
'typeName': 'ArithmeticError',
'source': expected_source_name
}
})

continued = dbg.session.get_awaiter_for_event('continued')
dbg.session.send_request(
Expand All @@ -81,30 +111,101 @@ def run_test_breaking_into_handled_exceptions(self, debug_info):
self.new_event('terminated'),
])

def run_test_breaking_into_unhandled_exceptions(self, debug_info,
expected_source_name):
excbreakpoints = [{'filters': ['uncaught']}]
options = {'debugOptions': ['RedirectOutput']}

with self.start_debugging(debug_info) as dbg:
stopped = dbg.session.get_awaiter_for_event('stopped')
(_, req_launch_attach, _, _, _, _) = lifecycle_handshake(
dbg.session,
debug_info.starttype,
excbreakpoints=excbreakpoints,
options=options,
threads=True)

Awaitable.wait_all(req_launch_attach, stopped)
self.assertEqual(stopped.event.body['text'], 'ArithmeticError')
self.assertIn("ArithmeticError('Hello'",
stopped.event.body['description'])

thread_id = stopped.event.body['threadId']
req_exc_info = dbg.session.send_request(
'exceptionInfo',
threadId=thread_id,
)
req_exc_info.wait()
exc_info = req_exc_info.resp.body

self.assert_is_subset(
exc_info, {
'exceptionId': 'ArithmeticError',
'breakMode': 'unhandled',
'details': {
'typeName': 'ArithmeticError',
'source': expected_source_name
}
})

continued = dbg.session.get_awaiter_for_event('continued')
dbg.session.send_request(
'continue',
threadId=thread_id,
).wait()
Awaitable.wait_all(continued)

received = list(_strip_newline_output_events(dbg.session.received))
self.assertEqual(
len(self.find_events(received, 'output', {'category': 'stdout'})),
1)
std_errs = self.find_events(received, 'output', {'category': 'stderr'})
self.assertGreaterEqual(len(std_errs), 1)
std_err_msg = ''.join([msg.body['output'] for msg in std_errs])
self.assertIn('ArithmeticError: Hello', std_err_msg)
self.assert_contains(received, [
self.new_event('continued', threadId=thread_id),
self.new_event('output', category='stdout', output='one'),
self.new_event('exited', exitCode=0),
self.new_event('terminated'),
])

class LaunchFileTests(ExceptionTests):

class LaunchFileTests(ExceptionTests):
def test_not_breaking_into_handled_exceptions(self):
filename = TEST_FILES.resolve('handled_exceptions_launch.py')
cwd = os.path.dirname(filename)
self.run_test_not_breaking_into_handled_exceptions(
DebugInfo(filename=filename, cwd=cwd))

def test_not_breaking_into_unhandled_exceptions(self):
filename = TEST_FILES.resolve('unhandled_exceptions_launch.py')
cwd = os.path.dirname(filename)
self.run_test_not_breaking_into_unhandled_exceptions(
DebugInfo(filename=filename, cwd=cwd))

def test_breaking_into_handled_exceptions(self):
filename = TEST_FILES.resolve('handled_exceptions_launch.py')
cwd = os.path.dirname(filename)
self.run_test_breaking_into_handled_exceptions(
DebugInfo(filename=filename, cwd=cwd))
DebugInfo(filename=filename, cwd=cwd), filename)

@unittest.skip('Issue #653')
def test_breaking_into_unhandled_exceptions(self):
filename = TEST_FILES.resolve('unhandled_exceptions_launch.py')
cwd = os.path.dirname(filename)
self.run_test_breaking_into_unhandled_exceptions(
DebugInfo(filename=filename, cwd=cwd), filename)

class LaunchModuleExceptionLifecycleTests(ExceptionTests):

class LaunchModuleExceptionLifecycleTests(ExceptionTests):
def test_breaking_into_handled_exceptions(self):
module_name = 'mypkg_launch1'
env = TEST_FILES.env_with_py_path()
cwd = TEST_FILES.parent.root
self.run_test_breaking_into_handled_exceptions(
DebugInfo(modulename=module_name, env=env, cwd=cwd))
DebugInfo(modulename=module_name, env=env, cwd=cwd),
os.path.join(TEST_FILES.root, module_name, '__init__.py'))

def test_not_breaking_into_handled_exceptions(self):
module_name = 'mypkg_launch1'
Expand All @@ -115,12 +216,23 @@ def test_not_breaking_into_handled_exceptions(self):


class ServerAttachExceptionLifecycleTests(ExceptionTests):

def test_breaking_into_handled_exceptions(self):
filename = TEST_FILES.resolve('handled_exceptions_launch.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
self.run_test_breaking_into_handled_exceptions(
DebugInfo(
filename=filename,
cwd=cwd,
starttype='attach',
argv=argv,
), filename)

def test_not_breaking_into_unhandled_exceptions(self):
filename = TEST_FILES.resolve('unhandled_exceptions_launch.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
self.run_test_not_breaking_into_unhandled_exceptions(
DebugInfo(
filename=filename,
cwd=cwd,
Expand All @@ -140,9 +252,20 @@ def test_not_breaking_into_handled_exceptions(self):
argv=argv,
))

def test_breaking_into_unhandled_exceptions(self):
filename = TEST_FILES.resolve('unhandled_exceptions_launch.py')
cwd = os.path.dirname(filename)
argv = ['localhost', str(PORT)]
self.run_test_breaking_into_unhandled_exceptions(
DebugInfo(
filename=filename,
cwd=cwd,
starttype='attach',
argv=argv,
), filename)

class PTVSDAttachExceptionLifecycleTests(ExceptionTests):

class PTVSDAttachExceptionLifecycleTests(ExceptionTests):
def test_breaking_into_handled_exceptions(self):
filename = TEST_FILES.resolve('handled_exceptions_attach.py')
cwd = os.path.dirname(filename)
Expand All @@ -154,9 +277,9 @@ def test_breaking_into_handled_exceptions(self):
cwd=cwd,
starttype='attach',
argv=argv,
))
), filename)

@unittest.skip('Needs fixing in #609')
@unittest.skip('Needs fixing in #609, #580')
def test_not_breaking_into_handled_exceptions(self):
filename = TEST_FILES.resolve('handled_exceptions_attach.py')
cwd = os.path.dirname(filename)
Expand All @@ -172,7 +295,6 @@ def test_not_breaking_into_handled_exceptions(self):


class ServerAttachModuleExceptionLifecycleTests(ExceptionTests):

def test_breaking_into_handled_exceptions(self):
module_name = 'mypkg_launch1'
env = TEST_FILES.env_with_py_path()
Expand All @@ -185,7 +307,7 @@ def test_breaking_into_handled_exceptions(self):
cwd=cwd,
argv=argv,
starttype='attach',
))
), os.path.join(TEST_FILES.root, module_name, '__init__.py'))

def test_not_breaking_into_handled_exceptions(self):
module_name = 'mypkg_launch1'
Expand All @@ -202,9 +324,7 @@ def test_not_breaking_into_handled_exceptions(self):
))


@unittest.skip('Needs fixing')
class PTVSDAttachModuleExceptionLifecycleTests(ExceptionTests):

def test_breaking_into_handled_exceptions(self):
module_name = 'mypkg_attach1'
env = TEST_FILES.env_with_py_path()
Expand All @@ -218,7 +338,7 @@ def test_breaking_into_handled_exceptions(self):
argv=argv,
attachtype='import',
starttype='attach',
))
), os.path.join(TEST_FILES.root, module_name, '__init__.py'))

def test_not_breaking_into_handled_exceptions(self):
module_name = 'mypkg_attach1'
Expand Down

0 comments on commit 501d163

Please sign in to comment.