18 мая 2014 г.

Мой новый блог

Блоггер довольно неудобен (или просто я не умею его готовить) если нужно добавлять код.
Поэтому я перешел на новый блог.

Он находится здесь - http://madmis.com.ua/

12 мая 2014 г.

Codeception - тестируем используя несколько баз данных

Недавно начал писать acceptance тесты, используя codeception. Инструмент просто замечательный. Весьма удобный для простых тестов.

Замечу, я работаю с MongoDb, но в принципе не проблема сделать тоже самое для Mysql (или других СУБД).

Но возникла у меня одна проблема.
Структура проекта подразумевает, что на один инстанс приложения есть две базы данных (почему, пока расписывать не буду).
Так вот, в тесте мне нужно было добавить пользователя в основную базу, а затем, после выполнения определенного процесса, проверить наличие данных в дополнительной базе данных.

Готового решения для переключения между connection или databases у codeception нет. Но используя (довольно костыльный, смею заметить, способ)  Group Classes, можно менять настройки модуля MongoDb (Db) при запуске/остановке тестов.
Данные классы оперируют событиями test.before.test.after.  (подробнее читайте в документации).

Собственно я создал 2 класса групп
1. UserGroup - при запуске теста пишет фикстуру пользователя в БД.

class UserGroup extends \Codeception\Platform\Group
{
    static $group = 'user';

    /**
     * @param \Codeception\Event\Test $e
     */
    public function _before(\Codeception\Event\Test $e)
    {
        $this->writeln("inserting user");

        /** @var \Codeception\Module\MongoDb $db */
        $db = $this->getModule('MongoDb');
        $data = $criteria = ["key" => "user", 'value' => User::getUserData()];
        $db->haveInCollection(User::collectionName(), $data);
        $db->_before($e->getTest());
    }

    /**
     * @param \Codeception\Event\Test $e
     */
    public function _after(\Codeception\Event\Test $e)
    {
        /** @var \Codeception\Module\MongoDb $db */
        $db = $this->getModule('MongoDb');
        $db->_after($e->getTest());
    }
}
2. RawSerpDbGroup - при запуске теста подменяет coonection подключаясь к дургой БД.

class RawSerpDbGroup extends \Codeception\Platform\Group
{
    static $group = 'raw-serp-db';

    /**
     * @param \Codeception\Event\Test $e
     */
    public function _before(\Codeception\Event\Test $e)
    {
        $this->writeln("connect to raw-serp-db");

        /** @var \Codeception\Module\MongoDb $db */
        $db = $this->getModule('MongoDb');
        $db->_reconfigure($this->config);
        $db->_initialize();
        $db->_before($e->getTest());
    }

    /**
     * @param \Codeception\Event\Test $e
     */
    public function _after(\Codeception\Event\Test $e)
    {
        /** @var \Codeception\Module\MongoDb $db */
        $db = $this->getModule('MongoDb');
        $db->_after($e->getTest());
    }
}
Сами настройки подключения хранятся в конфиге
codeception.yml
extensions:
    enabled: [RawSerpDbGroup, UserGroup]
    config:
        RawSerpDbGroup:
            dsn: 'mongodb://localhost:27017/db-r-s'
            user: ~
            password: ~
            populate: true
            cleanup: true
            dump: ~

Теперь в тесте необходимо определить группы для сценария
/** @var $scenario \Codeception\Scenario */
$scenario->group(UserGroup::$group);
$scenario->group(RawSerpDbGroup::$group);
$I = new CommandGuy($scenario);
причем порядок следования сценариев в данном случае важен.

Вот таком костыльным способом у меня получилось работать сразу с двумя базами.

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








8 мая 2014 г.

MongoDB и резервное копирование

бекап всей БД :
1
mongodump -h localhost -d DATABASE_NAME -o BACKUP_FOLDER
бекап определённых коллекций:
1
mongodump --db blog --collection posts
восстановление бекапа:
1
mongorestore -h localhost -d DATABASE_NAME BACKUP_FOLDER

26 марта 2014 г.

Symfony2 расширяем JMSJobQueueBundle

Так уж сложилось (такова архитектура приложения, которое я разрабатываю), что мне не хватало возможностей JMSJobQueueBundle. Поэтому пришлось подумать как добавить необходимые мне возможности.

