def test_from_raw(self): serverlocal = Address.as_server('localhost', 9876) serverremote = Address.as_server('1.2.3.4', 9876) clientlocal = Address.as_client('localhost', 9876) clientremote = Address.as_client('1.2.3.4', 9876) default = Address(None, 1111) external = Address('', 1111) values = [ (serverlocal, serverlocal), (serverremote, serverremote), (clientlocal, clientlocal), (clientremote, clientremote), (None, default), ('', external), ([], default), ({}, default), (9876, serverlocal), ('localhost:9876', clientlocal), ('1.2.3.4:9876', clientremote), ('*:9876', Address.as_server('', 9876)), ('*', external), (':9876', Address.as_server('', 9876)), ('localhost', Address('localhost', 1111)), (':', external), (dict(host='localhost'), Address('localhost', 1111)), (dict(port=9876), serverlocal), (dict(host=None, port=9876), serverlocal), (dict(host='localhost', port=9876), clientlocal), (dict(host='localhost', port='9876'), clientlocal), ] for value, expected in values: addr = Address.from_raw(value, defaultport=1111) assert addr == expected
def test_server(self): addr = Address.as_server('10.0.1.1', 8888) run_module(addr, 'spam', _run=self._run, _prog='eggs') self.assertEqual(self.argv, _get_args('--module', '--file', 'spam:')) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {})
def test_nodebug_module_no_args(self): addr = Address.as_server('10.0.1.1', 8888) run_main(addr, 'spam.py', 'module', _runner=self._no_debug_runner) self.assertEqual(self.argv, ['spam.py']) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertTrue(self.is_module) self.assertEqual(self.args, ()) self.assertEqual(self.kwargs, {})
def _parse_args(prog, argv): parser = argparse.ArgumentParser( prog=prog, usage=USAGE.format(prog), ) parser.add_argument('--nodebug', action='store_true') host = parser.add_mutually_exclusive_group() host.add_argument('--host') host.add_argument('--server-host') parser.add_argument('--port', type=int, required=True) target = parser.add_mutually_exclusive_group(required=True) target.add_argument('-m', dest='module') target.add_argument('--pid', type=int) target.add_argument('filename', nargs='?') parser.add_argument('--single-session', action='store_true') parser.add_argument('--wait', action='store_true') parser.add_argument('-V', '--version', action='version') parser.version = __version__ args = parser.parse_args(argv) ns = vars(args) serverhost = ns.pop('server_host', None) clienthost = ns.pop('host', None) if serverhost: args.address = Address.as_server(serverhost, ns.pop('port')) elif not clienthost: if args.nodebug: args.address = Address.as_client(clienthost, ns.pop('port')) else: args.address = Address.as_server(clienthost, ns.pop('port')) else: args.address = Address.as_client(clienthost, ns.pop('port')) pid = ns.pop('pid') module = ns.pop('module') filename = ns.pop('filename') if pid is not None: args.name = pid args.kind = 'pid' elif module is not None: args.name = module args.kind = 'module' else: args.name = filename args.kind = 'script' return args
def test_as_server_bad_port(self): port = None for host in [None, '', 'localhost', '1.2.3.4']: with self.subTest((host, port)): with self.assertRaises(TypeError): Address.as_server(host, port) for port in ['', -1, 65536]: for host in [None, '', 'localhost', '1.2.3.4']: with self.subTest((host, port)): with self.assertRaises(ValueError): Address.as_server(host, port)
def test_extra(self): args, extra = parse_args([ 'eggs', '--DEBUG', '--port', '8888', '--vm_type', '???', 'spam.py', '--xyz', '123', 'abc', '--cmd-line', '--', 'foo', '--server', '--bar' ]) self.assertEqual( vars(args), { 'kind': 'script', 'name': 'spam.py', 'address': Address.as_server(None, 8888), 'nodebug': False, 'single_session': False, 'wait': False, }) self.assertEqual( extra, [ '--DEBUG', '--vm_type', '???', '--', # Expected pydevd defaults separator '--xyz', '123', 'abc', '--cmd-line', 'foo', '--server', '--bar', ])
def start_for_attach(cls, addr, *args, **kwargs): srvtimeout = kwargs.pop('srvtimeout', SERVER_READY_TIMEOUT) addr = Address.as_server(*addr) adapter = cls._start_as(addr, *args, server=True, **kwargs) if srvtimeout is not None: wait_for_socket_server(addr, timeout=srvtimeout) return adapter
def test_as_server_public_host(self): addr = Address.as_server('', 9786) self.assertEqual( addr, Address('', 9786, isserver=True), )
def test_as_server_default_host(self): addr = Address.as_server(None, 9786) self.assertEqual( addr, Address('localhost', 9786, isserver=True), )
def enable_attach(address, on_attach=(lambda: None), redirect_output=True, _pydevd=pydevd, _install=install, _settrace=_pydevd_settrace, **kwargs): addr = Address.as_server(*address) debug('installing ptvsd as server') # pydevd.settrace() forces a "client" connection, so we trick it # by setting start_client to start_server.. daemon = _install(_pydevd, addr, start_client=start_server, notify_session_debugger_ready=(lambda s: on_attach()), singlesession=False, **kwargs) def start_pydevd(): debug('enabling pydevd') # Only pass the port so start_server() gets triggered. # As noted above, we also have to trick settrace() because it # *always* forces a client connection. _settrace( stdoutToServer=redirect_output, stderrToServer=redirect_output, port=addr.port, suspend=False, _pydevd=_pydevd, ) debug('pydevd enabled') t = new_hidden_thread('start-pydevd', start_pydevd) t.start() def wait(timeout=None): t.join(timeout) return not t.is_alive() def debug_current_thread(suspend=False, **kwargs): # Make sure that pydevd has finished starting before enabling # in the current thread. t.join() debug('enabling pydevd (current thread)') _settrace( host=None, # ignored stdoutToServer=False, # ignored stderrToServer=False, # ignored port=None, # ignored suspend=suspend, trace_only_current_thread=True, overwrite_prev_trace=True, patch_multiprocessing=False, _pydevd=_pydevd, **kwargs) debug('pydevd enabled (current thread)') return daemon, wait, debug_current_thread
def test_executable(self): addr = (None, 8888) run_file(addr, 'spam.py', _run=self._run) self.assertEqual(self.argv, _get_args('--file', 'spam.py', prog=sys.argv[0])) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {})
def test_local(self): addr = (None, 8888) run_file(addr, 'spam.py', _run=self._run, _prog='eggs') self.assertEqual(self.argv, _get_args('--file', 'spam.py')) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {})
def test_as_server_valid_address(self): for host in ['localhost', '127.0.0.1', '::', '1.2.3.4']: with self.subTest(host): addr = Address.as_server(host, 9786) self.assertEqual( addr, Address(host, 9786, isserver=True), )
def _parse_args(prog, argv): parser = argparse.ArgumentParser( prog=prog, usage=USAGE.format(prog), ) parser.add_argument('--nodebug', action='store_true') host = parser.add_mutually_exclusive_group() host.add_argument('--host') host.add_argument('--server-host') parser.add_argument('--port', type=int, required=True) target = parser.add_mutually_exclusive_group(required=True) target.add_argument('-m', dest='module') target.add_argument('filename', nargs='?') args = parser.parse_args(argv) ns = vars(args) serverhost = ns.pop('server_host', None) clienthost = ns.pop('host', None) if serverhost: args.address = Address.as_server(serverhost, ns.pop('port')) elif not clienthost: if args.nodebug: args.address = Address.as_client(clienthost, ns.pop('port')) else: args.address = Address.as_server(clienthost, ns.pop('port')) else: args.address = Address.as_client(clienthost, ns.pop('port')) module = ns.pop('module') filename = ns.pop('filename') if module is None: args.name = filename args.kind = 'script' else: args.name = module args.kind = 'module' #if argv[-1] != args.name or (module and argv[-1] != '-m'): # parser.error('script/module must be last arg') return args
def test_extra(self): addr = (None, 8888) run_module(addr, 'spam', '--vm_type', 'xyz', '--', '--DEBUG', _run=self._run, _prog='eggs') self.assertEqual(self.argv, _get_args( '--module', '--file', 'spam:', '--DEBUG', ptvsd_extras=['--vm_type', 'xyz'])) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {})
def test_nodebug_module_args(self): addr = (None, 8888) args = ('--one', '--two', '--three') run_main(addr, 'spam.py', 'module', *args, _runner=self._no_debug_runner) self.assertEqual(self.argv, ['spam.py'] + list(args)) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertTrue(self.is_module) self.assertEqual(self.args, args) self.assertEqual(self.kwargs, {})
def test_run(self): pydevd = FakePyDevd('pydevd/pydevd.py', self._main) addr = (None, 8888) run_file(addr, 'spam.py', _pydevd=pydevd, _install=self._install) self.assertEqual(self.pydevd, pydevd) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {}) self.assertEqual(self.maincalls, 1) self.assertEqual(sys.argv, _get_args('--file', 'spam.py', prog=sys.argv[0])) self.assertEqual(self.exitcode, -1)
def start_embedded(cls, addr, filename, argv=[], **kwargs): # ptvsd.enable_attach() slows things down, so we must wait longer. srvtimeout = kwargs.pop('srvtimeout', SERVER_READY_TIMEOUT + 2) addr = Address.as_server(*addr) with open(filename, 'r+') as scriptfile: content = scriptfile.read() # TODO: Handle this case somehow? assert 'ptvsd.enable_attach' in content adapter = cls.start_wrapper_script( filename, argv=argv, addr=addr, **kwargs) if srvtimeout is not None: wait_for_socket_server(addr, timeout=srvtimeout) return adapter
def test_exit(self): self.mainexc = SystemExit(1) pydevd = FakePyDevd('pydevd/pydevd.py', self._main) addr = (None, 8888) with self.assertRaises(SystemExit): run_file(addr, 'spam.py', _pydevd=pydevd, _install=self._install) self.assertEqual(self.pydevd, pydevd) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {}) self.assertEqual(self.maincalls, 1) self.assertEqual(sys.argv, _get_args('--file', 'spam.py', prog=sys.argv[0])) self.assertEqual(self.exitcode, 1)
def test_failure(self): self.mainexc = RuntimeError('boom!') pydevd = FakePyDevd('pydevd/pydevd.py', self._main) addr = (None, 8888) with self.assertRaises(RuntimeError) as cm: run_file(addr, 'spam.py', _pydevd=pydevd, _install=self._install) exc = cm.exception self.assertEqual(self.pydevd, pydevd) self.assertEqual(self.addr, Address.as_server(*addr)) self.assertEqual(self.kwargs, {}) self.assertEqual(self.maincalls, 1) self.assertEqual(sys.argv, _get_args('--file', 'spam.py', prog=sys.argv[0])) self.assertEqual(self.exitcode, -1) # TODO: Is this right? self.assertIs(exc, self.mainexc)
def test_module(self): args, extra = parse_args([ 'eggs', '--port', '8888', '-m', 'spam', ]) self.assertEqual(vars(args), { 'kind': 'module', 'name': 'spam', 'address': Address.as_server(None, 8888), 'nodebug': False, 'single_session': False, 'wait': False, 'multiprocess': False, }) self.assertEqual(extra, self.EXPECTED_EXTRA)
def test_script(self): args, extra = parse_args([ 'eggs', '--port', '8888', 'spam.py', ]) self.assertEqual( vars(args), { 'kind': 'script', 'name': 'spam.py', 'address': Address.as_server(None, 8888), 'nodebug': False, 'single_session': False, }) self.assertEqual(extra, self.EXPECTED_EXTRA)
def test_script_server(self): args, extra = parse_args([ 'eggs', '--server-host', '10.0.1.1', '--port', '8888', 'spam.py', ]) self.assertEqual(vars(args), { 'kind': 'script', 'name': 'spam.py', 'address': Address.as_server('10.0.1.1', 8888), 'nodebug': False, 'single_session': False, 'wait': False, 'multiprocess': False, }) self.assertEqual(extra, self.EXPECTED_EXTRA)
def test_pseudo_backward_compatibility(self): args, extra = parse_args([ 'eggs', '--port', '8888', '--module', '--file', 'spam', ]) self.assertEqual(vars(args), { 'kind': 'script', 'name': 'spam', 'address': Address.as_server(None, 8888), 'nodebug': False, 'single_session': False, 'wait': False, 'multiprocess': False, }) self.assertEqual(extra, ['--module'] + self.EXPECTED_EXTRA)
def test_script_server(): args, extra = parse_args([ 'eggs', '--host', '10.0.1.1', '--port', '8888', 'spam.py', ]) assert vars(args) == { 'kind': 'script', 'name': 'spam.py', 'address': Address.as_server('10.0.1.1', 8888), 'nodebug': False, 'single_session': False, 'wait': False, 'multiprocess': False, } assert extra == EXPECTED_EXTRA
def test_remote_single_session(self): args, extra = parse_args([ 'eggs', '--single-session', '--port', '8888', 'spam.py', ]) self.assertEqual( vars(args), { 'kind': 'script', 'name': 'spam.py', 'address': Address.as_server('localhost', 8888), 'nodebug': False, 'single_session': True, 'wait': False, }) self.assertEqual(extra, self.EXPECTED_EXTRA)
def test_pseudo_backward_compatibility(): args, extra = parse_args([ 'eggs', '--host', 'localhost', '--port', '8888', '--module', '--file', 'spam', ]) assert vars(args) == { 'kind': 'script', 'name': 'spam', 'address': Address.as_server('localhost', 8888), 'nodebug': False, 'single_session': False, 'wait': False, 'multiprocess': False, } assert extra == ['--module'] + EXPECTED_EXTRA
def test_extra(): args, extra = parse_args([ 'eggs', '--DEBUG', '--host', 'localhost', '--port', '8888', '--vm_type', '???', 'spam.py', '--xyz', '123', 'abc', '--cmd-line', '--', 'foo', '--server', '--bar' ]) assert vars(args) == { 'kind': 'script', 'name': 'spam.py', 'address': Address.as_server('localhost', 8888), 'nodebug': False, 'single_session': False, 'wait': False, 'multiprocess': False, } assert extra == [ '--DEBUG', '--vm_type', '???', '--', # Expected pydevd defaults separator '--xyz', '123', 'abc', '--cmd-line', 'foo', '--server', '--bar', ]
def enable_attach(address, on_attach=(lambda: None), redirect_output=True, _pydevd=pydevd, _install=install, **kwargs): addr = Address.as_server(*address) # pydevd.settrace() forces a "client" connection, so we trick it # by setting start_client to start_server.. daemon = _install(_pydevd, addr, start_client=start_server, notify_session_debugger_ready=(lambda s: on_attach()), singlesession=False, **kwargs) # Only pass the port so start_server() gets triggered. _pydevd.settrace( host=addr.host, stdoutToServer=redirect_output, stderrToServer=redirect_output, port=addr.port, suspend=False, ) return daemon
def start_as_server(cls, addr, *args, **kwargs): addr = Address.as_server(*addr) return cls._start_as(addr, *args, server=False, **kwargs)