Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021)

Материал из 0x1.tv
Перейти к: навигация, поиск
Докладчик
Денис Ефремов®.jpg
Денис Ефремов®

Обзор инструментов, технологий тестирования и способов организаций тестов, доступных в настоящий момент как в самом ядре «Linux», так и в сторонних открытых проектах. Ядро представляет собой большой и неоднородный проект, состоящий как из аппаратно-независимого кода, так и частей, работоспособность которых зависит от наличия соотвествующей аппаратуры или специфичных программ пользовательсткого пространства. Для тестирования разных частей ядра применяются разных методы и подходы. Обзор включает в себя рассмотрение таких инструментов/технологий как «kselftest», «KUnit», «KTF», «ktest» и наиболее распространённых тестовых пакетов «LTP», «LKP», «xfstests» и др.

Видео

on youtube

Презентация

Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021).pdf

Thesis

Модули ядра с тестами

Существует некоторое количество загружаемых модулей ядра, которые выполняют роль тестов. Разработчики пишут эти модули для проверки кода других модулей. Найти их можно, проверив конфигурационные параметры ядра на наличие строк и в них.

Тесты такого рода не имеют общей организации. Не существует какого-то общего протокола для представления результатов тестирования. Большинство из этих модулей пишут результаты в лог ядра. Лишь некоторые из тестов зависят от наличия специфичной аппаратуры.

Для запуска тестовых модулей необходимо либо собрать ядро вместе с ними, либо собрать их отдельно, в виде загружаемых модулей. В первом случае тесты будут выполняться в момент загрузки ядра, в последнем — в момент инициализации загружаемого модуля.

KUnit

KUnit[1] — это фреймворк для юнит тестирования ядра Linux. В основном он предназначен для небольших тестов, не зависящих от аппаратуры и компонентов пользовательского пространства. KUnit позволяет организовывать группы тестов, параметризировать тесты, подменять функции (mock), использует TAP[2] протокол для записи результатов тестирования и даёт набор общих программных интерфейсов для разработки тестов. Фреймворк предоставляет общую инфраструктуру для конфигурации, запуска и сбора результатов тестирования. Тесты KUnit могут быть найдены, по наличию строки KUNIT_TEST в конфигурационных параметрах ядра.

KUnit использует UserMode[3] (ARCH=um) архитектуру в качестве основной для запуска тестов, но не ограничен ей. Это позволяет запускать ядро Linux как обычный процесс, убирая из тестирования шаг установки ядра и загрузки машины с ним. Тесты запускаются существенно быстрей и работают без использования дополнительного программного обеспечения вроде qemu. Недостатком является то, что на текущий момент UserMode ядро не поддерживает такие отладочные технологиии, как KASAN и UBSAN. KUnit не полагается в своей работе на дополнительное программное обеспечение, не входящее в исходные коды ядра Linux. Фреймворк был включён в ядро Linux v5.5[4].

KTF

Kernel Test Framework[5] — также является фреймворком для разработки юнит-тестов на ядро Linux. В отличие от KUnit, не входит в само ядро, а является сторонним проектом, развиваемым компанией Oracle.

Фреймворк KTF состоит из ядерной части и программы пользовательского пространства. Последняя контролирует процесс тестирования, запуск тестов, обработку результатов и взаимодействует с компонентом KTF в ядре. Ядерный компонент предостоставляет библиотеку функций для разработки тестов, их запуска и отправку результатов. Результаты представляются в формате TAP. Фреймворк поддерживает параметризацию тестов, их группировку, перехват и подмену функций.

KTF, в отличие от KUnit, требует загрузки тестируемого ядра. Тесты реализуются только в виде загружаемых модулей ядра. Использование UserMode архитектуры при тестировании не поддерживается.

С другой стороны, KTF использует сокеты netlink (а не лог ядра) для записи результатов тестирования и контроля запуска тестов, а также использует технологии Kprobes/Kretprobes для перехвата внутренних API ядра. Всё это позволяет реализовывать гибридные тесты, которые выполняются и в пространстве пользователя и в пространстве ядра, что даёт возможность тестировать как внешнее воздействие на ядро отражается на его внутреннем состоянии. Полезными особенностями фреймворка является автоматизация доступа к внутренним неэкспортируемым API ядра и поддержка упрощённого покрытия кода, не требующего пересборки ядра.

К сожалению, в настоящий момент нет репрезентативного и публично доступного набора тестов, основанного на фреймворке KTF. После ухода из Oracle основного разработчика KTF проект поддерживается, но не продолжает своего развития. Была лишь одна попытка включить KTF в ядро Linux, которая имела ряд замечаний, в том числе замечание о необходимости его интеграции с KUnit. Дальнейших попыток включить KTF в ядро на сегодняшний день не предвидится.

Kselftest

Linux Kernel Selftests[6] — это набор тестовых программ пользовательского пространства для интеграционного и сквозного тестирования, который поставляется вместе с исходниками ядра Linux. Данные тесты предназначены для запуска после сборки, установки и загрузки тестируемого ядра.

