testbot_instructure 0.7.8

Sign up to get free protection for your applications and to get access to all the features.
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,108 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../lib/shared/adapters/helpers/ruby_env.rb'))
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'flexmock/test_unit'
5
+
6
+ class RubyEnvTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ # Can't override a stub in flexmock?
10
+ def RubyEnv.rvm?; false; end
11
+ end
12
+
13
+ context "self.bundler?" do
14
+
15
+ should "return true if bundler is installed and there is a Gemfile" do
16
+ flexmock(Gem::Specification).should_receive(:find_by_name).with("bundler").once.and_return(true)
17
+ flexmock(File).should_receive(:exists?).with("path/to/project/Gemfile").once.and_return(true)
18
+ assert_equal true, RubyEnv.bundler?("path/to/project")
19
+ end
20
+
21
+ should "return false if bundler is installed but there is no Gemfile" do
22
+ flexmock(Gem::Specification).should_receive(:find_by_name).with("bundler").once.and_return(true)
23
+ flexmock(File).should_receive(:exists?).and_return(false)
24
+ assert_equal false, RubyEnv.bundler?("path/to/project")
25
+ end
26
+
27
+ should "return false if bundler is not installed" do
28
+ flexmock(Gem::Specification).should_receive(:find_by_name).with("bundler").once.and_return(false)
29
+ assert_equal false, RubyEnv.bundler?("path/to/project")
30
+ end
31
+
32
+ end
33
+
34
+ context "self.rvm_prefix" do
35
+
36
+ should "return rvm prefix if rvm is installed" do
37
+ def RubyEnv.rvm?; true; end
38
+ flexmock(File).should_receive(:exists?).with("path/to/project/.rvmrc").once.and_return(true)
39
+ flexmock(File).should_receive(:read).with("path/to/project/.rvmrc").once.and_return("rvm 1.8.7\n")
40
+ assert_equal "rvm 1.8.7 exec", RubyEnv.rvm_prefix("path/to/project")
41
+ end
42
+
43
+ should "return nil if rvm is not installed" do
44
+ assert_equal nil, RubyEnv.rvm_prefix("path/to/project")
45
+ end
46
+
47
+ end
48
+
49
+ context "self.ruby_command" do
50
+
51
+ should "use ruby by default" do
52
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(false)
53
+ flexmock(File).should_receive(:exists?).and_return(false)
54
+ assert_equal 'ruby -S rspec', RubyEnv.ruby_command("path/to/project", :script => "script/spec", :bin => "rspec")
55
+ end
56
+
57
+ should "use bundler when available and use the binary when there is no script" do
58
+ flexmock(RubyEnv).should_receive(:bundler?).once.with("path/to/project").and_return(true)
59
+ flexmock(File).should_receive(:exists?).with("path/to/project/script/spec").and_return(false)
60
+ assert_equal 'ruby -S bundle exec rspec', RubyEnv.ruby_command("path/to/project", :script => "script/spec", :bin => "rspec")
61
+ end
62
+
63
+ should "use the script when it exists when using bundler" do
64
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(true)
65
+ flexmock(File).should_receive(:exists?).and_return(true)
66
+ assert_equal 'ruby -S bundle exec script/spec', RubyEnv.ruby_command("path/to/project", :script => "script/spec", :bin => "rspec")
67
+ end
68
+
69
+ should "use the script when it exists when not using bundler" do
70
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(false)
71
+ flexmock(File).should_receive(:exists?).and_return(true)
72
+ assert_equal 'ruby -S script/spec', RubyEnv.ruby_command("path/to/project", :script => "script/spec", :bin => "rspec")
73
+ end
74
+
75
+ should "not look for a script when none is provided" do
76
+ assert_equal 'ruby -S rspec', RubyEnv.ruby_command("path/to/project", :bin => "rspec")
77
+ end
78
+
79
+ should "be able to use jruby" do
80
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(false)
81
+ flexmock(File).should_receive(:exists?).and_return(true)
82
+ assert_equal 'jruby -S script/spec', RubyEnv.ruby_command("path/to/project", :script => "script/spec",
83
+ :bin => "rspec", :ruby_interpreter => "jruby")
84
+ end
85
+
86
+ should "be able to use jruby with bundler" do
87
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(true)
88
+ flexmock(File).should_receive(:exists?).and_return(true)
89
+ assert_equal 'jruby -S bundle exec script/spec', RubyEnv.ruby_command("path/to/project", :script => "script/spec",
90
+ :bin => "rspec", :ruby_interpreter => "jruby")
91
+ end
92
+
93
+ should "work when there is no binary specified and bundler is present" do
94
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(true)
95
+ flexmock(File).should_receive(:exists?).and_return(false)
96
+ assert_equal 'ruby -S bundle exec', RubyEnv.ruby_command("path/to/project")
97
+ end
98
+
99
+ should "work when there is no binary specified and bundler is not present" do
100
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(false)
101
+ flexmock(File).should_receive(:exists?).and_return(false)
102
+ assert_equal 'ruby -S', RubyEnv.ruby_command("path/to/project")
103
+ end
104
+
105
+
106
+ end
107
+
108
+ end
@@ -0,0 +1,109 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/shared/adapters/rspec_adapter.rb'))
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ class RspecAdapterTest < Test::Unit::TestCase
6
+
7
+ context "sum_results" do
8
+
9
+ should "be able to parse and sum results" do
10
+ results =<<STR
11
+ srv-y5ei5:/tmp/testbot
12
+ ..................FF..................................................
13
+
14
+ Finished in 4.962975 seconds
15
+
16
+ 69 examples, 2 failures
17
+
18
+
19
+ testbot1:/tmp/testbot
20
+ .............F...........*........................
21
+
22
+ Finished in 9.987141 seconds
23
+
24
+ 50 examples, 1 failure, 1 pending
25
+
26
+ testbot1:/tmp/testbot
27
+ .............FF.......****........................
28
+
29
+ Finished in 9.987141 seconds
30
+
31
+ 50 examples, 2 failures, 3 pending
32
+
33
+ testbot1:/tmp/testbot
34
+ .
35
+
36
+ Finished in 9.987141 seconds
37
+
38
+ 1 example, 0 failures, 0 pending
39
+ STR
40
+ assert_equal "170 examples, 5 failures, 4 pending", Color.strip(RspecAdapter.sum_results(results))
41
+ end
42
+
43
+ should "return 0 examples and failures for an empty resultset" do
44
+ assert_equal "0 examples, 0 failures", Color.strip(RspecAdapter.sum_results(""))
45
+ end
46
+
47
+ should "print in singular for examples" do
48
+ str =<<STR
49
+ testbot1:/tmp/testbot
50
+ .
51
+
52
+ Finished in 9.987141 seconds
53
+
54
+ 1 example, 0 failures
55
+ STR
56
+ assert_equal "1 example, 0 failures", Color.strip(RspecAdapter.sum_results(str))
57
+ end
58
+
59
+ should "print in singular for failures" do
60
+ str =<<STR
61
+ testbot1:/tmp/testbot
62
+ F
63
+
64
+ Finished in 9.987141 seconds
65
+
66
+ 0 example, 1 failures
67
+ STR
68
+ assert_equal "0 examples, 1 failure", Color.strip(RspecAdapter.sum_results(str))
69
+ end
70
+
71
+ should "make the result green if there is no failed or pending examples" do
72
+ str =<<STR
73
+ testbot1:/tmp/testbot
74
+ .
75
+
76
+ Finished in 9.987141 seconds
77
+
78
+ 1 example, 0 failures
79
+ STR
80
+ assert_equal "\033[32m1 example, 0 failures\033[0m", RspecAdapter.sum_results(str)
81
+ end
82
+
83
+ should "make the result orange if there is pending examples" do
84
+ str =<<STR
85
+ testbot1:/tmp/testbot
86
+ *
87
+
88
+ Finished in 9.987141 seconds
89
+
90
+ 1 example, 0 failures, 1 pending
91
+ STR
92
+ assert_equal "\033[33m1 example, 0 failures, 1 pending\033[0m", RspecAdapter.sum_results(str)
93
+ end
94
+
95
+ should "make the results red if there is failed examples" do
96
+ str = <<STR
97
+ testbot1:/tmp/testbot
98
+ F
99
+
100
+ Finished in 9.987141 seconds
101
+
102
+ 1 example, 1 failures
103
+ STR
104
+ assert_equal "\033[31m1 example, 1 failure\033[0m", RspecAdapter.sum_results(str)
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,185 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/shared/testbot')) unless defined?(Testbot)
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'flexmock/test_unit'
5
+ require 'sinatra'
6
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/requester/requester'))
7
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/server/server'))
8
+
9
+ module Testbot
10
+
11
+ module TestHelpers
12
+
13
+ def requester_attributes
14
+ { :server_host => "192.168.0.100",
15
+ :rsync_path => nil,
16
+ :rsync_ignores => '', :server_user => nil, :available_runner_usage => nil,
17
+ :project => nil, :ssh_tunnel => nil }
18
+ end
19
+
20
+ end
21
+
22
+ class CLITest < Test::Unit::TestCase
23
+
24
+ include TestHelpers
25
+
26
+ context "self.run" do
27
+
28
+ context "with no args" do
29
+ should "return false" do
30
+ assert_equal false, CLI.run([])
31
+ end
32
+ end
33
+
34
+ context "with --help" do
35
+ should "return false" do
36
+ assert_equal false, CLI.run([ '--help' ])
37
+ end
38
+ end
39
+
40
+ context "with --version" do
41
+ should "print version and return true" do
42
+ flexmock(CLI).should_receive(:puts).once.with("Testbot #{Testbot.version}")
43
+ assert_equal true, CLI.run([ '--version' ])
44
+ end
45
+ end
46
+
47
+ context "with --server" do
48
+ should "start a server" do
49
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::SERVER_PID)
50
+ flexmock(SimpleDaemonize).should_receive(:start).once.with(any, Testbot::SERVER_PID, "testbot (server)")
51
+ flexmock(CLI).should_receive(:puts).once.with("Testbot server started (pid: #{Process.pid})")
52
+ assert_equal true, CLI.run([ "--server" ])
53
+ end
54
+
55
+ should "start a server when start is passed" do
56
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::SERVER_PID)
57
+ flexmock(SimpleDaemonize).should_receive(:start).once
58
+ flexmock(CLI).should_receive(:puts)
59
+ assert_equal true, CLI.run([ "--server", "start" ])
60
+ end
61
+
62
+ should "stop a server when stop is passed" do
63
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::SERVER_PID).and_return(true)
64
+ flexmock(CLI).should_receive(:puts).once.with("Testbot server stopped")
65
+ assert_equal true, CLI.run([ "--server", "stop" ])
66
+ end
67
+
68
+ should "not print when SimpleDaemonize.stop returns false" do
69
+ flexmock(SimpleDaemonize).should_receive(:stop).and_return(false)
70
+ flexmock(CLI).should_receive(:puts).never
71
+ CLI.run([ "--stop", "server" ])
72
+ end
73
+
74
+ should "start it in the foreground with run" do
75
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::SERVER_PID)
76
+ flexmock(SimpleDaemonize).should_receive(:start).never
77
+ flexmock(Sinatra::Application).should_receive(:run!).once.with(:environment => "production")
78
+ assert_equal true, CLI.run([ "--server", 'run' ])
79
+ end
80
+ end
81
+
82
+ context "with --runner" do
83
+ should "start a runner" do
84
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::RUNNER_PID)
85
+ flexmock(SimpleDaemonize).should_receive(:start).once.with(any, Testbot::RUNNER_PID, "testbot (runner)")
86
+ flexmock(CLI).should_receive(:puts).once.with("Testbot runner started (pid: #{Process.pid})")
87
+ assert_equal true, CLI.run([ "--runner", "--connect", "192.168.0.100", "--working_dir", "/tmp/testbot" ])
88
+ end
89
+
90
+ should "start a runner when start is passed" do
91
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::RUNNER_PID)
92
+ flexmock(SimpleDaemonize).should_receive(:start).once
93
+ flexmock(CLI).should_receive(:puts)
94
+ assert_equal true, CLI.run([ "--runner", "start", "--connect", "192.168.0.100" ])
95
+ end
96
+
97
+ should "stop a runner when stop is passed" do
98
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::RUNNER_PID).and_return(true)
99
+ flexmock(CLI).should_receive(:puts).once.with("Testbot runner stopped")
100
+ assert_equal true, CLI.run([ "--runner", "stop" ])
101
+ end
102
+
103
+ should "return false without connect" do
104
+ assert_equal false, CLI.run([ "--runner", "--connect" ])
105
+ assert_equal false, CLI.run([ "--runner" ])
106
+ end
107
+
108
+ should "start it in the foreground with run" do
109
+ flexmock(SimpleDaemonize).should_receive(:stop).once.with(Testbot::RUNNER_PID)
110
+ flexmock(SimpleDaemonize).should_receive(:start).never
111
+ flexmock(Runner::Runner).should_receive(:new).once.and_return(mock = Object.new)
112
+ flexmock(mock).should_receive(:run!).once
113
+ assert_equal true, CLI.run([ "--runner", 'run', '--connect', '192.168.0.100' ])
114
+ end
115
+ end
116
+
117
+ Adapter.all.each do |adapter|
118
+ context "with --#{adapter.type}" do
119
+ should "start a #{adapter.name} requester and return true" do
120
+ flexmock(Requester::Requester).should_receive(:new).once.
121
+ with(requester_attributes).and_return(mock = Object.new)
122
+ flexmock(mock).should_receive(:run_tests).once.with(adapter, adapter.base_path)
123
+ assert_equal true, CLI.run([ "--#{adapter.type}", "--connect", "192.168.0.100" ])
124
+ end
125
+
126
+ should "accept a custom rsync_path" do
127
+ flexmock(Requester::Requester).should_receive(:new).once.
128
+ with(requester_attributes.merge({ :rsync_path => "/somewhere/else" })).
129
+ and_return(mock = Object.new)
130
+ flexmock(mock).should_receive(:run_tests)
131
+ CLI.run([ "--#{adapter.type}", "--connect", "192.168.0.100", '--rsync_path', '/somewhere/else' ])
132
+ end
133
+
134
+ should "accept rsync_ignores" do
135
+ flexmock(Requester::Requester).should_receive(:new).once.
136
+ with(requester_attributes.merge({ :rsync_ignores => "tmp log" })).
137
+ and_return(mock = Object.new)
138
+ flexmock(mock).should_receive(:run_tests)
139
+ CLI.run([ "--#{adapter.type}", "--connect", "192.168.0.100", '--rsync_ignores', 'tmp', 'log' ])
140
+ end
141
+
142
+ should "accept ssh tunnel" do
143
+ flexmock(Requester::Requester).should_receive(:new).once.
144
+ with(requester_attributes.merge({ :ssh_tunnel => true })).
145
+ and_return(mock = Object.new)
146
+ flexmock(mock).should_receive(:run_tests)
147
+ CLI.run([ "--#{adapter.type}", "--connect", "192.168.0.100", '--ssh_tunnel' ])
148
+ end
149
+
150
+ should "accept a custom user" do
151
+ flexmock(Requester::Requester).should_receive(:new).once.
152
+ with(requester_attributes.merge({ :server_user => "cruise" })).
153
+ and_return(mock = Object.new)
154
+ flexmock(mock).should_receive(:run_tests)
155
+ CLI.run([ "--#{adapter.type}", "--connect", "192.168.0.100", '--user', 'cruise' ])
156
+ end
157
+
158
+ should "accept a custom project name" do
159
+ flexmock(Requester::Requester).should_receive(:new).once.
160
+ with(requester_attributes.merge({ :project => "rspec" })).
161
+ and_return(mock = Object.new)
162
+ flexmock(mock).should_receive(:run_tests)
163
+ CLI.run([ "--#{adapter.type}", "--connect", "192.168.0.100", '--project', 'rspec' ])
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ context "self.parse_args" do
170
+
171
+ should 'convert ARGV arguments to a hash' do
172
+ hash = CLI.parse_args("--runner --connect http://127.0.0.1:#{Testbot::SERVER_PORT} --working_dir ~/testbot --ssh_tunnel user@testbot_server".split)
173
+ assert_equal ({ :runner => true, :connect => "http://127.0.0.1:#{Testbot::SERVER_PORT}", :working_dir => "~/testbot", :ssh_tunnel => "user@testbot_server" }), hash
174
+ end
175
+
176
+ should "handle just a key without a value" do
177
+ hash = CLI.parse_args([ "--server" ])
178
+ assert_equal ({ :server => true }), hash
179
+ end
180
+
181
+ end
182
+
183
+ end
184
+
185
+ end
data/testbot.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__) + '/lib/shared/version')
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "testbot_instructure"
6
+ s.version = Testbot.version
7
+ s.authors = ["Joakim Kolsjö"]
8
+ s.email = ["joakim.kolsjo@gmail.com"]
9
+ s.homepage = "http://github.com/joakimk/testbot"
10
+ s.summary = %q{A test distribution tool forked for instructure.}
11
+ s.description = %q{Testbot is a test distribution tool that works with Rails, RSpec, RSpec2, Test::Unit and Cucumber.}
12
+ s.bindir = "bin"
13
+ s.executables = [ "testbot" ]
14
+ s.files = Dir.glob("lib/**/*") + Dir.glob("test/**/*") + %w(Gemfile .gemtest Rakefile testbot.gemspec CHANGELOG README.markdown bin/testbot) +
15
+ (File.exists?("DEV_VERSION") ? [ "DEV_VERSION" ] : [])
16
+
17
+ s.add_dependency('sinatra', '~> 1.0.0')
18
+ s.add_dependency('httparty', '>= 0.6.1')
19
+ s.add_dependency('net-ssh', '>= 2.0.23')
20
+ s.add_dependency('json_pure', '>= 1.4.6')
21
+ s.add_dependency('daemons', '>= 1.0.10')
22
+ s.add_dependency('acts_as_rails3_generator')
23
+ s.add_dependency('posix-spawn', '>= 0.3.6')
24
+
25
+ s.add_development_dependency("shoulda")
26
+ s.add_development_dependency("rack-test")
27
+ s.add_development_dependency("flexmock")
28
+ s.add_development_dependency("rvm")
29
+ s.add_development_dependency("rake", "0.8.7")
30
+ s.add_development_dependency("bundler")
31
+ s.add_development_dependency("guard")
32
+ s.add_development_dependency("guard-test")
33
+ end
34
+