/* * Функция, ответственная за debug * тестирование пользовательских * решений. */ public ProgramTestingResult Debug() { /* * Переменная хранит полный путь * к запускаемому файлу авторского * решения задачи */ var authorSolutionExePath = GetAuthorSolutionExePath( out var authorLanguageConfiguration, out var authorCompilerPlugin ); /* * Передаём новосозданным переменным * информацию о лимитах для пользовательского * процесса (пользовательского решения задачи) */ GetDebugProgramLimits( out var memoryLimit, // переменная, хранящая значение лимита по памяти out var timeLimit // переменная, хранящая значение лимита по процессорному времени ); /* * Проводим нетестовый запуск авторского решения * и получаем всё необходимое для тестирования * пользовательской программы */ var authorTestingResult = new ProgramTester( ref authorLanguageConfiguration, ref authorCompilerPlugin, authorSolutionExePath, "-author-solution", memoryLimit, timeLimit, submissionInfo.CustomTest, 0, submissionInfo.ProblemInformation.AdaptProgramOutput ).RunTesting(); /* * Проверяем, успешно ли проведен запуск * авторского решения задачи. В случае * обнаружения каких-либо ошибок выбрасываем * исключение AuthorSolutionRunningException, * которое информирует улавливатель исключений * о необходимости предоставления информации * об ошибке в лог-файлах сервера и прочих * местах, где это важно и необходимо. */ if (authorTestingResult.Result != TestResult.MiddleSuccessResult) { throw new SimplePM_Exceptions.AuthorSolutionRunningException(); } /* * Получаем ссылку на объект, который * хранит информацию о конфигурации * компиляционного модуля для данного * языка программирования. */ var userLanguageConfiguration = SimplePM_Compiler.GetCompilerConfig( ref _languageConfigurations, submissionInfo.CodeLang ); /* * Получаем ссылку на объект, * созданный на основании класса, * который, в свою очередь, создан * по подобию интерфейса ICompilerPlugin. */ var userCompilerPlugin = SimplePM_Compiler.FindCompilerPlugin( ref _compilerPlugins, (string)userLanguageConfiguration.module_name ); /* * Проводим тестовый запуск пользовательского * решения поставленной задачи и получаем всё * необходимое для тестирования программы. */ var userTestingResult = new ProgramTester( ref userLanguageConfiguration, ref userCompilerPlugin, exeFileUrl, "-user-solution", memoryLimit, timeLimit, submissionInfo.CustomTest, Encoding.UTF8.GetString(authorTestingResult.Output).Length, submissionInfo.ProblemInformation.AdaptProgramOutput ).RunTesting(); /* * Если результат тестирования не полностью * известен, осуществляем проверку по дополнительным * тестам и выдвигаем остаточный результат debug * тестирования пользовательского решения задачи. */ if (userTestingResult.Result == TestResult.MiddleSuccessResult) { userTestingResult.Result = Convert.ToBase64String(userTestingResult.Output) == Convert.ToBase64String(authorTestingResult.Output) ? TestResult.FullSuccessResult : TestResult.FullNoSuccessResult; } /* * Формируем результат тестирования пользовательского * решения поставленной задачи, добавляем информацию * о единственном тесте, который был проведен * непосредственно при тестировании данного * пользовательского решения данной задачи. */ var programTestingResult = new ProgramTestingResult(1) { TestingResults = { [0] = userTestingResult } }; /* * Возвращаем сформированный результат * тестирования пользовательского * решения поставленной задачи. */ return(programTestingResult); }
/* * Функция, ответственная за скачивание, * компиляцию и получение полного пути * к авторскому решению поставленной * задачи. */ private string GetAuthorSolutionExePath( out dynamic authorLanguageConfiguration, out ICompilerPlugin authorCompilerPlugin ) { /* * Получаем ссылку на объект, который * хранит информацию о конфигурации * компиляционного модуля для данного * языка программирования. */ authorLanguageConfiguration = SimplePM_Compiler.GetCompilerConfig( ref _languageConfigurations, submissionInfo.ProblemInformation.AuthorSolutionCodeLanguage ); /* * Получаем ссылку на объект, * созданный на основании класса, * который, в свою очередь, создан * по подобию интерфейса ICompilerPlugin. */ authorCompilerPlugin = SimplePM_Compiler.FindCompilerPlugin( ref _compilerPlugins, (string)authorLanguageConfiguration.module_name ); /* * Компиляция авторского решения * поставленной задачи с последующим * возвращением результатов компиляции. */ // Определяем расширение файла var authorFileExt = "." + (string)authorLanguageConfiguration.source_ext; // Получаем случайный путь к директории авторского решения var tmpAuthorDir = (string)_serverConfiguration.path.temp + @"\author\" + Guid.NewGuid() + @"\"; // Создаём папку текущего авторского решения задачи Directory.CreateDirectory(tmpAuthorDir); // Определяем путь хранения файла исходного кода вторского решения var tmpAuthorSrcLocation = tmpAuthorDir + "sa" + submissionInfo.SubmissionId + authorFileExt; // Записываем исходный код авторского решения в заданный временный файл File.WriteAllBytes( tmpAuthorSrcLocation, submissionInfo.ProblemInformation.AuthorSolutionCode ); // Устанавливаем его аттрибуты File.SetAttributes( tmpAuthorSrcLocation, FileAttributes.Temporary | FileAttributes.NotContentIndexed ); // Инициализируем экземпляр класса компилятора var compiler = new SimplePM_Compiler( ref authorLanguageConfiguration, ref authorCompilerPlugin, "a" + submissionInfo.SubmissionId, tmpAuthorSrcLocation ); // Получаем структуру результата компиляции var cResult = compiler.ChooseCompilerAndRun(); /* * В случае возникновения ошибки при компиляции * авторского решения аварийно завершаем работу * функции и выбрасываем исключение, содержащее * информацию о файле и причине ошибки при его * открытии. */ if (cResult.HasErrors) { throw new FileLoadException(cResult.ExeFullname); } /* * Возвращаем полный путь к исполняемому * файлу авторского решения данной задачи. */ return(cResult.ExeFullname); }