Мой баг дня (записки тестировщика)
243 subscribers
169 photos
23 videos
11 files
126 links
Precondition:
Repro steps:
1. ...
2. ...
3. ...
Expected: good
Actual: bad

Связь: @MyachinDA
Download Telegram
Про неуспешные решения. Был такой конкруент (он и сейчас есть, но ошибки уже давно нет), который вообще не парился по поводу каких-то там профилей, прав. У него сервис стартовал с правами SYSTEM (что абсолютно ожидаемо, разумеется) и уже он запускал GUI со СВОИМИ ТЕКУЩИМИ ПРАВАМИ. То есть GUI тоже работал с правами SYSTEM.

Плюс такого подхода был, например, в возможности из GUI достучаться до путей, недоступных простому пользователю. Минус же перевешивал любой возможный плюс — локальное повышение привилегий. Любой пользователь в системе, даже супер ограниченный Гость, мог открыть GUI продукта, нажать F1, чтобы открылась справка, использующая движок IE, в ней ввести локальный адрес и в ответ система запускала explorer с правами SYSTEM в сеансе Guest. Ну а дальше делайте что хотите вообще, выше вас только звёзды.

Ну и раз речь зашла про то, как антивирусы добавляли огромные дыры в систему, оставлю здесь эту ссылку: http://4pda.ru/forum/index.php?showtopic=64914 Здесь идея в том, чтобы обходить систему безопасности поздних версий Symbian путём добавляения всяких патчеров в карантин некоторы антивирусов (тех, кто не особо заботился о безопасности — правильного вы там не найдёте) и затем восстановить их из карантина. После восстановления патчеры будут чудестным образом подписаны подписью антивируса.

Строго следите за безопасностью того, что вы делаете. Продумывайте векторы атак. Даже если для успешной атаки нужно иметь знание, доступное только в вашей команде — это всё равно проблема. Security through obscurity НЕ работает.
Если вам придётся ссориться с коллегами ради защиты клиентов — ссорьтесь. Деньги приносят клиенты, а не коллеги.
Коллеги тестировщики. Вычитываете все тексты. Держите в голове тот факт, что никто не читает инструкции и документы, кроме клиентов. Авторы инструкций сами их не вычитывают, а корректоров у вас в штате обычно нет.

Пример. Топаем на сайт Сбербанка и находим услугу "Прямое управление счетами": https://www.sberbank.ru/ru/legal/bankingservice/corporative/linecontrol
Прокручиваем страницу и находим "Инструкция по продукту «Прямое управление счетами»": https://www.sberbank.ru/common/img/uploaded/files/pdf/legal/sberbank-corp/instrukcia_pus.pdf

Открываем документ и делаем поиск по слову "корпор" — должно быть найдено 19 вхождений. Это слово "Корпор@ция". Теперь делаем очевидную фекальную опечатку — слово "копро". И видим 2 вхождения!

Тестировщик! На тебе лежит отвественность за всё. Ошибок не должно быть не только там, над чем работаешь лично ты, но вообще нигде. Ты единственный, кто умеет искать ошибки и ты обязан это делать.
Появилась задача проверить, можно ли установить apk весом более 4 ГБ на Android. Как оказалось, файл такого размера даже подписать не удаётся. Ни jarsigner из OpenJDK, ни apksinger из build-tools 28.0.3 не могут обработать файл такого (5 ГБ) размера. Аналогично проваливается и zipalign.

Если вы знаете, как подписать apk весом в 5 ГБ, вы очень поможете.
@Umnik_ADS
Я очень люблю плавающие баги. Их сложно обнаружить, их сложно локализовать, в них сложно разобраться, их сложно воспроиводить. С ними даже не всегда ясно, ошибка ли это. Так что такие ошибки — вызов. Да, я искренне люблю плавающие проблемы.

Ошибка из 2012 года, на исправление которой потребовалось два месяца и взаимодействие нескольких команд.

Описание предельно простое:
19/7/2012 17:32:44 - Dmitry Myachin (2502):
1. Change settings to custom. For example enable Interactive mode and allow detection for "Othes" category
2. Save settings
3. Reboot Windows
4. Check settings
Expected:
Settings are custom
Actual:
Settings are default

