litmus_paper 0.2.2 → 0.3.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.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use ruby-1.9.3-p0@litmus_paper --create
1
+ rvm use ruby-1.8.7-p249@litmus_paper --create
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 1.8.7
3
4
  - 1.9.2
4
5
  - 1.9.3
data/bin/litmusctl CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'optparse'
4
- require 'net/http'
4
+ require 'litmus_paper'
5
5
  require 'litmus_paper/cli/admin'
6
6
 
7
7
  LitmusPaper::CLI::Admin.new.run
@@ -1,9 +1,5 @@
1
1
  module LitmusPaper
2
2
  class App < Sinatra::Base
3
- register Sinatra::Synchrony
4
- set :dump_errors, true
5
- set :raise_errors, false
6
-
7
3
  get "/" do
8
4
  output = "Services monitored:\n"
9
5
  output += LitmusPaper.services.keys.join("\n")
@@ -48,7 +44,7 @@ module LitmusPaper
48
44
  end
49
45
 
50
46
  error do
51
- text 500, "Server Error: " + env['sinatra.error'].message
47
+ text 500, "Server Error"
52
48
  end
53
49
 
54
50
  def text(response_code, body, headers ={})
@@ -6,7 +6,7 @@ module LitmusPaper
6
6
  args, options = args.dup, {}
7
7
 
8
8
  opt_parser = OptionParser.new do |opts|
9
- opts.banner = "Usage: litmus [options]"
9
+ opts.banner = "Usage: litmus [mongrel, thin, etc] [options]"
10
10
  opts.on("-c", "--config=file", String,
11
11
  "Litmus configuration file", "Default: /etc/litmus.conf") { |v| options[:litmus_config] = v }
