Distribute cucumber scenarios across multiple hosts. Balance the load between the hosts with a distributed queue on redis.
Install redis:
$ sudo pacman -S redis
Start redis:
$ redis-server
Make sure that ssh is setup. Executing ssh localhost
should log you into a
new session and not prompt for a password.
Write a simple feature file with tests steps.
When the test launches we need to add the scenarios to a redis list so the list is available before the workers startup on the remote hosts. We will use simpleworker to distribute the tests. Simpleworker will handle copying files, updating gems, and running a command on the remote host.
# demo.rb
require 'redis'
require 'simpleworker'
require 'jcukeforker'
redis = Redis.new
key = "jcukeforker:#{redis.randomkey}"
redis.rpush key, JCukeForker::Scenarios.all
SimpleWorker::Runner.run "ruby launch.rb #{key}"
The remote hosts are setup in simpleworker.yml
. Change the user to your username. You can find your username by running whoami
.
---
workers:
- type: ssh
directory: /tmp/foo
user: jason
host: localhost
Now we setup the workers that will execute scenarios from the redis list.
# launch.rb
require 'redis'
require 'jcukeforker'
class RedisScenarioQueue
attr_reader :key
def initialize(key)
@redis = Redis.new
@key = key
end
def shift
@redis.lpop key
end
end
queue = RedisScenarioQueue.new ARGV[0]
JCukeForker::Runner.run queue,
:max => 2,
:format => :pretty,
:out => 'reports'
Jcukeforker (version >= 0.2.5) lazilly pops scenarios from the queue and distributes the task to a local worker.
To run the suite execute ruby demo.rb
.
When executing on muliple hosts it can be hard to tell which machine the output corresponds to. The following hack in sed will prepend user@hostname to each line.
SimpleWorker::Runner.run "ruby launch.rb #{key} | sed \"s/^/$(whoami)@$(hostname) /\""
The code for this example can be found on github.