Тестирование отказоустойчивого кода

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

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

  • Имейте внешний процесс, смотрят серверный код и затем пытаются уничтожить его в том, что думает внешний процесс, соответствующая точка в тесте
  • Добавьте кодируют приложение, которое заставит это отказывать, определенное знают критические точки

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

5
задан Robert 3 May 2010 в 09:09
поделиться

4 ответа

Ваше беспокойство по поводу внесения неисправностей не является фундаментальным. Вам просто нужен надежный способ предотвратить развертывание такого кода. Один из способов сделать это - спроектировать инжектор неисправностей в качестве отладчика. Т.е. ошибки вводятся внешним по отношению к вашему процессу процессом. Это уже обеспечивает уровень изоляции. Более того, большинство ОС предоставляют какой-то контроль доступа, который предотвращает отладку, если это специально не разрешено.В наиболее примитивной форме это ограничение до root , в других операционных системах требуется особая «привилегия отладки». Естественно, на производстве этого не будет ни у кого, а значит, неисправный инжектор не может даже работать на производстве.

Фактически, инжектор неисправности может устанавливать точки останова по определенным адресам, то есть функции или даже строке кода. Затем вы можете отреагировать на это, например путем завершения процесса после трехкратного срабатывания определенной точки останова.

2
ответ дан 14 December 2019 в 04:32
поделиться

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

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

Вы можете найти некоторые ресурсы на Fault Injection странице Википедии, в частности в разделе Software Implemented Fault Injection.

2
ответ дан 14 December 2019 в 04:32
поделиться

Я как раз собирался написать то же самое, что и Джастин:)

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

Также кажется возможным убедиться, что тестовый код не будет запущен в производство. Я бы не одобрил условную компиляцию, а предпочел бы использовать некоторый файл конфигурации для выбора компонента ведения журнала.

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

1
ответ дан 14 December 2019 в 04:32
поделиться

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

Во-вторых, запуск приложения со случайным kill -9, и отключение сетевых интерфейсов может быть хорошим способом проверить эти вещи.

Я бы также предложил проверить отказ файловой системы. Как вы это сделаете, зависит от вашей ОС, в Solaris или FreeBSD я бы создал файловую систему zfs в файл, а затем rm файл во время работы приложения.

Если вы используете код базы данных, тогда я бы также предложил проверить отказ базы данных.

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

3
ответ дан 14 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: