Example #1
0
 def open_editor(self, lang: str, src: str = '') -> str:
     file_suffix = '.' + executors[lang].Executor.ext
     editor = os.environ.get('EDITOR')
     if editor:
         with tempfile.NamedTemporaryFile(mode='w+',
                                          suffix=file_suffix) as temp:
             temp.write(src)
             temp.flush()
             subprocess.call([editor, temp.name])
             temp.seek(0)
             src = temp.read()
     else:
         print_ansi(
             '#ansi[$EDITOR not set, falling back to stdin](yellow)\n')
         lines = []
         try:
             while True:
                 s = input()
                 if s.strip() == ':q':
                     raise EOFError
                 lines.append(s)
         except EOFError:  # Ctrl+D
             src = '\n'.join(lines)
         except Exception as io:
             raise InvalidCommandException(str(io))
     return src
Example #2
0
def cli_main():
    import logging
    from dmoj import judgeenv, executors

    judgeenv.load_env(cli=True)
    executors.load_executors()

    print('Running local judge...')

    logging.basicConfig(
        filename=judgeenv.log_file,
        level=logging.INFO,
        format='%(levelname)s %(asctime)s %(module)s %(message)s')

    judge = LocalJudge()

    for warning in judgeenv.startup_warnings:
        print_ansi('#ansi[Warning: %s](yellow)' % warning)
    del judgeenv.startup_warnings
    print()

    from dmoj.commands import all_commands, commands, register_command
    for command in all_commands:
        register_command(command(judge))

    def run_command(line):
        if not line:
            return 127

        if line[0] in commands:
            cmd = commands[line[0]]
            try:
                return cmd.execute(line[1:])
            except InvalidCommandException as e:
                if e.message:
                    print_ansi("#ansi[%s](red|bold)\n" % e.message)
                print()
                return 1
        else:
            print_ansi('#ansi[Unrecognized command %s](red|bold)' % line[0])
            print()
            return 127

    with judge:
        try:
            judge.listen()

            if judgeenv.cli_command:
                return run_command(judgeenv.cli_command)
            else:
                while True:
                    command = input(
                        ansi_style(
                            "#ansi[dmoj](magenta)#ansi[>](green) ")).strip()
                    run_command(shlex.split(command))
        except (EOFError, KeyboardInterrupt):
            print()
        finally:
            judge.murder()
Example #3
0
    def run_self_test(
            cls,
            output: bool = True,
            error_callback: Optional[Callable[[Any], Any]] = None) -> bool:
        if not cls.test_program:
            return True

        if output:
            print_ansi("%-39s%s" % ('Self-testing #ansi[%s](|underline):' %
                                    cls.get_executor_name(), ''),
                       end=' ')
        try:
            executor = cls(cls.test_name, utf8bytes(cls.test_program))
            proc = executor.launch(time=cls.test_time,
                                   memory=cls.test_memory,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE)

            test_message = b'echo: Hello, World!'
            stdout, stderr = proc.communicate(test_message + b'\n')

            if proc.tle:
                print_ansi('#ansi[Time Limit Exceeded](red|bold)')
                return False
            if proc.mle:
                print_ansi('#ansi[Memory Limit Exceeded](red|bold)')
                return False

            res = stdout.strip() == test_message and not stderr
            if output:
                # Cache the versions now, so that the handshake packet doesn't take ages to generate
                cls.get_runtime_versions()
                usage = '[%.3fs, %d KB]' % (proc.execution_time,
                                            proc.max_memory)
                print_ansi(
                    ['#ansi[Failed](red|bold)',
                     '#ansi[Success](green|bold)'][res], usage)
            if stdout.strip() != test_message and error_callback:
                error_callback('Got unexpected stdout output:\n' +
                               utf8text(stdout))
            if stderr:
                if error_callback:
                    error_callback('Got unexpected stderr output:\n' +
                                   utf8text(stderr))
                else:
                    print(stderr, file=sys.stderr)
            if proc.protection_fault:
                print_protection_fault(proc.protection_fault)
            return res
        except Exception:
            if output:
                print_ansi('#ansi[Failed](red|bold)')
                traceback.print_exc()
            if error_callback:
                error_callback(traceback.format_exc())
            return False
