altria 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +41 -0
  3. data/LICENSE.txt +22 -0
  4. data/Procfile +4 -0
  5. data/README.md +40 -0
  6. data/Rakefile +6 -0
  7. data/altria.gemspec +50 -0
  8. data/app/assets/images/rails.png +0 -0
  9. data/app/assets/javascripts/altria.js.coffee +1 -0
  10. data/app/assets/javascripts/altria/build_view.js.coffee +13 -0
  11. data/app/assets/javascripts/altria/job_view.js.coffee +10 -0
  12. data/app/assets/javascripts/altria/server_event.js.coffee +8 -0
  13. data/app/assets/javascripts/application.js +20 -0
  14. data/app/assets/javascripts/events.js.coffee +13 -0
  15. data/app/assets/stylesheets/application.css +14 -0
  16. data/app/assets/stylesheets/builds.scss +35 -0
  17. data/app/assets/stylesheets/common.scss +69 -0
  18. data/app/assets/stylesheets/jobs.scss +129 -0
  19. data/app/assets/stylesheets/layout.scss +19 -0
  20. data/app/assets/stylesheets/mixin.scss +26 -0
  21. data/app/controllers/application_controller.rb +24 -0
  22. data/app/controllers/builds_controller.rb +48 -0
  23. data/app/controllers/events_controller.rb +27 -0
  24. data/app/controllers/jobs_controller.rb +50 -0
  25. data/app/helpers/application_helper.rb +5 -0
  26. data/app/models/build.rb +72 -0
  27. data/app/models/job.rb +141 -0
  28. data/app/views/builds/show.html.slim +36 -0
  29. data/app/views/jobs/_form.html.slim +22 -0
  30. data/app/views/jobs/edit.html.slim +9 -0
  31. data/app/views/jobs/index.html.slim +19 -0
  32. data/app/views/jobs/new.html.slim +7 -0
  33. data/app/views/jobs/show.html.slim +28 -0
  34. data/app/views/layouts/application.html.slim +11 -0
  35. data/app/workers/build_worker.rb +13 -0
  36. data/app/workers/job_enqueue_worker.rb +13 -0
  37. data/bin/altria +6 -0
  38. data/config.ru +4 -0
  39. data/config/application.rb +52 -0
  40. data/config/boot.rb +6 -0
  41. data/config/database.yml +29 -0
  42. data/config/environment.rb +5 -0
  43. data/config/environments/development.rb +23 -0
  44. data/config/environments/production.rb +71 -0
  45. data/config/environments/test.rb +33 -0
  46. data/config/initializers/backtrace_silencers.rb +7 -0
  47. data/config/initializers/inflections.rb +15 -0
  48. data/config/initializers/mime_types.rb +5 -0
  49. data/config/initializers/redis.rb +1 -0
  50. data/config/initializers/secret_token.rb +8 -0
  51. data/config/initializers/session_store.rb +8 -0
  52. data/config/initializers/wrap_parameters.rb +14 -0
  53. data/config/locales/en.yml +5 -0
  54. data/config/routes.rb +9 -0
  55. data/db/migrate/20130531143239_create_jobs.rb +10 -0
  56. data/db/migrate/20130531155155_create_builds.rb +14 -0
  57. data/db/migrate/20130608153135_change_job_column_name_from_config_to_properties.rb +9 -0
  58. data/db/migrate/20130608153655_add_column_properties_to_builds.rb +5 -0
  59. data/db/schema.rb +36 -0
  60. data/db/seeds.rb +7 -0
  61. data/lib/altria.rb +13 -0
  62. data/lib/altria/command.rb +61 -0
  63. data/lib/altria/configuration.rb +9 -0
  64. data/lib/altria/executer.rb +37 -0
  65. data/lib/altria/proprietary.rb +56 -0
  66. data/lib/altria/responder.rb +12 -0
  67. data/lib/altria/scheduler.rb +55 -0
  68. data/lib/altria/version.rb +3 -0
  69. data/lib/altria/workspace.rb +26 -0
  70. data/lib/tasks/resque.rake +3 -0
  71. data/public/404.html +26 -0
  72. data/public/422.html +26 -0
  73. data/public/500.html +25 -0
  74. data/public/favicon.ico +0 -0
  75. data/public/robots.txt +5 -0
  76. data/script/clock.rb +5 -0
  77. data/script/rails +6 -0
  78. data/spec/altria/command_spec.rb +53 -0
  79. data/spec/factories/build.rb +7 -0
  80. data/spec/factories/job.rb +7 -0
  81. data/spec/models/build_spec.rb +35 -0
  82. data/spec/models/job_spec.rb +101 -0
  83. data/spec/requests/builds_spec.rb +81 -0
  84. data/spec/requests/jobs_spec.rb +88 -0
  85. data/spec/spec_helper.rb +48 -0
  86. metadata +417 -0
