Exemple #1
0
 def debug(cls, input: str, content: str) -> dict:
     files = DebugFiles(data_in=clear_text(input), data_cpp=clear_text(content))
     container = cls._get_docker_container()
     exit_code, result = container.exec_run(
         cmd=f'bash -c "timeout {cls.conf["timeout"]} c++ {files.filename_cpp} -o {files.filename_out} < {files.filename_in}"',
         stream=True, demux=True, user=cls.conf['user']
     )
     print('===', exit_code, result)
     #
     # if not error:
     #     p2 = subprocess.Popen(
     #         args=[tmp.file_out_dir],
     #         stdin=subprocess.PIPE,
     #         stdout=subprocess.PIPE,
     #         stderr=subprocess.PIPE,
     #         cwd=settings.TMP_DIR,
     #     )
     #     try:
     #         stdout, stderr = p2.communicate(input=stdin)
     #         output, error = cls._get_decoded(stdout=stdout, stderr=stderr)
     #     except subprocess.TimeoutExpired:
     #         output, error = '', msg.CPP__02
     #     finally:
     #         p2.kill()
     #
     # tmp.remove_file_cpp()
     # tmp.remove_file_out()
     return {
         'output': 'output',
         'error': 'error',
     }
Exemple #2
0
    def check_tests(cls, content: str, task: Task) -> dict:
        """ Запускает код на наборе тестов в docker-песочнице и возвращает результаты тестирования """

        compare_method_name = f'_compare_{task.output_type}'
        compare_method = getattr(cls, compare_method_name)
        files = TestsFiles(data_py=clear_text(content))
        container = cls._get_docker_container()
        tests_data = []
        tests_num_success = 0
        for test in task.tests:
            filename_in = files.create_file_in(
                data_in=clear_text(test['input']))
            exit_code, result = container.exec_run(
                cmd=
                f'bash -c "timeout {conf["timeout"]} python {files.filename_py} < {filename_in}"',
                stream=True,
                demux=True,
                user=conf['user'])
            try:
                stdout, stderr = next(result)
            except StopIteration:
                output, error = '', ''
            else:
                output, error = cls._get_decoded(stdout=stdout, stderr=stderr)
            if error:
                success = False
            else:
                success = compare_method(etalon=clear_text(test['output']),
                                         val=clear_text(output))
            tests_num_success += success

            tests_data.append({
                "output": clear_text(output),
                "error": error,
                "success": success
            })

        files.remove()

        tests_num = len(task.tests)
        cls._check_zombie_procs()
        return {
            'num': tests_num,
            'num_success': tests_num_success,
            'data': tests_data,
            'success': tests_num == tests_num_success,
        }
Exemple #3
0
    def _process_error_msg(cls, msg: str):
        """ Обработка текста сообщения об ошибке """

        result = clear_text(re.sub(r'\s*File.+.py",', "", msg))
        if 'Terminated' in result:
            result = msg_utils.PYTHON__02
        if 'Read-only file system' in result:
            result = msg_utils.PYTHON__01
        return result
Exemple #4
0
    def debug(cls, input: str, content: str) -> dict:
        """ Запускает код в docker-песочнице и возвращает результаты """

        files = DebugFiles(data_in=clear_text(input),
                           data_py=clear_text(content))
        container = cls._get_docker_container()
        exit_code, result = container.exec_run(
            cmd=
            f'bash -c "timeout {conf["timeout"]} python {files.filename_py} < {files.filename_in}"',
            stream=True,
            demux=True,
            user=conf['user'])
        try:
            stdout, stderr = next(result)
        except StopIteration:
            output, error = '', ''
        else:
            output, error = cls._get_decoded(stdout=stdout, stderr=stderr)
        files.remove()
        cls._check_zombie_procs()
        return {'output': output, 'error': error}
