Ситуация: жил-был Сфинкс (поисковая система Sphinx) на старом сервере, да пришла пора на новый переезжать. Нужный порт на новом месте доступен скриптам, что живут там же, а снаружи — нет и не надейтесь. Результат — кое-где тесты покраснели.
На сервере есть SSH — значит, можно проложить туннель, чтоб разработчик мог тестировать свои приложения на своих компьютерах, прежде чем делать коммиты и лезть на сервер. Команда для проброса стандартного сфинксового порта 9312 с локальной машины на сервер может выглядеть так:
ssh -L 9312:localhost:9312 server.name
Однако в таком виде она неудобна: команду надо запускать в одном окне терминала, тесты — в соседнем, а после завершения тестов надо ещё и закрывать SSH-сессию в первом окне.
В инструкции (
man ssh
) пишут:
SYNOPSIS
ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address]
[-c cipher_spec] [-D [bind_address:]port] [-E log_file]
[-e escape_char] [-F configfile] [-I pkcs11]
[-i identity_file] [-J [user@]host[:port]] [-L address]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option]
[-p port] [-Q query_option] [-R address] [-S ctl_path]
[-W host:port] [-w local_tun[:remote_tun]]
[user@]hostname [command]
...
-f Requests ssh to go to background just before
command execution.
То есть, ssh позволяет и команду выполнить, и перед этим уйти в фоновый режим. Приме́ним полученные знания:
ssh -fL 9312:localhost:9312 server.name sleep 5
Такая команда откроет туннель, не выводя ничего в терминал, подождёт пять секунд и закроется — почти то, что надо!
Осталось исключить рытьё тоннелей на сервере
test `uname -n` != 'server' && ssh -fL 9312:localhost:9312 server.name sleep 5
и скрестить открытие туннеля с тестированием. Тесты в перловом веб-приложении, написанном с использованием микрофреймворка
Mojolicious::Lite, могут вызываться различными путями — и как
./application.pl test
, и командой
prove
, и как-нибудь ещё — я, например, обычно создаю
Makefile
с нужными мне задачами и тесты выполняю командой
make test
— мне так удобнее. Чтоб не рассматривать все возможные варианты тестирования, надо поместить открытие туннеля прямо в тест. Если конфигурация приложения хранится в каком-либо отдельном файле (YAML хорошо для этого подходит — в Моджолишисе есть плагин для чтения ЯМЛ-конфигов), можно команду открытия туннеля хранить рядом с остальными настройками — это лучше, чем пихать её в тест. А в тесте останется лишь вызвать её после создания объекта Test::Mojo:
my $t = Test::Mojo->new();
system($t->app->config->'sphinx'->'tunnel') == 0
or warn "Cannot open SSH tunnel to Sphinx: $!";
Тесты зеленеют, можно спокойно идти заниматься музыкой :-)
P.S. Если вместо
system применить функцию
exec, то тест не будет выполняться до тех пор, пока не закроется туннель — тест будет ждать завершения дочернего процесса и в итоге так и останется красным.
http://shoorick.ru/2018/03/21/sphinx-tunnel/