data/public/500.html ADDED
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ </div>
24
+ </body>
25
+ </html>
File without changes
data/public/robots.txt ADDED
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
data/script/clock.rb ADDED
@@ -0,0 +1,5 @@
1
+ require File.expand_path("../../config/environment.rb", __FILE__)
2
+
3
+ Clockwork.every(1.minute, "JobEnqueueWorker") do
4
+ Job.scheduled.each(&:enqueue)
5
+ end
data/script/rails ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe Altria::Command do
4
+ let(:command) do
5
+ described_class.new(arguments)
6
+ end
7
+
8
+ describe ".call" do
9
+ it "delegates to #call" do
10
+ described_class.any_instance.should_receive(:call)
11
+ described_class.call(["setup"])
12
+ end
13
+ end
14
+
15
+ describe "#call" do
16
+ let(:env) do
17
+ { "WORKSPACE_PATH" => Dir.pwd }
18
+ end
19
+
20
+ context "with `setup`" do
21
+ let(:arguments) do
22
+ ["setup"]
23
+ end
24
+
25
+ it "executes setup script" do
26
+ command.should_receive(:system).with(env, "cd #{Dir.pwd} && bundle install && bundle exec rake db:create db:migrate")
27
+ command.call
28
+ end
29
+ end
30
+
31
+ context "with `start`" do
32
+ let(:arguments) do
33
+ ["start"]
34
+ end
35
+
36
+ it "executes start script" do
37
+ command.should_receive(:system).with(env, "cd #{Dir.pwd} && bundle exec foreman start")
38
+ command.call
39
+ end
40
+ end
41
+
42
+ context "with unknown arguments" do
43
+ let(:arguments) do
44
+ []
45
+ end
46
+
47
+ it "shows usage" do
48
+ command.should_receive(:puts).with("Usage: altria {setup|start}")
49
+ command.call
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+ require "factory_girl"
2
+
3
+ FactoryGirl.define do
4
+ factory(:build) do
5
+ job { FactoryGirl.create(:job) }
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "factory_girl"
2
+
3
+ FactoryGirl.define do
4
+ factory(:job) do
5
+ sequence(:name) {|n| "name #{n}" }
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe Build do
4
+ let(:build) do
5
+ FactoryGirl.create(:build, job: job)
6
+ end
7
+
8
+ let(:job) do
9
+ FactoryGirl.create(:job, properties: { "script" => "true" })
10
+ end
11
+
12
+ describe "#run" do
13
+ context "with success" do
14
+ it "runs its job and sets status with true" do
15
+ build.run
16
+ build.started_at.should be_present
17
+ build.finished_at.should be_present
18
+ build.status.should == true
19
+ end
20
+ end
21
+
22
+ context "with failure" do
23
+ before do
24
+ build.job.script = "false"
25
+ end
26
+
27
+ it "runs its job and sets status with false" do
28
+ build.run
29
+ build.started_at.should be_present
30
+ build.finished_at.should be_present
31
+ build.status.should == false
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,101 @@
1
+ require "spec_helper"
2
+
3
+ describe Job do
4
+ let(:job) do
5
+ FactoryGirl.create(:job, properties: { "script" => "true" })
6
+ end
7
+
8
+ describe "#run" do
9
+ context "without script" do
10
+ before do
11
+ job.script = nil
12
+ end
13
+
14
+ it "raises Job::ScriptNotFound" do
15
+ expect { job.run }.to raise_error(Job::ScriptNotFound)
16
+ end
17
+ end
18
+
19
+ context "with script" do
20
+ before do
21
+ job.script = "true"
22
+ end
23
+
24
+ it "runs its job" do
25
+ Altria::Executer.should_receive(:execute).with("true")
26
+ job.run
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#scheduled?" do
32
+ context "without schedule" do
33
+ it "returns false" do
34
+ job.should_not be_scheduled
35
+ end
36
+ end
37
+
38
+ context "with empty schedule" do
39
+ before do
40
+ job.schedule = ""
41
+ end
42
+
43
+ it "returns false" do
44
+ job.should_not be_scheduled
45
+ end
46
+ end
47
+
48
+ context "with matched schedule" do
49
+ before do
50
+ job.schedule = "* * * * *"
51
+ end
52
+
53
+ it "returns true" do
54
+ job.should be_scheduled
55
+ end
56
+ end
57
+
58
+ context "without matched schedule" do
59
+ before do
60
+ job.schedule = "0 0 0 0 0"
61
+ end
62
+
63
+ it "returns false" do
64
+ job.should_not be_scheduled
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#enqueue_with_before_enqueues" do
70
+ before do
71
+ Job.before_enqueues.clear
72
+ end
73
+
74
+ after do
75
+ Job.before_enqueues.clear
76
+ end
77
+
78
+ context "with successful hooks" do
79
+ before do
80
+ Job.before_enqueue { Job.hook_is_executed }
81
+ end
82
+
83
+ it "enqueues a new build" do
84
+ Job.should_receive(:hook_is_executed)
85
+ job.enqueue_with_before_enqueues
86
+ end
87
+ end
88
+
89
+ context "with failed hooks" do
90
+ before do
91
+ Job.before_enqueue { false }
92
+ Job.before_enqueue { Job.hook_is_executed }
93
+ end
94
+
95
+ it "stops at failed hook" do
96
+ Job.should_not_receive(:hook_is_executed)
97
+ job.enqueue_with_before_enqueues
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,81 @@
1
+ require "spec_helper"
2
+
3
+ describe "Builds" do
4
+ let(:params) do
5
+ {}
6
+ end
7
+
8
+ let(:env) do
9
+ { "HTTP_ACCEPT" => "application/json" }
10
+ end
11
+
12
+ let(:job) do
13
+ FactoryGirl.create(:job, properties: { "script" => "true" })
14
+ end
15
+
16
+ let(:build) do
17
+ job.builds.create(id: 1)
18
+ end
19
+
20
+ describe "GET /jobs/:job_id/builds" do
21
+ before do
22
+ build
23
+ end
24
+
25
+ it "returns builds of the job", :autodoc do
26
+ get "/jobs/#{job.id}/builds", params, env
27
+ response.status.should == 200
28
+ response.body.should be_json([Hash])
29
+ end
30
+
31
+ context "with page" do
32
+ before do
33
+ params[:page] = 2
34
+ 10.times { job.builds.create }
35
+ end
36
+
37
+ it "paginates builds" do
38
+ get "/jobs/#{job.id}/builds", params, env
39
+ response.status.should == 200
40
+ response.body.should be_json([Hash])
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "GET /jobs/:job_id/builds/:id" do
46
+ it "returns the build", :autodoc do
47
+ get "/jobs/#{job.id}/builds/#{build.id}", params, env
48
+ response.status.should == 200
49
+ response.body.should be_json(Hash)
50
+ end
51
+ end
52
+
53
+ describe "POST /jobs/:job_id/builds" do
54
+ it "creates a new build and queue it", :autodoc do
55
+ post "/jobs/#{job.id}/builds", params, env
56
+ response.status.should == 201
57
+ response.body.should be_json(Hash)
58
+ job.builds.should have(1).builds
59
+ end
60
+ end
61
+
62
+ describe "PUT /jobs/:job_id/builds/:id" do
63
+ before do
64
+ params[:status] = 1
65
+ end
66
+
67
+ it "updates the build", :autodoc do
68
+ put "/jobs/#{job.id}/builds/#{build.id}", params, env
69
+ response.status.should == 204
70
+ build.reload.status.should == true
71
+ end
72
+ end
73
+
74
+ describe "DELETE /jobs/:job_id/builds/:id" do
75
+ it "deletes the build", :autodoc do
76
+ delete "/jobs/#{job.id}/builds/#{build.id}", params, env
77
+ response.status.should == 204
78
+ Build.should have(0).build
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,88 @@
1
+ require "spec_helper"
2
+
3
+ describe "Jobs" do
4
+ let(:params) do
5
+ {}
6
+ end
7
+
8
+ let(:env) do
9
+ { "HTTP_ACCEPT" => "application/json" }
10
+ end
11
+
12
+ let(:job) do
13
+ FactoryGirl.create(:job)
14
+ end
15
+
16
+ describe "GET /jobs" do
17
+ before do
18
+ job
19
+ end
20
+
21
+ it "returns jobs", :autodoc do
22
+ get "/jobs", params, env
23
+ response.status.should == 200
24
+ response.body.should be_json([Hash])
25
+ end
26
+ end
27
+
28
+ describe "GET /jobs/:id" do
29
+ it "returns the job", :autodoc do
30
+ get "/jobs/#{job.id}", params, env
31
+ response.status.should == 200
32
+ response.body.should be_json(Hash)
33
+ end
34
+ end
35
+
36
+ describe "POST /jobs" do
37
+ before do
38
+ params[:name] = "name"
39
+ params[:description] = "description"
40
+ end
41
+
42
+ context "with invalid params" do
43
+ before do
44
+ params.delete(:name)
45
+ end
46
+
47
+ it "returns 400" do
48
+ post "/jobs", params, env
49
+ response.status.should == 400
50
+ end
51
+ end
52
+
53
+ context "with valid condition" do
54
+ it "creates a new job", :autodoc do
55
+ post "/jobs", params, env
56
+ response.status.should == 201
57
+ job = Job.first
58
+ job.name.should == "name"
59
+ job.description.should == "description"
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "PUT /jobs/:id" do
65
+ before do
66
+ params[:name] = "name"
67
+ params[:description] = "description"
68
+ end
69
+
70
+ context "with valid condition" do
71
+ it "updates the job", :autodoc do
72
+ put "/jobs/#{job.id}", params, env
73
+ response.status.should == 204
74
+ job.reload
75
+ job.name.should == "name"
76
+ job.description.should == "description"
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "DELETE /jobs/:id" do
82
+ it "deletes the job" do
83
+ delete "/jobs/#{job.id}", params, env
84
+ response.status.should == 204
85
+ Job.should_not be_exist(job.id)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,48 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+ Coveralls.wear!
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter,
7
+ ]
8
+ SimpleCov.start
9
+
10
+ ENV["RAILS_ENV"] ||= "test"
11
+ require File.expand_path("../../config/environment", __FILE__)
12
+ require "rspec/rails"
13
+ require "rspec/autorun"
14
+
15
+ RSpec.configure do |config|
16
+ # If you"re not using ActiveRecord, or you"d prefer not to run each of your
17
+ # examples within a transaction, remove the following line or assign false
18
+ # instead of true.
19
+ config.use_transactional_fixtures = true
20
+
21
+ # If true, the base class of anonymous controllers will be inferred
22
+ # automatically. This will be the default behavior in future versions of
23
+ # rspec-rails.
24
+ config.infer_base_class_for_anonymous_controllers = false
25
+
26
+ # Enables :focus metadata filter.
27
+ config.filter_run :focus
28
+ config.run_all_when_everything_filtered = true
29
+ config.treat_symbols_as_metadata_keys_with_true_values = true
30
+
31
+ config.include RSpec::JsonMatcher, type: :request
32
+ config.include ResponseCodeMatchers, type: :request
33
+
34
+ config.before(:suite) do
35
+ Altria.configuration.workspace_path = Rails.root.join("tmp/workspace")
36
+ end
37
+
38
+ config.after(:suite) do
39
+ workspace = Rails.root.join("tmp/workspace")
40
+ workspace.rmtree if workspace.exist?
41
+ end
42
+
43
+ config.before do
44
+ $redis.stub(:publish)
45
+ end
46
+ end
47
+
48
+ Resque.inline = true