Test framework for Picodata plugins
- Test framework for Picodata plugins
Описание
Picotest - это фреймворк для тестирования плагинов, созданных в окружении pike.
Для использования Picotest требуется выполнить следующие действия:
- Установить pike:
- Добавить зависимости в
Cargo.tomlплагина:
Совместимость с Picodata
| Picotest | Picodata |
|---|---|
| >= 1.4.0 | 25.2.1 |
| >= 1.4.0 | 25.1.2 |
| < 1.4.0 | 25.1.1 |
Интеграционное тестирование
Интеграционные тесты предназначены для тестирования публичного интерфейса компонентов кластера. Для написания интеграционных тестов необходимо добавить #[picotest] к функции или модулю как показано здесь.
Каждый интеграционный тест исполняется в отдельном процессе и никак не зависит от запущенного кластера. Пользователю предлагается использовать эти группы тестов как сценарии взаимодействия с удаленным кластером через доступные порты, эндпоинты и любые другие публичные точки доступа.
Например, тест может отправлять HTTP запрос напрямую на конкретный URL, который "слушает" инстанс кластера.
graph TD;
A[picotest process] -->|sends HTTP request| C[Cluster];
subgraph Picodata Cluster
direction TB
C[Instance 1]
D[Instance 2]
E[Instance 3]
end
Важно понимать, что в коде таких тестов любое использование примитивов из окружения Пикодаты не представляется возможным, поскольку такие тесты компилируются в обычный исполняемый файл средствами компилятора Rust без каких-либо специфичных для Tarantool рантайма зависимостей.
Если необходимо протестировать конкретный функционал "внутри" кластера, который требует Tarantool runtime, то можно воспользоваться окружением юнит-тестов.
Использование #[picotest]
Макрос #[picotest] используется для написания интеграционных тестов и может применяться как к функциям, так и к модулям.
При использовании макроса на модуле, Picotest автоматически пометит все функции модуля, названия которых начинаются с test_, как rstest-функции.
use *;
Переменные окружения
WAIT_VSHARD_DISCOVERY
- Описание: управляет ожиданием инициализация vshard'a и завершением решардинга. Если включено, то после старта инстансов в кластере пикотест будет ждать завершения решардинга и синхронизации состояний инстансов с vshard'ом
- Допустимые значения:
true/false - Значение по умолчанию:
true
Совместимость с rstest
Макрос #[picotest] является оберткой над rstest, поэтому поддерживает использование:
fixture.
once
case
use picotest;
Атрибуты макроса #[picotest]
| Название | Описание | Значение по умолчанию |
|---|---|---|
path |
Путь до директории, содержащей файл топологии плагина (topology.toml) | Определяется автоматически |
Применение конфигурации плагина к запущенному кластеру Picodata
Picotest позволяет менять конфигурацию сервисов плагина во время исполнения интеграционного теста.
Изменение конфигурации происходит с помощью метода Cluster::apply_config, который доступен при использовании макроса #[picotest].
Формат конфигурации должен соответствовать маппингу YAML, заданному в plugin_config.yaml.
Пример:
Допустим конфигурация плагина с одним сервисом "router" задана следующим образом:
router:
rpc_endpoint: "/hello"
max_rpc_message_size_bytes: 1024
max_rpc_message_queue_size: 2048
Тогда интеграционный тест, изменяющий данную конфигурацию, может выглядеть следующим образом:
Подробнее в описании метода Cluster::apply_config.
Модульное тестирование
Юнит-тестирование (или модульное тестирование) предназначено для проверки отдельных, изолированных частей кода внутри кластера. Такие тесты необходимы, когда верифицируется код, использующий зависимости рантайма Пикодаты.
Picotest исполняет код юнит-тестов в окружении одного из инстансов Пикодаты.
graph TD;
subgraph Picodata Instance
direction TB
C[Tarantool runtime]
D[picotest unit]
end
Для написания юнит-тестов необходимо добавить атрибут #[picotest_unit] как показано в примерах использования.
Требования к конфигурации
Для работы юнит-тестов крейт должен быть объявлен как библиотека с поддержкой динамической линковки.
В Cargo.toml пакета необходимо указать:
[]
= ["cdylib"]
Примеры использования
Запуск тестов
Тесты запускаются через интерфейс cargo test:
Ограничения
#[picotest_unit]не может использоваться в модуле под#[cfg(test)].
Пример неверного использования макроса:
Пример верного использования макроса:
По скольку каждый юнит-тест компилируется и линкуется в динамическую библиотеку плагина (см. Структура плагина), он не должен быть задан в конфигурации, отличной от debug. В противном случае при сборке тестов они будут проигнорированы компилятором.
#[picotest_unit]не может использоваться совместно с другими атрибутами.
Все атрибуты используемые совместно с макросом #[picotest_unit] будут отброшены.
В примере ниже #[should_panic] будет отброшен в процессе компиляции.
Управление кластером в Picotest
Picotest обеспечивает полную изоляцию тестовых окружений за счет автоматического управления жизненным циклом кластера.
При написании тестов предлагается придерживаться следующей структуры файлов в проекте плагина.
Структура файлов плагина
Важно учитывать, что Picotest создает отдельный кластер для каждого исполняемого файла:
- При написании юнит-тестов будет развёрнут один кластер в пределах одного крейта;
- При написании интеграционных тестов кластер будет изолирован в пределах одного файла, поскольку
каждый
.rsфайл вtests/компилируется как самостоятельный исполняемый модуль.
Таким образом, в вышеописанной структуре файлов каждый файл test1.rs - testN.rs получит свой кластер, а
все юнит-тесты из src/ будут бежать на одном и том же single-node кластере.
Создание кластера вручную
Picotest позволяет создавать и удалять кластер без использования макроса #[picotest].
use rstest;
Подключение по Postrges протоколу
Picotest при запуске создаст дополнительного пользователя и назначит права на создание таблиц
User: Picotest
Password: Pic0test
Пример использования pgproto
use *;
use ;
use ;
Тестирование RPC ручек плагина
Для тестирования RPC ручек плагинов, предлагается использовать функцию PicotestInstance::execute_rpc, вызванную на конкретном инстансе, на котором задан RPC endpoint.
Аргументы функции:
- plugin_name - имя плагина
- path - имя эндпоинта, например
/test - service_name - имя сервиса, например
main - plugin_version - версия плагина, например
0.1.0 - input - тело запроса, например структура
User { ... }
Тип тела запроса и возвращаемого значения определяется через шаблонные параметры.
Для тестов необходим асинхронный рантайм, поэтому необходимо указать макрос #[tokio::test] и добавить к самому тесту модификатор async.
Пример теста:
async
Покдлючение к admin консоли и выполнение sql/lua
Для выполнения кода из консоли администратора на первом инстансе воспользуйтесь:
Если существует необходимость выполнить скрипт на любом другом инстансе:
Принудительная остановка инстанса
Метод stop_instance позволяет остановить конкретный экземпляр (instance) внутри кластера Picotest.
Пример использования