Ejemplo n.º 1
0
        public ProgramTester(
            ref dynamic compilerConfiguration,
            ref ICompilerPlugin _compilerPlugin,
            string path,
            string args,
            long memoryLimit       = 0,
            int processorTimeLimit = 0,
            byte[] input           = null,
            int outputCharsLimit   = 0,
            bool adaptOutput       = true
            )
        {
            _compilerConfiguration = compilerConfiguration;
            this._compilerPlugin   = _compilerPlugin;

            _programPath      = path;
            _programArguments = args;

            _programMemoryLimit        = memoryLimit;
            _programProcessorTimeLimit = processorTimeLimit;

            _programInputBytes = input;
            _outputCharsLimit  = outputCharsLimit;

            _adaptOutput = adaptOutput;
        }
Ejemplo n.º 2
0
 private void LoadPluginTypes(List <string> pluginNames, string assemblyName)
 {
     try {
         Assembly pluginAssembly = Assembly.LoadFile(assemblyName);
         foreach (Type t in pluginAssembly.GetTypes())
         {
             if (typeof(ICompilerPlugin).IsAssignableFrom(t))
             {
                 ConstructorInfo constructor = t.GetConstructor(new Type[] { });
                 if (constructor == null)
                 {
                     Console.Error.WriteLine("Cannot load plugin type '{0}' because it doesn't have a parameterless constructor", t.Name);
                     continue;
                 }
                 ICompilerPlugin plugin = (ICompilerPlugin)Activator.CreateInstance(t);
                 if (pluginNames.Contains(plugin.Identifier))
                 {
                     Console.WriteLine("Loaded plugin '{0}'", plugin.Name);
                     _loadedPlugins.Add(plugin);
                 }
             }
         }
     } catch (Exception ex) {
         Console.Error.WriteLine("Failed to load assembly '{0}', {1}", assemblyName, ex.Message);
     }
 }
Ejemplo n.º 3
0
        /*
         * Функция определяет необходимые действия
         * при запуске  процесса пользовательского
         * или авторского решения задачи.
         */
        public static void SetExecInfoByFileExt(
            ref dynamic languageConfiguration,
            ref ICompilerPlugin _compilerPlugin,
            ref ProcessStartInfo startInfo,
            string filePath,
            string arguments
            )
        {
            /*
             * Вызываем ассоциированный метод,
             * который  знает  лучше, как  это
             * делать.
             */
            var f = _compilerPlugin.SetRunningMethod(
                ref languageConfiguration,
                ref startInfo,
                filePath
                );

            /*
             * Добавляем к этому всему
             * аргументы коммандной строки.
             */
            if (startInfo.Arguments.Length > 0)
            {
                startInfo.Arguments += " " + arguments;
            }
            else
            {
                startInfo.Arguments = arguments;
            }

            /*
             * В случае возникновения непредвиденных
             * ошибок выбрасываем исключение.
             */
            if (!f)
            {
                throw new SimplePM_Exceptions.UnknownException("SetRunningMethod() failed!");
            }
        }
Ejemplo n.º 4
0
        private ICompilerPlugin _compilerPlugin; // Список загруженных модулей компиляторв

        public SimplePM_Compiler(
            ref dynamic _compilerConfig,
            ref ICompilerPlugin _compilerPlugin,
            string submissionId,
            string fileLocation
            )
        {
            // Проверяем путь к исходному коду на ошибки
            if (string.IsNullOrEmpty(fileLocation) || string.IsNullOrWhiteSpace(fileLocation) || !File.Exists(fileLocation))
            {
                throw new FileNotFoundException("File not found!", "fileLocation");
            }

            /*
             * Присваиваем глобальным для класса переменным
             * значения локальных  переменных  конструктора
             * класса.
             */
            this._compilerConfig = _compilerConfig;
            this._compilerPlugin = _compilerPlugin;
            _submissionId        = submissionId;
            _fileLocation        = fileLocation;
        }