12
12
  opts.on("-D", "--data-dir=path", String,
@@ -31,8 +31,7 @@ module LitmusPaper
31
31
  opt_parser.parse! args
32
32
 
33
33
  options[:config] = File.expand_path("../../../config.ru", File.dirname(__FILE__))
34
- options[:server] = 'thin-with-callbacks'
35
- options[:backend] = Thin::Backends::TcpServerWithCallbacks
34
+ options[:server] = args.shift
36
35
  options
37
36
  end
38
37
  end
@@ -47,13 +46,8 @@ module LitmusPaper
47
46
  exit 1
48
47
  end
49
48
 
50
- LitmusPaper.config_file = options[:litmus_config]
49
+ LitmusPaper.configure(options[:litmus_config])
51
50
  LitmusPaper.config_dir = options[:config_dir]
52
-
53
- Thin::Callbacks.after_connect do
54
- LitmusPaper.configure!
55
- end
56
-
57
51
  super
58
52
  end
59
53
 
@@ -3,27 +3,6 @@ require 'csv'
3
3
  module LitmusPaper
4
4
  module Dependency
5
5
  class HaproxyBackends
6
-
7
- module HaproxyStatReader
8
- def initialize(fiber)
9
- @fiber = fiber
10
- @stats = ""
11
- end
12
-
13
- def connection_completed
14
- send_data("show stat\n")
15
- end
16
-
17
- def receive_data(data)
18
- @stats << data
19
- @fiber.resume(@stats) if finished?
20
- end
21
-
22
- def finished?
23
- @stats =~ /\n\n\z/
24
- end
25
- end
26
-
27
6
  def initialize(domain_socket, cluster)
28
7
  @domain_socket = domain_socket
29
8
  @cluster = cluster
@@ -31,18 +10,10 @@ module LitmusPaper
31
10
 
32
11
  def available?
33
12
  stats = _parse_stats(_fetch_stats)
34
- servers = _servers_in(stats, @cluster)
35
13
 
36
- if not _any_up?(servers)
37
- LitmusPaper.logger.info("None of the servers (#{servers.map{ |s| s['svname'] }.join(',')}) are up")
38
- false
39
- else
40
- true
41
- end
42
- end
43
-
44
- def _any_up?(servers)
14
+ servers = _servers_in(stats, @cluster)
45
15
  available = servers.select { |s| s['status'] == "UP" }
16
+
46
17
  available.size > 0
47
18
  end
48
19
 
@@ -53,17 +24,16 @@ module LitmusPaper
53
24
  end
54
25
 
55
26
  def _parse_stats(csv)
56
- stats = CSV.parse(_fetch_stats)
27
+ stats = CSV.parse(csv)
57
28
  headers = stats.shift
58
29
  stats.map { |stat| Hash[headers.zip(stat)] }
59
30
  end
60
31
 
61
32
  def _fetch_stats
62
- fiber = Fiber.current
63
-
64
- connection = EM.connect_unix_domain(@domain_socket, HaproxyStatReader, fiber)
65
-
66
- Fiber.yield
33
+ UNIXSocket.open(@domain_socket) do |socket|
34
+ socket.send "show stat\n", 0
35
+ socket.read
36
+ end
67
37
  end
68
38
  end
69
39
  end
@@ -1,12 +1,10 @@
1
1
  module LitmusPaper
2
2
  module Dependency
3
3
  class HTTP
4
- VALID_RESPONSE_CODES = (200..399).freeze
5
-
6
4
  def initialize(uri, options = {})
7
5
  @uri = uri
8
6
  @expected_content = Regexp.new(options.fetch(:content, '.*'))
9
- @method = options.fetch(:method, 'get')
7
+ @method = options.fetch(:method, 'GET')
10
8
  @ca_file = options[:ca_file]
11
9
  end
12
10
 
@@ -15,7 +13,7 @@ module LitmusPaper
15
13
  success = _successful_response?(response)
16
14
  matches = _body_matches?(response)
17
15
 
18
- LitmusPaper.logger.info("Available check to #{@uri} failed with status #{response.response_header.status}") unless success
16
+ LitmusPaper.logger.info("Available check to #{@uri} failed with status #{response.code}") unless success
19
17
  LitmusPaper.logger.info("Available check to #{@uri} did not match #{@expected_content}") unless matches
20
18
 
21
19
  success && matches
@@ -26,18 +24,28 @@ module LitmusPaper
26
24
 
27
25
  def _make_request
28
26
  uri = URI.parse(@uri)
29
- request_options = {}
30
- request_options[:ssl] = {:verify_peer => true, :cert_chain_file => @ca_file} if uri.scheme == "https"
27
+ request = Net::HTTP.const_get(@method.capitalize).new(uri.normalize.path)
28
+ request.set_form_data({})
29
+
30
+ connection = Net::HTTP.new(uri.host, uri.port)
31
+ if uri.scheme == "https"
32
+ connection.use_ssl = true
33
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
34
+ connection.ca_file = @ca_file unless @ca_file.nil?
35
+ connection.verify_callback = proc { |preverify_ok, ssl_context| _verify_ssl_certificate(preverify_ok, ssl_context) }
36
+ end
31
37
 
32
- EM::HttpRequest.new(@uri).send(@method.downcase, request_options)
38
+ connection.start do |http|
39
+ http.request(request)
40
+ end
33
41
  end
34
42
 
35
43
  def _successful_response?(response)
36
- VALID_RESPONSE_CODES.include? response.response_header.status
44
+ response.is_a? Net::HTTPSuccess
37
45
  end
38
46
 
39
47
  def _body_matches?(response)
40
- (response.response =~ @expected_content) ? true : false
48
+ (response.body =~ @expected_content) ? true : false
41
49
  end
42
50
 
43
51
  def _verify_ssl_certificate(preverify_ok, ssl_context)
@@ -1,39 +1,18 @@
1
1
  module LitmusPaper
2
2
  module Dependency
3
3
  class TCP
4
- class EndpointAvailable < EM::Connection
5
- def initialize(fiber, timeout, ip, port)
6
- @fiber = fiber
7
- @ip = ip
8
- @port = port
9
- @timer = EM::Timer.new(timeout, method(:connection_timeout))
10
- end
11
-
12
- def connection_completed
13
- close_connection
14
- @timer.cancel
15
- @fiber.resume(true)
16
- end
17
-
18
- def connection_timeout
19
- LitmusPaper.logger.info("Available check to #{@ip}:#{@port} failed with a timeout")
20
- @fiber.resume(false)
21
- end
22
- end
23
-
24
- def initialize(ip, port, options = {})
4
+ def initialize(ip, port)
25
5
  @ip, @port = ip, port
26
- @timeout = options.fetch(:timeout, 2)
27
6
  end
28
7
 
29
8
  def available?
30
- fiber = Fiber.current
31
-
32
- EM.connect(@ip, @port, EndpointAvailable, fiber, @timeout, @ip, @port) do |connection|
33
- connection.set_pending_connect_timeout @timeout
9
+ Timeout.timeout(5) do
10
+ socket = TCPSocket.new(@ip, @port)
11
+ socket.close
34
12
  end
35
-
36
- return Fiber.yield
13
+ true
14
+ rescue Exception
15
+ false
37
16
  end
38
17
 
39
18
  def to_s
@@ -1,15 +1,15 @@
1
1
  module LitmusPaper
2
2
  class Logger
3
3
  extend Forwardable
4
- def_delegators :EM, :debug, :info
4
+ def_delegators :@syslog, :debug, :info
5
5
 
6
- def write(message)
7
- info(message)
6
+ def initialize
7
+ @syslog = SyslogLogger.new("litmus_paper")
8
8
  end
9
9
 
10
- def setup!
11
- # @file = File.open("/tmp/error", "w")
12
- EM.syslog_setup('0.0.0.0', 514)
10
+ def write(message)
11
+ @syslog.info(message)
13
12
  end
13
+
14
14
  end
15
15
  end
@@ -7,7 +7,7 @@ module LitmusPaper
7
7
  "KB" => 1024
8
8
  }
9
9
 
10
- def initialize(weight, facter = DeferredFacter)
10
+ def initialize(weight, facter = Facter)
11
11
  @weight = weight
12
12
  @facter = facter
13
13
  end
@@ -20,12 +20,12 @@ module LitmusPaper
20
20
  return @memory_total unless @memory_total.nil?
21
21
 
22
22
  size, scale = @facter.value('memorytotal').split(' ')
