dee93134ae00b18f04eec1f398cd088d5d77116a
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 (запрос на тестирование)
public record SubmitForTesterModel(
long Id,
long MissionId,
string Language,
string LanguageVersion,
string SourceCode,
string PackageUrl,
string CallbackUrl
);
TesterResponseModel (результат тестирования)
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)
# Сборка и запуск всех сервисов
docker-compose up --build
# Gateway доступен на http://localhost:8080
# Worker доступен на http://localhost:8081
Разработка без Docker
# Сборка всего решения
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
{
"id": 123,
"missionId": 456,
"language": "C++",
"languageVersion": "17",
"sourceCode": "#include <iostream>\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
Процесс тестирования
- Приём запроса: Gateway получает запрос с кодом и URL пакета
- Скачивание пакета: Gateway скачивает Polygon пакет
- Маршрутизация: Gateway отправляет запрос в Worker для нужного языка
- Парсинг: Worker распаковывает и парсит пакет (тесты, лимиты)
- Компиляция: Worker компилирует код (g++ для C++)
- Тестирование: Worker последовательно запускает все тесты
- Callback: Worker отправляет статусы на callback URL на каждом этапе
- Cleanup: Worker удаляет временные файлы
Изоляция и безопасность
Текущая реализация
- Процессы запускаются с ограничением по времени
- Контроль памяти через PeakWorkingSet64
- Процессы убиваются при превышении лимитов
Production рекомендации
- Linux namespaces (PID, network, mount)
- cgroups для контроля CPU и памяти
- seccomp для ограничения системных вызовов
- AppArmor/SELinux профили
- chroot окружение
- Отключение доступа к сети для тестируемого кода
Деплой в Kubernetes
См. k8s/README.md для подробной инструкции.
# Быстрый деплой
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)
{
"PackageDownloadDirectory": "/tmp/packages",
"Workers": {
"Cpp": "http://liquidcode-tester-worker-cpp:8080"
}
}
Worker (appsettings.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)
Расширение на другие языки
Для добавления поддержки нового языка:
- Создайте новый Worker проект (или расширьте существующий)
- Реализуйте
ICompilationServiceдля языка - Реализуйте
IExecutionServiceдля языка - Обновите конфигурацию Gateway
- Создайте Dockerfile с нужным компилятором/runtime
- Добавьте Kubernetes манифесты
Разработка
Структура кода
- Controllers: REST API endpoints
- Services: Бизнес-логика (компиляция, тестирование, callback)
- Models: Модели данных
Логирование
Используется встроенный ILogger ASP.NET Core.
Тестирование
dotnet test
Лицензия
[Укажите лицензию]
Авторы
LiquidCode Team
Description
Languages
C#
46.4%
C++
38%
TeX
6.4%
Shell
3%
Batchfile
2.4%
Other
3.8%