Example #1
0
def test_source_code(tmpdir, language_manager, repo_manager):
    repo = repo_manager.repo

    tmpdir = Path(str(tmpdir))
    (tmpdir / 'src').mkdir()
    src_cpp1 = tmpdir / 'src' / 'aplusb.cpp'
    src_py1 = tmpdir / 'src' / 'code.py'
    shutil.copy(fspath(tests_location() / 'aplusb.cpp'), fspath(src_cpp1))
    shutil.copy(fspath(tests_location() / 'code.py'), fspath(src_py1))

    lang1 = language_manager.get_lang('cpp.g++11')
    lang2 = language_manager.get_lang('cpp.g++14')
    src1 = language_manager.create_source(src_cpp1, language=lang1)
    src1.compile()
    src1.runner.stdin = '2 3'
    assert src1.runner.stdin == '2 3'
    src1.run(EmptyRunProfile(repo))
    assert src1.runner.stdout == '5\n'
    assert src1.runner.stderr == ''

    src2 = language_manager.create_source(src_cpp1, language=lang2)
    with pytest.raises(CompileError):
        src2.compile()

    src3 = language_manager.create_source(src_py1)
    src3.compile()
    src3.run(EmptyRunProfile(repo))
    assert src3.runner.stdout == 'hello world\n'
Example #2
0
 def shell_str(self):
     if fspath(self.work_dir) == path.curdir:
         return '{}{}'.format(command_flags_to_str(self.flags),
                              self._shell_str_internal())
     return '{}cd {} && {}'.format(command_flags_to_str(self.flags),
                                   shlex.quote(fspath(self.work_dir)),
                                   self._shell_str_internal())
Example #3
0
 def __copyfile(self, src, dst):
     try:
         shutil.copy(fspath(src), fspath(dst))
     except shutil.SameFileError as exc:
         pass
     except OSError as exc:
         msg = 'could not copy file \"{}\" due to OS error: {}'
         self.compiler_output = msg.format(fspath(src), exc.strerror)
         self._raise_error()
Example #4
0
def test_make_rules(tmpdir, language_manager, repo_manager, taker_app):
    repo = repo_manager.repo

    tmpdir = Path(str(tmpdir))
    (tmpdir / 'task' / 'src').mkdir()
    lib_dir = tmpdir / 'task' / 'lib'
    lib_dir.mkdir()

    src_cpp1 = tmpdir / 'task' / 'src' / 'aplusb.cpp'
    src_cpp2 = tmpdir / 'task' / 'src' / 'code_libs.cpp'
    src_cpp3 = tmpdir / 'task' / 'src' / 'code_gen_out.cpp'
    src_cpplib = tmpdir / 'task' / 'lib' / 'code_mylib.h'
    src_py1 = tmpdir / 'task' / 'src' / 'code.py'
    shutil.copy(fspath(tests_location() / 'aplusb.cpp'), fspath(src_cpp1))
    shutil.copy(fspath(tests_location() / 'code_libs.cpp'), fspath(src_cpp2))
    shutil.copy(fspath(tests_location() / 'code_gen_out.cpp'),
                fspath(src_cpp3))
    shutil.copy(fspath(tests_location() / 'code_mylib.h'), fspath(src_cpplib))
    shutil.copy(fspath(tests_location() / 'code.py'), fspath(src_py1))

    src1 = language_manager.create_source(src_cpp1, language='cpp.g++11')
    rule1 = src1.add_compile_rule()
    src2 = language_manager.create_source(src_cpp2,
                                          language='cpp.g++14',
                                          library_dirs=[lib_dir])
    rule2 = src2.add_compile_rule()
    src3 = language_manager.create_source(src_py1)
    rule3 = src3.add_compile_rule()
    src4 = language_manager.create_source(src_cpp3)
    rule4 = src4.add_compile_rule()

    rule5 = repo_manager.makefile.add_phony_rule('genout')
    src4.add_run_command(rule5, CompilerRunProfile(repo), ['arg1', 'arg2'])
    src4.add_run_command(rule5,
                         'generator',
                         quiet=True,
                         stdin="see '42'!",
                         working_dir=tmpdir)

    assert rule3 is None
    assert rule4 is not None
    repo_manager.makefile.all_rule.add_depend(rule1)
    repo_manager.makefile.all_rule.add_depend(rule2)
    repo_manager.makefile.all_rule.add_depend(rule3)
    repo_manager.makefile.all_rule.add_depend(rule5)

    make_template = (tests_location() / 'srcbuild.make').open('r').read()
    make_template = make_template.format(taker_app)

    assert repo_manager.makefile.dump() == make_template

    repo_manager.build()
    assert src1.exe_file.exists()
    assert src2.exe_file.exists()
    assert src3.exe_file.exists()
    assert (tmpdir / 'output.txt').exists()
    assert (tmpdir / 'task' / 'src' / 'output.txt').exists()
