среда, 13 декабря 2017 г.

Используем bibisect для поиска регрессий в коде LibreOffice

Регрессия в программном коде - это, когда после внесения изменений в программу, перестаёт работать то, что должно было продолжать работать. Например, разработчик написал код, добавляющий новую фичу (или исправляющий ошибку) в одном месте программы, а в другом месте программы из-за этого возникла другая ошибка, например стал неправильно отображаться формат ячейки или некорректно стало считаться некое вычисляемое значение, да и вообще все, что угодно.
Когда обнаруживается такая регрессия (в 5.3. работало, в 5.4 перестало работать или работает с ошибками), то для облегчения жизни кодерам (и для сокращения затрат их времени) люди из QA команды делают bibisecting.
Bibisect - это инструмент GIT, который используется для определения момента, когда ошибка впервые появилась в LibreOffice. То есть мы будем искать первый коммит, который привел к появлению некой ошибки.
В вики проекта есть страничка с описанием процесса для ОС Windows (на английском языке), но, читая ее, я сам не смог корректно проделать процедуру, потому что я дочитал до момента "установите git" и полез ставить официальный клиент git for windows.
ВНИМАНИЕ! Это было ОШИБКОЙ, потому что официальный клиент git for windows странно работает с репами bisect от LibreOffice, вываливаются ошибки, которые не дают выполнять bibisect!
А если бы я почитал чуть далее, то увидел бы, что ставить нужно cygwin!
Итак, начнем.
Шаг №1. Идем на сайт cygwin и качаем инсталлятор в любом виде для вашей битности Windows. В процессе установки будет предложено выбрать дополнительные пакеты, там есть фильтр, введите в нем git и просто установите все пакеты, которые оно вам покажет. Хотя Майк советовал выбрать просто сам git и всё.
Шаг №2. Для корректной работы LibreOffice в Windows необходимы библиотеки типа msvcrXXX.dll от Visual C++ Redistributable Packages for Visual Studio соответствующих версий. Скачать их можно с сайта MicroSoft. Если вы ищете ошибку в той версии офиса, которая уже установлена и работает, то скорее всего нужные библиотеки от MS уже установлены. Если решили проверить альфу или бету версию офиса, то нужно уточнить у разработчиков, какие библиотеки нужны и нужны ли вообще.
Шаг №3. Нужно скачать репозиторий бинарников для той версии офиса, в которой вы собираетесь искать регрессию. Создаем каталог, где будут храниться репы, например E:\libo. Запускаем cygwin, откроется окно терминала:

нужно перейти в наш рабочий каталог, выполнив команду cd /cygdrive/e/libo, приглашение командной строки изменится на соответствующий путь.
Далее выполняем команду git clone git://gerrit.libreoffice.org/bibisect-win32-5.4 (последние две цифры 5.4 означают номер версии LibreOffice, которую мы будем исследовать, если вы работаете с иной версией LibreOffice измените последние две цифры на нужную версию).
Ждем достаточно долгое время, пока сформируется архив на сервере, пока он выкачается к Вам на компьютер, а затем распакуется. В терминале все эти шаги будут отражаться.
Шаг №4. Начинаем собственно процесс поиска плохого коммита. Переходим в каталог с репой бисектинга для нужной версии, даем команду cd bibisect-win32-5.4.
Приглашение командной строки соответственно изменится на /cygdrive/e/libo/bibisect-win32-5.4.
Теоретически, нужно проделать 12 итераций (но по факту их может быть и на один или два больше!) - запусков сборок LibreOffice из репы-bisect, для каждой из которых нужно проверить наличие или отсутствие ошибки. Git сам в итоге выведет итоговый коммит, который приводит к сбою.
Сначала нужно убедиться, что мы используем нужную репу для поиска нашей регрессии. Мы проверим, что в последнем билде в данной ветке наша ошибка уже присутствует, а в первой еще нет. Для этого введите команду git checkout master, оно чуть подумает и выведет некий результат:
Если вывод в терминале будет раскрашен в красный цвет или будет пестрить фразами типа error, значит что-то пошло не так и нужно разбираться и просить помощи (как это делал я, когда мучался в начале процесса).
Следующая команда instdir/program/soffice запустит последнюю сборку (или билд - от английского build) LibreOffice в данной версии bisect-репозитория. Теперь в этом запущенном экземпляре LibreOffice вы делаете те действия, которые приводят к Вашей ошибке. Это нужно, чтобы убедиться, что ошибка УЖЕ есть в данном билде.
ВНИМАНИЕ! Часто бывает, что команда instdir/program/soffice не запускает LibreOffice и ничего не выводит в консоль. Дайте эту команду повторно. И только если и после второй попытки запуска LibreOffice не запустился, то можно говорить о том, что есть проблема либо с репозиторием, либо с git, либо что-то ещё.
ПРИМЕЧАНИЕ: если в последнем билде Вашей ошибки нет, это значит, что вы ищете регрессию не в той версии!
ПРИМЕЧАНИЕ: Вы должны искать только Вашу ошибку, на иные ошибки не обращайте внимание, за один цикл итераций (см.ниже) вы находите одну конкретную регрессию, которая привела именно к Вашей ошибке.
Убедились, что ошибка есть? Хорошо. Следующая команда будет git checkout oldest. И следом за ней сразу instdir/program/soffice. Эта последовательность запустит самый первый билд в версии. Выполните снова действия, которые приводят к Вашей ошибке. Убедитесь, что ошибки ЕЩЁ НЕТ! Если это так (в последнем билде есть ошибка, а в первом нет), то регрессия была внесена где-то между этими билдами. И мы начинаем самое главное.
Даем команду git bisect start master oldest.
И начинаем выполнять следующие действия раз за разом:
1. Вводим команду instdir/program/soffice - запускаем LibreOffice, проверяем на наличие ошибки, просто закрываем LibreOffice (либо, если ошибка критическая, то он сам закроется), и
2. - если ошибка есть, даем команду git bisect bad
    - если ошибки нет, даем команду git bisect good