23
- @memory_total = (size.to_f * MULTIPLIER[scale]).to_i
23
+ @memory_total = size.to_i * MULTIPLIER[scale]
24
24
  end
25
25
 
26
26
  def memory_free
27
27
  size, scale = @facter.value('memoryfree').split(' ')
28
- (size.to_f * MULTIPLIER[scale]).to_i
28
+ size.to_i * MULTIPLIER[scale]
29
29
  end
30
30
 
31
31
  def to_s
@@ -1,7 +1,7 @@
1
1
  module LitmusPaper
2
2
  module Metric
3
3
  class CPULoad
4
- def initialize(weight, facter = DeferredFacter)
4
+ def initialize(weight, facter = Facter)
5
5
  @weight = weight
6
6
  @facter = facter
7
7
  end
@@ -1,3 +1,3 @@
1
1
  module LitmusPaper
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/litmus_paper.rb CHANGED
@@ -4,23 +4,14 @@ require 'net/https'
4
4
  require 'uri'
5
5
  require 'forwardable'
6
6
 
7
- require 'async-rack'
8
7
  require 'sinatra/base'
9
- require 'sinatra/synchrony'
10
- require 'em-synchrony/em-http'
11
- require 'em/syslog'
12
-
13
- require 'thin'
14
- require 'thin/callbacks'
15
- require 'thin/backends/tcp_server_with_callbacks'
16
- require 'thin/callback_rack_handler'
17
-
18
8
  require 'facter'
9
+ require 'syslog_logger'
10
+
19
11
  require 'facts/loadaverage'
20
12
 
21
13
  require 'litmus_paper/app'
22
14
  require 'litmus_paper/configuration'
23
- require 'litmus_paper/deferred_facter'
24
15
  require 'litmus_paper/dependency/haproxy_backends'
25
16
  require 'litmus_paper/dependency/http'
26
17
  require 'litmus_paper/dependency/tcp'
@@ -35,17 +26,17 @@ require 'litmus_paper/status_file'
35
26
  module LitmusPaper
36
27
  class << self
37
28
  attr_reader :services, :config_dir
38
- attr_accessor :logger, :config_file
29
+ attr_accessor :logger
39
30
  end
40
31
 
41
32
  self.logger = Logger.new
42
33
 
43
- def self.configure!
44
- LitmusPaper.logger.setup!
34
+ def self.configure(filename)
35
+ @config_file = filename
36
+
45
37
  begin
46
- @services = LitmusPaper::Configuration.new(@config_file).evaluate
47
- rescue Exception => e
48
- logger.info("Error in configuration #{e.message}")
38
+ @services = LitmusPaper::Configuration.new(filename).evaluate
39
+ rescue Exception
49
40
  end
50
41
  end
51
42
 
@@ -54,11 +45,7 @@ module LitmusPaper
54
45
  end
55
46
 
56
47
  def self.reload
57
- begin
58
- @services = LitmusPaper::Configuration.new(@config_file).evaluate
59
- rescue Exception => e
60
- logger.info("Error in configuration #{e.message}")
61
- end
48
+ configure(@config_file)
62
49
  end
63
50
 
64
51
  def self.reset
@@ -67,4 +54,3 @@ module LitmusPaper
67
54
  end
68
55
 
69
56
  Signal.trap("HUP") { LitmusPaper.reload }
70
-
data/litmus_paper.gemspec CHANGED
@@ -15,21 +15,12 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = LitmusPaper::VERSION
17
17
 
18
- gem.required_ruby_version = '>= 1.9.1'
19
-
20
- gem.add_dependency "thin", "~> 1.3.1"
21
- gem.add_dependency "async-rack", "~> 0.5.1"
22
18
  gem.add_dependency "sinatra", "~> 1.3.2"
23
- gem.add_dependency "rack-fiber_pool", "~> 0.9"
24
19
  gem.add_dependency "facter", "~> 1.6.7"
25
- gem.add_dependency "eventmachine", "> 1.0.0.beta.1", "< 1.0.0.beta.100"
26
- gem.add_dependency "em-http-request", "~> 1.0"
27
- gem.add_dependency "em-synchrony", "~> 1.0"
28
- gem.add_dependency "em-resolv-replace", "~> 1.1"
29
- gem.add_dependency "em-syslog", "~> 0.0.2"
20
+ gem.add_dependency "SyslogLogger", "1.4.1"
30
21
 
31
- gem.add_development_dependency "rspec", "~> 2.9.0"
32
- gem.add_development_dependency "rack-test", "~> 0.6.1"
33
- gem.add_development_dependency "rake", "~> 0.9.2.2"
34
- gem.add_development_dependency "rake_commit", "~> 0.13"
22
+ gem.add_development_dependency "rspec", "2.9.0"
23
+ gem.add_development_dependency "rack-test", "0.6.1"
24
+ gem.add_development_dependency "rake"
25
+ gem.add_development_dependency "rake_commit", "0.13"
35
26
  end
@@ -237,7 +237,7 @@ describe LitmusPaper::App do
237
237
  get "/test/error"
238
238
  last_response.status.should == 500
239
239
  last_response.headers["Content-Type"].should == "text/plain"
