понедельник, 2 июля 2012 г.

Дырка от бублика

Не знаю почему так получилось, но в тестировании, на мой взгляд, незаслуженно мало внимания уделяется анализу ошибок, того откуда и как они происходят, насколько катастрофичными они могут быть. Что, казалось бы, довольно странно - люди, работа которых искать ошибки, в первую очередь учатся кодить, болтать, мечтать стать менеджером и нараспев орать с табуретки набор заученных догматов-методологий (а как их иначе называть, если подкоркой не интересуемся?).

Для начала возьмем довольно старую и популярную модель, успользуемую для анализа рисков и управления ими - модель "швейцарского сыра". У нее (как и у любого обобщения) есть ряд недостатков, но она очень крутая в педагогическом плане. Про недостатки можно будет побеседовать потом, пока просто опишу что она из себя представляет.

Если вкратце, то модель представляет нам любую мало-мальски сложную социально-техническую систему в виде нескольких слоев швейцарского сыра, которые постоянно крутятся. Каждый слой сыра это своего рода барьер, которым организация/система пытается отгородиться от ошибок. Дырки в сыре это персональные недостатки того или иного куска системы - они все время меняются в размерах и перемещаются по различным кускам сыра. И когда все они совпадают происходит следующее:
Другими словами все становится очень нехорошо. Или просто нехорошо. Сложные системы штука такая - кумулятивный эффект от ошибок на разных уровнях скотина бездушная и легко может привести к чудовищным последствиям.

Дырки в сыре так же принято классифицировать как латентные и активные ошибки.

Чтобы было понятнее - разберем на примере.

Допусим у нас есть четыре слоя сыра:
  • Планирование
  • Код
  • Обучение
  • Сервера
На каких-то серверах не мониторится I/O. Это типичная латентная ошибка, т.к. сама по себе она проблему вызвать не может, но если что-то внезапно случится, то мы просто не сможем на этой стадии предотвратить проблему и все жахнет. И, скорее всего, пока не жахнет - эта ошибка будет существовать. Последнее, кстати, является крайне неприятным свойством латентных ошибок, но умный менеджер знает как с такими штуками бороться. Запишем эту ошибку:
  • Планирование
  • Код
  • Обучение
  • Сервера (не мониторим I/O - латентная ошибка)
Продолжим разбор гипотетического инциндента дальше.
Допустим группа умных людей немного ошиблась на стадии планирования емкостей и завизировала кривые расчеты у начальства. Получаем еще одну латентную дырку:
  • Планирование (ошиблись в расчетах емкостей - латентная ошибка)
  • Код
  • Обучение
  • Сервера (не мониторим I/O - латентная ошибка)
Все еще мало для катастрофы. Давайте добавим еще немного.
Пусть у нас тотальный непрерывный деплой и парочка unit-test'ов из тех, что прогоняются перед выкладкой кода на сервер ближайшие 20 минут не прогонятеся, т.к. рефакторится или находится в еще каком переходном состоянии. Ну бывает. Это непонятная ошибка, пусть будет латентная.
Еще кто-то взял и немножко нарушил стандарты кодирования. Наговнокодил, другими словами. Тоже бывает. Латентная ошибка.
А еще кто-то взял и зафигачил в код большой такой, сочный баг, который приводит к тому, что при вызове какой-то функции адово абузится запись на диск. Самая что ни на есть активная ошибка.
И чтобы жизнь медом не казалась кто-то намудил с фиче свичами перед выкладкой и открыл наружу вызовы той самой волшебной API и по ней автоматом обновилась дока. Опять активная ошибка.
Суммируем:
  • Планирование (ошиблись в расчетах емкостей - латентная ошибка)
  • Код (бага - активная ошибка, говнокод -  латентная  ошибка)
  • Обучение (открыли API наружу когда неположено - активная ошибка)
  • Сервера (не мониторим I/O - латентная ошибка, тесты мигрируют -  латентная  ошибка)
Если мы попытаемся сложить все вместе, то катастрофа случилась примерно так: 
  1. Запланировали емкостей явно меньше чем безопасно
  2. Случайно нашлась бага, которая абьюзит I/O
  3. Функцию с багой оказалось возможным вызвать через API снаружи
  4. Тесты не нашли внешний вызов и багу, т.к. мигрировали на юга