Example #5
0
def test_files():
    infile = InputFile('q.txt')
    outfile = OutputFile('w.txt')
    assert fspath(infile) == 'q.txt'
    assert fspath(outfile) == 'w.txt'
    assert str(infile) == 'q.txt'
    assert InputFile('q.txt') == InputFile('q.txt')
    assert not InputFile('q.txt') != InputFile('q.txt')
    assert InputFile('q.txt') != InputFile('w.txt')
    assert not InputFile('q.txt') == InputFile('w.txt')
    assert not File('q.txt') == InputFile('q.txt')
    assert File('q.txt') != InputFile('q.txt')
    assert File('q.txt') == File('q.txt', prefix='t=')
Example #6
0
def test_app():
    old_app = consoleapp.__APP
    try:
        consoleapp.__APP = None
        with pytest.raises(RuntimeError):
            app()

        my_app = ConsoleApp('take')
        register_app(my_app)
        assert consoleapp.__APP is my_app
        with pytest.raises(RuntimeError):
            register_app(ConsoleApp('taker2'))
        assert consoleapp.__APP is my_app

        exe = app_exe()
        assert fspath(exe) == shutil.which('take')
        with pytest.raises(RuntimeError):
            app_exe('taker2')

        got_value = 0

        def callback(value):
            nonlocal got_value
            got_value = value
            return 142

        my_app.add_subcommand(MySubcommand(callback))
        with pytest.raises(SystemExit) as exc:
            my_app.run(['cmd', '42'])
        assert exc.value.code == 142
        assert got_value == 42
    finally:
        consoleapp.__APP = old_app
Example #7
0
    def run(self, args):
        repo_manager = RepositoryManager()
        language_manager = LanguageManager(repo_manager)

        profile = create_profile(args.profile, repo_manager.repo)
        runner = ProfiledRunner(profile)

        cmdline = []
        if args.lang is None:
            cmdline = [fspath(args.exe.absolute())] + args.args
        else:
            lang = language_manager.get_lang(args.lang)
            cmdline = lang.run_args(args.exe, args.args)

        if args.input is not None:
            runner.stdin = args.input

        runner.run(cmdline, args.work_dir)
        if args.quiet:
            print(runner.stdout, end='')
            print(runner.stderr, end='', file=sys.stderr)
            status = runner.results.status
            if status not in {Status.OK, Status.RUNTIME_ERROR}:
                print(Fore.RED + Style.BRIGHT + 'error: ' + Style.RESET_ALL +
                      'program exited with status ' + repr(status),
                      file=sys.stderr)
        else:
            print(runner.format_results())
        return runner.get_cli_exitcode()
Example #8
0
 def __arg_to_shell(self, arg):
     if isinstance(arg, str):
         return arg
     if isinstance(arg, File):
         return arg.prefix + fspath(
             arg.relative_to(self.repo, self.work_dir))
     raise TypeError('arg has invalid type (str or File expected)')
Example #9
0
    def _do_add_command(self, command):
        for the_file in command.get_output_files():
            the_file = fspath(the_file)
            if the_file not in self.files:
                self.output_files.add(the_file)
                self.files.add(the_file)

        for the_file in command.get_input_files():
            the_file = fspath(the_file)
            if the_file not in self.files:
                self.input_files.add(the_file)
                self.files.add(the_file)

        for the_file in command.get_all_files():
            the_file = fspath(the_file)
            self.files.add(the_file)
