2015-12-30 2 views
12

Как я могу использовать локальные библиотеки репозитория hg для тестирования изоляции из уже установленных библиотек?Как изолировать от установленных библиотек в hg-репо для тестирования?

Установленный пакет производства Perl и местный Hg репо имеет ту же структуру

+-- lib 
     |-- modA.pm 
     |-- modB.pm 
    +-- bin 
     |-- example.pl 
    +-- t 
     |-- modA.t 
     |-- modB.t 

библиотеки, установленную на и путь добавлен к @ perl5

/nfs_share/perl/ 
env|grep -i perl 
PERL5:/usr/local/perl:/nfs_share/perl 

местной рт.ст. репо на:

/data/user/hg/perl 

modB.pm

#!/usr/bin/perl 
use modA; 
sub modB_compare{ 
    my (x,y) = @_; 
    # ..... 
    return x-y; 
} 

бен/example.pl

use FindBin qw($Bin); 
use lib "${Bin}/lib/"; 
use modA, modB; 
# if this call is from local lib 
my $result = modB_compare(x,y); 
# if sub being called from production or local hg? 
my $result2 = modA_method(); 
# from local hg repo or from production lib?! 

Если бы я изменить и тест в местной рт.ст. репо, нет Gurantee, что Lib я назвал это из локального репозитория, а не от производства LIBS.

Каковы потенциальные решения для изоляции библиотек для тестирования в локальном реестре hg?

+3

Я думаю, вам может понадобиться немного расширить этот вопрос, чтобы получить ответ. Несколько неясно, о чем вы на самом деле спрашиваете. Вы получите предупреждение, если вы переопределите подпрограмму с помощью операции импорта. Но из ['perlmod'] (http://perldoc.perl.org/perlmod.html) вы можете возиться с typeglobs' \ * somesub {PACKAGE} '- это не поможет, если вы импортировали его в свой таблица локальных символов. – Sobrique

+1

Вы правы, вопрос непонятен, я займу некоторое время, чтобы переработать его – Gang

+0

Я полностью согласен с трюмом. спасибо – Gang

ответ

3

Короткий ответ: для испытаний просто используйте prove -l.

Если бы я был модифицирован и протестирован в локальном репозитории hg, у меня нет гарантий, что я вызывал lib из локального репо, а не из производственной библиотеки.

На самом деле существует проблема, которую вы определили.

Если вы знаете, что ./lib/modA.pm существует и ./lib/ в @INC, то ./lib/modA.pm будет загружен и любая система Perl версии не будет *.

Ваша заявка use lib делает это за вас, как задокументировано в perlvar @INC и require.

Однако для испытаний, это нормальная практика не к use lib, но вместо использовать -I flag in perl (perl -Ilib t/modA.t) или, лучше, prove, который также имеет -l флаг, так что вы можете просто сделать prove -l и он работает все тесты в t/ с использованием модулей в ./lib.

NB: Вы также можете посмотреть в ExtUtils::MakeMaker или Module::Build::Tiny, которые помогают с задачами распределения, и вы могли бы хотеть рассмотреть Dist::Zilla или (для более быстрого запуска) Dist::Milla

Если вы просто хотите, чтобы проверить, что происходит Вы можете проверить, какие файлы были загружены в use или require заявлениями, просмотрев %INC.

Если вы абсолютно должны управления, какие модули доступны, например, потому что вы хотите проверить различное поведение в зависимости от того, установлены ли (а не своего собственного кода) сторонние модули, я предлагаю смотреть в perlbrew. Это поможет вам скомпилировать ваш собственный perl (почти любой неопределенно недавней версии), который не использует библиотеки из системы perl, но вместо этого имеет свои собственные библиотеки, используя local::lib; вы можете переключаться между несколькими установленными perls. Единственными исключениями являются библиотеки, которые упакованы вместе с perl; вы можете получить их список из Module::Corelist.

Наконец, вы можете проверить Carton. Я не думаю, что это совсем то, о чем вы просите, но это такая же проблемная область, что, я думаю, стоит упомянуть.


* OK, строго, lib должен появиться в @INCперед тем система PERL Lib каталогов, потому что происходит то, что Perl проходит через @INC в порядке и находит файлы, соответствующие имени пакета, который вы попросили его загрузить; все методы, которые вы использовали, и что я говорю в этом ответе, будут уверены, что ваш каталог lib появится раньше в @INC, а затем в вашей системе perl libs.

2

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

В результате - для такого сценария я использую Docker. С риском упрощения бит, это способ упаковки вашего экземпляра приложения с его зависимостями в своего рода мини-виртуальную машину.

Вы создаете образ из файла докеров, который очень похож на файл make, за исключением того, что он «сводится» к изображению, которое вы можете запустить, включая приложение и все его зависимости.

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

Если это изображение обращается, то точно такое же изображение разворачивается в prod. Поскольку он самодостаточен и упакован со всеми его зависимостями, я получаю высокую степень уверенности в том, что я не буду путешествовать по перекосу версии установленных библиотек, и я не смогу сработать над будущим обновлением, нарушающим что-либо, потому что все мои " версия »должна быть частью изображения.

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

Вы можете даже довольно безопасно запускать ваш dev/ref/prod на одном и том же физическом жестяне и просто связывать/сопоставлять различные ресурсы (тома/порты и т. Д.) Для дифференциации.

Смежные вопросы