Example #4
0
 def start(self):
     if self._monitor is not None:
         try:
             self._monitor.start()
         except OSError:
             logger.exception('Failed to start problem monitor.')
             print_ansi(
                 '#ansi[Warning: failed to start problem monitor!](yellow)')
     if self._refresher is not None:
         self._refresher.start()
Example #5
0
    def execute(self, line):
        args = self.arg_parser.parse_args(line)

        if args.limit is not None and args.limit <= 0:
            raise InvalidCommandException("--limit must be >= 0")

        submissions = self.judge.graded_submissions if not args.limit else self.judge.graded_submissions[:args.limit]

        for i, (problem, lang, src, tl, ml) in enumerate(submissions):
            print_ansi('#ansi[%s](yellow)/#ansi[%s](green) in %s' % (problem, i + 1, lang))
        print()
Example #6
0
    def execute(self, line: str) -> None:
        args = self.arg_parser.parse_args(line)

        if args.limit is not None and args.limit <= 0:
            raise InvalidCommandException('--limit must be >= 0')

        submissions = self.judge.graded_submissions if not args.limit else self.judge.graded_submissions[:args
                                                                                                         .
                                                                                                         limit]

        for i, (problem, lang, src, tl, ml) in enumerate(submissions):
            print_ansi(
                f'#ansi[{problem}](yellow)/#ansi[{i + 1}](green) in {lang}')
        print()
Example #7
0
    def run_command(line):
        if not line:
            return 127

        if line[0] in commands:
            cmd = commands[line[0]]
            try:
                return cmd.execute(line[1:])
            except InvalidCommandException as e:
                if e.message:
                    print_ansi("#ansi[%s](red|bold)\n" % e.message)
                print()
                return 1
        else:
            print_ansi('#ansi[Unrecognized command %s](red|bold)' % line[0])
            print()
            return 127
Example #8
0
def main():
    judgeenv.load_env(cli=True, testsuite=True)

    logging.basicConfig(filename=judgeenv.log_file, level=logging.INFO,
                        format='%(levelname)s %(asctime)s %(module)s %(message)s')

    executors.load_executors()
    contrib.load_contrib_modules()

    tester = Tester(judgeenv.problem_regex, judgeenv.case_regex)
    fails = tester.test_all()
    print()
    print('Test complete')
    if fails:
        print_ansi('#ansi[A total of %d case(s) failed](red|bold).' % fails)
    else:
        print_ansi('#ansi[All cases passed.](green|bold)')
    raise SystemExit(int(fails != 0))
Example #9
0
def main():  # pragma: no cover
    unicode_stdout_stderr()

    if not sanity_check():
        return 1

    from dmoj import judgeenv, contrib, executors

    judgeenv.load_env()

    executors.load_executors()
    contrib.load_contrib_modules()

    if hasattr(signal, 'SIGUSR2'):
        signal.signal(signal.SIGUSR2, signal.SIG_IGN)

    print('Running live judge...')

    for warning in judgeenv.startup_warnings:
        print_ansi('#ansi[Warning: %s](yellow)' % warning)
    del judgeenv.startup_warnings

    if 'judges' in env:
        logfile = judgeenv.log_file
        try:
            logfile = logfile % 'master'
        except TypeError:
            pass
        logging.basicConfig(
            filename=logfile,
            level=logging.INFO,
            format='%(levelname)s %(asctime)s %(process)d %(name)s %(message)s'
        )
        if env.pidfile:
            with open(env.pidfile) as f:
                f.write(str(os.getpid()))
        manager = JudgeManager(env.judges)
        manager.run()
    else:
        return judge_proc(need_monitor=True)