Первый подход к снаряду случился уже на следующий день, но он не помог. Стали копать дальше. По логам выходило, что сервис долго завершался и это как-то приводило к несохранению. Значит нужно было ускорить завершение сервиса?!
Второй подход к снаряду должен был ускорить завершение работы сервиса на выключении системы, однако ничего не изменилось в самой ошибке. Настройки всё также не сохранялись, но стали не сохраняться реже. У разработчиков же вообще проблемы не было. Не было проблемы и у тестировщиков. Но проблема была у меня на личном ПК и то не всегда.
Скилов текущего разработчика уже не хватало, подключили экспертов по компонентам, чтобы те посмотрели, как быстро завершаются их собственные компоненты. Каждый из разработчиков ответил, что с их стороны всё в порядке, из компоненты завершились задолго до завершения работы сервиса.

Тогда почему не сохраняются настройки? И почему не всегда? И почему не на всех машинах? Как вообще связано сохранение настроек и завршение работы сервиса.
Новый подход к снаряду — расширенные логгирования. По ним стало видно, что настройки не сохраняются по причине "пока не нужно". Это "не нужно" вешала команда, занимающаяся производительностью. Задачу перевесили на них, чтобы разобрались.
Команда производительности сказала, что у них всё нормально. Они не флашат настройки после каждого перетыкивания галки в интерфейсе, чтобы не нагружать системы. Они накапливают изменения и записывают настройки либо когда никто ничем не занимается в системе, либо когда система завершает работу.

Стало немножко яснее. У тестировщиков и разработчиков виртуалки часто простаивали и потому у них проблемы не было. А мой личный комп не простаивал вообще никогда. Отсюда это "пока не нужно".

Стало понятно, что есть конфликт — либо сохранять каждую настройку сразу, что может сказаться на производительности системы (в те времена SSD ещё не были популярны, иначе бы ещё этот аргумент добавили — лишние записи, если можно записать один раз), особенно если прямо сейчас у пользователя, скажем, идёт работа с файловой системой, либо всё же победить ошибку с несохранением на выключении. Первое, очевидно, делается очень просто, но второе — это честно.

Задачу перевесили на очень экспертного эксперта, который и разобрался со всем. Как оказалось, продукт не может записать настройки на выключении, потому что нечно убивает сервис. Нечто — это ОС. Но почему? Поведение системы должно быть таким, что система оповещает всех о выключении. На этом оповещении сервис быстро бы записал настройки, буквально за одну секунду (на самом деле быстрее) и всё бы должно быть хорошо.

Оказалось, что операция записи настроек выполнялась не оптимально именно в сценарии, когда система оповещает о выключении. Ну то есть как не оптимально. Использовался тот же самый механзим записи настроек. Если сильно упростить, то дёргался метод .saveSettings(), внутри которого была всё та же проверка на нагрузку на ОС и продукт принимал решение подождать момента, когда и проц посвободнее будет, и диск не будут жрать. На выключении, ага. А Windows даёт лишь 5 секунд и после этого завершает сервис сама.
Когда с этим разобрались, фикс появился очень быстро. И разобрался с этим один конкретный разработчик. Пожалуй, один из самых сильных в компании. Мне кажется, что если он захочет, он может переписать продукт целиком по памяти, каждый компонент, каждый драйвер. И вот это его понимание всех компонентов продукта позволило увидеть проблему сверху, тогда как каждая из подкоманд не видела проблемы со своей стороны. С точки зрения каждой подкоманды всё шло хорошо.

Кстати, параллельно этому разбору разработчик нашёл баг и в самой Windows. В Windows есть пециальный параметр в реестре, которым можно увеличить таймаут на завершение сервиса. И этот параметр не рабтает в Win7/2003: https://support.microsoft.com/en-us/help/2549760/waittokillservicetimeout-registry-value-does-not-work-in-windows-7-or Примечательно, что MS знал уже об этом баге, а разработчик просто нашёл его при исследовании. После обнаружения проверил на сайте MS и нашёл, что даже патч есть, но персональный. То есть персональным он был на тот момент, сейчас уже, наверное, раскатан на всех.

Если со всех сторон проблемы нет, а она вот, перед глазами, значит нужно подняться уровнями выше. Вам потребуется человек, который знает тонкости взаимодействий этих сторон. И великолепно, если это будете вы сами.
Когда покупаете рекламу, тщательно выбирайте площадки и способы распространения. Потому что может получиться вот так.
Дизайн 2/5, конечно.
Я тут выяснил, что очень многие не понимают, что такое каналы уведомлений (Notification Channel) в современных версиях Android, зачем они вообще нужны и как их применять.

