deep_thought 0.1.0

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +184 -0
  5. data/Rakefile +50 -0
  6. data/config.ru +5 -0
  7. data/db/migrate/20130414012805_create_projects.rb +15 -0
  8. data/db/migrate/20130426165010_create_states.rb +14 -0
  9. data/db/migrate/20130501003758_create_users.rb +14 -0
  10. data/db/migrate/20130508001711_add_api_key_to_users.rb +9 -0
  11. data/db/migrate/20130509014935_create_deploys.rb +27 -0
  12. data/db/migrate/20130514062148_create_delayed_jobs.rb +21 -0
  13. data/db/migrate/20130516042149_change_delayed_job_last_error_to_text.rb +9 -0
  14. data/db/migrate/20130517010210_add_ci_to_projects.rb +9 -0
  15. data/db/migrate/20130525001332_add_notification_url_to_users.rb +9 -0
  16. data/db/migrate/20131127022704_remove_deploy_type_and_ci_from_projects.rb +11 -0
  17. data/db/schema.rb +72 -0
  18. data/deep_thought.gemspec +45 -0
  19. data/lib/deep_thought.rb +62 -0
  20. data/lib/deep_thought/api.rb +156 -0
  21. data/lib/deep_thought/app.rb +342 -0
  22. data/lib/deep_thought/ci_service.rb +39 -0
  23. data/lib/deep_thought/ci_service/janky.rb +34 -0
  24. data/lib/deep_thought/deployer.rb +180 -0
  25. data/lib/deep_thought/deployer/deployer.rb +17 -0
  26. data/lib/deep_thought/deployer/shell.rb +45 -0
  27. data/lib/deep_thought/git.rb +76 -0
  28. data/lib/deep_thought/models/deploy.rb +27 -0
  29. data/lib/deep_thought/models/project.rb +32 -0
  30. data/lib/deep_thought/models/state.rb +6 -0
  31. data/lib/deep_thought/models/user.rb +45 -0
  32. data/lib/deep_thought/notifier.rb +13 -0
  33. data/lib/deep_thought/public/assets/javascripts/jquery.min.js +6 -0
  34. data/lib/deep_thought/public/assets/javascripts/main.js +36 -0
  35. data/lib/deep_thought/public/assets/stylesheets/main.css +438 -0
  36. data/lib/deep_thought/public/robots.txt +2 -0
  37. data/lib/deep_thought/scaler.rb +35 -0
  38. data/lib/deep_thought/tasks.rb +65 -0
  39. data/lib/deep_thought/version.rb +3 -0
  40. data/lib/deep_thought/views/history/index.haml +4 -0
  41. data/lib/deep_thought/views/history/show.haml +68 -0
  42. data/lib/deep_thought/views/layouts/layout.haml +32 -0
  43. data/lib/deep_thought/views/projects/edit.haml +15 -0
  44. data/lib/deep_thought/views/projects/index.haml +7 -0
  45. data/lib/deep_thought/views/projects/new.haml +8 -0
  46. data/lib/deep_thought/views/projects/show.haml +25 -0
  47. data/lib/deep_thought/views/sessions/login.haml +8 -0
  48. data/lib/deep_thought/views/users/index.haml +7 -0
  49. data/lib/deep_thought/views/users/new.haml +12 -0
  50. data/lib/deep_thought/views/users/show.haml +38 -0
  51. data/script/bootstrap +3 -0
  52. data/script/console +7 -0
  53. data/script/server +7 -0
  54. data/script/test +3 -0
  55. data/test/deep_thought_api_test.rb +114 -0
  56. data/test/deep_thought_app_test.rb +315 -0
  57. data/test/deep_thought_ci_service_test.rb +44 -0
  58. data/test/deep_thought_deployer_test.rb +72 -0
  59. data/test/deep_thought_git_test.rb +62 -0
  60. data/test/deep_thought_janky_test.rb +42 -0
  61. data/test/deep_thought_notifier_test.rb +35 -0
  62. data/test/deep_thought_project_test.rb +34 -0
  63. data/test/deep_thought_shell_test.rb +38 -0
  64. data/test/fixtures/project-test/HEAD +1 -0
  65. data/test/fixtures/project-test/config +8 -0
  66. data/test/fixtures/project-test/description +1 -0
  67. data/test/fixtures/project-test/hooks/applypatch-msg.sample +15 -0
  68. data/test/fixtures/project-test/hooks/commit-msg.sample +24 -0
  69. data/test/fixtures/project-test/hooks/post-update.sample +8 -0
  70. data/test/fixtures/project-test/hooks/pre-applypatch.sample +14 -0
  71. data/test/fixtures/project-test/hooks/pre-commit.sample +49 -0
  72. data/test/fixtures/project-test/hooks/pre-push.sample +54 -0
  73. data/test/fixtures/project-test/hooks/pre-rebase.sample +169 -0
  74. data/test/fixtures/project-test/hooks/prepare-commit-msg.sample +36 -0
  75. data/test/fixtures/project-test/hooks/update.sample +128 -0
  76. data/test/fixtures/project-test/info/exclude +6 -0
  77. data/test/fixtures/project-test/objects/13/8b8baba400e64fc384d468e80f10cf707e38d7 +1 -0
  78. data/test/fixtures/project-test/objects/6b/8fb16e1675767742afc70ac2ce038da46461f8 +0 -0
  79. data/test/fixtures/project-test/objects/7f/fc496d150b8a0015e3a16be8bacd47daed1a1c +0 -0
  80. data/test/fixtures/project-test/objects/8f/8606174a2aa11545d119fe3c4d6840fe0c4825 +0 -0
  81. data/test/fixtures/project-test/objects/9c/362942288a8ff6dc1addf7c5199bd9837e09de +0 -0
  82. data/test/fixtures/project-test/objects/b5/f7341de6145d3f8b95877cd2675d798fd172f1 +0 -0
  83. data/test/fixtures/project-test/objects/d1/f1e8664b0326316fb18796ac4ae1171e239cb6 +1 -0
  84. data/test/fixtures/project-test/objects/e6/d7ad6d61242936a2cd2bb9ae236adf43e59718 +0 -0
  85. data/test/fixtures/project-test/objects/fa/4cf5ff52462d17b6378a06fae8771c13b654b0 +1 -0
  86. data/test/fixtures/project-test/objects/fa/dda6bc20afa5cf93196bfb08a4989ee3b75ed7 +0 -0
  87. data/test/fixtures/project-test/packed-refs +4 -0
  88. data/test/fixtures/project-test/refs/heads/.gitkeep +0 -0
  89. data/test/fixtures/project-test/refs/tags/.gitkeep +0 -0
  90. data/test/test_helper.rb +42 -0
  91. metadata +462 -0
