Тестирование пакета
Как проверять пакет до публикации: от smoke-теста до mock.
На этой странице
Тестирование гарантирует, что пакет работает корректно и не ломает систему. Перед публикацией лучше идти от дешёвых проверок к дорогим: сначала статический анализ и локальная сборка, потом smoke-тест, затем чистая среда (mock или ABF).
Уровни тестирования
1. rpmlint ← Статический анализ SPEC и RPM
2. Локальная сборка ← Пакет вообще собирается
3. %check ← Unit-тесты upstream
4. Установка ← Пакет ставится без ошибок
5. Smoke-тест ← Приложение запускается и работает
6. Зависимости ← Корректные Requires, нет лишних
7. mock / ABF ← Чистое окружение (как на сборочной ферме)
Уровень 1: rpmlint
rpmlint mypackage.spec
rpmlint ~/rpmbuild/RPMS/x86_64/mypackage-*.rpm
Подробности в разделе rpmlint.
Уровень 2: Локальная сборка
rpmbuild -ba mypackage.spec
Этот шаг не доказывает, что пакет воспроизводим, но быстро показывает синтаксические проблемы в SPEC, ошибки %install и очевидные промахи в %files.
Уровень 3: Unit-тесты (%check)
Секция %check запускает тесты, предоставляемые upstream:
%check
# C/C++ (CTest)
%ctest
# Python
%pytest -q
# Rust
cargo test --release --locked
# Go
go test ./...
# Make-based
make check
Когда тесты нужно делать опциональными
%bcond_with tests
%if %{with tests}
BuildRequires: python3-pytest
BuildRequires: python3-mock
%endif
%check
%if %{with tests}
%pytest -q -k "not network"
%endif
Причины:
- Тесты требуют сеть (на ABF обычно недоступна)
- Тесты требуют специальное оборудование (GPU, звуковую карту)
- Тесты нестабильны (flaky) и ломают сборку случайно
- Тесты требуют запущенные сервисы (БД, X11)
Пропуск отдельных тестов
%check
# Пропустить сетевые тесты
%pytest -k "not (test_download or test_upload)"
# Пропустить по маркеру
%pytest -m "not network"
# CTest: исключить по имени
%ctest --exclude-regex "test_network|test_integration"
В ROSA хороший тон — не просто отключить тесты, а оставить в SPEC комментарий, почему это сделано и при каких условиях тесты можно вернуть.
Уровень 4: Тест на установку
# Установить собранный пакет
sudo dnf install ~/rpmbuild/RPMS/x86_64/mypackage-*.rpm
# Проверить, что установилось
rpm -q mypackage
rpm -ql mypackage
# Проверить зависимости
rpm -qR mypackage
Установка в чистом окружении (через mock)
# Создать чистое окружение
mock -r <профиль_из_/etc/mock> --init
# Установить пакет в него
mock -r <профиль_из_/etc/mock> --install ~/rpmbuild/RPMS/x86_64/mypackage-*.rpm
Уровень 5: Smoke-тест
Проверьте, что приложение реально работает:
# CLI-утилита
myapp --version
myapp --help
echo "test" | myapp process
# Библиотека — проверить, что линкуется
ldconfig -p | grep libfoo
pkg-config --libs foo
# Systemd-сервис
sudo systemctl start myservice
sudo systemctl status myservice
journalctl -u myservice --no-pager | tail -20
sudo systemctl stop myservice
# GUI-приложение
myapp & # Запускается ли?
# Проверить основные действия вручную
Для GUI-приложений не пытайтесь автоматизировать всё на первом проходе. Достаточно короткого сценария: запуск, открытие окна, одна-две ключевые функции, корректное завершение.
Уровень 6: Проверка зависимостей
# Что требует пакет
rpm -qR mypackage
# Нет ли лишних зависимостей
# (например, зависимость от конкретной версии библиотеки,
# которая есть только на вашей системе)
# Проверить, что все зависимости разрешаются
dnf repoquery --requires --resolve mypackage
# Проверить обратные зависимости (для библиотек)
dnf repoquery --whatrequires libfoo
Типичные проблемы с зависимостями
- Не указан BuildRequires — пакет собрался локально (зависимость уже стояла), но упадёт на ABF
- Лишний Requires — указана явная зависимость, которая определяется автоматически
- Пропущенный Requires — программа требует утилиту (например,
curl), не определяемую автоматически
Уровень 7: Сборка в mock
Mock эмулирует чистое окружение ABF:
# Установить mock
sudo dnf install mock
sudo usermod -aG mock $USER
# Перелогиниться!
# Собрать SRPM
rpmbuild -bs mypackage.spec
# Собрать в чистом окружении (имя профиля смотрите в /etc/mock)
mock -r <профиль_из_/etc/mock> --rebuild ~/rpmbuild/SRPMS/mypackage-*.src.rpm
Если mock на вашей машине пока не готов, следующей чистой проверкой может быть сборка в ABF. Но локальную сборку и rpmlint перед этим всё равно лучше не пропускать: так вы сэкономите время и себе, и ревьюеру.
Анализ результатов mock
# Результаты
ls /var/lib/mock/<профиль_из_/etc/mock>/result/
# Лог сборки
less /var/lib/mock/<профиль_из_/etc/mock>/result/build.log
# Лог инициализации (ошибки зависимостей)
less /var/lib/mock/<профиль_из_/etc/mock>/result/root.log
# Интерактивная отладка внутри chroot
mock -r <профиль_из_/etc/mock> --shell
Почему mock важен
| Что проверяет | Без mock | С mock |
|---|---|---|
| Все BuildRequires указаны | Не видно (пакеты уже стоят) | Видно сразу |
| Чистая среда | Нет | Да |
| Воспроизводимость | Не гарантирована | Гарантирована |
| Близость к ABF | Далеко | Почти идентично |
Чеклист тестирования
Перед отправкой на ABF убедитесь:
-
rpmlint— нет ошибок (E:) -
rpmbuild -ba— сборка проходит - Если
%checkотключён, причина понятна и отражена в SPEC - Пакет устанавливается через
dnf install - Приложение запускается и выдаёт ожидаемый результат
-
rpm -qR— зависимости выглядят разумно - mock-сборка или сборка в ABF проходит в чистой среде
- При удалении пакета система остаётся чистой
Проверьте понимание
- Почему mock-сборка важнее локальной?
- Как пропустить сетевые тесты в %check?
- Что такое smoke-тест?
- Как проверить, что все BuildRequires указаны?
- Что делать, если тесты нестабильны?
Далее: Чеклист перед релизом