Каналы нужны для того, чтобы пользователь мог управлять уведомлениями разной сути отдельно от других. К примеру, ваш продукт умеет создавать web сервер, smb сервер и ftp сервер. И пользователь держит ftp всё время включенным, а остальные включает время от времени.
Для того, чтобы система вас не убивала как можно дольше, вы используете foreground service, а значит отображаетесь в уведомлениях. И пользователя разжражает лишняя плашка, ведь он и так помнит, что FTP сервер вечно запущен. Так что он может отключить этот канал. С вашей стороны разумно три разных уведомления разделить в три разных канала. Тогда отключение канала с уведомлением для FTP никак не затронет другие два.
Более того, пользователь может настроить все каналы по-разному. Одному добавит звуковое уведомление при старте, а другому не разрешит включать погашенный экран.

Пример с KIS для Android. Пользователей раздражает вечно весящее уведомление о работе. Но если его убрать, отвалится часть функционала продукта на Android 8 и новее. Я предложил команде сделать разные каналы для разных событий. Но главное, выделить постоянное уведомление в отдельный канал типа «Persistent notification». Тогда пользователь сможет спокойно убрать именно это уведомление, но при этом получать другие уведомления продукта — о старте обновлений баз, об обнаружении угрозы. Надеюсь, это дотащат до релиза. По крайней мере концепт уже сделан.

Но есть обратные примеры. Скажем, Telegram создаёт по одному каналу уведомлений на каждый из чатиков. Включая приватные чаты и каналы. И не удаляет их. Этим он частично раскрывает вас, как пользователя. Скажем, вы запаролили вход в ТГ. Но можно открыть настройки уведомлений ТГ и увидеть там каналы, на которые вы подписаны, увидеть, с кем вы переписывались, даже если вы уже удалили эти переписки. Можете проверить сами и убедиться. Не удаление этих каналов уведомлений сливает о вас данные, которые вы хотели бы скрыть.
Строго говоря, я считаю это уязвимостью, ставящую под угрозу мою приватность.
При этом не понятно, зачем создавать канал на каждый чат, если проще из самого приложения управлять уведомлениями конкретного чата. Правильным было бы иметь один канал на сервисные сообщения, один канал на обычные сообщения, один на приватные (те, у которых время уничтожения задаётся) и один "на всякий случай". Тогда бы пользователь мог глобально настроить, чтобы все секретные чаты не показывали уведомлений и не включали экран. Сейчас же нельзя настроить такое поведение и это противоречит идее каналов уведомлений.

Надесь, это поможет кому-то разобраться с действительно полезной штукой, которую, к сожалению, почти никто не умеет использовать по назначению. Особенно не умеет это делать Телеграм.
Дополнение про каналы уведомлений. К сожалению, в Android 8.0 (именно .0, но не в 8.1 и выше) есть баг. Если вы сделаете канал типа Persistent notification, чтобы пользователь мог его штатно скрыть, то ему тут же вывалится другое уведомление, уже от ОС. В нём будет сказано что-то вроде "Приложение ХХХ работает в фоне" или что-то такое. В общем, намекать будет на расход батарейки.

Ошибка в Андроид в том, что пользователь и так знал, что приложение работает в фоне, он видел это по постоянно висящему не смахиваемому уведомлению (которое создаёт foreground service этого приложения). И он сам, своими руками, скрыл это уведомление. Зачем ему сообщать о том, что он и так знает? При этом сообщать это другом не смахиваемым уведомлением. Бред же.

Этот бред исправлен в 8.1 и новее. Так что будьте готовы к такому поведению в 8.0.

У вас есть несколько способов убрать это раздражающее уведомление и ни один из них не является хорошим:
1. Дать пользователю инструкцию, как в системе отключить канал, сообщающих о фоновых работах. То есть даже когда это уведомление действительно будет нужно, пользователь его не увидит.
2. Запросить права на управление уведомлениями. Эта фича появилась в Android 4.3. Тогда вы сможете скрывать чужие уведомления. _ВОЗМОЖНО_ сможете скрыть и это. Честно говоря, я не проверял.

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