@@ -0,0 +1,315 @@
1
+ require File.expand_path '../test_helper.rb', __FILE__
2
+
3
+ class DeepThoughtAppTest < MiniTest::Unit::TestCase
4
+ include Rack::Test::Methods
5
+ include Capybara::DSL
6
+
7
+ def setup
8
+ DatabaseCleaner.start
9
+
10
+ @deployer = mock('class')
11
+ @deployer.stubs(:new).returns(@deployer)
12
+ @deployer.stubs(:setup)
13
+ @deployer.stubs(:execute).returns(true)
14
+ DeepThought::Deployer.register_adapter('mock', @deployer)
15
+
16
+ @user_email = 'test@test.com'
17
+ @user_password = 'secret'
18
+ @user = DeepThought::User.create(:email => @user_email, :password => @user_password, :password_confirmation => @user_password)
19
+ end
20
+
21
+ def teardown
22
+ Capybara.reset_sessions!
23
+ Capybara.use_default_driver
24
+
25
+ if File.directory?(".projects/_test")
26
+ FileUtils.rm_rf(".projects/_test")
27
+ end
28
+
29
+ DatabaseCleaner.clean
30
+ end
31
+
32
+ def app
33
+ DeepThought.app
34
+ end
35
+
36
+ def test_app_root_logged_out
37
+ get '/'
38
+ follow_redirect!
39
+ assert last_response.ok?
40
+ assert_equal "http://example.org/login", last_request.url
41
+ end
42
+
43
+ def test_app_root_logged_in
44
+ login(@user_email, @user_password)
45
+
46
+ assert_equal 200, page.status_code
47
+ assert_equal "http://www.example.com/", page.current_url
48
+ end
49
+
50
+ def test_app_logout
51
+ login(@user_email, @user_password)
52
+
53
+ assert_equal 200, page.status_code
54
+ assert_equal "http://www.example.com/", page.current_url
55
+
56
+ logout
57
+
58
+ visit '/'
59
+ assert_equal 200, page.status_code
60
+ assert_equal "http://www.example.com/login", page.current_url
61
+ end
62
+
63
+ def test_app_user_generate_api_key
64
+ login(@user_email, @user_password)
65
+
66
+ visit "/users/#{@user.id}"
67
+ assert_equal "http://www.example.com/users/#{@user.id}", page.current_url
68
+ assert page.has_content?('no api key (yet)')
69
+
70
+ DeepThought::User.any_instance.expects(:generate_api_key)
71
+
72
+ @user.api_key = '12345'
73
+ @user.save!
74
+
75
+ within(".user-api-key") do
76
+ click_button 'generate new api key'
77
+ end
78
+
79
+ assert_equal "http://www.example.com/users/#{@user.id}", page.current_url
80
+ assert page.has_content?('12345')
81
+
82
+ logout
83
+
84
+ login(@user_email, @user_password)
85
+
86
+ assert_equal 200, page.status_code
87
+ assert_equal "http://www.example.com/", page.current_url
88
+ end
89
+
90
+ def test_app_add_user
91
+ login(@user_email, @user_password)
92
+
93
+ visit "/users/new"
94
+ within(".content > form") do
95
+ fill_in 'email', :with => 'new@user.email'
96
+ fill_in 'password', :with => 'secret'
97
+ fill_in 'password_confirmation', :with => 'secret'
98
+ click_button 'create user'
99
+ end
100
+
101
+ assert_equal "http://www.example.com/users", page.current_url
102
+ assert page.has_content?('new@user.email')
103
+ end
104
+
105
+ def test_app_delete_user
106
+ login(@user_email, @user_password)
107
+
108
+ visit "/users/new"
109
+ within(".content > form") do
110
+ fill_in 'email', :with => 'new@user.email'
111
+ fill_in 'password', :with => 'secret'
112
+ fill_in 'password_confirmation', :with => 'secret'
113
+ click_button 'create user'
114
+ end
115
+
116
+ assert page.has_content?('new@user.email')
117
+
118
+ within(".list") do
119
+ click_link 'new@user.email'
120
+ end
121
+
122
+ click_button 'delete user'
123
+
124
+ assert_equal "http://www.example.com/users", page.current_url
125
+ assert !page.has_content?('new@user.email')
126
+ end
127
+
128
+ def test_app_user_update_email
129
+ login(@user_email, @user_password)
130
+
131
+ within("nav") do
132
+ click_link "me"
133
+ end
134
+
135
+ within(".user-info > form") do
136
+ fill_in 'email', :with => 'new@user.email'
137
+ click_button 'update'
138
+ end
139
+
140
+ assert page.has_content?('new@user.email')
141
+
142
+ logout
143
+
144
+ login('new@user.email', @user_password)
145
+
146
+ assert_equal "http://www.example.com/", page.current_url
147
+ end
148
+
149
+ def test_app_project_branches
150
+ project = DeepThought::Project.create(:name => '_test', :repo_url => './test/fixtures/project-test')
151
+
152
+ login(@user_email, @user_password)
153
+
154
+ within(".list") do
155
+ click_link '_test'
156
+ end
157
+
158
+ assert page.has_select?('deploy[branch]', :options => ['master', 'mock', 'no-config'])
159
+ end
160
+
161
+ def test_app_project_deploy_no_attributes
162
+ DeepThought::Notifier.stubs(:notify)
163
+
164
+ project = DeepThought::Project.create(:name => '_test', :repo_url => './test/fixtures/project-test')
165
+
166
+ assert_equal 0, DeepThought::Deploy.count
167
+
168
+ login(@user_email, @user_password)
169
+
170
+ within(".list") do
171
+ click_link '_test'
172
+ end
173
+
174
+ within(".deploy > form") do
175
+ click_button 'deploy'
176
+ end
177
+
178
+ assert_equal 1, DeepThought::Deploy.count
179
+
180
+ deploy = DeepThought::Deploy.all[0]
181
+
182
+ assert_equal 'master', deploy.branch
183
+ assert_nil deploy.environment
184
+ assert_nil deploy.box
185
+ assert_nil deploy.actions
186
+ assert_nil deploy.variables
187
+ assert_equal 'web', deploy.via
188
+ end
189
+
190
+ def test_app_project_deploy_with_attributes
191
+ DeepThought::Notifier.stubs(:notify)
192
+
193
+ project = DeepThought::Project.create(:name => '_test', :repo_url => './test/fixtures/project-test')
194
+
195
+ assert_equal 0, DeepThought::Deploy.count
196
+
197
+ login(@user_email, @user_password)
198
+
199
+ within(".list") do
200
+ click_link '_test'
201
+ end
202
+
203
+ within(".deploy > form") do
204
+ select('mock', :from => 'deploy[branch]')
205
+ fill_in 'environment', :with => 'development'
206
+ fill_in 'box', :with => 'dev1'
207
+ # TODO: Test actions and variables (need to integrate JavaScript into testing)
208
+ click_button 'deploy'
209
+ end
210
+
211
+ assert_equal 1, DeepThought::Deploy.count
212
+
213
+ deploy = DeepThought::Deploy.all[0]
214
+
215
+ assert_equal 'mock', deploy.branch
216
+ assert_equal 'development', deploy.environment
217
+ assert_equal 'dev1', deploy.box
218
+ assert_nil deploy.actions
219
+ assert_nil deploy.variables
220
+ assert_equal 'web', deploy.via
221
+ end
222
+
223
+ def test_app_project_history
224
+ DeepThought::Notifier.stubs(:notify)
225
+
226
+ project = DeepThought::Project.create(:name => '_test', :repo_url => './test/fixtures/project-test')
227
+
228
+ login(@user_email, @user_password)
229
+
230
+ visit '/projects/_test'
231
+
232
+ click_link 'history...'
233
+
234
+ assert !page.has_content?("deploy master by #{@user_email}")
235
+
236
+ deploy = DeepThought::Deploy.new(:project_id => project.id, :user_id => @user.id, :branch => 'master', :commit => '12345')
237
+
238
+ deploy.save
239
+
240
+ visit '/projects/_test/deploys'
241
+
242
+ assert page.has_content?("deploy master by #{@user_email}")
243
+ end
244
+
245
+ def test_app_add_project
246
+ login(@user_email, @user_password)
247
+
248
+ visit "/projects/add/new"
249
+ within(".content > form") do
250
+ fill_in 'name', :with => '_test'
251
+ fill_in 'repo', :with => './test/fixtures/project-test'
252
+ click_button 'create project'
253
+ end
254
+
255
+ assert_equal "http://www.example.com/", page.current_url
256
+ assert page.has_content?('_test')
257
+
258
+ visit "/projects/edit/_test"
259
+
260
+ assert_equal '_test', find_field('name').value
261
+ assert_equal './test/fixtures/project-test', find_field('repo').value
262
+ end
263
+
264
+ def test_app_edit_project
265
+ login(@user_email, @user_password)
266
+
267
+ visit "/projects/add/new"
268
+ within(".content > form") do
269
+ fill_in 'name', :with => '_test'
270
+ fill_in 'repo', :with => './test/fixtures/project-test'
271
+ click_button 'create project'
272
+ end
273
+
274
+ assert page.has_content?('_test')
275
+
276
+ visit "/projects/edit/_test"
277
+ within(".content > form") do
278
+ fill_in 'name', :with => '_test'
279
+ fill_in 'repo', :with => './test/fixtures/project-test'
280
+ click_button 'update project'
281
+ end
282
+
283
+ assert_equal "http://www.example.com/projects/_test", page.current_url
284
+ assert page.has_content?('Now pondering: _test')
285
+
286
+ visit "/projects/edit/_test"
287
+
288
+ assert_equal '_test', find_field('name').value
289
+ assert_equal './test/fixtures/project-test', find_field('repo').value
290
+ end
291
+
292
+ def test_app_delete_project
293
+ login(@user_email, @user_password)
294
+
295
+ visit "/projects/add/new"
296
+ within(".content > form") do
297
+ fill_in 'name', :with => '_test'
298
+ fill_in 'repo', :with => './test/fixtures/project-test'
299
+ click_button 'create project'
300
+ end
301
+
302
+ assert page.has_content?('_test')
303
+
304
+ within(".list") do
305
+ click_link '_test'
306
+ end
307
+
308
+ click_link 'edit...'
309
+
310
+ click_button 'delete project'
311
+
312
+ assert_equal "http://www.example.com/", page.current_url
313
+ assert !page.has_content?('_test')
314
+ end
315
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path '../test_helper.rb', __FILE__
2
+
3
+ class DeepThoughtCIServiceTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ DatabaseCleaner.start
6
+
7
+ DeepThought::CIService.adapters = {}
8
+ DeepThought::CIService.ci_service = nil
9
+ end
10
+
11
+ def teardown
12
+ DatabaseCleaner.clean
13
+ end
14
+
15
+ def test_no_ci_service
16
+ DeepThought::CIService.setup({})
17
+
18
+ assert !DeepThought::CIService.ci_service
19
+ end
20
+
21
+ def test_ci_service_not_found
22
+ assert_raises(DeepThought::CIService::CIServiceNotFoundError) { DeepThought::CIService.setup({"CI_SERVICE" => "no-service"}) }
23
+ end
24
+
25
+ def test_ci_service_is_branch_green_success
26
+ ci_service = mock('class')
27
+ ci_service.expects(:new).returns(ci_service)
28
+ ci_service.expects(:setup).with({"CI_SERVICE" => "mock"})
29
+ ci_service.expects(:is_branch_green?).with('app', 'master', 'hash').returns(true)
30
+ DeepThought::CIService.register_adapter('mock', ci_service)
31
+ DeepThought::CIService.setup({"CI_SERVICE" => "mock"})
32
+ assert DeepThought::CIService.is_branch_green?('app', 'master', 'hash')
33
+ end
34
+
35
+ def test_ci_service_is_branch_green_failed
36
+ ci_service = mock('class')
37
+ ci_service.expects(:new).returns(ci_service)
38
+ ci_service.expects(:setup).with({"CI_SERVICE" => "mock"})
39
+ ci_service.expects(:is_branch_green?).with('app', 'master', 'hash').returns(false)
40
+ DeepThought::CIService.register_adapter('mock', ci_service)
41
+ DeepThought::CIService.setup({"CI_SERVICE" => "mock"})
42
+ assert !DeepThought::CIService.is_branch_green?('app', 'master', 'hash')
43
+ end
44
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path '../test_helper.rb', __FILE__
2
+
3
+ class DeepThoughtDeployerTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ DatabaseCleaner.start
6
+
7
+ DeepThought::Deployer.adapters = {}
8
+
9
+ @deployer = mock('class')
10
+ @deployer.stubs(:new).returns(@deployer)
11
+ @deployer.stubs(:setup)
12
+ DeepThought::Deployer.register_adapter('mock', @deployer)
13
+
14
+ @project = DeepThought::Project.create(:name => '_test', :repo_url => './test/fixtures/project-test')
15
+ @user = DeepThought::User.create(:email => 'test@test.com', :password => 'secret', :password_confirmation => 'secret')
16
+ @deploy = DeepThought::Deploy.new(:project_id => @project.id, :user_id => @user.id, :branch => 'master', :commit => '12345')
17
+ end
18
+
19
+ def teardown
20
+ DatabaseCleaner.clean
21
+ end
22
+
23
+ def test_config_not_found
24
+ @deploy.branch = 'no-config'
25
+ assert_raises(DeepThought::ProjectConfigNotFoundError) { @deploy.save }
26
+ end
27
+
28
+ def test_deployer_not_found
29
+ DeepThought::Deployer.adapters = {}
30
+ @deploy.branch = 'mock'
31
+ assert_raises(DeepThought::Deployer::DeployerNotFoundError) { @deploy.save }
32
+ end
33
+
34
+ def test_deployer_execute_success
35
+ @deploy.branch = 'mock'
36
+
37
+ DeepThought::Notifier.stubs(:notify)
38
+ @deployer.expects(:execute).with(@deploy, {'deploy_type' => 'mock'}).returns(true)
39
+
40
+ assert !@deploy.started_at
41
+ assert !@deploy.finished_at
42
+ assert !@deploy.was_successful
43
+
44
+ assert @deploy.save
45
+ assert @deploy.started_at
46
+ assert @deploy.finished_at
47
+ assert @deploy.was_successful
48
+ end
49
+
50
+ def test_deployer_execute_failed
51
+ @deploy.branch = 'mock'
52
+
53
+ DeepThought::Notifier.stubs(:notify)
54
+ @deployer.expects(:execute).with(@deploy, {'deploy_type' => 'mock'}).returns(false)
55
+
56
+ assert !@deploy.started_at
57
+ assert !@deploy.finished_at
58
+ assert !@deploy.was_successful
59
+
60
+ assert_raises(DeepThought::Deployer::DeploymentFailedError) { @deploy.save }
61
+
62
+ assert @deploy.started_at
63
+ assert @deploy.finished_at
64
+ assert !@deploy.was_successful
65
+ end
66
+
67
+ def test_deployer_lock
68
+ DeepThought::Deployer.lock_deployer
69
+ @deployer.stubs(:execute).with(@deploy).returns(true)
70
+ assert_raises(DeepThought::Deployer::DeploymentInProgressError) { @deploy.save }
71
+ end
72
+ end
@@ -0,0 +1,62 @@
1
+ require File.expand_path '../test_helper.rb', __FILE__
2
+
3
+ class DeepThoughtGitTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ DatabaseCleaner.start
6
+
7
+ if File.directory?(".projects/_test")
8
+ FileUtils.rm_rf(".projects/_test")
9
+ end
10
+
11
+ deployer = mock('class')
12
+ deployer.stubs(:new).returns(deployer)
13
+ deployer.stubs(:setup)
14
+ DeepThought::Deployer.register_adapter('mock', deployer)
15
+
16
+ @project = DeepThought::Project.new(:name => '_test', :repo_url => './test/fixtures/project-test')
17
+ end
18
+
19
+ def teardown
20
+ if File.directory?(".projects/_test")
21
+ FileUtils.rm_rf(".projects/_test")
22
+ end
23
+
24
+ DatabaseCleaner.clean
25
+ end
26
+
27
+ def test_git_setup_failed
28
+ @project.repo_url = 'http://fake.url'
29
+ @project.save
30
+ # assert !@project.id
31
+ assert !DeepThought::Git.setup(@project)
32
+ end
33
+
34
+ def test_git_setup_success
35
+ assert @project.save!
36
+ end
37
+
38
+ def test_git_get_latest_commit_for_branch_success
39
+ @project.save!
40
+ assert_kind_of String, DeepThought::Git.get_latest_commit_for_branch(@project, 'master')
41
+ end
42
+
43
+ def test_git_get_latest_commit_for_branch_failed
44
+ @project.save!
45
+ assert_raises(DeepThought::Git::GitBranchNotFoundError) { DeepThought::Git.switch_to_branch(@project, 'no-branch') }
46
+ end
47
+
48
+ def test_git_switch_to_branch_success
49
+ @project.save!
50
+ assert DeepThought::Git.switch_to_branch(@project, 'master')
51
+ end
52
+
53
+ def test_git_switch_to_branch_failed
54
+ @project.save!
55
+ assert_raises(DeepThought::Git::GitBranchNotFoundError) { DeepThought::Git.switch_to_branch(@project, 'no-branch') }
56
+ end
57
+
58
+ def test_git_get_list_of_branches
59
+ @project.save!
60
+ assert_equal ['master', 'mock', 'no-config'], DeepThought::Git.get_list_of_branches(@project)
61
+ end
62
+ end