mariadb-test Обзор
Основы
В своей основе, mariadb-test очень прост. Клиентская программа mariadb-test выполняет файл теста и сравнивает полученный вывод с файлом результата. Если файлы совпадают, тест пройден; в противном случае тест не пройден. Этот подход можно использовать для тестирования любых SQL-запросов, а также других исполняемых файлов (с помощью команды exec).
Весь процесс тестирования управляется и контролируется скриптом-драйвером mariadb-test-run.pl, или mtr для краткости (для удобства, mtr создается как символическая ссылка на mariadb-test-run.pl). Скрипт mtr отвечает за подготовку тестовой среды, создание списка всех тестов для запуска, их запуск и создание отчета в конце. Он может запускать множество тестов параллельно, выполнять тесты в порядке, минимизирующем перезапуски сервера (поскольку они медленные), запускать тесты в отладчике или под valgrind или strace, и так далее.
Файлы тестов находятся в наборах. Набор — это каталог, содержащий файлы тестов, файлы результатов и необязательные конфигурационные файлы. Мtr ищет наборы в каталоге mariadb-test/suite и в подкаталогах плагинов и каталогов движков хранилища mariadb-test. Например, следующие пути к наборам являются допустимыми:
mariadb-test/suite/rpl
mariadb-test/suite/handler
storage/example/mariadb-test/demo
plugin/auth_pam/mariadb-test/pam
Практически во всех случаях имя каталога набора — это имя набора. Заметным историческим исключением является набор main, который расположен непосредственно в каталоге mariadb-test.
Файлы тестов имеют расширение .test и могут быть размещены непосредственно в каталоге набора (например, mariadb-test/suite/handler/interface.test) или в подкаталоге t (например, mariadb-test/suite/rpl/t/rpl_alter.test или mariadb-test/t/grant.test). Аналогично, файлы результатов имеют расширение .result и могут быть размещены либо в каталоге набора, либо в подкаталоге r.
Файл теста может включать другие файлы (с помощью команды source). Эти включенные файлы могут иметь любое имя и размещаться где угодно, но обычно они имеют расширение .inc и располагаются либо в каталоге набора, либо в подкаталогах inc или include (например, mariadb-test/suite/handler/init.inc или mariadb-test/include/start_slave.inc).
Другие файлы, которые влияют на тестирование, хотя и не являются сами по себе тестами, это:
-
disabled.def -
suite.opt - другие файлы
*.opt -
my.cnf - другие файлы
*.cnf -
combinations - другие файлы
*.combinations -
suite.pm -
файлы
*.sh -
файлы
*.require -
файлы
*.rdiff -
valgrind.supp
Подробную информацию об этих файлах см. в разделе Вспомогательные файлы.
Наложения
Помимо обычных каталогов наборов, mtr поддерживает наложения. Наложение — это каталог с тем же именем, что и существующий набор, но расположенный в каталоге движка хранилища или плагина. Например, storage/myisam/mariadb-test/rpl может быть наложением myisam набора rpl в каталоге mariadb-test/suite/rpl. А plugin/daemon_example/mariadb-test/demo может быть наложением daemon_example на набор demo в storage/example/mariadb-test/demo. В качестве особого исключения наложение на главный набор должно называться main, как в storage/pbxt/mariadb-test/main.
Наложение подобно второму прозрачному слою в графическом редакторе. Оно может затемнять, расширять или изменять изображение фона. Также можно заметить, что наложение очень близко к UnionFS, но реализовано на Perl внутри mtr.
Наложение может заменить практически любой файл в наложении набора или добавить новые файлы. Например, если какое-то наложение на основной набор содержит файл include/have_innodb.inc, то все тесты, которые его включают, увидят и будут использовать версию с наложением. Или, наложение может создать файл t/create.opt (даже если основной набор такого файла не имеет), и create.test будет выполнен со специфицированными дополнительными параметрами.
Однако добавление наложения никогда не влияет на то, как выполняется исходный набор. То есть, mtr всегда выполняет исходный набор так, как будто наложение отсутствует. А затем дополнительно выполняет объединённое «объединение» наложения и исходного набора. При этом mtr позаботится о том, чтобы не повторно выполнять тесты, которые не были изменены в наложении. Например, создание t/create.opt в наложении на основной набор вызовет выполнение только create.test в наложении. Но создание suite.opt затрагивает все тесты — и это вызовет повторное выполнение всех тестов с новыми параметрами.
Комбинации
В некоторых случаях имеет смысл запускать определённый тест или группу тестов несколько раз с разными настройками сервера. Это можно сделать с помощью так называемых комбинаций. Файл комбинаций определяет эти альтернативы с использованием синтаксиса my.cnf, например
[row] binlog-format=row [stmt] binlog-format=statement [mix] binlog-format=mixed
И все тесты, на которые распространяется этот файл комбинаций, будут выполнены трижды: один раз для комбинации с именем «row», и --binlog-format=row на командной строке сервера, один раз для комбинации «stmt» и один раз для комбинации «mix».
Для данного файла теста может быть применимо более одного файла комбинаций. В этом случае mtr выполнит тест для всех возможных комбинаций заданных комбинаций. Тест, использующий репликацию (три комбинации, как выше) и innodb (две комбинации — innodb и xtradb), будет выполнен шесть раз.
Пример вывода
Типичный вывод mtr выглядит следующим образом
============================================================================== TEST WORKER RESULT TIME (ms) or COMMENT -------------------------------------------------------------------------- rpl.rpl_row_find_row_debug [ skipped ] Requires debug build main-pbxt.connect [ skipped ] No PBXT engine main-pbxt.mysqlbinlog_row [ disabled ] test expects a non-transactional engine rpl.rpl_savepoint 'mix,xtradb' w2 [ pass ] 238 rpl.rpl_stm_innodb 'innodb_plugin,row' w1 [ skipped ] Neither MIXED nor STATEMENT binlog format binlog.binlog_sf 'stmt' w2 [ pass ] 7 unit.dbug w2 [ pass ] 1 maria.small_blocksize w1 [ pass ] 23 sys_vars.autocommit_func3 'innodb_plugin' w1 [ pass ] 5 sys_vars.autocommit_func3 'xtradb' w1 [ pass ] 6 main.ipv6 w1 [ pass ] 131 ...
Каждый тест печатается как «suitename.testname», и имя набора может включать имя наложения (как в main-pbxt). После имени теста mtr печатает применённые к этому тесту комбинации, если таковые имеются.
Аналогичный синтаксис можно использовать в командной строке mtr для указания, какие тесты необходимо запустить:
$ ./mtr innodb |
поиск теста innodb во всех наборах из стандартного списка и запуск всех найденных. |
|---|---|
$ ./mtr main.innodb |
запуск теста innodb из набора main |
$ ./mtr main-pbxt.innodb |
запуск теста innodb из наложения pbxt набора main |
$ ./mtr main-.innodb |
запуск теста innodb из набора main и всех его наложений. |
$ ./mtr main.innodb,xtradb |
запуск теста innodb из набора main только в комбинации xtradb |
Поддержка плагинов
Драйвер mtr имеет специальную поддержку плагинов MariaDB.
Во-первых, при запуске он копирует или создаёт символические ссылки на все динамически скомпилированные плагины в var/plugins. Это позволяет загружать несколько плагинов одновременно. Например, можно загрузить движки Federated и InnoDB вместе. Также mtr создаёт переменные среды для каждого плагина с соответствующим именем плагина. Например, если движок InnoDB был скомпилирован, $HA_INNODB_SO будет установлено в ha_innodb.so (или ha_innodb.dll в Windows). И тест может безопасно использовать соответствующую переменную среды на всех платформах для ссылки на файл плагина; она всегда будет иметь правильное зависящее от платформы расширение.
Во-вторых, при объединении параметров командной строки сервера (которые могут поступать из многих различных источников) в один длинный список перед запуском mariadbd, mtr обрабатывает --plugin-load специально. Стандартная семантика сервера заключается в использовании последнего значения любого конкретного параметра в командной строке. Если запустить сервер, например, с --port=2000 --port=3000, сервер будет использовать последнее значение для порта, т. е. 3000. Чтобы разрешить различным файлам .opt требовать различные плагины, mtr проходит по собранной командной строке сервера и объединяет все параметры --plugin-load в один. Кроме того, он удаляет все пустые параметры --plugin-load. Например, предположим, что на тест влияют три файла .opt, которые содержат соответственно:
--plugin-load=$HA_INNODB_SO
--plugin-load=$AUTH_PAM_SO
--plugin-load=$HA_EXAMPLE_SO
…и предположим, что движок Example не был скомпилирован ($HA_EXAMPLE_SO пусто). Тогда сервер получит:
--plugin-load=ha_innodb.so:auth_pam.so
вместо
--plugin-load=ha_innodb.so --plugin-load=auth_pam.so --plugin-load=
В-третьих, чтобы разрешить копирование источников плагинов в каталоги plugin/ или storage/ и при этом не влиять на существующие тесты (даже если новые плагины статически связаны с сервером), mtr автоматически отключает все необязательные плагины при запуске сервера. Плагин является необязательным, если его можно отключить с помощью соответствующего параметра командной строки сервера --skip-XXX. Обязательные плагины, такие как MyISAM или MEMORY, не имеют параметров --skip-XXX (например, нет параметра --skip-myisam). Это поведение mtr означает, что ни один плагин, скомпилированный статически или динамически, не оказывает никакого влияния на сервер, если он не был явно включён. Удобный способ включить данный плагин XXX для определённых тестов — создать файл have_XXX.opt, содержащий необходимые параметры командной строки, и файл have_XXX.inc, который проверяет, был ли загружен плагин. Затем любой тест, которому нужен этот плагин, может подключить файл have_XXX.inc и автоматически загрузить плагин.
Процедура связи mtr
mtr сначала создаёт сокет сервера (master).
После этого workers создаются с помощью fork().
Для каждого работника вызывается функция run_worker(), которая выполняет следующее:
- создаёт новый сокет для подключения к
server_port, полученному изmaster - инициализирует общение с
master, используя командуSTART -
masterотправляет первый тест из списка тестов, предоставленного пользователем, и немедленно отправляет командуTESTCASEсерверуworker -
workerполучает командуTESTCASEи обрабатывает тестовый случай, вызывая функциюrun_testcase(), которая запускает (или перезапускает при необходимости) сервер и отправляетTESTRESULT(в случае перезапуска издаётся командаWARNINGSдля сервераmaster, если обнаружены предупреждения или ошибки) -
masterпринимает командуTESTRESULTи выполняет функциюmtr_report_test(), которая проверяет, не провалился ли тест, и также генерирует новую командуTESTCASE, если существуют новые тестовые случаи - Если других тестовых случаев нет,
masterотправляет командуBYE, которую принимает серверworker, который корректно закрывает соединение.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/mariadb-test-overview/