testbot_instructure 0.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG +264 -0
  4. data/Gemfile +3 -0
  5. data/README.markdown +141 -0
  6. data/Rakefile +35 -0
  7. data/bin/testbot +59 -0
  8. data/lib/generators/testbot/templates/testbot.rake.erb +35 -0
  9. data/lib/generators/testbot/templates/testbot.yml.erb +45 -0
  10. data/lib/generators/testbot/testbot_generator.rb +19 -0
  11. data/lib/railtie.rb +16 -0
  12. data/lib/requester/requester.rb +171 -0
  13. data/lib/runner/job.rb +112 -0
  14. data/lib/runner/runner.rb +222 -0
  15. data/lib/runner/safe_result_text.rb +29 -0
  16. data/lib/server/build.rb +36 -0
  17. data/lib/server/group.rb +48 -0
  18. data/lib/server/job.rb +64 -0
  19. data/lib/server/memory_model.rb +91 -0
  20. data/lib/server/runner.rb +47 -0
  21. data/lib/server/server.rb +103 -0
  22. data/lib/server/status/javascripts/jquery-1.4.4.min.js +167 -0
  23. data/lib/server/status/status.html +48 -0
  24. data/lib/server/status/stylesheets/status.css +14 -0
  25. data/lib/shared/adapters/adapter.rb +27 -0
  26. data/lib/shared/adapters/cucumber_adapter.rb +91 -0
  27. data/lib/shared/adapters/helpers/ruby_env.rb +47 -0
  28. data/lib/shared/adapters/rspec2_adapter.rb +61 -0
  29. data/lib/shared/adapters/rspec_adapter.rb +79 -0
  30. data/lib/shared/adapters/test_unit_adapter.rb +44 -0
  31. data/lib/shared/color.rb +16 -0
  32. data/lib/shared/simple_daemonize.rb +25 -0
  33. data/lib/shared/ssh_tunnel.rb +36 -0
  34. data/lib/shared/testbot.rb +132 -0
  35. data/lib/shared/version.rb +12 -0
  36. data/lib/tasks/testbot.rake +30 -0
  37. data/lib/testbot.rb +2 -0
  38. data/test/fixtures/local/Rakefile +7 -0
  39. data/test/fixtures/local/config/testbot.yml +5 -0
  40. data/test/fixtures/local/log/test.log +0 -0
  41. data/test/fixtures/local/script/spec +2 -0
  42. data/test/fixtures/local/spec/models/car_spec.rb +0 -0
  43. data/test/fixtures/local/spec/models/house_spec.rb +0 -0
  44. data/test/fixtures/local/spec/spec.opts +0 -0
  45. data/test/fixtures/local/tmp/restart.txt +0 -0
  46. data/test/integration_test.rb +55 -0
  47. data/test/requester/requester_test.rb +407 -0
  48. data/test/requester/testbot.yml +7 -0
  49. data/test/requester/testbot_with_erb.yml +2 -0
  50. data/test/runner/job_test.rb +94 -0
  51. data/test/runner/safe_result_text_test.rb +20 -0
  52. data/test/server/group_test.rb +43 -0
  53. data/test/server/server_test.rb +511 -0
  54. data/test/shared/adapters/adapter_test.rb +22 -0
  55. data/test/shared/adapters/cucumber_adapter_test.rb +72 -0
  56. data/test/shared/adapters/helpers/ruby_env_test.rb +108 -0
  57. data/test/shared/adapters/rspec_adapter_test.rb +109 -0
  58. data/test/shared/testbot_test.rb +185 -0
  59. data/testbot.gemspec +34 -0
  60. metadata +313 -0
