На Хабре уже были подборки «самых масштабных багов в истории»: взорвавшаяся ракета Ariane-5, передозировка радиацией от Therac-25 и так далее.

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

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

Перерыв на лимонад

Такая же загадочная, как и с 500-милевой почтой, история произошла  в одной компании, разрабатывающей финансовое приложение. Вскоре после сдачи проекта служба поддержки получила заявку, в которой пользователь описывал проблему с веб-приложением вот так: «Оно падает каждый раз, когда я пью колу».

Саппорт посмеялся над заявкой и проигнорировал ее. Но пользователь упорствовал и добавлял новые сведения, что, мол, приложение работает нормально, когда он пьет кофе, а вот на кока-коле вырубается. Один из членов поддержки все же решил разобраться в проблеме.

Выяснилось следующее. Кофейный автомат находился всего в нескольких метрах от пользователя. А автомат по продаже колы — на совсем другом этаже в кафетерии, так что отправляясь туда, пользователь тратил ощутимое время. А в онлайновой веб-форме была функция тайм-аута, которая заставляла приложение разлогиниваться, если со страницей не взаимодействовали более 15 минут.

В общем, даже когда пользовательский баг-репорт на первый взгляд кажется абсурдным, не стоит сразу отметать его со словами «глупый пользователь».

Перерыв на кубики

А вот перекликающаяся история. Ещё в 2017-м на Heisenbug Андрей Солнцев рассказывал (в отдельном хабрапосте можно прочитать подробнее):

«Детективное расследование длиной в два года, абсолютно реальный случай. Ситуация такая: наши тесты довольно часто были flaky и падали, и в стек-трейсах было видно, что Chrome зависает: не тест наш, а именно Chrome. Пытались сделать всё, что только может прийти в голову — проблема лишь стала возникать ещё чаще. 

Попытались воспроизвести проблему: пишем цикл от 1 до 1000, в цикле просто открываем браузер, первую страничку в нашем приложении и закрываем. Написали такой цикл, и… бинго! Результат: проблема стала повторяться стабильно (правда, примерно через каждые 80 итераций)! Круто! Правда, это достижение долго ничего не давало. Запустил ты, дождался 80-й итерации, завис Chrome… а дальше что делать? Смотришь в стек-трейсы, дампы, логи — ничего полезного там нет. 

И тут в этой истории начинается сказочный момент. Однажды, после бесконечного количества попыток, я снова запустил эти тесты, он у меня снова на какой-то итерации вроде 56-й завис, я думаю «давай ещё что-нибудь покопаю» (правда, не знаю, куда ещё брейкпойнт поставить или какой-то лог добавить). В этот момент дочка предлагает поиграть в кубики, а у меня тут как раз тест завис. Я говорю «Подожди», она мне: «Ты что, не понял, у меня тут к у б и к и

Что поделать, с грустью оставил компьютер, пошёл играть в кубики… И вдруг, примерно через 20 минут, случайно бросаю взгляд на экран, и вижу совершенно неожиданную картину:

Что получается: идёт отсчёт, через сколько минут истечёт сессия, а я строю башню из кубиков, остаётся две, одна… сессия истекает, тест продолжается, бежит до конца и падает (элемента уже нет, сессия истекла).

Что получается: Chrome на самом деле не зависал, как мы думали всё это время, он всё это время что-то ждал. Когда сессия истекала, дожидался, шёл дальше». 

Смотрите, как (не) надо

Реддитор Xantoxu решил провести серию стримов по программированию и на примере создания игры рассмотреть некоторые концепции написания кода. Он хотел научить людей хорошим методам программирования, логике, организации кода, основам искусственного интеллекта и балансировки игры, и все в таком духе. Для этого он выбрал простую текстовую игру для консоли Windows, и там делал всякие интересные штуки.

Во время отладочного стрима реддитор специально вставлял в код ошибки, чтобы показать, как правильно читать ошибки, которые выдает компилятор. Все шло прекрасно. Он объяснял, что значат те или иные выводы компилятора и рассказывал как тестировать свою игру. Но в каком-то куске кода забыл поставить точку с запятой. Правда, забыл. Это не входило в планы. Компилятор начал ругаться, и стримеру понадобился целый час, чтобы понять, что не так.

То есть он целый час искал ошибку на стриме по работе с ошибками. Наверняка зрители были в восторге.

Баг? Я звоню в полицию

А вот история из 1995 года. Один реддитор zircofluoride работал в стартапе, где создавал embedded-систему со встроенным телефонным номеронабирателем, где использовался тональный набор (Dual-Tone Multi-Frequency, DTMF).

