chicanery 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,32 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chicanery (0.1.0)
4
+ chicanery (0.1.1)
5
5
  nokogiri (~> 1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- diff-lcs (1.1.3)
10
+ diff-lcs (1.2.1)
11
11
  fakeweb (1.3.0)
12
- multi_json (1.3.7)
12
+ multi_json (1.6.1)
13
13
  nokogiri (1.5.6)
14
- rake (0.9.2.2)
15
- rspec (2.11.0)
16
- rspec-core (~> 2.11.0)
17
- rspec-expectations (~> 2.11.0)
18
- rspec-mocks (~> 2.11.0)
19
- rspec-core (2.11.1)
20
- rspec-expectations (2.11.3)
21
- diff-lcs (~> 1.1.3)
22
- rspec-mocks (2.11.3)
14
+ rake (0.9.6)
15
+ rspec (2.13.0)
16
+ rspec-core (~> 2.13.0)
17
+ rspec-expectations (~> 2.13.0)
18
+ rspec-mocks (~> 2.13.0)
19
+ rspec-core (2.13.0)
20
+ rspec-expectations (2.13.0)
21
+ diff-lcs (>= 1.1.3, < 2.0)
22
+ rspec-mocks (2.13.0)
23
23
  simplecov (0.7.1)
24
24
  multi_json (~> 1.0)
25
25
  simplecov-html (~> 0.7.1)
26
26
  simplecov-gem-adapter (1.0.1)
27
27
  simplecov
28
28
  simplecov-html (0.7.1)
29
- vcr (2.3.0)
29
+ vcr (2.4.0)
30
30
 
31
31
  PLATFORMS
32
32
  ruby
data/README.md CHANGED
@@ -16,18 +16,18 @@ State is persisted between executions so that it be scheduled to run regularly w
16
16
 
17
17
  Create a configuration file. This file is just a ruby file that can make use of a few configuration and callback methods:
18
18
 
19
- require 'chicanery/cctray'
20
19
  require 'chicanery/git'
21
-
22
20
  include Chicanery::Git
23
-
24
- git_repo 'chicanery', '/tmp/chicanery', remotes: {
21
+ git 'chicanery', '.', branches: [:master], remotes: {
25
22
  github: { url: 'git://github.com/markryall/chicanery.git' }
26
23
  }
27
- server Chicanery::Cctray.new 'tddium', 'https://cihost.com/cctray.xml'
24
+
25
+ require 'chicanery/cctray'
26
+ include Chicanery::Cctray
27
+ cctray 'tddium', 'https://cihost.com/cctray.xml'
28
28
 
29
29
  when_run do |state|
30
- puts 'checked state'
30
+ puts state.has_failure? ? "something is wrong" : "all builds are fine"
31
31
  end
32
32
 
33
33
  when_commit do |repo, commit, previous|
@@ -66,6 +66,39 @@ If you want to specify an alternate location for this state file, add the follow
66
66
 
67
67
  persist_state_to '/tmp/build_state'
68
68
 
69
+ # Callbacks
70
+
71
+ ## General
72
+
73
+ The 'when_run' callback is executed on every poll.
74
+
75
+ ## Servers
76
+
77
+ The following callbacks may be received after checking a CI server:
78
+
79
+ * when_started - when a new job has started
80
+ * when_succeeded - when a job finishes successfully
81
+ * when_failed - when a job finishes unsuccessfully
82
+ * when_broken - when a previously passing job fails
83
+ * when_fixed - when a previously failing job passes
84
+
85
+ ## Repos
86
+
87
+ The following callbacks may be received after checking a source repository:
88
+
89
+ * when_commit - when a new commit is detected in the repository
90
+
91
+ Currently only git repositories are supported.
92
+
93
+ ## Site
94
+
95
+ The following callbacks may be received after checking a web site:
96
+
97
+ * when_up - the website responded with a 2xx HTTP status
98
+ * when_down - the website did not responded with a 2xx HTTP status
99
+ * when_crashed - the website was previously up and is now down
100
+ * when_recovered - the website was previously down and is now up
101
+
69
102
  ## Supported CI servers
70
103
 
71
104
  Currently only ci servers that can provide [cctray reporting format](http://confluence.public.thoughtworks.org/display/CI/Multiple+Project+Summary+Reporting+Standard) are supported.
@@ -88,7 +121,6 @@ Basic authentication is supported by passing :user => 'user', :password => 'pass
88
121
  * monitoring a subversion repository for commit notifications
89
122
  * monitoring heroku for deployment event notification
90
123
  * monitoring more ci servers (atlassian bamboo, jetbrains team city, etc.)
91
- * integration with the blinky gem to control a delcom build light
92
124
  * other interesting notifier plugins or examples
93
125
 
94
126
  ## Contributing
@@ -97,4 +129,4 @@ Basic authentication is supported by passing :user => 'user', :password => 'pass
97
129
  2. Create your feature branch (`git checkout -b my-new-feature`)
98
130
  3. Commit your changes (`git commit -am 'Add some feature'`)
99
131
  4. Push to the branch (`git push origin my-new-feature`)
100
- 5. Create new Pull Request
132
+ 5. Create new Pull Request
@@ -10,6 +10,8 @@ git 'chicanery', '.', branches: [:master], remotes: {
10
10
 
11
11
  cctray 'travis', 'https://api.travis-ci.org/repositories/markryall/chicanery/cc.xml'
12
12
 
13
+ site 'travis', 'https://api.travis-ci.org/repositories/markryall/chicanery.json'
14
+
13
15
  poll_period 10
14
16
 
15
17
  def growlnotify message
@@ -18,6 +20,7 @@ end
18
20
 
19
21
  when_run do |state|
20
22
  puts state.has_failure? ? "something is wrong" : "all builds are fine"
23
+ puts state.site_down? ? "something is wrong" : "all sites are fine"
21
24
  end
22
25
 
23
26
  when_commit do |repo, commit, previous|
@@ -45,4 +48,16 @@ end
45
48
  when_fixed do |job_name, job|
46
49
  growlnotify "job #{job_name} is fixed"
47
50
  `afplay ~/build_sounds/applause.mp3`
51
+ end
52
+
53
+ when_up do |name, site|
54
+ puts "#{name} returned #{site.code} in #{site.duration} seconds"
55
+ end
56
+
57
+ when_crashed do |name, site|
58
+ puts "#{name} has crashed with status of #{site.code}"
59
+ end
60
+
61
+ when_recovered do |name, site|
62
+ puts "#{name} has recovered with status of #{site.code}"
48
63
  end
@@ -1,4 +1,4 @@
1
- require 'net/http'
1
+ require 'chicanery/site'
2
2
  require 'nokogiri'
3
3
  require 'date'
4
4
 
@@ -12,31 +12,14 @@ module Chicanery
12
12
  server Cctray::Server.new *args
13
13
  end
14
14
 
15
- class Server
16
- attr_reader :name, :uri, :options
17
-
18
- def initialize name, url, options={}
19
- @name, @uri, @options = name, URI(url), options
20
- end
21
-
22
- def get
23
- req = Net::HTTP::Get.new(uri.path)
24
- req.basic_auth options[:user], options[:password] if options[:user] and options[:password]
25
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https', verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
26
- https.request(req)
27
- end
28
- res.value #check for success via a spectactulalry poorly named method
29
- res.body
30
- end
31
-
15
+ class Server < Chicanery::Site
32
16
  def jobs
33
17
  jobs = {}
34
- response_body = get
35
- Nokogiri::XML(response_body).css("Project").each do |project|
18
+ Nokogiri::XML(response_body = get).css("Project").each do |project|
36
19
  job = {
37
20
  activity: project[:activity] == 'Sleeping' ? :sleeping : :building,
38
21
  last_build_status: parse_build_status(project[:lastBuildStatus]),
39
- last_build_time: project[:lastBuildTime].empty? ? nil : DateTime.parse(project[:lastBuildTime]).to_time.to_i,
22
+ last_build_time: parse_build_time(project[:lastBuildTime]),
40
23
  url: project[:webUrl],
41
24
  last_label: project[:lastBuildLabel]
42
25
  }
@@ -46,6 +29,11 @@ module Chicanery
46
29
  jobs
47
30
  end
48
31
 
32
+ def parse_build_time time
33
+ return nil if time.nil? || time.empty?
34
+ DateTime.parse(time).to_time.to_i
35
+ end
36
+
49
37
  def parse_build_status status
50
38
  case status
51
39
  when /^Success/ then :success
@@ -1,6 +1,6 @@
1
1
  module Chicanery
2
2
  module Handlers
3
- %w{run started succeeded failed broken fixed commit}.each do |status|
3
+ %w{run started succeeded failed broken fixed commit up down crashed recovered}.each do |status|
4
4
  class_eval <<-EOF
5
5
  def when_#{status} &block
6
6
  #{status}_handlers << block
@@ -0,0 +1,26 @@
1
+ require 'chicanery/collections'
2
+ require 'chicanery/handlers'
3
+
4
+ module Chicanery
5
+ module Repos
6
+ include Collections
7
+ include Handlers
8
+
9
+ def check_repos current_state, previous_state
10
+ current_state[:repos] = {}
11
+ repos.each do |repo|
12
+ repo_state = repo.state
13
+ compare_repo_state repo.name, repo_state, previous_state[:repos][repo.name] if previous_state[:repos]
14
+ current_state[:repos][repo.name] = repo_state
15
+ end
16
+ end
17
+
18
+ def compare_repo_state name, current, previous
19
+ return unless previous
20
+ current.each do |branch, state|
21
+ next unless previous[branch]
22
+ notify_commit_handlers "#{name}/#{branch}", state, previous[branch] if state != previous[branch]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,20 @@
1
+ require 'chicanery/collections'
2
+ require 'chicanery/handlers'
3
+
1
4
  module Chicanery
2
- module StateComparison
5
+ module Servers
6
+ include Collections
7
+ include Handlers
8
+
9
+ def check_servers current_state, previous_state
10
+ current_state[:servers] = {}
11
+ servers.each do |server|
12
+ current_jobs = server.jobs
13
+ compare_jobs current_jobs, previous_state[:servers][server.name] if previous_state[:servers]
14
+ current_state[:servers][server.name] = current_jobs
15
+ end
16
+ end
17
+
3
18
  def compare_jobs current_jobs, previous_jobs
4
19
  return unless previous_jobs
5
20
  current_jobs.each do |job_name, job|
@@ -17,13 +32,5 @@ module Chicanery
17
32
  notify_broken_handlers name, current if current[:last_build_status] == :failure and previous[:last_build_status] == :success
18
33
  notify_fixed_handlers name, current if current[:last_build_status] == :success and previous[:last_build_status] == :failure
19
34
  end
20
-
21
- def compare_repo_state name, current, previous
22
- return unless previous
23
- current.each do |branch, state|
24
- next unless previous[branch]
25
- notify_commit_handlers "#{name}/#{branch}", state, previous[branch] if state != previous[branch]
26
- end
27
- end
28
35
  end
29
36
  end
@@ -0,0 +1,26 @@
1
+ require 'net/http'
2
+ require 'benchmark'
3
+
4
+ module Chicanery
5
+ class Site
6
+ attr_reader :name, :uri, :options, :body, :code, :duration
7
+
8
+ def initialize name, url, options={}
9
+ @name, @uri, @options = name, URI(url), options
10
+ end
11
+
12
+ def get
13
+ req = Net::HTTP::Get.new uri.path
14
+ req.basic_auth options[:user], options[:password] if options[:user] and options[:password]
15
+ http_opts = { use_ssl: uri.scheme == 'https' }
16
+ http_opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE unless options[:verify_ssl]
17
+ start = Time.now
18
+ res = Net::HTTP.start uri.host, uri.port, http_opts do |https|
19
+ https.request req
20
+ end
21
+ @duration, @code, @body = (Time.now - start), res.code, res.body
22
+ res.value #check for success via a spectactularly poorly named method
23
+ res.body
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ require 'chicanery/handlers'
2
+ require 'chicanery/site'
3
+
4
+ module Chicanery
5
+ module Sites
6
+ include Handlers
7
+
8
+ def sites
9
+ @sites ||= []
10
+ end
11
+
12
+ def site *args
13
+ sites << Chicanery::Site.new(*args)
14
+ end
15
+
16
+ def check_sites current_state, previous_state
17
+ current_state[:sites] = {}
18
+ sites.each do |site|
19
+ begin
20
+ content = site.get
21
+ current_state[:sites][site.name] = :up
22
+ notify_up_handlers site.name, site
23
+ notify_recovered_handlers site.name, site if previous_state && previous_state[:sites] && previous_state[:sites][site.name] == :down
24
+ rescue Exception
25
+ current_state[:sites][site.name] = :down
26
+ notify_down_handlers site.name, site
27
+ notify_crashed_handlers site.name, site if previous_state && previous_state[:sites] && previous_state[:sites][site.name] == :up
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -7,5 +7,11 @@ module Chicanery
7
7
  end
8
8
  end.flatten.inject(false) {|v,a| v || a}
9
9
  end
10
+
11
+ def site_down?
12
+ self[:sites].map do |name, status|
13
+ status == :down
14
+ end.inject(false) {|v,a| v || a}
15
+ end
10
16
  end
11
17
  end
data/lib/chicanery.rb CHANGED
@@ -5,18 +5,18 @@ if ENV['COVERAGE']
5
5
  end
6
6
 
7
7
  require 'chicanery/persistence'
8
- require 'chicanery/collections'
9
- require 'chicanery/handlers'
10
- require 'chicanery/state_comparison'
8
+ require 'chicanery/servers'
9
+ require 'chicanery/repos'
10
+ require 'chicanery/sites'
11
11
  require 'chicanery/summary'
12
12
 
13
13
  module Chicanery
14
14
  include Persistence
15
- include Collections
16
- include Handlers
17
- include StateComparison
15
+ include Servers
16
+ include Repos
17
+ include Sites
18
18
 
19
- VERSION = "0.1.0"
19
+ VERSION = "0.1.1"
20
20
 
21
21
  def poll_period seconds=nil
22
22
  @poll_period = seconds if seconds
@@ -24,40 +24,29 @@ module Chicanery
24
24
  end
25
25
 
26
26
  def execute args
27
- load args.shift
28
- run_every poll_period
27
+ begin
28
+ load args.shift
29
+ run_every poll_period
30
+ rescue Interrupt
31
+ end
29
32
  end
30
33
 
31
34
  def run_every poll_period
32
- begin
33
- loop do
34
- run
35
- break unless poll_period
36
- sleep poll_period
37
- end
38
- rescue Interrupt
35
+ loop do
36
+ run
37
+ break unless poll_period
38
+ sleep poll_period
39
39
  end
40
40
  end
41
41
 
42
42
  def run
43
43
  previous_state = restore
44
- current_state = {
45
- servers: {},
46
- repos: {}
47
- }
48
- repos.each do |repo|
49
- repo_state = repo.state
50
- compare_repo_state repo.name, repo_state, previous_state[:repos][repo.name] if previous_state[:repos]
51
- current_state[:repos][repo.name] = repo_state
52
- end
53
- servers.each do |server|
54
- current_jobs = server.jobs
55
- compare_jobs current_jobs, previous_state[:servers][server.name] if previous_state[:servers]
56
- current_state[:servers][server.name] = current_jobs
57
- end
44
+ current_state = {}
45
+ check_servers current_state, previous_state
46
+ check_repos current_state, previous_state
47
+ check_sites current_state, previous_state
58
48
  current_state.extend Chicanery::Summary
59
49
  run_handlers.each {|handler| handler.call current_state, previous_state }
60
50
  persist current_state
61
51
  end
62
-
63
52
  end
@@ -52,17 +52,16 @@ describe Chicanery::Cctray do
52
52
  }
53
53
  end
54
54
  end
55
-
55
+
56
56
  it 'should complain if there are no jobs in response' do
57
57
  VCR.use_cassette('no_projects') do
58
58
  expect{server.jobs}.to raise_error "could not find any jobs in response: [Nothing here but us chickens]"
59
59
  end
60
60
  end
61
-
61
+
62
62
  it 'should complain if it gets a non 2xx response' do
63
63
  VCR.use_cassette('redirect') do
64
64
  expect{server.jobs}.to raise_error Net::HTTPRetriableError
65
65
  end
66
- end
67
-
66
+ end
68
67
  end
@@ -1,5 +1,5 @@
1
- describe Chicanery::StateComparison do
2
- include Chicanery::StateComparison
1
+ describe Chicanery::Servers do
2
+ include Chicanery::Servers
3
3
 
4
4
  describe '#compare_jobs' do
5
5
  let(:current_jobs) { {} }
@@ -15,10 +15,7 @@ describe Chicanery do
15
15
  end
16
16
 
17
17
  it 'should persist new state' do
18
- should_receive(:persist).with({
19
- servers: {},
20
- repos: {}
21
- })
18
+ should_receive(:persist).with servers: {}, repos: {}, sites: {}
22
19
  end
23
20
 
24
21
  it 'should sleep for specified time when poll period is provided' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chicanery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-19 00:00:00.000000000 Z
12
+ date: 2013-03-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -154,12 +154,15 @@ files:
154
154
  - lib/chicanery/git.rb
155
155
  - lib/chicanery/handlers.rb
156
156
  - lib/chicanery/persistence.rb
157
- - lib/chicanery/state_comparison.rb
157
+ - lib/chicanery/repos.rb
158
+ - lib/chicanery/servers.rb
159
+ - lib/chicanery/site.rb
160
+ - lib/chicanery/sites.rb
158
161
  - lib/chicanery/summary.rb
159
162
  - spec/chicanery/cctray_spec.rb
160
163
  - spec/chicanery/collections_spec.rb
161
164
  - spec/chicanery/persistence_spec.rb
162
- - spec/chicanery/state_comparison_spec.rb
165
+ - spec/chicanery/servers_spec.rb
163
166
  - spec/chicanery/summary_spec.rb
164
167
  - spec/chicanery_spec.rb
165
168
  - spec/embedded_chicanery_spec.rb
@@ -177,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
180
  version: '0'
178
181
  segments:
179
182
  - 0
180
- hash: -1168261720268673254
183
+ hash: -3139042759217892738
181
184
  required_rubygems_version: !ruby/object:Gem::Requirement
182
185
  none: false
183
186
  requirements:
@@ -186,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
189
  version: '0'
187
190
  segments:
188
191
  - 0
189
- hash: -1168261720268673254
192
+ hash: -3139042759217892738
190
193
  requirements: []
191
194
  rubyforge_project:
192
195
  rubygems_version: 1.8.23
@@ -197,7 +200,7 @@ test_files:
197
200
  - spec/chicanery/cctray_spec.rb
198
201
  - spec/chicanery/collections_spec.rb
199
202
  - spec/chicanery/persistence_spec.rb
200
- - spec/chicanery/state_comparison_spec.rb
203
+ - spec/chicanery/servers_spec.rb
201
204
  - spec/chicanery/summary_spec.rb
202
205
  - spec/chicanery_spec.rb
203
206
  - spec/embedded_chicanery_spec.rb