예제 #1
0
def change_name_test(objective_path):
    info[-1].add_test('change\nname')

    shutil.move(f'A2/{assignment_folder_name}/world_cities.csv',
                f'A2/{assignment_folder_name}/world_cities.tmp')

    run_input = """New York City
Hong Kong
bye"""

    print('[0] Change Name Test\n' 'Run with input:', style='bold magenta')
    print(run_input)

    out_str = run(f'./{objective_path}',
                  input_content=run_input,
                  print_msg="Run output")

    shutil.move(f'A2/{assignment_folder_name}/world_cities.tmp',
                f'A2/{assignment_folder_name}/world_cities.csv')

    # Check output
    if contains(out_str, 'world_cities.csv', 'miss', 'file'):
        print('PASS', style='bold green')
        info[-1].update_last(success=True)
    else:
        print('FAIL', style='bold red')
        info[-1].update_last(success=False)

    print('\n\n')
예제 #2
0
def auto_select_test(objective_path):
    info[-1].add_test('auto\nselect')

    run_input = """New York
Hong Kong
bye"""

    print('[2] Auto Select Test\n' 'Run with input:', style='bold magenta')
    print(run_input)

    out_str = run(f'./{objective_path}',
                  input_content=run_input,
                  print_msg="Run output")

    check_and_save(out_str)
예제 #3
0
def correctness_test(objective_path):
    info[-1].add_test('correct')

    run_input = """New York City
Hong Kong
bye"""

    print('[1] Correctness Test\n' 'Run with input:', style='bold magenta')
    print(run_input)

    out_str = run(f'./{objective_path}',
                  input_content=run_input,
                  print_msg="Run output")

    check_and_save(out_str)
예제 #4
0
def manual_select_test(objective_path):
    info[-1].add_test('manual\nselect')

    run_input = """New
Hong Kong
bye"""

    print('[3] Manually Select Test\n' 'Run with input:', style='bold magenta')
    print(run_input)

    out_str = run(f'./{objective_path}',
                  input_content=run_input,
                  print_msg="Run output")

    has_numbers = lambda s: any(char.isdigit() for char in s)

    # The correct distance is CORRECT_DISTANCE
    if out_str and f'{CORRECT_DISTANCE}' not in out_str:
        if 'New York City' in out_str:
            str_index = out_str.find('New York City')

            match = re.search(r"\d", out_str[:str_index][::-1])

            if match:
                index = str_index - match.start() - 1

            if match and abs(index - str_index) < 5:
                run_input = f"""New
{out_str[index]}
Hong Kong
bye"""
            else:
                print('No number before New York City! Using full NYC name.',
                      style='bold magenta')
                run_input = f"""New
New York City
Hong Kong
bye"""

            print(
                '[3.1] Manually Select Test with Full NYC Name\n'
                'Run with input:',
                style='bold magenta')
            print(run_input)
            out_str = run(f'./{objective_path}', input_content=run_input)

    check_and_save(out_str)
예제 #5
0
def case_insensitive_test(objective_path):
    info[-1].add_test('case\nsensitive')

    run_input = """NEw YoRk City
Hong KONG
bye"""

    print('[5] Case Insensitive Test\n'
          'Run with input:',
          style='bold magenta')
    print(run_input)

    out_str = run(f'./{objective_path}',
                  input_content=run_input,
                  print_msg="Run output")

    check_and_save(out_str)
예제 #6
0
def ignore_whitespace_test(objective_path):
    info[-1].add_test('ignore\nws')

    run_input = """  New York City 
Hong Kong
bye"""

    print('[4] Ignore Whitespace Test\n'
          'Run with input:',
          style='bold magenta')
    print(run_input)

    out_str = run(f'./{objective_path}',
                  input_content=run_input,
                  print_msg="Run output")

    check_and_save(out_str)
예제 #7
0
def run(command: str, input_content=None, print_msg=""):
    partial_run = partial(subprocess.run,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          cwd=f"A2/{assignment_folder_name}",
                          timeout=5,
                          encoding='utf-8')

    try:
        p = partial_run(command.split(" "), input=input_content)
        print_process(p, print_msg)

        return p.stdout
    except subprocess.TimeoutExpired as e:
        print("Time Out! Continue to next file.", style='bold red')
        print_process(e, "Error message:")

        return e.stdout.decode('utf-8')
예제 #8
0
def check_and_save(out_str: str):
    if f'{CORRECT_DISTANCE}' in out_str:
        print('PASS', style='bold green')
        info[-1].update_last(success=True)
    else:
        print('FAIL', style='bold red')
        info[-1].update_last(success=False)

    print('\n\n')

    return
예제 #9
0
def judge(file: str):
    print(f'Judging {file}', style='bold blue')
    info.add_student(file.replace('.cpp', ''))

    clang_path = "/home/linuxbrew/.linuxbrew/bin/clang++"
    objective_path = file.replace(".cpp", ".o")

    try:
        compile_test(clang_path, file, objective_path)
    except CompilerException as e:
        print('Compiler Error!', style='bold red')
        print('Continue to next file.', style='bold red')
        return

    change_name_test(objective_path)
    correctness_test(objective_path)
    auto_select_test(objective_path)
    manual_select_test(objective_path)
    ignore_whitespace_test(objective_path)
    case_insensitive_test(objective_path)
예제 #10
0
def print_process(p: subprocess.CompletedProcess, message: str):
    print(f"{message}:")
    print("Stdout:", style='bold green')

    if p.stdout:
        if len(p.stdout) > 20000:
            print(
                f'Stdout length too long: {len(p.stdout)}, only print firt 2000 letters.',
                style='bold red')
            print(p.stdout[:2000])
        else:
            print(p.stdout)

    if p.stderr:
        print("Stderr (Can be warning here!):", style='bold red')

        if len(p.stderr) > 20000:
            print(
                f'Stderr length too long: {len(p.stdout)}, only print firt 2000 letters.',
                style='bold red')
            print(p.stderr[:2000].decode('utf-8'))
        else:
            print(p.stderr, style='red')

        if 'compil' in message.lower() and 'error' in p.stderr.lower():
            raise CompilerException()
예제 #11
0
    clang_path = "/home/linuxbrew/.linuxbrew/bin/clang++"
    objective_path = file.replace(".cpp", ".o")

    try:
        compile_test(clang_path, file, objective_path)
    except CompilerException as e:
        print('Compiler Error!', style='bold red')
        print('Continue to next file.', style='bold red')
        return

    change_name_test(objective_path)
    correctness_test(objective_path)
    auto_select_test(objective_path)
    manual_select_test(objective_path)
    ignore_whitespace_test(objective_path)
    case_insensitive_test(objective_path)


if __name__ == '__main__':
    # judge('11911626.cpp')
    for root, dirs, files in os.walk(f'A2/{assignment_folder_name}'):
        valid_names = list(filter(lambda s: s.endswith('.cpp'), files))
        for filename in valid_names:
            judge(filename)
            print(
                '===============================================================',
                style='bold yellow')

    info.summary()