240
- last_response.body.should == "Server Error: an error"
240
+ last_response.body.should == "Server Error"
241
241
  ensure
242
242
  app.environment = old_environment
243
243
  end
@@ -7,8 +7,7 @@ describe 'litmusctl' do
7
7
  end
8
8
 
9
9
  before(:all) do
10
- `env RACK_ENV=production bundle exec ruby -I lib bin/litmus -p 9293 -d -D #{LitmusPaper.config_dir} -c #{TEST_CONFIG} -P /tmp/litmus.pid`
11
- SpecHelper.wait_for_service :host => '127.0.0.1', :port => 9293
10
+ system "bundle exec ruby -I lib bin/litmus -p 9293 -d -D /tmp/litmus_paper -c #{TEST_CONFIG} -P /tmp/litmus.pid"
12
11
  end
13
12
 
14
13
  after(:all) do
@@ -1,45 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LitmusPaper::Dependency::HaproxyBackends do
4
- run_in_reactor
5
-
6
- module StubHaproxy
7
- def receive_data(data)
8
- send_data(<<-DATA)
9
- # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
10
- stats,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,,
11
- stats_backend,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,35,0,,1,2,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,
12
- yellow,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,3,0,,,,0,0,0,0,,,,,,,,,,,0,0,0,,,
13
- yellow_cluster,node1,0,0,0,0,,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,1,35,35,,1,4,1,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,
14
- yellow_cluster,node2,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,35,35,,1,4,1,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,
15
- yellow_cluster,node3,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,34,34,,1,4,2,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,
16
- yellow_cluster,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,1,34,34,,1,4,0,,0,,1,0,,0,,,,,,,,,,,,,,0,0,
17
- orange,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,5,0,,,,0,0,0,0,,,,,,,,,,,0,0,0,,,
18
- orange_cluster,orange1,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,0,35,0,,1,6,1,,0,,2,0,,0,L4OK,,5,,,,,,,0,,,,0,0,
19
- orange_cluster,orange2,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,0,35,0,,1,6,1,,0,,2,0,,0,L4OK,,5,,,,,,,0,,,,0,0,
20
- orange_cluster,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,DOWN,1,1,0,,0,35,0,,1,6,0,,0,,1,0,,0,,,,,,,,,,,,,,0,0,
21
-
22
- DATA
23
- end
24
- end
25
-
26
4
  describe "available?" do
27
- around(:each) do |spec|
28
- begin
29
- EM.start_unix_domain_server("/tmp/haproxy.#{Process.pid}", StubHaproxy)
30
- spec.run
31
- ensure
32
- FileUtils.rm("/tmp/haproxy.#{Process.pid}")
33
- end
5
+ before(:each) do
6
+ FileUtils.rm_rf("/tmp/stub-haproxy-stats")
7
+ system "spec/support/haproxy_test_socket /tmp/stub-haproxy-stats &"
8
+ sleep 1
34
9
  end
35
10
 
36
11
  it "is available if at least one backend is up" do
37
- haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/haproxy.#{Process.pid}", "yellow_cluster")
12
+ haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/stub-haproxy-stats", "yellow_cluster")
38
13
  haproxy.should be_available
39
14
  end
40
15
 
41
16
  it "returns 0 if no nodes are available" do
42
- haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/haproxy.#{Process.pid}", "orange_cluster")
17
+ haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/stub-haproxy-stats", "orange_cluster")
43
18
  haproxy.should_not be_available
44
19
  end
45
20
  end
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LitmusPaper::Dependency::HTTP do
4
- run_in_reactor
5
-
6
4
  before(:all) do
7
5
  server_start = system "bundle exec rackup spec/support/http_test_server_config.ru --port 9294 --pid /tmp/http-test-server.pid --daemonize"
8
6
  SpecHelper.wait_for_service :host => '127.0.0.1', :port => 9294
@@ -1,37 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LitmusPaper::Dependency::TCP do
4
- run_in_reactor
4
+ before(:all) do
5
+ @server = TCPServer.new 3333
6
+ end
5
7
 
6
- describe "#available?" do
7
- around(:each) do |spec|
8
- begin
9
- @server = EM.start_server('127.0.0.1', 3333)
10
- spec.run
11
- ensure
12
- EM.stop_server @server if @server
13
- end
14
- end
8
+ after(:all) do
9
+ @server.close
10
+ end
15
11
 
12
+ describe "#available?" do
16
13
  it "is true when it's able to reach the ip and port" do
17
14
  check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3333)
18
15
  check.should be_available
19
16
  end
20
17
 
21
- it "cancels the timer when successful" do
22
- SpecHelper.ensure_no_outstanding_timers do
23
- check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3333)
24
- check.should be_available
25
- end
26
- end
27
-
28
18
  it "is false when the ip is not available" do
29
- check = LitmusPaper::Dependency::TCP.new("127.1.1.15", 3333, :timeout => 0.3)
19
+ check = LitmusPaper::Dependency::TCP.new("10.254.254.254", 3333)
30
20
  check.should_not be_available
31
21
  end
32
22
 
33
23
  it "is false when the port is not available" do
34
- check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3334, :timeout => 0.3)
24
+ check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3334)
35
25
  check.should_not be_available
