# LiquidCode Tester Система автоматической проверки решений задач по программированию (Online Judge) для платформы LiquidCode. ## Архитектура Проект состоит из трёх основных компонентов: ### 1. Gateway (Шлюз) - **Технология**: ASP.NET Core Web API - **Функции**: - Приём запросов на тестирование через REST API - Скачивание пакетов задач из Polygon - Маршрутизация запросов к соответствующим Worker'ам по языку программирования ### 2. Worker (Тестировщик) - **Технология**: ASP.NET Core Web API + компиляторы языков - **Функции**: - Компиляция пользовательского кода - Запуск в изолированной среде - Тестирование на наборе тестов - Контроль ограничений по времени и памяти - Отправка статусов на callback URL ### 3. Common (Общая библиотека) - **Технология**: .NET Class Library - **Функции**: Общие модели данных для Gateway и Worker ## Поддерживаемые языки - **C++** (текущая реализация) - Java (планируется) - Kotlin (планируется) - C# (планируется) ## Модель данных ### SubmitForTesterModel (запрос на тестирование) ```csharp public record SubmitForTesterModel( long Id, long MissionId, string Language, string LanguageVersion, string SourceCode, string PackageUrl, string CallbackUrl ); ``` ### TesterResponseModel (результат тестирования) ```csharp public record TesterResponseModel( long SubmitId, State State, // Waiting, Compiling, Testing, Done ErrorCode ErrorCode, // None, CompileError, RuntimeError, etc. string Message, int CurrentTest, int AmountOfTests ); ``` ## Быстрый старт ### Локальная разработка (Docker Compose) ```bash # Сборка и запуск всех сервисов docker-compose up --build # Gateway доступен на http://localhost:8080 # Worker доступен на http://localhost:8081 ``` ### Разработка без Docker ```bash # Сборка всего решения dotnet build # Запуск Gateway cd src/LiquidCode.Tester.Gateway dotnet run # Запуск Worker (в другом терминале) cd src/LiquidCode.Tester.Worker dotnet run ``` ## API Endpoints ### Gateway **POST /api/tester/submit** ```json { "id": 123, "missionId": 456, "language": "C++", "languageVersion": "17", "sourceCode": "#include \nint main() { ... }", "packageUrl": "https://example.com/package.zip", "callbackUrl": "https://example.com/api/submit/callback" } ``` **GET /api/tester/health** - Проверка состояния Gateway ### Worker **POST /api/test** - Принимает multipart/form-data с метаданными и ZIP файлом пакета **GET /api/test/health** - Проверка состояния Worker ## Процесс тестирования 1. **Приём запроса**: Gateway получает запрос с кодом и URL пакета 2. **Скачивание пакета**: Gateway скачивает Polygon пакет 3. **Маршрутизация**: Gateway отправляет запрос в Worker для нужного языка 4. **Парсинг**: Worker распаковывает и парсит пакет (тесты, лимиты) 5. **Компиляция**: Worker компилирует код (g++ для C++) 6. **Тестирование**: Worker последовательно запускает все тесты 7. **Callback**: Worker отправляет статусы на callback URL на каждом этапе 8. **Cleanup**: Worker удаляет временные файлы ## Изоляция и безопасность ### Текущая реализация - Процессы запускаются с ограничением по времени - Контроль памяти через PeakWorkingSet64 - Процессы убиваются при превышении лимитов ### Production рекомендации - Linux namespaces (PID, network, mount) - cgroups для контроля CPU и памяти - seccomp для ограничения системных вызовов - AppArmor/SELinux профили - chroot окружение - Отключение доступа к сети для тестируемого кода ## Деплой в Kubernetes См. [k8s/README.md](k8s/README.md) для подробной инструкции. ```bash # Быстрый деплой kubectl apply -f k8s/namespace.yaml kubectl apply -f k8s/configmap.yaml kubectl apply -f k8s/worker-cpp-deployment.yaml kubectl apply -f k8s/gateway-deployment.yaml ``` ## Конфигурация ### Gateway (appsettings.json) ```json { "PackageDownloadDirectory": "/tmp/packages", "Workers": { "Cpp": "http://liquidcode-tester-worker-cpp:8080" } } ``` ### Worker (appsettings.json) ```json { "Cpp": { "Compiler": "g++", "CompilerFlags": "-O2 -std=c++17 -Wall" } } ``` ## Структура проекта ``` LiquidCode.Tester/ ├── src/ │ ├── LiquidCode.Tester.Common/ # Общие модели │ │ └── Models/ │ ├── LiquidCode.Tester.Gateway/ # API Gateway │ │ ├── Controllers/ │ │ ├── Services/ │ │ └── Dockerfile │ └── LiquidCode.Tester.Worker/ # C++ Worker │ ├── Controllers/ │ ├── Services/ │ └── Dockerfile ├── k8s/ # Kubernetes манифесты ├── compose.yaml # Docker Compose └── README.md ``` ## Требования - .NET 9.0 SDK - Docker & Docker Compose (для контейнеризации) - g++ (для C++ Worker) - Kubernetes cluster (для production) ## Расширение на другие языки Для добавления поддержки нового языка: 1. Создайте новый Worker проект (или расширьте существующий) 2. Реализуйте `ICompilationService` для языка 3. Реализуйте `IExecutionService` для языка 4. Обновите конфигурацию Gateway 5. Создайте Dockerfile с нужным компилятором/runtime 6. Добавьте Kubernetes манифесты ## Разработка ### Структура кода - **Controllers**: REST API endpoints - **Services**: Бизнес-логика (компиляция, тестирование, callback) - **Models**: Модели данных ### Логирование Используется встроенный ILogger ASP.NET Core. ### Тестирование ```bash dotnet test ``` ## Лицензия [Укажите лицензию] ## Авторы LiquidCode Team