Example #10
0
    def execute(self, line):
        args = self.arg_parser.parse_args(line)

        problem_ids = args.problem_ids
        supported_problems = set(get_supported_problems())

        unknown_problems = ', '.join(
            map(
                lambda x: "'%s'" % x,
                filter(lambda problem_id: problem_id not in supported_problems,
                       problem_ids)))
        if unknown_problems:
            raise InvalidCommandException("unknown problem(s) %s" %
                                          unknown_problems)

        tester = ProblemTester()
        total_fails = 0
        for problem_id in problem_ids:
            fails = tester.test_problem(problem_id)
            if fails:
                print_ansi(
                    'Problem #ansi[%s](cyan|bold) #ansi[failed %d case(s)](red|bold).'
                    % (problem_id, fails))
            else:
                print_ansi(
                    'Problem #ansi[%s](cyan|bold) passed with flying colours.'
                    % problem_id)
            print()
            total_fails += fails

        print()
        print('Test complete.')
        if fails:
            print_ansi('#ansi[A total of %d test(s) failed](red|bold)' % fails)
        else:
            print_ansi('#ansi[All tests passed.](green|bold)')

        return fails
Example #11
0
    def execute(self, line: str) -> int:
        args = self.arg_parser.parse_args(line)

        problem_ids = args.problem_ids
        supported_problems = set(get_supported_problems())

        unknown_problems = ', '.join(f"'{i}'" for i in problem_ids
                                     if i not in supported_problems)
        if unknown_problems:
            raise InvalidCommandException(
                f'unknown problem(s) {unknown_problems}')

        tester = ProblemTester()
        total_fails = 0
        for problem_id in problem_ids:
            fails = tester.run_problem_tests(problem_id)
            if fails:
                print_ansi(
                    f'Problem #ansi[{problem_id}](cyan|bold) #ansi[failed {fails} case(s)](red|bold).'
                )
            else:
                print_ansi(
                    f'Problem #ansi[{problem_id}](cyan|bold) passed with flying colours.'
                )
            print()
            total_fails += fails

        print()
        print('Test complete.')
        if total_fails:
            print_ansi(
                f'#ansi[A total of {total_fails} test(s) failed](red|bold)')
        else:
            print_ansi('#ansi[All tests passed.](green|bold)')

        return total_fails
Example #12
0
def main():  # pragma: no cover
    unicode_stdout_stderr()

    if not sanity_check():
        return 1

    from dmoj import judgeenv, contrib, executors

    judgeenv.load_env()

    executors.load_executors()
    contrib.load_contrib_modules()

    print('Running live judge...')

    for warning in judgeenv.startup_warnings:
        print_ansi('#ansi[Warning: %s](yellow)' % warning)
    del judgeenv.startup_warnings

    logfile = judgeenv.log_file

    try:
        logfile = logfile % env['id']
    except TypeError:
        pass

    logging.basicConfig(
        filename=logfile,
        level=logging.INFO,
        format='%(levelname)s %(asctime)s %(process)d %(module)s %(message)s')

    setproctitle('DMOJ Judge %s on %s' % (env['id'], make_host_port(judgeenv)))

    judge = ClassicJudge(
        judgeenv.server_host,
        judgeenv.server_port,
        secure=judgeenv.secure,
        no_cert_check=judgeenv.no_cert_check,
        cert_store=judgeenv.cert_store,
    )
    monitor = Monitor()
    monitor.callback = judge.update_problems

    if hasattr(signal, 'SIGUSR2'):

        def update_problem_signal(signum, frame):
            judge.update_problems()

        signal.signal(signal.SIGUSR2, update_problem_signal)

    if judgeenv.api_listen:
        judge_instance = judge

        class Handler(JudgeControlRequestHandler):
            judge = judge_instance

        api_server = HTTPServer(judgeenv.api_listen, Handler)
        thread = threading.Thread(target=api_server.serve_forever)
        thread.daemon = True
        thread.start()
    else:
        api_server = None

    print()
    with monitor:
        try:
            judge.listen()
        except KeyboardInterrupt:
            pass
        except Exception:
            traceback.print_exc()
        finally:
            judge.murder()
            if api_server:
                api_server.shutdown()
