Эффективное параллельное выполнение изолированных «пакетных» вызовов
Я пишу инструмент разработчика для Ruby и в рамках его тестирования на различных драгоценных камнях запускаю такие команды, какbundle cache
иbundle install --local
, которые изменяют состояние внутри установки Ruby (AFAICT, это изменение невозможно предотвратить, но я не полностью понимаю все флаги для различных подкоманд).
В частности, последовательность команд для тестирования одного драгоценного камня выглядит следующим образом:
# First get gem-under-test's dependencies
# This step is mostly an optimization, so
# that any modified directories can be cached
# and this step can be skipped when only
# my-tool.gem is modified.
cd gem-under-test && bundle cache
cp /path/to/my-tool.gem vendor/cache/
# Tweak Gemfile+Gemfile.lock to mark my-tool as a dependency
git apply /path/to/gem-under-test.patch
# Mimic an actual user running 'bundle install' after
# updating their Gemfile with my-tool as a dependency
bundle install --local
# Check that my-tool.gem works properly, mimicking
# what a user of my-tool would do
bundle exec my-tool
Я бы хотел, чтобы тесты выполнялись параллельно, поэтому общая мутация установки Ruby нежелательна. Наивно было бы иметь несколько изолированных установок Ruby и тестировать их. Однако наличие нескольких установок Ruby кажется сложным из-за того, что установки Ruby не зависят от местоположения. Изruby/setup-ruby
README:
Каталог кэша инструментов по умолчанию (
/opt/hostedtoolcache
на линуксе,/Users/runner/hostedtoolcache
на macOS,C:/hostedtoolcache/windows
в Windows) должен быть доступен для записи пользователю бегуна. Это необходимо, поскольку сборки Ruby включают путь установки при сборке и не могут быть перемещены.(выделение добавлено)
Это означает, что наличие нескольких установок Ruby в разных местах файловой системы требует сборки Ruby из исходного кода для каждого теста (вместо того, чтобы собирать его один раз и копировать установку), что слишком медленно, чтобы быть практичным.
Какой хороший способ решить проблему с запускомbundle
параллельные вызовы на одном и том же базовом наборе инструментов, но с изоляцией друг от друга?
Я рассмотрел несколько проектов, которые кажутся потенциально связанными:
- Существует rbenv-gemset , но он, похоже, отключает отдельный
.rbenv-gemsets
файл, и в README нет упоминания о Bundler. Я хотел бы не конвертировать изGemfile
/Gemfile.lock
/.gemspec
файлы, если это возможно (для простоты) - Есть Portable-ruby от Homebrew . Из скудной информации в README мне неясно, можно ли ее использовать как стандартную установку Ruby. Если это может заполнить бит «независимо от местоположения», то я могу скопировать каталог установки один раз за тест.
Другой вариант — выбрать более сложное решение, например сначала создать образ Docker с Ruby и его зависимостями, а затем запустить тесты внутри образа. Однако это добавляет кучу сложностей с точки зрения настройки + худшую отладку (по сравнению с простым наличием отдельных каталогов).