Тестирование возможностей параллелизма - PullRequest
4 голосов
/ 17 ноября 2011

Как бы вы протестировали код Ruby, который имеет некоторые функции параллелизма?Например, давайте предположим, что у меня есть механизм синхронизации, который должен предотвращать взаимные блокировки.Есть ли реальный способ проверить, что он на самом деле делает?Может ли контролируемое выполнение в волокнах быть путь вперед?

Ответы [ 3 ]

3 голосов
/ 15 июля 2012

У меня была точно такая же проблема, и я реализовал простой гем для синхронизации подпроцессов с использованием точек останова: http://github.com/remen/fork_break

Я также задокументировал сценарий расширенного использования rails3 в http://www.hairoftheyak.com/testing-concurrency-in-rails/

1 голос
/ 30 октября 2014

Это определенно сложная проблема. Я начал писать свой тест, используя потоки, и понял, что они реализуют код, который я тестировал, и мне нужно, чтобы идентификаторы процессов (PID) действительно отличались. Потоки запускаются с использованием того же PID, что и процесс, запускающий поток. Урок выучен.

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

Следующая проблема, с которой я столкнулся, была с DatabaseCleaner. Независимо от того, какую стратегию он использовал (усечение или транзакция), данные дочернего процесса усекались / откатывались по завершении дочернего процесса, поэтому данные, вставленные дочерними процессами, исчезали, и родительский процесс не мог выбрать и проверить, что это было правильно.

После того, как я покачал головой и попробовал много других неудачных вещей, я наткнулся на этот пост http://makandracards.com/makandra/556-test-concurrent-ruby-code, который был почти точно тем, что я уже делал, с одним небольшим дополнением. Вызов "Process.exit!" в конце вилки. Мое лучшее предположение (основанное на моем довольно ограниченном понимании разветвления) заключается в том, что это приводит к тому, что процесс завершается достаточно быстро, чтобы полностью обойти любой тип очистки базы данных после завершения дочернего процесса. Таким образом, мой родительский процесс, настоящий тест, может продолжаться и проверять данные, необходимые для проверки. Затем во время обычного перехвата теста (в данном случае огурца, но также легко можно использовать rspec) очиститель базы данных запускает и очищает данные, как обычно для теста.

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

1 голос
/ 23 ноября 2011

Мне нужно было убедиться, что созданный мною гем (redis-native_hash) может обрабатывать параллельные записи в тот же хэш Redis, обнаруживать состояние гонки и элегантно восстанавливаться.Я обнаружил, что для проверки этого мне вообще не нужно было использовать потоки.

it "should respect changes made since last read from redis" do
  concurrent_edit = Redis::NativeHash.find :test => @hash.key
  concurrent_edit["foo"] = "race value"
  concurrent_edit.save
  @hash["yin"] = "yang"
  @hash["foo"] = "bad value"
  @hash.save
  hash = Redis::NativeHash.find :test => @hash.key
  hash["foo"].should == "race value"
  hash["yin"].should == "yang"
end

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

Не все проблемы, связанные с параллелизмом, могут быть проверены без фактического использования ИСПОЛЬЗОВАНИЯ, но в этом случае это было возможно.Вы можете попробовать поискать что-то похожее, чтобы протестировать ваши решения для параллелизма.Если это возможно, это определенно более легкий путь.

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