Example #13
0
    def run_self_test(
            cls,
            output: bool = True,
            error_callback: Optional[Callable[[Any], Any]] = None) -> bool:
        if not cls.test_program:
            return True

        if output:
            print_ansi(
                f'Self-testing #ansi[{cls.get_executor_name()}](|underline):'.
                ljust(39),
                end=' ')
        try:
            executor = cls(cls.test_name, utf8bytes(cls.test_program))
            proc = executor.launch(time=cls.test_time,
                                   memory=cls.test_memory,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE)

            test_message = b'echo: Hello, World!'
            stdout, stderr = proc.communicate(test_message + b'\n')

            if proc.is_tle:
                print_ansi('#ansi[Time Limit Exceeded](red|bold)')
                return False
            if proc.is_mle:
                print_ansi('#ansi[Memory Limit Exceeded](red|bold)')
                return False

            res = stdout.strip() == test_message and not stderr
            if output:
                # Cache the versions now, so that the handshake packet doesn't take ages to generate
                cls.get_runtime_versions()
                usage = f'[{proc.execution_time:.3f}s, {proc.max_memory} KB]'
                print_ansi(
                    f'{["#ansi[Failed](red|bold) ", "#ansi[Success](green|bold)"][res]} {usage:<19}',
                    end=' ')
                print_ansi(', '.join([
                    f'#ansi[{runtime}](cyan|bold) {".".join(map(str, version))}'
                    for runtime, version in cls.get_runtime_versions()
                ]))
            if stdout.strip() != test_message and error_callback:
                error_callback('Got unexpected stdout output:\n' +
                               utf8text(stdout))
            if stderr:
                if error_callback:
                    error_callback('Got unexpected stderr output:\n' +
                                   utf8text(stderr))
                else:
                    print(stderr, file=sys.stderr)
            if proc.protection_fault:
                print_protection_fault(proc.protection_fault)
            return res
        except Exception:
            if output:
                print_ansi('#ansi[Failed](red|bold)')
                traceback.print_exc()
            if error_callback:
                error_callback(traceback.format_exc())
            return False
Example #14
0
 def error_output(self, message):
     print_ansi('#ansi[%s](red)' % message)
Example #15
0
def ci_test(executors_to_test, overrides, allow_fail=frozenset()):
    result = {}
    failed = False
    failed_executors = []

    for name in executors_to_test:
        executor = import_module('dmoj.executors.' + name)

        print_ansi('%-34s%s' % ('Testing #ansi[%s](|underline):' % name, ''),
                   end=' ')

        if not hasattr(executor, 'Executor'):
            failed = True
            print_ansi(
                '#ansi[Does not export](red|bold) #ansi[Executor](red|underline)'
            )
            continue

        if not hasattr(executor.Executor, 'autoconfig'):
            print_ansi('#ansi[Could not autoconfig](magenta|bold)')
            continue

        try:
            if name in overrides:
                if not overrides[name]:
                    print_ansi('#ansi[Environment not found on Travis](red)')
                    continue
                print_ansi('#ansi[(manual config)](yellow)', end=' ')
                data = executor.Executor.autoconfig_run_test(overrides[name])
            else:
                data = executor.Executor.autoconfig()
            config = data[0]
            success = data[1]
            feedback = data[2]
            errors = '' if len(data) < 4 else data[3]
        except Exception:
            print_ansi('#ansi[Autoconfig broken](red|bold)')
            traceback.print_exc()
            if name not in allow_fail:
                failed = True
                failed_executors.append(name)
        else:
            print_ansi(
                ['#ansi[%s](red|bold)', '#ansi[%s](green|bold)'][success] %
                (feedback or ['Failed', 'Success'][success]))

            if success:
                result.update(config)
                executor.Executor.runtime_dict = config
                executors[name] = executor
                for runtime, ver in executor.Executor.get_runtime_versions():
                    print_ansi('  #ansi[%s](cyan): %s' %
                               (runtime,
                                '.'.join(map(str, ver))) if ver else 'unknown')
            else:
                if feedback == 'Could not find JVM':
                    continue

                if config:
                    print('  Attempted:')
                    print(
                        '   ',
                        yaml.safe_dump(
                            config, default_flow_style=False).rstrip().replace(
                                '\n', '\n' + ' ' * 4))

                if errors:
                    print('  Errors:')
                    print('   ', errors.replace('\n', '\n' + ' ' * 4))
                if name not in allow_fail:
                    failed = True
                    failed_executors.append(name)

    print()
    print_ansi('#ansi[Configuration result](green|bold|underline):')
    print(
        yaml.safe_dump({
            'runtime': result
        }, default_flow_style=False).rstrip())
    print()
    if failed:
        print_ansi('#ansi[Executor configuration failed.](red|bold)')
        print_ansi('#ansi[Failed executors:](|bold)',
                   ', '.join(failed_executors))
    else:
        print_ansi('#ansi[Executor configuration succeeded.](green|bold)')
    load_contrib_modules()
    print()
    print()
    print('Running test cases...')
    judgeenv.problem_dirs = [
        os.path.normpath(
            os.path.join(os.path.dirname(__file__), '..', 'testsuite'))
    ]
    tester = Tester()
    fails = tester.test_all()
    print()
    print('Test complete.')
    if fails:
        print_ansi('#ansi[A total of %d case(s) failed](red|bold).' % fails)
    else:
        print_ansi('#ansi[All cases passed.](green|bold)')
    failed |= fails != 0
    raise SystemExit(int(failed))