Exemple #5
0
    def check_tests(cls, content: str, task: Task, **kwargs) -> dict:
        compare_method_name = f'_compare_{task.output_type}'  #имя метода сравнения результатов
        compare_method = getattr(cls, compare_method_name)
        tests_data = []
        tests_num_success = 0
        ind = 0  #индекс б.д. текущего теста
        for test in task.tests:  #почему несколько файлов б.д.
            ind += 1
            error = ""
            output = ""
            success = False
            try:
                #create_db("bd_"+str(ind)+".db", kwargs['session_key'] + ".db")#все б.д. назвать bd_1, bd_2 и т.д.
                create_db("bd_" + str(ind) + ".db",
                          "kappa" + ".db")  #для юнит тестов
                BASE_DIR = os.path.dirname(os.path.abspath(__file__))
                #db_path = os.path.join(BASE_DIR, "users_db",kwargs['session_key']+".db")#путь к б.д. пользователя
                db_path = os.path.join(BASE_DIR, "users_db",
                                       "kappa" + ".db")  #для юнит тестов
                conn = sqlite3.connect(
                    db_path)  #стандартное выполнение запроса в sqlite3
                c = conn.cursor()
                c.execute(content)
                conn.commit()
            except Exception as e:
                error = str(e)
                conn.close()
                #os.remove(os.path.join(BASE_DIR, "users_db", kwargs['session_key'] + ".db"))
                os.remove(os.path.join(BASE_DIR, "users_db",
                                       "kappa" + ".db"))  #для юнит тестов
            else:
                if "sqlselect" not in compare_method_name:  #не изм. б.д. запрос
                    for res in c.fetchall():
                        output += str(res) + "\n"
                    success = compare_method(etalon=clear_text(test['output']),
                                             val=clear_text(output))
                    c.close()
                else:  #изм. б.д. запрос
                    c.execute(test['input'])
                    for res in c.fetchall():
                        output += str(res) + "\n"
                    c.close()
                    success = compare_method(etalon=test["output"], val=output)

            tests_num_success += success

            tests_data.append({
                "output": output,
                "error": error,
                "success": success
            })
        try:
            #os.remove(os.path.join(BASE_DIR, "users_db", kwargs['session_key'] + ".db"))
            os.remove(os.path.join(BASE_DIR, "users_db",
                                   "kappa" + ".db"))  #для юнит тестов
        except:
            pass
        tests_num = len(task.tests)
        return {
            'num': tests_num,
            'num_success': tests_num_success,
            'data': tests_data,
            'success': tests_num == tests_num_success,
        }
Exemple #6
0
    def check_tests(cls, content: str, task: Task) -> dict:
        tmp = TmpFiles(clear_text(content))

        compare_method_name = f'_compare_{task.output_type}'
        compare_method = getattr(cls, compare_method_name)

        tests_data = []
        tests_num_success = 0
        args = ['c++', tmp.file_cpp_dir, '-o', tmp.filename_out]
        for test in task.tests:
            p1 = subprocess.Popen(
                args=args,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=settings.TMP_DIR,
            )

            stdin = test['input'].encode('utf-8')
            stdout, stderr = p1.communicate(input=stdin)
            p1.wait()
            p1.kill()
            output, error = cls._get_decoded(stdout, stderr)

            if not error:
                p2 = subprocess.Popen(
                    args=[tmp.file_out_dir],
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    cwd=settings.TMP_DIR,
                )
                try:
                    stdout, stderr = p2.communicate(stdin)
                    output, error = cls._get_decoded(stdout=stdout,
                                                     stderr=stderr)
                    tmp.remove_file_out()
                except subprocess.TimeoutExpired:
                    output, error = '', msg.CPP__02
                finally:
                    p2.kill()

            if error:
                success = False
            else:
                success = compare_method(etalon=clear_text(test['output']),
                                         val=clear_text(output))
            tests_num_success += success

            tests_data.append({
                "output": output,
                "error": error,
                "success": success
            })

        tmp.remove_file_cpp()
        tmp.remove_file_out()
        tests_num = len(task.tests)

        return {
            'num': tests_num,
            'num_success': tests_num_success,
            'data': tests_data,
            'success': tests_num == tests_num_success
        }