testbot 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ 0.2.5
2
+
3
+ Made testbot into a gem. Simplified the design. Added a CLI. Removed git support.
4
+
5
+ 0.2.3
6
+
7
+ Added JRuby support.
8
+
9
+ 0.2.2
10
+
11
+ Replaced runtime optimization code with a simpler file size based method.
12
+
13
+ 0.2.1
14
+
15
+ Added support for Test:Unit and multiple projects.
16
+
17
+ 0.2.0
18
+
19
+ Added "ssh_tunnel" so that you don't have to be able to access the http server directly.
20
+
21
+ 0.1.9
22
+
23
+ The server can now handle if a runner is shutdown in the middle of a test run (it will give the
24
+ job to another runner).
25
+
26
+ 0.1.8
27
+
28
+ Added cucumber support and failure detection to the client. Added docs. Added code that uses
29
+ historic test runtimes to reduce test runtime (in theory).
30
+
31
+ 0.1.7
32
+
33
+ Added a basic client so that testbot can be installed as a rails plugin. 'rake testbot:spec'.
34
+
35
+ 0.1.6
36
+
37
+ Now only fetching the code once, and only keeping one copy of it. Less overhead.
38
+
39
+ 0.1.5
40
+
41
+ Added "/runners/total_instances" to be able to balance requesters by knowing how many instances
42
+ there are in total.
43
+
44
+ 0.1.4
45
+
46
+ Added support for fetching the latest version from git instead of rsync when doing a test run.
47
+
48
+ 0.1.3
49
+
50
+ Added "/runners/available" to see how many runners are available.
51
+
52
+ 0.1.2
53
+
54
+ Added cucumber support.
55
+
56
+ 0.1.1
57
+
58
+ Added a CPU usage check to make sure that the runner does not start a job when the computer is busy.
59
+
60
+ 0.1
61
+
62
+ Added hostname and STDERR to runner results.
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
4
+ group :development do
5
+ gem "shoulda"
6
+ gem "rack-test"
7
+ gem "flexmock"
8
+ gem "cucumber"
9
+ gem "rvm"
10
+ gem "rake"
11
+ end
12
+
@@ -0,0 +1,128 @@
1
+ Testbot is a test distribution tool that works with Rails, RSpec, Test::Unit and Cucumber. The basic idea is that you let testbot spread the load of running your tests across multiple machines to make the tests run faster.
2
+
3
+ Using testbot on 11 machines (25 cores) we got our test suite down to **2 minutes from 30**. [More examples of how testbot is used](http://github.com/joakimk/testbot/wiki/How-testbot-is-being-used).
4
+
5
+ Installing
6
+ ----
7
+
8
+ gem install testbot
9
+
10
+ Try it out
11
+ ----
12
+
13
+ testbot --server
14
+ testbot --runner --connect localhost
15
+ mkdir -p testbotdemo/test; cd testbotdemo
16
+ echo 'require "test/unit"' > test/demo_test.rb
17
+ echo 'class DemoTest < Test::Unit::TestCase; def test_first; end; end' >> test/demo_test.rb
18
+ testbot --test --connect localhost
19
+
20
+ # Cleanup
21
+ testbot --server stop
22
+ testbot --runner stop
23
+ cd ..; rm -rf testbotdemo
24
+ rm -rf /tmp/testbot
25
+
26
+ The project files from the demo project are synced to /tmp/testbot/$USER (default). The runner syncs the files to /tmp/testbot/project (default). The tests are then run and the results returned through the server and displayed.
27
+
28
+ How it works
29
+ ----
30
+
31
+ Testbot is:
32
+
33
+ * A **server** to distribute test jobs.
34
+ * One or more **runners** to run test jobs and return the results (this is the "slave" process that runs tests).
35
+ * One or more **requesters** that tells the server which tests to distribute and displays the results (the client you use to run tests, for example: **rake testbot:spec**).
36
+
37
+ <pre>
38
+ Requester -- (files to run) --> Server -- (files to run) --> (many-)Runner(s)
39
+ ^ | ^ |
40
+ |---------------------------| |----------------------------------|
41
+ (results) (results)
42
+ </pre>
43
+
44
+ Example setup
45
+ ----
46
+
47
+ Here I make the assumption that you have a user called **testbot** on a server at **192.168.0.100** that every computer [can log into without a password](http://github.com/joakimk/testbot/wiki/SSH-Public-Key-Authentication) and that you have **installed testbot** on each computer.
48
+
49
+ ssh testbot@192.168.0.100
50
+ testbot --server
51
+
52
+ On every computer that should share CPU resources run:
53
+
54
+ testbot --runner --connect 192.168.0.100
55
+
56
+ Running tests:
57
+
58
+ testbot --test --connect 192.168.0.100
59
+ # --test could also be --spec or --features
60
+
61
+ Using testbot with Rails 3:
62
+
63
+ rails g testbot --connect 192.168.0.100
64
+ rake testbot:spec (or :test, :features)
65
+
66
+ # Gemfile:
67
+ gem 'testbot'
68
+
69
+ Using testbot with Rails 2:
70
+
71
+ ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.2.6'
72
+
73
+ The rails 2 config generator isn't done yet so you can look at the following examples instead:
74
+ [lib/tasks/testbot.rake](https://gist.github.com/715836) and
75
+ [config/testbot.yml](https://gist.github.com/715839).
76
+
77
+ rake testbot:spec (or :test, :features)
78
+
79
+ Updating testbot
80
+ ----
81
+
82
+ To simplify updates there is a **--auto_update** option for the runner. The runner processes that use this option will be automatically updated and restarted when you change the server version.
83
+
84
+ This requires testbot to be installed **without sudo** as the update simply runs "gem install testbot -v new_version". I recommend using [RVM](http://rvm.beginrescueend.com/) (it handles paths correctly).
85
+
86
+ Example:
87
+ testbot --runner --connect 192.168.0.100 --auto_update
88
+
89
+ More options
90
+ ----
91
+
92
+ testbot (or testbot --help)
93
+
94
+ Could this readme be better somehow?
95
+ ----
96
+
97
+ If there is anything missing or unclear you can create an [issue](http://github.com/joakimk/testbot/issues) (or send me a pull request).
98
+
99
+ Features
100
+ ----
101
+ * You can add and remove computers at any time. Testbot simply gives abandoned jobs to other computers.
102
+ * Testbot will try to balance the testload so that every computer finishes running the tests at the same time to reduce the time it takes to run the entire test suite. It does a good job, but has potential for further improvement.
103
+ * You can access your testbot network through SSH by using the built in SSH tunneling code.
104
+ * Testbot is continuously tested for compability with Ruby 1.8.7 and 1.9.2.
105
+
106
+ Contributing to testbot
107
+ ----
108
+
109
+ First, get the tests to run:
110
+ bundle
111
+ rake
112
+
113
+ For development I recommend: [grosser/autotest](http://github.com/grosser/autotest)
114
+ autotest -f -c
115
+
116
+ Make your change (don't forget to write tests) and send me a pull request.
117
+
118
+ You can also contribute by adding to the [wiki](http://github.com/joakimk/testbot/wiki).
119
+
120
+ How to add support for more test frameworks and/or programming languages
121
+ ----
122
+
123
+ Add a **lib/adapters/framework_name_adapter.rb** file, update **lib/adapters/adapter.rb** and this readme.
124
+
125
+ More
126
+ ----
127
+
128
+ * Check the [wiki](http://github.com/joakimk/testbot/wiki) for more info.
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/testbot.rb'))
4
+
5
+ def show_help
6
+ puts "Testbot #{Testbot::VERSION}"
7
+ puts
8
+ puts "Testbot is a test distribution tool that works with Rails, RSpec, Test::Unit and Cucumber."
9
+ puts
10
+ puts "More info: http://github.com/joakimk/testbot"
11
+ puts "Wiki: http://github.com/joakimk/testbot/wiki"
12
+ puts
13
+ puts "Examples:"
14
+ puts " testbot --server"
15
+ puts " testbot --runner --connect 192.168.0.100"
16
+ puts " testbot --test --connect 192.168.0.100"
17
+ puts
18
+ puts "Types:"
19
+ puts " --server <start|stop|run>"
20
+ puts " --runner <start|stop|run>"
21
+ Adapter.all.each do |adapter|
22
+ puts " --#{adapter.type}\t\t\t# Run #{adapter.name} tests"
23
+ end
24
+ puts
25
+ puts "Runner options:"
26
+ puts " --connect <host_or_ip>\t# Which server to use (required)"
27
+ puts " --working_dir <path>\t\t# Where to store temporary files (default: #{Testbot::DEFAULT_WORKING_DIR})"
28
+ puts " --cpus <number>\t\t# The number of CPU cores to use (default: use all)"
29
+ puts " --ssh_tunnel\t\t\t# Use a ssh tunnel"
30
+ puts " --user <username>\t\t# Use a custom ssh tunnel user (default: testbot)"
31
+ puts " --auto_update\t\t\t# Keep testbot updated to the same version as the server."
32
+ puts " --max_jruby_instances <num>\t# To use less instances when running JRuby (as it requires more memory)"
33
+ puts " --jruby_opts <-J-X...>\t# Options to JRuby."
34
+ puts
35
+ puts "Test options:"
36
+ puts " --connect <host_or_ip>\t# Which server to use (required)"
37
+ puts " --rsync_ignores <ignores>\t# Files to ignore when syncing (default: include all)"
38
+ puts " --rsync_path <path>\t\t# Sync path on the server (default: #{Testbot::DEFAULT_SERVER_PATH})"
39
+ puts " --ssh_tunnel\t\t\t# Use a ssh tunnel"
40
+ puts " --user <username>\t\t# Use a custom rsync / ssh tunnel user (default: #{Testbot::DEFAULT_USER})"
41
+ puts " --project <project_name>\t# Use a custom project name (default: #{Testbot::DEFAULT_PROJECT})"
42
+ puts
43
+ puts "Other:"
44
+ puts " --help\t\t\t# Show help (this page)"
45
+ puts " --version\t\t\t# Show the testbot version"
46
+
47
+ # puts " # (when the server gem version is changed,"
48
+ # puts " # this runs gem install with the same version"
49
+ # puts " # and restarts the test runner)"
50
+
51
+
52
+ # TODO:
53
+ # puts " --use_git_ignore # Don't rsync files that are ignored by git"
54
+ # puts " --status # Show running background processes"
55
+ # puts " --port <number> # Use a custom port"
56
+
57
+ end
58
+
59
+ show_help unless Testbot::CLI.run(ARGV)
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/rspec_adapter'
2
+ require File.dirname(__FILE__) + '/cucumber_adapter'
3
+ require File.dirname(__FILE__) + '/test_unit_adapter'
4
+
5
+ class Adapter
6
+ def self.all
7
+ [ RSpecAdapter, CucumberAdapter, TestUnitAdapter ]
8
+ end
9
+
10
+ def self.find(type)
11
+ case type.to_sym
12
+ when :spec
13
+ RSpecAdapter
14
+ when :features
15
+ CucumberAdapter
16
+ when :test
17
+ TestUnitAdapter
18
+ else
19
+ raise "Unknown adapter: #{type}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ class CucumberAdapter
2
+
3
+ def self.command(ruby_interpreter, files)
4
+ "export AUTOTEST=1; #{ruby_interpreter} script/cucumber -f progress --backtrace -r features/support -r features/step_definitions #{files} -t ~@disabled_in_cruise"
5
+ end
6
+
7
+ def self.file_pattern
8
+ '**/**/*.feature'
9
+ end
10
+
11
+ def self.requester_port
12
+ 2230
13
+ end
14
+
15
+ def self.pluralized
16
+ 'features'
17
+ end
18
+
19
+ def self.base_path
20
+ pluralized
21
+ end
22
+
23
+ def self.name
24
+ 'Cucumber'
25
+ end
26
+
27
+ def self.type
28
+ pluralized
29
+ end
30
+
31
+ end
@@ -0,0 +1,31 @@
1
+ class RSpecAdapter
2
+
3
+ def self.command(ruby_interpreter, files)
4
+ "export RSPEC_COLOR=true; #{ruby_interpreter} script/spec -O spec/spec.opts #{files}"
5
+ end
6
+
7
+ def self.file_pattern
8
+ '**/**/*_spec.rb'
9
+ end
10
+
11
+ def self.requester_port
12
+ 2299
13
+ end
14
+
15
+ def self.pluralized
16
+ 'specs'
17
+ end
18
+
19
+ def self.base_path
20
+ type
21
+ end
22
+
23
+ def self.name
24
+ 'RSpec'
25
+ end
26
+
27
+ def self.type
28
+ 'spec'
29
+ end
30
+
31
+ end
@@ -0,0 +1,31 @@
1
+ class TestUnitAdapter
2
+
3
+ def self.command(ruby_interpreter, files)
4
+ "#{ruby_interpreter} -Itest -e '%w(#{files}).each { |file| require(file) }'"
5
+ end
6
+
7
+ def self.file_pattern
8
+ '**/**/*_test.rb'
9
+ end
10
+
11
+ def self.requester_port
12
+ 2231
13
+ end
14
+
15
+ def self.pluralized
16
+ 'tests'
17
+ end
18
+
19
+ def self.base_path
20
+ type
21
+ end
22
+
23
+ def self.name
24
+ 'Test::Unit'
25
+ end
26
+
27
+ def self.type
28
+ 'test'
29
+ end
30
+
31
+ end
@@ -0,0 +1,35 @@
1
+ namespace :testbot do
2
+ task :before_request do
3
+ # This is run after you start a request (ex: rake testbot:spec)
4
+ end
5
+
6
+ task :before_run do
7
+ # This is run by the runner after files are synced but before tests are run
8
+
9
+ # Example: Setting up a test database
10
+ database_yml = <<-DB_CONFIG
11
+ test:
12
+ adapter: mysql
13
+ encoding: utf8
14
+ database: <%= options.project %>_testbot_test<%%= ENV['TEST_ENV_NUMBER'] %>
15
+ username: root
16
+ password:
17
+ host: localhost
18
+ DB_CONFIG
19
+
20
+ # database_file_path = "config/database.yml"
21
+ # File.open(database_file_path, 'w') { |f| f.write(database_yml) }
22
+ #
23
+ # # Setup databases for all instances
24
+ # 0.upto(ENV['TEST_INSTANCES'].to_i - 1) do |instance|
25
+ # test_env_number = (instance == 0) ? '' : instance + 1
26
+ # system "mysqladmin -u root -f drop <%= options.project %>_testbot_test#{test_env_number} > /dev/null 2>&1"
27
+ # system "mysqladmin -u root -f create <%= options.project %>_testbot_test#{test_env_number} > /dev/null 2>&1"
28
+ # system "export RAILS_ENV=test; export TEST_ENV_NUMBER=#{test_env_number}; rake db:test:load"
29
+ # end
30
+
31
+ # Example: Building gems
32
+ # system "rm vendor/gems/*/ext/**/*.o > /dev/null 2>&1"
33
+ # system "rake gems:build:force > /dev/null 2>&1"
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ # Which server to use.
2
+ server_host: <%= options.connect %>
3
+ <%- if options.user -%>
4
+ server_user: <%= options.user %>
5
+ <%- else -%>
6
+ # server_user: <%= Testbot::DEFAULT_USER %>
7
+ <%- end -%>
8
+
9
+ # Project prefix. Used for prefixing project files
10
+ # so that you can run multiple projects in the same testbot network.
11
+ <%- if options.project %>
12
+ project: <%= options.project %>
13
+ <%- else -%>
14
+ # project: <%= Testbot::DEFAULT_PROJECT %>
15
+ <%- end -%>
16
+
17
+ # RSync settings. The folder where your files are synced to
18
+ # and then fetched from before running the tests.
19
+ <%- if options.rsync_path -%>
20
+ rsync_path: <%= options.rsync_path %>
21
+ <%- else -%>
22
+ # rsync_path: <%= Testbot::DEFAULT_SERVER_PATH %>
23
+ <%- end -%>
24
+ <%- if options.rsync_ignores -%>
25
+ rsync_ignores: <%= options.rsync_ignores %>
26
+ <%- else -%>
27
+ # rsync_ignores:
28
+ <%- end -%>
29
+
30
+ # To tunnel traffic through SSH
31
+ <%- if options.ssh_tunnel -%>
32
+ ssh_tunnel: true
33
+ <%- else -%>
34
+ # ssh_tunnel: true
35
+ <%- end -%>
36
+
37
+ # Runner usage. Set to a lower percentage to not use
38
+ # every available instance or higher to create more
39
+ # jobs than there are instances.
40
+ available_runner_usage: 100%