Esempio n. 1
0
def load_debugger(secret, port, debugger_search_path, mixed_mode):
    # Load the debugger package
    try:
        if debugger_search_path:
            sys.path.insert(0, debugger_search_path)

        if secret and port:
            # Start tests with legacy debugger
            import ptvsd
            from ptvsd.debugger import DONT_DEBUG, DEBUG_ENTRYPOINTS, get_code
            from ptvsd import enable_attach, wait_for_attach

            DONT_DEBUG.append(os.path.normcase(__file__))
            DEBUG_ENTRYPOINTS.add(get_code(main))
            enable_attach(secret, ('127.0.0.1', port), redirect_output=True)
            wait_for_attach()
        elif port:
            # Start tests with new debugger
            from ptvsd import enable_attach, wait_for_attach

            enable_attach(('127.0.0.1', port))
            wait_for_attach()
        elif mixed_mode:
            # For mixed-mode attach, there's no ptvsd and hence no wait_for_attach(),
            # so we have to use Win32 API in a loop to do the same thing.
            from time import sleep
            from ctypes import windll, c_char
            while True:
                if windll.kernel32.IsDebuggerPresent() != 0:
                    break
                sleep(0.1)
            try:
                debugger_helper = windll[
                    'Microsoft.PythonTools.Debugger.Helper.x86.dll']
            except WindowsError:
                debugger_helper = windll[
                    'Microsoft.PythonTools.Debugger.Helper.x64.dll']
            isTracing = c_char.in_dll(debugger_helper, "isTracing")
            while True:
                if isTracing.value != 0:
                    break
                sleep(0.1)

        if debugger_search_path:
            del sys.path[0]

    except:
        traceback.print_exc()
        print('''
Internal error detected. Please copy the above traceback and report at
https://github.com/Microsoft/vscode-python/issues/new

Press Enter to close. . .''')
        try:
            raw_input()
        except NameError:
            input()
        sys.exit(1)
