https://github.com/cookpad/rrrspec
Distributed RSpec
https://github.com/cookpad/rrrspec
Last synced: 29 days ago
JSON representation
Distributed RSpec
- Host: GitHub
- URL: https://github.com/cookpad/rrrspec
- Owner: cookpad
- License: mit
- Created: 2014-02-13T09:06:44.000Z (about 11 years ago)
- Default Branch: master
- Last Pushed: 2019-02-22T08:09:47.000Z (about 6 years ago)
- Last Synced: 2024-04-24T16:24:30.371Z (about 1 year ago)
- Language: Ruby
- Homepage:
- Size: 1.05 MB
- Stars: 489
- Watchers: 31
- Forks: 34
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# RRRSpec
RRRSpec enables you to run RSpec in a distributed manner.
This is developed for the purpose to obtain the fault-tolerance properties to
process-failures, machine-failures, and unresponsiveness of processes in the
automated testing process.RRRSpec is used in production as a CI service, running 60+ RSpec processes
concurrently, and it undergoes those failures, which include lots of `rb_bug`s,
assertion errors, and segmentation faults.## MAINTENANCE NOTICE
As of Feb 2019, we, Cookpad, are not using RRRSpec internally. We may ocassionally review and accept PRs, but note that this software is not under active maintainance.
(Background: The circumstances has been changed since 2013. Modern IaaS providers such as AWS now provide machines with many vCPUs under cheap pricing. Also, Cookpad is working to split their largest Rails monolith application ([blog post :jp:](https://techlife.cookpad.com/entry/2018-odaiba-strategy)), and it makes the test suite small. Thus, we decided to stop operating RRRSpec cluster.)
## Features
* Automatic resume on process or machine failures
* RSpec integration
* Captured stdout/stderr per tests
* Automatic retrial of failed tests
* Optimization of the test execution order
* Speculative execution of long-running tests
* Severe timeout of stuck processesSome considerations on creating RRRSpec are described in DESIGN.md, hoping it
helps other developers writing other distributed test execution services avoid
common pitfalls.## Installation
### Client
Add this line to your application's Gemfile:
```ruby
gem 'rrrspec-client'
```Create '.rrrspec'
```ruby
RRRSpec.configure do |conf|
conf.redis = { host: 'redisserver.local', port: 6379 }
endRRRSpec.configure(:client) do |conf|
Time.zone_default = Time.find_zone('Asia/Tokyo')conf.packaging_dir = `git rev-parse --show-toplevel`.strip
conf.rsync_remote_path = 'rsyncserver.local:/mnt/rrrspec-rsync'
conf.rsync_options = %w(
--compress
--times
--recursive
--links
--perms
--inplace
--delete
).join(' ')conf.spec_files = lambda do
Dir.chdir(conf.packaging_dir) do
Dir['spec/**{,/*/**}/*_spec.rb'].uniq
end
endconf.setup_command = <<-SETUP
bundle install
SETUP
conf.slave_command = <<-SLAVE
bundle exec rrrspec-client slave
SLAVEconf.taskset_class = 'myapplication'
conf.worker_type = 'default'
conf.max_workers = 10
conf.max_trials = 3
conf.unknown_spec_timeout_sec = 8 * 60
conf.least_timeout_sec = 60
end
```### Master and Workers
Install 'rrrspec-server'
$ gem install rrrspec-server
Create 'rrrspec-server-config.rb'
```ruby
RRRSpec.configure do |conf|
conf.redis = { host: 'redisserver.local', port: 6379 }
endRRRSpec.configure(:server) do |conf|
ActiveRecord::Base.default_timezone = :local
conf.redis = { host: 'redisserver.local', port: 6379 }conf.persistence_db = {
adapter: 'mysql2',
encoding: 'utf8mb4',
charset: 'utf8mb4',
collation: 'utf8mb4_general_ci',
reconnect: false,
database: 'rrrspec',
pool: 5,
password: 'XXX',
host: 'localhost'
}
conf.execute_log_text_path = '/tmp/rrrspec-log-texts'
conf.pidfile = "/tmp/rrrspec-server.pid"
endRRRSpec.configure(:worker) do |conf|
conf.redis = { host: 'redisserver.local', port: 6379 }conf.rsync_remote_path = 'rsyncserver.local:/mnt/rrrspec-rsync'
conf.rsync_options = %w(
--compress
--times
--recursive
--links
--perms
--inplace
--delete
).join(' ')conf.working_dir = '/mnt/working'
conf.worker_type = 'default'
conf.pidfile = "/tmp/rrrspec-worker.pid"
end
```## Usage
### Master and Workers
$ rake -f /path/to/rrrspec-server-X.X.X/tasks/db.rake rrrspec:server:db:create rrrspec:server:db:migrate RRRSPEC_CONFIG_FILES=rrrspec-server-config.rb
$ rrrspec-server server --config=rrrspec-server-config.rb
$ rrrspec-server worker --config=rrrspec-server-config.rb
Note: You must be able to rsync files from the host where the server runs to the host where the worker runs, without being prompted to for a passphrase.
### Client
$ bundle exec rrrspec-client start
...
rrrspec:taskset:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX$ bundle exec rrrspec-client waitfor rrrspec:taskset:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
$ bundle exec rrrspec-client show rrrspec:taskset:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
## Local test
You can try RRRSpec locally using Docker.```
% docker-compose up
% docker-compose run worker local_test/run_client.sh
% xdg-open http://localhost:3000/
```## Contributing
See HACKING.md for the internal structure.
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request