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,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
+