Ejemplo n.º 5
0
        private ProgramTestingResult RunTesting(
            CompilerResult cResult,
            ref dynamic compilerConfiguration,
            ref ICompilerPlugin compilerPlugin
            )
        {
            /*
             * Записываем   в   лог-файл  информацию  о  том,
             * что в данный  момент  производим  тестирование
             * пользовательского решения поставленной задачи.
             */

            logger.Trace(
                "#" + _submissionInfo.SubmissionId +
                ": Running solution testing subsystem (" +
                _submissionInfo.TestType +
                " mode)..."
                );

            /*
             * Объявляем временную переменную,
             * которая будет хранить результат
             * выполнения тестирования пользо-
             * вательской программы.
             */

            ProgramTestingResult tmpResult = null;

            /*
             * Объявляем  объект на базе класса
             * тестировщика, с помощью которого
             * в скором времени будем выполнять
             * тестировани пользовательских ре-
             * шений задач по программированию.
             */

            var tester = new SimplePM_Tester.SimplePM_Tester(
                ref _connection,
                ref _serverConfiguration,
                ref _compilerConfigurations,
                ref _compilerPlugins,
                cResult.ExeFullname,
                ref _submissionInfo
                );

            /*
             * Выполняем тестирование в блоке обработки
             * исключительных систуаций,  и,  в  случае
             * возникновения такой  ситуации записываем
             * данные о ней в лог-файл  и  искусственно
             * создаём     результаты      тестирования
             * пользовательского решения задачи.
             */

            try
            {
                /*
                 * В зависимости от выбранного пользователем
                 * типа тестирования выполняем специфические
                 * операции по отношению к решению задачи.
                 */

                switch (_submissionInfo.TestType)
                {
                /* Проверка синтаксиса */
                case "syntax":

                    /*
                     * Вызываем   метод,   который   создаёт
                     * иллюзию  проверки   пользовательского
                     * решения    поставленной    задачи   и
                     * возвращает результаты своей "работы".
                     */

                    tmpResult = tester.Syntax();

                    break;

                /* Debug-тестирование */
                case "debug":

                    /*
                     * Вызываем метод Debug-тестирования
                     * пользовательского решения постав-
                     * ленной задачи по программированию
                     */

                    tmpResult = tester.Debug();

                    break;

                /* Release-тестирование */
                case "release":

                    /*
                     * Вызываем метод Release-тестирования
                     * пользовательского  решения  постав-
                     * ленной задачи  по  программированию
                     */

                    tmpResult = tester.Release(
                        ref compilerConfiguration,
                        ref compilerPlugin
                        );

                    break;
                }
            }
            catch (Exception ex)
            {
                // Записываем информацию об исключении в лог
                logger.Error(ex);

                /*
                 * Создаём псевдорезультат тестирования,
                 * который будет содержать информацию о
                 * возникшем во время тестирования поль-
                 * зовательского решения задачи исключе-
                 * нии.
                 */

                tmpResult = new ProgramTestingResult(1)
                {
                    /*
                     * Создаём превдотест и добавляем его
                     * в массив результатов тестирования.
                     */
                    TestingResults =
                    {
                        [0] = new TestResult
                        {
                        // За код выхода принимаем номер исклбчения
                        ExitCode = ex.HResult,

                        // За выходной поток ошибок принимаем исключение
                        ErrorOutput = ex.ToString(),

                        // Заполняем выходные данные информацией (not null)
                        Output = Encoding.UTF8.GetBytes("An exception occured during testing!"),

                        // Устанавливаем результат тестирования
                        Result = TestResult.ErrorOutputNotNullResult,

                        /*
                         * Указываем, что память и процессорное
                         * время не были использованы.
                         */

                        UsedMemory        = 0,
                        UsedProcessorTime = 0
                        }
                    }
                };
            }

            /*
             * Возвращаем результат выполнения
             * тестирования  пользовательского
             * решения данной задачи.
             */

            return(tmpResult);
        }
Ejemplo n.º 6
0
        public ProgramTestingResult Release(
            ref dynamic compilerConfiguration,
            ref ICompilerPlugin compilerPlugin
            )
        {
            /*
             * Получаем информацию о тестах
             * для     release-тестирования
             * пользовательского    решения
             * посталвенной задачи.
             */

            var ReleaseTestsInfo = GetTestsInfo();

            /*
             * Сохраняем первоначальное количество
             * тестов в отдельной переменной, дабы
             * не затерять   эту   информацию  при
             * видоизменении очереди.
             */

            var testsCount = ReleaseTestsInfo.Count;

            /*
             * Создаём объект,  который будет
             * хранить  результаты  релизного
             * тестирования пользовательского
             * решения  поставленной  задачи.
             */

            var programTestingResult = new ProgramTestingResult(testsCount);

            /*
             * В цикле  тестируем  пользовательское
             * решение   поставленной   задачи   на
             * заранее  подготовленных   тестах   и
             * записываем  результаты  проверки  по
             * каждому тесту в специально созданный
             * для этих нужд массив.
             */

            for (var currentTestIndex = 0; currentTestIndex < testsCount; currentTestIndex++)
            {
                /*
                 * Делаем выборку  данных о текущем
                 * релизном тесте из очереди тестов
                 */

                var currentTest = ReleaseTestsInfo.Dequeue();

                /*
                 * Запускаем  тестирование  пользовательского
                 * решения поставленной задачи  на  указанном
                 * тесте и получаем  промежуточные результаты
                 * тестирования, заносим их в соответственную
                 * переменную,  созданную специально для этих
                 * нужд.
                 */

                var currentTestResult = new ProgramTester(
                    ref compilerConfiguration,
                    ref compilerPlugin,
                    exeFileUrl,
                    "",
                    currentTest.MemoryLimit,
                    currentTest.ProcessorTimeLimit,
                    currentTest.InputData,
                    Encoding.UTF8.GetString(currentTest.OutputData).Length * 2,
                    submissionInfo.ProblemInformation.AdaptProgramOutput
                    ).RunTesting();

                /*
                 * Если временный  результат  успешен,
                 * проводим   финальную   перепроверку
                 * результата тестирования  на  данном
                 * тесте и выносим финальный результат
                 * данного теста.
                 */

                if (currentTestResult.Result == TestResult.MiddleSuccessResult)
                {
                    /*
                     * Сравнение выходных потоков
                     * и вынесение  результата по
                     * данному тесту.
                     */
                    currentTestResult.Result =
                        Convert.ToBase64String(currentTestResult.Output) == Convert.ToBase64String(currentTest.OutputData)
                            ? TestResult.FullSuccessResult
                            : TestResult.FullNoSuccessResult;
                }

                /*
                 * Заносим результат проведения
                 * текущего теста в специальный
                 * массив.
                 */

                programTestingResult.TestingResults[currentTestIndex] = currentTestResult;
            }

            /*
             * Возвращаем информацию  о  тестировании
             * пользовательского решения поставленной
             * задачи.
             */

            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);
        }