def main():
    import os
    import sys
    import unittest
    from optparse import OptionParser
    global _channel

    parser = OptionParser(prog='visualstudio_py_testlauncher',
                          usage='Usage: %prog [<option>] <test names>... ')
    parser.add_option(
        '-s',
        '--secret',
        metavar='<secret>',
        help=
        'restrict server to only allow clients that specify <secret> when connecting'
    )
    parser.add_option('-p',
                      '--port',
                      type='int',
                      metavar='<port>',
                      help='listen for debugger connections on <port>')
    parser.add_option('-x',
                      '--mixed-mode',
                      action='store_true',
                      help='wait for mixed-mode debugger to attach')
    parser.add_option('-t',
                      '--test',
                      type='str',
                      dest='tests',
                      action='append',
                      help='specifies a test to run')
    parser.add_option('-c',
                      '--coverage',
                      type='str',
                      help='enable code coverage and specify filename')
    parser.add_option(
        '-r',
        '--result-port',
        type='int',
        help='connect to port on localhost and send test results')
    parser.add_option('--test-list',
                      metavar='<file>',
                      type='str',
                      help='read tests from this file')
    parser.add_option('--dry-run',
                      action='store_true',
                      help='prints a list of tests without executing them')
    (opts, _) = parser.parse_args()

    sys.path[0] = os.getcwd()

    if opts.result_port:
        _channel = _IpcChannel(
            socket.create_connection(('127.0.0.1', opts.result_port)))
        sys.stdout = _TestOutput(sys.stdout, is_stdout=True)
        sys.stderr = _TestOutput(sys.stderr, is_stdout=False)

    if opts.secret and opts.port:
        from ptvsd.debugger import DONT_DEBUG, DEBUG_ENTRYPOINTS, get_code
        from ptvsd import DEFAULT_PORT, enable_attach, wait_for_attach

        DONT_DEBUG.append(os.path.normcase(__file__))
        DEBUG_ENTRYPOINTS.add(get_code(main))

        enable_attach(opts.secret,
                      ('127.0.0.1', getattr(opts, 'port', DEFAULT_PORT)),
                      redirect_output=True)
        wait_for_attach()
    elif opts.mixed_mode:
        # For mixed-mode attach, there's no ptvsd and hence no wait_for_attach(),
        # so we have to use Win32 API in a loop to do the same thing.
        from time import sleep
        from ctypes import windll, c_char
        while True:
            if windll.kernel32.IsDebuggerPresent() != 0:
                break
            sleep(0.1)
        try:
            debugger_helper = windll[
                'Microsoft.PythonTools.Debugger.Helper.x86.dll']
        except WindowsError:
            debugger_helper = windll[
                'Microsoft.PythonTools.Debugger.Helper.x64.dll']
        isTracing = c_char.in_dll(debugger_helper, "isTracing")
        while True:
            if isTracing.value != 0:
                break
            sleep(0.1)

    all_tests = list(opts.tests or [])
    if opts.test_list:
        with open(opts.test_list, 'r', encoding='utf-8') as test_list:
            all_tests.extend(t.strip() for t in test_list)

    if opts.dry_run:
        if _channel:
            for test in all_tests:
                print(test)
                _channel.send_event(name='start', test=test)
                _channel.send_event(name='result', outcome='passed', test=test)
        else:
            for test in all_tests:
                print(test)
        sys.exit(0)

    cov = None
    try:
        if opts.coverage:
            try:
                import coverage
                cov = coverage.coverage(opts.coverage)
                cov.load()
                cov.start()
            except:
                pass

        tests = []
        for test in all_tests:
            if not test:
                continue
            try:
                for loaded_test in unittest.defaultTestLoader.loadTestsFromName(
                        test):
                    # Starting with Python 3.5, rather than letting any import error
                    # exception propagate out of loadTestsFromName, unittest catches it and
                    # creates instance(s) of unittest.loader._FailedTest.
                    # Those have an unexpected test.id(), ex: 'unittest.loader._FailedTest.test1'
                    # Store the test id passed in as an additional attribute and
                    # VsTestResult will use that instead of test.id().
                    loaded_test.test_id = test
                    tests.append(loaded_test)
            except Exception as err:
                traceback.print_exc()
                formatted = traceback.format_exc().splitlines()
                # Remove the 'Traceback (most recent call last)'
                formatted = formatted[1:]
                tb = '\n'.join(formatted)
                message = str(err)

                if _channel is not None:
                    _channel.send_event(name='start', test=test)
                    _channel.send_event(name='result',
                                        outcome='failed',
                                        traceback=tb,
                                        message=message,
                                        test=test)

        runner = unittest.TextTestRunner(verbosity=0, resultclass=VsTestResult)

        result = runner.run(unittest.defaultTestLoader.suiteClass(tests))

        sys.exit(not result.wasSuccessful())
    finally:
        if cov is not None:
            cov.stop()
            cov.save()
            cov.xml_report(outfile=opts.coverage + '.xml', omit=__file__)
        if _channel is not None:
            _channel.send_event(name='done')
            _channel.close()