Зная Google, никакие обновления от 1 и 5 чисел каждого месяца не будут исправлять эту ошибку.
Классика — опечататься в названии компании. Это 2013 год. С тех пор, вроде, такого не встречалось.
Но я не об этом. Сейчас расскажу об одном более-менее интересном баге, который нашёл буквально вслепую. Она была в коде, который считался недостижимым (Unreachable code).

Возможно кто-то из вас помнит про очень старую уязвимость у многих производителей Android прошивок. Она была связана с USSD кодом *2767*3855#. Этот код вызывал hard reset огромного множества устройств без подтверждения пользователя. То есть можно было на сайте разместить ссылку <frame src="tel:*2767*3855%23" /> и при заходе на страничку телефон сразу форматировался.

Многие производители как прошивок, так и security решений срочно выпустили маленькие приложения, которые становились звонилками по умолчанию. Всё, что они делали — не прокидыали именно этот USSD в системную звонилку, а всё остальное прокидывали молча. Проксировали, в общем.

Лаборатория не стала делать отдельную утилиту, а выпустила обновление антивируса с такой функциональность.

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

Раскатали релиз, всё шло хорошо. В следующем релизе убрали и прокси-звонилку. И всё и дальше шло бы хорошо, если бы через какое-то время Google не представил супер новую невиданную ранее фичу — Okay Google. И пошли редкие, но достаточно стабильные падения в вызове кода, который нельзя было вызвать. А падало потому что и кода уже не было.

Поставили мне задачу понять, как это происходит. Как вообще людям удаётся достать недостижимый код. Я пробовал и по ссылка tel: тыкать, и в SMS их присылал, и звонилки разные пробовал, и USSD код этот вызывал. Пока не сказал Okay Google call one one two. И продукт упал.

Этот код вызывался в сценарии, которого вообще не существовало во время его написания. Он вызывался только через Окей Гугл. Ассистент (тогда ещё не было Ассистента, до его появления было ещё несколько лет, но пусть будет он) дёргал вызов, который пропустили при вырезании этой фичи.

Фикс был очень простым и быстрым. А вот его обнаружение было тем ещё развлечением.

И нет, по стек трейсу нельзя было понять, как именно происходил вызов. Там лишь было падение из-за того, что есть обращение к тому, чего быть не должно. Можно было бы просто обернуть это исключение, но это костыль, а не решение проблемы.

Любой тестировщик со временем начинает мыслить очень творчески. Это помогает.
Я не умер, я в отпуске. А потому короткая история о том, как делать не надо.
В свой первый отпуск 10 (или уже 11?) лет назад я ушёл, подложив говна под дверью команды, образно говоря.
В день подписания релиза, когда высокоприоритетных ошибок уже не было, я решил проверить, что будет, если отправлять в драйверы продукта некорректные вызовы.
Сейчас мне очевидно, что это была хоть и правильная проверка, но не вовремя. Такое нужно делать сильно заранее.
В общем, эти тесты отправляли XP в синяк. Я записал баг высокого приоритета (а это стоп релиза), встал из-за стола, взял рюкзак и свалил.

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

Не повторяйте моих ошибок, не хреначте стопари без объявления войны. Да, для вас качество должно быть на первом месте, но не всегда найденная ошибка должна останавливать релиз. Иногда разумнее перенести баг на патч, если вы с ними работаете. Называется это "патч нулевого дня". То есть даже пусть в релизном билде будет сценарий, при котором кровь кишки, при патче нулевого дня клиент с этой ошибкой не столкнётся.

Баг был в Windows XP самом, кстати. Драйвер лишь дал возможность на него напороться. Фикс был в банальном запрете этого вызова.
Мир свернул сильно не туда, когда дал управление маркетологам и продажникам. Да, понятно, что все хотят денег (и я, и вы), но всё же нужно знать меру.
Это скриншот сетевых запросов от браузера, когда пользователь пытается прочитать Privacy Statement для продукта, который собирается использовать.
Это не ошибка, всё здесь "правильно". Я специально писал письмо со своим недовольством по такому поведению, но нет, здесь всё юридически честно и чисто.

Но меня это всё равно печалит. Неправильно это. Неправильно не конкретно из-за компании, а неправильно вообще, в общем и в целом. Ведь так делают вообще все.
Все, кто хотел, прошли дополнение ко второй (в современном перезапуске) Ларе про Бабу Ягу? Там есть такая ачивка, описание которой меня расстроило. Точнее, перевод на русский язык:
https://pbs.twimg.com/media/DX86STNWAAAdODo.jpg:large