Example #16
0
def main():
    parser = argparse.ArgumentParser(
        description='Automatically configures runtimes')
    output_conf = parser.add_mutually_exclusive_group()
    output_conf.add_argument('-s',
                             '--silent',
                             action='store_true',
                             help='silent mode')
    output_conf.add_argument('-V',
                             '--verbose',
                             action='store_true',
                             help='verbose mode')
    args = parser.parse_args()

    if not args.silent:
        logging.basicConfig(
            level=logging.DEBUG if args.verbose else logging.WARNING,
            format='%(message)s')

    result = {}
    judgeenv.env['runtime'] = {}

    if args.silent:
        sys.stderr = open(os.devnull, 'w')

    for name in get_available():
        executor = load_executor(name)

        if executor is None or not hasattr(executor, 'Executor'):
            continue

        Executor = executor.Executor
        if not args.verbose and not issubclass(Executor, NullStdoutMixin):
            # if you are printing errors into stdout, you may do so in your own blood
            # *cough* Racket *cough*
            Executor = type('Executor', (NullStdoutMixin, Executor), {})

        if hasattr(Executor, 'autoconfig'):
            if not args.silent:
                print_ansi(
                    '%-43s%s' %
                    ('Auto-configuring #ansi[%s](|underline):' % name, ''),
                    end=' ',
                    file=sys.stderr)
                sys.stdout.flush()

            try:
                data = Executor.autoconfig()
                config = data[0]
                success = data[1]
                feedback = data[2]
                errors = '' if len(data) < 4 else data[3]
            except Exception:
                if not args.silent:
                    print_ansi('#ansi[Not supported](red|bold)',
                               file=sys.stderr)
                    traceback.print_exc()
            else:
                if not args.silent:
                    print_ansi(
                        ['#ansi[%s](red|bold)', '#ansi[%s](green|bold)'
                         ][success] %
                        (feedback or ['Failed', 'Success'][success]),
                        file=sys.stderr,
                    )

                if not success and args.verbose:
                    if config:
                        print('  Attempted:', file=sys.stderr)
                        print(
                            '   ',
                            yaml.safe_dump(
                                config,
                                default_flow_style=False).rstrip().replace(
                                    '\n', '\n' + ' ' * 4),
                            file=sys.stderr,
                        )

                    if errors:
                        print('  Errors:', file=sys.stderr)
                        print('   ',
                              errors.replace('\n', '\n' + ' ' * 4),
                              file=sys.stderr)

                if success:
                    result.update(config)

    if not args.silent and sys.stdout.isatty():
        print(file=sys.stderr)

    if result:
        if not args.silent and sys.stdout.isatty():
            print_ansi('#ansi[Configuration result](green|bold|underline):',
                       file=sys.stderr)
    else:
        print_ansi('#ansi[No runtimes configured.](red|bold)',
                   file=sys.__stderr__)
        if not args.verbose:
            print_ansi(
                'Run #ansi[%s -V](|underline) to see why this is the case.' %
                (parser.prog, ),
                file=sys.__stderr__)

    print(
        yaml.safe_dump({
            'runtime': result
        }, default_flow_style=False).rstrip())