Отдельный тест представляет собой пользовательскую программу, которая взаимодействиет с ядром посредством системных вызовов, возможно также полагаясь на наличие в системе специфичных интерфейсов /dev/*, /proc/*, /sys/* отдельных драйверов.

Kselftest использует протокол TAP для записи результатов тестирования и поддерживает множество компьютерных архитектур. Тесты осуществляют проверку того, что API для программ пользовательского пространства функционируют ожидаемым образом. Основной целью проекта является помочь разработчикам ядра производить базовое тестирование (включая регрессионное) менее чем за 20 минут.

Ktest

Более 10 лет в составе ядра существует скрипт ktest.pl[7], предназначенный для автоматизации тестирования ядра. Скрипт поддерживает как работу с физическими оборудованием, так и виртуальные машины. Ktest позволяет производить тестирование сборки и загрузки ядра, в том числе с выполнением некоторого набора тестов после загрузки. Ktest имеет режимы проверки отдельных патчей, поиска коммитов (git bisect) с ошибками, минимизации конфигурации ядра.

В рамках тестирования сборки и загрузки ядра, ktest может сверять результаты с прошлыми запусками и выявляеть новые ошибки/аномалии на основании этого.

Ktest в основном разрабатывался как инструмент мейнтейнеров ядра Linux для ревью и тестирования патчей из списков рассылок. Соответственно, он обладает функциональностью необходимой для максимальной автоматизации и упрощения данного рабочего процесса.

Тестовые пакеты

Существует большое количество тестовых пакетов, нацеленных на разные подсистемы и функциональность ядра Linux. Данные тесты поддерживаются и разрабатываются разными мейнтейнерами и компаниями. Это программы пользовательского пространства, нацеленные на регрессионное, функциональное, интеграционное, сквозное, стресс тестирование интерфейсов ядра или системы в целом, её производительности. Они не имеют какой-то общей структуры, представления результатов, и в отдельных случаях не имеют оракулов для отслеживания ошибок ядра во время тестирования. В последнее время такие continuous integration проекты как CKI, LKFT, KernelCI, 0-Day Test Service начали активно использовать данные тестовые пакеты и включать их в цикл непрерыной интеграции.

Вот только некоторые из публично доступных тестовых пакетов на ядро Linux:

  • Linux Test Project (LTP)[8] — большой тестовый пакет на практически все подсистемы ядра, включая стресс тесты и тесты на наличие неисправленных уязвимостей. Развивается и поддерживается крупными компаниями.
  • Linux Kernel Performance tests (LKP)[9] — тесты производительности подсистем виртуальной памяти, ввода-вывода, сетевой и др. Развивается Intel, используется в O-Day Continuous Integration системе с автоматической отправкой результатов в публичные списки рассылки.
  • xfstests[10] — набор регрессионных тестов для операций с файловыми системами. Изначально разрабатывался для тестирования XFS, но постепенно стал основным инструментом тестирования для всех файловых систем ядра Linux.
  • syzkaller-repros[11] — коллекция программ вызывающих ошибки в ядре, найденных при помощи системы фаззинга системных вызовов syzkaller. Используется в качестве набора регрессионных тестов.
  • Firmware Test Suite[12] — тесты для проверки прошивок. Нацелен на выявление ошибок BIOS, UEFI, ACPI и др.
  • KVM unit tests[13]/Xen Test Suite[14] — тесты для проверки гипервизоров KVM и XEN. Представляют собой наборы минимальных виртуальных машин разных конфигураций. В тестовый набор XEN включаются регрессионные тесты на выявления известных уязвимостей XSA.

Остальные тестовые пакеты на ядро Linux практически наверняка можно найти в базе KCIDB[15] системы непрерывной интеграции KernelCI.

Инструменты тестирования ядра Linux (Денис Ефремов, OSSDEVCONF-2021)!.jpg

Примечания и ссылки

  1. KUnit — Unit Testing for the Linux Kernel https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html
  2. Test Anything Protocol https://testanything.org/
  3. \UML HowTo https://www.kernel.org/doc/html/latest/virt/uml/user_mode_linux_howto_v2.html
  4. kunit: test: add KUnit test runner core https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=914cc63eea6f
  5. Kernel Test Framework https://github.com/oracle/ktf/
  6. Linux Kernel Selftests https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html
  7. Ktest https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/ktest
  8. Linux Test Project https://github.com/linux-test-project/ltp
  9. Linux Kernel Performance tests, https://github.com/intel/lkp-tests
  10. (X)FSTests filesystem testing suite https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/
  11. Syzkaller bug reproducers https://github.com/dvyukov/syzkaller-repros
  12. Firmware Test Suite https://wiki.ubuntu.com/FirmwareTestSuite
  13. KVM unit tests https://www.linux-kvm.org/page/KVM-unit-tests
  14. Xen Test Framework http://xenbits.xenproject.org/docs/xtf/
  15. KCIDB https://github.com/kernelci/kcidb/blob/2da9805978e73b2bbba3c1d5996c0d49d7944163/tests.yaml

Plays:7   Comments:0