@@ -0,0 +1,27 @@
1
+ class Adapter
2
+
3
+ FILES = Dir[File.dirname(__FILE__) + "/*_adapter.rb"]
4
+ FILES.each { |file| require(file) }
5
+
6
+ def self.all
7
+ FILES.map { |file| load_adapter(file) }
8
+ end
9
+
10
+ def self.find(type)
11
+ if adapter = all.find { |adapter| adapter.type == type.to_s }
12
+ adapter
13
+ else
14
+ raise "Unknown adapter: #{type}"
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def self.load_adapter(file)
21
+ eval("::" + File.basename(file).
22
+ gsub(/\.rb/, '').
23
+ gsub(/(?:^|_)(.)/) { $1.upcase })
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/helpers/ruby_env"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../color"))
3
+
4
+ class CucumberAdapter
5
+
6
+ def self.command(project_path, ruby_interpreter, files)
7
+ cucumber_command = RubyEnv.ruby_command(project_path, :script => "script/cucumber", :bin => "cucumber",
8
+ :ruby_interpreter => ruby_interpreter)
9
+ "export AUTOTEST=1; #{cucumber_command} -f progress --backtrace -r features/support -r features/step_definitions #{files} -t ~@disabled"
10
+ end
11
+
12
+ def self.test_files(dir)
13
+ Dir["#{dir}/#{file_pattern}"]
14
+ end
15
+
16
+ def self.get_sizes(files)
17
+ files.map { |file| File.stat(file).size }
18
+ end
19
+
20
+ def self.requester_port
21
+ 2230
22
+ end
23
+
24
+ def self.pluralized
25
+ 'features'
26
+ end
27
+
28
+ def self.base_path
29
+ pluralized
30
+ end
31
+
32
+ def self.name
33
+ 'Cucumber'
34
+ end
35
+
36
+ def self.type
37
+ pluralized
38
+ end
39
+
40
+ # This is an optional method. It gets passed the entire test result and summarizes it. See the tests.
41
+ def self.sum_results(text)
42
+ scenarios, steps = parse_scenarios_and_steps(text)
43
+
44
+ scenarios_line = "#{scenarios[:total]} scenarios (" + [
45
+ (Color.colorize("#{scenarios[:failed]} failed", :red) if scenarios[:failed] > 0),
46
+ (Color.colorize("#{scenarios[:undefined]} undefined", :orange) if scenarios[:undefined] > 0),
47
+ (Color.colorize("#{scenarios[:passed]} passed", :green) if scenarios[:passed] > 0)
48
+ ].compact.join(', ') + ")"
49
+
50
+ steps_line = "#{steps[:total]} steps (" + [
51
+ (Color.colorize("#{steps[:failed]} failed", :red) if steps[:failed] > 0),
52
+ (Color.colorize("#{steps[:skipped]} skipped", :cyan) if steps[:skipped] > 0),
53
+ (Color.colorize("#{steps[:undefined]} undefined", :orange) if steps[:undefined] > 0),
54
+ (Color.colorize("#{steps[:passed]} passed", :green) if steps[:passed] > 0)
55
+ ].compact.join(', ') + ")"
56
+
57
+ scenarios_line + "\n" + steps_line
58
+ end
59
+
60
+ private
61
+
62
+ def self.parse_scenarios_and_steps(text)
63
+ results = {
64
+ :scenarios => { :total => 0, :passed => 0, :failed => 0, :undefined => 0 },
65
+ :steps => { :total => 0, :passed => 0, :failed => 0, :skipped => 0, :undefined => 0 }
66
+ }
67
+
68
+ Color.strip(text).split("\n").each do |line|
69
+ type = line.include?("scenarios") ? :scenarios : :steps
70
+
71
+ if match = line.match(/\((.+)\)/)
72
+ results[type][:total] += line.split.first.to_i
73
+ parse_status_counts(results[type], match[1])
74
+ end
75
+ end
76
+
77
+ [ results[:scenarios], results[:steps] ]
78
+ end
79
+
80
+ def self.parse_status_counts(results, status_counts)
81
+ status_counts.split(', ').each do |part|
82
+ results.keys.each do |key|
83
+ results[key] += part.split.first.to_i if part.include?(key.to_s)
84
+ end
85
+ end
86
+ end
87
+
88
+ def self.file_pattern
89
+ '**/**/*.feature'
90
+ end
91
+ end
@@ -0,0 +1,47 @@
1
+ class RubyEnv
2
+ def self.bundler?(project_path)
3
+ gem_exists?("bundler") && File.exists?("#{project_path}/Gemfile")
4
+ end
5
+
6
+ def self.gem_exists?(gem)
7
+ if Gem::Specification.respond_to?(:find_by_name)
8
+ Gem::Specification.find_by_name(gem)
9
+ else
10
+ # older depricated method
11
+ Gem.available?(gem)
12
+ end
13
+ rescue Gem::LoadError
14
+ false
15
+ end
16
+
17
+ def self.ruby_command(project_path, opts = {})
18
+ ruby_interpreter = opts[:ruby_interpreter] || "ruby"
19
+
20
+ if opts[:script] && File.exists?("#{project_path}/#{opts[:script]}")
21
+ command = opts[:script]
22
+ elsif opts[:bin]
23
+ command = opts[:bin]
24
+ else
25
+ command = nil
26
+ end
27
+
28
+ if bundler?(project_path)
29
+ "#{rvm_prefix(project_path)} #{ruby_interpreter} -S bundle exec #{command}".strip
30
+ else
31
+ "#{rvm_prefix(project_path)} #{ruby_interpreter} -S #{command}".strip
32
+ end
33
+ end
34
+
35
+ def self.rvm_prefix(project_path)
36
+ if rvm?
37
+ rvmrc_path = File.join project_path, ".rvmrc"
38
+ if File.exists?(rvmrc_path)
39
+ File.read(rvmrc_path).to_s.strip + " exec"
40
+ end
41
+ end
42
+ end
43
+
44
+ def self.rvm?
45
+ system("rvm info") != nil
46
+ end
47
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/helpers/ruby_env"))
2
+
3
+ class Rspec2Adapter
4
+
5
+ def self.command(project_path, ruby_interpreter, files)
6
+ spec_command = RubyEnv.ruby_command(project_path,
7
+ :bin => "rspec",
8
+ :ruby_interpreter => ruby_interpreter)
9
+
10
+ if File.exists?("#{project_path}/spec/spec.opts")
11
+ spec_command += " -O spec/spec.opts"
12
+ end
13
+
14
+ "export RSPEC_COLOR=true; #{spec_command} #{files}"
15
+ end
16
+
17
+ def self.test_files(dir)
18
+ if ENV['SELENIUM_SPECS']
19
+ puts 'running selenium specs'
20
+ test_files = FileList['spec/selenium/**/*_spec.rb'] + FileList['vendor/plugins/*/spec_canvas/selenium/*_spec.rb']
21
+ elsif ENV['PLUGIN_SPECS']
22
+ puts 'running plugin specs'
23
+ test_files = FileList['vendor/plugins/*/spec_canvas/**/*_spec.rb'].exclude('vendor/plugins/*/spec_canvas/selenium/*_spec.rb') + FileList['spec/**/*_spec.rb'].exclude('spec/selenium/**/*_spec.rb')
24
+ :ew3else
25
+ puts 'normal pattern'
26
+ test_files = Dir["#{dir}/#{file_pattern}"]
27
+ end
28
+ test_files
29
+ end
30
+
31
+ def self.get_sizes(files)
32
+ files.map { |file| File.stat(file).size }
33
+ end
34
+
35
+ def self.requester_port
36
+ 2299
37
+ end
38
+
39
+ def self.pluralized
40
+ 'specs'
41
+ end
42
+
43
+ def self.base_path
44
+ "spec"
45
+ end
46
+
47
+ def self.name
48
+ 'RSpec2'
49
+ end
50
+
51
+ def self.type
52
+ 'rspec'
53
+ end
54
+
55
+ private
56
+
57
+ def self.file_pattern
58
+ '**/**/*_spec.rb'
59
+ end
60
+
61
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/helpers/ruby_env"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "../color"))
3
+
4
+ class RspecAdapter
5
+
6
+ def self.command(project_path, ruby_interpreter, files)
7
+ spec_command = RubyEnv.ruby_command(project_path, :script => "script/spec", :bin => "rspec",
8
+ :ruby_interpreter => ruby_interpreter)
9
+ if File.exists?("#{project_path}/spec/spec.opts")
10
+ spec_command += " -O spec/spec.opts"
11
+ end
12
+
13
+ "export RSPEC_COLOR=true; #{spec_command} #{files}"
14
+ end
15
+
16
+ def self.test_files(dir)
17
+ Dir["#{dir}/#{file_pattern}"]
18
+ end
19
+
20
+ def self.get_sizes(files)
21
+ files.map { |file| File.stat(file).size }
22
+ end
23
+
24
+ def self.requester_port
25
+ 2299
26
+ end
27
+
28
+ def self.pluralized
29
+ 'specs'
30
+ end
31
+
32
+ def self.base_path
33
+ type
34
+ end
35
+
36
+ def self.name
37
+ 'RSpec'
38
+ end
39
+
40
+ def self.type
41
+ 'spec'
42
+ end
43
+
44
+ # This is an optional method. It gets passed the entire test result and summarizes it. See the tests.
45
+ def self.sum_results(results)
46
+ examples, failures, pending = 0, 0, 0
47
+ results.split("\n").each do |line|
48
+ line =~ /(\d+) examples?, (\d+) failures?(, (\d+) pending)?/
49
+ next unless $1
50
+ examples += $1.to_i
51
+ failures += $2.to_i
52
+ pending += $4.to_i
53
+ end
54
+
55
+ result = [ pluralize(examples, 'example'), pluralize(failures, 'failure'), (pending > 0 ? "#{pending} pending" : nil) ].compact.join(', ')
56
+ if failures == 0 && pending == 0
57
+ Color.colorize(result, :green)
58
+ elsif failures == 0 && pending > 0
59
+ Color.colorize(result, :orange)
60
+ else
61
+ Color.colorize(result, :red)
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def self.pluralize(count, singular)
68
+ if count == 1
69
+ "#{count} #{singular}"
70
+ else
71
+ "#{count} #{singular}s"
72
+ end
73
+ end
74
+
75
+ def self.file_pattern
76
+ '**/**/*_spec.rb'
77
+ end
78
+
79
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/helpers/ruby_env"))
2
+
3
+ class TestUnitAdapter
4
+
5
+ def self.command(project_path, ruby_interpreter, files)
6
+ ruby_command = RubyEnv.ruby_command(project_path, :ruby_interpreter => ruby_interpreter)
7
+ %{#{ruby_command} -Itest -e '%w(#{files}).each { |file| require(Dir.pwd + "/" + file) }'}
8
+ end
9
+
10
+ def self.test_files(dir)
11
+ Dir["#{dir}/#{file_pattern}"]
12
+ end
13
+
14
+ def self.get_sizes(files)
15
+ files.map { |file| File.stat(file).size }
16
+ end
17
+
18
+ def self.requester_port
19
+ 2231
20
+ end
21
+
22
+ def self.pluralized
23
+ 'tests'
24
+ end
25
+
26
+ def self.base_path
27
+ type
28
+ end
29
+
30
+ def self.name
31
+ 'Test::Unit'
32
+ end
33
+
34
+ def self.type
35
+ 'test'
36
+ end
37
+
38
+ private
39
+
40
+ def self.file_pattern
41
+ '**/**/*_test.rb'
42
+ end
43
+
44
+ end
@@ -0,0 +1,16 @@
1
+ class Color
2
+ def self.colorize(text, color)
3
+ colors = { :green => 32, :orange => 33, :red => 31, :cyan => 36 }
4
+
5
+ if colors[color]
6
+ "\033[#{colors[color]}m#{text}\033[0m"
7
+ else
8
+ raise "Color not implemented: #{color}"
9
+ end
10
+ end
11
+
12
+ def self.strip(text)
13
+ text.gsub(/\e.+?m/, '')
14
+ end
15
+ end
16
+
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'daemons'
3
+
4
+ class SimpleDaemonize
5
+
6
+ def self.start(proc, pid_path, app_name)
7
+ working_dir = Dir.pwd
8
+
9
+ group = Daemons::ApplicationGroup.new(app_name)
10
+ group.new_application(:mode => :none).start
11
+
12
+ File.open(pid_path, 'w') { |file| file.write(Process.pid) }
13
+ Dir.chdir(working_dir)
14
+ proc.call
15
+ end
16
+
17
+ def self.stop(pid_path)
18
+ return unless File.exists?(pid_path)
19
+ pid = File.read(pid_path)
20
+
21
+ system "kill -9 #{pid} &> /dev/null"
22
+ system "rm #{pid_path} &> /dev/null"
23
+ end
24
+
25
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'net/ssh'
3
+
4
+ class SSHTunnel
5
+
6
+ def initialize(host, user, local_port = 2288)
7
+ @host, @user, @local_port = host, user, local_port
8
+ end
9
+
10
+ def open
11
+ connect
12
+
13
+ start_time = Time.now
14
+ while true
15
+ break if @up
16
+ sleep 0.5
17
+
18
+ if Time.now - start_time > 5
19
+ puts "SSH connection failed, trying again..."
20
+ start_time = Time.now
21
+ connect
22
+ end
23
+ end
24
+ end
25
+
26
+ def connect
27
+ @thread.kill! if @thread
28
+ @thread = Thread.new do
29
+ Net::SSH.start(@host, @user, { :timeout => 1 }) do |ssh|
30
+ ssh.forward.local(@local_port, 'localhost', Testbot::SERVER_PORT)
31
+ ssh.loop { @up = true }
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,132 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '/version'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '/simple_daemonize'))
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '/adapters/adapter'))
4
+ require 'fileutils'
5
+
6
+ module Testbot
7
+ require 'railtie' if defined?(Rails)
8
+
9
+ if ENV['INTEGRATION_TEST']
10
+ SERVER_PID = "/tmp/integration_test_testbot_server.pid"
11
+ RUNNER_PID = "/tmp/integration_test_testbot_runner.pid"
12
+ else
13
+ SERVER_PID = "/tmp/testbot_server.pid"
14
+ RUNNER_PID = "/tmp/testbot_runner.pid"
15
+ end
16
+
17
+ DEFAULT_WORKING_DIR = "/tmp/testbot"
18
+ DEFAULT_SERVER_PATH = "/tmp/testbot/#{ENV['USER']}"
19
+ DEFAULT_USER = "testbot"
20
+ DEFAULT_PROJECT = "project"
21
+ DEFAULT_RUNNER_USAGE = "100%"
22
+ SERVER_PORT = ENV['INTEGRATION_TEST'] ? 22880 : 2288
23
+
24
+ class CLI
25
+
26
+ def self.run(argv)
27
+ return false if argv == []
28
+ opts = parse_args(argv)
29
+
30
+ if opts[:help]
31
+ return false
32
+ elsif opts[:version]
33
+ puts "Testbot #{Testbot.version}"
34
+ elsif [ true, 'run', 'start' ].include?(opts[:server])
35
+ start_server(opts[:server])
36
+ elsif opts[:server] == 'stop'
37
+ stop('server', Testbot::SERVER_PID)
38
+ elsif [ true, 'run', 'start' ].include?(opts[:runner])
39
+ require File.expand_path(File.join(File.dirname(__FILE__), '/../runner/runner'))
40
+ return false unless valid_runner_opts?(opts)
41
+ start_runner(opts)
42
+ elsif opts[:runner] == 'stop'
43
+ stop('runner', Testbot::RUNNER_PID)
44
+ elsif adapter = Adapter.all.find { |adapter| opts[adapter.type.to_sym] }
45
+ require File.expand_path(File.join(File.dirname(__FILE__), '/../requester/requester'))
46
+ start_requester(opts, adapter)
47
+ end
48
+
49
+ true
50
+ end
51
+
52
+ def self.parse_args(argv)
53
+ last_setter = nil
54
+ hash = {}
55
+ str = ''
56
+ argv.each_with_index do |arg, i|
57
+ if arg.include?('--')
58
+ str = ''
59
+ last_setter = arg.split('--').last.to_sym
60
+ hash[last_setter] = true if (i == argv.size - 1) || argv[i+1].include?('--')
61
+ else
62
+ str += ' ' + arg
63
+ hash[last_setter] = str.strip
64
+ end
65
+ end
66
+ hash
67
+ end
68
+
69
+ def self.start_runner(opts)
70
+ stop('runner', Testbot::RUNNER_PID)
71
+
72
+ proc = lambda {
73
+ working_dir = opts[:working_dir] || Testbot::DEFAULT_WORKING_DIR
74
+ FileUtils.mkdir_p(working_dir)
75
+ Dir.chdir(working_dir)
76
+ runner = Runner::Runner.new(:server_host => opts[:connect],
77
+ :auto_update => opts[:auto_update], :max_instances => opts[:cpus],
78
+ :ssh_tunnel => opts[:ssh_tunnel], :server_user => opts[:user],
79
+ :max_jruby_instances => opts[:max_jruby_instances],
80
+ :dev_gem_root => opts[:dev_gem_root],
81
+ :wait_for_updated_gem => opts[:wait_for_updated_gem],
82
+ :jruby_opts => opts[:jruby_opts])
83
+ runner.run!
84
+ }
85
+
86
+ if opts[:runner] == 'run'
87
+ proc.call
88
+ else
89
+ puts "Testbot runner started (pid: #{Process.pid})"
90
+ SimpleDaemonize.start(proc, Testbot::RUNNER_PID, "testbot (runner)")
91
+ end
92
+ end
93
+
94
+ def self.start_server(type)
95
+ stop('server', Testbot::SERVER_PID)
96
+ require File.expand_path(File.join(File.dirname(__FILE__), '/../server/server'))
97
+
98
+ if type == 'run'
99
+ Sinatra::Application.run! :environment => "production"
100
+ else
101
+ puts "Testbot server started (pid: #{Process.pid})"
102
+ SimpleDaemonize.start(lambda {
103
+ Sinatra::Application.run! :environment => "production"
104
+ }, Testbot::SERVER_PID, "testbot (server)")
105
+ end
106
+ end
107
+
108
+ def self.stop(name, pid)
109
+ puts "Testbot #{name} stopped" if SimpleDaemonize.stop(pid)
110
+ end
111
+
112
+ def self.start_requester(opts, adapter)
113
+ requester = Requester::Requester.new(:server_host => opts[:connect],
114
+ :rsync_path => opts[:rsync_path],
115
+ :rsync_ignores => opts[:rsync_ignores].to_s,
116
+ :available_runner_usage => nil,
117
+ :project => opts[:project],
118
+ :ssh_tunnel => opts[:ssh_tunnel], :server_user => opts[:user])
119
+ requester.run_tests(adapter, adapter.base_path)
120
+ end
121
+
122
+ def self.valid_runner_opts?(opts)
123
+ opts[:connect].is_a?(String)
124
+ end
125
+
126
+ def self.lib_path
127
+ File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
128
+ end
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,12 @@
1
+ module Testbot
2
+ # Don't forget to update readme and changelog
3
+ def self.version
4
+ version = "0.7.8"
5
+ dev_version_file = File.join(File.dirname(__FILE__), '..', '..', 'DEV_VERSION')
6
+ if File.exists?(dev_version_file)
7
+ version += File.read(dev_version_file)
8
+ end
9
+ version
10
+ end
11
+ end
12
+
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../shared/adapters/adapter'
2
+
3
+ namespace :testbot do
4
+
5
+ def run_and_show_results(adapter, custom_path)
6
+ 'testbot:before_request'.tap { |t| Rake::Task.task_defined?(t) && Rake::Task[t].invoke }
7
+
8
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'requester', 'requester.rb'))
9
+ requester = Testbot::Requester::Requester.create_by_config("#{Rails.root}/config/testbot.yml")
10
+
11
+ puts "Running #{adapter.pluralized}..."
12
+ start_time = Time.now
13
+
14
+ path = custom_path ? "#{adapter.base_path}/#{custom_path}" : adapter.base_path
15
+ success = requester.run_tests(adapter, path)
16
+
17
+ puts
18
+ puts "Finished in #{Time.now - start_time} seconds."
19
+ success
20
+ end
21
+
22
+ Adapter.all.each do |adapter|
23
+
24
+ desc "Run the #{adapter.name} tests using testbot"
25
+ task adapter.type, :custom_path do |_, args|
26
+ exit 1 unless run_and_show_results(adapter, args[:custom_path])
27
+ end
28
+
29
+ end
30
+ end
data/lib/testbot.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Rails plugin hook
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '/shared/testbot'))
@@ -0,0 +1,7 @@
1
+ namespace :testbot do
2
+
3
+ task :before_run do
4
+ puts "prepare got called"
5
+ end
6
+
7
+ end
@@ -0,0 +1,5 @@
1
+ server_host: localhost
2
+ rsync_path: ../server
3
+ available_runner_usage: 100%
4
+ rsync_ignores: log/* tmp/*
5
+
File without changes
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ puts "script/spec got called with #{ARGV.inspect}"
File without changes
File without changes
File without changes
File without changes