Что мне нужно?
Мне нужна возможность выполнять команды в разных окружениях. JMSJobQueueBundle, к сожалению, пока такого не позволяет (хотя компонент Symfony  Process позволяет это сделать очень просто). По этому поводу я уже создал issue, и если разработчик его сделает, то эта статья будет неактуальной.

Значит что сделал я.

В первую очередь я расширил сам бандл. Подробнее об этом можно почитать в документации Symfony.

Собственно я создал бандл, имя которого совпадает с текущим, и указал родителя
namespace Netberry\JobQueueBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class NetberryJobQueueBundle extends Bundle
{
    public function getParent()
    {
        return 'JMSJobQueueBundle';
    }
}
 После этого в новый бандл добавил следующую команду
namespace Netberry\JobQueueBundle\Command;
use JMS\JobQueueBundle\Entity\Job;
use Netberry\JobQueueBundle\Entity\Environment;
use Symfony\Component\Process\ProcessBuilder;
class RunCommand extends \JMS\JobQueueBundle\Command\RunCommand
{
    const COMMAND = 'jms-job-queue:run';
    /**
     * @var Job
     */
    protected $job;
    /**
     * @param Job $job
     * @throws \LogicException
     */
    protected function startJob(Job $job)
    {
        $this->job = $job;
        parent::startJob($job);
    }

    /**
     * @return ProcessBuilder
     */
    protected function getCommandProcessBuilder()
    {
        $pb = parent::getCommandProcessBuilder();
        /** @var Environment $Env */
        $Env = $this->job->getRelatedEntities()->first();
        if(!$Env) {
            $Env = new Environment('common', 'common');
        }

        $pb->setEnv('SYMFONY__APP', $Env->getApp());
        $pb->setEnv('SYMFONY__HOST', $Env->getHost());

        return $pb;
    }
}
Постарался обойтись минимальными изменениями.

Но проблема в том, что в оригинальной команде вышеописанные методы приватные (private) и поэтому их можно только переопределить, но нельзя расширить. Поэтому пока пришлось изменить код оригинальной команды, что есть очень плохо и совершенно не правильно (но другого варианта я пока не нашел).
В вышеуказанном issue, я попросил автора бандла подумать и об этом. Посмотрим, что он придумает.



22 марта 2014 г.

Ubntu 13.10 & PhpStorm 7 - проблемы с горячими клавишами в русской раскладке

Т.к., я работаю программистом, в один прекрасный день мне пришлось спрыгнуть с винды на линкус. Я перешел на ubuntu.
В то время я перешел на ubuntu 13.04. Эта ось мне очень понравилась. Для разработки лучше не придумаешь.

Позже пришлось перейти на ubuntu 13.10,  а вот тут то  и пришлось по плеваться. Ubutnu 13.10 выпустили достаточно сырой.
Основная проблема с которой пришлось столкнуться - это проблема смены раскладки (думаю описывать ее нет смысла, т.к. весь инет пестрит сообщениями об этой проблеме и путями ее решения). В итоге разработчики исправили эту проблему, но не до конца.

Лично у меня проявление проблемы осталось в том, что в PhpStorm 7 не работали hot keys (Ctrl+C, Ctrl+V, Ctrl+Z ...) в русской раскладке. Для многих это не является проблемой, т.к. остаются рабочими клавишами Ctrl+Insert, Shift+Insert? но это дело привычки.

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

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

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

Решить данную проблему помогает патч для Java - https://github.com/zheludkovm/LinuxJavaFixes.

Собственно нужно загрузить себе этот патч, а затем в файле phpstorm.vmoptions (или phpstorm64.vmoptions) добавить следующую строку
             -javaagent:[path]/LinuxJavaFixes-1.0.0-SNAPSHOT.jar

У меня файлы phpstorm.vmoptions & phpstorm64.vmoptions находятся в каталоге /home/dimon/Programs/PhpStorm-133.679/bin. Собственно у вас это будет каталог, в который установлена IDE PhpStrom.

Вот и все. Проблема решена.

Вообще, ubuntu 13.10 это очень неудачная версия на мой взгляд.
Будем ждать 14.04 и надеяться что там эти косяки будут исправлены.

И напоследок. Для размещения своих проектов я использую сервера от DigitalOcean. Классно они все сделали, все очень просто и удобно.
Если вы разрабатываете под web, очень рекомендую обратить внимание на этот сервис.

Реферальная ссылка и  для противников реферальных программ прямая ссылка