История создания


Sparrow — очень молодой проект. Возник как надстройка над инструментом swat — DSL, написанным на perl для разработки тестовых сценариев различных web приложений. Описание swat — отдельная тема, которую я, возможно, раскрою в следующих публикациях, но, если в двух словах, то swat — это средство для автоматизация web тестирования, базирующееся на использовании утилиты curl и позволяющее создавать произвольные http запросы и валидировать возвращаемый контент.

Установка sparrow


Ставим как обычный cpan модуль.

$ sudo cpanm Sparrow

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

Идеология sparrow


Sparrow задуман как простой консольный клиент позволяющий быстро настраивать и запускать тесты для различных web приложений. Можно выделить два типа базовых операций в рамках данного инструмента — создание тестовой структуры и установка, запуск sparrow плагинов.

Структура sparrow проекта


На данный момент есть три основных сущности, которыми оперирует sparrow — проекты, сайты и плагины.

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

$ sparrow project foo
# sparrow environment initialzed at /home/vagrant/sparrow
project foo info:

[plugins]

        swat-mongodb-http
        swat-pintod
        swat-app-docsisious
        metacpan
        swat-lighttpd
        swat-yars
        swat-nginx

[sites]

        mongodb-http-server [127.0.0.1:28017]
        pintod-server [127.0.0.1:3111]
        metacpan [http://metacpan.org]
        lighttpd [127.0.0.1:8080]
        thorsen [http://home.thorsen.pm/docsisious]
        yars_server [localhost:9001]
        localhost [127.0.0.1]

Из приведенного вывода можно понять, что данный проект содержит набор плагинов (mongodb-http-server, pintod-server, ...) для тестирования соответствующих приложений и набор сайтов, о которых речь пойдет далее.

Сайты sparrow


Сайты в sparrow описывают произвольное тестируемое web приложение. Помимо идентификатора сайт должен иметь базовый URL, являющимся «корневым» URL для http запросов, которые будут приходить во время прогона тестов. В большинстве случаем базовый URL может совпадать с fqdn или IP адресом сервера тестируемого приложения, причем указание схемы и порта необязательно. Если быть точным, base url должен быть совместимым с форматом curl url. Стоит также заметить, что несмотря на то, что curl позволяет взаимодействие и с другими протоколами ( ftp,… ), sparrow в связке со swat используется только для тестирования приложений по протоколу http.

Вот пример создания сайта в проекте sparrow в случае с приложением типа nginx сервер:

$ sparrow project foo add_site nginx-server 127.0.0.1

Плагины sparrow


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

В двух словах, sparrow-плагин — это переносимый набор тестов (test suite), который можно установить и запустить. Очень понятная аналогия может быть построена на примере различных пакетных менеджером, типа yum в centos или apt-get в debian. Под различные типы приложений должна быть возможность выбрать и установить плагин, инкапсулирующий определенный тестовый набор, который может быть запущен для данного приложения.

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

Итак, sparrow плагины могут быть установлены и добавлены к проектам:

$ sparrow plg list
# sparrow environment initialzed at /home/vagrant/sparrow
[sparrow plugins list]

swat-yars | https://github.com/melezhik/swat-yars.git
metacpan | https://github.com/CPAN-API/metacpan-monitoring.git
swat-app-docsisious | https://github.com/melezhik/swat-app-docsisious.git
swat-nginx | https://github.com/melezhik/swat-nginx.git
swat-lighttpd | https://github.com/melezhik/swat-lighttpd.git
swat-pintod | https://github.com/melezhik/swat-pintod.git
swat-mongodb-http | https://github.com/melezhik/swat-mongodb-http.git

Установка плагина на данный момент реализована как обычный чекаут из удаленного git репозитария, возможно в будущем данная функциональность будет переписана с использованием собственных sparrow репоизитариев с версионированием дистрибутивов и прочими удобствами, по аналогии с обычным cpan репозитарием.

vagrant@Debian-jessie-amd64-netboot:~/projects/sparrow$ sparrow plg install  swat-nginx
# sparrow environment initialzed at /home/vagrant/sparrow
installing plugin swat-nginx ...
Cloning into 'swat-nginx'...
.... 
Installing modules using /home/vagrant/sparrow/plugins/swat-nginx/cpanfile
Successfully installed Outthentic-DSL-0.0.4
Successfully installed swat-0.1.68
2 distributions installed
Complete! Modules were installed into /home/vagrant/sparrow/plugins/swat-nginx/local

Установив плагин, нужно прикрепить его к проекту и после этого запустить тестовый набор, используя в качестве входного параметра выбранный сайт (web приложение):

$ sparrow project foo add_plg  swat-nginx
# sparrow environment initialzed at /home/vagrant/sparrow
plugin swat-nginx is successfully added to project foo

$ sparrow project foo check_site nginx-server  swat-nginx
# sparrow environment initialzed at /home/vagrant/sparrow
/home/vagrant/.swat/.cache/3486/prove/00.GET.t ..
ok 1 - GET 127.0.0.1/ succeeded
# response saved to /home/vagrant/.swat/.cache/3486/prove/p3y5aUKFgj
ok 2 - output match '200 OK'
ok 3 - output match /Server: nginx\/(\S+)/
ok 4 - valid nginx version: 1.6.2
1..4
ok
All tests successful.
Files=1, Tests=4,  1 wallclock secs ( 0.01 usr  0.00 sys +  0.04 cusr  0.00 csys =  0.05 CPU)
Result: PASS

Заключение


На этом наше знакомство со sparrow к сожалению заканчивается, хотя, конечно, еще есть о чем рассказать. Как уже упоминалось, проект еще очень молодой и активно развивается, как, впрочем, и основной компонент для написания тестовых сценариев — swat. Есть надежда, что perl сообщество, да и все те, кому близка автоматизация процессов тестирования и мониторинга внесут свой вклад в историю жизни пока еще маленького, но уже проворного воробья (*).

(*) — «sparrow» — в переводе с английского означает воробей.

P.S.


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

  1. удаленный запуск тестов через web api — такая возможность планируется к реализации в ближайшее время, памятуя о большом количестве систем, позволяющих проверять доступность web сервисов через вызовы во внешние API, например, тот же consul или nagios.
  2. интеграция с существующими системами непрерывной интеграции и отчетности — так на выходе, после запуска sparrow плагина мы получаем TAP, легко написать парсер, конвертирующий результаты в другие форматы. Скажу больше: так как sparrow при запуске плагинов вызывает swat, который в свою очередь использует perl prove для выполнения тестов, данная возможность по конвертации TAP в разные форматы предоставляется «из коробки», ну или с минимальным написанием кода, детали можно узнать на странице документации swat, в секции «TAP».
  3. ну и, наконец, вполне резонный вопрос — «где уже тестировалось данное решение (sparrow/swat) ?» Swat зарекомендовал себя как очень удобное средство для быстрой разработки smoke тестов для десятков web приложений в короткие сроки в ходе моей ежедневной работы в качестве devops инженера. Sparrow еще только тестируется, но уже сейчас можно сказать, что данный проект является логическим продолжением swat, a c применением sparrow плагинов есть шанс, что станет востребованным с среде web разработчиков, девопосов и системных администраторов.

Комментарии (44)


  1. ivanych
    03.12.2015 20:20

    1. Чем приложение отличается от сайта?


    1. alexey_melezhik
      03.12.2015 20:54

      Приложение и сайт — синонимы. Возможно термин сайт не самый удачный. Трестируемое приложение не обязательно должно быть сайтом в общем смысле это слова, вообще говоря это любой веб сервис, что-то к чему можно сделать запрос по http протоколу. Просто термин сайт звучит по-короче и более привычен. Хотя впринципе вопрос с терминологией ещё открыт, проект ещё в стадии активной разработки.


      1. ivanych
        03.12.2015 21:48

        Хотя впринципе вопрос с терминологией ещё открыт

        Веб-сервис?


        1. alexey_melezhik
          03.12.2015 21:54

          Как вариант, но хотелось бы чего то более лаконичного, ну по крайней мере в смысле команд sparrow клиента, в случае в веб сервисом, будет выглядеть как то так —
          sparrow project foo add_web_srv… .?

          Не длинновато? :-)


          1. ivanych
            03.12.2015 22:07

            «sparrow project foo add service»

            В команде часть «веб-» можно опускать.

            И кстати, просится возможность брать проект из контекста, типа как «git remote add» — текущий репозиторий указывать не требуется.


            1. alexey_melezhik
              03.12.2015 22:19

              Насчёт термина service, неплохо, надо подумать ;-))

              Насчёт «возможность брать проект из контекста» вот тут просьба разъяснить. Проект то все равно надо указывать всегда явно, откуда его брать? или…?


              1. ivanych
                03.12.2015 22:24

                Я, может, не совсем понимаю как оно на практике используется, но вот возьмем Гит для примера. Репозиториев же может быть много? Но при этом мы находимся в контексте какого-то конкретного репозитория.

                Нельзя так же сделать для Воробья? Переходим в некий конкретный проект — и вот он, контекст.


                1. alexey_melezhik
                  03.12.2015 22:31

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


                  1. alexey_melezhik
                    03.12.2015 22:41

                    Сори перечитал ещё раз ваш комент, вы все таки имели ввиду содавать папки с проектами? тогда да, это интересно, и не меняет дизайна, где проект центральная составляющая, но все равно надо думать :-)


                    1. ivanych
                      03.12.2015 23:57

                      Конкретно папку я не имел в виду, но центром должен быть проект, да. Ну, например, можно переменную окружения задавать. Если она указана — Воробей берет имя проекта из неё.


    1. cynovg
      04.12.2015 18:23

      На пример, в контексте современных фреймворков, вы создаете и работаете с приложением, но не с сайтом.


  1. ivanych
    03.12.2015 20:24

    2. Откуда sparrow берет список плагинов? Если я напишу плагин, как sparrow о нем узнает?


    1. alexey_melezhik
      03.12.2015 21:17

      Хороший вопрос. Сейчас схема довольна простая. Единого репозитария, наподобие того же cpan, нет. Схема добавления нового плагина такова. Вы создаёте плагин, размещаете код плагина в удаленном гит репозитарии и добавляете «ссылку» на плагин в файл списка плагинов на машине где установлен sparrow (~/sparrow/sparrow.list) в в виде:

      plugin-name git-repo-url

      Причём имя плагина выбираете на своё усмотрение, это просто некий идентификатор, по которому вы потом его можете установить и запустить через sparrow:

      sparrow plg install plugin-name

      Существует список готовых к использованию плагинов, с которым можно ознакомится тут — github.com/melezhik/sparrow-hub. Вы так же можете кинуть мне пул реквест или написать и я добавлю ваш плагин в этот список, если конечно гит репозитарий, где лежит плагин публично доступен. Скорее всего данный список аналог централизованного репозитария для комьюнити плагинов. Сейчас он состоит из плагинов, написанных только мной. Одной из целей данной статьи было как раз привлечение разработчиков для новых плагинов.

      Вообщем, вопрос с централизованным репозитарием для плагинов и доступом к нему через sparrow пока открытый, пока не определился с лучшим решением. Предлагайте :-)


      1. ivanych
        03.12.2015 21:53

        А вариант делать плагины просто модулями CPAN Вы не рассматривали? Допустим, в неймспейсе Sparrow::Plugin::*. Плюсы/минусы?


        1. alexey_melezhik
          03.12.2015 22:06

          Читаете мои мысли :) Это была первая идея, которая пришла мне в голову, и я кстати от неё пока окончательно не отказался.

          Плюс конечно основной, что вся готовая инфраструктура дистрибуции уже сущесвует и понятно всему perl сообществу.

          Минус в том, что sparrow плагины, не совсем cpan модули, хотя очень похожи на них. Если посмотреть в документацию по swat, там так же могут зависимости от обычных cpan модулей. Сейчас я решаю это использованию локальной установкой через carton, добавляя в корень проекта cpanfile. Короче, что бы не быть многословным, накладные расходы на дистрибуцию через cpan все же есть, два минуса вижу здесь — затруднительно будет распространять приватные плагины, несмотря на существующие решения ввиде pinto или minicpan, второй минус хочется максимально сузить цикл поставки новых версий, а в случае с вокалом через cpan, имеем задержку, а что может быть быстрее git commit, git push и git pull? :-)

          Но с другой стороны если sparrow плагины рассматривать как паблик модули, то здесь без версиоонирования будет сложно.


        1. alexey_melezhik
          03.12.2015 22:13

          Да кстати на каком то этапе swat «умел» запускать тесты поставляемые через спан модули, я использовал для этого фичу file::sharedir, но потом решил от этого отказаться.


  1. ivanych
    03.12.2015 20:34

    3. Для чего нужно привязывать плагин к проекту? Для запуска пакетного тестирования проекта всеми плагинами сразу? Каждый сайт в проекте будет тестироваться каждым плагином?


    1. alexey_melezhik
      03.12.2015 21:36

      >Для чего нужно привязывать плагин к проекту?
      Проект сущность необходимая для логической группировки тестируемых приложений ( aka сайтов ). Прикрепив плагин к проекту мы делаем возможным запускать плагин для приложений. Просто так запустить плагин нельзя. Плагин — это набор тестовых сценариев относительно какого-то приложения, приложение содержится внутри проекта. Впринципе сущность как проект можно было бы не вводить, но обычно подобная группировка оказывается очень полезной, даже если прямо сейчас этого явно не видно. Да и кстати «Для запуска пакетного тестирования проекта всеми плагинами сразу» хорошая идея.

      >Каждый сайт в проекте будет тестироваться каждым плагином?

      Сайты проекта и плагины, прикреплённые к проекту никак явно не соотносятся. Связь возникает когда вы запускаете плагин. Делая отсылку к ответу на ваш предыдущий вопрос — плагин всегда запускается для конкретного сайта, а сайт берётся из проекта. Почему полезно было ввести такую сущность как сайт, не заменив её просто на входной параметр запускаемого плагина? Опять таки да для удобства. Один из важных моментов вы можете определить настройки запускаемого плагина ( swat settings ) на уровне сайта командой «swat project project-name site-name swat_setup». Настройки плагина как правило определяют различные заранее неизвестные входные данные для ваших тестовых сценариев, наприм логин и пароль для аутентификации в веб приложении, которые конечно же нельзя оставлять в гит репозитории, ну и так далее. Подробнее о swat settings, можно прочитать на странице документации swat — DSL, используемом при написании тестовых сценариев в sparrow плагинах, github.com/melezhik/swat


      1. ivanych
        03.12.2015 21:57

        Честно говоря, я так и не понял, зачем нужна связка проект-плагин, если по факту плагин связан с сайтом, а не с проектом. Возможно, нужно поковырять на практике.

        Зачем проект группирует сайты — это я понимаю, тут вопросов нет.


  1. alexey_melezhik
    03.12.2015 21:50

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

    Но в любом случае сейчас нет никакой валидация того какие приложения какими плагинами можно тестировать, мы исходим из того, что человек запускающий плагин владеть этим знанием и на собирается запускать плагин написанный для mongodb-http для проверки какого-нибудь nginx сервера.

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


  1. ivanych
    03.12.2015 22:19

    Немного оффтопик:

    Мне, вообще, очень нравится этот Ваш проект — и сват, и воробей — но доками у них как-то не хорошо. К примеру, metacpan.org прекрасно отображает POD, но у Вас его нету:(


  1. alexey_melezhik
    03.12.2015 22:27

    Зашёл на метаспан, поискал в модулях swat, вот ссылка metacpan.org/pod/distribution/swat/lib/swat.pm, pod прекрасно отображается, тоже самое по sparrow — metacpan.org/pod/distribution/Sparrow/lib/Sparrow.pm

    У местаспана кстати бывают проблемы со ссылками на pod если выходишь на модуль не через поиск модулей, а через ссылку в разделе recent — свежее, может в этом дело, не знаю, проверьте мои ссылки, pod читается?


    1. ivanych
      04.12.2015 00:02

      Мм… По Вашей ссылке читается. А как Вы эту ссылку получили? Вот ссылка на модуль: metacpan.org/release/swat если там перейти непосредственно на pm, то pod не читается.


    1. ivanych
      04.12.2015 00:06

      И с Воробьем та же ерунда. Не открывается нормально pod. Что-то где-то не так.


      1. alexey_melezhik
        04.12.2015 08:44

        Все верно, как я уже сказал, нужно идти по другому.
        Идём на metacpan.org, в форме поиска вводим Sparrow или swat, соответсвенно на следующей странице открываем самую верхнюю, выделенную жирным ссылку (lib/swat.pm ) и жмём на неё, попадаем на страницу именно документации — metacpan.org/pod/distribution/swat/lib/swat.pm, там pod рендерится. Еже ли идти по другому маршруту, по которому вы скорее всего шли, получается так: metacpan.org/recent, затем выбираем ссылку ссылку Sparrow-0.0.6, попадаем на страницу, указанную вами — metacpan.org/release/Sparrow, все ссылки в блоке provides там будут давать ссылки на код, без рендеринга pod документации, эта особенность местаспана, я тоже уже с ней сталкивался…


      1. alexey_melezhik
        04.12.2015 08:46

        Ну или на крайняк можно воспользоваться старым добрым search.cpan.org :-) но у него через раз вывяливается ошибка связанная с прокси, по крайней мере в меня, когда им пытаюсь воспользоваться.


      1. alexey_melezhik
        04.12.2015 08:51

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


        1. ivanych
          04.12.2015 09:09

          Я иду именно через форму, как у Вас и написано. Но ссылка lib/swat открывает исходник, а не pod. Вы обратите внимание — сам вид ссылки, «lib/swat» уже говорит о том, что что-то нет так. Обычно ссылка выглядит как название модуля, «DBI» или «Text::Iconv», что-то типа того, но не как путь к файлу.

          Дело именно в какой-то ошибке в Ваших дистрибутивах.


          1. alexey_melezhik
            04.12.2015 11:01

            странно. привожу свои скрины:

            image
            image

            PS. ну уж если и так не заработает юзайте доку прямо с гитхаба в маркдауне:

            * github.com/melezhik/swat
            * github.com/melezhik/sparrow


            1. ivanych
              04.12.2015 14:54

              И всё-таки, что-то не так с дистрибутивом.

              Вот смотрите, пример дистрибутива: metacpan.org/release/JSON

              Видите, там есть разделы «Modules» и «Provides». Modules — это, я так понимаю, модули, в которых есть POD. А Provides — это модули, в которых нет POD. У Вас есть только Provides, т.е. Метацпан считает, что модулей с POD у Вас нет.

              При этом мы знаем, что POD у Вас таки есть, и иногда он даже отображается.

              Причина таких глюков, я полагаю, в том, что дистрибутив как-то неправильно размечен. Не знаю, что конкретно не так. Мейкфайл, наверное, не кошерный:)


              1. alexey_melezhik
                04.12.2015 15:13

                согласен, будем посмотреть ;-)


              1. alaska332
                04.12.2015 19:16

                Provides — это package, в одном .pm файле может быть задекларировано несколько package.


                1. ivanych
                  04.12.2015 19:19

                  А Modules это что?


                  1. alaska332
                    12.12.2015 13:59

                    Perl module — это Module/Name.pm — .pm или .pl файл относительно @ INC.
                    Модуль может содержать несколько package (неймспейсов) — это provides в терминологии metaspan, т.е. какие неймспейсы предоставляет данный дистрибутив (набор модулей).


                    1. ivanych
                      12.12.2015 15:04

                      Тогда почему тут metacpan.org/release/Sparrow нет Modules?


                      1. alaska332
                        12.12.2015 15:13

                        Видимо потому, что у него неправильно встроен POD.
                        Нет =pod метки — поэтому pod не парсится и не отображается. Может поэтому metacpan не показывает эти файлы, как модули.
                        Это имеет смысл, т.к. pod может относиться только к модулю а не к package внутри модуля. И нет смысла показывать файлы без pod.


                        1. alexey_melezhik
                          12.12.2015 15:37

                          Да, да все верно, спасибо за уточнение!


                        1. ivanych
                          12.12.2015 17:16

                          Нет, дело явно не в метке =pod. Вот, к примеру -https://metacpan.org/release/JSON там нет этой метки. А еще там есть раздел Documentation, это тогда что?


                          1. alaska332
                            12.12.2015 19:19

                            Не знаю, надо эксперементировать.

                            Но лучше всего сделать стандатный дистрибутив с помощью Dist::Zilla, если напрямую не получается.

                            Возможно, что надо использовать META.json вместо META.yml (давно признан устаревшим).

                            TODO:

                            1. META.yml -> META.json;
                            2. добавить cpanfile чтобы можно было устанавливать только зависимости (cpanm --installdeps .);
                            3. Сделать POD как надо;

                            Больше ничего быть не может.


                            1. alexey_melezhik
                              12.12.2015 20:01

                              Ok, планирую в ближайших релизах улучшить этот момент


                          1. alaska332
                            12.12.2015 21:04

                            package # This is JSON::backportPP
                            JSON::PP;

                            Неймспейс JSON::PP спрятан от индексации — в provides не отображается, т.к. metacpan не видит его.

                            Но модуль JSON/backportPP.pm содержит POD.

                            Этот POD отображается как Documentation без привязки к модулю. Название берется из =head1 NAME ...;

                            Provides — это ссылка на декларацию package в исходнике модуля, ЕСЛИ имя модуля не совпадает с этим package;

                            Modules — ссылки на POD для модулей с POD;

                            Documentation — все остальные POD, которые не могут быть связаны с модулем, или из отдельных .pod файлов;


                            1. ivanych
                              13.12.2015 00:38

                              > Неймспейс JSON::PP спрятан от индексации

                              Как?


                              1. alaska332
                                13.12.2015 00:46

                                с помошью коммента.

                                package # comment…
                                JSON::PP;

                                такое cpan пропускает.
                                это все используют.


            1. ivanych
              04.12.2015 15:00

              Еще один нехороший признак — в строке поиска по мере набирания названия модуля выскакивают подсказки. Попробуйте с любым модулем. Но если набрать, к примеру, Sparrow — подсказки не будет.