Теория.
Практически всегда мы тестируем то как себя будет вести приложение при взаимодействии пользователя с ним.Это правильно с одной стороны - пользователь важен, он приносит нам деньги и то "качество", которое хочет видеть пользователь - оно превыше всего.
Но есть определенные обстоятельства в которых мы тестируем не то как пользователь взаимодействует с приложением, а то как приложение взаимодействует с другими приложениями (если мы гооворим о распределенных системах) или как модули приложения взаимодействуют между собой.
(так выглядят сервисы внутри twitter, источник)
И вот с этого момента нас начинает интересовать, что будет с нашим приложением А если приложение Б от которого оно зависит ляжет или начнет себя неадекватно вести.
Этим аспектам уделяют мало внимания, в лучшем случае - падение одного приложения потянет за собой крэш всей системы (пользовательской).
Это хорошо и правильно - если вы не видите для себя другого способа, то пусть будет хотя бы так.
Однако если вы его не только видите но и используете, то скорее всего вы заинтересованы в проверке работоспособности вашей зашиты от падений сторонних компонентов.
И вот тут начинаются интересности:
- Естественно у вас такая защита должна быть. А вот всунуть ее в legacy-код или продукт дизайн которого таких возможностей не предусматривал не так просто.
- Уровень и с которого "падаем" и глубина падения. Если говорить про стандартную трехзвенную архитектуру, то тут фантазии особо разгуляться негде.
Все намного интереснее - често говоря просто эта задача актуальнее - когда у вас SOA или микросервисы. Здесь и уровней больше, типы и глубина падения тоже могут быть разными. Про типы хочется написать отдельно - это может быть как и просто генерация исключения для тестирования того что приложение стабильно его обрабатывает, проглатывает и снаружи ничего не видно, так и внедрение более изощеренного поведения - эмуляция неправильной конфигурации приложения, изменение диапазна типовых значений для экспериментов над поведением. Про банальности типа потери соединения с БД во время работы - молчу. - Крушение приложения. Отдельная тема для распределенных систем особенно для тех что занимаются in-memory вычислениями (Storm, Kafka, Mesos, Suro). Что произойдет с блоком данных отправленным на in-memory обработку если обработчик сдох? Крушения опять же могут быть разными, но тут очень много специфики у каждого.
Довольно теории, перейдем к практике.
Приложение отзывается на три урла.
http://127.0.0.1:9090/doWork - отдает рандомное целое число от 0 до 1000.
http://127.0.0.1:9090/fault?mode=enabled - включает fault-режим
http://127.0.0.1:9090/fault?mode=disabled - выключает fault-режим
После включения режима падения генератор случайных числе начинает отдавать 0 или 1. Это и есть наше падение.
http://127.0.0.1:9090/crash?time=15 - падение приложения через указанное время (опционально, если не указано, то упадет сразу).
Код приложения выложен на github.
Хочется более приближенных к реальности примеров - их есть у меня.
Вот например ключи запуска Chromium
Практика.
Для практики я построил на коленке простейшее вэб-приложение на Java (Jetty inside).Приложение отзывается на три урла.
http://127.0.0.1:9090/doWork - отдает рандомное целое число от 0 до 1000.
http://127.0.0.1:9090/fault?mode=disabled - выключает fault-режим
После включения режима падения генератор случайных числе начинает отдавать 0 или 1. Это и есть наше падение.
http://127.0.0.1:9090/crash?time=15 - падение приложения через указанное время (опционально, если не указано, то упадет сразу).
Как оно организовано изнутри.
Внутри все сделал по максимуму просто - интерфейс генератора случайных чисел задекорирован и на уровне декоратора отрабатывает бизнес-логика использования или неиспользования fault-режима.Код приложения выложен на github.
Хочется более приближенных к реальности примеров - их есть у меня.
Вот например ключи запуска Chromium