Говнокод и косяки с мониторингом к происхождению проблемы отношения не имеют, но чисто теоретически могут в этой ситуации привести к увеличению масштабов катастрофы. Их отсутствие предотвратить катастрофу не смогло бы, но сильно бы способствовало тому, чтобы приуменьшить ее вероятность/масштабы.

Если любое из приведенных 4-х событий не случилось (бага в другом месте, другие тесты мигрировали и т.д. и т.п.), то данной конкретной катастрофы могло бы и не случиться. Да и другой тоже. В этом плане "швейцарский сыр" мало чем отличается от модели "домино", разве что позволяет наглядно продемонстрировать все множество участников событий да как-то классифицировать ошибки на разных концах цепочки.

Вот такая вот гимнатиска. Какие меры стоит принимать для того чтобы такого больше не повторилось - думайте сами.
Явных козла отпущения у нас тут два - по числу активных ошибок. Еще пачка по остальным ошибкам. Но "сырная" модель сообщает, что поиск козлов отпущения не для правильных ребят.
Как нужно было делать до - теперь уже любой идиот скажет (мне, лично, в точке, где у нас просос по мониторингу еще откровения с Марса не приходили).

ЗЫ: Думаю какой-нибудь надмозг советской закалки уже снимает ремень чтобы выпороть того кто ему меньше всего понравился (примерно по этой причине планировать емкости безопаснее чем писать тесты - перед вами море материала для перевода стрелок). Т.е. хочет чисто гипотетически и совсем уж постфактум зыкрыть всего одну сырную дырку не обеспечив того что она никогда не повторится. Ну ок, сам себе злобный идиот раз создает такую корпоративную культуру.

ЗЗЫ: Еще раз повторюсь - модель говно и есть лучше. Но оно все так сложно...

5 комментариев:

  1. Это не странно.

    Просто не каждый тестировщик может внятно сказать, в чем была причина ошибки. Было ли это системно, или просто неведомая запятая затесалась - он симптомы описал, а дальше режьте, что хотите...

    Та же фигня и с post-mortem - кому приятно ковыряться в том, что только-только затихло?

    - А ещё, Леша, ты допустил вот такую ошибку...
    - Я был не виноват! Это все Клава!
    - Не виноватая я, они сами поздно пришли!
    - Как не виновата? Очень виновата, очень!
    - Да нет же!

    Вот и анализируй причиный багов.

    ОтветитьУдалить
    Ответы
    1. Это очень и очень странно. Тестировщик должен уметь исследовать проблему. Плохое описание симптоматики (не просто steps to reproduce) это отвратительно и кушает время у разработчиков. Если тестировщик может указать в чем конкретно проблема - это очень хорошо. Я уж молчу про такие вещи как анализ возможных последствий.

      Ну и из Канера в тему:
      To test effectively, our theories of error have to be theories about the mistakes people make and when / why they make them.


      А описанный post-mortem это треш уар и содомия. Если организация создает такие условия для post-mortem анализа, то она сама себе обрубает возможность хорошей профилактики и сводит желание давать обратную связь на нет.

      Удалить
    2. Кстати, эта "сырная" модель - наглядная демонстрация роли организационных структур в идентификации и профилактике ошибок. В этом основная ее ценность, т.к. генезис проблемы она показывает не очень хорошо.

      Удалить
  2. A3 анализ от Тоёты?
    У нас некоторые пытаются делать такой анализ проблем, но когда он никому не нужен и его хотят 1-2 человека - то what's the value?

    ОтветитьУдалить
    Ответы
    1. A3 это уже не просто модель (до кучи еще и весьма сомнительный процесс).
      Ну и если всем пофигу, то по меньшей мере есть одна ценность - понимание того что факапоопасность работы и твоя собственная производительность от тебя самого как правило не зависят и имеют более сложную цепочки причин и следствий чем многим кажется. И если организация достаточно тупая чтобы разбор факапов ограничивать раздачей люлей задействованным лицам, то вполне естественно для сотрудника стремиться оказаться подальше от мест, где раздают люли. Ему просто ничего больше не остается за неимением возможности что-то поменять.

      Удалить