Схема кодирования DTMF располагает цифры 0–9, #, * (и A–D) в матрице 4x4 с разной частотой для каждой строки и столбца. Суть программы была в том, что прошивка генерирует частоту строки на одном GPIO, а частоту столбца — на другом GPIO, аппаратура смешивает тоны и подает результат на телефонную линию.

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

Оказалось, что код использовал неправильные частоты для всех частот, кроме одного столбца и двух строк, соответствующих цифрам 1 и 9, и программа эффективно набирала 9-1-1 снова и снова. Через четыре минуты после запуска кода в офисе появились полицейские с оружием наготове.

Когда маркетинг лезет в разработку

А вот еще одна старая драматическая история, без стрельбы, но почти с детективным сюжетом.

Один программист работал в компании, которая генерирует отчеты со статистикой по медицинскому ПО и оборудованию. Долгое время команда разработки занималась миграцией сайтов на MVC ASP.NET. В числе прочего сделали логирование, и поначалу всё шло хорошо, число ошибок становилось меньше с каждым днем.

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

А утром один менеджер из отдела маркетинга проболтался, что сам добавил проблемный код на сайт. Он проигнорировал существующий процесс по деплою и выложил на сервер код, которого не было в системе контроля версий, и никто не знал про это. Это был баннер с бегущей строкой, сделанный на JS и взятый откуда-то из интернета.

Этот простой код постоянно исполнялся, и отчет генерировался буквально каждую итерацию. Логирование, которое внедрила команда, не содержало никакого средства против подобного «спама» и отправляло на сервер тысячи запросов, что блокировало браузер и валило серверы. Не стоит и говорить, что эту чуму снесли с сервера, а менеджера ждал серьезный разговор с директором.

Не фича, а баг

А бывает так, что реализованные и корректно работающие (с точки зрения разработчика) функции в итоге убираются, потому что они хуже багов.

Самый известный пример — это помощник Скрепыш (Clippy) в пакете MS Office. 

Поначалу Clippy казался безобидным офисным помощником. Но пользователей он бесил и раздражал. Есть даже дипломная работа на тему того, почему люди ненавидят несчастную Скрепку (спойлер: потому что она заставляет чувствовать себя беспомощным).

В итоге Microsoft удалила Скрепку из системы. И фактически рекламировала тот факт, что в новой версии Office ее нет. Мол, в Office XP настолько все просто и понятно, что помощник просто будет сидеть без работы. Вот так фича стала багом и даже вошла в топ-50 худших изобретений вместе с ДДТ и водородными дирижаблями.

В истории разработки найдется много историй о продуктах, провалившихся из-за недостаточного качества. Здесь и эппловская ОС Copland, и Netscape Navigator 6.0, и забагованные игры.

Не баг, а фича. Развенчиваем миф про грудь Лары Крофт

И раз уж мы упомянули игры напоследок побудем разрушителями легенд.

Есть городская легенда, объясняющая откуда взялся оригинальный образ Лары Крофт с большой грудью. Якобы Тоби Гард — художник-аниматор — случайно установил слишком большое значение и заметил это слишком поздно, уже когда надо было сдавать работу. А менеджерам настолько понравился образ большегрудой красотки, что они решили так и выпускать.

В 1997 Тоби Гард давал интервью журналу The Face, и когда журналист спросил про размеры груди Лары Крофт, Тоби саркастически ответил, что у него дрогнула рука с мышью и он случайно установил такое значение. Это была очевидная шутка.

Но затем журнал GameSpot опубликовал статью (1 апреля, между прочим) про «ужасную ошибку», и понеслась. 

Но на самом деле все это было часть запланированной маркетинговой компании, и подобный образ Лары Крофт помогал продавать продукт. Хотя и без багов в игре тоже не обошлось.

Вывод

Можно ли сделать из всего написанного выше какие-то выводы? Случаи слишком разные для категоричных общих заявлений, но можно выделить что-то в таком духе:

  • В тестировании полезно уметь «think outside the box»: иногда правильные ответы бывают очень неочевидными и контринтуитивными.

  • Всем, у кого есть доступы со стороны разработки, стоит помнить, что правила придуманы не просто так: не знаешь брод — не суйся в прод.

  • А отвлечься от тестирования и поиграть с ребёнком в кубики бывает полезно не только для семьи, но и для тестирования.

Мы пойдём дальше готовить Heisenbug: его онлайн-часть начнётся уже в понедельник. А 21 июня у него будет отдельный офлайн-день в Петербурге. Программу можно увидеть на сайте, билеты — там же.

Будем рады увидеть вас и в онлайне, и в Питере!