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
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()
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
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()
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()
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()
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
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))
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)
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
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
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()
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
def error_output(self, message): print_ansi('#ansi[%s](red)' % message)
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))
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())