Example #10
0
 def __init__(self,
              makefile,
              target_name,
              description=None,
              options=DEFAULT_OPTIONS):
     super().__init__(makefile, target_name, description, options)
     self.target_file = self.target_path() / target_name
     self.makefile.alias(self.name, fspath(self.target_file))
Example #11
0
 def build(self, target=None):
     self.makefile.save()
     jobs = config()['make']['jobs']
     if jobs is None:
         jobs = os.cpu_count()
     args = ['make', '-j', str(jobs)]
     if target is not None:
         args += [target]
     subprocess.check_call(args, cwd=fspath(self.repo.directory))
Example #12
0
 def compile(self):
     if not self.language.compile_args(self.src_file, self.exe_file):
         # just copy the file
         if not self.save_exe:
             return
         self.__copyfile(self.src_file, self.exe_file)
         return
     temp_dir = Path(
         mkdtemp('compilebox', '', fspath(self.repo.internal_dir(True))))
     try:
         src = temp_dir / self.src_file.name
         exe = temp_dir / self.exe_file.name
         self.__copyfile(self.src_file, src)
         self.__runner.run(
             self.language.compile_args(src, exe, self.library_dirs))
         self.compiler_output = self.__runner.format_results()
         if self.__runner.results.status != Status.OK:
             self._raise_error(self.__runner.get_cli_exitcode())
         if self.save_exe:
             self.__copyfile(exe, self.exe_file)
     finally:
         shutil.rmtree(fspath(temp_dir))
Example #13
0
def test_compile(repo_manager, monkeypatch):
    monkeypatch.chdir(fspath(repo_manager.repo.directory))
    make_source()
    make_badsource()
    res = subprocess.run(['take', 'compile', 'file.cpp'],
                         stdout=PIPE,
                         stderr=PIPE,
                         universal_newlines=True)
    assert res.returncode == 0
    assert res.stdout.find('ok') >= 0

    res = subprocess.run(['take', 'compile', 'bad.cpp'],
                         stdout=PIPE,
                         stderr=PIPE,
                         universal_newlines=True)
    assert res.returncode != 0
    assert res.stdout.find('compilation error') >= 0
Example #14
0
def parameters_to_json(parameters):
    param_dict = parameters._asdict()
    param_dict = dict_keys_replace(param_dict, '_', '-')
    # convert paths to strings
    for key in param_dict:
        if isinstance(param_dict[key], Path):
            param_dict[key] = fspath(param_dict[key])
    # set default values (if unset)
    if parameters.idle_limit is None:
        param_dict['idle-limit'] = 3.5 * parameters.time_limit
    if parameters.isolate_dir is None:
        param_dict['isolate-dir'] = parameters.working_dir
    if parameters.isolate_policy is None:
        param_dict['isolate-policy'] = IsolatePolicy.NORMAL
    param_dict['isolate-policy'] = param_dict['isolate-policy'].value
    # dump as JSON
    return json.dumps(param_dict)
Example #15
0
 def __fspath__(self):
     return fspath(self.filename)