3. Возвращаемся к пункту 1.
ВНИМАНИЕ! Обратите внимание на то, что ошибка обязательно должна проявиться при выполнении этих итераций хотя бы пару раз. Если у вас все время ответ будет good, это значит, что что-то пошло не так и нужно разбираться со знающими людьми! 
ВНИМАНИЕ! Может случится так, что LibreOffice не будет стартовать вовсе или с какими-то ошибками, это может означать, что билд был неработоспособный. В таком случае необходимо дать команду git bisect skip, и вернуться к пункту 1.
По мере выполнения этих шагов git будет писать нечто вроде "Осталось 11 (10, 9......2, 1) шагов до конца". Может писать и "Осталось 0 шагов до конца, но при этом не покажет финальный результат (о нем чуть ниже), поэтому процесс нужно продолжать до тех пор, пока git не покажет примерно такой вывод в консоли:
Это и есть наша регрессия. Это то, что мы должны показать в багзилле в качестве результата проведенной операции bibisecting'a.
ВНИМАНИЕ! Из этого вывода нам нужна строка source-hash и Author из НИЖНЕГО блока, в нашем случае Jan Holesovsky.
В багзиллу проекта помимо описания бага, Вы должны после bibisecting'a написать нечто вроде: "I bisected this bug. First bad commit 2d19e9bb07ccff3134f855812dddfda5c07b1fe4 from Jan Holesovsky." И в доказательсво привести вывод из вашей консоли git с результатом bibicting'a.

2 комментария:

  1. Спасибо Роману и всем, кто, прочитав это, сделает хотя бы один бибисект!

    > нужно перейти в наш рабочий каталог, выполнив команду cd /cygdrive/e/libo

    Сейчас в cygwin работает также указание путей без cygdrive в таком виде:

    cd e:/libo

    То есть достаточно взять Windows-путь, и все обратные слеши заменить на прямые.

    > Далее выполняем команду git clone git://gerrit.libreoffice.org/bibisect-win32-5.4

    Примечание: Адреса репозиториев для разных версий указаны на страничке, указанной вначале, а также можно посмотреть релевантные репозитории здесь: https://gerrit.libreoffice.org/#/admin/projects/?filter=bibisect

    ОтветитьУдалить
  2. После того, как виви... сорри, бибисекция окончена, её нужно закрыть. Для этого используется команда

    git bisect reset

    После её выполнения можно начать новую бибисекцию. Выполнение этой команды вернёт репозиторий в то состояние (к тому коммиту), которое было на момент выполнения git bisect start ... (вероятно, это самый первый коммит в репозитории (т.е. oldest), если всё выполнено согласно приведённой инструкции). Если нужно вернуться к определённому коммиту, например, самому последнему, нужно указать его так:

    git bisect reset master

    ОтветитьУдалить

Внимание! Сообщения проходят премодерацию!