def main():
    import os
    from optparse import OptionParser
    global _channel

    parser = OptionParser(prog = 'visualstudio_py_testlauncher', usage = 'Usage: %prog [<option>] <test names>... ')
    parser.add_option('-s', '--secret', metavar='<secret>', help='restrict server to only allow clients that specify <secret> when connecting')
    parser.add_option('-p', '--port', type='int', metavar='<port>', help='listen for debugger connections on <port>')
    parser.add_option('-x', '--mixed-mode', action='store_true', help='wait for mixed-mode debugger to attach')
    parser.add_option('-t', '--test', type='str', dest='tests', action='append', help='specifies a test to run')
    parser.add_option('-c', '--coverage', type='str', help='enable code coverage and specify filename')
    parser.add_option('-r', '--result-port', type='int', help='connect to port on localhost and send test results')
    parser.add_option('--test-list', metavar='<file>', type='str', help='read tests from this file')
    parser.add_option('--dry-run', action='store_true', help='prints a list of tests without executing them')
    (opts, _) = parser.parse_args()
    
    sys.path[0] = os.getcwd()
    
    if opts.result_port:
        _channel = _IpcChannel(socket.create_connection(('127.0.0.1', opts.result_port)))
        sys.stdout = _TestOutput(sys.stdout, is_stdout = True)
        sys.stderr = _TestOutput(sys.stderr, is_stdout = False)

    if opts.secret and opts.port:
        from ptvsd.debugger import DONT_DEBUG, DEBUG_ENTRYPOINTS, get_code
        from ptvsd import DEFAULT_PORT, enable_attach, wait_for_attach

        DONT_DEBUG.append(os.path.normcase(__file__))
        DEBUG_ENTRYPOINTS.add(get_code(main))

        enable_attach(opts.secret, ('127.0.0.1', getattr(opts, 'port', DEFAULT_PORT)), redirect_output = True)
        wait_for_attach()
    elif opts.mixed_mode:
        # For mixed-mode attach, there's no ptvsd and hence no wait_for_attach(), 
        # so we have to use Win32 API in a loop to do the same thing.
        from time import sleep
        from ctypes import windll, c_char
        while True:
            if windll.kernel32.IsDebuggerPresent() != 0:
                break
            sleep(0.1)
        try:
            debugger_helper = windll['Microsoft.PythonTools.Debugger.Helper.x86.dll']
        except WindowsError:
            debugger_helper = windll['Microsoft.PythonTools.Debugger.Helper.x64.dll']
        isTracing = c_char.in_dll(debugger_helper, "isTracing")
        while True:
            if isTracing.value != 0:
                break
            sleep(0.1)

    all_tests = list(opts.tests or [])
    if opts.test_list:
        with open(opts.test_list, 'r', encoding='utf-8') as test_list:
            all_tests.extend(t.strip() for t in test_list)

    if opts.dry_run:
        if _channel:
            for test in all_tests:
                print(test)
                _channel.send_event(
                    name='start', 
                    test = test
                )
                _channel.send_event(
                    name='result', 
                    outcome='passed',
                    test = test
                )
        else:
            for test in all_tests:
                print(test)
        sys.exit(0)

    cov = None
    try:
        if opts.coverage:
            try:
                import coverage
                cov = coverage.coverage(opts.coverage)
                cov.load()
                cov.start()
            except:
                pass

        tests = []
        for test in all_tests:
            if not test:
                continue
            try:
                for loaded_test in unittest.defaultTestLoader.loadTestsFromName(test):
                    # Starting with Python 3.5, rather than letting any import error
                    # exception propagate out of loadTestsFromName, unittest catches it and
                    # creates instance(s) of unittest.loader._FailedTest.
                    # Those have an unexpected test.id(), ex: 'unittest.loader._FailedTest.test1'
                    # Store the test id passed in as an additional attribute and
                    # VsTestResult will use that instead of test.id().
                    loaded_test.test_id = test
                    tests.append(loaded_test)
            except Exception:
                trace = sys.exc_info()

                traceback.print_exception(*trace)
                tb = _get_traceback(trace)
                message = str(trace[1])

                if _channel is not None:
                    _channel.send_event(
                        name='start', 
                        test = test
                    )
                    _channel.send_event(
                        name='result', 
                        outcome='failed',
                        traceback = tb,
                        message = message,
                        test = test
                    )

        if _IS_OLD_UNITTEST:
            def _makeResult(self):
                return VsTestResult(self.stream, self.descriptions, self.verbosity)

            unittest.TextTestRunner._makeResult = _makeResult

            runner = unittest.TextTestRunner(verbosity=0)
        else:
            runner = unittest.TextTestRunner(verbosity=0, resultclass=VsTestResult)
        
        result = runner.run(unittest.defaultTestLoader.suiteClass(tests))

        sys.exit(not result.wasSuccessful())
    finally:
        if cov is not None:
            cov.stop()
            cov.save()
            cov.xml_report(outfile = opts.coverage + '.xml', omit=__file__)
        if _channel is not None:
            _channel.send_event(
                name='done'
            )
            _channel.close()