Example #16
0
def test_run(repo_manager, monkeypatch):
    tests_loc = tests_location()
    badexe_loc = bad_exe_location()

    monkeypatch.chdir(fspath(repo_manager.repo.directory))

    shutil.copy(fspath(tests_loc / 'code_div.cpp'), '.')
    subprocess.run(['take', 'compile', 'code_div.cpp'],
                   check=True,
                   stdout=PIPE,
                   stderr=PIPE,
                   universal_newlines=True)

    code_div_exe = 'code_div' + default_exe_ext()

    open('input.txt', 'w').write('12 3')
    res = subprocess.run(['take', 'run', code_div_exe, '-p', 'compiler'],
                         check=True,
                         stdout=PIPE,
                         stderr=PIPE,
                         universal_newlines=True)
    assert res.stdout.startswith('stdout:\n4\n\nstderr:\n')

    res = subprocess.run(['take', 'run', code_div_exe, '-p', 'compiler', '-q'],
                         check=True,
                         stdout=PIPE,
                         stderr=PIPE,
                         universal_newlines=True)
    assert res.stdout == '4\n'
    assert res.stderr == 'done\n'

    open('input.txt', 'w').write('12 0')
    res = subprocess.run(['take', 'run', code_div_exe, '-p', 'compiler'],
                         stdout=PIPE,
                         stderr=PIPE,
                         universal_newlines=True)
    assert res.returncode != 0
    assert res.stdout.find('runtime-error') >= 0
    assert res.stdout.find('signal: ') >= 0

    os.mkdir('work')
    inner_in = Path('work') / 'input.txt'
    inner_in.open('w').write('42 6')
    res = subprocess.run(
        ['take', 'run', code_div_exe, '-p', 'compiler', '-q', '-w', 'work'],
        check=True,
        stdout=PIPE,
        stderr=PIPE,
        universal_newlines=True)
    assert res.stdout == '7\n'

    res = subprocess.run(
        ['take', 'run', fspath(badexe_loc), '-p', 'compiler'],
        stdout=PIPE,
        stderr=PIPE,
        universal_newlines=True)
    assert res.returncode != 0
    assert res.stdout.find('run-fail') >= 0

    res = subprocess.run(
        ['take', 'run',
         fspath(badexe_loc), '-p', 'compiler', '-q'],
        stdout=PIPE,
        stderr=PIPE,
        universal_newlines=True)
    assert res.returncode != 0
    assert res.stdout == ''
    assert res.stderr.find('error: program exited with status run-fail') >= 0
Example #17
0
def abspath(cur_path):
    return Path(path.abspath(fspath(cur_path)))
Example #18
0
 def normalize(self, repo):
     new_filename = shutil.which(fspath(self.filename))
     if new_filename is None:
         raise FileNotFoundError(
             'command {} not found'.format(new_filename))
     self.filename = Path(new_filename)
Example #19
0
 def command_name(self, repo, work_dir):
     return fspath(self.filename)
Example #20
0
 def save_to_file(self, file_name):
     open(fspath(file_name), 'w', encoding='utf8').write(self.dump())
Example #21
0
 def load_from_file(self, file_name):
     self.load(open(fspath(file_name), 'r', encoding='utf8').read())
Example #22
0
def relpath(cur_path, start=None):
    if start is None:
        start = Path.cwd()
    return Path(path.relpath(fspath(cur_path), fspath(start)))
Example #23
0
 def to_task_dir(self):
     os.chdir(fspath(self.directory))
Example #24
0
def test_mock_app_exe(taker_app):
    assert taker_app == app_exe()
    assert fspath(app_exe()) == shutil.which('take')
Example #25
0
def test_profiles(config_manager, repo_manager, monkeypatch, taker_app):
    config_manager.user_config(CONFIG_NAME).open(
        'w', encoding='utf8').write('''
[compiler]
time-limit = 3.0
memory-limit = 100.0

[checker]
time-limit = 6.0
memory-limit = 200.0

[validator]
time-limit = 9.0
memory-limit = 300.0

[generator]
time-limit = 12.0
memory-limit = 400.0

[custom]
time-limit = 15.0
memory-limit = 500.0
''')

    runner = Runner()
    repo = repo_manager.repo

    compiler_profile = create_profile('compiler', repo)
    assert type(compiler_profile) is CompilerRunProfile
    compiler_profile.update_runner(runner)
    assert runner.parameters.time_limit == 3.0
    assert runner.parameters.memory_limit == 100.0

    checker_profile = create_profile('checker', repo)
    assert type(checker_profile) is CheckerRunProfile
    checker_profile.update_runner(runner)
    assert runner.parameters.time_limit == 6.0
    assert runner.parameters.memory_limit == 200.0

    validator_profile = create_profile('validator', repo)
    assert type(validator_profile) is ValidatorRunProfile
    validator_profile.update_runner(runner)
    assert runner.parameters.time_limit == 9.0
    assert runner.parameters.memory_limit == 300.0

    generator_profile = create_profile('generator', repo)
    assert type(generator_profile) is GeneratorRunProfile
    generator_profile.update_runner(runner)
    assert runner.parameters.time_limit == 12.0
    assert runner.parameters.memory_limit == 400.0

    with pytest.raises(KeyError):
        create_profile('custom', repo)

    register_profile(CustomRunProfile)
    custom_profile = create_profile('custom', repo)
    assert type(custom_profile) is CustomRunProfile
    custom_profile.update_runner(runner)
    assert runner.parameters.time_limit == 15.0
    assert runner.parameters.memory_limit == 500.0

    run_count = 0

    def run(self):
        nonlocal run_count
        run_count += 1

    monkeypatch.setattr(Runner, 'run', run)
    profiled_runner = ProfiledRunner(generator_profile)
    profiled_runner.stdin = 'some input'
    in_runner = profiled_runner._ProfiledRunner__runner
    profiled_runner.run([fspath(taker_app)])
    assert run_count == 1
    assert in_runner.parameters.time_limit == 12.0
    assert in_runner.parameters.memory_limit == 400.0
    assert not in_runner.pass_stdin
    assert not in_runner.capture_stdout
    assert in_runner.capture_stderr
    assert in_runner.stdin == 'some input'
    assert in_runner.stdin == profiled_runner.stdin
    assert in_runner.parameters.working_dir == taker_app.parent

    profiled_runner.run([fspath(taker_app)], repo_manager.task_dir)
    assert run_count == 2
    assert in_runner.parameters.working_dir == repo_manager.task_dir

    profiles = set(list_profiles())
    assert 'compiler' in profiles
    assert 'validator' in profiles
