# port test /usr/ports/net/csup
Глава 10. Тестирование вашего порта
Этот перевод может быть устаревшим. Для того, чтобы помочь с переводом, пожалуйста, обратитесь к Сервер переводов FreeBSD.
Содержание
10.1. Запуск make describe
Некоторые утилиты FreeBSD для сопровождения портов, например, portupgrade(1), опираются на базу данных с именем /usr/ports/INDEX, в которой отслеживаются такие характеристики портов, как их зависимости. Файл INDEX создаётся при помощи ports/Makefile верхнего уровня по команде make index
, спускающейся в подкаталог каждого порта и выполняющей в нём make describe
. Таким образом, если выполнение make describe
с каким-либо портом завершится неудачно, то никому не удастся создать INDEX, при этом много людей вскоре станут несчастны.
Возможность генерировать этот файл очень важна вне зависимости от того, какие параметры присутствуют в make.conf, поэтому, пожалуйста, избегайте, таких вещей, как использование декларации |
Если make describe
выдаёт строчку, а не ошибку, то для вас это пройдёт безболезненно. Обратитесь к файлу bsd.port.mk, чтобы выяснить значение выдаваемых строк.
Также обратите внимание, что запуск актуальной версии portlint
(как указано в следующем разделе) приведёт к автоматическому выполнению make describe
.
10.2. Запуск make test
Даже если порт успешно собирается, рекомендуется убедиться, что программа корректно выполняет свои функции. Если исходный проект предоставляет тесты вместе с программным обеспечением, рекомендуется их запустить и проверить, что всё работает, как ожидается.
Порт может автоматически включить тесты, используя переменную TEST_TARGET
. Когда эта переменная установлена, она содержит имя цели тестирования порта. Обычно это просто test
, но другие варианты включают tests
, check
или, в специфических случаях, такие значения, как run_tests.py
.
В дополнение к переменной TEST_TARGET
фреймворк предоставляет следующие переменные для управления выполнением тестов:
TEST_WRKSRC
— это каталог для выполнения тестов.TEST_ENV
содержит дополнительные переменные, которые передаются на этап тестирования.TEST_ARGS
содержит любые дополнительные аргументы, переданные на этапе тестирования.
Примеры использования этих переменных можно найти в cad/xyce, www/libjwt и других.
Убедитесь, что тесты не ломаются при обновлении порта. |
10.3. Portclippy / Portfmt
Эти инструменты поставляются из пакета:ports-mgmt/portfmt[].
Portclippy — это линтер, проверяющий, расположены ли переменные в файле Makefile в правильном порядке согласно Порядку переменных в Makefile портов.
Portfmt — это инструмент для автоматического форматирования Makefile.
10.4. Portlint
Проверьте свою работу командой portlint
перед тем, как её отослать или перенести в дерево портов. portlint
предупреждает вас о многих распространённых ошибках, как функциональных, так и стилистических. Для нового (или скопированного внутри хранилища) порта самым подходящим является запуск portlint -A
; для уже существующего порта достаточно будет запустить portlint -C
.
Так как для обнаружения ошибок portlint
использует эвристические методы, то им могут выдаваться и ошибочные предупреждения. Кроме того, время от времени нечто, отмечаемое как некорректность, из-за ограничений механизма создания портов не может быть сделано никак иначе. Если вы сомневаетесь, то лучше всего спросить в Список рассылки, посвящённый Портам FreeBSD.
10.5. Инструменты для работы с портами
Программа ports-mgmt/porttools входит в состав Коллекции Портов.
port
является сценарием переднего плана, который может упростить вам задачу тестирования. Если вы хотите проверить новый порт или обновить существующий, то вы можете использовать port test
для проверки вашего порта, включая проверку portlint
. Эта команда также находит и отображает любые файлы, которые невключенные в pkg-plist. Смотрите следующий пример:
10.6. PREFIX
и DESTDIR
Переменная PREFIX
определяет, куда будет установлен порт. По умолчанию это /usr/local, но может меняться пользователем на собственный путь, такой как /opt. В вашем порту значение этой переменной должно учитываться.
Если пользователь установил переменную DESTDIR
, то она определяет полное альтернативное окружение, обычно, это jail или установленная система, смонтированная в месте, отличном от /. На самом деле порт устанавливается в DESTDIR/PREFIX и регистрируется в базе данных пакетов в DESTDIR/var/db/pkg. Поскольку управление DESTDIR
производится автоматически инфраструктурой портов с помощью chroot(8), вам не нужны никакие изменения или проявление особой осторожности при написании портов, совместымых с DESTDIR
.
Значение переменной PREFIX
будет установлено в LOCALBASE
(по умолчанию /usr/local). Если задана переменная USE_LINUX_PREFIX
, то PREFIX
примет значение LINUXBASE
(по умолчанию /compat/linux).
Избегание явно прописываемых путей /usr/local в исходном коде сделает порт гораздо более гибким и способным удовлетворить потребности других серверов. Часто этого можно добиться простой заменой строк /usr/local в различных файлах Makefile внутри порта на ${PREFIX}
. Эта переменная автоматически передаётся далее на каждом этапе построения и установки.
Проверьте, что ваше приложение не устанавливает чего-либо в каталог /usr/local вместо PREFIX
. Наличие явно указанных путей можно быстро проверить следующим образом:
% make clean; make package PREFIX=/var/tmp/`make -V PORTNAME`
Если что-то было установлено за пределами PREFIX
, то процесс создания пакета сообщит об отсутствии файлов.
Это также стоит проверить с использованием поддержки каталога сборки (смотрите Staging):
% make stage && make check-plist && make stage-qa && make package
check-plist
проверяет отсутствующие в plist файлы и файлы в plist, которые не установлены портом.stage-qa
проверяет наличие распространённых проблем, таких как неправильный шебанг (интерпретаторная строка в первой строке скрипта), символьные ссылки, указывающие за пределы stage-директории,файлы с setuid битом и библиотеки с отладочной информацией…
Эти тесты не обнаружат жёстко заданные пути в файлах порта, а также не проверят, что LOCALBASE
используется корректно для ссылок на файлы из других портов. Временно установленный порт в /var/tmp/make -V PORTNAME
должен быть протестирован на корректную работу, чтобы убедиться в отсутствии проблем с путями.
PREFIX
не должен быть явно установлен в Makefile порта. Пользователи, устанавливающие порт, могут задать PREFIX
в другом месте, и порт должен учитывать эту настройку.
Обращайтесь к программам и файлам из других портов с помощью упомянутых выше переменных, а не явных путей. Например, если порт требует, чтобы макрос PAGER
содержал полный путь к less
, не используйте явный путь /usr/local/bin/less. Вместо этого используйте ${LOCALBASE}
:
-DPAGER=\"${LOCALBASE}/bin/less\"
Путь с LOCALBASE
с большей вероятностью продолжит работать, если системный администратор переместил всё дерево /usr/local в другое место.
Все эти тесты выполняются автоматически при запуске |
10.7. poudriere
Для контрибьютора портов poudriere является одним из самых важных и полезных инструментов для тестирования и сборки. Его основные возможности включают:
Массовая сборка всего дерева портов, определенных подмножеств дерева портов или отдельного порта с его зависимостями
Автоматическая упаковка результатов сборки
Генерация файлов журнала сборки для каждого порта
Предоставление подписанного репозитория pkg(8)
Тестирование сборки портов перед отправкой патча в трекер ошибок FreeBSD или внесением изменений в дерево портов
Тестирование успешных сборок портов с использованием различных параметров
Поскольку poudriere выполняет сборку в чистой среде jail(8) и использует возможности zfs(8), он имеет несколько преимуществ по сравнению с традиционным тестированием на основной системе:
Отсутствие загрязнения основной среды: никаких оставшихся файлов, случайных удалений или изменений существующих конфигурационных файлов.
Проверяет pkg-plist на наличие отсутствующих или лишних записей
Коммиттеры портов иногда запрашивают журнал poudriere вместе с отправкой патча, чтобы оценить, готов ли патч для интеграции в дерево портов
Также его настройка и использование довольно просты, он не имеет зависимостей и будет работать в любой поддерживаемой версии FreeBSD. В этом разделе показано, как установить, настроить и запустить poudriere в рамках обычного рабочего процесса разработчика портов.
Примеры в этом разделе показывают стандартную структуру файлов, принятую в FreeBSD. Внесите соответствующие изменения, если у вас используются другие настройки. Дерево портов, обозначаемое как ${PORTSDIR}
, находится в /usr/ports. По умолчанию ${LOCALBASE}
и ${PREFIX}
указывают на /usr/local.
10.7.1. Установка poudriere
poudriere доступен в дереве портов в пакете ports-mgmt/poudriere. Его можно установить с помощью pkg(8) или из портов:
# pkg install poudriere
или
# make -C /usr/ports/ports-mgmt/poudriere install clean
Также существует версия poudriere в разработке, которая в конечном итоге станет следующим релизом. Она доступна в пакете:ports-mgmt/poudriere-devel[]. Эта версия используется для официальных сборок пакетов FreeBSD, поэтому она хорошо протестирована. В ней часто появляются новые интересные функции. Коммиттер портов захочет использовать версию в разработке, так как именно она используется в продакшене и содержит все новые функции, которые гарантируют, что всё будет работать идеально. Контрибьютору не обязательно нужны эти функции, так как наиболее важные исправления переносятся в выпущенную версию. Основная причина использования версии в разработке для сборки официальных пакетов заключается в её скорости — она позволяет сократить время полной сборки с 18 до 17 часов при использовании высокопроизводительного сервера с 32 CPU и 128 ГБ оперативной памяти. Эти оптимизации не будут столь значимы при сборке портов на настольном компьютере.
10.7.2. Настройка poudriere
Порт устанавливает файл конфигурации по умолчанию, /usr/local/etc/poudriere.conf. Каждый параметр описан в этом файле конфигурации.
Вот минимальный пример конфигурационного файла:
ZPOOL=zroot BASEFS=/usr/local/poudriere DISTFILES_CACHE=/usr/ports/distfiles RESOLV_CONF=/etc/resolv.conf
ZPOOL
Имя пула хранения ZFS, который будет использовать poudriere. Должно быть указано в выводе команды
zpool status
.BASEFS
Корневая точка монтирования файловых систем poudriere. Эта запись приведет к тому, что poudriere смонтирует
tank/poudriere
в/poudriere
.DISTFILES_CACHE
Определяет, где хранятся distfiles. В этом примере poudriere и хост используют общий каталог для хранения distfiles. Это позволяет избежать загрузки tарболов, которые уже присутствуют в системе. Пожалуйста, создайте этот каталог, если он ещё не существует, чтобы poudriere мог его найти.
RESOLV_CONF
Используйте файл /etc/resolv.conf хоста внутри клеток для DNS. Это необходимо, чтобы клетки могли разрешать URL-адреса distfiles при загрузке. Это не требуется при использовании прокси. Обратитесь к файлу конфигурации по умолчанию для настройки прокси.
10.7.3. Создание клеток poudriere
Создайте базовые клетки, которые poudriere будет использовать для сборки:
# poudriere jail -c -j 131Ramd64 -v 13.1-RELEASE -a amd64
Загрузите 13.1-RELEASE
для amd64
с FTP-сервера, указанного в FREEBSD_HOST
в poudriere.conf, создайте ZFS-файловую систему tank/poudriere/jails/131Ramd64
, смонтируйте её в /poudriere/jails/131Ramd64 и распакуйте тарболлы 13.1-RELEASE
в эту файловую систему.
# poudriere jail -c -j 12i386 -v stable/12 -a i386 -m git+https
Создайте tank/poudriere/jails/12i386
, смонтируйте его на /poudriere/jails/12i386, затем извлеките верхушку ветки Git FreeBSD-12-STABLE
из GIT_HOST
в poudriere.conf или по умолчанию git.freebsd.org
в /poudriere/jails/12i386/usr/src, после чего выполните buildworld
и установите его в /poudriere/jails/12i386.
Хотя возможно собрать более новую версию FreeBSD на старой версии, в большинстве случаев она не запустится. Например, если требуется клетка на |
Для создания клетки poudriere для
Для запуска клетки |
Список клеток, известных poudriere, можно вывести с помощью команды poudriere jail -l
:
# poudriere jail -l
JAILNAME VERSION ARCH METHOD
131Ramd64 13.1-RELEASE amd64 ftp
12i386 12.4-STABLE i386 git+https
10.7.4. Обновление клеток poudriere
Управление обновлениями очень простое. Команда:
# poudriere jail -u -j JAILNAME
обновляет указанную клетку до последней доступной версии. Для релизов FreeBSD обновление до последнего уровня исправлений с помощью freebsd-update(8). Для версий FreeBSD, собранных из исходников, обновление до последней ревизии git в ветке.
Для клеток, использующих метод
|
10.7.5. Настройка деревьев портов для использования с poudriere
Существует несколько способов использования деревьев портов в poudriere. Наиболее простой способ — позволить poudriere создать для себя дерево портов по умолчанию, используя Git:
# poudriere ports -c -m git+https -B main
Эти команды создают tank/poudriere/ports/default
, монтируют его в /poudriere/ports/default и заполняют с помощью Git. После этого он включается в список известных деревьев портов:
# poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
default git+https 2020-07-20 04:23:56 /poudriere/ports/default
Обратите внимание, что дерево портов "default" является особым. Каждая из команд сборки, объяснённых далее, будет неявно использовать это дерево портов, если явно не указано иное. Чтобы использовать другое дерево, добавьте |
Лучший способ работы с локальными изменениями для разработчика портов — использовать Git. Как и при создании клеток, можно использовать другой метод для создания дерева портов. Чтобы добавить дополнительное дерево портов для тестирования локальных изменений и разработки портов, предпочтительно использовать клонирование дерева через git (как описано выше).
10.7.6. Использование управляемых вручную деревьев портов с помощью poudriere
В зависимости от рабочего процесса может быть крайне полезно использовать деревья портов, которые поддерживаются вручную. Например, если существует локальная копия дерева портов в /work/ports, укажите poudriere на это расположение:
# poudriere ports -c -m null -M /work/ports -p development
Это будет указано в таблице известных деревьев:
# poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
development null 2020-07-20 05:06:33 /work/ports
Тире или |
10.7.7. Обновление деревьев портов poudriere
Так же просто, как с клетками, описанными ранее:
# poudriere ports -u -p PORTSTREE
Обновит указанное PORTSTREE, дерево, указанное в выводе команды poudriere -l
, до последней доступной ревизии на официальных серверах.
Деревья портов без метода, см. Использование вручную управляемых деревьев портов с помощью poudriere, не могут быть обновлены таким образом и должны обновляться вручную сопровождающим портов. |
10.7.8. Тестирование портов
После настройки клеток и деревьев портов можно проверить результат изменений, внесенных участником в дерево портов.
Например, локальные изменения в порте www/firefox, расположенном в /work/ports/www/firefox, можно протестировать в ранее созданной клетке 13.1-RELEASE:
# poudriere testport -j 131Ramd64 -p development -o www/firefox
Это соберет все зависимости Firefox. Если зависимость уже была собрана ранее и остается актуальной, будет установлен готовый пакет. Если для зависимости нет актуального пакета, он будет собран с параметрами по умолчанию в клетке. Затем будет собран сам Firefox.
Полная сборка каждого порта записывается в /poudriere/data/logs/bulk/131Ri386-development/build-time/logs.
Имя каталога 131Ri386-development
формируется из аргументов -j
и -p
соответственно. Для удобства также поддерживается символическая ссылка /poudriere/data/logs/bulk/131Ri386-development/latest. Эта ссылка указывает на последний каталог времени сборки. Также в этом каталоге находится файл index.html, который позволяет наблюдать за процессом сборки через веб-браузер.
По умолчанию poudriere очищает клетки и оставляет файлы журналов в указанных выше каталогах. Для упрощения анализа клетки можно оставить запущенными после сборки, добавив -i
к testport
:
# poudriere testport -j 131Ramd64 -p development -i -o www/firefox
После завершения сборки, независимо от того, была ли она успешной, в клетке предоставляется оболочка. Эта оболочка используется для дальнейшего исследования. Можно указать poudriere оставить клетку запущенной после завершения сборки с помощью -I
. poudriere покажет команду для выполнения, когда клетка больше не нужна. Затем можно использовать jexec(8) для входа в неё:
# poudriere testport -j 131Ramd64 -p development -I -o www/firefox
[...]
====>> Installing local Pkg repository to /usr/local/etc/pkg/repos
====>> Leaving jail 131Ramd64-development-n running, mounted at /poudriere/data/.m/131Ramd64-development/ref for interactive run testing
====>> To enter jail: jexec 131Ramd64-development-n env -i TERM=$TERM /usr/bin/login -fp root
====>> To stop jail: poudriere jail -k -j 131Ramd64 -p development
# jexec 131Ramd64-development-n env -i TERM=$TERM /usr/bin/login -fp root
# [do some stuff in the jail]
# exit
# poudriere jail -k -j 131Ramd64 -p development
====>> Umounting file systems
Неотъемлемой частью инфраструктуры сборки портов FreeBSD является возможность настройки портов под личные предпочтения с помощью опций. Их также можно тестировать с помощью poudriere. Добавление опции -c
:
# poudriere testport -j 131Ramd64 -c -o www/firefox
Представляет диалог настройки порта перед его сборкой. Порты, указанные после -o
в формате категория/имя_порта
, будут использовать указанные опции, все зависимости будут использовать опции по умолчанию. Тестирование зависимых портов с нестандартными опциями может быть выполнено с использованием наборов, см. Использование наборов.
При тестировании портов, где файл pkg-plist изменяется во время сборки в зависимости от выбранных опций, рекомендуется выполнить тестовый запуск со всеми выбранными опциями и один без выбранных опций. |
10.7.9. Использование наборов
Для всех действий, связанных со сборкой, можно указать так называемый набор с помощью -z имя_набора
. Набор относится к полностью независимой сборке. Это позволяет, например, использовать testport
с нестандартными параметрами для зависимых портов.
Для использования наборов poudriere ожидает, что будет использована структура каталогов, аналогичная PORT_DBDIR
, по умолчанию /var/db/ports, в его конфигурационной директории. Этот каталог затем монтируется с помощью nullfs(5) в клетки, где собираются порты и их зависимости. Обычно подходящую начальную точку можно получить, рекурсивно скопировав существующий PORT_DBDIR
в /usr/local/etc/poudriere.d/jailname-portname-setname-options. Это подробно описано в poudriere(8). Например, для тестирования www/firefox в определённом наборе с именем devset
, добавьте параметр -z devset
к команде testport
:
# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox
Это проверит наличие этих каталогов в следующем порядке:
/usr/local/etc/poudriere.d/131Ramd64-development-devset-options
/usr/local/etc/poudriere.d/131Ramd64-devset-options
/usr/local/etc/poudriere.d/131Ramd64-development-options
/usr/local/etc/poudriere.d/devset-options
/usr/local/etc/poudriere.d/development-options
/usr/local/etc/poudriere.d/131Ramd64-options
/usr/local/etc/poudriere.d/options
Из этого списка poudriere nullfs(5) монтирует первое существующее дерево каталогов в директорию /var/db/ports сборных клеток. Таким образом, все пользовательские настройки используются для всех портов во время этого запуска testport
.
После предоставления структуры каталогов для набора можно изменить параметры для конкретного порта. Например:
# poudriere options -c www/firefox -z devset
Отображается диалог настройки www/firefox, где можно редактировать параметры. Выбранные параметры сохраняются в набор devset
.
poudriere очень гибок в настройке опций. poudriere можно настроить для конкретных клеток, деревьев портов и для нескольких портов одной командой. Подробности см. в poudriere(8). |
10.7.10. Предоставление пользовательского файла make.conf
Подобно использованию наборов, poudriere также использует пользовательский make.conf, если он предоставлен. Для этого не требуется специального аргумента командной строки. Вместо этого poudriere ищет существующие файлы, соответствующие схеме именования, производной от командной строки. Например:
# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox
заставляет poudriere проверять наличие этих файлов в следующем порядке:
/usr/local/etc/poudriere.d/make.conf
/usr/local/etc/poudriere.d/devset-make.conf
/usr/local/etc/poudriere.d/development-make.conf
/usr/local/etc/poudriere.d/131Ramd64-make.conf
/usr/local/etc/poudriere.d/131Ramd64-development-make.conf
/usr/local/etc/poudriere.d/131Ramd64-devset-make.conf
/usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf
В отличие от наборов, все найденные файлы будут добавлены, в указанном порядке, в один make.conf внутри клеток сборки. Таким образом, можно задать общие переменные make, предназначенные для влияния на все сборки, в файле /usr/local/etc/poudriere.d/make.conf. Специальные переменные, предназначенные только для определённых клеток или наборов, можно задать в специализированных файлах make.conf, например, в /usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf.
Для сборки набора с нестандартной версией Perl, например, 5.20
, используя набор с именем perl5-20
, создайте файл perl5-20-make.conf со следующей строкой:
DEFAULT_VERSIONS+= perl=5.20
10.7.11. Удаление ненужных файлов дистрибутива
poudriere имеет встроенный механизм для удаления устаревших файлов дистрибутива, которые больше не используются ни одним портом данного дерева. Команда
# poudriere distclean -p portstree
будет сканировать папку файлов дистрибутива, DISTFILES_CACHE
в poudriere.conf, сравнивая ее с деревом портов, указанным аргументом -p portstree
, и запрашивать подтверждение на удаление этих файлов дистрибутива. Чтобы пропустить запрос и удалить все неиспользуемые файлы без подтверждения, можно добавить аргумент -y
:
# poudriere distclean -p portstree -y
10.8. Отладка портов
Иногда что-то идёт не так, и порт не работает во время выполнения. Фреймворк предоставляет некоторые средства для отладки портов. Эти вспомогательные инструменты ограничены, поскольку способ отладки порта во многом зависит от используемой технологии. Следующие переменные помогают в отладке портов:
WITH_DEBUG
. Если установлено, порты собираются с отладочными символами.WITH_DEBUG_PORTS
. Указывает список портов, которые должны собираться с установленнымWITH_DEBUG
.DEBUG_FLAGS
. Используется для указания дополнительных флагов дляCFLAGS
. По умолчанию-g
.
Когда WITH_DEBUG
установлен, глобально или для списка портов, результирующие бинарные файлы не лишаются символов.
Эти переменные могут быть указаны в make.conf или в командной строке:
# cd category/port && make -DWITH_DEBUG DEBUG_FLAGSS="-g -O0"
Если порт собирается с использованием ports-mgmt/poudriere, отладочные переменные должны быть указаны в make.conf poudriere, а не в /etc/make.conf. Подробности см. в документации ports-mgmt/poudriere. |
Пожалуйста, обратитесь к отладочной информации в Руководстве разработчика для получения более подробной информации о доступных инструментах отладки.
Изменено: 18 сентября 2025 г. by Vladlen Popolitov