February 21, 2012

Генерируем внешние API по-питоновски

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

Итак мы пишем серверный компонент программы, который должен контролироваться внешними утилитами. Типичные варианты управления:

  • CLI - административный интерфейс командной строки, так-же удобен для разработки
  • REST - для других языков, WebUI & Co
  • RCP в каком-то виде (thrift, PyRo, etc)

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

February 11, 2012

Использование виртуальных машин для автоматического тестировани

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

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

February 10, 2012

Запуск процессов в linux с ограничением ресурсов


Иногда хочется ограничить максимальное количество ресурсов доступных процессу. Последней пинком стали юнит-тесты из текущего проекта - из-за ошибок они несколько раз съели все 8Gb ОЗУ и отправили систему в глубокий своп, откуда она со скрипом доставалась минут 15. Полная виртуализация таких случаях избыточна - нужно что-то по легче. В linux для этого есть cgroups (control groups) - они позволяют поместить процесс (вместе со всеми его потомками) в контейнер, имеющий доступ только к части ресурсов системы. На самом деле cgroups умеют больше, чем просто ограничение ресурсов - тут и счетчики производительности и другая статистика.

cgroups можно манипулировать вручную или с помощью libcgroup. Последний способ значительно удобнее и по нему есть отличная документация от redhat. Она обязательна к прочтению - есть несколько не очевидных моментов (для пользователей ubuntu - в этом дистрибутиве по умолчанию cgroups монтируются в /sys/fs/cgroups).