Example #26
0
 def command_name(self, repo, work_dir):
     result = fspath(self.relative_to(repo, work_dir))
     if path.basename(result) == result:
         result = path.join(path.curdir, result)
     return result
Example #27
0
 def __init__(self, makefile, filename, options=DEFAULT_OPTIONS):
     super().__init__(makefile,
                      fspath(makefile.repo.relpath(filename)),
                      options=options)
Example #28
0
def test_languages(tmpdir, config_manager):
    tmpdir = Path(str(tmpdir))

    config = '''
[lang/sh.sh]
run-args = ['sh', '{exe}']
priority = 42
exe-ext = '.sh'
[lang/cpp.g++]
# Overwrite default g++
compile-args = ['<cpp-compiler>', '{src}', '-o', '{exe}', '-Ofast']
priority = 1150
exe-ext = '.42.exe'
[lang/cpp.g++14]
active = false
'''

    c_compiler = shutil.which('gcc')
    if not c_compiler:
        c_compiler = shutil.which('clang')
    cpp_compiler = shutil.which('g++')
    if not cpp_compiler:
        cpp_compiler = shutil.which('clang++')

    config = config.replace('<cpp-compiler>', cpp_compiler)

    config_manager.user_config(CONFIG_NAME).open('w',
                                                 encoding='utf8').write(config)

    lang_manager = LanguageManagerBase()

    assert ([str(lang.name) for lang in lang_manager.get_ext('.cpp')
             ] == ['cpp.g++17', 'cpp.g++', 'cpp.g++11'])
    assert lang_manager.get_ext('.bad_ext') == []
    assert lang_manager['py.py2'].name == 'py.py2'
    assert lang_manager['py.py3'].name == 'py.py3'
    assert lang_manager['py.py3'].exe_ext == '.py'

    with pytest.raises(LanguageError):
        lang_manager['bad_ext.bad_lang']

    with pytest.raises(ValueError):
        Language('q.q', exe_ext='iNeedDot')

    lang = lang_manager['c.gcc']
    compile_arg_exp = [
        c_compiler,
        fspath(Path.cwd() / 'file.cpp'), '-o',
        fspath(Path.cwd() / 'file.exe'), '-O2',
        '-I' + fspath(Path.cwd() / 'libs'),
        '-I' + fspath(Path.cwd() / 'morelibs')
    ]
    compile_arg_found = lang.compile_args(
        Path('file.cpp'), Path('file.exe'),
        [Path('libs'), Path('morelibs')])
    assert compile_arg_exp == compile_arg_found
    run_arg_exp = [fspath(tmpdir / 'file.exe'), 'arg1', 'arg2']
    with pytest.raises(FileNotFoundError):
        lang.run_args(tmpdir / 'file.exe')
    (tmpdir / 'file.exe').touch()
    (tmpdir / 'file.exe').chmod(0o755)
    assert run_arg_exp == lang.run_args(tmpdir / 'file.exe', ['arg1', 'arg2'])
    assert lang.exe_ext == default_exe_ext()

    lang = lang_manager['cpp.g++']
    compile_arg_exp = [
        cpp_compiler,
        fspath(Path.cwd() / 'file.cpp'), '-o',
        fspath(Path.cwd() / 'file.exe'), '-Ofast'
    ]
    compile_arg_found = lang.compile_args(Path('file.cpp'), Path('file.exe'))
    assert compile_arg_exp == compile_arg_found
    assert lang.exe_ext == '.42.exe'

    lang = lang_manager['sh.sh']
    assert lang.compile_args(Path('file.sh'), Path('file.exe')) is None
    run_arg_exp = [shutil.which('sh'), fspath(Path.cwd() / 'file.sh')]
    assert lang.run_args(Path('file.sh')) == run_arg_exp
    assert lang.exe_ext == '.sh'

    assert lang_manager.get_best_lang('.py').name == 'py.py3'
    with pytest.raises(LanguageError):
        lang_manager.get_best_lang('.red')
Example #29
0
def test_compiler(tmpdir, repo_manager, language_manager):
    tmpdir = Path(str(tmpdir))
    repo = repo_manager.repo

    lang_cpp = language_manager.get_lang('cpp.g++14')
    lang_py = language_manager.get_lang('py.py3')

    src_dir = tmpdir / 'src'
    src_dir.mkdir()

    for fname in ['code.cpp', 'compile_error.cpp', 'code_libs.cpp', 'code.py']:
        shutil.copy(fspath(tests_location() / fname), fspath(src_dir / fname))

    src_cpp1 = src_dir / 'code.cpp'
    src_cpp2 = src_dir / 'compile_error.cpp'
    src_cpp3 = src_dir / 'code_libs.cpp'
    src_py1 = src_dir / 'code.py'
    src_bad1 = src_dir / 'bad_code.py'
    src_bad2 = src_dir / 'bad_code2.py'

    exe_cpp1 = src_dir / ('1-code' + default_exe_ext())
    exe_py1 = src_dir / ('1-code' + default_exe_ext())

    with pytest.raises(CompileError):
        compiler = Compiler(repo, lang_cpp, src_cpp2)
        compiler.compile()
    with pytest.raises(CompileError):
        compiler = Compiler(repo, lang_cpp, src_py1)
        compiler.compile()
    with pytest.raises(CompileError):
        compiler = Compiler(repo, lang_py, src_bad1, src_bad2)
        compiler.compile()

    runner = Runner()
    runner.capture_stdout = True
    runner.capture_stderr = True

    compiler = Compiler(repo, lang_cpp, src_cpp1)
    compiler.compile()
    runner.parameters.executable = compiler.exe_file
    runner.run()
    assert runner.results.status == Status.OK
    assert runner.stdout == 'hello world\n'

    compiler = Compiler(repo,
                        lang_cpp,
                        src_cpp3,
                        library_dirs=[tests_location()])
    compiler.compile()
    runner.parameters.executable = compiler.exe_file
    runner.run()
    assert runner.results.status == Status.OK
    assert runner.stdout == 'hello world\n'

    compiler = Compiler(repo, lang_py, src_py1)
    compiler.compile()
    runner.parameters.executable = lang_py.run_args(compiler.exe_file)[0]
    runner.parameters.args = lang_py.run_args(compiler.exe_file)[1:]
    runner.run()
    assert runner.results.status == Status.OK
    assert runner.stdout == 'hello world\n'

    compiler = Compiler(repo, lang_cpp, src_cpp1, exe_cpp1)
    compiler.compile()
    runner.parameters.executable = exe_cpp1
    runner.run()
    assert runner.results.status == Status.OK
    assert runner.stdout == 'hello world\n'

    compiler = Compiler(repo, lang_py, src_py1, exe_py1)
    compiler.compile()
    runner.parameters.executable = lang_py.run_args(exe_py1)[0]
    runner.parameters.args = lang_py.run_args(exe_py1)[1:]
    runner.run()
    assert runner.results.status == Status.OK
    assert runner.stdout == 'hello world\n'