36
26
  end
37
27
  end
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LitmusPaper::Metric::AvailableMemory do
4
- run_in_reactor
5
-
6
4
  describe "#current_health" do
7
5
  it "multiplies weight by memory available" do
8
6
  facter = StubFacter.new({"memorytotal" => "10 GB", "memoryfree" => "5 GB"})
@@ -10,24 +8,12 @@ describe LitmusPaper::Metric::AvailableMemory do
10
8
  memory.current_health.should == 25
11
9
  end
12
10
 
13
- it "multiplies weight by memory available when handling floating point values" do
14
- facter = StubFacter.new({"memorytotal" => "2.0 GB", "memoryfree" => "1.8 GB"})
15
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
16
- memory.current_health.should == 44
17
- end
18
-
19
11
  describe "#memory_total" do
20
12
  it "is a positive integer" do
21
13
  metric = LitmusPaper::Metric::AvailableMemory.new(50)
22
14
  metric.memory_total.should > 1_000
23
15
  end
24
16
 
25
- it "handles floating point values properly" do
26
- facter = StubFacter.new("memorytotal" => "1.80 GB")
27
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
28
- memory.memory_total.should == 1932735283
29
- end
30
-
31
17
  it "is cached" do
32
18
  Facter.should_receive(:value).once.and_return("10 MB")
33
19
  metric = LitmusPaper::Metric::AvailableMemory.new(50)
@@ -42,12 +28,6 @@ describe LitmusPaper::Metric::AvailableMemory do
42
28
  metric = LitmusPaper::Metric::AvailableMemory.new(50)
43
29
  metric.memory_free.should > 100
44
30
  end
45
-
46
- it "handles floating point values properly" do
47
- facter = StubFacter.new("memoryfree" => "1.80 GB")
48
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
49
- memory.memory_free.should == 1932735283
50
- end
51
31
  end
52
32
 
53
33
  describe "#to_s" do
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LitmusPaper::Metric::CPULoad do
4
- run_in_reactor
5
-
6
4
  describe "#current_health" do
7
5
  it "is the percent of available cpu capacity" do
8
6
  facter = StubFacter.new({"processorcount" => "4", "loadaverage" => "1.00 0.40 0.10"})
@@ -3,16 +3,14 @@ require 'spec_helper'
3
3
  describe LitmusPaper do
4
4
  describe 'configure' do
5
5
  it 'populates services from the config file' do
6
- LitmusPaper.config_file = TEST_CONFIG
7
- LitmusPaper.configure!
6
+ LitmusPaper.configure(TEST_CONFIG)
8
7
  LitmusPaper.services.has_key?('test').should == true
9
8
  end
10
9
  end
11
10
 
12
11
  describe "reload" do
13
12
  it "will reconfigure the services" do
14
- LitmusPaper.config_file = TEST_CONFIG
15
- LitmusPaper.configure!
13
+ LitmusPaper.configure(TEST_CONFIG)
16
14
  LitmusPaper.services["bar"] = :service
17
15
 
18
16
  LitmusPaper.reload
@@ -22,18 +20,20 @@ describe LitmusPaper do
22
20
  end
23
21
 
24
22
  it "keeps the old config if there are errors in the new config" do
25
- LitmusPaper.config_file = SpecHelper.create_temp_file(<<-END)
23
+ old_config_file = SpecHelper.create_temp_file(<<-END)
26
24
  service :old_service do |s|
27
25
  s.measure_health Metric::CPULoad, :weight => 100
28
26
  end
29
27
  END
30
- LitmusPaper.configure!
31
- LitmusPaper.config_file = SpecHelper.create_temp_file(<<-END)
28
+ new_bad_config_file = SpecHelper.create_temp_file(<<-END)
32
29
  service :old_service do |s|
33
30
  syntax error here
34
31
  end
35
32
  END
36
- LitmusPaper.reload
33
+ LitmusPaper.configure(old_config_file)
34
+ LitmusPaper.services.keys.should == ["old_service"]
35
+ LitmusPaper.configure(new_bad_config_file)
36
+ LitmusPaper.services.keys.should == ["old_service"]
37
37
  end
38
38
  end
39
39
  end
data/spec/spec_helper.rb CHANGED
@@ -14,18 +14,6 @@ RSpec.configure do |config|
14
14
  config.before :each do
15
15
  FileUtils.rm_rf(LitmusPaper.config_dir)
16
16
  LitmusPaper.reset
17
- LitmusPaper.logger = NullLogger.new
18
- end
19
- end
20
-
21
- def run_in_reactor(timeout = 5)
22
- around(:each) do |spec|
23
- EM.synchrony do
24
- sig = EM.add_timer(timeout) { fail "timeout!"; EM.stop }
25
- spec.run
26
- EM.cancel_timer(sig)
27
- EM.stop
28
- end
29
17
  end
30
18
  end
31
19
 
@@ -37,15 +25,6 @@ module SpecHelper
37
25
  file.path
38
26
  end
39
27
 
40
- def self.ensure_no_outstanding_timers(&block)
41
- timer_keys = EM.instance_variable_get("@timers").keys
42
- yield
43
- new_timer_keys = EM.instance_variable_get("@timers").keys - timer_keys
44
- new_timer_keys.each do |timer_key|
45
- EM.instance_variable_get("@timers")[timer_key].should == false
46
- end
47
- end
48
-
49
28
  def self.wait_for_service(options)
50
29
  Timeout::timeout(options[:timeout] || 20) do
51
30
  loop do
@@ -0,0 +1,22 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'socket'
4
+
5
+ UNIXServer.open(ARGV[0]) do |server|
6
+ socket = server.accept
7
+ socket.puts <<-DATA
8
+ # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
9
+ stats,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,,
10
+ stats_backend,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,35,0,,1,2,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,
11
+ yellow,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,3,0,,,,0,0,0,0,,,,,,,,,,,0,0,0,,,
12
+ yellow_cluster,node1,0,0,0,0,,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,1,35,35,,1,4,1,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,
13
+ yellow_cluster,node2,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,35,35,,1,4,1,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,
14
+ yellow_cluster,node3,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,34,34,,1,4,2,,0,,2,0,,0,L4CON,,0,,,,,,,0,,,,0,0,
15
+ yellow_cluster,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,1,34,34,,1,4,0,,0,,1,0,,0,,,,,,,,,,,,,,0,0,
16
+ orange,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,5,0,,,,0,0,0,0,,,,,,,,,,,0,0,0,,,
17
+ orange_cluster,orange1,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,0,35,0,,1,6,1,,0,,2,0,,0,L4OK,,5,,,,,,,0,,,,0,0,
18
+ orange_cluster,orange2,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,0,35,0,,1,6,1,,0,,2,0,,0,L4OK,,5,,,,,,,0,,,,0,0,
19
+ orange_cluster,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,DOWN,1,1,0,,0,35,0,,1,6,0,,0,,1,0,,0,,,,,,,,,,,,,,0,0,
20
+ DATA
21
+ socket.close
22
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: litmus_paper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,33 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-19 00:00:00.000000000Z
12
+ date: 2012-06-22 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: thin
16
- requirement: &70141208657940 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: 1.3.1
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: *70141208657940
25
- - !ruby/object:Gem::Dependency
26
- name: async-rack
27
- requirement: &70141208657480 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ~>
31
- - !ruby/object:Gem::Version
32
- version: 0.5.1
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: *70141208657480
36
14
  - !ruby/object:Gem::Dependency
37
15
  name: sinatra
38
- requirement: &70141208657020 !ruby/object:Gem::Requirement
16
+ requirement: &70190125701040 !ruby/object:Gem::Requirement
39
17
  none: false
40
18
  requirements:
41
19
  - - ~>
@@ -43,21 +21,10 @@ dependencies:
43
21
  version: 1.3.2
44
22
  type: :runtime
45
23
  prerelease: false
46
- version_requirements: *70141208657020
47
- - !ruby/object:Gem::Dependency
48
- name: rack-fiber_pool
49
- requirement: &70141208656540 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
54
- version: '0.9'
55
- type: :runtime
56
- prerelease: false
57
- version_requirements: *70141208656540
24
+ version_requirements: *70190125701040
58
25
  - !ruby/object:Gem::Dependency
59
26
  name: facter
60
- requirement: &70141208656060 !ruby/object:Gem::Requirement
27
+ requirement: &70190125700200 !ruby/object:Gem::Requirement
61
28
  none: false
62
29
  requirements:
63
30
  - - ~>
@@ -65,109 +32,62 @@ dependencies:
65
32
  version: 1.6.7
66
33
  type: :runtime
67
34
  prerelease: false
68
- version_requirements: *70141208656060
35
+ version_requirements: *70190125700200
69
36
  - !ruby/object:Gem::Dependency
70
- name: eventmachine
71
- requirement: &70141208655560 !ruby/object:Gem::Requirement
37
+ name: SyslogLogger
38
+ requirement: &70190125698680 !ruby/object:Gem::Requirement
72
39
  none: false
73
40
  requirements:
74
- - - ! '>'
41
+ - - =
75
42
  - !ruby/object:Gem::Version
76
- version: 1.0.0.beta.1
77
- - - <
78
- - !ruby/object:Gem::Version
79
- version: 1.0.0.beta.100
43
+ version: 1.4.1
80
44
  type: :runtime
81
45
  prerelease: false
82
- version_requirements: *70141208655560
83
- - !ruby/object:Gem::Dependency
84
- name: em-http-request
85
- requirement: &70141208654800 !ruby/object:Gem::Requirement
86
- none: false
87
- requirements:
88
- - - ~>
89
- - !ruby/object:Gem::Version
90
- version: '1.0'
91
- type: :runtime
92
- prerelease: false
93
- version_requirements: *70141208654800
94
- - !ruby/object:Gem::Dependency
95
- name: em-synchrony
96
- requirement: &70141208654320 !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ~>
100
- - !ruby/object:Gem::Version
101
- version: '1.0'
102
- type: :runtime
103
- prerelease: false
104
- version_requirements: *70141208654320
105
- - !ruby/object:Gem::Dependency
106
- name: em-resolv-replace
107
- requirement: &70141208653820 !ruby/object:Gem::Requirement
108
- none: false
109
- requirements:
110
- - - ~>
111
- - !ruby/object:Gem::Version
112
- version: '1.1'
113
- type: :runtime
114
- prerelease: false
115
- version_requirements: *70141208653820
116
- - !ruby/object:Gem::Dependency
117
- name: em-syslog
118
- requirement: &70141208653340 !ruby/object:Gem::Requirement
119
- none: false
120
- requirements:
121
- - - ~>
122
- - !ruby/object:Gem::Version
123
- version: 0.0.2
124
- type: :runtime
125
- prerelease: false
126
- version_requirements: *70141208653340
46
+ version_requirements: *70190125698680
127
47
  - !ruby/object:Gem::Dependency
128
48
  name: rspec
129
- requirement: &70141208652840 !ruby/object:Gem::Requirement
49
+ requirement: &70190125696660 !ruby/object:Gem::Requirement
130
50
  none: false
131
51
  requirements:
132
- - - ~>
52
+ - - =
133
53
  - !ruby/object:Gem::Version
134
54
  version: 2.9.0
135
55
  type: :development
136
56
  prerelease: false
137
- version_requirements: *70141208652840
57
+ version_requirements: *70190125696660
138
58
  - !ruby/object:Gem::Dependency
139
59
  name: rack-test
140
- requirement: &70141208652340 !ruby/object:Gem::Requirement
60
+ requirement: &70190125694260 !ruby/object:Gem::Requirement
141
61
  none: false
142
62
  requirements:
143
- - - ~>
63
+ - - =
144
64
  - !ruby/object:Gem::Version
145
65
  version: 0.6.1
146
66
  type: :development
147
67
  prerelease: false
148
- version_requirements: *70141208652340
68
+ version_requirements: *70190125694260
149
69
  - !ruby/object:Gem::Dependency
150
70
  name: rake
151
- requirement: &70141208651880 !ruby/object:Gem::Requirement
71
+ requirement: &70190125693180 !ruby/object:Gem::Requirement
152
72
  none: false
153
73
  requirements:
154
- - - ~>
74
+ - - ! '>='
155
75
  - !ruby/object:Gem::Version
156
- version: 0.9.2.2
76
+ version: '0'
157
77
  type: :development
158
78
  prerelease: false
159
- version_requirements: *70141208651880
79
+ version_requirements: *70190125693180
160
80
  - !ruby/object:Gem::Dependency
161
81
  name: rake_commit
162
- requirement: &70141208651420 !ruby/object:Gem::Requirement
82
+ requirement: &70190125691740 !ruby/object:Gem::Requirement
163
83
  none: false
164
84
  requirements:
165
- - - ~>
85
+ - - =
166
86
  - !ruby/object:Gem::Version
167
87
  version: '0.13'
168
88
  type: :development
169
89
  prerelease: false
170
- version_requirements: *70141208651420
90
+ version_requirements: *70190125691740
171
91
  description: Backend health tester for HA Services
172
92
  email:
173
93
  - code@getbraintree.com
@@ -194,7 +114,6 @@ files:
194
114
  - lib/litmus_paper/cli/admin.rb
195
115
  - lib/litmus_paper/cli/server.rb
196
116
  - lib/litmus_paper/configuration.rb
197
- - lib/litmus_paper/deferred_facter.rb
198
117
  - lib/litmus_paper/dependency/haproxy_backends.rb
199
118
  - lib/litmus_paper/dependency/http.rb
200
119
  - lib/litmus_paper/dependency/tcp.rb
@@ -206,16 +125,11 @@ files:
206
125
  - lib/litmus_paper/service.rb
207
126
  - lib/litmus_paper/status_file.rb
208
127
  - lib/litmus_paper/version.rb
209
- - lib/sinatra/synchrony.rb
210
- - lib/thin/backends/tcp_server_with_callbacks.rb
211
- - lib/thin/callback_rack_handler.rb
212
- - lib/thin/callbacks.rb
213
128
  - litmus_paper.gemspec
214
129
  - spec/litmus_paper/app_spec.rb
215
130
  - spec/litmus_paper/cli/admin_spec.rb
216
131
  - spec/litmus_paper/cli/server_spec.rb
217
132
  - spec/litmus_paper/configuration_spec.rb
218
- - spec/litmus_paper/deferred_facter_spec.rb
219
133
  - spec/litmus_paper/dependency/haproxy_backends_spec.rb
220
134
  - spec/litmus_paper/dependency/http_spec.rb
221
135
  - spec/litmus_paper/dependency/tcp_spec.rb
@@ -233,10 +147,10 @@ files:
233
147
  - spec/support/config.d/passing_test.config
234
148
  - spec/support/config.d/test.config
235
149
  - spec/support/constant_metric.rb
150
+ - spec/support/haproxy_test_socket
236
151
  - spec/support/http_test_server.rb
237
152
  - spec/support/http_test_server_config.ru
238
153
  - spec/support/never_available_dependency.rb
239
- - spec/support/null_logger.rb
240
154
  - spec/support/stdout_logger.rb
241
155
  - spec/support/stub_facter.rb
242
156
  - spec/support/test.config
@@ -252,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
252
166
  requirements:
253
167
  - - ! '>='
254
168
  - !ruby/object:Gem::Version
255
- version: 1.9.1
169
+ version: '0'
256
170
  required_rubygems_version: !ruby/object:Gem::Requirement
257
171
  none: false
258
172
  requirements:
@@ -270,7 +184,6 @@ test_files:
270
184
  - spec/litmus_paper/cli/admin_spec.rb
271
185
  - spec/litmus_paper/cli/server_spec.rb
272
186
  - spec/litmus_paper/configuration_spec.rb
273
- - spec/litmus_paper/deferred_facter_spec.rb
274
187
  - spec/litmus_paper/dependency/haproxy_backends_spec.rb
275
188
  - spec/litmus_paper/dependency/http_spec.rb
276
189
  - spec/litmus_paper/dependency/tcp_spec.rb
@@ -288,10 +201,10 @@ test_files:
288
201
  - spec/support/config.d/passing_test.config
289
202
  - spec/support/config.d/test.config
290
203
  - spec/support/constant_metric.rb
204
+ - spec/support/haproxy_test_socket
291
205
  - spec/support/http_test_server.rb
292
206
  - spec/support/http_test_server_config.ru
293
207
  - spec/support/never_available_dependency.rb
294
- - spec/support/null_logger.rb
295
208
  - spec/support/stdout_logger.rb
296
209
  - spec/support/stub_facter.rb
297
210
  - spec/support/test.config
@@ -1,14 +0,0 @@
1
- module LitmusPaper
2
- class DeferredFacter
3
- def self.value(key)
4
- fiber = Fiber.current
5
-
6
- EM.defer(
7
- proc { Facter.value(key) },
8
- proc { |value| fiber.resume(value) }
9
- )
10
-
11
- return Fiber.yield
12
- end
13
- end
14
- end
@@ -1,41 +0,0 @@
1
- # inlined from sinatra-synchrony
2
- require 'sinatra/base'
3
- require 'rack/fiber_pool'
4
- require 'eventmachine'
5
- require 'em-http-request'
6
- require 'em-synchrony'
7
- require 'em-resolv-replace'
8
-
9
- module Sinatra
10
- module Synchrony
11
- def self.registered(app)
12
- app.disable :threaded
13
- end
14
-
15
- def setup_sessions(builder)
16
- builder.use Rack::FiberPool, {:rescue_exception => handle_exception } unless test?
17
- super
18
- end
19
-
20
- def handle_exception
21
- Proc.new do |env, e|
22
- if settings.show_exceptions?
23
- request = Sinatra::Request.new(env)
24
- printer = Sinatra::ShowExceptions.new(proc{ raise e })
25
- s, h, b = printer.call(env)
26
- [s, h, b]
27
- else
28
- LitmusPaper.logger.info(e)
29
- [500, {}, ""]
30
- end
31
- end
32
- end
33
-
34
- class << self
35
- def overload_tcpsocket!
36
- require 'sinatra/synchrony/tcpsocket'
37
- end
38
- end
39
- end
40
- register Synchrony
41
- end
@@ -1,20 +0,0 @@
1
- module Thin
2
- module Backends
3
- class TcpServerWithCallbacks < TcpServer
4
- def initialize(host, port, options)
5
- super(host, port)
6
- end
7
-
8
- def connect
9
- super
10
- Thin::Callbacks.after_connect_callbacks.each { |callback| callback.call }
11
- end
12
-
13
- def disconnect
14
- Thin::Callbacks.before_disconnect_callbacks.each { |callback| callback.call }
15
- super
16
- end
17
- end
18
- end
19
- end
20
-
@@ -1,14 +0,0 @@
1
- module Thin
2
- class CallbackRackHandler
3
- def self.run(app, options)
4
- server = ::Thin::Server.new(options[:Host] || '0.0.0.0',
5
- options[:Port] || 8080,
6
- app,
7
- options)
8
- yield server if block_given?
9
- server.start
10
- end
11
- end
12
- end
13
-
14
- Rack::Handler.register 'thin-with-callbacks', Thin::CallbackRackHandler
@@ -1,19 +0,0 @@
1
- module Thin
2
- class Callbacks
3
- def self.after_connect_callbacks
4
- @after_connect_callbacks ||= []
5
- end
6
-
7
- def self.after_connect(&block)
8
- after_connect_callbacks << block
9
- end
10
-
11
- def self.before_disconnect_callbacks
12
- @before_disconnect_callbacks ||= []
13
- end
14
-
15
- def self.before_disconnect(&block)
16
- before_disconnect_callbacks << block
17
- end
18
- end
19
- end
@@ -1,12 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LitmusPaper::DeferredFacter do
4
- run_in_reactor
5
-
6
- describe "value" do
7
- it "executes Facter access on another thread" do
8
- processors = LitmusPaper::DeferredFacter.value("processorcount")
9
- processors.should match(/\d+/)
10
- end
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- class NullLogger
2
- def write(message)
3
- end
4
- def info(message)
5
- end
6
- def debug(message)
7
- end
8
-
9
- def setup!
10
- end
11
- end