remove k8s configs, update worker for multi-languages support, add local-submit option

This commit is contained in:
prixod
2025-10-27 21:28:46 +04:00
parent 7f0e7fbe20
commit 6041acb8ed
38 changed files with 2205 additions and 342 deletions

258
README.md
View File

@@ -13,10 +13,11 @@
- Скачивание пакетов задач из Polygon
- Маршрутизация запросов к соответствующим Worker'ам по языку программирования
### 2. Worker (Тестировщик)
- **Технология**: ASP.NET Core Web API + компиляторы языков
### 2. Worker (Универсальный тестировщик)
- **Технология**: ASP.NET Core Web API + компиляторы всех поддерживаемых языков
- **Функции**:
- Компиляция пользовательского кода
- Динамический выбор компилятора/интерпретатора на основе языка
- Компиляция пользовательского кода (C++, Java, Kotlin, C#) или подготовка к исполнению (Python)
- Запуск в изолированной среде
- Тестирование на наборе тестов
- Контроль ограничений по времени и памяти
@@ -28,10 +29,11 @@
## Поддерживаемые языки
- **C++** (текущая реализация)
- Java (планируется)
- Kotlin (планируется)
- C# (планируется)
- **C++** (реализовано)
- **Java** (реализовано)
- **Kotlin** (реализовано)
- **C#** (реализовано)
- **Python** (реализовано)
## Модель данных
@@ -87,11 +89,71 @@ cd src/LiquidCode.Tester.Worker
dotnet run
```
## Локальное тестирование
Для тестирования системы без внешних зависимостей используйте endpoint `/api/Tester/submit-local`:
### 1. Подготовка тестового пакета
Создайте ZIP файл с тестами в формате:
```
test-package.zip
├── 1.in # Входные данные для теста 1
├── 1.out # Ожидаемый результат для теста 1
├── 2.in # Входные данные для теста 2
├── 2.out # Ожидаемый результат для теста 2
└── ...
```
### 2. Отправка запроса
```bash
curl -X 'POST' \
'http://localhost:8080/api/Tester/submit-local' \
-F 'id=1' \
-F 'missionId=1' \
-F 'language=python' \
-F 'languageVersion=3.11' \
-F 'sourceCode=n = int(input())
print(n * 2)' \
-F 'callbackUrl=log' \
-F 'package=@./test-package.zip'
```
### 3. Просмотр результатов
При использовании `callbackUrl=log` результаты тестирования выводятся в консоль Worker:
```
╔═══════════════════════════════════════════════════════════════╗
║ CALLBACK RESULT ║
╠═══════════════════════════════════════════════════════════════╣
{
"submitId": 1,
"state": "Done",
"errorCode": "None",
"message": "All tests passed",
"currentTest": 3,
"amountOfTests": 3
}
╚═══════════════════════════════════════════════════════════════╝
```
### Специальные значения callbackUrl
- `"log"` - Вывод результатов в логи Worker
- `"console"` - Аналогично "log"
- `"log://"` - Аналогично "log"
- Любой HTTP URL - Отправка результатов на указанный endpoint
## API Endpoints
### Gateway
**POST /api/tester/submit**
Отправка решения с удаленным пакетом тестов:
```json
{
"id": 123,
@@ -104,6 +166,31 @@ dotnet run
}
```
**POST /api/tester/submit-local**
Отправка решения с локальным пакетом тестов (для отладки):
```bash
curl -X 'POST' \
'http://localhost:8080/api/Tester/submit-local' \
-F 'id=1' \
-F 'missionId=1' \
-F 'language=python' \
-F 'languageVersion=3.11' \
-F 'sourceCode=print("Hello, World!")' \
-F 'callbackUrl=log' \
-F 'package=@/path/to/test-package.zip'
```
**Параметры:**
- `id` - ID сабмита
- `missionId` - ID задачи
- `language` - Язык программирования (C++, Java, Kotlin, C#, Python)
- `languageVersion` - Версия языка (опционально, используется "latest" по умолчанию)
- `sourceCode` - Исходный код решения
- `callbackUrl` - URL для отправки результатов или `"log"` для вывода в консоль
- `package` - ZIP файл с тестами
**GET /api/tester/health**
- Проверка состояния Gateway
@@ -121,7 +208,7 @@ dotnet run
2. **Скачивание пакета**: Gateway скачивает Polygon пакет
3. **Маршрутизация**: Gateway отправляет запрос в Worker для нужного языка
4. **Парсинг**: Worker распаковывает и парсит пакет (тесты, лимиты)
5. **Компиляция**: Worker компилирует код (g++ для C++)
5. **Компиляция**: Worker выбирает нужный компилятор на основе языка и компилирует код
6. **Тестирование**: Worker последовательно запускает все тесты
7. **Callback**: Worker отправляет статусы на callback URL на каждом этапе
8. **Cleanup**: Worker удаляет временные файлы
@@ -141,17 +228,6 @@ dotnet run
- 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
```
## Конфигурация
@@ -160,7 +236,11 @@ kubectl apply -f k8s/gateway-deployment.yaml
{
"PackageDownloadDirectory": "/tmp/packages",
"Workers": {
"Cpp": "http://liquidcode-tester-worker-cpp:8080"
"Cpp": "http://localhost:8081",
"Java": "http://localhost:8081",
"Kotlin": "http://localhost:8081",
"CSharp": "http://localhost:8081",
"Python": "http://localhost:8081"
}
}
```
@@ -170,11 +250,115 @@ kubectl apply -f k8s/gateway-deployment.yaml
{
"Cpp": {
"Compiler": "g++",
"CompilerFlags": "-O2 -std=c++17 -Wall"
"CompilerFlags": "-O2 -std=c++17 -Wall",
"Versions": {
"14": {
"Compiler": "g++",
"CompilerFlags": "-O2 -std=c++14 -Wall"
},
"17": {
"Compiler": "g++",
"CompilerFlags": "-O2 -std=c++17 -Wall"
},
"20": {
"Compiler": "g++",
"CompilerFlags": "-O2 -std=c++20 -Wall"
}
}
},
"Java": {
"Compiler": "javac",
"CompilerFlags": "",
"Versions": {
"8": {
"Compiler": "javac",
"CompilerFlags": "-source 8 -target 8"
},
"11": {
"Compiler": "javac",
"CompilerFlags": "-source 11 -target 11"
},
"17": {
"Compiler": "javac",
"CompilerFlags": ""
}
}
},
"Kotlin": {
"Compiler": "kotlinc",
"CompilerFlags": "",
"Versions": {
"1.9": {
"Compiler": "kotlinc",
"CompilerFlags": ""
}
}
},
"CSharp": {
"Compiler": "csc",
"CompilerFlags": "/optimize+",
"Versions": {
"7": {
"Compiler": "csc",
"CompilerFlags": "/optimize+ /langversion:7"
},
"8": {
"Compiler": "csc",
"CompilerFlags": "/optimize+ /langversion:8"
},
"9": {
"Compiler": "csc",
"CompilerFlags": "/optimize+ /langversion:9"
}
}
},
"Python": {
"Executable": "python3",
"Versions": {
"3.8": {
"Executable": "python3.8"
},
"3.9": {
"Executable": "python3.9"
},
"3.10": {
"Executable": "python3.10"
},
"3.11": {
"Executable": "python3.11"
}
}
}
}
```
#### Поддержка версий языков
Система поддерживает указание версии языка программирования через параметр `languageVersion`:
- **"latest"** или **null** - использует версию по умолчанию из основной конфигурации
- **Конкретная версия** (например, "17", "3.11") - использует конфигурацию из секции `Versions`
- **Несуществующая версия** - логируется предупреждение и используется версия по умолчанию
Каждый язык имеет свою конфигурацию с возможностью указания:
- Для компилируемых языков (C++, Java, Kotlin, C#): путь к компилятору и флаги компиляции
- Для интерпретируемых языков (Python): путь к интерпретатору
Пример использования:
```bash
# Использование Python 3.11
curl -X POST 'http://localhost:8080/api/Tester/submit-local' \
-F 'languageVersion=3.11' \
-F 'language=python' \
...
# Использование C++20
curl -X POST 'http://localhost:8080/api/Tester/submit-local' \
-F 'languageVersion=20' \
-F 'language=C++' \
...
```
## Структура проекта
```
@@ -186,11 +370,13 @@ LiquidCode.Tester/
│ │ ├── Controllers/
│ │ ├── Services/
│ │ └── Dockerfile
│ └── LiquidCode.Tester.Worker/ # C++ Worker
│ └── LiquidCode.Tester.Worker/ # Универсальный Worker (все языки)
│ ├── Controllers/
│ ├── Services/
│ │ ├── Compilation/ # Компиляторы
│ │ ├── Execution/ # Исполнители
│ │ └── Factories/ # Фабрики
│ └── Dockerfile
├── k8s/ # Kubernetes манифесты
├── compose.yaml # Docker Compose
└── README.md
```
@@ -199,19 +385,29 @@ LiquidCode.Tester/
- .NET 9.0 SDK
- Docker & Docker Compose (для контейнеризации)
- g++ (для C++ Worker)
- Kubernetes cluster (для production)
- Компиляторы языков программирования (устанавливаются автоматически в Docker):
- g++ (C++)
- OpenJDK 17 (Java)
- Kotlin compiler (Kotlin)
- Mono (C#)
- Python 3
## Расширение на другие языки
Для добавления поддержки нового языка:
1. Создайте новый Worker проект (или расширьте существующий)
2. Реализуйте `ICompilationService` для языка
3. Реализуйте `IExecutionService` для языка
4. Обновите конфигурацию Gateway
5. Создайте Dockerfile с нужным компилятором/runtime
6. Добавьте Kubernetes манифесты
1. Создайте новую реализацию `ICompilationService` для языка (например, `GoCompilationService.cs`)
2. Создайте новую реализацию `IExecutionService` для языка (например, `GoExecutionService.cs`)
3. Зарегистрируйте новые сервисы в `Program.cs`:
```csharp
builder.Services.AddSingleton<GoCompilationService>();
builder.Services.AddSingleton<GoExecutionService>();
```
4. Обновите фабрики (`CompilationServiceFactory` и `ExecutionServiceFactory`), добавив поддержку нового языка
5. Добавьте конфигурацию языка в `appsettings.json` Worker
6. Обновите `Dockerfile` Worker, добавив установку компилятора/runtime
7. Добавьте конфигурацию воркера для нового языка в `appsettings.json` Gateway
8. Обновите `WorkerClientService` Gateway, добавив маппинг языка на URL воркера
## Разработка