remove k8s configs, update worker for multi-languages support, add local-submit option
This commit is contained in:
258
README.md
258
README.md
@@ -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 воркера
|
||||
|
||||
## Разработка
|
||||
|
||||
|
||||
Reference in New Issue
Block a user